diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..b512c09d4 --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json index 16f4b2fd3..10d737da9 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -16,7 +16,7 @@ "ecmaFeatures": { "jsx": true }, - "project": "./tsconfig.json" + "project": ["./tsconfig.json", "./src/test/javascript/tsconfig.json"] }, "settings": { "react": { @@ -30,7 +30,6 @@ "default": ["static-field", "instance-field", "constructor", "static-method", "instance-method"] } ], - "@typescript-eslint/no-parameter-properties": ["warn", { "allows": ["public", "private", "protected"] }], "@typescript-eslint/no-unused-vars": "off", "@typescript-eslint/explicit-member-accessibility": "off", "@typescript-eslint/explicit-function-return-type": "off", @@ -43,6 +42,17 @@ "@typescript-eslint/restrict-template-expressions": "off", "@typescript-eslint/restrict-plus-operands": "off", "@typescript-eslint/no-floating-promises": "off", + "@typescript-eslint/prefer-regexp-exec": "off", + + // Added by Ben while upgrading node + "@typescript-eslint/no-unsafe-argument": "off", + "@typescript-eslint/no-misused-promises": [ + "error", + { + "checksVoidReturn": false + } + ], + "@typescript-eslint/ban-types": [ "error", { diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml index a889eb173..3b7aa2892 100644 --- a/.github/release-drafter.yml +++ b/.github/release-drafter.yml @@ -42,5 +42,5 @@ template: | ## 🕵️‍♀️ Full commit logs - - https://github.com/oncokb/oncokb-transcript/compare/$PREVIOUS_TAG...v$NEXT_PATCH_VERSION + - https://github.com/oncokb/oncokb-curation/compare/$PREVIOUS_TAG...v$NEXT_PATCH_VERSION diff --git a/.github/workflows/after-branch-commit.yml b/.github/workflows/after-branch-commit.yml new file mode 100644 index 000000000..762744c5c --- /dev/null +++ b/.github/workflows/after-branch-commit.yml @@ -0,0 +1,122 @@ +name: After branch commit + +on: + push: + branches: + - master + - rc + +jobs: + check-version-level-and-update: + if: github.repository == 'oncokb/oncokb-transcript' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: 'Update Version Level' + run: | + git pull + VERSION_LEVEL=$(cat .version-level | tr "[:upper:]" "[:lower:]") + + RELEASE_DRAFTER_MINOR='NEXT_MINOR_VERSION' + RELEASE_DRAFTER_PATCH='NEXT_PATCH_VERSION' + + if [[ $VERSION_LEVEL == 'minor' ]]; then + sed -i "s/$RELEASE_DRAFTER_PATCH/$RELEASE_DRAFTER_MINOR/gi" .github/release-drafter.yml + fi + + if [[ $VERSION_LEVEL == 'patch' ]]; then + sed -i "s/$RELEASE_DRAFTER_MINOR/$RELEASE_DRAFTER_PATCH/gi" .github/release-drafter.yml + fi + + CHANGED=$(git diff --name-only HEAD --) + if [ -n "$CHANGED" ] + then + git config user.name oncokb-bot + git config user.email dev.oncokb@gmail.com + git add . + git commit -m "Update action files to align the version level to $VERSION_LEVEL" + git push + fi + + update-draft-release: + needs: [check-version-level-and-update] + if: github.repository == 'oncokb/oncokb-transcript' + runs-on: ubuntu-latest + steps: + # Drafts your next Release notes as Pull Requests are merged into "master" + - uses: release-drafter/release-drafter@v5 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + update-pom: + needs: [check-version-level-and-update] + if: github.repository == 'oncokb/oncokb-transcript' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Extract branch name + id: extract_branch + shell: bash + run: echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT + + - name: Find previous release + id: find_release + uses: actions/github-script@v7 + with: + script: | + const branch = '${{ steps.extract_branch.outputs.branch }}'; + console.log('Looking for a latest release that is based on branch: ${{ steps.extract_branch.outputs.branch }}'); + + const releases = await github.rest.repos.listReleases({ + owner: context.repo.owner, + repo: context.repo.repo, + }); + + const release = releases.data.find(r => (r.target_commitish === branch || r.target_commitish === `refs/heads/${branch}`) && !r.draft); + + if (release) { + core.setOutput('tag', release.tag_name); + } else { + core.setFailed("No tag available, fail the action."); + } + + - name: 'Get next semantic versions' + id: semvers + uses: "WyriHaximus/github-action-next-semvers@v1" + with: + version: ${{ steps.find_release.outputs.tag }} + + - name: 'Setup Java' + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: 17 + + - name: 'Get Current Version Level' + id: version_level + run: | + VERSION_LEVEL=$(cat .version-level | tr "[:upper:]" "[:lower:]") + echo "::set-output name=VERSION_LEVEL::$VERSION_LEVEL" + + - name: 'Update Pom' + if: ${{ success() }} + env: + NEW_VERSION: ${{ steps.version_level.outputs.VERSION_LEVEL == 'minor' && steps.semvers.outputs.minor || steps.semvers.outputs.patch}} + run: | + echo "${NEW_VERSION}" + git pull + mvn --batch-mode versions:set -DnewVersion=${NEW_VERSION} -DgenerateBackupPoms=false + + CHANGED=$(git diff --name-only HEAD --) + if [ -n "$CHANGED" ] + then + git config user.name oncokb-bot + git config user.email dev.oncokb@gmail.com + git add . + git commit -m 'Update pom version' + git push + fi diff --git a/.github/workflows/after-master-commit.yml b/.github/workflows/after-master-commit.yml deleted file mode 100644 index 23e4ea763..000000000 --- a/.github/workflows/after-master-commit.yml +++ /dev/null @@ -1,89 +0,0 @@ -name: After master commit - -on: - push: - branches: - - master - -jobs: - check-version-level-and-update: - if: github.repository == 'oncokb/oncokb-transcript' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - name: 'Update Version Level' - run: | - git pull - VERSION_LEVEL=$(cat .version-level | tr "[:upper:]" "[:lower:]") - - RELEASE_DRAFTER_MINOR='NEXT_MINOR_VERSION' - RELEASE_DRAFTER_PATCH='NEXT_PATCH_VERSION' - - if [[ $VERSION_LEVEL == 'minor' ]]; then - sed -i "s/$RELEASE_DRAFTER_PATCH/$RELEASE_DRAFTER_MINOR/gi" .github/release-drafter.yml - fi - - if [[ $VERSION_LEVEL == 'patch' ]]; then - sed -i "s/$RELEASE_DRAFTER_MINOR/$RELEASE_DRAFTER_PATCH/gi" .github/release-drafter.yml - fi - - CHANGED=$(git diff --name-only HEAD --) - if [ -n "$CHANGED" ] - then - git config user.name oncokb-bot - git config user.email dev.oncokb@gmail.com - git add . - git commit -m "Update action files to align the version level to $VERSION_LEVEL" - git push - fi - - - update-pom: - needs: [check-version-level-and-update] - if: github.repository == 'oncokb/oncokb-transcript' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - - name: 'Get Previous tag' - id: previoustag - uses: "WyriHaximus/github-action-get-previous-tag@master" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - - - name: 'Get next semantic versions' - id: semvers - uses: "WyriHaximus/github-action-next-semvers@v1" - with: - version: ${{ steps.previoustag.outputs.tag }} - - - name: 'Setup Java' - uses: actions/setup-java@v1 - with: - java-version: 8 - - - name: 'Get Current Version Level' - id: 'version-level' - run: | - VERSION_LEVEL=$(cat .version-level | tr "[:upper:]" "[:lower:]") - echo "::set-output name=VERSION_LEVEL::$VERSION_LEVEL" - - name: 'Update Pom' - env: - NEW_VERSION: ${{ steps.version-level.outputs.VERSION_LEVEL == 'minor' && steps.semvers.outputs.minor || steps.semvers.outputs.patch}} - run: | - git pull - mvn --batch-mode versions:set -DnewVersion=${NEW_VERSION} -DgenerateBackupPoms=false - - CHANGED=$(git diff --name-only HEAD --) - if [ -n "$CHANGED" ] - then - git config user.name oncokb-bot - git config user.email dev.oncokb@gmail.com - git add . - git commit -m 'Update pom version' - git push - fi diff --git a/.github/workflows/docker-release.yml b/.github/workflows/docker-release.yml index 8c498349c..6d807d412 100644 --- a/.github/workflows/docker-release.yml +++ b/.github/workflows/docker-release.yml @@ -1,5 +1,11 @@ name: Build/Push docker image on: + workflow_dispatch: + inputs: + tag-name: + description: "Tag name to use for the image must start with a v" + required: true + type: string release: types: [ published ] jobs: @@ -7,26 +13,51 @@ jobs: if: github.repository == 'oncokb/oncokb-transcript' name: Build and Push runs-on: ubuntu-latest + env: + VERSION: ${{ inputs.tag-name || github.ref }} steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: - node-version: '12' - - uses: actions/setup-java@v2 + node-version: '20.12.2' + - uses: actions/setup-java@v4 with: distribution: 'adopt' - java-version: '11' + java-version: '17' - name: Install node.js packages - run: npm install + run: yarn install - name: Package application with Jib env: DOCKER_USERNAME: ${{secrets.DOCKER_USERNAME}} DOCKER_PASSWORD: ${{secrets.DOCKER_PASSWORD}} - TAG_NAME: ${{ github.event.release.tag_name }} + TAG_NAME: ${{ inputs.tag-name || github.event.release.tag_name }} REPOSITORY: ${{ github.repository }} run: | ./mvnw -ntp package -Pprod verify jib:build \ -DskipTests \ - -Djib.to.image="${REPOSITORY}:${TAG_NAME:1}" \ + -Djib.to.image="mskcc/oncokb-curation:${TAG_NAME:1}" \ -Djib.to.auth.username=$DOCKER_USERNAME \ -Djib.to.auth.password=$DOCKER_PASSWORD + + - name: Create a Sentry.io release in oncokb-curation-website + uses: getsentry/action-release@v1.7.0 + env: + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + SENTRY_ORG: memorial-sloan-kettering + SENTRY_PROJECT: oncokb-curation-website + with: + version: ${{ env.VERSION }} + environment: production + version_prefix: oncokb-curation-website- + sourceMapOptions: '{"include": ["target/classes/static/app"]}' + + - name: Create a Sentry.io release in oncokb-curation-backend + uses: getsentry/action-release@v1.7.0 + env: + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + SENTRY_ORG: memorial-sloan-kettering + SENTRY_PROJECT: oncokb-curation-backend + with: + version: ${{ env.VERSION }} + environment: production + version_prefix: oncokb-curation-backend- diff --git a/.github/workflows/github-ci.yml b/.github/workflows/github-ci.yml index c93d25b7c..68988e16e 100644 --- a/.github/workflows/github-ci.yml +++ b/.github/workflows/github-ci.yml @@ -5,15 +5,15 @@ jobs: name: OncoKB Build runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: - node-version: "12.16" - - uses: actions/setup-java@v2 + node-version: "20.12.2" + - uses: actions/setup-java@v4 with: distribution: 'adopt' - java-version: '11' + java-version: '17' - name: Install node.js packages - run: npm install + run: yarn install - name: Package application run: ./mvnw -ntp package -Pprod diff --git a/.github/workflows/release-management.yml b/.github/workflows/release-management.yml deleted file mode 100644 index da8f566b9..000000000 --- a/.github/workflows/release-management.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Release Management - -on: - push: - # branches to consider in the event; optional, defaults to all - branches: - - master - workflow_run: - workflows: - - "After master commit" - branches: - - master - types: - - completed - -jobs: - update_draft_release: - if: github.repository == 'oncokb/oncokb-transcript' - runs-on: ubuntu-latest - steps: - # Drafts your next Release notes as Pull Requests are merged into "master" - - uses: release-drafter/release-drafter@v5 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/webdriver-test.yml b/.github/workflows/webdriver-test.yml new file mode 100644 index 000000000..4b066d0b6 --- /dev/null +++ b/.github/workflows/webdriver-test.yml @@ -0,0 +1,25 @@ +name: Webdriver Test + +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Build Docker images + run: docker compose build + + - name: Run Docker containers + run: | + docker compose up -d + docker compose run --rm wdio + + - name: Archive screenshots + if: failure() + uses: actions/upload-artifact@v4 + with: + name: visual-regression-screenshots + path: ./src/test/javascript/screenshots diff --git a/.gitignore b/.gitignore index 50f7684bb..21d01696e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ /src/main/webapp/content/css/main.css /target/classes/static/** /src/test/javascript/coverage/ +/.firebaserc ###################### # Node @@ -157,3 +158,16 @@ Desktop.ini ###################### /coverage/ /.nyc_output/ + +###################### +# Screenshots +###################### +/src/test/javascript/screenshots/actual +/src/test/javascript/screenshots/diff +# Sentry Config File +.env.sentry-build-plugin +.vscode/settings.json + +local-frontend-config.json +src/main/resources/firebase.json +src/main/resources/config/application-dev.yml diff --git a/.java-version b/.java-version index b4de39476..03b6389f3 100644 --- a/.java-version +++ b/.java-version @@ -1 +1 @@ -11 +17.0 diff --git a/.jhipster/Drug.json b/.jhipster/Drug.json deleted file mode 100644 index b9422876e..000000000 --- a/.jhipster/Drug.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "Drug", - "fields": [ - { - "fieldName": "name", - "fieldType": "byte[]", - "fieldTypeBlobContent": "text" - }, - { - "fieldName": "code", - "fieldType": "String" - }, - { - "fieldName": "semanticType", - "fieldType": "byte[]", - "fieldTypeBlobContent": "text" - } - ], - "relationships": [ - { - "relationshipType": "one-to-many", - "otherEntityName": "drugSynonym", - "otherEntityRelationshipName": "drug", - "relationshipName": "synonyms" - } - ], - "entityTableName": "drug", - "dto": "no", - "pagination": "no", - "service": "serviceClass", - "jpaMetamodelFiltering": false, - "fluentMethods": true, - "readOnly": false, - "embedded": false, - "applications": "*", - "changelogDate": "20210421184924", - "skipClient": true -} diff --git a/.jhipster/DrugSynonym.json b/.jhipster/DrugSynonym.json deleted file mode 100644 index 333c4ca68..000000000 --- a/.jhipster/DrugSynonym.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "DrugSynonym", - "fields": [ - { - "fieldName": "name", - "fieldType": "byte[]", - "fieldTypeBlobContent": "text" - } - ], - "relationships": [ - { - "relationshipType": "many-to-one", - "otherEntityName": "drug", - "otherEntityRelationshipName": "synonyms", - "relationshipName": "drug" - } - ], - "entityTableName": "drug_synonym", - "dto": "no", - "pagination": "no", - "service": "serviceClass", - "jpaMetamodelFiltering": false, - "fluentMethods": true, - "readOnly": false, - "embedded": false, - "applications": "*", - "changelogDate": "20210421184925", - "skipClient": true -} diff --git a/.jhipster/EnsemblGene.json b/.jhipster/EnsemblGene.json deleted file mode 100644 index cfbd2ef95..000000000 --- a/.jhipster/EnsemblGene.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "name": "EnsemblGene", - "fields": [ - { - "fieldName": "referenceGenome", - "fieldType": "String", - "fieldValidateRules": ["required"] - }, - { - "fieldName": "ensemblGeneId", - "fieldType": "String", - "fieldValidateRules": ["required"] - }, - { - "fieldName": "canonical", - "fieldType": "Boolean", - "fieldValidateRules": ["required"] - }, - { - "fieldName": "chromosome", - "fieldType": "String", - "fieldValidateRules": ["required"] - }, - { - "fieldName": "start", - "fieldType": "Integer", - "fieldValidateRules": ["required"] - }, - { - "fieldName": "end", - "fieldType": "Integer", - "fieldValidateRules": ["required"] - }, - { - "fieldName": "strand", - "fieldType": "Integer", - "fieldValidateRules": ["required"] - } - ], - "relationships": [ - { - "relationshipType": "one-to-many", - "otherEntityName": "transcript", - "otherEntityRelationshipName": "ensemblGene", - "relationshipName": "transcript" - }, - { - "relationshipType": "many-to-one", - "otherEntityName": "gene", - "otherEntityRelationshipName": "ensemblGene", - "relationshipName": "gene" - } - ], - "entityTableName": "ensembl_gene", - "dto": "no", - "pagination": "no", - "service": "serviceClass", - "jpaMetamodelFiltering": false, - "fluentMethods": true, - "readOnly": false, - "embedded": false, - "applications": "*", - "skipClient": true, - "changelogDate": "20211130002704" -} diff --git a/.jhipster/Gene.json b/.jhipster/Gene.json deleted file mode 100644 index c7168144d..000000000 --- a/.jhipster/Gene.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "Gene", - "fields": [ - { - "fieldName": "entrezGeneId", - "fieldType": "Integer" - }, - { - "fieldName": "hugoSymbol", - "fieldType": "String" - } - ], - "relationships": [ - { - "relationshipType": "one-to-many", - "otherEntityName": "geneAlias", - "otherEntityRelationshipName": "gene", - "relationshipName": "geneAlias" - }, - { - "relationshipType": "one-to-many", - "otherEntityName": "ensemblGene", - "otherEntityRelationshipName": "gene", - "relationshipName": "ensemblGene" - } - ], - "entityTableName": "gene", - "dto": "no", - "pagination": "no", - "service": "serviceClass", - "jpaMetamodelFiltering": false, - "fluentMethods": true, - "readOnly": false, - "embedded": false, - "applications": "*", - "changelogDate": "20210503173531", - "skipClient": true -} diff --git a/.jhipster/GeneAlias.json b/.jhipster/GeneAlias.json deleted file mode 100644 index 60070b78c..000000000 --- a/.jhipster/GeneAlias.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "GeneAlias", - "fields": [ - { - "fieldName": "name", - "fieldType": "String" - } - ], - "relationships": [ - { - "relationshipType": "many-to-one", - "otherEntityName": "gene", - "otherEntityRelationshipName": "geneAlias", - "relationshipName": "gene" - } - ], - "entityTableName": "gene_alias", - "dto": "no", - "pagination": "no", - "service": "serviceClass", - "jpaMetamodelFiltering": false, - "fluentMethods": true, - "readOnly": false, - "embedded": false, - "applications": "*", - "changelogDate": "20210503173532", - "skipClient": true -} diff --git a/.jhipster/GenomeFragment.json b/.jhipster/GenomeFragment.json deleted file mode 100644 index 31cad94c8..000000000 --- a/.jhipster/GenomeFragment.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "name": "GenomeFragment", - "fields": [ - { - "fieldName": "chromosome", - "fieldType": "String" - }, - { - "fieldName": "start", - "fieldType": "Integer" - }, - { - "fieldName": "end", - "fieldType": "Integer" - }, - { - "fieldName": "strand", - "fieldType": "Integer" - }, - { - "fieldName": "type", - "fieldType": "GenomeFragmentType", - "fieldValues": "GENE,EXON,FIVE_PRIME_UTR,THREE_PRIME_UTR" - } - ], - "relationships": [ - { - "relationshipType": "many-to-one", - "otherEntityName": "transcript", - "otherEntityRelationshipName": "fragments", - "relationshipName": "transcript" - } - ], - "entityTableName": "genome_fragment", - "dto": "no", - "pagination": "no", - "service": "serviceClass", - "jpaMetamodelFiltering": false, - "fluentMethods": true, - "readOnly": false, - "embedded": false, - "applications": "*", - "skipClient": true, - "changelogDate": "20211118024252" -} diff --git a/.jhipster/Info.json b/.jhipster/Info.json deleted file mode 100644 index a29c87d93..000000000 --- a/.jhipster/Info.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "Info", - "fields": [ - { - "fieldName": "type", - "fieldType": "InfoType", - "fieldValues": "NCIT_VERSION,GENE_LAST_UPDATED", - "fieldValidateRules": ["unique", "required"] - }, - { - "fieldName": "value", - "fieldType": "String" - }, - { - "fieldName": "lastUpdated", - "fieldType": "Instant" - } - ], - "relationships": [], - "entityTableName": "info", - "dto": "no", - "pagination": "no", - "service": "serviceClass", - "jpaMetamodelFiltering": false, - "fluentMethods": true, - "readOnly": false, - "embedded": false, - "applications": "*", - "changelogDate": "20210421184926", - "skipClient": true -} diff --git a/.jhipster/Sequence.json b/.jhipster/Sequence.json deleted file mode 100644 index a8b8f8034..000000000 --- a/.jhipster/Sequence.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "Sequence", - "fields": [ - { - "fieldName": "sequenceType", - "fieldType": "SequenceType", - "fieldValues": "PROTEIN,CDNA" - }, - { - "fieldName": "sequence", - "fieldType": "byte[]", - "fieldTypeBlobContent": "text" - } - ], - "relationships": [ - { - "relationshipType": "many-to-one", - "otherEntityName": "transcript", - "otherEntityRelationshipName": "sequence", - "relationshipName": "transcript" - } - ], - "entityTableName": "sequence", - "dto": "no", - "pagination": "no", - "service": "serviceClass", - "jpaMetamodelFiltering": false, - "fluentMethods": true, - "readOnly": false, - "embedded": false, - "applications": "*", - "changelogDate": "20210129192153", - "skipClient": true -} diff --git a/.jhipster/Transcript.json b/.jhipster/Transcript.json deleted file mode 100644 index 724862c22..000000000 --- a/.jhipster/Transcript.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "name": "Transcript", - "fields": [ - { - "fieldName": "ensemblTranscriptId", - "fieldType": "String" - }, - { - "fieldName": "canonical", - "fieldType": "Boolean", - "fieldValidateRules": ["required"] - }, - { - "fieldName": "ensemblProteinId", - "fieldType": "String" - }, - { - "fieldName": "referenceSequenceId", - "fieldType": "String" - }, - { - "fieldName": "description", - "fieldType": "String" - } - ], - "relationships": [ - { - "relationshipType": "one-to-many", - "otherEntityName": "genomeFragment", - "otherEntityRelationshipName": "transcript", - "relationshipName": "fragments" - }, - { - "relationshipType": "one-to-many", - "otherEntityName": "sequence", - "otherEntityRelationshipName": "transcript", - "relationshipName": "sequence" - }, - { - "relationshipType": "many-to-one", - "otherEntityName": "ensemblGene", - "otherEntityRelationshipName": "transcript", - "relationshipName": "ensemblGene" - } - ], - "entityTableName": "transcript", - "dto": "mapstruct", - "pagination": "no", - "service": "serviceClass", - "jpaMetamodelFiltering": false, - "fluentMethods": true, - "readOnly": false, - "embedded": false, - "applications": "*", - "changelogDate": "20210201194018", - "skipClient": true -} diff --git a/.jhipster/TranscriptUsage.json b/.jhipster/TranscriptUsage.json deleted file mode 100644 index 741f95a84..000000000 --- a/.jhipster/TranscriptUsage.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "TranscriptUsage", - "fields": [ - { - "fieldName": "source", - "fieldType": "UsageSource", - "fieldValues": "ONCOKB" - } - ], - "relationships": [ - { - "relationshipType": "many-to-one", - "otherEntityName": "transcript", - "otherEntityRelationshipName": "transcriptUsage", - "relationshipName": "transcript" - } - ], - "entityTableName": "transcript_usage", - "dto": "no", - "pagination": "no", - "service": "serviceClass", - "jpaMetamodelFiltering": false, - "fluentMethods": true, - "readOnly": false, - "embedded": false, - "applications": "*", - "changelogDate": "20210201194019", - "skipClient": true -} diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index a9f1ef87b..abd303b67 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1,2 +1,2 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.3/apache-maven-3.8.3-bin.zip +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.2/apache-maven-3.8.2-bin.zip wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar diff --git a/.npmrc b/.npmrc deleted file mode 100644 index 80bcbed90..000000000 --- a/.npmrc +++ /dev/null @@ -1 +0,0 @@ -legacy-peer-deps = true diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 000000000..87834047a --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +20.12.2 diff --git a/.prettierignore b/.prettierignore index ab0567f5c..17f8c0007 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,8 +1,7 @@ node_modules -target -build package-lock.json .git +target + +# Generated by maven .mvn -gradle -.gradle diff --git a/.prettierrc b/.prettierrc index 6d25fbaf5..f0685b927 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,5 +1,8 @@ # Prettier configuration +plugins: + - prettier-plugin-java + printWidth: 140 singleQuote: true tabWidth: 2 @@ -13,6 +16,7 @@ bracketSameLine: false # java rules: overrides: - - files: "*.java" + - files: '*.java' options: tabWidth: 4 + parser: 'java' diff --git a/.yo-rc.json b/.yo-rc.json index cdd91278d..f55365a72 100644 --- a/.yo-rc.json +++ b/.yo-rc.json @@ -1,65 +1,90 @@ { "generator-jhipster": { - "promptValues": { - "packageName": "org.mskcc.oncokb.transcript" - }, - "jhipsterVersion": "7.3.1", "applicationType": "monolith", - "baseName": "oncokb-transcript", - "packageName": "org.mskcc.oncokb.transcript", - "packageFolder": "org/mskcc/oncokb/transcript", - "serverPort": "9090", - "authenticationType": "jwt", + "authenticationType": "oauth2", + "baseName": "oncokb-curation", + "blueprints": [ + { + "name": "generator-jhipster-migrate", + "version": "1.2.0" + } + ], + "buildTool": "maven", "cacheProvider": "redis", - "enableHibernateCache": false, - "websocket": false, + "clientFramework": "react", + "clientPackageManager": "yarn", + "clientTheme": "none", + "clientThemeVariant": "", + "creationTimestamp": 1592938365904, "databaseType": "sql", "devDatabaseType": "mysql", - "prodDatabaseType": "mysql", - "searchEngine": false, - "messageBroker": false, - "serviceDiscoveryType": false, - "buildTool": "maven", - "enableSwaggerCodegen": false, - "jwtSecretKey": "NGUwNTlhNDNhOWQ2ZGJlMmEzODczOWJjYWM2MWY4NDAwOTM4YTBmNGFjM2UxNjczZDU2YWZjZjc3MjdkNmU4YjVhZmIwYzI1NDhjMDFkZThiYmE5Mjc5MjM0MGVhODU5MGFhMTAyOTE0M2I3ODA1MGUzZWFhYWUwNWY2ZDgyNjQ=", - "embeddableLaunchScript": false, - "useSass": true, - "clientPackageManager": "npm", - "skipClient": false, - "creationTimestamp": 1592938365904, - "testFrameworks": [], - "jhiPrefix": "jhi", - "entitySuffix": "", + "devServerPort": 9060, "dtoSuffix": "DTO", - "otherModules": [], + "embeddableLaunchScript": false, + "enableGradleEnterprise": false, + "enableHibernateCache": false, + "enableSwaggerCodegen": false, "enableTranslation": false, - "blueprints": [], - "clientFramework": "react", - "skipUserManagement": true, - "withAdminUi": true, - "clientTheme": "none", - "clientThemeVariant": "", - "skipServer": false, - "skipCheckLengthOfIdentifier": false, - "skipFakeData": true, - "pages": [], - "reactive": false, - "nativeLanguage": "en", - "languages": ["en", "fr"], "entities": [ "Sequence", "Transcript", - "TranscriptUsage", - "Drug", - "DrugSynonym", "Info", "Gene", - "GeneAlias", "GenomeFragment", - "EnsemblGene" + "EnsemblGene", + "Drug", + "SpecimenType", + "CompanionDiagnosticDevice", + "FdaSubmissionType", + "FdaSubmission", + "Alteration", + "CancerType", + "Article", + "CategoricalAlteration", + "Consequence", + "FdaDrug", + "SeqRegion", + "Flag", + "Association", + "ClinicalTrial", + "ClinicalTrialArm", + "EligibilityCriteria", + "Evidence", + "GenomicIndicator", + "LevelOfEvidence", + "NciThesaurus", + "Synonym", + "AlleleState", + "Rule" ], - "lastLiquibaseTimestamp": 1638232024000, - "devServerPort": 9060, - "enableGradleEnterprise": false + "entitySuffix": "", + "jhiPrefix": "jhi", + "jhipsterVersion": "8.5.0", + "jwtSecretKey": "NGUwNTlhNDNhOWQ2ZGJlMmEzODczOWJjYWM2MWY4NDAwOTM4YTBmNGFjM2UxNjczZDU2YWZjZjc3MjdkNmU4YjVhZmIwYzI1NDhjMDFkZThiYmE5Mjc5MjM0MGVhODU5MGFhMTAyOTE0M2I3ODA1MGUzZWFhYWUwNWY2ZDgyNjQ=", + "languages": ["en", "fr"], + "lastLiquibaseTimestamp": 1710954881000, + "messageBroker": false, + "nativeLanguage": "en", + "otherModules": [], + "packageFolder": "org/mskcc/oncokb/curation", + "packageName": "org.mskcc.oncokb.curation", + "pages": [], + "prodDatabaseType": "mysql", + "promptValues": { + "packageName": "org.mskcc.oncokb.curation" + }, + "reactive": false, + "searchEngine": false, + "serverPort": "9090", + "serviceDiscoveryType": false, + "skipCheckLengthOfIdentifier": false, + "skipClient": false, + "skipFakeData": true, + "skipServer": false, + "skipUserManagement": true, + "testFrameworks": [], + "useSass": true, + "websocket": false, + "withAdminUi": false } } diff --git a/README.md b/README.md index 92586cba1..eb17afecc 100644 --- a/README.md +++ b/README.md @@ -1,222 +1,391 @@ -# oncokb-transcript +# OncoKB Curation -This application was generated using JHipster 7.3.1, you can find documentation and help at [https://www.jhipster.tech/documentation-archive/v7.3.1](https://www.jhipster.tech/documentation-archive/v7.3.1). +## Local Development + +1. Before you can build this project, you must install the following + dependencies on your machine: -## Development + 1. [Docker](https://www.docker.com/get-started). + 2. [mysql 8](https://dev.mysql.com/doc/mysql-installation-excerpt/8.0/en/). + 3. [Java 17](https://dev.java/download/) SDK. + 4. [Node.js](https://nodejs.org): We use Node to run a development web server + and build the project. Depending on your system, you can install Node either + from source or as a pre-packaged bundle. The version of node we are using can + be found in the [.nvmrc](.nvmrc) file. -Before you can build this project, you must install and configure the following dependencies on your machine: + - If you are using [nvm](https://github.com/nvm-sh/nvm?tab=readme-ov-file#installing-and-updating) + simply run the following commands from the root directory of the project + to install and use the correct version of node. + + ```sh + nvm install + nvm use + ``` + + 5. [Yarn](https://classic.yarnpkg.com/lang/en/docs/install/) + +2. Copy the example dev yaml file + + ```sh + cp src/main/resources/config/application-dev-example.yml src/main/resources/config/application-dev.yml + ``` + +3. Run the brew command for the Mac in the [compiling section](https://github.com/Automattic/node-canvas?tab=readme-ov-file#compiling) + of the node-canvas readme. For other systems, please see + [compiling section](https://github.com/Automattic/node-canvas?tab=readme-ov-file#compiling) + for instructions. + + ```sh + brew install pkg-config cairo pango libpng jpeg giflib librsvg pixman + ``` + +4. After installing Node and yarn, you should be able to run the following command + to install development tools. You will only need to run this command when + dependencies change in [package.json](package.json). + + ```sh + yarn install + ``` + + We use yarn scripts and [Webpack](https://webpack.js.org/) as our build system. + +5. If you are using redis as a cache, you will have to launch a cache server (Optional). + + - To start your cache server, run: + + ```sh + docker-compose -f src/main/docker/redis.yml up + ``` + + - The cache can also be turned off by adding to the [application-dev.yaml](src/main/resources/config/application-dev.yml): + + ```yaml + spring: + cache: + type: none + ``` + + See [here](https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-caching.html#boot-features-caching-provider-none) + for details. + +6. Configure Keycloak and Google SSO + + To log in to your app, you'll need to have [Keycloak](https://keycloak.org) + up and running. + + ```sh + docker-compose -f src/main/docker/keycloak.yml up + ``` + + 1. Once keycloak server is running, go to `http://localhost:8080` and click + `Administration Console` + 2. Login with the credential `username: admin, password:admin`. + + - Note this will match the credentials in the [keycloak.yml](src/main/docker/keycloak.yml). + + 3. [Create a realm](https://www.keycloak.org/docs/latest/server_admin/#proc-creating-a-realm_server_administration_guide) + and name it `oncokb-curation` + 4. [Create a new openid-connect client](https://www.keycloak.org/docs/latest/server_admin/#assembly-managing-clients_server_administration_guide) + - Set Access Type to `confidential` + - Enable Standard Flow + - Enable implicit flow + - Disable access grants + - Disable service accounts + - Disable OAuth 2.0 Device Authorization Grant + - Disable Authorization + - Set valid Redirect URI's to `http://localhost:*` and `https://localhost:*` + - Set Web Origins to `*` + 5. Follow [instructions](https://support.google.com/cloud/answer/6158849) + to obtain Google Oauth2 client id and secret. + 6. In Keycloak, go to **Identity Providers** > + **Edit button on google provider** > **Replace client id and secret** + 7. Copy the redirect URL for the google identity provider. + It should look like `http://localhost:8080/realms/oncokb-curation/broker/google/endpoint` + 8. Go back to Google APIs & Services `Credentials` tab and click on your + application. Add the redirect URL from the last step into the list with + the label `Authorized redirect URIs`. + + 9. Update the security settings in [application-dev.yml](src/main/resources/config/application-dev.yml). + + - Include realm name in the `spring.security.oauth2.client.provider.oidc.issue-uri` + property. + - To find the client secret, go to keycloak admin console and look for `web_app` + client. Find the `Credentials` tab and copy the client secret. + Credentials tab will only show when the client's `Access Type = confidential`. + + ```yaml + spring: + ... + security: + oauth2: + client: + provider: + oidc: + issuer-uri: http://localhost:8080/realms/oncokb-curation + registration: + oidc: + client-id: web_app + client-secret: CLIENT_SECRET + scope: openid,profile,email + ``` + +7. Configure Firebase + + 1. Go to [Firebase Console](https://console.firebase.google.com/) and create + a new project + - You can disable Google Analytics + 2. Expand **Build** and click **Realtime Database** + 3. Click **Create Database** + - You can use the default location + - Start in locked mode + 4. Import a JSON file with seed data. + - If you wish to have sample data for firebase then please contact + [dev@oncokb.org](mailto:dev@oncokb.org) + 5. Click the **Rules** section of the **Realtime Database** page + 6. Create a Firebase Realtime Database and configure the rules as such: + + ```json + { + "rules": { + ".read": "auth !== null && auth.token.firebaseAuthorizedUser === true", + ".write": "auth !== null && auth.token.firebaseAuthorizedUser === true" + } + } + ``` + + 7. Click **Publish** to save the changes + 8. Select gear icon next to **Project Overview** + 9. Click **Project settings** + 10. Choose **Service Accounts** on header + 11. Under **Firebase Admin SDK** section, click on **Generate new private key** + 12. Move the service account credentials under `src/main/resources/firebase.json` + > [!WARNING] + > Never commit the `firebase.json` file to git! + 13. Update `application.firebase.service-account-credentials-path` + to the filename + 14. Under **Project Overview** page in the **General** tab under the **Your apps** + section click the `` to add a web application. + 15. Pick whatever name you want to represent the oncokb curation frontend + - You do not need to setup firebase hosting + 16. The resulting credential and paste them in the corresponding fields + in `application.firebase` + 17. Copy example front configuration file + + ```sh + cp local-frontend-config-example.json local-frontend-config.json + ``` + + 18. Copy the same credentials you put in `application.firebase` into the `local-frontend-config.json` + file. + 19. Expand **Build** and click **Authentication** + 20. Click the **Sign-in method** section and add email/password provider + +8. Verify that your mysql configuration in [application-dev.yaml](src/main/resources/config/application-dev.yml) + is correct for you mysql server instance. + + ```yaml + spring: + datasource: + url: jdbc:mysql://localhost:3306/oncokb_curation?useUnicode=true&characterEncoding=utf8&useSSL=false&useLegacyDatetimeCode=false&serverTimezone=UTC&createDatabaseIfNotExist=true + username: root + password: root + ``` + +9. Run the application (Don't login just yet) + + - Note your a oncokb_curation schema will be created in your mysql database. + Data will also be seeded for it. + + ```sh + ./mvnw + ``` + +10. Wait until the server is listening to requests and is able to redirect you to + the login screen. (server url defaults to `http://localhost:9090`) + +11. Add a login for yourself into your mysql instance. Replace + with your gmail email address. + + ```sql + INSERT INTO `oncokb_curation`.`user` + ( + `login`, + `email`, + `created_by`, + `activated`) + VALUES + ('', + '', + 'SYSTEM', + 1); + + SET @UserID = (SELECT Id + FROM `oncokb_curation`.`user` + WHERE email = ''); + + INSERT INTO `oncokb_curation`.`user_authority` + (user_id, authority_name) + VALUES + (@UserId, 'ROLE_ADMIN'), + (@UserId, 'ROLE_DEV'), + (@UserId, 'ROLE_CURATOR'), + (@UserId, 'ROLE_USER'); + + ``` + +12. Login to curation! -1. [Node.js][]: We use Node to run a development web server and build the project. - Depending on your system, you can install Node either from source or as a pre-packaged bundle. - -After installing Node, you should be able to run the following command to install development tools. -You will only need to run this command when dependencies change in [package.json](package.json). - -``` -npm install -``` +## Building for production -We use npm scripts and [Webpack][] as our build system. +### Packaging as jar -If you are using redis as a cache, you will have to launch a cache server. -To start your cache server, run: +To build the final jar and optimize the oncokb-curation application for +production, run: -``` -docker-compose -f src/main/docker/redis.yml up -d +```sh +./mvnw -Pprod clean verify ``` -The cache can also be turned off by adding to the application yaml: +This will concatenate and minify the client CSS and JavaScript files. It will +also modify `index.html` so it references these new files. +To ensure everything worked, run: -``` -spring: - cache: - type: none +```sh +java -jar target/\*.jar ``` -See [here](https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-caching.html#boot-features-caching-provider-none) for details. +Then navigate to [http://localhost:9090](http://localhost:9090) in your browser. -**WARNING**: If you using second level hibernate cache and disabling the spring cache, you have to disable the second level hibernate cache as well since they are using -the same CacheManager. +### Packaging as war -Run the following commands in two separate terminals to create a blissful development experience where your browser -auto-refreshes when files change on your hard drive. +To package your application as a war in order to deploy it to an application +server, run: +```sh +./mvnw -Pprod,war clean verify ``` -./mvnw -npm start -``` - -Npm is also used to manage CSS and JavaScript dependencies used in this application. You can upgrade dependencies by -specifying a newer version in [package.json](package.json). You can also run `npm update` and `npm install` to manage dependencies. -Add the `help` flag on any command to see how you can use it. For example, `npm help update`. - -The `npm run` command will list all of the scripts available to run for this project. - -### PWA Support -JHipster ships with PWA (Progressive Web App) support, and it's turned off by default. One of the main components of a PWA is a service worker. +## Testing -The service worker initialization code is commented out by default. To enable it, uncomment the following code in `src/main/webapp/index.html`: +To launch your application's tests, run: -```html - +```sh +./mvnw verify ``` -Note: [Workbox](https://developers.google.com/web/tools/workbox/) powers JHipster's service worker. It dynamically generates the `service-worker.js` file. - -### Managing dependencies +### Unit tests -For example, to add [Leaflet][] library as a runtime dependency of your application, you would run following command: +#### Set up -``` -npm install --save --save-exact leaflet -``` +To run the tests the first time, you need to follow the steps in below. -To benefit from TypeScript type definitions from [DefinitelyTyped][] repository in development, you would run following command: +1. Run the brew command for the Mac in the [compiling section](https://github.com/Automattic/node-canvas?tab=readme-ov-file#compiling) of the node-canvas readme. For other systems, please see [compiling section](https://github.com/Automattic/node-canvas?tab=readme-ov-file#compiling) for instructions. +```sh +brew install pkg-config cairo pango libpng jpeg giflib librsvg pixman ``` -npm install --save-dev --save-exact @types/leaflet -``` - -Then you would import the JS and CSS files specified in library's installation instructions so that [Webpack][] knows about them: -Note: There are still a few other things remaining to do for Leaflet that we won't detail here. -For further instructions on how to develop with JHipster, have a look at [Using JHipster in development][]. - -### JHipster Control Center - -JHipster Control Center can help you manage and control your application(s). You can start a local control center server (accessible on http://localhost:7419) with: +2. Install the new npm packages with yarn. +```sh +yarn install --frozen-lockfile ``` -docker-compose -f src/main/docker/jhipster-control-center.yml up -``` - -## Building for production - -### Packaging as jar -To build the final jar and optimize the oncokb-transcript application for production, run: +3. Log into the firebase CLI -``` -./mvnw -Pprod clean verify +```sh +npx firebase login ``` -This will concatenate and minify the client CSS and JavaScript files. It will also modify `index.html` so it references these new files. -To ensure everything worked, run: +4. Create an emulated version of firebase locally. -``` -java -jar target/*.jar +```sh +npx firebase init ``` -Then navigate to [http://localhost:9090](http://localhost:9090) in your browser. +- Select `Set up local emulators for Firebase products` +- Name your project, for instance `oncokb-local` +- Enter when prompted for the project name so it defaulted to your project +- Select Authentication Emulator, Database Emulator when asked which emulators to setup -Refer to [Using JHipster in production][] for more details. +#### Run unit tests -### Packaging as war +Unit tests are run by [Jest](https://jestjs.io/docs/getting-started). They're +located in [src/test/javascript/](src/test/javascript/) and can be run with: -To package your application as a war in order to deploy it to an application server, run: - -``` -./mvnw -Pprod,war clean verify +```sh +yarn test ``` -## Testing +### End-to-end tests -To launch your application's tests, run: - -``` -./mvnw verify -``` - -### Client tests +We use the [WebDriverIO](https://webdriver.io/) framework for our end-to-end testing, allowing us to test interactions like a user and take screenshots. We provide two options for running these tests: locally and in docker. -Unit tests are run by [Jest][]. They're located in [src/test/javascript/](src/test/javascript/) and can be run with: +**IMPORTANT**: Expect the screenshot tests to fail if ran locally due to resolution issues. Local development for screenshot tests is only recommended during development for faster iteration. To update screenshots, wait for the [GitHub action](.github/workflows/webdriver-test.yml) after pushing your changes and retrieve the updated screenshots from the `actual` folder. -``` -npm test -``` +#### Run tests locally -For more information, refer to the [Running tests page][]. +1. Follow the [Set up](#set-up) instructions -### Code quality +2. Edit `initializeFirebase` function in firbase-app.store.ts -Sonar is used to analyse code quality. You can start a local Sonar server (accessible on http://localhost:9001) with: - -``` -docker-compose -f src/main/docker/sonar.yml up -d +```sh + initializeFirebase() { + // Add the code at the begin of the function, you can find parameter value at application-dev.yml + if (AppConfig.serverConfig.frontend) { + AppConfig.serverConfig.frontend.firebase = { + enabled: true, + apiKey: "api-key", + authDomain: "auth-domain", + databaseUrl: "database-url", + projectId: "project-id", + storageBucket: "storage-bucket", + messagingSenderId: "messageing-sender-id", + appId: "app-id", + measurementId: "measurement-id", + connectToFirebaseEmulators: false, + }; + } ``` -Note: we have turned off authentication in [src/main/docker/sonar.yml](src/main/docker/sonar.yml) for out of the box experience while trying out SonarQube, for real use cases turn it back on. - -You can run a Sonar analysis with using the [sonar-scanner](https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) or by using the maven plugin. - -Then, run a Sonar analysis: +3. Start up just the local client -``` -./mvnw -Pprod clean verify sonar:sonar +```sh +yarn start ``` -If you need to re-run the Sonar phase, please be sure to specify at least the `initialize` phase since Sonar properties are loaded from the sonar-project.properties file. +4. Start the firebase emulator +```sh +yarn run firebase-emulator ``` -./mvnw initialize sonar:sonar -``` - -For more information, refer to the [Code quality page][]. - -## Using Docker to simplify development (optional) -You can use Docker to improve your JHipster development experience. A number of docker-compose configuration are available in the [src/main/docker](src/main/docker) folder to launch required third party services. +5. Run web driver IO -For example, to start a mysql database in a docker container, run: - -``` -docker-compose -f src/main/docker/mysql.yml up -d +```sh +yarn run wdio ``` -To stop it and remove the container, run: +#### Run tests in Docker -``` -docker-compose -f src/main/docker/mysql.yml down -``` +Run `docker compose up` to build and run the tests. Make sure to update the images after making changes to the project. -You can also fully dockerize your application and all the services that it depends on. -To achieve this, first build a docker image of your app by running: +## Build production docker image -``` -./mvnw -Pprod verify jib:dockerBuild +If you are already logged into docker hub: + +```sh +./mvnw -ntp package -Pprod verify jib:build -DskipTests -Djib.to.image=oncokb/oncokb-curation:0.6.0 ``` -Then run: +If you want to explicitly pass a username and password: +```sh +./mvnw -ntp package \ + -Pprod verify \ + jib:build \ + -DskipTests \ + -Djib.to.image=oncokb/oncokb-curation:0.6.0 \ + -Djib.to.auth.username=USERNAME \ + -Djib.to.auth.password=PASSWORD ``` -docker-compose -f src/main/docker/app.yml up -d -``` - -For more information refer to [Using Docker and Docker-Compose][], this page also contains information on the docker-compose sub-generator (`jhipster docker-compose`), which is able to generate docker configurations for one or several JHipster applications. - -## Continuous Integration (optional) - -To configure CI for your project, run the ci-cd sub-generator (`jhipster ci-cd`), this will let you generate configuration files for a number of Continuous Integration systems. Consult the [Setting up Continuous Integration][] page for more information. - -[jhipster homepage and latest documentation]: https://www.jhipster.tech -[jhipster 7.3.1 archive]: https://www.jhipster.tech/documentation-archive/v7.3.1 -[using jhipster in development]: https://www.jhipster.tech/documentation-archive/v7.3.1/development/ -[using docker and docker-compose]: https://www.jhipster.tech/documentation-archive/v7.3.1/docker-compose -[using jhipster in production]: https://www.jhipster.tech/documentation-archive/v7.3.1/production/ -[running tests page]: https://www.jhipster.tech/documentation-archive/v7.3.1/running-tests/ -[code quality page]: https://www.jhipster.tech/documentation-archive/v7.3.1/code-quality/ -[setting up continuous integration]: https://www.jhipster.tech/documentation-archive/v7.3.1/setting-up-ci/ -[node.js]: https://nodejs.org/ -[npm]: https://www.npmjs.com/ -[webpack]: https://webpack.github.io/ -[browsersync]: https://www.browsersync.io/ -[jest]: https://facebook.github.io/jest/ -[leaflet]: https://leafletjs.com/ -[definitelytyped]: https://definitelytyped.org/ diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 000000000..fcdeda000 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,49 @@ +services: + app: + build: + context: . + dockerfile: ./docker/app/Dockerfile + ports: + - "9000:9000" + healthcheck: + test: ["CMD", "curl", "-k", "https://localhost:9000"] + command: yarn start-tls DOCKER=true + + wdio: + build: + context: . + dockerfile: ./docker/app/Dockerfile + depends_on: + app: + condition: service_healthy + firebase: + condition: service_healthy + chrome: + condition: service_healthy + volumes: + - ./src/test/javascript/screenshots:/app/src/test/javascript/screenshots + environment: + - DOCKER=true + - FIREBASE_DATABASE_EMULATOR_HOST=firebase:9095 + command: yarn run wdio + + firebase: + build: + context: . + dockerfile: ./docker/firebase/Dockerfile + ports: + - "9095:9095" + - "9099:9099" + - "4000:4000" + - "4400:4400" + healthcheck: + test: ["CMD", "curl", "http://localhost:4400"] + command: firebase emulators:start --import firebase --project oncokb-curation-test-54b6c # change config here + + chrome: + image: seleniarm/standalone-chromium # for those with m1 processors + shm_size: 2g + healthcheck: + test: ["CMD", "/opt/bin/check-grid.sh", "--host", "0.0.0.0", "--port", "4444"] + ports: + - 4444:4444 \ No newline at end of file diff --git a/docker/app/Dockerfile b/docker/app/Dockerfile new file mode 100644 index 000000000..819abed2e --- /dev/null +++ b/docker/app/Dockerfile @@ -0,0 +1,23 @@ +FROM node:20.12.2 as base + +RUN apt-get update + +RUN apt-get install build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev libnss3 -y + + +FROM base as node_modules + +RUN mkdir /app +WORKDIR /app + +COPY package*.json . +COPY yarn.lock . + +RUN yarn install + + +FROM node_modules as final + +WORKDIR /app +COPY . . +RUN yarn run webapp:build:dev diff --git a/docker/firebase/Dockerfile b/docker/firebase/Dockerfile new file mode 100644 index 000000000..fa621aab5 --- /dev/null +++ b/docker/firebase/Dockerfile @@ -0,0 +1,17 @@ +FROM sapmachine:11-jre-headless-ubuntu as base + +RUN apt-get update +RUN apt-get install curl -y +RUN apt-get install npm -y +RUN npm cache clean -f +RUN npm install -g n +RUN npm install -g firebase-tools + +FROM base as final + +RUN mkdir /app +WORKDIR /app + +RUN n 20.12.2 +COPY firebase.json . +COPY ./src/test/javascript . diff --git a/firebase.json b/firebase.json new file mode 100644 index 000000000..400cda312 --- /dev/null +++ b/firebase.json @@ -0,0 +1,24 @@ +{ + "emulators": { + "database": { + "port": 9095, + "host": "0.0.0.0" + }, + "ui": { + "enabled": true, + "port": "4000", + "host": "0.0.0.0" + }, + "hub": { + "host": "0.0.0.0" + }, + "logging": { + "host": "0.0.0.0" + }, + "singleProjectMode": true, + "auth": { + "port": 9099, + "host": "0.0.0.0" + } + } +} diff --git a/jest.conf.js b/jest.conf.js index 7c2eea4c9..36d69067e 100644 --- a/jest.conf.js +++ b/jest.conf.js @@ -1,11 +1,15 @@ const tsconfig = require('./tsconfig.json'); +process.env.TZ = 'UTC'; + module.exports = { testEnvironment: 'jsdom', transform: { '^.+\\.tsx?$': 'ts-jest', }, - testURL: 'http://localhost/', + testEnvironmentOptions: { + url: 'http://localhost/', + }, cacheDirectory: '/target/jest-cache', coverageDirectory: '/target/test-results/', testMatch: ['/src/main/webapp/app/**/@(*.)@(spec.ts?(x))'], diff --git a/jhipster-jdl.jdl b/jhipster-jdl.jdl index cab800703..72a8950fa 100644 --- a/jhipster-jdl.jdl +++ b/jhipster-jdl.jdl @@ -1,86 +1,451 @@ +/** + * Enumeration + */ -entity Transcript { - ensemblTranscriptId String, - canonical Boolean required, - ensemblProteinId String, - referenceSequenceId String, - description String +enum AlterationType { + GENOMIC_CHANGE, + CDNA_CHANGE, + PROTEIN_CHANGE, + MUTATION, + COPY_NUMBER_ALTERATION, + STRUCTURAL_VARIANT, + ANY, + UNKNOWN, + NA } -entity EnsemblGene { - referenceGenome String required, - ensemblGeneId String required, - canonical Boolean required, - chromosome String required, - start Integer required, - end Integer required, - strand Integer required +enum ArticleType { + PUBMED, ABSTRACT, REFERENCE, FDADRUG_LETTER, FDADRUG_LABEL, FDADRUG_SUMMARY, FDADRUG_SUMMARY_REVIEW } -entity GenomeFragment { - chromosome String, - start Integer, - end Integer, - strand Integer, - type GenomeFragmentType +enum CategoricalAlterationType{ + ONCOGENIC_MUTATIONS, + GAIN_OF_FUNCTION_MUTATIONS, + LOSS_OF_FUNCTION_MUTATIONS, + SWITCH_OF_FUNCTION_MUTATIONS, + KINASE_DOMAIN_DUPLICATIONS, + INTERNAL_TANDEM_DUPLICATIONS, + PARTIAL_TANDEM_DUPLICATIONS, + OVEREXPRESSION, + HYPERMETHYLATION, + MSIH, + TMBH, + EPIGENETIC_SILENCING, + VI, + VII, + VIII, + VIV, + VV + VUS, + TRUNCATING_MUTATIONS, + FUSIONS, + AMPLIFICATION, + DELETION, + GAIN, + LOSS, + PROMOTER, + WILDTYPE +} + +enum EligibilityCriteriaType { + INCLUSION, EXCLUSION +} + +enum EvidenceType { + GENE_SUMMARY, + MUTATION_SUMMARY, + TUMOR_TYPE_SUMMARY, + GENE_TUMOR_TYPE_SUMMARY, + PROGNOSTIC_SUMMARY, + DIAGNOSTIC_SUMMARY, + GENE_BACKGROUND, + ONCOGENIC, + MUTATION_EFFECT, + VUS, + PROGNOSTIC_IMPLICATION, + DIAGNOSTIC_IMPLICATION +} + +enum FdaSubmissionTypeKey { + DEVICE_PMA, DEVICE_DENOVO, DEVICE_HDE, DEVICE_PMN, DRUG_NDA, DRUG_BLA +} + +enum FlagType { + GENE_TYPE + GENE_PANEL + TRANSCRIPT + DRUG +} + +enum GeographicRegion { + US, EU +} + +enum GenePanelFlagEnum { + ONCOKB, + MSK_IMPACT_505, + MSK_ACCESS, + MSK_HEME, + VOGELSTEIN, + CGC_T1, + FOUNDATION_ONE, + FOUNDATION_HEME, + TEMPUS_XT, + TEMPUS_XR, + TEMPUS_XF, + TEMPUS_XG, + TEMPUS_XG_PLUS, + TEMPUS_XE, + GUARDANT_360, + ONCOMINE_DX + ONCOMINE_CA_V3 + ONCOMINE_CA_PLUS + CARIS_MI + TRUSIGHT_ONCOLOGY_500 } enum GenomeFragmentType { - GENE, - EXON, + GENE, + EXON, FIVE_PRIME_UTR, THREE_PRIME_UTR } -entity Sequence { - sequenceType SequenceType - sequence TextBlob +enum GenomicIndicatorType { + GERMLINE +} + +enum InfoType { + NCIT_VERSION, + GENE_VERSION, + ONCOKB_TRANSCRIPT_VERSION, + MANE_TRANSCRIPT_VERSION, + ENSEMBL_VERSION +} + +enum LevelOfEvidenceType { + TX, DX, PX, FDA, TX_LIQUID_PROPAGATION, TX_SOLID_PROPAGATION +} + +enum ReferenceGenome { + GRCh37, GRCh38 } enum SequenceType { - PROTEIN, CDNA + PROTEIN, CDNA, GENOMIC } -entity Drug { - name TextBlob +enum StructuralVariantType { + FUSION +} + +enum SynonymType { + GENE, NCIT, CANCER_TYPE, ARTICLE +} + +enum TranscriptFlagEnum { + MANE_SELECT, + MANE_PLUS_CLINICAL, + GN_CANONICAL, + ONCOKB, + ENSEMBL_CANONICAL +} + +enum TumorForm { + SOLID, LIQUID, MIXED +} + +/** + * Entity + */ + +entity AlleleState { + name String required unique +} + +entity Alteration { + type AlterationType required + name String required + alteration String required + proteinChange String required + start Integer + end Integer + refResidues String + variantResidues String +} + +entity Article { + type ArticleType required + uid String + title TextBlob + content TextBlob + link String + authors String + date Instant +} + +entity Association { + name String +} + +entity Rule { + entity String required + rule String + name String +} + +entity CancerType { code String - semanticType TextBlob + color String + level Integer required + mainType String required + subtype String + tissue String + tumorForm TumorForm required +} + +entity CategoricalAlteration { + alterationType AlterationType required + type String required unique + name String required +} + +entity ClinicalTrial { + nctId String + briefTitle String required + phase String + status String } -entity DrugSynonym { - name TextBlob +entity ClinicalTrialArm { + name String required +} + +entity CompanionDiagnosticDevice { + name String required + manufacturer String required + indicationDetails String + platformType String + lastUpdated Instant +} + +entity Consequence { + term String required unique + name String required + isGenerallyTruncating Boolean required + description String +} + +entity Drug { + uuid String required unique + name TextBlob required +} + +entity EligibilityCriteria { + type EligibilityCriteriaType required + priority Integer + criteria TextBlob +} + +entity EnsemblGene { + referenceGenome ReferenceGenome + ensemblGeneId String required + canonical Boolean required + start Integer required + end Integer required + strand Integer required +} + +entity Evidence { + uuid String + evidenceType String required + knownEffect String + description TextBlob + note TextBlob +} + +entity FdaDrug { + applicationNumber String unique required + sponsorName String + overallMarketingStatus String +} + +entity FdaSubmission { + number String required + supplementNumber String required + + deviceName String required + genericName String + + dateReceived LocalDate + decisionDate LocalDate + + description TextBlob + + curated Boolean required + genetic Boolean required + + note TextBlob +} + +entity FdaSubmissionType { + type FdaSubmissionTypeKey required unique + name String required + shortName String + submissionPrefix String + submissionLink String + description TextBlob +} + +entity Flag { + type String required + flag String required + name String required + description TextBlob required +} + +entity Gene { + entrezGeneId Integer required unique + hugoSymbol String required + hgncId String +} + +entity GenomeFragment { + start Integer required + end Integer required + strand Integer required + type GenomeFragmentType required +} + +entity GenomicIndicator { + uuid String required unique + type String required + name String required + description TextBlob } entity Info { - type InfoType unique required + type String unique required value String + created Instant required lastUpdated Instant } -enum InfoType { - NCIT_VERSION, - GENE_LAST_UPDATED +entity LevelOfEvidence { + type String required + level String required unique + description String required + htmlDescription String required + color String required } -entity Gene { - entrezGeneId Integer - hugoSymbol String +entity NciThesaurus { + version String required + code String unique required + preferredName String + displayName String } -entity GeneAlias { - name String + +entity SeqRegion { + name String required unique + chromosome String + description TextBlob +} + +entity Sequence { + sequenceType SequenceType required + sequence TextBlob required +} + +entity SpecimenType{ + type String required + name String required +} + +entity Synonym { + type String required + source String required + code String + name String required + note TextBlob +} + +entity Transcript { + referenceGenome ReferenceGenome + ensemblTranscriptId String + canonical Boolean required + ensemblProteinId String + referenceSequenceId String + description String +} + +/** + * Relationship + */ + +relationship OneToOne { + Drug{nciThesaurus(code)} to NciThesaurus + Evidence to Association } relationship OneToMany { - Drug{synonyms} to DrugSynonym - Gene to GeneAlias - Gene to EnsemblGene - Transcript{fragments} to GenomeFragment{transcript} + Association to Rule + CancerType{children} to CancerType {parent} + ClinicalTrial to ClinicalTrialArm + ClinicalTrial to EligibilityCriteria + CompanionDiagnosticDevice to FdaSubmission + Consequence to Alteration {consequence(term)} + Consequence to CategoricalAlteration {consequence(term)} + Drug to FdaDrug EnsemblGene to Transcript + FdaDrug to FdaSubmission + FdaSubmissionType to FdaSubmission{type(type)} + Gene to EnsemblGene + Gene to Evidence + Gene to Transcript + SeqRegion to EnsemblGene {seqRegion(name)} + SeqRegion to GenomeFragment {seqRegion(name)} Transcript to Sequence + Transcript{fragments} to GenomeFragment{transcript} +} + +relationship ManyToMany { + Alteration to Flag + Alteration to Gene + Alteration to Transcript + Article to Flag + Article to Synonym + Association to Alteration + Association to Article + Association to CancerType + Association to Drug + CancerType to Synonym + ClinicalTrial to Association + ClinicalTrialArm to Association + CompanionDiagnosticDevice to SpecimenType + Drug to Flag + EligibilityCriteria to Association + Evidence to LevelOfEvidence + FdaSubmission to Article + FdaSubmission to Association + Gene to Flag + Gene to Synonym + GenomicIndicator to AlleleState + GenomicIndicator to Association + NciThesaurus to Synonym + Transcript to Flag } +paginate Alteration, Article, CancerType, ClinicalTrial, ClinicalTrialArm, +EligibilityCriteria, EnsemblGene, Evidence, FdaDrug, FdaSubmission, Flag , Gene, GenomeFragment, +NciThesaurus, Sequence, Synonym, Transcript with pagination + service * with serviceClass -dto Transcript with mapstruct -skipClient * +filter Alteration, Article, CancerType, ClinicalTrial, ClinicalTrialArm, +CompanionDiagnosticDevice, Consequence, Drug, EligibilityCriteria, +EnsemblGene, Evidence, FdaDrug, FdaSubmission, Flag, Gene, GenomeFragment, +GenomicIndicator, NciThesaurus, Sequence, Synonym, Transcript + +dto Transcript with mapstruct diff --git a/local-frontend-config-example.json b/local-frontend-config-example.json new file mode 100644 index 000000000..487a13c94 --- /dev/null +++ b/local-frontend-config-example.json @@ -0,0 +1,14 @@ +{ + "firebase": { + "enabled": true, + "apiKey": "", + "authDomain": "", + "databaseUrl": "", + "projectId": "", + "storageBucket": "", + "messagingSenderId": "", + "appId": "", + "measurementId": "", + "connectToFirebaseEmulators": false + } +} diff --git a/mvnw b/mvnw index a16b5431b..ac8e247e1 100755 --- a/mvnw +++ b/mvnw @@ -8,7 +8,7 @@ # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # -# https://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an @@ -19,292 +19,232 @@ # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- -# Maven Start Up Batch script -# -# Required ENV vars: -# ------------------ -# JAVA_HOME - location of a JDK home dir +# Apache Maven Wrapper startup batch script, version 3.3.1 # # Optional ENV vars # ----------------- -# M2_HOME - location of maven2's installed home dir -# MAVEN_OPTS - parameters passed to the Java VM when running Maven -# e.g. to debug Maven itself, use -# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# JAVA_HOME - location of a JDK home dir, required when download maven via java source +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output # ---------------------------------------------------------------------------- -if [ -z "$MAVEN_SKIP_RC" ] ; then - - if [ -f /etc/mavenrc ] ; then - . /etc/mavenrc - fi +set -euf +[ "${MVNW_VERBOSE-}" != debug ] || set -x - if [ -f "$HOME/.mavenrc" ] ; then - . "$HOME/.mavenrc" - fi +# OS specific support. +native_path() { printf %s\\n "$1"; } +case "$(uname)" in +CYGWIN* | MINGW*) + [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" + native_path() { cygpath --path --windows "$1"; } + ;; +esac -fi +# set JAVACMD and JAVACCMD +set_java_home() { + # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched + if [ -n "${JAVA_HOME-}" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACCMD="$JAVA_HOME/jre/sh/javac" + else + JAVACMD="$JAVA_HOME/bin/java" + JAVACCMD="$JAVA_HOME/bin/javac" -# OS specific support. $var _must_ be set to either true or false. -cygwin=false; -darwin=false; -mingw=false -case "`uname`" in - CYGWIN*) cygwin=true ;; - MINGW*) mingw=true;; - Darwin*) darwin=true - # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home - # See https://developer.apple.com/library/mac/qa/qa1170/_index.html - if [ -z "$JAVA_HOME" ]; then - if [ -x "/usr/libexec/java_home" ]; then - export JAVA_HOME="`/usr/libexec/java_home`" - else - export JAVA_HOME="/Library/Java/Home" + if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then + echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 + echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 + return 1 fi fi - ;; -esac - -if [ -z "$JAVA_HOME" ] ; then - if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=`java-config --jre-home` + else + JAVACMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v java + )" || : + JAVACCMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v javac + )" || : + + if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then + echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 + return 1 + fi fi -fi - -if [ -z "$M2_HOME" ] ; then - ## resolve links - $0 may be a link to maven's home - PRG="$0" +} - # need this for relative symlinks - while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG="`dirname "$PRG"`/$link" - fi +# hash string like Java String::hashCode +hash_string() { + str="${1:-}" h=0 + while [ -n "$str" ]; do + char="${str%"${str#?}"}" + h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) + str="${str#?}" done + printf %x\\n $h +} - saveddir=`pwd` +verbose() { :; } +[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } - M2_HOME=`dirname "$PRG"`/.. +die() { + printf %s\\n "$1" >&2 + exit 1 +} - # make it fully qualified - M2_HOME=`cd "$M2_HOME" && pwd` +# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +while IFS="=" read -r key value; do + case "${key-}" in + distributionUrl) distributionUrl="${value-}" ;; + distributionSha256Sum) distributionSha256Sum="${value-}" ;; + esac +done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties" + +case "${distributionUrl##*/}" in +maven-mvnd-*bin.*) + MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ + case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in + *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; + :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; + :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; + :Linux*x86_64*) distributionPlatform=linux-amd64 ;; + *) + echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 + distributionPlatform=linux-amd64 + ;; + esac + distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" + ;; +maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; +*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac - cd "$saveddir" - # echo Using m2 at $M2_HOME -fi +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" +distributionUrlName="${distributionUrl##*/}" +distributionUrlNameMain="${distributionUrlName%.*}" +distributionUrlNameMain="${distributionUrlNameMain%-bin}" +MAVEN_HOME="$HOME/.m2/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" + +exec_maven() { + unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : + exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" +} -# For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin ; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --unix "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --unix "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +if [ -d "$MAVEN_HOME" ]; then + verbose "found existing MAVEN_HOME at $MAVEN_HOME" + exec_maven "$@" fi -# For Mingw, ensure paths are in UNIX format before anything is touched -if $mingw ; then - [ -n "$M2_HOME" ] && - M2_HOME="`(cd "$M2_HOME"; pwd)`" - [ -n "$JAVA_HOME" ] && - JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" -fi +case "${distributionUrl-}" in +*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; +*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; +esac -if [ -z "$JAVA_HOME" ]; then - javaExecutable="`which javac`" - if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then - # readlink(1) is not available as standard on Solaris 10. - readLink=`which readlink` - if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then - if $darwin ; then - javaHome="`dirname \"$javaExecutable\"`" - javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" - else - javaExecutable="`readlink -f \"$javaExecutable\"`" - fi - javaHome="`dirname \"$javaExecutable\"`" - javaHome=`expr "$javaHome" : '\(.*\)/bin'` - JAVA_HOME="$javaHome" - export JAVA_HOME - fi - fi +# prepare tmp dir +if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then + clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } + trap clean HUP INT TERM EXIT +else + die "cannot create temp dir" fi -if [ -z "$JAVACMD" ] ; then - if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - else - JAVACMD="`which java`" - fi -fi +mkdir -p -- "${MAVEN_HOME%/*}" -if [ ! -x "$JAVACMD" ] ; then - echo "Error: JAVA_HOME is not defined correctly." >&2 - echo " We cannot execute $JAVACMD" >&2 - exit 1 -fi +# Download and Install Apache Maven +verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +verbose "Downloading from: $distributionUrl" +verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" -if [ -z "$JAVA_HOME" ] ; then - echo "Warning: JAVA_HOME environment variable is not set." +# select .zip or .tar.gz +if ! command -v unzip >/dev/null; then + distributionUrl="${distributionUrl%.zip}.tar.gz" + distributionUrlName="${distributionUrl##*/}" fi -CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher +# verbose opt +__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' +[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v -# traverses directory structure from process work directory to filesystem root -# first directory with .mvn subdirectory is considered project base directory -find_maven_basedir() { +# normalize http auth +case "${MVNW_PASSWORD:+has-password}" in +'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; +has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; +esac - if [ -z "$1" ] - then - echo "Path not specified to find_maven_basedir" - return 1 - fi +if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then + verbose "Found wget ... using wget" + wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" +elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then + verbose "Found curl ... using curl" + curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" +elif set_java_home; then + verbose "Falling back to use Java to download" + javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" + targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" + cat >"$javaSource" <<-END + public class Downloader extends java.net.Authenticator + { + protected java.net.PasswordAuthentication getPasswordAuthentication() + { + return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); + } + public static void main( String[] args ) throws Exception + { + setDefault( new Downloader() ); + java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); + } + } + END + # For Cygwin/MinGW, switch paths to Windows format before running javac and java + verbose " - Compiling Downloader.java ..." + "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" + verbose " - Running Downloader.java ..." + "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" +fi - basedir="$1" - wdir="$1" - while [ "$wdir" != '/' ] ; do - if [ -d "$wdir"/.mvn ] ; then - basedir=$wdir - break +# If specified, validate the SHA-256 sum of the Maven distribution zip file +if [ -n "${distributionSha256Sum-}" ]; then + distributionSha256Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha256sum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then + distributionSha256Result=true fi - # workaround for JBEAP-8937 (on Solaris 10/Sparc) - if [ -d "${wdir}" ]; then - wdir=`cd "$wdir/.."; pwd` + elif command -v shasum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then + distributionSha256Result=true fi - # end of workaround - done - echo "${basedir}" -} - -# concatenates all lines of a file -concat_lines() { - if [ -f "$1" ]; then - echo "$(tr -s '\n' ' ' < "$1")" + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha256Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 + exit 1 fi -} - -BASE_DIR=`find_maven_basedir "$(pwd)"` -if [ -z "$BASE_DIR" ]; then - exit 1; fi -########################################################################################## -# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -# This allows using the maven wrapper in projects that prohibit checking in binary data. -########################################################################################## -if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found .mvn/wrapper/maven-wrapper.jar" - fi +# unzip and move +if command -v unzip >/dev/null; then + unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." - fi - if [ -n "$MVNW_REPOURL" ]; then - jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - else - jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - fi - while IFS="=" read key value; do - case "$key" in (wrapperUrl) jarUrl="$value"; break ;; - esac - done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" - if [ "$MVNW_VERBOSE" = true ]; then - echo "Downloading from: $jarUrl" - fi - wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" - if $cygwin; then - wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` - fi - - if command -v wget > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found wget ... using wget" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - wget "$jarUrl" -O "$wrapperJarPath" - else - wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" - fi - elif command -v curl > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found curl ... using curl" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - curl -o "$wrapperJarPath" "$jarUrl" -f - else - curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f - fi - - else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Falling back to using Java to download" - fi - javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" - # For Cygwin, switch paths to Windows format before running javac - if $cygwin; then - javaClass=`cygpath --path --windows "$javaClass"` - fi - if [ -e "$javaClass" ]; then - if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Compiling MavenWrapperDownloader.java ..." - fi - # Compiling the Java class - ("$JAVA_HOME/bin/javac" "$javaClass") - fi - if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - # Running the downloader - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Running MavenWrapperDownloader.java ..." - fi - ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") - fi - fi - fi -fi -########################################################################################## -# End of extension -########################################################################################## - -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} -if [ "$MVNW_VERBOSE" = true ]; then - echo $MAVEN_PROJECTBASEDIR + tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" fi -MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" - -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` - [ -n "$MAVEN_PROJECTBASEDIR" ] && - MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` -fi - -# Provide a "standardized" way to retrieve the CLI args that will -# work with both Windows and non-Windows executions. -MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" -export MAVEN_CMD_LINE_ARGS - -WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" -exec "$JAVACMD" \ - $MAVEN_OPTS \ - -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" +clean || : +exec_maven "$@" diff --git a/mvnw.cmd b/mvnw.cmd index c8d43372c..7b0c0943b 100644 --- a/mvnw.cmd +++ b/mvnw.cmd @@ -1,3 +1,4 @@ +<# : batch portion @REM ---------------------------------------------------------------------------- @REM Licensed to the Apache Software Foundation (ASF) under one @REM or more contributor license agreements. See the NOTICE file @@ -7,7 +8,7 @@ @REM "License"); you may not use this file except in compliance @REM with the License. You may obtain a copy of the License at @REM -@REM https://www.apache.org/licenses/LICENSE-2.0 +@REM http://www.apache.org/licenses/LICENSE-2.0 @REM @REM Unless required by applicable law or agreed to in writing, @REM software distributed under the License is distributed on an @@ -18,165 +19,128 @@ @REM ---------------------------------------------------------------------------- @REM ---------------------------------------------------------------------------- -@REM Maven Start Up Batch script -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir +@REM Apache Maven Wrapper startup batch script, version 3.3.1 @REM @REM Optional ENV vars -@REM M2_HOME - location of maven2's installed home dir -@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending -@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven -@REM e.g. to debug Maven itself, use -@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output @REM ---------------------------------------------------------------------------- -@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' -@echo off -@REM set title of command window -title %0 -@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' -@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% - -@REM set %HOME% to equivalent of $HOME -if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") - -@REM Execute a user defined script before this one -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre -@REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" -:skipRcPre - -@setlocal - -set ERROR_CODE=0 - -@REM To isolate internal variables from possible post scripts, we use another setlocal -@setlocal - -@REM ==== START VALIDATION ==== -if not "%JAVA_HOME%" == "" goto OkJHome - -echo. -echo Error: JAVA_HOME not found in your environment. >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -:OkJHome -if exist "%JAVA_HOME%\bin\java.exe" goto init - -echo. -echo Error: JAVA_HOME is set to an invalid directory. >&2 -echo JAVA_HOME = "%JAVA_HOME%" >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -@REM ==== END VALIDATION ==== - -:init - -@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". -@REM Fallback to current working directory if not found. - -set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% -IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir - -set EXEC_DIR=%CD% -set WDIR=%EXEC_DIR% -:findBaseDir -IF EXIST "%WDIR%"\.mvn goto baseDirFound -cd .. -IF "%WDIR%"=="%CD%" goto baseDirNotFound -set WDIR=%CD% -goto findBaseDir - -:baseDirFound -set MAVEN_PROJECTBASEDIR=%WDIR% -cd "%EXEC_DIR%" -goto endDetectBaseDir - -:baseDirNotFound -set MAVEN_PROJECTBASEDIR=%EXEC_DIR% -cd "%EXEC_DIR%" - -:endDetectBaseDir - -IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig - -@setlocal EnableExtensions EnableDelayedExpansion -for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a -@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% - -:endReadAdditionalConfig - -SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" -set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - -FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( - IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B -) - -@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -@REM This allows using the maven wrapper in projects that prohibit checking in binary data. -if exist %WRAPPER_JAR% ( - if "%MVNW_VERBOSE%" == "true" ( - echo Found %WRAPPER_JAR% - ) -) else ( - if not "%MVNW_REPOURL%" == "" ( - SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - ) - if "%MVNW_VERBOSE%" == "true" ( - echo Couldn't find %WRAPPER_JAR%, downloading it ... - echo Downloading from: %DOWNLOAD_URL% - ) - - powershell -Command "&{"^ - "$webclient = new-object System.Net.WebClient;"^ - "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ - "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ - "}"^ - "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ - "}" - if "%MVNW_VERBOSE%" == "true" ( - echo Finished downloading %WRAPPER_JAR% - ) +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) ) -@REM End of extension - -@REM Provide a "standardized" way to retrieve the CLI args that will -@REM work with both Windows and non-Windows executions. -set MAVEN_CMD_LINE_ARGS=%* - -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* -if ERRORLEVEL 1 goto error -goto end - -:error -set ERROR_CODE=1 - -:end -@endlocal & set ERROR_CODE=%ERROR_CODE% - -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost -@REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" -:skipRcPost - -@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%" == "on" pause - -if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% - -exit /B %ERROR_CODE% +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' +$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" +$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/npmw b/npmw deleted file mode 100755 index f5ade0641..000000000 --- a/npmw +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh - -basedir=`dirname "$0"` - -if [ -f "$basedir/mvnw" ]; then - builddir="target/node" - installCommand="$basedir/mvnw -Pwebapp frontend:install-node-and-npm@install-node-and-npm" -else - builddir=".gradle/npm" - installCommand="$basedir/gradlew npmSetup" -fi - -NPM_EXE="$basedir/$builddir/npm" - -if ! [ -x "$NPM_EXE" ]; then - $installCommand || true -fi - -if ! [ -x "$NPM_EXE" ]; then - echo "Using npm installed globally" - npm "$@" -else - echo "Using npm installed locally $($NPM_EXE --version)" - $NPM_EXE "$@" -fi diff --git a/npmw.cmd b/npmw.cmd deleted file mode 100644 index eb8f2571a..000000000 --- a/npmw.cmd +++ /dev/null @@ -1,24 +0,0 @@ -@echo off - -@setlocal - -set NPMW_DIR=%~dp0 - -if exist "%NPMW_DIR%\mvnw.cmd" ( - set NPM_EXE=%NPMW_DIR%\target\node\npm.cmd - set INSTALL_NPM_COMMAND=%NPMW_DIR%\mvnw.cmd -Pwebapp frontend:install-node-and-npm@install-node-and-npm -) else ( - set NPM_EXE=%NPMW_DIR%\.gradle\npm\npm.cmd - set INSTALL_NPM_COMMAND=%NPMW_DIR%\gradlew.bat npmSetup -) - -if not exist %NPM_EXE% ( - call %INSTALL_NPM_COMMAND% -) - -if not exist %NPM_EXE% goto globalNpm - -%NPM_EXE% %* - -:globalNpm -npm %* diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 758d7b556..000000000 --- a/package-lock.json +++ /dev/null @@ -1,16418 +0,0 @@ -{ - "name": "oncokb-transcript", - "version": "0.0.1-SNAPSHOT", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@apideck/better-ajv-errors": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.2.7.tgz", - "integrity": "sha512-J2dW+EHYudbwI7MGovcHWLBrxasl21uuroc2zT8bH2RxYuv2g5GqsO5jcKUZz4LaMST45xhKjVuyRYkhcWyMhA==", - "dev": true, - "requires": { - "json-schema": "^0.3.0", - "jsonpointer": "^5.0.0", - "leven": "^3.1.0" - }, - "dependencies": { - "json-schema": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.3.0.tgz", - "integrity": "sha512-TYfxx36xfl52Rf1LU9HyWSLGPdYLL+SQ8/E/0yVyKG8wCCDaSrhPap0vEdlsZWRaS6tnKKLPGiEJGiREVC8kxQ==", - "dev": true - } - } - }, - "@babel/code-frame": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz", - "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==", - "dev": true, - "requires": { - "@babel/highlight": "^7.16.0" - } - }, - "@babel/compat-data": { - "version": "7.16.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.4.tgz", - "integrity": "sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q==", - "dev": true - }, - "@babel/core": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.0.tgz", - "integrity": "sha512-mYZEvshBRHGsIAiyH5PzCFTCfbWfoYbO/jcSdXQSUQu1/pW0xDZAUP7KEc32heqWTAfAHhV9j1vH8Sav7l+JNQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.16.0", - "@babel/generator": "^7.16.0", - "@babel/helper-compilation-targets": "^7.16.0", - "@babel/helper-module-transforms": "^7.16.0", - "@babel/helpers": "^7.16.0", - "@babel/parser": "^7.16.0", - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.0", - "@babel/types": "^7.16.0", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.0.tgz", - "integrity": "sha512-RR8hUCfRQn9j9RPKEVXo9LiwoxLPYn6hNZlvUOR8tSnaxlD0p0+la00ZP9/SnRt6HchKr+X0fO2r8vrETiJGew==", - "dev": true, - "requires": { - "@babel/types": "^7.16.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.0.tgz", - "integrity": "sha512-ItmYF9vR4zA8cByDocY05o0LGUkp1zhbTQOH1NFyl5xXEqlTJQCEJjieriw+aFpxo16swMxUnUiKS7a/r4vtHg==", - "dev": true, - "requires": { - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.0.tgz", - "integrity": "sha512-9KuleLT0e77wFUku6TUkqZzCEymBdtuQQ27MhEKzf9UOOJu3cYj98kyaDAzxpC7lV6DGiZFuC8XqDsq8/Kl6aQ==", - "dev": true, - "requires": { - "@babel/helper-explode-assignable-expression": "^7.16.0", - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.16.3", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.3.tgz", - "integrity": "sha512-vKsoSQAyBmxS35JUOOt+07cLc6Nk/2ljLIHwmq2/NM6hdioUaqEXq/S+nXvbvXbZkNDlWOymPanJGOc4CBjSJA==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.16.0", - "@babel/helper-validator-option": "^7.14.5", - "browserslist": "^4.17.5", - "semver": "^6.3.0" - }, - "dependencies": { - "caniuse-lite": { - "version": "1.0.30001282", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001282.tgz", - "integrity": "sha512-YhF/hG6nqBEllymSIjLtR2iWDDnChvhnVJqp+vloyt2tEHFG1yBR+ac2B/rOw0qOK0m0lEXU2dv4E/sMk5P9Kg==" - }, - "electron-to-chromium": { - "version": "1.3.901", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.901.tgz", - "integrity": "sha512-ToJdV2vzwT2jeAsw8zIggTFllJ4Kxvwghk39AhJEHHlIxor10wsFI3wo69p8nFc0s/ATWBqugPv/k3nW4Y9Mww==" - }, - "node-releases": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", - "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==" - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "@babel/helper-create-class-features-plugin": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.0.tgz", - "integrity": "sha512-XLwWvqEaq19zFlF5PTgOod4bUA+XbkR4WLQBct1bkzmxJGB0ZEJaoKF4c8cgH9oBtCDuYJ8BP5NB9uFiEgO5QA==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-member-expression-to-functions": "^7.16.0", - "@babel/helper-optimise-call-expression": "^7.16.0", - "@babel/helper-replace-supers": "^7.16.0", - "@babel/helper-split-export-declaration": "^7.16.0" - } - }, - "@babel/helper-create-regexp-features-plugin": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.0.tgz", - "integrity": "sha512-3DyG0zAFAZKcOp7aVr33ddwkxJ0Z0Jr5V99y3I690eYLpukJsJvAbzTy1ewoCqsML8SbIrjH14Jc/nSQ4TvNPA==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "regexpu-core": "^4.7.1" - } - }, - "@babel/helper-define-polyfill-provider": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.0.tgz", - "integrity": "sha512-7hfT8lUljl/tM3h+izTX/pO3W3frz2ok6Pk+gzys8iJqDfZrZy2pXjRTZAvG2YmfHun1X4q8/UZRLatMfqc5Tg==", - "dev": true, - "requires": { - "@babel/helper-compilation-targets": "^7.13.0", - "@babel/helper-module-imports": "^7.12.13", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/traverse": "^7.13.0", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2", - "semver": "^6.1.2" - }, - "dependencies": { - "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "dev": true, - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "@babel/helper-explode-assignable-expression": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.0.tgz", - "integrity": "sha512-Hk2SLxC9ZbcOhLpg/yMznzJ11W++lg5GMbxt1ev6TXUiJB0N42KPC+7w8a+eWGuqDnUYuwStJoZHM7RgmIOaGQ==", - "dev": true, - "requires": { - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-function-name": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.0.tgz", - "integrity": "sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.16.0", - "@babel/template": "^7.16.0", - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz", - "integrity": "sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ==", - "dev": true, - "requires": { - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.0.tgz", - "integrity": "sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg==", - "dev": true, - "requires": { - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.0.tgz", - "integrity": "sha512-bsjlBFPuWT6IWhl28EdrQ+gTvSvj5tqVP5Xeftp07SEuz5pLnsXZuDkDD3Rfcxy0IsHmbZ+7B2/9SHzxO0T+sQ==", - "dev": true, - "requires": { - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-module-imports": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz", - "integrity": "sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg==", - "dev": true, - "requires": { - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-module-transforms": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.0.tgz", - "integrity": "sha512-My4cr9ATcaBbmaEa8M0dZNA74cfI6gitvUAskgDtAFmAqyFKDSHQo5YstxPbN+lzHl2D9l/YOEFqb2mtUh4gfA==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.16.0", - "@babel/helper-replace-supers": "^7.16.0", - "@babel/helper-simple-access": "^7.16.0", - "@babel/helper-split-export-declaration": "^7.16.0", - "@babel/helper-validator-identifier": "^7.15.7", - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.0", - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.0.tgz", - "integrity": "sha512-SuI467Gi2V8fkofm2JPnZzB/SUuXoJA5zXe/xzyPP2M04686RzFKFHPK6HDVN6JvWBIEW8tt9hPR7fXdn2Lgpw==", - "dev": true, - "requires": { - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", - "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", - "dev": true - }, - "@babel/helper-remap-async-to-generator": { - "version": "7.16.4", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.4.tgz", - "integrity": "sha512-vGERmmhR+s7eH5Y/cp8PCVzj4XEjerq8jooMfxFdA5xVtAk9Sh4AQsrWgiErUEBjtGrBtOFKDUcWQFW4/dFwMA==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-wrap-function": "^7.16.0", - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-replace-supers": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.0.tgz", - "integrity": "sha512-TQxuQfSCdoha7cpRNJvfaYxxxzmbxXw/+6cS7V02eeDYyhxderSoMVALvwupA54/pZcOTtVeJ0xccp1nGWladA==", - "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.16.0", - "@babel/helper-optimise-call-expression": "^7.16.0", - "@babel/traverse": "^7.16.0", - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-simple-access": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.0.tgz", - "integrity": "sha512-o1rjBT/gppAqKsYfUdfHq5Rk03lMQrkPHG1OWzHWpLgVXRH4HnMM9Et9CVdIqwkCQlobnGHEJMsgWP/jE1zUiw==", - "dev": true, - "requires": { - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz", - "integrity": "sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw==", - "dev": true, - "requires": { - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz", - "integrity": "sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw==", - "dev": true, - "requires": { - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", - "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", - "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", - "dev": true - }, - "@babel/helper-wrap-function": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.16.0.tgz", - "integrity": "sha512-VVMGzYY3vkWgCJML+qVLvGIam902mJW0FvT7Avj1zEe0Gn7D93aWdLblYARTxEw+6DhZmtzhBM2zv0ekE5zg1g==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.16.0", - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.0", - "@babel/types": "^7.16.0" - } - }, - "@babel/helpers": { - "version": "7.16.3", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.3.tgz", - "integrity": "sha512-Xn8IhDlBPhvYTvgewPKawhADichOsbkZuzN7qz2BusOM0brChsyXMDJvldWaYMMUNiCQdQzNEioXTp3sC8Nt8w==", - "dev": true, - "requires": { - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.3", - "@babel/types": "^7.16.0" - } - }, - "@babel/highlight": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.0.tgz", - "integrity": "sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.15.7", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - } - } - }, - "@babel/parser": { - "version": "7.16.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.4.tgz", - "integrity": "sha512-6V0qdPUaiVHH3RtZeLIsc+6pDhbYzHR8ogA8w+f+Wc77DuXto19g2QUwveINoS34Uw+W8/hQDGJCx+i4n7xcng==", - "dev": true - }, - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.16.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.2.tgz", - "integrity": "sha512-h37CvpLSf8gb2lIJ2CgC3t+EjFbi0t8qS7LCS1xcJIlEXE4czlofwaW7W1HA8zpgOCzI9C1nmoqNR1zWkk0pQg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.0.tgz", - "integrity": "sha512-4tcFwwicpWTrpl9qjf7UsoosaArgImF85AxqCRZlgc3IQDvkUHjJpruXAL58Wmj+T6fypWTC/BakfEkwIL/pwA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", - "@babel/plugin-proposal-optional-chaining": "^7.16.0" - } - }, - "@babel/plugin-proposal-async-generator-functions": { - "version": "7.16.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.4.tgz", - "integrity": "sha512-/CUekqaAaZCQHleSK/9HajvcD/zdnJiKRiuUFq8ITE+0HsPzquf53cpFiqAwl/UfmJbR6n5uGPQSPdrmKOvHHg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-remap-async-to-generator": "^7.16.4", - "@babel/plugin-syntax-async-generators": "^7.8.4" - } - }, - "@babel/plugin-proposal-class-properties": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.0.tgz", - "integrity": "sha512-mCF3HcuZSY9Fcx56Lbn+CGdT44ioBMMvjNVldpKtj8tpniETdLjnxdHI1+sDWXIM1nNt+EanJOZ3IG9lzVjs7A==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.16.0", - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-proposal-class-static-block": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.16.0.tgz", - "integrity": "sha512-mAy3sdcY9sKAkf3lQbDiv3olOfiLqI51c9DR9b19uMoR2Z6r5pmGl7dfNFqEvqOyqbf1ta4lknK4gc5PJn3mfA==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.16.0", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - } - }, - "@babel/plugin-proposal-dynamic-import": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.0.tgz", - "integrity": "sha512-QGSA6ExWk95jFQgwz5GQ2Dr95cf7eI7TKutIXXTb7B1gCLTCz5hTjFTQGfLFBBiC5WSNi7udNwWsqbbMh1c4yQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - } - }, - "@babel/plugin-proposal-export-namespace-from": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.0.tgz", - "integrity": "sha512-CjI4nxM/D+5wCnhD11MHB1AwRSAYeDT+h8gCdcVJZ/OK7+wRzFsf7PFPWVpVpNRkHMmMkQWAHpTq+15IXQ1diA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - } - }, - "@babel/plugin-proposal-json-strings": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.0.tgz", - "integrity": "sha512-kouIPuiv8mSi5JkEhzApg5Gn6hFyKPnlkO0a9YSzqRurH8wYzSlf6RJdzluAsbqecdW5pBvDJDfyDIUR/vLxvg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-json-strings": "^7.8.3" - } - }, - "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.0.tgz", - "integrity": "sha512-pbW0fE30sVTYXXm9lpVQQ/Vc+iTeQKiXlaNRZPPN2A2VdlWyAtsUrsQ3xydSlDW00TFMK7a8m3cDTkBF5WnV3Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - } - }, - "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.0.tgz", - "integrity": "sha512-3bnHA8CAFm7cG93v8loghDYyQ8r97Qydf63BeYiGgYbjKKB/XP53W15wfRC7dvKfoiJ34f6Rbyyx2btExc8XsQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - } - }, - "@babel/plugin-proposal-numeric-separator": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.0.tgz", - "integrity": "sha512-FAhE2I6mjispy+vwwd6xWPyEx3NYFS13pikDBWUAFGZvq6POGs5eNchw8+1CYoEgBl9n11I3NkzD7ghn25PQ9Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - } - }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.0.tgz", - "integrity": "sha512-LU/+jp89efe5HuWJLmMmFG0+xbz+I2rSI7iLc1AlaeSMDMOGzWlc5yJrMN1d04osXN4sSfpo4O+azkBNBes0jg==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.16.0", - "@babel/helper-compilation-targets": "^7.16.0", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.16.0" - } - }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.0.tgz", - "integrity": "sha512-kicDo0A/5J0nrsCPbn89mTG3Bm4XgYi0CZtvex9Oyw7gGZE3HXGD0zpQNH+mo+tEfbo8wbmMvJftOwpmPy7aVw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - } - }, - "@babel/plugin-proposal-optional-chaining": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.0.tgz", - "integrity": "sha512-Y4rFpkZODfHrVo70Uaj6cC1JJOt3Pp0MdWSwIKtb8z1/lsjl9AmnB7ErRFV+QNGIfcY1Eruc2UMx5KaRnXjMyg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - } - }, - "@babel/plugin-proposal-private-methods": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.0.tgz", - "integrity": "sha512-IvHmcTHDFztQGnn6aWq4t12QaBXTKr1whF/dgp9kz84X6GUcwq9utj7z2wFCUfeOup/QKnOlt2k0zxkGFx9ubg==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.16.0", - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-proposal-private-property-in-object": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.0.tgz", - "integrity": "sha512-3jQUr/HBbMVZmi72LpjQwlZ55i1queL8KcDTQEkAHihttJnAPrcvG9ZNXIfsd2ugpizZo595egYV6xy+pv4Ofw==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-create-class-features-plugin": "^7.16.0", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - } - }, - "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.0.tgz", - "integrity": "sha512-ti7IdM54NXv29cA4+bNNKEMS4jLMCbJgl+Drv+FgYy0erJLAxNAIXcNjNjrRZEcWq0xJHsNVwQezskMFpF8N9g==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.16.0", - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.3" - } - }, - "@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-typescript": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.0.tgz", - "integrity": "sha512-Xv6mEXqVdaqCBfJFyeab0fH2DnUoMsDmhamxsSi4j8nLd4Vtw213WMJr55xxqipC/YVWyPY3K0blJncPYji+dQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-arrow-functions": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.0.tgz", - "integrity": "sha512-vIFb5250Rbh7roWARvCLvIJ/PtAU5Lhv7BtZ1u24COwpI9Ypjsh+bZcKk6rlIyalK+r0jOc1XQ8I4ovNxNrWrA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-async-to-generator": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.0.tgz", - "integrity": "sha512-PbIr7G9kR8tdH6g8Wouir5uVjklETk91GMVSUq+VaOgiinbCkBP6Q7NN/suM/QutZkMJMvcyAriogcYAdhg8Gw==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.16.0", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-remap-async-to-generator": "^7.16.0" - } - }, - "@babel/plugin-transform-block-scoped-functions": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.0.tgz", - "integrity": "sha512-V14As3haUOP4ZWrLJ3VVx5rCnrYhMSHN/jX7z6FAt5hjRkLsb0snPCmJwSOML5oxkKO4FNoNv7V5hw/y2bjuvg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-block-scoping": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.0.tgz", - "integrity": "sha512-27n3l67/R3UrXfizlvHGuTwsRIFyce3D/6a37GRxn28iyTPvNXaW4XvznexRh1zUNLPjbLL22Id0XQElV94ruw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-classes": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.0.tgz", - "integrity": "sha512-HUxMvy6GtAdd+GKBNYDWCIA776byUQH8zjnfjxwT1P1ARv/wFu8eBDpmXQcLS/IwRtrxIReGiplOwMeyO7nsDQ==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-optimise-call-expression": "^7.16.0", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-replace-supers": "^7.16.0", - "@babel/helper-split-export-declaration": "^7.16.0", - "globals": "^11.1.0" - }, - "dependencies": { - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - } - } - }, - "@babel/plugin-transform-computed-properties": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.0.tgz", - "integrity": "sha512-63l1dRXday6S8V3WFY5mXJwcRAnPYxvFfTlt67bwV1rTyVTM5zrp0DBBb13Kl7+ehkCVwIZPumPpFP/4u70+Tw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-destructuring": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.0.tgz", - "integrity": "sha512-Q7tBUwjxLTsHEoqktemHBMtb3NYwyJPTJdM+wDwb0g8PZ3kQUIzNvwD5lPaqW/p54TXBc/MXZu9Jr7tbUEUM8Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-dotall-regex": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.0.tgz", - "integrity": "sha512-FXlDZfQeLILfJlC6I1qyEwcHK5UpRCFkaoVyA1nk9A1L1Yu583YO4un2KsLBsu3IJb4CUbctZks8tD9xPQubLw==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.16.0", - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-duplicate-keys": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.0.tgz", - "integrity": "sha512-LIe2kcHKAZOJDNxujvmp6z3mfN6V9lJxubU4fJIGoQCkKe3Ec2OcbdlYP+vW++4MpxwG0d1wSDOJtQW5kLnkZQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-exponentiation-operator": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.0.tgz", - "integrity": "sha512-OwYEvzFI38hXklsrbNivzpO3fh87skzx8Pnqi4LoSYeav0xHlueSoCJrSgTPfnbyzopo5b3YVAJkFIcUpK2wsw==", - "dev": true, - "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.16.0", - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-for-of": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.0.tgz", - "integrity": "sha512-5QKUw2kO+GVmKr2wMYSATCTTnHyscl6sxFRAY+rvN7h7WB0lcG0o4NoV6ZQU32OZGVsYUsfLGgPQpDFdkfjlJQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-function-name": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.0.tgz", - "integrity": "sha512-lBzMle9jcOXtSOXUpc7tvvTpENu/NuekNJVova5lCCWCV9/U1ho2HH2y0p6mBg8fPm/syEAbfaaemYGOHCY3mg==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-literals": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.0.tgz", - "integrity": "sha512-gQDlsSF1iv9RU04clgXqRjrPyyoJMTclFt3K1cjLmTKikc0s/6vE3hlDeEVC71wLTRu72Fq7650kABrdTc2wMQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-member-expression-literals": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.0.tgz", - "integrity": "sha512-WRpw5HL4Jhnxw8QARzRvwojp9MIE7Tdk3ez6vRyUk1MwgjJN0aNpRoXainLR5SgxmoXx/vsXGZ6OthP6t/RbUg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-modules-amd": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.0.tgz", - "integrity": "sha512-rWFhWbCJ9Wdmzln1NmSCqn7P0RAD+ogXG/bd9Kg5c7PKWkJtkiXmYsMBeXjDlzHpVTJ4I/hnjs45zX4dEv81xw==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.16.0", - "@babel/helper-plugin-utils": "^7.14.5", - "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.0.tgz", - "integrity": "sha512-Dzi+NWqyEotgzk/sb7kgQPJQf7AJkQBWsVp1N6JWc1lBVo0vkElUnGdr1PzUBmfsCCN5OOFya3RtpeHk15oLKQ==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.16.0", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-simple-access": "^7.16.0", - "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.0.tgz", - "integrity": "sha512-yuGBaHS3lF1m/5R+6fjIke64ii5luRUg97N2wr+z1sF0V+sNSXPxXDdEEL/iYLszsN5VKxVB1IPfEqhzVpiqvg==", - "dev": true, - "requires": { - "@babel/helper-hoist-variables": "^7.16.0", - "@babel/helper-module-transforms": "^7.16.0", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-validator-identifier": "^7.15.7", - "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "@babel/plugin-transform-modules-umd": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.0.tgz", - "integrity": "sha512-nx4f6no57himWiHhxDM5pjwhae5vLpTK2zCnDH8+wNLJy0TVER/LJRHl2bkt6w9Aad2sPD5iNNoUpY3X9sTGDg==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.16.0", - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.0.tgz", - "integrity": "sha512-LogN88uO+7EhxWc8WZuQ8vxdSyVGxhkh8WTC3tzlT8LccMuQdA81e9SGV6zY7kY2LjDhhDOFdQVxdGwPyBCnvg==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.16.0" - } - }, - "@babel/plugin-transform-new-target": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.0.tgz", - "integrity": "sha512-fhjrDEYv2DBsGN/P6rlqakwRwIp7rBGLPbrKxwh7oVt5NNkIhZVOY2GRV+ULLsQri1bDqwDWnU3vhlmx5B2aCw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-object-super": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.0.tgz", - "integrity": "sha512-fds+puedQHn4cPLshoHcR1DTMN0q1V9ou0mUjm8whx9pGcNvDrVVrgw+KJzzCaiTdaYhldtrUps8DWVMgrSEyg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-replace-supers": "^7.16.0" - } - }, - "@babel/plugin-transform-parameters": { - "version": "7.16.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.3.tgz", - "integrity": "sha512-3MaDpJrOXT1MZ/WCmkOFo7EtmVVC8H4EUZVrHvFOsmwkk4lOjQj8rzv8JKUZV4YoQKeoIgk07GO+acPU9IMu/w==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-property-literals": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.0.tgz", - "integrity": "sha512-XLldD4V8+pOqX2hwfWhgwXzGdnDOThxaNTgqagOcpBgIxbUvpgU2FMvo5E1RyHbk756WYgdbS0T8y0Cj9FKkWQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-regenerator": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.0.tgz", - "integrity": "sha512-JAvGxgKuwS2PihiSFaDrp94XOzzTUeDeOQlcKzVAyaPap7BnZXK/lvMDiubkPTdotPKOIZq9xWXWnggUMYiExg==", - "dev": true, - "requires": { - "regenerator-transform": "^0.14.2" - } - }, - "@babel/plugin-transform-reserved-words": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.0.tgz", - "integrity": "sha512-Dgs8NNCehHSvXdhEhln8u/TtJxfVwGYCgP2OOr5Z3Ar+B+zXicEOKNTyc+eca2cuEOMtjW6m9P9ijOt8QdqWkg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-shorthand-properties": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.0.tgz", - "integrity": "sha512-iVb1mTcD8fuhSv3k99+5tlXu5N0v8/DPm2mO3WACLG6al1CGZH7v09HJyUb1TtYl/Z+KrM6pHSIJdZxP5A+xow==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-spread": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.0.tgz", - "integrity": "sha512-Ao4MSYRaLAQczZVp9/7E7QHsCuK92yHRrmVNRe/SlEJjhzivq0BSn8mEraimL8wizHZ3fuaHxKH0iwzI13GyGg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0" - } - }, - "@babel/plugin-transform-sticky-regex": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.0.tgz", - "integrity": "sha512-/ntT2NljR9foobKk4E/YyOSwcGUXtYWv5tinMK/3RkypyNBNdhHUaq6Orw5DWq9ZcNlS03BIlEALFeQgeVAo4Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-template-literals": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.0.tgz", - "integrity": "sha512-Rd4Ic89hA/f7xUSJQk5PnC+4so50vBoBfxjdQAdvngwidM8jYIBVxBZ/sARxD4e0yMXRbJVDrYf7dyRtIIKT6Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-typeof-symbol": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.0.tgz", - "integrity": "sha512-++V2L8Bdf4vcaHi2raILnptTBjGEFxn5315YU+e8+EqXIucA+q349qWngCLpUYqqv233suJ6NOienIVUpS9cqg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-unicode-escapes": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.0.tgz", - "integrity": "sha512-VFi4dhgJM7Bpk8lRc5CMaRGlKZ29W9C3geZjt9beuzSUrlJxsNwX7ReLwaL6WEvsOf2EQkyIJEPtF8EXjB/g2A==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.0.tgz", - "integrity": "sha512-jHLK4LxhHjvCeZDWyA9c+P9XH1sOxRd1RO9xMtDVRAOND/PczPqizEtVdx4TQF/wyPaewqpT+tgQFYMnN/P94A==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.16.0", - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/preset-env": { - "version": "7.16.4", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.16.4.tgz", - "integrity": "sha512-v0QtNd81v/xKj4gNKeuAerQ/azeNn/G1B1qMLeXOcV8+4TWlD2j3NV1u8q29SDFBXx/NBq5kyEAO+0mpRgacjA==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.16.4", - "@babel/helper-compilation-targets": "^7.16.3", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-validator-option": "^7.14.5", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.16.2", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.16.0", - "@babel/plugin-proposal-async-generator-functions": "^7.16.4", - "@babel/plugin-proposal-class-properties": "^7.16.0", - "@babel/plugin-proposal-class-static-block": "^7.16.0", - "@babel/plugin-proposal-dynamic-import": "^7.16.0", - "@babel/plugin-proposal-export-namespace-from": "^7.16.0", - "@babel/plugin-proposal-json-strings": "^7.16.0", - "@babel/plugin-proposal-logical-assignment-operators": "^7.16.0", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.0", - "@babel/plugin-proposal-numeric-separator": "^7.16.0", - "@babel/plugin-proposal-object-rest-spread": "^7.16.0", - "@babel/plugin-proposal-optional-catch-binding": "^7.16.0", - "@babel/plugin-proposal-optional-chaining": "^7.16.0", - "@babel/plugin-proposal-private-methods": "^7.16.0", - "@babel/plugin-proposal-private-property-in-object": "^7.16.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.16.0", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.16.0", - "@babel/plugin-transform-async-to-generator": "^7.16.0", - "@babel/plugin-transform-block-scoped-functions": "^7.16.0", - "@babel/plugin-transform-block-scoping": "^7.16.0", - "@babel/plugin-transform-classes": "^7.16.0", - "@babel/plugin-transform-computed-properties": "^7.16.0", - "@babel/plugin-transform-destructuring": "^7.16.0", - "@babel/plugin-transform-dotall-regex": "^7.16.0", - "@babel/plugin-transform-duplicate-keys": "^7.16.0", - "@babel/plugin-transform-exponentiation-operator": "^7.16.0", - "@babel/plugin-transform-for-of": "^7.16.0", - "@babel/plugin-transform-function-name": "^7.16.0", - "@babel/plugin-transform-literals": "^7.16.0", - "@babel/plugin-transform-member-expression-literals": "^7.16.0", - "@babel/plugin-transform-modules-amd": "^7.16.0", - "@babel/plugin-transform-modules-commonjs": "^7.16.0", - "@babel/plugin-transform-modules-systemjs": "^7.16.0", - "@babel/plugin-transform-modules-umd": "^7.16.0", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.16.0", - "@babel/plugin-transform-new-target": "^7.16.0", - "@babel/plugin-transform-object-super": "^7.16.0", - "@babel/plugin-transform-parameters": "^7.16.3", - "@babel/plugin-transform-property-literals": "^7.16.0", - "@babel/plugin-transform-regenerator": "^7.16.0", - "@babel/plugin-transform-reserved-words": "^7.16.0", - "@babel/plugin-transform-shorthand-properties": "^7.16.0", - "@babel/plugin-transform-spread": "^7.16.0", - "@babel/plugin-transform-sticky-regex": "^7.16.0", - "@babel/plugin-transform-template-literals": "^7.16.0", - "@babel/plugin-transform-typeof-symbol": "^7.16.0", - "@babel/plugin-transform-unicode-escapes": "^7.16.0", - "@babel/plugin-transform-unicode-regex": "^7.16.0", - "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.16.0", - "babel-plugin-polyfill-corejs2": "^0.3.0", - "babel-plugin-polyfill-corejs3": "^0.4.0", - "babel-plugin-polyfill-regenerator": "^0.3.0", - "core-js-compat": "^3.19.1", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "@babel/preset-modules": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", - "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - } - }, - "@babel/runtime": { - "version": "7.13.10", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz", - "integrity": "sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==", - "requires": { - "regenerator-runtime": "^0.13.4" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.13.7", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", - "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" - } - } - }, - "@babel/template": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.0.tgz", - "integrity": "sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.16.0", - "@babel/parser": "^7.16.0", - "@babel/types": "^7.16.0" - } - }, - "@babel/traverse": { - "version": "7.16.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.3.tgz", - "integrity": "sha512-eolumr1vVMjqevCpwVO99yN/LoGL0EyHiLO5I043aYQvwOJ9eR5UsZSClHVCzfhBduMAsSzgA/6AyqPjNayJag==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.16.0", - "@babel/generator": "^7.16.0", - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-hoist-variables": "^7.16.0", - "@babel/helper-split-export-declaration": "^7.16.0", - "@babel/parser": "^7.16.3", - "@babel/types": "^7.16.0", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "dependencies": { - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - } - } - }, - "@babel/types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.0.tgz", - "integrity": "sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.15.7", - "to-fast-properties": "^2.0.0" - } - }, - "@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "@chevrotain/types": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-9.1.0.tgz", - "integrity": "sha512-3hbCD1CThkv9gnaSIPq0GUXwKni68e0ph6jIHwCvcWiQ4JB2xi8bFxBain0RF04qHUWuDjgnZLj4rLgimuGO+g==", - "dev": true - }, - "@chevrotain/utils": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-9.1.0.tgz", - "integrity": "sha512-llLJZ8OAlZrjGlBvamm6Zdo/HmGAcCLq5gx7cSwUX8No+n/8ip+oaC4x33IdZIif8+Rh5dQUIZXmfbSghiOmNQ==", - "dev": true - }, - "@dabh/diagnostics": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.2.tgz", - "integrity": "sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q==", - "dev": true, - "requires": { - "colorspace": "1.1.x", - "enabled": "2.0.x", - "kuler": "^2.0.0" - } - }, - "@discoveryjs/json-ext": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.5.tgz", - "integrity": "sha512-6nFkfkmSeV/rqSaS4oWHgmpnYw194f6hmWF5is6b0J1naJZoiD0NTc9AiUwPHvWsowkjuHErCZT1wa0jg+BLIA==", - "dev": true - }, - "@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - } - } - }, - "@fortawesome/fontawesome-common-types": { - "version": "0.2.36", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.36.tgz", - "integrity": "sha512-a/7BiSgobHAgBWeN7N0w+lAhInrGxksn13uK7231n2m8EDPE3BMCl9NZLTGrj9ZXfCmC6LM0QLqXidIizVQ6yg==" - }, - "@fortawesome/fontawesome-svg-core": { - "version": "1.2.36", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.36.tgz", - "integrity": "sha512-YUcsLQKYb6DmaJjIHdDWpBIGCcyE/W+p/LMGvjQem55Mm2XWVAP5kWTMKWLv9lwpCVjpLxPyOMOyUocP1GxrtA==", - "requires": { - "@fortawesome/fontawesome-common-types": "^0.2.36" - } - }, - "@fortawesome/free-solid-svg-icons": { - "version": "5.15.4", - "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.4.tgz", - "integrity": "sha512-JLmQfz6tdtwxoihXLg6lT78BorrFyCf59SAwBM6qV/0zXyVeDygJVb3fk+j5Qat+Yvcxp1buLTY5iDh1ZSAQ8w==", - "requires": { - "@fortawesome/fontawesome-common-types": "^0.2.36" - } - }, - "@fortawesome/react-fontawesome": { - "version": "0.1.16", - "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.16.tgz", - "integrity": "sha512-aLmzDwC9rEOAJv2UJdMns89VZR5Ry4IHu5dQQh24Z/lWKEm44lfQr1UNalZlkUaQN8d155tNh+CS7ntntj1VMA==", - "requires": { - "prop-types": "^15.7.2" - } - }, - "@gar/promisify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.2.tgz", - "integrity": "sha512-82cpyJyKRoQoRi+14ibCeGPu0CwypgtBAdBhq1WfvagpCZNKqwXbKwXllYSMG91DhmG4jt9gN8eP6lGOtozuaw==", - "dev": true - }, - "@hapi/hoek": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.1.tgz", - "integrity": "sha512-gfta+H8aziZsm8pZa0vj04KO6biEiisppNgA1kbJvFrrWu9Vm7eaUEy76DIxsuTaWvti5fkJVhllWc6ZTE+Mdw==", - "dev": true - }, - "@hapi/topo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", - "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", - "dev": true, - "requires": { - "@hapi/hoek": "^9.0.0" - } - }, - "@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - } - }, - "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "@hypnosphi/create-react-context": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@hypnosphi/create-react-context/-/create-react-context-0.3.1.tgz", - "integrity": "sha512-V1klUed202XahrWJLLOT3EXNeCpFHCcJntdFGI15ntCwau+jfT386w7OFTMaCqOgXUH1fa0w/I1oZs+i/Rfr0A==", - "requires": { - "gud": "^1.0.0", - "warning": "^4.0.3" - } - }, - "@isaacs/string-locale-compare": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@isaacs/string-locale-compare/-/string-locale-compare-1.1.0.tgz", - "integrity": "sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ==", - "dev": true - }, - "@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } - } - }, - "@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true - }, - "@jest/console": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.3.1.tgz", - "integrity": "sha512-RkFNWmv0iui+qsOr/29q9dyfKTTT5DCuP31kUwg7rmOKPT/ozLeGLKJKVIiOfbiKyleUZKIrHwhmiZWVe8IMdw==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^27.3.1", - "jest-util": "^27.3.1", - "slash": "^3.0.0" - } - }, - "@jest/core": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.3.1.tgz", - "integrity": "sha512-DMNE90RR5QKx0EA+wqe3/TNEwiRpOkhshKNxtLxd4rt3IZpCt+RSL+FoJsGeblRZmqdK4upHA/mKKGPPRAifhg==", - "dev": true, - "requires": { - "@jest/console": "^27.3.1", - "@jest/reporters": "^27.3.1", - "@jest/test-result": "^27.3.1", - "@jest/transform": "^27.3.1", - "@jest/types": "^27.2.5", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-changed-files": "^27.3.0", - "jest-config": "^27.3.1", - "jest-haste-map": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.3.1", - "jest-resolve-dependencies": "^27.3.1", - "jest-runner": "^27.3.1", - "jest-runtime": "^27.3.1", - "jest-snapshot": "^27.3.1", - "jest-util": "^27.3.1", - "jest-validate": "^27.3.1", - "jest-watcher": "^27.3.1", - "micromatch": "^4.0.4", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "requires": { - "type-fest": "^0.21.3" - } - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true - } - } - }, - "@jest/environment": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.3.1.tgz", - "integrity": "sha512-BCKCj4mOVLme6Tanoyc9k0ultp3pnmuyHw73UHRPeeZxirsU/7E3HC4le/VDb/SMzE1JcPnto+XBKFOcoiJzVw==", - "dev": true, - "requires": { - "@jest/fake-timers": "^27.3.1", - "@jest/types": "^27.2.5", - "@types/node": "*", - "jest-mock": "^27.3.0" - } - }, - "@jest/fake-timers": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.3.1.tgz", - "integrity": "sha512-M3ZFgwwlqJtWZ+QkBG5NmC23A9w+A6ZxNsO5nJxJsKYt4yguBd3i8TpjQz5NfCX91nEve1KqD9RA2Q+Q1uWqoA==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "@sinonjs/fake-timers": "^8.0.1", - "@types/node": "*", - "jest-message-util": "^27.3.1", - "jest-mock": "^27.3.0", - "jest-util": "^27.3.1" - } - }, - "@jest/globals": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.3.1.tgz", - "integrity": "sha512-Q651FWiWQAIFiN+zS51xqhdZ8g9b88nGCobC87argAxA7nMfNQq0Q0i9zTfQYgLa6qFXk2cGANEqfK051CZ8Pg==", - "dev": true, - "requires": { - "@jest/environment": "^27.3.1", - "@jest/types": "^27.2.5", - "expect": "^27.3.1" - } - }, - "@jest/reporters": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.3.1.tgz", - "integrity": "sha512-m2YxPmL9Qn1emFVgZGEiMwDntDxRRQ2D58tiDQlwYTg5GvbFOKseYCcHtn0WsI8CG4vzPglo3nqbOiT8ySBT/w==", - "dev": true, - "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.3.1", - "@jest/test-result": "^27.3.1", - "@jest/transform": "^27.3.1", - "@jest/types": "^27.2.5", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.4", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.3", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "jest-haste-map": "^27.3.1", - "jest-resolve": "^27.3.1", - "jest-util": "^27.3.1", - "jest-worker": "^27.3.1", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^8.1.0" - } - }, - "@jest/source-map": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.0.6.tgz", - "integrity": "sha512-Fek4mi5KQrqmlY07T23JRi0e7Z9bXTOOD86V/uS0EIW4PClvPDqZOyFlLpNJheS6QI0FNX1CgmPjtJ4EA/2M+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" - } - }, - "@jest/test-result": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.3.1.tgz", - "integrity": "sha512-mLn6Thm+w2yl0opM8J/QnPTqrfS4FoXsXF2WIWJb2O/GBSyResL71BRuMYbYRsGt7ELwS5JGcEcGb52BNrumgg==", - "dev": true, - "requires": { - "@jest/console": "^27.3.1", - "@jest/types": "^27.2.5", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/test-sequencer": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.3.1.tgz", - "integrity": "sha512-siySLo07IMEdSjA4fqEnxfIX8lB/lWYsBPwNFtkOvsFQvmBrL3yj3k3uFNZv/JDyApTakRpxbKLJ3CT8UGVCrA==", - "dev": true, - "requires": { - "@jest/test-result": "^27.3.1", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.1", - "jest-runtime": "^27.3.1" - } - }, - "@jest/transform": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.3.1.tgz", - "integrity": "sha512-3fSvQ02kuvjOI1C1ssqMVBKJpZf6nwoCiSu00zAKh5nrp3SptNtZy/8s5deayHnqxhjD9CWDJ+yqQwuQ0ZafXQ==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^27.2.5", - "babel-plugin-istanbul": "^6.0.0", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.1", - "jest-regex-util": "^27.0.6", - "jest-util": "^27.3.1", - "micromatch": "^4.0.4", - "pirates": "^4.0.1", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - } - }, - "@jest/types": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.2.5.tgz", - "integrity": "sha512-nmuM4VuDtCZcY+eTpw+0nvstwReMsjPoj7ZR80/BbixulhLaiX+fbv8oeLW8WZlJMcsGQsTmMKT/iTZu1Uy/lQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - } - }, - "@kwsites/file-exists": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", - "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", - "dev": true, - "requires": { - "debug": "^4.1.1" - } - }, - "@kwsites/promise-deferred": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", - "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", - "dev": true - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@npmcli/arborist": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/@npmcli/arborist/-/arborist-2.10.0.tgz", - "integrity": "sha512-CLnD+zXG9oijEEzViimz8fbOoFVb7hoypiaf7p6giJhvYtrxLAyY3cZAMPIFQvsG731+02eMDp3LqVBNo7BaZA==", - "dev": true, - "requires": { - "@isaacs/string-locale-compare": "^1.0.1", - "@npmcli/installed-package-contents": "^1.0.7", - "@npmcli/map-workspaces": "^1.0.2", - "@npmcli/metavuln-calculator": "^1.1.0", - "@npmcli/move-file": "^1.1.0", - "@npmcli/name-from-folder": "^1.0.1", - "@npmcli/node-gyp": "^1.0.1", - "@npmcli/package-json": "^1.0.1", - "@npmcli/run-script": "^1.8.2", - "bin-links": "^2.2.1", - "cacache": "^15.0.3", - "common-ancestor-path": "^1.0.1", - "json-parse-even-better-errors": "^2.3.1", - "json-stringify-nice": "^1.1.4", - "mkdirp": "^1.0.4", - "mkdirp-infer-owner": "^2.0.0", - "npm-install-checks": "^4.0.0", - "npm-package-arg": "^8.1.5", - "npm-pick-manifest": "^6.1.0", - "npm-registry-fetch": "^11.0.0", - "pacote": "^11.3.5", - "parse-conflict-json": "^1.1.1", - "proc-log": "^1.0.0", - "promise-all-reject-late": "^1.0.0", - "promise-call-limit": "^1.0.1", - "read-package-json-fast": "^2.0.2", - "readdir-scoped-modules": "^1.1.0", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "ssri": "^8.0.1", - "treeverse": "^1.0.4", - "walk-up-path": "^1.0.0" - }, - "dependencies": { - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - } - } - }, - "@npmcli/fs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.0.0.tgz", - "integrity": "sha512-8ltnOpRR/oJbOp8vaGUnipOi3bqkcW+sLHFlyXIr08OGHmVJLB1Hn7QtGXbYcpVtH1gAYZTlmDXtE4YV0+AMMQ==", - "dev": true, - "requires": { - "@gar/promisify": "^1.0.1", - "semver": "^7.3.5" - } - }, - "@npmcli/git": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-2.1.0.tgz", - "integrity": "sha512-/hBFX/QG1b+N7PZBFs0bi+evgRZcK9nWBxQKZkGoXUT5hJSwl5c4d7y8/hm+NQZRPhQ67RzFaj5UM9YeyKoryw==", - "dev": true, - "requires": { - "@npmcli/promise-spawn": "^1.3.2", - "lru-cache": "^6.0.0", - "mkdirp": "^1.0.4", - "npm-pick-manifest": "^6.1.1", - "promise-inflight": "^1.0.1", - "promise-retry": "^2.0.1", - "semver": "^7.3.5", - "which": "^2.0.2" - }, - "dependencies": { - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - } - } - }, - "@npmcli/installed-package-contents": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-1.0.7.tgz", - "integrity": "sha512-9rufe0wnJusCQoLpV9ZPKIVP55itrM5BxOXs10DmdbRfgWtHy1LDyskbwRnBghuB0PrF7pNPOqREVtpz4HqzKw==", - "dev": true, - "requires": { - "npm-bundled": "^1.1.1", - "npm-normalize-package-bin": "^1.0.1" - } - }, - "@npmcli/map-workspaces": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@npmcli/map-workspaces/-/map-workspaces-1.0.4.tgz", - "integrity": "sha512-wVR8QxhyXsFcD/cORtJwGQodeeaDf0OxcHie8ema4VgFeqwYkFsDPnSrIRSytX8xR6nKPAH89WnwTcaU608b/Q==", - "dev": true, - "requires": { - "@npmcli/name-from-folder": "^1.0.1", - "glob": "^7.1.6", - "minimatch": "^3.0.4", - "read-package-json-fast": "^2.0.1" - } - }, - "@npmcli/metavuln-calculator": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@npmcli/metavuln-calculator/-/metavuln-calculator-1.1.1.tgz", - "integrity": "sha512-9xe+ZZ1iGVaUovBVFI9h3qW+UuECUzhvZPxK9RaEA2mjU26o5D0JloGYWwLYvQELJNmBdQB6rrpuN8jni6LwzQ==", - "dev": true, - "requires": { - "cacache": "^15.0.5", - "pacote": "^11.1.11", - "semver": "^7.3.2" - } - }, - "@npmcli/move-file": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", - "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", - "dev": true, - "requires": { - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" - }, - "dependencies": { - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - } - } - }, - "@npmcli/name-from-folder": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/name-from-folder/-/name-from-folder-1.0.1.tgz", - "integrity": "sha512-qq3oEfcLFwNfEYOQ8HLimRGKlD8WSeGEdtUa7hmzpR8Sa7haL1KVQrvgO6wqMjhWFFVjgtrh1gIxDz+P8sjUaA==", - "dev": true - }, - "@npmcli/node-gyp": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-1.0.3.tgz", - "integrity": "sha512-fnkhw+fmX65kiLqk6E3BFLXNC26rUhK90zVwe2yncPliVT/Qos3xjhTLE59Df8KnPlcwIERXKVlU1bXoUQ+liA==", - "dev": true - }, - "@npmcli/package-json": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-1.0.1.tgz", - "integrity": "sha512-y6jnu76E9C23osz8gEMBayZmaZ69vFOIk8vR1FJL/wbEJ54+9aVG9rLTjQKSXfgYZEr50nw1txBBFfBZZe+bYg==", - "dev": true, - "requires": { - "json-parse-even-better-errors": "^2.3.1" - } - }, - "@npmcli/promise-spawn": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-1.3.2.tgz", - "integrity": "sha512-QyAGYo/Fbj4MXeGdJcFzZ+FkDkomfRBrPM+9QYJSg+PxgAUL+LU3FneQk37rKR2/zjqkCV1BLHccX98wRXG3Sg==", - "dev": true, - "requires": { - "infer-owner": "^1.0.4" - } - }, - "@npmcli/run-script": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-1.8.6.tgz", - "integrity": "sha512-e42bVZnC6VluBZBAFEr3YrdqSspG3bgilyg4nSLBJ7TRGNCzxHa92XAHxQBLYg0BmgwO4b2mf3h/l5EkEWRn3g==", - "dev": true, - "requires": { - "@npmcli/node-gyp": "^1.0.2", - "@npmcli/promise-spawn": "^1.3.2", - "node-gyp": "^7.1.0", - "read-package-json-fast": "^2.0.1" - } - }, - "@octokit/auth-token": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz", - "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==", - "dev": true, - "requires": { - "@octokit/types": "^6.0.3" - } - }, - "@octokit/core": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz", - "integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==", - "dev": true, - "requires": { - "@octokit/auth-token": "^2.4.4", - "@octokit/graphql": "^4.5.8", - "@octokit/request": "^5.6.0", - "@octokit/request-error": "^2.0.5", - "@octokit/types": "^6.0.3", - "before-after-hook": "^2.2.0", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/endpoint": { - "version": "6.0.12", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", - "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", - "dev": true, - "requires": { - "@octokit/types": "^6.0.3", - "is-plain-object": "^5.0.0", - "universal-user-agent": "^6.0.0" - }, - "dependencies": { - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true - } - } - }, - "@octokit/graphql": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz", - "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==", - "dev": true, - "requires": { - "@octokit/request": "^5.6.0", - "@octokit/types": "^6.0.3", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/openapi-types": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.2.0.tgz", - "integrity": "sha512-PBsVO+15KSlGmiI8QAzaqvsNlZlrDlyAJYcrXBCvVUxCp7VnXjkwPoFHgjEJXx3WF9BAwkA6nfCUA7i9sODzKA==", - "dev": true - }, - "@octokit/plugin-paginate-rest": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.17.0.tgz", - "integrity": "sha512-tzMbrbnam2Mt4AhuyCHvpRkS0oZ5MvwwcQPYGtMv4tUa5kkzG58SVB0fcsLulOZQeRnOgdkZWkRUiyBlh0Bkyw==", - "dev": true, - "requires": { - "@octokit/types": "^6.34.0" - } - }, - "@octokit/plugin-request-log": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", - "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", - "dev": true - }, - "@octokit/plugin-rest-endpoint-methods": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.13.0.tgz", - "integrity": "sha512-uJjMTkN1KaOIgNtUPMtIXDOjx6dGYysdIFhgA52x4xSadQCz3b/zJexvITDVpANnfKPW/+E0xkOvLntqMYpviA==", - "dev": true, - "requires": { - "@octokit/types": "^6.34.0", - "deprecation": "^2.3.1" - } - }, - "@octokit/request": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.2.tgz", - "integrity": "sha512-je66CvSEVf0jCpRISxkUcCa0UkxmFs6eGDRSbfJtAVwbLH5ceqF+YEyC8lj8ystKyZTy8adWr0qmkY52EfOeLA==", - "dev": true, - "requires": { - "@octokit/endpoint": "^6.0.1", - "@octokit/request-error": "^2.1.0", - "@octokit/types": "^6.16.1", - "is-plain-object": "^5.0.0", - "node-fetch": "^2.6.1", - "universal-user-agent": "^6.0.0" - }, - "dependencies": { - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true - } - } - }, - "@octokit/request-error": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", - "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", - "dev": true, - "requires": { - "@octokit/types": "^6.0.3", - "deprecation": "^2.0.0", - "once": "^1.4.0" - } - }, - "@octokit/rest": { - "version": "18.12.0", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz", - "integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==", - "dev": true, - "requires": { - "@octokit/core": "^3.5.1", - "@octokit/plugin-paginate-rest": "^2.16.8", - "@octokit/plugin-request-log": "^1.0.4", - "@octokit/plugin-rest-endpoint-methods": "^5.12.0" - } - }, - "@octokit/types": { - "version": "6.34.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.34.0.tgz", - "integrity": "sha512-s1zLBjWhdEI2zwaoSgyOFoKSl109CUcVBCc7biPJ3aAf6LGLU6szDvi31JPU7bxfla2lqfhjbbg/5DdFNxOwHw==", - "dev": true, - "requires": { - "@octokit/openapi-types": "^11.2.0" - } - }, - "@reduxjs/toolkit": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.6.2.tgz", - "integrity": "sha512-HbfI/hOVrAcMGAYsMWxw3UJyIoAS9JTdwddsjlr5w3S50tXhWb+EMyhIw+IAvCVCLETkzdjgH91RjDSYZekVBA==", - "requires": { - "immer": "^9.0.6", - "redux": "^4.1.0", - "redux-thunk": "^2.3.0", - "reselect": "^4.0.0" - } - }, - "@rollup/plugin-babel": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.0.tgz", - "integrity": "sha512-9uIC8HZOnVLrLHxayq/PTzw+uS25E14KPUBh5ktF+18Mjo5yK0ToMMx6epY0uEgkjwJw0aBW4x2horYXh8juWw==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.10.4", - "@rollup/pluginutils": "^3.1.0" - } - }, - "@rollup/plugin-node-resolve": { - "version": "11.2.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz", - "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^3.1.0", - "@types/resolve": "1.17.1", - "builtin-modules": "^3.1.0", - "deepmerge": "^4.2.2", - "is-module": "^1.0.0", - "resolve": "^1.19.0" - }, - "dependencies": { - "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "dev": true, - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - } - } - }, - "@rollup/plugin-replace": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", - "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^3.1.0", - "magic-string": "^0.25.7" - } - }, - "@rollup/pluginutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", - "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", - "dev": true, - "requires": { - "@types/estree": "0.0.39", - "estree-walker": "^1.0.1", - "picomatch": "^2.2.2" - }, - "dependencies": { - "@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", - "dev": true - } - } - }, - "@sideway/address": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.2.tgz", - "integrity": "sha512-idTz8ibqWFrPU8kMirL0CoPH/A29XOzzAzpyN3zQ4kAWnzmNfFmRaoMNN6VI8ske5M73HZyhIaW4OuSFIdM4oA==", - "dev": true, - "requires": { - "@hapi/hoek": "^9.0.0" - } - }, - "@sideway/formula": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz", - "integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==", - "dev": true - }, - "@sideway/pinpoint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", - "dev": true - }, - "@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", - "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, - "@sinonjs/samsam": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.0.2.tgz", - "integrity": "sha512-jxPRPp9n93ci7b8hMfJOFDPRLFYadN6FSpeROFTR4UNF4i5b+EK6m4QXPO46BDhFgRy1JuS87zAnFOzCUwMJcQ==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.6.0", - "lodash.get": "^4.4.2", - "type-detect": "^4.0.8" - } - }, - "@sinonjs/text-encoding": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", - "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", - "dev": true - }, - "@surma/rollup-plugin-off-main-thread": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-1.4.2.tgz", - "integrity": "sha512-yBMPqmd1yEJo/280PAMkychuaALyQ9Lkb5q1ck3mjJrFuEobIfhnQ4J3mbvBoISmR3SWMWV+cGB/I0lCQee79A==", - "dev": true, - "requires": { - "ejs": "^2.6.1", - "magic-string": "^0.25.0" - }, - "dependencies": { - "ejs": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.4.tgz", - "integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==", - "dev": true - } - } - }, - "@testing-library/dom": { - "version": "8.11.1", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.11.1.tgz", - "integrity": "sha512-3KQDyx9r0RKYailW2MiYrSSKEfH0GTkI51UGEvJenvcoDoeRYs0PZpi2SXqtnMClQvCqdtTTpOfFETDTVADpAg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^4.2.0", - "aria-query": "^5.0.0", - "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.4.4", - "pretty-format": "^27.0.2" - } - }, - "@testing-library/react": { - "version": "12.1.2", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-12.1.2.tgz", - "integrity": "sha512-ihQiEOklNyHIpo2Y8FREkyD1QAea054U0MVbwH1m8N9TxeFz+KoJ9LkqoKqJlzx2JDm56DVwaJ1r36JYxZM05g==", - "dev": true, - "requires": { - "@babel/runtime": "^7.12.5", - "@testing-library/dom": "^8.0.0" - } - }, - "@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "dev": true - }, - "@trysound/sax": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", - "dev": true - }, - "@types/aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==", - "dev": true - }, - "@types/babel__core": { - "version": "7.1.16", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.16.tgz", - "integrity": "sha512-EAEHtisTMM+KaKwfWdC3oyllIqswlznXCIVCt7/oRNrh+DhgT4UEBNC/jlADNjvw7UnfbcdkGQcPVZ1xYiLcrQ==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "@types/babel__generator": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz", - "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@types/babel__traverse": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", - "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", - "dev": true, - "requires": { - "@babel/types": "^7.3.0" - } - }, - "@types/concat-stream": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", - "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/eslint": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.29.0.tgz", - "integrity": "sha512-VNcvioYDH8/FxaeTKkM4/TiTwt6pBV9E3OfGmvaw8tPl0rrHCJ4Ll15HRT+pMiFAf/MLQvAzC+6RzUMEL9Ceng==", - "dev": true, - "requires": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "@types/eslint-scope": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.1.tgz", - "integrity": "sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g==", - "dev": true, - "requires": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "@types/estree": { - "version": "0.0.50", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", - "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==", - "dev": true - }, - "@types/expect": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/@types/expect/-/expect-1.20.4.tgz", - "integrity": "sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg==", - "dev": true - }, - "@types/form-data": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", - "integrity": "sha1-yayFsqX9GENbjIXZ7LUObWyJP/g=", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", - "dev": true, - "requires": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/history": { - "version": "4.7.9", - "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.9.tgz", - "integrity": "sha512-MUc6zSmU3tEVnkQ78q0peeEjKWPUADMlC/t++2bI8WnAG2tvYRPIgHG8lWkXwqc8MsUF6Z2MOf+Mh5sazOmhiQ==", - "dev": true - }, - "@types/hoist-non-react-statics": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", - "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", - "requires": { - "@types/react": "*", - "hoist-non-react-statics": "^3.3.0" - }, - "dependencies": { - "@types/react": { - "version": "17.0.35", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.35.tgz", - "integrity": "sha512-r3C8/TJuri/SLZiiwwxQoLAoavaczARfT9up9b4Jr65+ErAUX3MIkU0oMOQnrpfgHme8zIqZLX7O5nnjm5Wayw==", - "requires": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" - } - } - } - }, - "@types/html-minifier-terser": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.0.0.tgz", - "integrity": "sha512-NZwaaynfs1oIoLAV1vg18e7QMVDvw+6SQrdJc8w3BwUaoroVSf6EBj/Sk4PBWGxsq0dzhA2drbsuMC1/6C6KgQ==", - "dev": true - }, - "@types/http-proxy": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.7.tgz", - "integrity": "sha512-9hdj6iXH64tHSLTY+Vt2eYOGzSogC+JQ2H7bdPWkuh7KXP5qLllWx++t+K9Wk556c3dkDdPws/SpMRi0sdCT1w==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", - "dev": true - }, - "@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "*" - } - }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "@types/jest": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.0.2.tgz", - "integrity": "sha512-4dRxkS/AFX0c5XW6IPMNOydLn2tEhNhJV7DnYK+0bjoJZ+QTmfucBlihX7aoEsh/ocYtkLC73UbnBXBXIxsULA==", - "dev": true, - "requires": { - "jest-diff": "^27.0.0", - "pretty-format": "^27.0.0" - } - }, - "@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", - "dev": true - }, - "@types/lodash": { - "version": "4.14.175", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.175.tgz", - "integrity": "sha512-XmdEOrKQ8a1Y/yxQFOMbC47G/V2VDO1GvMRnl4O75M4GW/abC5tnfzadQYkqEveqRM1dEJGFFegfPNA2vvx2iw==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", - "dev": true - }, - "@types/node": { - "version": "16.11.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.1.tgz", - "integrity": "sha512-PYGcJHL9mwl1Ek3PLiYgyEKtwTMmkMw4vbiyz/ps3pfdRYLVv+SN7qHVAImrjdAXxgluDEw6Ph4lyv+m9UpRmA==", - "dev": true - }, - "@types/normalize-package-data": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", - "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", - "dev": true - }, - "@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", - "dev": true - }, - "@types/prettier": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.2.tgz", - "integrity": "sha512-ekoj4qOQYp7CvjX8ZDBgN86w3MqQhLE1hczEJbEIjgFEumDy+na/4AJAbLXfgEWFNB2pKadM5rPFtuSGMWK7xA==", - "dev": true - }, - "@types/prop-types": { - "version": "15.7.4", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz", - "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==" - }, - "@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", - "dev": true - }, - "@types/react": { - "version": "17.0.30", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.30.tgz", - "integrity": "sha512-3Dt/A8gd3TCXi2aRe84y7cK1K8G+N9CZRDG8kDGguOKa0kf/ZkSwTmVIDPsm/KbQOVMaDJXwhBtuOXxqwdpWVg==", - "dev": true, - "requires": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" - } - }, - "@types/react-dom": { - "version": "17.0.9", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.9.tgz", - "integrity": "sha512-wIvGxLfgpVDSAMH5utdL9Ngm5Owu0VsGmldro3ORLXV8CShrL8awVj06NuEXFQ5xyaYfdca7Sgbk/50Ri1GdPg==", - "dev": true, - "requires": { - "@types/react": "*" - } - }, - "@types/react-redux": { - "version": "7.1.19", - "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.19.tgz", - "integrity": "sha512-L37dSCT0aoJnCgpR8Iuginlbxoh7qhWOXiaDqEsxVMrER1CmVhFD+63NxgJeT4pkmEM28oX0NH4S4f+sXHTZjA==", - "dev": true, - "requires": { - "@types/hoist-non-react-statics": "^3.3.0", - "@types/react": "*", - "hoist-non-react-statics": "^3.3.0", - "redux": "^4.0.0" - } - }, - "@types/react-router": { - "version": "5.1.17", - "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.17.tgz", - "integrity": "sha512-RNSXOyb3VyRs/EOGmjBhhGKTbnN6fHWvy5FNLzWfOWOGjgVUKqJZXfpKzLmgoU8h6Hj8mpALj/mbXQASOb92wQ==", - "dev": true, - "requires": { - "@types/history": "*", - "@types/react": "*" - } - }, - "@types/react-router-dom": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.1.tgz", - "integrity": "sha512-UvyRy73318QI83haXlaMwmklHHzV9hjl3u71MmM6wYNu0hOVk9NLTa0vGukf8zXUqnwz4O06ig876YSPpeK28A==", - "dev": true, - "requires": { - "@types/history": "*", - "@types/react": "*", - "@types/react-router": "*" - } - }, - "@types/redux": { - "version": "3.6.31", - "resolved": "https://registry.npmjs.org/@types/redux/-/redux-3.6.31.tgz", - "integrity": "sha1-QOr6dXXbNrkSzgBZuF3pjCBbBwg=", - "dev": true - }, - "@types/resolve": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", - "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/retry": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.1.tgz", - "integrity": "sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==", - "dev": true - }, - "@types/scheduler": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", - "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" - }, - "@types/stack-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", - "dev": true - }, - "@types/trusted-types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz", - "integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==", - "dev": true - }, - "@types/vinyl": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/vinyl/-/vinyl-2.0.6.tgz", - "integrity": "sha512-ayJ0iOCDNHnKpKTgBG6Q6JOnHTj9zFta+3j2b8Ejza0e4cvRyMn0ZoLEmbPrTHe5YYRlDYPvPWVdV4cTaRyH7g==", - "dev": true, - "requires": { - "@types/expect": "^1.20.4", - "@types/node": "*" - } - }, - "@types/webpack-env": { - "version": "1.16.3", - "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.16.3.tgz", - "integrity": "sha512-9gtOPPkfyNoEqCQgx4qJKkuNm/x0R2hKR7fdl7zvTJyHnIisuE/LfvXOsYWL0o3qq6uiBnKZNNNzi3l0y/X+xw==", - "dev": true - }, - "@types/yargs": { - "version": "16.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", - "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "@types/yargs-parser": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", - "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", - "dev": true - }, - "@typescript-eslint/eslint-plugin": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", - "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", - "dev": true, - "requires": { - "@typescript-eslint/experimental-utils": "4.33.0", - "@typescript-eslint/scope-manager": "4.33.0", - "debug": "^4.3.1", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", - "regexpp": "^3.1.0", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/experimental-utils": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", - "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - } - }, - "@typescript-eslint/parser": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", - "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "debug": "^4.3.1" - } - }, - "@typescript-eslint/scope-manager": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", - "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0" - } - }, - "@typescript-eslint/types": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", - "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", - "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", - "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.33.0", - "eslint-visitor-keys": "^2.0.0" - } - }, - "@webassemblyjs/ast": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", - "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", - "dev": true, - "requires": { - "@webassemblyjs/helper-numbers": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", - "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", - "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", - "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", - "dev": true - }, - "@webassemblyjs/helper-numbers": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", - "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", - "dev": true, - "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", - "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", - "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", - "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", - "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", - "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", - "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/helper-wasm-section": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-opt": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "@webassemblyjs/wast-printer": "1.11.1" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", - "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", - "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", - "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", - "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@xtuc/long": "4.2.2" - } - }, - "@webpack-cli/configtest": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.1.0.tgz", - "integrity": "sha512-ttOkEkoalEHa7RaFYpM0ErK1xc4twg3Am9hfHhL7MVqlHebnkYd2wuI/ZqTDj0cVzZho6PdinY0phFZV3O0Mzg==", - "dev": true - }, - "@webpack-cli/info": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.4.0.tgz", - "integrity": "sha512-F6b+Man0rwE4n0409FyAJHStYA5OIZERxmnUfLVwv0mc0V1wLad3V7jqRlMkgKBeAq07jUvglacNaa6g9lOpuw==", - "dev": true, - "requires": { - "envinfo": "^7.7.3" - } - }, - "@webpack-cli/serve": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.6.0.tgz", - "integrity": "sha512-ZkVeqEmRpBV2GHvjjUZqEai2PpUbuq8Bqd//vEYsp63J8WyexI8ppCqVS3Zs0QADf6aWuPdU+0XsPI647PVlQA==", - "dev": true - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "abab": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", - "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", - "dev": true - }, - "abbrev": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", - "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", - "dev": true - }, - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "dev": true, - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - } - }, - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - }, - "acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "dev": true, - "requires": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, - "acorn-import-assertions": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", - "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true - }, - "acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "dev": true - }, - "after": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", - "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", - "dev": true - }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "requires": { - "debug": "4" - } - }, - "agentkeepalive": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.1.4.tgz", - "integrity": "sha512-+V/rGa3EuU74H6wR04plBb7Ks10FbtUQgRj/FQOG7uUIEuaINI+AiqJR1k6t3SVNs7o7ZjIdus6706qqzVq8jQ==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "depd": "^1.1.2", - "humanize-ms": "^1.2.1" - } - }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, - "requires": { - "ajv": "^8.0.0" - }, - "dependencies": { - "ajv": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.1.tgz", - "integrity": "sha512-6CiMNDrzv0ZR916u2T+iRunnD60uWmNn8SkdB44/6stVORUg0aAkWO7PkOhpCmjmW8f2I/G/xnowD66fxGyQJg==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - } - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true - }, - "alphanum-sort": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", - "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", - "dev": true - }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "dev": true, - "optional": true - }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true - }, - "ansi-html-community": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", - "dev": true - }, - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "ansi-wrap": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", - "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=", - "dev": true - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "are-we-there-yet": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", - "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", - "dev": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "aria-query": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.0.0.tgz", - "integrity": "sha512-V+SM7AbUwJ+EBnB8+DXs0hPZHO0W6pqBcc0dW90OwtVG02PswOu/teuARoLQjdDOH+t9pJgGnW5/Qmouf3gPJg==", - "dev": true - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-differ": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", - "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", - "dev": true - }, - "array-flatten": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", - "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", - "dev": true - }, - "array-includes": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", - "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.7" - } - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "array.prototype.flatmap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.5.tgz", - "integrity": "sha512-08u6rVyi1Lj7oqWbS9nUxliETrtIROT4XGTA4D/LWGten6E3ocm7cy9SIrmNHOL5XVbVuckUp3X6Xyg8/zpvHA==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0" - } - }, - "arraybuffer.slice": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", - "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", - "dev": true - }, - "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "dev": true - }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", - "dev": true - }, - "asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true - }, - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - }, - "async-each-series": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/async-each-series/-/async-each-series-0.1.1.tgz", - "integrity": "sha1-dhfBkXQB/Yykooqtzj266Yr+tDI=", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true - }, - "atomically": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/atomically/-/atomically-1.7.0.tgz", - "integrity": "sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w==", - "dev": true - }, - "autoprefixer": { - "version": "10.3.7", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.3.7.tgz", - "integrity": "sha512-EmGpu0nnQVmMhX8ROoJ7Mx8mKYPlcUHuxkwrRYEYMz85lu7H09v8w6R1P0JPdn/hKU32GjpLBFEOuIlDWCRWvg==", - "dev": true, - "requires": { - "browserslist": "^4.17.3", - "caniuse-lite": "^1.0.30001264", - "fraction.js": "^4.1.1", - "normalize-range": "^0.1.2", - "picocolors": "^0.2.1", - "postcss-value-parser": "^4.1.0" - }, - "dependencies": { - "caniuse-lite": { - "version": "1.0.30001282", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001282.tgz", - "integrity": "sha512-YhF/hG6nqBEllymSIjLtR2iWDDnChvhnVJqp+vloyt2tEHFG1yBR+ac2B/rOw0qOK0m0lEXU2dv4E/sMk5P9Kg==", - "dev": true - }, - "electron-to-chromium": { - "version": "1.3.901", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.901.tgz", - "integrity": "sha512-ToJdV2vzwT2jeAsw8zIggTFllJ4Kxvwghk39AhJEHHlIxor10wsFI3wo69p8nFc0s/ATWBqugPv/k3nW4Y9Mww==" - }, - "node-releases": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", - "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==" - }, - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", - "dev": true - } - } - }, - "aws-sdk": { - "version": "2.1009.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1009.0.tgz", - "integrity": "sha512-qKbmt+vzQ7ZSnfEvA+u6d7CkV09AcAGnxZAiNgOAEn8GFFEtERy6C39VoAuWfON/B2avJDYvtRocjVmAxWpgjQ==", - "dev": true, - "requires": { - "buffer": "4.9.2", - "events": "1.1.1", - "ieee754": "1.1.13", - "jmespath": "0.15.0", - "querystring": "0.2.0", - "sax": "1.2.1", - "url": "0.10.3", - "uuid": "3.3.2", - "xml2js": "0.4.19" - }, - "dependencies": { - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true - } - } - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true - }, - "aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", - "dev": true - }, - "axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "requires": { - "follow-redirects": "^1.14.0" - } - }, - "babel-jest": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.3.1.tgz", - "integrity": "sha512-SjIF8hh/ir0peae2D6S6ZKRhUy7q/DnpH7k/V6fT4Bgs/LXXUztOpX4G2tCgq8mLo5HA9mN6NmlFMeYtKmIsTQ==", - "dev": true, - "requires": { - "@jest/transform": "^27.3.1", - "@jest/types": "^27.2.5", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^27.2.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "slash": "^3.0.0" - } - }, - "babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", - "dev": true, - "requires": { - "object.assign": "^4.1.0" - } - }, - "babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "dependencies": { - "istanbul-lib-instrument": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", - "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", - "dev": true, - "requires": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "babel-plugin-jest-hoist": { - "version": "27.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.2.0.tgz", - "integrity": "sha512-TOux9khNKdi64mW+0OIhcmbAn75tTlzKhxmiNXevQaPbrBYK7YKjP1jl6NHTJ6XR5UgUrJbCnWlKVnJn29dfjw==", - "dev": true, - "requires": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-plugin-polyfill-corejs2": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.0.tgz", - "integrity": "sha512-wMDoBJ6uG4u4PNFh72Ty6t3EgfA91puCuAwKIazbQlci+ENb/UU9A3xG5lutjUIiXCIn1CY5L15r9LimiJyrSA==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.13.11", - "@babel/helper-define-polyfill-provider": "^0.3.0", - "semver": "^6.1.1" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "babel-plugin-polyfill-corejs3": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.4.0.tgz", - "integrity": "sha512-YxFreYwUfglYKdLUGvIF2nJEsGwj+RhWSX/ije3D2vQPOXuyMLMtg/cCGMDpOA7Nd+MwlNdnGODbd2EwUZPlsw==", - "dev": true, - "requires": { - "@babel/helper-define-polyfill-provider": "^0.3.0", - "core-js-compat": "^3.18.0" - } - }, - "babel-plugin-polyfill-regenerator": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.0.tgz", - "integrity": "sha512-dhAPTDLGoMW5/84wkgwiLRwMnio2i1fUe53EuvtKMv0pn2p3S8OCoV1xAzfJPl0KOX7IB89s2ib85vbYiea3jg==", - "dev": true, - "requires": { - "@babel/helper-define-polyfill-provider": "^0.3.0" - } - }, - "babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "requires": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - } - }, - "babel-preset-jest": { - "version": "27.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.2.0.tgz", - "integrity": "sha512-z7MgQ3peBwN5L5aCqBKnF6iqdlvZvFUQynEhu0J+X9nHLU72jO3iY331lcYrg+AssJ8q7xsv5/3AICzVmJ/wvg==", - "dev": true, - "requires": { - "babel-plugin-jest-hoist": "^27.2.0", - "babel-preset-current-node-syntax": "^1.0.0" - } - }, - "backo2": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base64-arraybuffer": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz", - "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI=", - "dev": true - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true - }, - "base64id": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", - "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", - "dev": true - }, - "batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "before-after-hook": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz", - "integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==", - "dev": true - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "bin-links": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-2.3.0.tgz", - "integrity": "sha512-JzrOLHLwX2zMqKdyYZjkDgQGT+kHDkIhv2/IK2lJ00qLxV4TmFoHi8drDBb6H5Zrz1YfgHkai4e2MGPqnoUhqA==", - "dev": true, - "requires": { - "cmd-shim": "^4.0.1", - "mkdirp-infer-owner": "^2.0.0", - "npm-normalize-package-bin": "^1.0.0", - "read-cmd-shim": "^2.0.0", - "rimraf": "^3.0.0", - "write-file-atomic": "^3.0.3" - } - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, - "binaryextensions": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/binaryextensions/-/binaryextensions-4.18.0.tgz", - "integrity": "sha512-PQu3Kyv9dM4FnwB7XGj1+HucW+ShvJzJqjuw1JkKVs1mWdwOKVcRjOi+pV9X52A0tNvrPCsPkbFFQb+wE1EAXw==", - "dev": true - }, - "bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - }, - "dependencies": { - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - } - } - }, - "blob": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", - "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==", - "dev": true - }, - "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", - "dev": true, - "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - }, - "dependencies": { - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "dev": true - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "dev": true - }, - "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", - "dev": true, - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", - "dev": true - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true - }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", - "dev": true - } - } - }, - "bonjour": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", - "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", - "dev": true, - "requires": { - "array-flatten": "^2.1.0", - "deep-equal": "^1.0.1", - "dns-equal": "^1.0.0", - "dns-txt": "^2.0.2", - "multicast-dns": "^6.0.1", - "multicast-dns-service-types": "^1.1.0" - } - }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", - "dev": true - }, - "bootstrap": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.0.tgz", - "integrity": "sha512-Io55IuQY3kydzHtbGvQya3H+KorS/M9rSNyfCGCg9WZ4pyT/lCxIlpJgG1GXW/PswzC84Tr2fBYi+7+jFVQQBw==" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, - "browser-sync": { - "version": "2.27.5", - "resolved": "https://registry.npmjs.org/browser-sync/-/browser-sync-2.27.5.tgz", - "integrity": "sha512-0GMEPDqccbTxwYOUGCk5AZloDj9I/1eDZCLXUKXu7iBJPznGGOnMHs88mrhaFL0fTA0R23EmsXX9nLZP+k5YzA==", - "dev": true, - "requires": { - "browser-sync-client": "^2.27.5", - "browser-sync-ui": "^2.27.5", - "bs-recipes": "1.3.4", - "bs-snippet-injector": "^2.0.1", - "chokidar": "^3.5.1", - "connect": "3.6.6", - "connect-history-api-fallback": "^1", - "dev-ip": "^1.0.1", - "easy-extender": "^2.3.4", - "eazy-logger": "3.1.0", - "etag": "^1.8.1", - "fresh": "^0.5.2", - "fs-extra": "3.0.1", - "http-proxy": "^1.18.1", - "immutable": "^3", - "localtunnel": "^2.0.1", - "micromatch": "^4.0.2", - "opn": "5.3.0", - "portscanner": "2.1.1", - "qs": "6.2.3", - "raw-body": "^2.3.2", - "resp-modifier": "6.0.2", - "rx": "4.1.0", - "send": "0.16.2", - "serve-index": "1.9.1", - "serve-static": "1.13.2", - "server-destroy": "1.0.1", - "socket.io": "2.4.0", - "ua-parser-js": "^0.7.28", - "yargs": "^15.4.1" - } - }, - "browser-sync-client": { - "version": "2.27.7", - "resolved": "https://registry.npmjs.org/browser-sync-client/-/browser-sync-client-2.27.7.tgz", - "integrity": "sha512-wKg9UP9a4sCIkBBAXUdbkdWFJzfSAQizGh+nC19W9y9zOo9s5jqeYRFUUbs7x5WKhjtspT+xetVp9AtBJ6BmWg==", - "dev": true, - "requires": { - "etag": "1.8.1", - "fresh": "0.5.2", - "mitt": "^1.1.3", - "rxjs": "^5.5.6" - } - }, - "browser-sync-ui": { - "version": "2.27.7", - "resolved": "https://registry.npmjs.org/browser-sync-ui/-/browser-sync-ui-2.27.7.tgz", - "integrity": "sha512-Bt4OQpx9p18OIzk0KKyu7jqlvmjacasUlk8ARY3uuIyiFWSBiRgr2i6XY8dEMF14DtbooaEBOpHEu9VCYvMcCw==", - "dev": true, - "requires": { - "async-each-series": "0.1.1", - "connect-history-api-fallback": "^1", - "immutable": "^3", - "server-destroy": "1.0.1", - "socket.io-client": "^2.4.0", - "stream-throttle": "^0.1.3" - } - }, - "browser-sync-webpack-plugin": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/browser-sync-webpack-plugin/-/browser-sync-webpack-plugin-2.3.0.tgz", - "integrity": "sha512-MDvuRrTCtoL11dTdwMymo9CNJvYxJoW67gOO61cThfzHNX40S5WcBU+0bVQ86ll7r7aNpNgyzxF7RtnXMTDbyA==", - "dev": true, - "requires": { - "lodash": "^4" - } - }, - "browserslist": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.18.1.tgz", - "integrity": "sha512-8ScCzdpPwR2wQh8IT82CA2VgDwjHyqMovPBZSNH54+tm4Jk2pCuv90gmAdH6J84OCRWi0b4gMe6O6XPXuJnjgQ==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001280", - "electron-to-chromium": "^1.3.896", - "escalade": "^3.1.1", - "node-releases": "^2.0.1", - "picocolors": "^1.0.0" - }, - "dependencies": { - "caniuse-lite": { - "version": "1.0.30001282", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001282.tgz", - "integrity": "sha512-YhF/hG6nqBEllymSIjLtR2iWDDnChvhnVJqp+vloyt2tEHFG1yBR+ac2B/rOw0qOK0m0lEXU2dv4E/sMk5P9Kg==", - "dev": true - }, - "electron-to-chromium": { - "version": "1.3.901", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.901.tgz", - "integrity": "sha512-ToJdV2vzwT2jeAsw8zIggTFllJ4Kxvwghk39AhJEHHlIxor10wsFI3wo69p8nFc0s/ATWBqugPv/k3nW4Y9Mww==", - "dev": true - }, - "node-releases": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", - "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==", - "dev": true - } - } - }, - "bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "requires": { - "fast-json-stable-stringify": "2.x" - } - }, - "bs-recipes": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/bs-recipes/-/bs-recipes-1.3.4.tgz", - "integrity": "sha1-DS1NSKcYyMBEdp/cT4lZLci2lYU=", - "dev": true - }, - "bs-snippet-injector": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/bs-snippet-injector/-/bs-snippet-injector-2.0.1.tgz", - "integrity": "sha1-YbU5PxH1JVntEgaTEANDtu2wTdU=", - "dev": true - }, - "bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "requires": { - "node-int64": "^0.4.0" - } - }, - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - } - } - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "buffer-indexof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", - "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", - "dev": true - }, - "builtin-modules": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", - "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", - "dev": true - }, - "builtins": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", - "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=", - "dev": true - }, - "bytes": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", - "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==", - "dev": true - }, - "cacache": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", - "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", - "dev": true, - "requires": { - "@npmcli/fs": "^1.0.0", - "@npmcli/move-file": "^1.0.1", - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", - "infer-owner": "^1.0.4", - "lru-cache": "^6.0.0", - "minipass": "^3.1.1", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^1.0.3", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^8.0.1", - "tar": "^6.0.2", - "unique-filename": "^1.1.1" - }, - "dependencies": { - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - } - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "dev": true, - "requires": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, - "caniuse-lite": { - "version": "1.0.30001189", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001189.tgz", - "integrity": "sha512-BSfxClP/UWCD0RX1h1L+vLDexNSJY7SfOtbJtW10bcnatfj3BcoietUFYNwWreOCk+SNvGUaNapGqUNPiGAiSA==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true - }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, - "chevrotain": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-9.1.0.tgz", - "integrity": "sha512-A86/55so63HCfu0dgGg3j9u8uuuBOrSqly1OhBZxRu2x6sAKILLzfVjbGMw45kgier6lz45EzcjjWtTRgoT84Q==", - "dev": true, - "requires": { - "@chevrotain/types": "^9.1.0", - "@chevrotain/utils": "^9.1.0", - "regexp-to-ast": "0.5.0" - } - }, - "chokidar": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", - "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true - }, - "ci-info": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", - "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", - "dev": true - }, - "cjs-module-lexer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", - "dev": true - }, - "classnames": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz", - "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==" - }, - "clean-css": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.2.2.tgz", - "integrity": "sha512-/eR8ru5zyxKzpBLv9YZvMXgTSSQn7AdkMItMYynsFgGwTveCRVam9IUPFloE85B4vAIj05IuKmmEoV7/AQjT0w==", - "dev": true, - "requires": { - "source-map": "~0.6.0" - } - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "cli-spinners": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", - "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", - "dev": true - }, - "cli-table": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.7.tgz", - "integrity": "sha512-ADKScujxlVFQhcea3OW7MmQRhUW3VDhaVRLx/77FjIME04K/BrguPa+p8DaXYSSlxDTO1f4ykf71a6WG0OB2/A==", - "dev": true, - "requires": { - "colors": "1.0.3", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "colors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", - "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "cli-truncate": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", - "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", - "dev": true, - "requires": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "slice-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - } - } - } - }, - "cli-width": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", - "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", - "dev": true - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", - "dev": true - }, - "clone-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", - "dev": true - }, - "clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - } - }, - "clone-stats": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", - "dev": true - }, - "cloneable-readable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", - "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "process-nextick-args": "^2.0.0", - "readable-stream": "^2.3.5" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "clsx": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz", - "integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==" - }, - "cmd-shim": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-4.1.0.tgz", - "integrity": "sha512-lb9L7EM4I/ZRVuljLPEtUJOP+xiQVknZ4ZMpMgEp4JzNldPb27HU03hi6K1/6CoIuit/Zm/LQXySErFeXxDprw==", - "dev": true, - "requires": { - "mkdirp-infer-owner": "^2.0.0" - } - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", - "dev": true - }, - "color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", - "dev": true, - "requires": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "color-string": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.6.0.tgz", - "integrity": "sha512-c/hGS+kRWJutUBEngKKmk4iH3sD59MBkoxVapS/0wgpCz2u7XsNloxknyvBhzwEs1IbV36D9PwqLPJ2DTu3vMA==", - "dev": true, - "requires": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "colord": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.1.tgz", - "integrity": "sha512-4LBMSt09vR0uLnPVkOUBnmxgoaeN4ewRbx801wY/bXcltXfpR/G46OdWn96XpYmCWuYvO46aBZP4NgX8HpNAcw==", - "dev": true - }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true - }, - "colorspace": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", - "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", - "dev": true, - "requires": { - "color": "^3.1.3", - "text-hex": "1.0.x" - } - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "common-ancestor-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz", - "integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==", - "dev": true - }, - "common-tags": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", - "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-bind": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", - "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "component-inherit": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", - "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", - "dev": true - }, - "compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "dev": true, - "requires": { - "mime-db": ">= 1.43.0 < 2" - } - }, - "compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "dev": true, - "requires": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "dependencies": { - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "dev": true - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concurrently": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-6.3.0.tgz", - "integrity": "sha512-k4k1jQGHHKsfbqzkUszVf29qECBrkvBKkcPJEUDTyVR7tZd1G/JOfnst4g1sYbFvJ4UjHZisj1aWQR8yLKpGPw==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "date-fns": "^2.16.1", - "lodash": "^4.17.21", - "rxjs": "^6.6.3", - "spawn-command": "^0.0.2-1", - "supports-color": "^8.1.0", - "tree-kill": "^1.2.2", - "yargs": "^16.2.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - } - } - }, - "conf": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/conf/-/conf-10.0.3.tgz", - "integrity": "sha512-4gtQ/Q36qVxBzMe6B7gWOAfni1VdhuHkIzxydHkclnwGmgN+eW4bb6jj73vigCfr7d3WlmqawvhZrpCUCTPYxQ==", - "dev": true, - "requires": { - "ajv": "^8.6.3", - "ajv-formats": "^2.1.1", - "atomically": "^1.7.0", - "debounce-fn": "^4.0.0", - "dot-prop": "^6.0.1", - "env-paths": "^2.2.1", - "json-schema-typed": "^7.0.3", - "onetime": "^5.1.2", - "pkg-up": "^3.1.0", - "semver": "^7.3.5" - }, - "dependencies": { - "ajv": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.1.tgz", - "integrity": "sha512-6CiMNDrzv0ZR916u2T+iRunnD60uWmNn8SkdB44/6stVORUg0aAkWO7PkOhpCmjmW8f2I/G/xnowD66fxGyQJg==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - } - } - }, - "connect": { - "version": "3.6.6", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz", - "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=", - "dev": true, - "requires": { - "debug": "2.6.9", - "finalhandler": "1.1.0", - "parseurl": "~1.3.2", - "utils-merge": "1.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "connect-history-api-fallback": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", - "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", - "dev": true - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true - }, - "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", - "dev": true, - "requires": { - "safe-buffer": "5.1.2" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "dev": true - }, - "convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } - } - }, - "cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", - "dev": true - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", - "dev": true - }, - "copy-webpack-plugin": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-9.0.1.tgz", - "integrity": "sha512-14gHKKdYIxF84jCEgPgYXCPpldbwpxxLbCmA7LReY7gvbaT555DgeBWBgBZM116tv/fO6RRJrsivBqRyRlukhw==", - "dev": true, - "requires": { - "fast-glob": "^3.2.5", - "glob-parent": "^6.0.0", - "globby": "^11.0.3", - "normalize-path": "^3.0.0", - "p-limit": "^3.1.0", - "schema-utils": "^3.0.0", - "serialize-javascript": "^6.0.0" - }, - "dependencies": { - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - } - } - }, - "core-js": { - "version": "3.18.3", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.18.3.tgz", - "integrity": "sha512-tReEhtMReZaPFVw7dajMx0vlsz3oOb8ajgPoHVYGxr8ErnZ6PcYEvvmjGmXlfpnxpkYSdOQttjB+MvVbCGfvLw==", - "dev": true - }, - "core-js-compat": { - "version": "3.19.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.19.1.tgz", - "integrity": "sha512-Q/VJ7jAF/y68+aUsQJ/afPOewdsGkDtcMb40J8MbuWKlK3Y+wtHq8bTHKPj2WKWLIqmS5JhHs4CzHtz6pT2W6g==", - "dev": true, - "requires": { - "browserslist": "^4.17.6", - "semver": "7.0.0" - }, - "dependencies": { - "caniuse-lite": { - "version": "1.0.30001282", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001282.tgz", - "integrity": "sha512-YhF/hG6nqBEllymSIjLtR2iWDDnChvhnVJqp+vloyt2tEHFG1yBR+ac2B/rOw0qOK0m0lEXU2dv4E/sMk5P9Kg==" - }, - "electron-to-chromium": { - "version": "1.3.901", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.901.tgz", - "integrity": "sha512-ToJdV2vzwT2jeAsw8zIggTFllJ4Kxvwghk39AhJEHHlIxor10wsFI3wo69p8nFc0s/ATWBqugPv/k3nW4Y9Mww==" - }, - "node-releases": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", - "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==" - }, - "semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", - "dev": true - } - } - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", - "dev": true, - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.7.2" - } - }, - "cross-env": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", - "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.1" - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "dev": true - }, - "css-declaration-sorter": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.1.3.tgz", - "integrity": "sha512-SvjQjNRZgh4ULK1LDJ2AduPKUKxIqmtU7ZAyi47BTV+M90Qvxr9AB6lKlLbDUfXqI9IQeYA8LbAsCZPpJEV3aA==", - "dev": true, - "requires": { - "timsort": "^0.3.0" - } - }, - "css-loader": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.4.0.tgz", - "integrity": "sha512-Dlt6qfsxI/w1vU0r8qDd4BtMPxWqJeY5qQU7SmmZfvbpe6Xl18McO4GhyaMLns24Y2VNPiZwJPQ8JSbg4qvQLw==", - "dev": true, - "requires": { - "icss-utils": "^5.1.0", - "postcss": "^8.2.15", - "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.0", - "postcss-modules-scope": "^3.0.0", - "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.1.0", - "semver": "^7.3.5" - }, - "dependencies": { - "postcss": { - "version": "8.3.11", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.11.tgz", - "integrity": "sha512-hCmlUAIlUiav8Xdqw3Io4LcpA1DOt7h3LSTAC4G6JGHFFaWzI6qvFt9oilvl8BmkbBRX1IhM90ZAmpk68zccQA==", - "dev": true, - "requires": { - "nanoid": "^3.1.30", - "picocolors": "^1.0.0", - "source-map-js": "^0.6.2" - } - } - } - }, - "css-minimizer-webpack-plugin": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.1.1.tgz", - "integrity": "sha512-KlB8l5uoNcf9F7i5kXnkxoqJGd2BXH4f0+Lj2vSWSmuvMLYO1kNsJ1KHSzeDW8e45/whgSOPcKVT/3JopkT8dg==", - "dev": true, - "requires": { - "cssnano": "^5.0.6", - "jest-worker": "^27.0.2", - "p-limit": "^3.0.2", - "postcss": "^8.3.5", - "schema-utils": "^3.1.0", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1" - }, - "dependencies": { - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "postcss": { - "version": "8.3.11", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.11.tgz", - "integrity": "sha512-hCmlUAIlUiav8Xdqw3Io4LcpA1DOt7h3LSTAC4G6JGHFFaWzI6qvFt9oilvl8BmkbBRX1IhM90ZAmpk68zccQA==", - "dev": true, - "requires": { - "nanoid": "^3.1.30", - "picocolors": "^1.0.0", - "source-map-js": "^0.6.2" - } - } - } - }, - "css-select": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.1.3.tgz", - "integrity": "sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA==", - "dev": true, - "requires": { - "boolbase": "^1.0.0", - "css-what": "^5.0.0", - "domhandler": "^4.2.0", - "domutils": "^2.6.0", - "nth-check": "^2.0.0" - } - }, - "css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "dev": true, - "requires": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - } - }, - "css-what": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz", - "integrity": "sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==", - "dev": true - }, - "cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true - }, - "cssnano": { - "version": "5.0.11", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.0.11.tgz", - "integrity": "sha512-5SHM31NAAe29jvy0MJqK40zZ/8dGlnlzcfHKw00bWMVFp8LWqtuyPSFwbaoIoxvt71KWJOfg8HMRGrBR3PExCg==", - "dev": true, - "requires": { - "cssnano-preset-default": "^5.1.7", - "is-resolvable": "^1.1.0", - "lilconfig": "^2.0.3", - "yaml": "^1.10.2" - } - }, - "cssnano-preset-default": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.1.7.tgz", - "integrity": "sha512-bWDjtTY+BOqrqBtsSQIbN0RLGD2Yr2CnecpP0ydHNafh9ZUEre8c8VYTaH9FEbyOt0eIfEUAYYk5zj92ioO8LA==", - "dev": true, - "requires": { - "css-declaration-sorter": "^6.0.3", - "cssnano-utils": "^2.0.1", - "postcss-calc": "^8.0.0", - "postcss-colormin": "^5.2.1", - "postcss-convert-values": "^5.0.2", - "postcss-discard-comments": "^5.0.1", - "postcss-discard-duplicates": "^5.0.1", - "postcss-discard-empty": "^5.0.1", - "postcss-discard-overridden": "^5.0.1", - "postcss-merge-longhand": "^5.0.4", - "postcss-merge-rules": "^5.0.3", - "postcss-minify-font-values": "^5.0.1", - "postcss-minify-gradients": "^5.0.3", - "postcss-minify-params": "^5.0.2", - "postcss-minify-selectors": "^5.1.0", - "postcss-normalize-charset": "^5.0.1", - "postcss-normalize-display-values": "^5.0.1", - "postcss-normalize-positions": "^5.0.1", - "postcss-normalize-repeat-style": "^5.0.1", - "postcss-normalize-string": "^5.0.1", - "postcss-normalize-timing-functions": "^5.0.1", - "postcss-normalize-unicode": "^5.0.1", - "postcss-normalize-url": "^5.0.3", - "postcss-normalize-whitespace": "^5.0.1", - "postcss-ordered-values": "^5.0.2", - "postcss-reduce-initial": "^5.0.1", - "postcss-reduce-transforms": "^5.0.1", - "postcss-svgo": "^5.0.3", - "postcss-unique-selectors": "^5.0.2" - } - }, - "cssnano-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-2.0.1.tgz", - "integrity": "sha512-i8vLRZTnEH9ubIyfdZCAdIdgnHAUeQeByEeQ2I7oTilvP9oHO6RScpeq3GsFUVqeB8uZgOQ9pw8utofNn32hhQ==", - "dev": true - }, - "csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", - "dev": true, - "requires": { - "css-tree": "^1.1.2" - } - }, - "cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", - "dev": true - }, - "cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dev": true, - "requires": { - "cssom": "~0.3.6" - }, - "dependencies": { - "cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true - } - } - }, - "csstype": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.7.tgz", - "integrity": "sha512-KxnUB0ZMlnUWCsx2Z8MUsr6qV6ja1w9ArPErJaJaF8a5SOWoHLIszeCTKGRGRgtLgYrs1E8CHkNSP1VZTTPc9g==" - }, - "dargs": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", - "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dev": true, - "requires": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - }, - "dependencies": { - "tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dev": true, - "requires": { - "punycode": "^2.1.1" - } - }, - "webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "dev": true - }, - "whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "dev": true, - "requires": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - } - } - } - }, - "date-fns": { - "version": "2.25.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.25.0.tgz", - "integrity": "sha512-ovYRFnTrbGPD4nqaEqescPEv1mNwvt+UTqI3Ay9SzNtey9NZnYu6E2qCcBBgJ6/2VF1zGGygpyTDITqpQQ5e+w==", - "dev": true - }, - "dateformat": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", - "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", - "dev": true - }, - "dayjs": { - "version": "1.10.7", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.7.tgz", - "integrity": "sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig==" - }, - "debounce-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/debounce-fn/-/debounce-fn-4.0.0.tgz", - "integrity": "sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ==", - "dev": true, - "requires": { - "mimic-fn": "^3.0.0" - } - }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "debuglog": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz", - "integrity": "sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=", - "dev": true - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decimal.js": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", - "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", - "dev": true - }, - "dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", - "dev": true - }, - "deep-equal": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", - "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", - "requires": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" - } - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" - }, - "default-gateway": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", - "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", - "dev": true, - "requires": { - "execa": "^5.0.0" - }, - "dependencies": { - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true - } - } - }, - "defaults": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", - "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", - "dev": true, - "requires": { - "clone": "^1.0.2" - } - }, - "define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "dev": true - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "requires": { - "object-keys": "^1.0.12" - } - }, - "del": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/del/-/del-6.0.0.tgz", - "integrity": "sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ==", - "dev": true, - "requires": { - "globby": "^11.0.1", - "graceful-fs": "^4.2.4", - "is-glob": "^4.0.1", - "is-path-cwd": "^2.2.0", - "is-path-inside": "^3.0.2", - "p-map": "^4.0.0", - "rimraf": "^3.0.2", - "slash": "^3.0.0" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true - }, - "deprecation": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", - "dev": true - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true - }, - "detect-indent": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", - "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", - "dev": true - }, - "detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true - }, - "detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "dev": true - }, - "dev-ip": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dev-ip/-/dev-ip-1.0.1.tgz", - "integrity": "sha1-p2o+0YVb56ASu4rBbLgPPADcKPA=", - "dev": true - }, - "dezalgo": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz", - "integrity": "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=", - "dev": true, - "requires": { - "asap": "^2.0.0", - "wrappy": "1" - } - }, - "didyoumean": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", - "dev": true - }, - "diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true - }, - "diff-sequences": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", - "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==", - "dev": true - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "dev": true - }, - "dns-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", - "dev": true - }, - "dns-packet": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.4.tgz", - "integrity": "sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==", - "dev": true, - "requires": { - "ip": "^1.1.0", - "safe-buffer": "^5.0.1" - } - }, - "dns-txt": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", - "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", - "dev": true, - "requires": { - "buffer-indexof": "^1.0.0" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "dom-accessibility-api": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.10.tgz", - "integrity": "sha512-Xu9mD0UjrJisTmv7lmVSDMagQcU9R5hwAbxsaAE/35XPnPLJobbuREfV/rraiSaEj/UOvgrzQs66zyTWTlyd+g==", - "dev": true - }, - "dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "dev": true, - "requires": { - "utila": "~0.4" - } - }, - "dom-helpers": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", - "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", - "requires": { - "@babel/runtime": "^7.8.7", - "csstype": "^3.0.2" - } - }, - "dom-serializer": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", - "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", - "dev": true, - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - } - }, - "domelementtype": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", - "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==" - }, - "domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", - "dev": true, - "requires": { - "webidl-conversions": "^5.0.0" - }, - "dependencies": { - "webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true - } - } - }, - "domhandler": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.2.tgz", - "integrity": "sha512-PzE9aBMsdZO8TK4BnuJwH0QT41wgMbRzuZrHUcpYncEjmQazq8QEaBWgLG7ZyC/DAZKEgglpIA6j4Qn/HmxS3w==", - "requires": { - "domelementtype": "^2.2.0" - } - }, - "domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "dev": true, - "requires": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - } - }, - "dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "dev": true, - "requires": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "dot-prop": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", - "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", - "dev": true, - "requires": { - "is-obj": "^2.0.0" - } - }, - "drange": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/drange/-/drange-1.1.1.tgz", - "integrity": "sha512-pYxfDYpued//QpnLIm4Avk7rsNtAtQkUES2cwAYSvD/wd2pKD71gN2Ebj3e7klzXwjocvE8c5vx/1fxwpqmSxA==", - "dev": true - }, - "easy-extender": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/easy-extender/-/easy-extender-2.3.4.tgz", - "integrity": "sha512-8cAwm6md1YTiPpOvDULYJL4ZS6WfM5/cTeVVh4JsvyYZAoqlRVUpHL9Gr5Fy7HA6xcSZicUia3DeAgO3Us8E+Q==", - "dev": true, - "requires": { - "lodash": "^4.17.10" - } - }, - "eazy-logger": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eazy-logger/-/eazy-logger-3.1.0.tgz", - "integrity": "sha512-/snsn2JqBtUSSstEl4R0RKjkisGHAhvYj89i7r3ytNUKW12y178KDZwXLXIgwDqLW6E/VRMT9qfld7wvFae8bQ==", - "dev": true, - "requires": { - "tfunk": "^4.0.0" - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "ejs": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz", - "integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==", - "dev": true, - "requires": { - "jake": "^10.6.1" - } - }, - "emittery": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", - "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "enabled": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", - "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==", - "dev": true - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true - }, - "encoding": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "dev": true, - "optional": true, - "requires": { - "iconv-lite": "^0.6.2" - }, - "dependencies": { - "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - } - } - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "engine.io": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.5.0.tgz", - "integrity": "sha512-21HlvPUKaitDGE4GXNtQ7PLP0Sz4aWLddMPw2VTyFz1FVZqu/kZsJUO8WNpKuE/OCL7nkfRaOui2ZCJloGznGA==", - "dev": true, - "requires": { - "accepts": "~1.3.4", - "base64id": "2.0.0", - "cookie": "~0.4.1", - "debug": "~4.1.0", - "engine.io-parser": "~2.2.0", - "ws": "~7.4.2" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "engine.io-client": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.5.2.tgz", - "integrity": "sha512-QEqIp+gJ/kMHeUun7f5Vv3bteRHppHH/FMBQX/esFj/fuYfjyUKWGMo3VCvIP/V8bE9KcjHmRZrhIz2Z9oNsDA==", - "dev": true, - "requires": { - "component-emitter": "~1.3.0", - "component-inherit": "0.0.3", - "debug": "~3.1.0", - "engine.io-parser": "~2.2.0", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "parseqs": "0.0.6", - "parseuri": "0.0.6", - "ws": "~7.4.2", - "xmlhttprequest-ssl": "~1.6.2", - "yeast": "0.1.2" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "engine.io-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.1.tgz", - "integrity": "sha512-x+dN/fBH8Ro8TFwJ+rkB2AmuVw9Yu2mockR/p3W8f8YtExwFgDvBDi0GWyb4ZLkpahtDGZgtr3zLovanJghPqg==", - "dev": true, - "requires": { - "after": "0.8.2", - "arraybuffer.slice": "~0.0.7", - "base64-arraybuffer": "0.1.4", - "blob": "0.0.5", - "has-binary2": "~1.0.2" - } - }, - "enhanced-resolve": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", - "integrity": "sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "dependencies": { - "tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true - } - } - }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" - } - }, - "entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" - }, - "env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true - }, - "envinfo": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", - "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", - "dev": true - }, - "err-code": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", - "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", - "dev": true - }, - "error": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/error/-/error-10.4.0.tgz", - "integrity": "sha512-YxIFEJuhgcICugOUvRx5th0UM+ActZ9sjY0QJmeVwsQdvosZ7kYzc9QqS0Da3R5iUmgU5meGIxh0xBeZpMVeLw==", - "dev": true - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", - "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "object-inspect": "^1.11.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - } - }, - "es-module-lexer": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", - "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", - "dev": true - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "escodegen": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", - "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", - "dev": true, - "requires": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - } - } - }, - "eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", - "dev": true, - "requires": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "eslint-config-prettier": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz", - "integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==", - "dev": true - }, - "eslint-plugin-react": { - "version": "7.26.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.26.1.tgz", - "integrity": "sha512-Lug0+NOFXeOE+ORZ5pbsh6mSKjBKXDXItUD2sQoT+5Yl0eoT82DqnXeTMfUare4QVCn9QwXbfzO/dBLjLXwVjQ==", - "dev": true, - "requires": { - "array-includes": "^3.1.3", - "array.prototype.flatmap": "^1.2.4", - "doctrine": "^2.1.0", - "estraverse": "^5.2.0", - "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "minimatch": "^3.0.4", - "object.entries": "^1.1.4", - "object.fromentries": "^2.0.4", - "object.hasown": "^1.0.0", - "object.values": "^1.1.4", - "prop-types": "^15.7.2", - "resolve": "^2.0.0-next.3", - "semver": "^6.3.0", - "string.prototype.matchall": "^4.0.5" - }, - "dependencies": { - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - } - }, - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - }, - "eslint-webpack-plugin": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-3.0.1.tgz", - "integrity": "sha512-PAHHDjCg2yWBNoiBPYLZWcv+M83urkslQKER7XvK84lo5YLcihJK6qwnCH2Fkt3eVdX+G1iyGZRlKsIhTiczHw==", - "dev": true, - "requires": { - "@types/eslint": "^7.2.14", - "jest-worker": "^27.0.6", - "micromatch": "^4.0.4", - "normalize-path": "^3.0.0", - "schema-utils": "^3.1.0" - } - }, - "espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, - "requires": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "estree-walker": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", - "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true - }, - "eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true - }, - "events": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", - "dev": true - }, - "execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - } - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true - }, - "expect": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.3.1.tgz", - "integrity": "sha512-MrNXV2sL9iDRebWPGOGFdPQRl2eDQNu/uhxIMShjjx74T6kC6jFIkmQ6OqXDtevjGUkyB2IT56RzDBqXf/QPCg==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "ansi-styles": "^5.0.0", - "jest-get-type": "^27.3.1", - "jest-matcher-utils": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-regex-util": "^27.0.6" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - } - } - }, - "express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", - "dev": true, - "requires": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", - "dev": true - }, - "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", - "dev": true - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - } - }, - "http-errors": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", - "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", - "dev": true - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "dev": true, - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "dependencies": { - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - } - } - }, - "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "dev": true, - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - } - }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", - "dev": true - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true - }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", - "dev": true - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true - }, - "faker": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/faker/-/faker-5.5.3.tgz", - "integrity": "sha512-wLTv2a28wjUyWkbnX7u/ABZBkUkIF2fCd73V6P2oFqEGEktDfzWx4UxrSqtPRw0xPRAcjeAOIiJWqZm3pP4u3g==", - "dev": true - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-glob": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", - "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "fastest-levenshtein": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", - "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", - "dev": true - }, - "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", - "dev": true, - "requires": { - "bser": "2.1.1" - } - }, - "fecha": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.1.tgz", - "integrity": "sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q==", - "dev": true - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "filelist": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz", - "integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==", - "dev": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "finalhandler": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", - "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.1", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.2", - "statuses": "~1.3.1", - "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "find-yarn-workspace-root2": { - "version": "1.2.16", - "resolved": "https://registry.npmjs.org/find-yarn-workspace-root2/-/find-yarn-workspace-root2-1.2.16.tgz", - "integrity": "sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==", - "dev": true, - "requires": { - "micromatch": "^4.0.2", - "pkg-dir": "^4.2.0" - } - }, - "first-chunk-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz", - "integrity": "sha1-G97NuOCDwGZLkZRVgVd6Q6nzHXA=", - "dev": true, - "requires": { - "readable-stream": "^2.0.2" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz", - "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==", - "dev": true - }, - "fn.name": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", - "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==", - "dev": true - }, - "follow-redirects": { - "version": "1.14.8", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz", - "integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==" - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, - "fork-ts-checker-webpack-plugin": { - "version": "6.3.4", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.3.4.tgz", - "integrity": "sha512-z0dns2NXH9NHH0wpW6iuUmyXYRN9BI2Lqnv+RCdL+9GXSW6tKUqYnwf+h3ZaucJsbsrdobdxuOELGgm1xVZITA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@types/json-schema": "^7.0.5", - "chalk": "^4.1.0", - "chokidar": "^3.4.2", - "cosmiconfig": "^6.0.0", - "deepmerge": "^4.2.2", - "fs-extra": "^9.0.0", - "glob": "^7.1.6", - "memfs": "^3.1.2", - "minimatch": "^3.0.4", - "schema-utils": "2.7.0", - "semver": "^7.3.2", - "tapable": "^1.0.0" - }, - "dependencies": { - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "schema-utils": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", - "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.4", - "ajv": "^6.12.2", - "ajv-keywords": "^3.4.1" - } - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - } - } - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "dev": true - }, - "fraction.js": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.1.2.tgz", - "integrity": "sha512-o2RiJQ6DZaR/5+Si0qJUIy637QMRudSi9kU/FFzx9EZazrIdnBgpU+3sEWCxAVhH2RtxW2Oz+T4p2o8uOPVcgA==", - "dev": true - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true - }, - "fs-extra": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", - "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^3.0.0", - "universalify": "^0.1.0" - } - }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "fs-monkey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", - "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dev": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } - }, - "generator-jhipster": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/generator-jhipster/-/generator-jhipster-7.3.1.tgz", - "integrity": "sha512-7B4PlBtZFcSz021SkbHYaCqr46NEm6NUrnGqIAFyY03nP60Maw4xAh/ZK2RqwCkA/L+jzwUuL1mcOzRQQzqTRg==", - "dev": true, - "requires": { - "aws-sdk": "2.1009.0", - "axios": "0.23.0", - "chalk": "4.1.2", - "chevrotain": "9.1.0", - "commander": "8.2.0", - "conf": "10.0.3", - "debug": "4.3.2", - "didyoumean": "1.2.2", - "ejs": "3.1.6", - "faker": "5.5.3", - "glob": "7.2.0", - "gulp-filter": "7.0.0", - "insight": "0.11.1", - "js-yaml": "4.1.0", - "lodash": "4.17.21", - "mem-fs-editor": "9.3.0", - "minimatch": "3.0.4", - "normalize-path": "3.0.0", - "os-locale": "5.0.0", - "p-queue": "6.6.2", - "parse-gitignore": "1.0.1", - "pluralize": "8.0.0", - "prettier": "2.4.1", - "prettier-plugin-java": "1.5.0", - "prettier-plugin-packagejson": "2.2.13", - "progress": "2.0.3", - "randexp": "0.5.3", - "semver": "7.3.5", - "shelljs": "0.8.4", - "simple-git": "2.46.0", - "then-request": "6.0.2", - "uuid": "8.3.2", - "winston": "3.3.3", - "yeoman-environment": "3.6.0", - "yeoman-generator": "5.4.2" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "axios": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.23.0.tgz", - "integrity": "sha512-NmvAE4i0YAv5cKq8zlDoPd1VLKAqX5oLuZKs8xkJa4qi6RGn0uhCYFjWtHHC9EM/MwOwYWOs53W+V0aqEXq1sg==", - "dev": true, - "requires": { - "follow-redirects": "^1.14.4" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "commander": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.2.0.tgz", - "integrity": "sha512-LLKxDvHeL91/8MIyTAD5BFMNtoIwztGPMiM/7Bl8rIPmHCZXRxmSWr91h57dpOpnQ6jIUqEWdXE/uBYMfiVZDA==", - "dev": true - }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-own-enumerable-property-symbols": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", - "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", - "dev": true - }, - "get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true - }, - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "git-hooks-list": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/git-hooks-list/-/git-hooks-list-1.0.3.tgz", - "integrity": "sha512-Y7wLWcrLUXwk2noSka166byGCvhMtDRpgHdzCno1UQv/n/Hegp++a2xBWJL1lJarnKD3SWaljD+0z1ztqxuKyQ==", - "dev": true - }, - "github-username": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/github-username/-/github-username-6.0.0.tgz", - "integrity": "sha512-7TTrRjxblSI5l6adk9zd+cV5d6i1OrJSo3Vr9xdGqFLBQo0mz5P9eIfKCDJ7eekVGGFLbce0qbPSnktXV2BjDQ==", - "dev": true, - "requires": { - "@octokit/rest": "^18.0.6" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true - }, - "globals": { - "version": "13.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", - "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "globby": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - } - }, - "graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", - "dev": true - }, - "grouped-queue": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/grouped-queue/-/grouped-queue-2.0.0.tgz", - "integrity": "sha512-/PiFUa7WIsl48dUeCvhIHnwNmAAzlI/eHoJl0vu3nsFA366JleY7Ff8EVTplZu5kO0MIdZjKTTnzItL61ahbnw==", - "dev": true - }, - "growly": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", - "dev": true - }, - "gud": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz", - "integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==" - }, - "gulp-filter": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/gulp-filter/-/gulp-filter-7.0.0.tgz", - "integrity": "sha512-ZGWtJo0j1mHfP77tVuhyqem4MRA5NfNRjoVe6VAkLGeQQ/QGo2VsFwp7zfPTGDsd1rwzBmoDHhxpE6f5B3Zuaw==", - "dev": true, - "requires": { - "multimatch": "^5.0.0", - "plugin-error": "^1.0.1", - "streamfilter": "^3.0.0", - "to-absolute-glob": "^2.0.2" - } - }, - "handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", - "dev": true - }, - "handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", - "dev": true, - "requires": { - "minimist": "^1.2.5", - "neo-async": "^2.6.0", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4", - "wordwrap": "^1.0.0" - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true - }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "dev": true, - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - } - }, - "harmony-reflect": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.1.tgz", - "integrity": "sha512-WJTeyp0JzGtHcuMsi7rw2VwtkvLa+JyfEKJCFyfcS0+CDkjQ5lHPu7zEhFZP+PDSRrEgXa5Ah0l1MbgbE41XjA==", - "dev": true - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - } - } - }, - "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "dev": true - }, - "has-binary2": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", - "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", - "dev": true, - "requires": { - "isarray": "2.0.1" - } - }, - "has-cors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", - "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "requires": { - "has-symbols": "^1.0.2" - } - }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "history": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", - "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", - "requires": { - "@babel/runtime": "^7.1.2", - "loose-envify": "^1.2.0", - "resolve-pathname": "^3.0.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0", - "value-equal": "^1.0.1" - } - }, - "hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "requires": { - "react-is": "^16.7.0" - } - }, - "hosted-git-info": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", - "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dev": true, - "requires": { - "whatwg-encoding": "^1.0.5" - } - }, - "html-entities": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.2.tgz", - "integrity": "sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ==", - "dev": true - }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "html-minifier-terser": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.0.2.tgz", - "integrity": "sha512-AgYO3UGhMYQx2S/FBJT3EM0ZYcKmH6m9XL9c1v77BeK/tYJxGPxT1/AtsdUi4FcP8kZGmqqnItCcjFPcX9hk6A==", - "dev": true, - "requires": { - "camel-case": "^4.1.2", - "clean-css": "^5.1.5", - "commander": "^8.1.0", - "he": "^1.2.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.7.2" - }, - "dependencies": { - "commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "dev": true - } - } - }, - "html-webpack-plugin": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.4.0.tgz", - "integrity": "sha512-cSUdckNOIqKc0nOrCJG7zkvzEIUcXjzEiVbKdEdIzW3BD5T4xPK6boV1mrTrPDZiL+aAr/j45eqbNL1akU2ZRA==", - "dev": true, - "requires": { - "@types/html-minifier-terser": "^6.0.0", - "html-minifier-terser": "^6.0.2", - "lodash": "^4.17.21", - "pretty-error": "^3.0.4", - "tapable": "^2.0.0" - }, - "dependencies": { - "tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true - } - } - }, - "htmlparser2": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" - }, - "dependencies": { - "dom-serializer": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", - "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - } - }, - "domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "requires": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - } - } - } - }, - "http-basic": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", - "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", - "dev": true, - "requires": { - "caseless": "^0.12.0", - "concat-stream": "^1.6.2", - "http-response-object": "^3.0.1", - "parse-cache-control": "^1.0.1" - } - }, - "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true - }, - "http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", - "dev": true - }, - "http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.1" - }, - "dependencies": { - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true - } - } - }, - "http-parser-js": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.3.tgz", - "integrity": "sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==", - "dev": true - }, - "http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dev": true, - "requires": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - } - }, - "http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dev": true, - "requires": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - } - }, - "http-proxy-middleware": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.1.tgz", - "integrity": "sha512-cfaXRVoZxSed/BmkA7SwBVNI9Kj7HFltaE5rqYOub5kWzWZ+gofV2koVN1j2rMW7pEfSSlCHGJ31xmuyFyfLOg==", - "dev": true, - "requires": { - "@types/http-proxy": "^1.17.5", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - }, - "dependencies": { - "is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", - "dev": true - } - } - }, - "http-response-object": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", - "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", - "dev": true, - "requires": { - "@types/node": "^10.0.3" - }, - "dependencies": { - "@types/node": { - "version": "10.17.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", - "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", - "dev": true - } - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", - "dev": true - }, - "humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", - "dev": true, - "requires": { - "ms": "^2.0.0" - } - }, - "husky": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/husky/-/husky-7.0.2.tgz", - "integrity": "sha512-8yKEWNX4z2YsofXAMT7KvA1g8p+GxtB1ffV8XtpAEGuXNAbCV5wdNKH+qTpw8SM9fh4aMPDR+yQuKfgnreyZlg==", - "dev": true - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "icss-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "dev": true - }, - "idb": { - "version": "6.1.5", - "resolved": "https://registry.npmjs.org/idb/-/idb-6.1.5.tgz", - "integrity": "sha512-IJtugpKkiVXQn5Y+LteyBCNk1N8xpGV3wWZk9EVtZWH8DYkjBn0bX1XnGP9RkyZF0sAcywa6unHqSWKe7q4LGw==", - "dev": true - }, - "identity-obj-proxy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", - "integrity": "sha1-lNK9qWCERT7zb7xarsN+D3nx/BQ=", - "dev": true, - "requires": { - "harmony-reflect": "^1.4.6" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "ignore": { - "version": "5.1.9", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.9.tgz", - "integrity": "sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==", - "dev": true - }, - "ignore-walk": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.4.tgz", - "integrity": "sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==", - "dev": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "immer": { - "version": "9.0.6", - "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.6.tgz", - "integrity": "sha512-G95ivKpy+EvVAnAab4fVa4YGYn24J1SpEktnJX7JJ45Bd7xqME/SCplFzYFmTbrkwZbQ4xJK1xMTUYBkN6pWsQ==" - }, - "immutable": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz", - "integrity": "sha1-wkOZUUVbs5kT2vKBN28VMOEErfM=", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "import-local": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.3.tgz", - "integrity": "sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==", - "dev": true, - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - }, - "indexof": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "inquirer": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", - "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", - "dev": true, - "requires": { - "ansi-escapes": "^3.2.0", - "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^2.0.0", - "lodash": "^4.17.12", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^6.4.0", - "string-width": "^2.1.0", - "strip-ansi": "^5.1.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - } - } - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - } - } - }, - "insight": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/insight/-/insight-0.11.1.tgz", - "integrity": "sha512-TBcZ0qC9dgdmcxL93OoqkY/RZXJtIi0i07phX/QyYk2ysmJtZex59dgTj4Doq50N9CG9dLRe/RIudc/5CCoFNw==", - "dev": true, - "requires": { - "async": "^2.6.2", - "chalk": "^4.1.1", - "conf": "^10.0.1", - "inquirer": "^6.3.1", - "lodash.debounce": "^4.0.8", - "os-name": "^4.0.1", - "request": "^2.88.0", - "tough-cookie": "^4.0.0", - "uuid": "^8.3.2" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "internal-ip": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-6.2.0.tgz", - "integrity": "sha512-D8WGsR6yDt8uq7vDMu7mjcR+yRMm3dW8yufyChmszWRjcSHuxLBkR3GdS2HZAjodsaGuCvXeEJpueisXJULghg==", - "dev": true, - "requires": { - "default-gateway": "^6.0.0", - "ipaddr.js": "^1.9.1", - "is-ip": "^3.1.0", - "p-event": "^4.2.0" - }, - "dependencies": { - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true - } - } - }, - "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - } - }, - "interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true - }, - "invert-kv": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-3.0.1.tgz", - "integrity": "sha512-CYdFeFexxhv/Bcny+Q0BfOV+ltRlJcd4BBZBYFX/O0u4npJrgZtIcjokegtiSMAvlMTJ+Koq0GBCc//3bueQxw==", - "dev": true - }, - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true - }, - "ip-regex": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz", - "integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==", - "dev": true - }, - "ipaddr.js": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.0.1.tgz", - "integrity": "sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==", - "dev": true - }, - "is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", - "dev": true, - "requires": { - "is-relative": "^1.0.0", - "is-windows": "^1.0.1" - } - }, - "is-absolute-url": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", - "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", - "dev": true - }, - "is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "requires": { - "has-bigints": "^1.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", - "dev": true - }, - "is-core-module": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", - "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-interactive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", - "dev": true - }, - "is-ip": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-3.1.0.tgz", - "integrity": "sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==", - "dev": true, - "requires": { - "ip-regex": "^4.0.0" - } - }, - "is-lambda": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", - "integrity": "sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=", - "dev": true - }, - "is-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", - "dev": true - }, - "is-negated-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", - "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", - "dev": true - }, - "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", - "dev": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-number-like": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/is-number-like/-/is-number-like-1.0.8.tgz", - "integrity": "sha512-6rZi3ezCyFcn5L71ywzz2bS5b2Igl1En3eTlZlvKjpz1n3IZLAYMbKYAIQgFmEu0GENg92ziU/faEOA/aixjbA==", - "dev": true, - "requires": { - "lodash.isfinite": "^3.3.2" - } - }, - "is-number-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true - }, - "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true - }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", - "dev": true - }, - "is-relative": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", - "dev": true, - "requires": { - "is-unc-path": "^1.0.0" - } - }, - "is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true - }, - "is-scoped": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-scoped/-/is-scoped-2.1.0.tgz", - "integrity": "sha512-Cv4OpPTHAK9kHYzkzCrof3VJh7H/PrG2MBUMvvJebaaUMbqhm0YAtXnvh0I3Hnj2tMZWwrRROWLSgfJrKqWmlQ==", - "dev": true, - "requires": { - "scoped-regex": "^2.0.0" - } - }, - "is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", - "dev": true - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true - }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "is-unc-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", - "dev": true, - "requires": { - "unc-path-regex": "^0.1.2" - } - }, - "is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true - }, - "is-weakref": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz", - "integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.0" - } - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "dev": true - }, - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", - "dev": true - }, - "isbinaryfile": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.8.tgz", - "integrity": "sha512-53h6XFniq77YdW+spoRrebh0mnmTxRPTlcuIArO57lmMdq4uBKFKaeTjnb92oYWrSn/LVL+LT+Hap2tFQj8V+w==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "istanbul": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz", - "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", - "dev": true, - "requires": { - "abbrev": "1.0.x", - "async": "1.x", - "escodegen": "1.8.x", - "esprima": "2.7.x", - "glob": "^5.0.15", - "handlebars": "^4.0.1", - "js-yaml": "3.x", - "mkdirp": "0.5.x", - "nopt": "3.x", - "once": "1.x", - "resolve": "1.1.x", - "supports-color": "^3.1.0", - "which": "^1.1.1", - "wordwrap": "^1.0.0" - }, - "dependencies": { - "escodegen": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", - "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", - "dev": true, - "requires": { - "esprima": "^2.7.1", - "estraverse": "^1.9.1", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.2.0" - } - }, - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", - "dev": true - }, - "estraverse": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", - "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", - "dev": true - }, - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true - }, - "source-map": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", - "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", - "dev": true, - "optional": true, - "requires": { - "amdefine": ">=0.0.4" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", - "dev": true - }, - "istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dev": true, - "requires": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - } - }, - "istanbul-reports": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.5.tgz", - "integrity": "sha512-5+19PlhnGabNWB7kOFnuxT8H3T/iIyQzIbQMxXsURmmvKg86P2sbkrGOT77VnHw0Qr0gc2XzRaRfMZYYbSQCJQ==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "jake": { - "version": "10.8.2", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz", - "integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==", - "dev": true, - "requires": { - "async": "0.9.x", - "chalk": "^2.4.2", - "filelist": "^1.0.1", - "minimatch": "^3.0.4" - }, - "dependencies": { - "async": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", - "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - } - } - }, - "java-parser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/java-parser/-/java-parser-2.0.0.tgz", - "integrity": "sha512-5sTEggUlp+uns7tfHGwRTN+cMlgPHw00oNjAz6YdwEyQyWQ9VzUNbYuPuDyJDWfcFyZTlHKD5f7VbtChKZf4xw==", - "dev": true, - "requires": { - "chevrotain": "6.5.0", - "lodash": "4.17.21" - }, - "dependencies": { - "chevrotain": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-6.5.0.tgz", - "integrity": "sha512-BwqQ/AgmKJ8jcMEjaSnfMybnKMgGTrtDKowfTP3pX4jwVy0kNjRsT/AP6h+wC3+3NC+X8X15VWBnTCQlX+wQFg==", - "dev": true, - "requires": { - "regexp-to-ast": "0.4.0" - } - }, - "regexp-to-ast": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/regexp-to-ast/-/regexp-to-ast-0.4.0.tgz", - "integrity": "sha512-4qf/7IsIKfSNHQXSwial1IFmfM1Cc/whNBQqRwe0V2stPe7KmN1U0tWQiIx6JiirgSrisjE0eECdNf7Tav1Ntw==", - "dev": true - } - } - }, - "jest": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.3.0.tgz", - "integrity": "sha512-ZSwT6ROUbUs3bXirxzxBvohE/1y7t+IHIu3fL8WgIeJppE2XsFoa2dB03CI9kXA81znW0Kt0t2R+QVOWeY8cYw==", - "dev": true, - "requires": { - "@jest/core": "^27.3.0", - "import-local": "^3.0.2", - "jest-cli": "^27.3.0" - }, - "dependencies": { - "jest-cli": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.3.1.tgz", - "integrity": "sha512-WHnCqpfK+6EvT62me6WVs8NhtbjAS4/6vZJnk7/2+oOr50cwAzG4Wxt6RXX0hu6m1169ZGMlhYYUNeKBXCph/Q==", - "dev": true, - "requires": { - "@jest/core": "^27.3.1", - "@jest/test-result": "^27.3.1", - "@jest/types": "^27.2.5", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "import-local": "^3.0.2", - "jest-config": "^27.3.1", - "jest-util": "^27.3.1", - "jest-validate": "^27.3.1", - "prompts": "^2.0.1", - "yargs": "^16.2.0" - } - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - } - } - }, - "jest-changed-files": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.3.0.tgz", - "integrity": "sha512-9DJs9garMHv4RhylUMZgbdCJ3+jHSkpL9aaVKp13xtXAD80qLTLrqcDZL1PHA9dYA0bCI86Nv2BhkLpLhrBcPg==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "execa": "^5.0.0", - "throat": "^6.0.1" - }, - "dependencies": { - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true - } - } - }, - "jest-circus": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.3.1.tgz", - "integrity": "sha512-v1dsM9II6gvXokgqq6Yh2jHCpfg7ZqV4jWY66u7npz24JnhP3NHxI0sKT7+ZMQ7IrOWHYAaeEllOySbDbWsiXw==", - "dev": true, - "requires": { - "@jest/environment": "^27.3.1", - "@jest/test-result": "^27.3.1", - "@jest/types": "^27.2.5", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "expect": "^27.3.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.3.1", - "jest-matcher-utils": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-runtime": "^27.3.1", - "jest-snapshot": "^27.3.1", - "jest-util": "^27.3.1", - "pretty-format": "^27.3.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" - } - }, - "jest-config": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.3.1.tgz", - "integrity": "sha512-KY8xOIbIACZ/vdYCKSopL44I0xboxC751IX+DXL2+Wx6DKNycyEfV3rryC3BPm5Uq/BBqDoMrKuqLEUNJmMKKg==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^27.3.1", - "@jest/types": "^27.2.5", - "babel-jest": "^27.3.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-circus": "^27.3.1", - "jest-environment-jsdom": "^27.3.1", - "jest-environment-node": "^27.3.1", - "jest-get-type": "^27.3.1", - "jest-jasmine2": "^27.3.1", - "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.3.1", - "jest-runner": "^27.3.1", - "jest-util": "^27.3.1", - "jest-validate": "^27.3.1", - "micromatch": "^4.0.4", - "pretty-format": "^27.3.1" - } - }, - "jest-diff": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.3.1.tgz", - "integrity": "sha512-PCeuAH4AWUo2O5+ksW4pL9v5xJAcIKPUPfIhZBcG1RKv/0+dvaWTQK1Nrau8d67dp65fOqbeMdoil+6PedyEPQ==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^27.0.6", - "jest-get-type": "^27.3.1", - "pretty-format": "^27.3.1" - } - }, - "jest-docblock": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.0.6.tgz", - "integrity": "sha512-Fid6dPcjwepTFraz0YxIMCi7dejjJ/KL9FBjPYhBp4Sv1Y9PdhImlKZqYU555BlN4TQKaTc+F2Av1z+anVyGkA==", - "dev": true, - "requires": { - "detect-newline": "^3.0.0" - } - }, - "jest-each": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.3.1.tgz", - "integrity": "sha512-E4SwfzKJWYcvOYCjOxhZcxwL+AY0uFMvdCOwvzgutJiaiodFjkxQQDxHm8FQBeTqDnSmKsQWn7ldMRzTn2zJaQ==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "chalk": "^4.0.0", - "jest-get-type": "^27.3.1", - "jest-util": "^27.3.1", - "pretty-format": "^27.3.1" - } - }, - "jest-environment-jsdom": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.3.1.tgz", - "integrity": "sha512-3MOy8qMzIkQlfb3W1TfrD7uZHj+xx8Olix5vMENkj5djPmRqndMaXtpnaZkxmxM+Qc3lo+yVzJjzuXbCcZjAlg==", - "dev": true, - "requires": { - "@jest/environment": "^27.3.1", - "@jest/fake-timers": "^27.3.1", - "@jest/types": "^27.2.5", - "@types/node": "*", - "jest-mock": "^27.3.0", - "jest-util": "^27.3.1", - "jsdom": "^16.6.0" - } - }, - "jest-environment-node": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.3.1.tgz", - "integrity": "sha512-T89F/FgkE8waqrTSA7/ydMkcc52uYPgZZ6q8OaZgyiZkJb5QNNCF6oPZjH9IfPFfcc9uBWh1574N0kY0pSvTXw==", - "dev": true, - "requires": { - "@jest/environment": "^27.3.1", - "@jest/fake-timers": "^27.3.1", - "@jest/types": "^27.2.5", - "@types/node": "*", - "jest-mock": "^27.3.0", - "jest-util": "^27.3.1" - } - }, - "jest-get-type": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.3.1.tgz", - "integrity": "sha512-+Ilqi8hgHSAdhlQ3s12CAVNd8H96ZkQBfYoXmArzZnOfAtVAJEiPDBirjByEblvG/4LPJmkL+nBqPO3A1YJAEg==", - "dev": true - }, - "jest-haste-map": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.3.1.tgz", - "integrity": "sha512-lYfNZIzwPccDJZIyk9Iz5iQMM/MH56NIIcGj7AFU1YyA4ewWFBl8z+YPJuSCRML/ee2cCt2y3W4K3VXPT6Nhzg==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.3.2", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^27.0.6", - "jest-serializer": "^27.0.6", - "jest-util": "^27.3.1", - "jest-worker": "^27.3.1", - "micromatch": "^4.0.4", - "walker": "^1.0.7" - } - }, - "jest-jasmine2": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.3.1.tgz", - "integrity": "sha512-WK11ZUetDQaC09w4/j7o4FZDUIp+4iYWH/Lik34Pv7ukL+DuXFGdnmmi7dT58J2ZYKFB5r13GyE0z3NPeyJmsg==", - "dev": true, - "requires": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^27.3.1", - "@jest/source-map": "^27.0.6", - "@jest/test-result": "^27.3.1", - "@jest/types": "^27.2.5", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^27.3.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.3.1", - "jest-matcher-utils": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-runtime": "^27.3.1", - "jest-snapshot": "^27.3.1", - "jest-util": "^27.3.1", - "pretty-format": "^27.3.1", - "throat": "^6.0.1" - } - }, - "jest-junit": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-13.0.0.tgz", - "integrity": "sha512-JSHR+Dhb32FGJaiKkqsB7AR3OqWKtldLd6ZH2+FJ8D4tsweb8Id8zEVReU4+OlrRO1ZluqJLQEETm+Q6/KilBg==", - "dev": true, - "requires": { - "mkdirp": "^1.0.4", - "strip-ansi": "^6.0.1", - "uuid": "^8.3.2", - "xml": "^1.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "jest-leak-detector": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.3.1.tgz", - "integrity": "sha512-78QstU9tXbaHzwlRlKmTpjP9k4Pvre5l0r8Spo4SbFFVy/4Abg9I6ZjHwjg2QyKEAMg020XcjP+UgLZIY50yEg==", - "dev": true, - "requires": { - "jest-get-type": "^27.3.1", - "pretty-format": "^27.3.1" - } - }, - "jest-matcher-utils": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.3.1.tgz", - "integrity": "sha512-hX8N7zXS4k+8bC1Aj0OWpGb7D3gIXxYvPNK1inP5xvE4ztbz3rc4AkI6jGVaerepBnfWB17FL5lWFJT3s7qo8w==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^27.3.1", - "jest-get-type": "^27.3.1", - "pretty-format": "^27.3.1" - } - }, - "jest-message-util": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.3.1.tgz", - "integrity": "sha512-bh3JEmxsTZ/9rTm0jQrPElbY2+y48Rw2t47uMfByNyUVR+OfPh4anuyKsGqsNkXk/TI4JbLRZx+7p7Hdt6q1yg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.2.5", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.4", - "pretty-format": "^27.3.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-mock": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.3.0.tgz", - "integrity": "sha512-ziZiLk0elZOQjD08bLkegBzv5hCABu/c8Ytx45nJKkysQwGaonvmTxwjLqEA4qGdasq9o2I8/HtdGMNnVsMTGw==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "@types/node": "*" - } - }, - "jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true - }, - "jest-regex-util": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.6.tgz", - "integrity": "sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ==", - "dev": true - }, - "jest-resolve": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.3.1.tgz", - "integrity": "sha512-Dfzt25CFSPo3Y3GCbxynRBZzxq9AdyNN+x/v2IqYx6KVT5Z6me2Z/PsSGFSv3cOSUZqJ9pHxilao/I/m9FouLw==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.1", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.3.1", - "jest-validate": "^27.3.1", - "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", - "slash": "^3.0.0" - }, - "dependencies": { - "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "dev": true, - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - } - } - }, - "jest-resolve-dependencies": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.3.1.tgz", - "integrity": "sha512-X7iLzY8pCiYOnvYo2YrK3P9oSE8/3N2f4pUZMJ8IUcZnT81vlSonya1KTO9ZfKGuC+svE6FHK/XOb8SsoRUV1A==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "jest-regex-util": "^27.0.6", - "jest-snapshot": "^27.3.1" - } - }, - "jest-runner": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.3.1.tgz", - "integrity": "sha512-r4W6kBn6sPr3TBwQNmqE94mPlYVn7fLBseeJfo4E2uCTmAyDFm2O5DYAQAFP7Q3YfiA/bMwg8TVsciP7k0xOww==", - "dev": true, - "requires": { - "@jest/console": "^27.3.1", - "@jest/environment": "^27.3.1", - "@jest/test-result": "^27.3.1", - "@jest/transform": "^27.3.1", - "@jest/types": "^27.2.5", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-docblock": "^27.0.6", - "jest-environment-jsdom": "^27.3.1", - "jest-environment-node": "^27.3.1", - "jest-haste-map": "^27.3.1", - "jest-leak-detector": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-resolve": "^27.3.1", - "jest-runtime": "^27.3.1", - "jest-util": "^27.3.1", - "jest-worker": "^27.3.1", - "source-map-support": "^0.5.6", - "throat": "^6.0.1" - } - }, - "jest-runtime": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.3.1.tgz", - "integrity": "sha512-qtO6VxPbS8umqhEDpjA4pqTkKQ1Hy4ZSi9mDVeE9Za7LKBo2LdW2jmT+Iod3XFaJqINikZQsn2wEi0j9wPRbLg==", - "dev": true, - "requires": { - "@jest/console": "^27.3.1", - "@jest/environment": "^27.3.1", - "@jest/globals": "^27.3.1", - "@jest/source-map": "^27.0.6", - "@jest/test-result": "^27.3.1", - "@jest/transform": "^27.3.1", - "@jest/types": "^27.2.5", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "execa": "^5.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-mock": "^27.3.0", - "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.3.1", - "jest-snapshot": "^27.3.1", - "jest-util": "^27.3.1", - "jest-validate": "^27.3.1", - "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^16.2.0" - }, - "dependencies": { - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true - }, - "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - } - } - }, - "jest-serializer": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.0.6.tgz", - "integrity": "sha512-PtGdVK9EGC7dsaziskfqaAPib6wTViY3G8E5wz9tLVPhHyiDNTZn/xjZ4khAw+09QkoOVpn7vF5nPSN6dtBexA==", - "dev": true, - "requires": { - "@types/node": "*", - "graceful-fs": "^4.2.4" - } - }, - "jest-snapshot": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.3.1.tgz", - "integrity": "sha512-APZyBvSgQgOT0XumwfFu7X3G5elj6TGhCBLbBdn3R1IzYustPGPE38F51dBWMQ8hRXa9je0vAdeVDtqHLvB6lg==", - "dev": true, - "requires": { - "@babel/core": "^7.7.2", - "@babel/generator": "^7.7.2", - "@babel/parser": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.0.0", - "@jest/transform": "^27.3.1", - "@jest/types": "^27.2.5", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^27.3.1", - "graceful-fs": "^4.2.4", - "jest-diff": "^27.3.1", - "jest-get-type": "^27.3.1", - "jest-haste-map": "^27.3.1", - "jest-matcher-utils": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-resolve": "^27.3.1", - "jest-util": "^27.3.1", - "natural-compare": "^1.4.0", - "pretty-format": "^27.3.1", - "semver": "^7.3.2" - } - }, - "jest-sonar-reporter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jest-sonar-reporter/-/jest-sonar-reporter-2.0.0.tgz", - "integrity": "sha512-ZervDCgEX5gdUbdtWsjdipLN3bKJwpxbvhkYNXTAYvAckCihobSLr9OT/IuyNIRT1EZMDDwR6DroWtrq+IL64w==", - "dev": true, - "requires": { - "xml": "^1.0.1" - } - }, - "jest-util": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.3.1.tgz", - "integrity": "sha512-8fg+ifEH3GDryLQf/eKZck1DEs2YuVPBCMOaHQxVVLmQwl/CDhWzrvChTX4efLZxGrw+AA0mSXv78cyytBt/uw==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.4", - "picomatch": "^2.2.3" - } - }, - "jest-validate": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.3.1.tgz", - "integrity": "sha512-3H0XCHDFLA9uDII67Bwi1Vy7AqwA5HqEEjyy934lgVhtJ3eisw6ShOF1MDmRPspyikef5MyExvIm0/TuLzZ86Q==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^27.3.1", - "leven": "^3.1.0", - "pretty-format": "^27.3.1" - }, - "dependencies": { - "camelcase": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.1.tgz", - "integrity": "sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==", - "dev": true - } - } - }, - "jest-watcher": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.3.1.tgz", - "integrity": "sha512-9/xbV6chABsGHWh9yPaAGYVVKurWoP3ZMCv6h+O1v9/+pkOroigs6WzZ0e9gLP/njokUwM7yQhr01LKJVMkaZA==", - "dev": true, - "requires": { - "@jest/test-result": "^27.3.1", - "@jest/types": "^27.2.5", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^27.3.1", - "string-length": "^4.0.1" - }, - "dependencies": { - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "requires": { - "type-fest": "^0.21.3" - } - }, - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true - } - } - }, - "jest-worker": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.3.1.tgz", - "integrity": "sha512-ks3WCzsiZaOPJl/oMsDjaf0TRiSv7ctNgs0FqRr2nARsovz6AWWy4oLElwcquGSz692DzgZQrCLScPNs5YlC4g==", - "dev": true, - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jmespath": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", - "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=", - "dev": true - }, - "joi": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.4.2.tgz", - "integrity": "sha512-Lm56PP+n0+Z2A2rfRvsfWVDXGEWjXxatPopkQ8qQ5mxCEhwHG+Ettgg5o98FFaxilOxozoa14cFhrE/hOzh/Nw==", - "dev": true, - "requires": { - "@hapi/hoek": "^9.0.0", - "@hapi/topo": "^5.0.0", - "@sideway/address": "^4.1.0", - "@sideway/formula": "^3.0.0", - "@sideway/pinpoint": "^2.0.0" - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true - }, - "jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", - "dev": true, - "requires": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" - }, - "dependencies": { - "acorn": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", - "dev": true - }, - "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dev": true, - "requires": { - "punycode": "^2.1.1" - } - }, - "webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "dev": true - }, - "whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "dev": true, - "requires": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - } - } - } - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "json-loader": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz", - "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==", - "dev": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-schema-typed": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-7.0.3.tgz", - "integrity": "sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "json-stringify-nice": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/json-stringify-nice/-/json-stringify-nice-1.1.4.tgz", - "integrity": "sha512-5Z5RFW63yxReJ7vANgW6eZFGWaQvnPE3WNmZoOJrSkGju2etKA2L5rrOa1sm877TVTFt57A80BH1bArcmlLfPw==", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "jsonfile": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", - "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", - "dev": true - }, - "jsonpointer": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.0.tgz", - "integrity": "sha512-PNYZIdMjVIvVgDSYKTT63Y+KZ6IZvGRNNWcxwD+GNnUz1MKPfv30J8ueCjdwcN0nDx2SlshgyB7Oy0epAzVRRg==", - "dev": true - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jsx-ast-utils": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.1.tgz", - "integrity": "sha512-uP5vu8xfy2F9A6LGC22KO7e2/vGTS1MhP+18f++ZNlf0Ohaxbc9nIEwHAsejlJKyzfZzU5UIhe5ItYkitcZnZA==", - "dev": true, - "requires": { - "array-includes": "^3.1.3", - "object.assign": "^4.1.2" - } - }, - "just-diff": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/just-diff/-/just-diff-3.1.1.tgz", - "integrity": "sha512-sdMWKjRq8qWZEjDcVA6llnUT8RDEBIfOiGpYFPYa9u+2c39JCsejktSP7mj5eRid5EIvTzIpQ2kDOCw1Nq9BjQ==", - "dev": true - }, - "just-diff-apply": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/just-diff-apply/-/just-diff-apply-3.1.2.tgz", - "integrity": "sha512-TCa7ZdxCeq6q3Rgms2JCRHTCfWAETPZ8SzYUbkYF6KR3I03sN29DaOIC+xyWboIcMvjAsD5iG2u/RWzHD8XpgQ==", - "dev": true - }, - "just-extend": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", - "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true - }, - "klona": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.5.tgz", - "integrity": "sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==", - "dev": true - }, - "kuler": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", - "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==", - "dev": true - }, - "lcid": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-3.1.1.tgz", - "integrity": "sha512-M6T051+5QCGLBQb8id3hdvIW8+zeFV2FyBGFS9IEK5H9Wt4MueD4bW1eWikpHgZp+5xR3l5c8pZUkQsIA0BFZg==", - "dev": true, - "requires": { - "invert-kv": "^3.0.0" - } - }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "lilconfig": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.4.tgz", - "integrity": "sha512-bfTIN7lEsiooCocSISTWXkiWJkRqtL9wYtYy+8EK3Y41qh3mpwPU0ycTOgjdY9ErwXCc8QyrQp82bdL0Xkm9yA==", - "dev": true - }, - "limiter": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", - "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==", - "dev": true - }, - "lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", - "dev": true - }, - "lint-staged": { - "version": "11.2.3", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-11.2.3.tgz", - "integrity": "sha512-Tfmhk8O2XFMD25EswHPv+OYhUjsijy5D7liTdxeXvhG2rsadmOLFtyj8lmlfoFFXY8oXWAIOKpoI+lJe1DB1mw==", - "dev": true, - "requires": { - "cli-truncate": "2.1.0", - "colorette": "^1.4.0", - "commander": "^8.2.0", - "cosmiconfig": "^7.0.1", - "debug": "^4.3.2", - "enquirer": "^2.3.6", - "execa": "^5.1.1", - "listr2": "^3.12.2", - "micromatch": "^4.0.4", - "normalize-path": "^3.0.0", - "please-upgrade-node": "^3.2.0", - "string-argv": "0.3.1", - "stringify-object": "3.3.0", - "supports-color": "8.1.1" - }, - "dependencies": { - "colorette": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", - "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", - "dev": true - }, - "commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "dev": true - }, - "cosmiconfig": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", - "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", - "dev": true, - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - } - }, - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "listr2": { - "version": "3.13.4", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.13.4.tgz", - "integrity": "sha512-lZ1Rut1DSIRwbxQbI8qaUBfOWJ1jEYRgltIM97j6kKOCI2pHVWMyxZvkU/JKmRBWcIYgDS2PK+yDgVqm7u3crw==", - "dev": true, - "requires": { - "cli-truncate": "^2.1.0", - "clone": "^2.1.2", - "colorette": "^2.0.16", - "log-update": "^4.0.0", - "p-map": "^4.0.0", - "rxjs": "^7.4.0", - "through": "^2.3.8", - "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", - "dev": true - }, - "colorette": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", - "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", - "dev": true - }, - "rxjs": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.4.0.tgz", - "integrity": "sha512-7SQDi7xeTMCJpqViXh8gL/lebcwlp3d831F05+9B44A4B0WfsEwUQHR64gsH1kvJ+Ep/J9K2+n1hVl1CsGN23w==", - "dev": true, - "requires": { - "tslib": "~2.1.0" - } - }, - "tslib": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", - "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", - "dev": true - } - } - }, - "load-yaml-file": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/load-yaml-file/-/load-yaml-file-0.2.0.tgz", - "integrity": "sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.5", - "js-yaml": "^3.13.0", - "pify": "^4.0.1", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - } - } - }, - "loader-runner": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", - "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", - "dev": true - }, - "localtunnel": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/localtunnel/-/localtunnel-2.0.2.tgz", - "integrity": "sha512-n418Cn5ynvJd7m/N1d9WVJISLJF/ellZnfsLnx8WBWGzxv/ntNcFkJ1o6se5quUhCplfLGBNL5tYHiq5WF3Nug==", - "dev": true, - "requires": { - "axios": "0.21.4", - "debug": "4.3.2", - "openurl": "1.1.1", - "yargs": "17.1.1" - }, - "dependencies": { - "yargs": { - "version": "17.1.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.1.1.tgz", - "integrity": "sha512-c2k48R0PwKIqKhPMWjeiF6y2xY/gPMUlro0sgxqXpbOIohWiLNXWslsootttv7E1e73QPAMQSg5FeySbVcpsPQ==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - } - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", - "dev": true - }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" - }, - "lodash.isfinite": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz", - "integrity": "sha1-+4m2WpqAKBgz8LdHizpRBPiY67M=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", - "dev": true - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", - "dev": true - }, - "lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", - "dev": true - }, - "lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", - "dev": true - }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - } - }, - "log-update": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", - "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", - "dev": true, - "requires": { - "ansi-escapes": "^4.3.0", - "cli-cursor": "^3.1.0", - "slice-ansi": "^4.0.0", - "wrap-ansi": "^6.2.0" - }, - "dependencies": { - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "requires": { - "type-fest": "^0.21.3" - } - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "requires": { - "restore-cursor": "^3.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true - }, - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - } - } - }, - "logform": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.3.0.tgz", - "integrity": "sha512-graeoWUH2knKbGthMtuG1EfaSPMZFZBIrhuJHhkS5ZseFBrc7DupCzihOQAzsK/qIKPQaPJ/lFQFctILUY5ARQ==", - "dev": true, - "requires": { - "colors": "^1.2.1", - "fecha": "^4.2.0", - "ms": "^2.1.1", - "safe-stable-stringify": "^1.1.0", - "triple-beam": "^1.3.0" - } - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "dev": true, - "requires": { - "tslib": "^2.0.3" - } - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "lz-string": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", - "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=", - "dev": true - }, - "macos-release": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.5.0.tgz", - "integrity": "sha512-EIgv+QZ9r+814gjJj0Bt5vSLJLzswGmSUbUpbi9AIr/fsN2IWFBl2NucV9PAiek+U1STK468tEkxmVYUtuAN3g==", - "dev": true - }, - "magic-string": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", - "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", - "dev": true, - "requires": { - "sourcemap-codec": "^1.4.4" - } - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "make-fetch-happen": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz", - "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==", - "dev": true, - "requires": { - "agentkeepalive": "^4.1.3", - "cacache": "^15.2.0", - "http-cache-semantics": "^4.1.0", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^6.0.0", - "minipass": "^3.1.3", - "minipass-collect": "^1.0.2", - "minipass-fetch": "^1.3.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.2", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^6.0.0", - "ssri": "^8.0.0" - } - }, - "makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "requires": { - "tmpl": "1.0.5" - } - }, - "map-age-cleaner": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", - "dev": true, - "requires": { - "p-defer": "^1.0.0" - } - }, - "mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", - "dev": true - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true - }, - "mem": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/mem/-/mem-5.1.1.tgz", - "integrity": "sha512-qvwipnozMohxLXG1pOqoLiZKNkC4r4qqRucSoDwXowsNGDSULiqFTRUF05vcZWnwJSG22qTsynQhxbaMtnX9gw==", - "dev": true, - "requires": { - "map-age-cleaner": "^0.1.3", - "mimic-fn": "^2.1.0", - "p-is-promise": "^2.1.0" - }, - "dependencies": { - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - } - } - }, - "mem-fs": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/mem-fs/-/mem-fs-2.2.1.tgz", - "integrity": "sha512-yiAivd4xFOH/WXlUi6v/nKopBh1QLzwjFi36NK88cGt/PRXI8WeBASqY+YSjIVWvQTx3hR8zHKDBMV6hWmglNA==", - "dev": true, - "requires": { - "@types/node": "^15.6.1", - "@types/vinyl": "^2.0.4", - "vinyl": "^2.0.1", - "vinyl-file": "^3.0.0" - }, - "dependencies": { - "@types/node": { - "version": "15.14.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-15.14.9.tgz", - "integrity": "sha512-qjd88DrCxupx/kJD5yQgZdcYKZKSIGBVDIBE1/LTGcNm3d2Np/jxojkdePDdfnBHJc5W7vSMpbJ1aB7p/Py69A==", - "dev": true - } - } - }, - "mem-fs-editor": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/mem-fs-editor/-/mem-fs-editor-9.3.0.tgz", - "integrity": "sha512-QKFbPwGCh1ypmc2H8BUYpbapwT/x2AOCYZQogzSui4rUNes7WVMagQXsirPIfp18EarX0SSY9Fpg426nSjew4Q==", - "dev": true, - "requires": { - "binaryextensions": "^4.16.0", - "commondir": "^1.0.1", - "deep-extend": "^0.6.0", - "ejs": "^3.1.6", - "globby": "^11.0.3", - "isbinaryfile": "^4.0.8", - "minimatch": "^3.0.4", - "multimatch": "^5.0.0", - "normalize-path": "^3.0.0", - "textextensions": "^5.13.0" - } - }, - "memfs": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.3.0.tgz", - "integrity": "sha512-BEE62uMfKOavX3iG7GYX43QJ+hAeeWnwIAuJ/R6q96jaMtiLzhsxHJC8B1L7fK7Pt/vXDRwb3SG/yBpNGDPqzg==", - "dev": true, - "requires": { - "fs-monkey": "1.0.3" - } - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", - "dev": true - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "dev": true - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "mime": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", - "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", - "dev": true - }, - "mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", - "dev": true - }, - "mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", - "dev": true, - "requires": { - "mime-db": "1.51.0" - } - }, - "mimic-fn": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", - "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==", - "dev": true - }, - "mini-create-react-context": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz", - "integrity": "sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==", - "requires": { - "@babel/runtime": "^7.12.1", - "tiny-warning": "^1.0.3" - } - }, - "mini-css-extract-plugin": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.4.2.tgz", - "integrity": "sha512-ZmqShkn79D36uerdED+9qdo1ZYG8C1YsWvXu0UMJxurZnSdgz7gQKO2EGv8T55MhDqG3DYmGtizZNpM/UbTlcA==", - "dev": true, - "requires": { - "schema-utils": "^3.1.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true - }, - "minipass": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.5.tgz", - "integrity": "sha512-+8NzxD82XQoNKNrl1d/FSi+X8wAEWR+sbYAfIvub4Nz0d22plFG72CEVVaufV8PNf4qSslFTD8VMOxNVhHCjTw==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "minipass-collect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", - "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass-fetch": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz", - "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==", - "dev": true, - "requires": { - "encoding": "^0.1.12", - "minipass": "^3.1.0", - "minipass-sized": "^1.0.3", - "minizlib": "^2.0.0" - } - }, - "minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass-json-stream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz", - "integrity": "sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==", - "dev": true, - "requires": { - "jsonparse": "^1.3.1", - "minipass": "^3.0.0" - } - }, - "minipass-pipeline": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass-sized": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", - "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - } - }, - "mitt": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mitt/-/mitt-1.2.0.tgz", - "integrity": "sha512-r6lj77KlwqLhIUku9UWYes7KJtsczvolZkzp8hbaDPPaE24OmWl5s539Mytlj22siEQKosZ26qCBgda2PKwoJw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "mkdirp-infer-owner": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mkdirp-infer-owner/-/mkdirp-infer-owner-2.0.0.tgz", - "integrity": "sha512-sdqtiFt3lkOaYvTXSRIUjkIdPTcxgv5+fgqYE/5qgwdw12cOrAuzzgzvVExIkH/ul1oeHN3bCLOWSG3XOqbKKw==", - "dev": true, - "requires": { - "chownr": "^2.0.0", - "infer-owner": "^1.0.4", - "mkdirp": "^1.0.3" - }, - "dependencies": { - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - } - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "multicast-dns": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", - "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", - "dev": true, - "requires": { - "dns-packet": "^1.3.1", - "thunky": "^1.0.2" - } - }, - "multicast-dns-service-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", - "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", - "dev": true - }, - "multimatch": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz", - "integrity": "sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==", - "dev": true, - "requires": { - "@types/minimatch": "^3.0.3", - "array-differ": "^3.0.0", - "array-union": "^2.1.0", - "arrify": "^2.0.1", - "minimatch": "^3.0.4" - } - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true - }, - "nanoid": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz", - "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==" - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", - "dev": true - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "nise": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.0.tgz", - "integrity": "sha512-W5WlHu+wvo3PaKLsJJkgPup2LrsXCcm7AWwyNZkUnn5rwPkuPBi3Iwk5SQtN0mv+K65k7nKKjwNQ30wg3wLAQQ==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0", - "@sinonjs/fake-timers": "^7.0.4", - "@sinonjs/text-encoding": "^0.7.1", - "just-extend": "^4.0.2", - "path-to-regexp": "^1.7.0" - }, - "dependencies": { - "@sinonjs/fake-timers": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz", - "integrity": "sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - } - } - }, - "no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "dev": true, - "requires": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dev": true, - "requires": { - "whatwg-url": "^5.0.0" - } - }, - "node-forge": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", - "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", - "dev": true - }, - "node-gyp": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz", - "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==", - "dev": true, - "requires": { - "env-paths": "^2.2.0", - "glob": "^7.1.4", - "graceful-fs": "^4.2.3", - "nopt": "^5.0.0", - "npmlog": "^4.1.2", - "request": "^2.88.2", - "rimraf": "^3.0.2", - "semver": "^7.3.2", - "tar": "^6.0.2", - "which": "^2.0.2" - }, - "dependencies": { - "nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "dev": true, - "requires": { - "abbrev": "1" - } - } - } - }, - "node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", - "dev": true - }, - "node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", - "dev": true - }, - "node-notifier": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-9.0.1.tgz", - "integrity": "sha512-fPNFIp2hF/Dq7qLDzSg4vZ0J4e9v60gJR+Qx7RbjbWqzPDdEqeVpEx5CFeDAELIl+A/woaaNn1fQ5nEVerMxJg==", - "dev": true, - "requires": { - "growly": "^1.3.0", - "is-wsl": "^2.2.0", - "semver": "^7.3.2", - "shellwords": "^0.1.1", - "uuid": "^8.3.0", - "which": "^2.0.2" - }, - "dependencies": { - "is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "requires": { - "is-docker": "^2.0.0" - } - } - } - }, - "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", - "dev": true, - "requires": { - "abbrev": "1" - } - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "dev": true, - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", - "dev": true - }, - "normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "dev": true - }, - "npm-bundled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz", - "integrity": "sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==", - "dev": true, - "requires": { - "npm-normalize-package-bin": "^1.0.1" - } - }, - "npm-install-checks": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-4.0.0.tgz", - "integrity": "sha512-09OmyDkNLYwqKPOnbI8exiOZU2GVVmQp7tgez2BPi5OZC8M82elDAps7sxC4l//uSUtotWqoEIDwjRvWH4qz8w==", - "dev": true, - "requires": { - "semver": "^7.1.1" - } - }, - "npm-normalize-package-bin": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", - "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", - "dev": true - }, - "npm-package-arg": { - "version": "8.1.5", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-8.1.5.tgz", - "integrity": "sha512-LhgZrg0n0VgvzVdSm1oiZworPbTxYHUJCgtsJW8mGvlDpxTM1vSJc3m5QZeUkhAHIzbz3VCHd/R4osi1L1Tg/Q==", - "dev": true, - "requires": { - "hosted-git-info": "^4.0.1", - "semver": "^7.3.4", - "validate-npm-package-name": "^3.0.0" - } - }, - "npm-packlist": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-2.2.2.tgz", - "integrity": "sha512-Jt01acDvJRhJGthnUJVF/w6gumWOZxO7IkpY/lsX9//zqQgnF7OJaxgQXcerd4uQOLu7W5bkb4mChL9mdfm+Zg==", - "dev": true, - "requires": { - "glob": "^7.1.6", - "ignore-walk": "^3.0.3", - "npm-bundled": "^1.1.1", - "npm-normalize-package-bin": "^1.0.1" - } - }, - "npm-pick-manifest": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-6.1.1.tgz", - "integrity": "sha512-dBsdBtORT84S8V8UTad1WlUyKIY9iMsAmqxHbLdeEeBNMLQDlDWWra3wYUx9EBEIiG/YwAy0XyNHDd2goAsfuA==", - "dev": true, - "requires": { - "npm-install-checks": "^4.0.0", - "npm-normalize-package-bin": "^1.0.1", - "npm-package-arg": "^8.1.2", - "semver": "^7.3.4" - } - }, - "npm-registry-fetch": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-11.0.0.tgz", - "integrity": "sha512-jmlgSxoDNuhAtxUIG6pVwwtz840i994dL14FoNVZisrmZW5kWd63IUTNv1m/hyRSGSqWjCUp/YZlS1BJyNp9XA==", - "dev": true, - "requires": { - "make-fetch-happen": "^9.0.1", - "minipass": "^3.1.3", - "minipass-fetch": "^1.3.0", - "minipass-json-stream": "^1.0.1", - "minizlib": "^2.0.0", - "npm-package-arg": "^8.0.0" - } - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "requires": { - "path-key": "^3.0.0" - } - }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dev": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "nth-check": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz", - "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==", - "dev": true, - "requires": { - "boolbase": "^1.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "numeral": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/numeral/-/numeral-2.0.6.tgz", - "integrity": "sha1-StCAk21EPCVhrtnyGX7//iX05QY=" - }, - "nwsapi": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-inspect": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", - "dev": true - }, - "object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "object.entries": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz", - "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - } - }, - "object.fromentries": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.5.tgz", - "integrity": "sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - } - }, - "object.hasown": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.0.tgz", - "integrity": "sha512-MhjYRfj3GBlhSkDHo6QmvgjRLXQ2zndabdf3nX0yTyZK9rPfxb6uRpAac8HXNLy1GpqWtZ81Qh4v3uOls2sRAg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - } - }, - "object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - } - }, - "obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "dev": true - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "one-time": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", - "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", - "dev": true, - "requires": { - "fn.name": "1.x.x" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - }, - "dependencies": { - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - } - } - }, - "open": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", - "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==", - "dev": true, - "requires": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - }, - "dependencies": { - "is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "requires": { - "is-docker": "^2.0.0" - } - } - } - }, - "openurl": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/openurl/-/openurl-1.1.1.tgz", - "integrity": "sha1-OHW0sO96UsFW8NtB1GCduw+Us4c=", - "dev": true - }, - "opn": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.3.0.tgz", - "integrity": "sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==", - "dev": true, - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "ora": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", - "dev": true, - "requires": { - "bl": "^4.1.0", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.5.0", - "is-interactive": "^1.0.0", - "is-unicode-supported": "^0.1.0", - "log-symbols": "^4.1.0", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "requires": { - "restore-cursor": "^3.1.0" - } - }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "os-locale": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-5.0.0.tgz", - "integrity": "sha512-tqZcNEDAIZKBEPnHPlVDvKrp7NzgLi7jRmhKiUoa2NUmhl13FtkAGLUVR+ZsYvApBQdBfYm43A4tXXQ4IrYLBA==", - "dev": true, - "requires": { - "execa": "^4.0.0", - "lcid": "^3.0.0", - "mem": "^5.0.0" - } - }, - "os-name": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-4.0.1.tgz", - "integrity": "sha512-xl9MAoU97MH1Xt5K9ERft2YfCAoaO6msy1OBA0ozxEC0x0TmIoE6K3QvgJMMZA9yKGLmHXNY/YZoDbiGDj4zYw==", - "dev": true, - "requires": { - "macos-release": "^2.5.0", - "windows-release": "^4.0.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "p-defer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", - "dev": true - }, - "p-event": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", - "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", - "dev": true, - "requires": { - "p-timeout": "^3.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, - "p-is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", - "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "p-queue": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", - "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", - "dev": true, - "requires": { - "eventemitter3": "^4.0.4", - "p-timeout": "^3.2.0" - } - }, - "p-retry": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.1.tgz", - "integrity": "sha512-e2xXGNhZOZ0lfgR9kL34iGlU8N/KO0xZnQxVEwdeOvpqNDQfdnxIYizvWtK8RglUa3bGqI8g0R/BdfzLMxRkiA==", - "dev": true, - "requires": { - "@types/retry": "^0.12.0", - "retry": "^0.13.1" - }, - "dependencies": { - "retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "dev": true - } - } - }, - "p-timeout": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", - "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", - "dev": true, - "requires": { - "p-finally": "^1.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pacote": { - "version": "11.3.5", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-11.3.5.tgz", - "integrity": "sha512-fT375Yczn4zi+6Hkk2TBe1x1sP8FgFsEIZ2/iWaXY2r/NkhDJfxbcn5paz1+RTFCyNf+dPnaoBDJoAxXSU8Bkg==", - "dev": true, - "requires": { - "@npmcli/git": "^2.1.0", - "@npmcli/installed-package-contents": "^1.0.6", - "@npmcli/promise-spawn": "^1.2.0", - "@npmcli/run-script": "^1.8.2", - "cacache": "^15.0.5", - "chownr": "^2.0.0", - "fs-minipass": "^2.1.0", - "infer-owner": "^1.0.4", - "minipass": "^3.1.3", - "mkdirp": "^1.0.3", - "npm-package-arg": "^8.0.1", - "npm-packlist": "^2.1.4", - "npm-pick-manifest": "^6.0.0", - "npm-registry-fetch": "^11.0.0", - "promise-retry": "^2.0.1", - "read-package-json-fast": "^2.0.1", - "rimraf": "^3.0.2", - "ssri": "^8.0.1", - "tar": "^6.1.0" - }, - "dependencies": { - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - } - } - }, - "param-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "dev": true, - "requires": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-cache-control": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", - "integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104=", - "dev": true - }, - "parse-conflict-json": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/parse-conflict-json/-/parse-conflict-json-1.1.1.tgz", - "integrity": "sha512-4gySviBiW5TRl7XHvp1agcS7SOe0KZOjC//71dzZVWJrY9hCrgtvl5v3SyIxCZ4fZF47TxD9nfzmxcx76xmbUw==", - "dev": true, - "requires": { - "json-parse-even-better-errors": "^2.3.0", - "just-diff": "^3.0.1", - "just-diff-apply": "^3.0.0" - } - }, - "parse-gitignore": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-gitignore/-/parse-gitignore-1.0.1.tgz", - "integrity": "sha512-UGyowyjtx26n65kdAMWhm6/3uy5uSrpcuH7tt+QEVudiBoVS+eqHxD5kbi9oWVRwj7sCzXqwuM+rUGw7earl6A==", - "dev": true - }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "parse-srcset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz", - "integrity": "sha1-8r0iH2zJcKk42IVWq8WJyqqiveE=" - }, - "parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true - }, - "parseqs": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz", - "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==", - "dev": true - }, - "parseuri": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz", - "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==", - "dev": true - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true - }, - "pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "dev": true, - "requires": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "path-browserify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==" - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", - "requires": { - "isarray": "0.0.1" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - } - } - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" - }, - "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pirates": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", - "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", - "dev": true, - "requires": { - "node-modules-regexp": "^1.0.0" - } - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - }, - "pkg-up": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - } - } - }, - "please-upgrade-node": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", - "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", - "dev": true, - "requires": { - "semver-compare": "^1.0.0" - } - }, - "plugin-error": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", - "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", - "dev": true, - "requires": { - "ansi-colors": "^1.0.1", - "arr-diff": "^4.0.0", - "arr-union": "^3.1.0", - "extend-shallow": "^3.0.2" - }, - "dependencies": { - "ansi-colors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", - "dev": true, - "requires": { - "ansi-wrap": "^0.1.0" - } - } - } - }, - "pluralize": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", - "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", - "dev": true - }, - "popper.js": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", - "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==" - }, - "portfinder": { - "version": "1.0.28", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", - "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", - "dev": true, - "requires": { - "async": "^2.6.2", - "debug": "^3.1.1", - "mkdirp": "^0.5.5" - }, - "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "portscanner": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/portscanner/-/portscanner-2.1.1.tgz", - "integrity": "sha1-6rtAnk3iSVD1oqUW01rnaTQ/u5Y=", - "dev": true, - "requires": { - "async": "1.5.2", - "is-number-like": "^1.0.3" - } - }, - "postcss": { - "version": "8.3.11", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.11.tgz", - "integrity": "sha512-hCmlUAIlUiav8Xdqw3Io4LcpA1DOt7h3LSTAC4G6JGHFFaWzI6qvFt9oilvl8BmkbBRX1IhM90ZAmpk68zccQA==", - "requires": { - "nanoid": "^3.1.30", - "picocolors": "^1.0.0", - "source-map-js": "^0.6.2" - } - }, - "postcss-calc": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.0.0.tgz", - "integrity": "sha512-5NglwDrcbiy8XXfPM11F3HeC6hoT9W7GUH/Zi5U/p7u3Irv4rHhdDcIZwG0llHXV4ftsBjpfWMXAnXNl4lnt8g==", - "dev": true, - "requires": { - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.0.2" - } - }, - "postcss-colormin": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.2.1.tgz", - "integrity": "sha512-VVwMrEYLcHYePUYV99Ymuoi7WhKrMGy/V9/kTS0DkCoJYmmjdOMneyhzYUxcNgteKDVbrewOkSM7Wje/MFwxzA==", - "dev": true, - "requires": { - "browserslist": "^4.16.6", - "caniuse-api": "^3.0.0", - "colord": "^2.9.1", - "postcss-value-parser": "^4.1.0" - }, - "dependencies": { - "caniuse-lite": { - "version": "1.0.30001282", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001282.tgz", - "integrity": "sha512-YhF/hG6nqBEllymSIjLtR2iWDDnChvhnVJqp+vloyt2tEHFG1yBR+ac2B/rOw0qOK0m0lEXU2dv4E/sMk5P9Kg==" - }, - "electron-to-chromium": { - "version": "1.3.901", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.901.tgz", - "integrity": "sha512-ToJdV2vzwT2jeAsw8zIggTFllJ4Kxvwghk39AhJEHHlIxor10wsFI3wo69p8nFc0s/ATWBqugPv/k3nW4Y9Mww==" - }, - "node-releases": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", - "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==" - } - } - }, - "postcss-convert-values": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.0.2.tgz", - "integrity": "sha512-KQ04E2yadmfa1LqXm7UIDwW1ftxU/QWZmz6NKnHnUvJ3LEYbbcX6i329f/ig+WnEByHegulocXrECaZGLpL8Zg==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-discard-comments": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.0.1.tgz", - "integrity": "sha512-lgZBPTDvWrbAYY1v5GYEv8fEO/WhKOu/hmZqmCYfrpD6eyDWWzAOsl2rF29lpvziKO02Gc5GJQtlpkTmakwOWg==", - "dev": true - }, - "postcss-discard-duplicates": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.1.tgz", - "integrity": "sha512-svx747PWHKOGpAXXQkCc4k/DsWo+6bc5LsVrAsw+OU+Ibi7klFZCyX54gjYzX4TH+f2uzXjRviLARxkMurA2bA==", - "dev": true - }, - "postcss-discard-empty": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.0.1.tgz", - "integrity": "sha512-vfU8CxAQ6YpMxV2SvMcMIyF2LX1ZzWpy0lqHDsOdaKKLQVQGVP1pzhrI9JlsO65s66uQTfkQBKBD/A5gp9STFw==", - "dev": true - }, - "postcss-discard-overridden": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.0.1.tgz", - "integrity": "sha512-Y28H7y93L2BpJhrdUR2SR2fnSsT+3TVx1NmVQLbcnZWwIUpJ7mfcTC6Za9M2PG6w8j7UQRfzxqn8jU2VwFxo3Q==", - "dev": true - }, - "postcss-loader": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-6.2.0.tgz", - "integrity": "sha512-H9hv447QjQJVDbHj3OUdciyAXY3v5+UDduzEytAlZCVHCpNAAg/mCSwhYYqZr9BiGYhmYspU8QXxZwiHTLn3yA==", - "dev": true, - "requires": { - "cosmiconfig": "^7.0.0", - "klona": "^2.0.4", - "semver": "^7.3.5" - }, - "dependencies": { - "cosmiconfig": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", - "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", - "dev": true, - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - } - } - } - }, - "postcss-merge-longhand": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.0.4.tgz", - "integrity": "sha512-2lZrOVD+d81aoYkZDpWu6+3dTAAGkCKbV5DoRhnIR7KOULVrI/R7bcMjhrH9KTRy6iiHKqmtG+n/MMj1WmqHFw==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.1.0", - "stylehacks": "^5.0.1" - } - }, - "postcss-merge-rules": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.0.3.tgz", - "integrity": "sha512-cEKTMEbWazVa5NXd8deLdCnXl+6cYG7m2am+1HzqH0EnTdy8fRysatkaXb2dEnR+fdaDxTvuZ5zoBdv6efF6hg==", - "dev": true, - "requires": { - "browserslist": "^4.16.6", - "caniuse-api": "^3.0.0", - "cssnano-utils": "^2.0.1", - "postcss-selector-parser": "^6.0.5" - }, - "dependencies": { - "caniuse-lite": { - "version": "1.0.30001282", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001282.tgz", - "integrity": "sha512-YhF/hG6nqBEllymSIjLtR2iWDDnChvhnVJqp+vloyt2tEHFG1yBR+ac2B/rOw0qOK0m0lEXU2dv4E/sMk5P9Kg==" - }, - "electron-to-chromium": { - "version": "1.3.901", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.901.tgz", - "integrity": "sha512-ToJdV2vzwT2jeAsw8zIggTFllJ4Kxvwghk39AhJEHHlIxor10wsFI3wo69p8nFc0s/ATWBqugPv/k3nW4Y9Mww==" - }, - "node-releases": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", - "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==" - } - } - }, - "postcss-minify-font-values": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.0.1.tgz", - "integrity": "sha512-7JS4qIsnqaxk+FXY1E8dHBDmraYFWmuL6cgt0T1SWGRO5bzJf8sUoelwa4P88LEWJZweHevAiDKxHlofuvtIoA==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-minify-gradients": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.0.3.tgz", - "integrity": "sha512-Z91Ol22nB6XJW+5oe31+YxRsYooxOdFKcbOqY/V8Fxse1Y3vqlNRpi1cxCqoACZTQEhl+xvt4hsbWiV5R+XI9Q==", - "dev": true, - "requires": { - "colord": "^2.9.1", - "cssnano-utils": "^2.0.1", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-minify-params": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.0.2.tgz", - "integrity": "sha512-qJAPuBzxO1yhLad7h2Dzk/F7n1vPyfHfCCh5grjGfjhi1ttCnq4ZXGIW77GSrEbh9Hus9Lc/e/+tB4vh3/GpDg==", - "dev": true, - "requires": { - "alphanum-sort": "^1.0.2", - "browserslist": "^4.16.6", - "cssnano-utils": "^2.0.1", - "postcss-value-parser": "^4.1.0" - }, - "dependencies": { - "caniuse-lite": { - "version": "1.0.30001282", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001282.tgz", - "integrity": "sha512-YhF/hG6nqBEllymSIjLtR2iWDDnChvhnVJqp+vloyt2tEHFG1yBR+ac2B/rOw0qOK0m0lEXU2dv4E/sMk5P9Kg==" - }, - "electron-to-chromium": { - "version": "1.3.901", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.901.tgz", - "integrity": "sha512-ToJdV2vzwT2jeAsw8zIggTFllJ4Kxvwghk39AhJEHHlIxor10wsFI3wo69p8nFc0s/ATWBqugPv/k3nW4Y9Mww==" - }, - "node-releases": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", - "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==" - } - } - }, - "postcss-minify-selectors": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.1.0.tgz", - "integrity": "sha512-NzGBXDa7aPsAcijXZeagnJBKBPMYLaJJzB8CQh6ncvyl2sIndLVWfbcDi0SBjRWk5VqEjXvf8tYwzoKf4Z07og==", - "dev": true, - "requires": { - "alphanum-sort": "^1.0.2", - "postcss-selector-parser": "^6.0.5" - } - }, - "postcss-modules-extract-imports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", - "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", - "dev": true - }, - "postcss-modules-local-by-default": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", - "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", - "dev": true, - "requires": { - "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-modules-scope": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", - "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", - "dev": true, - "requires": { - "postcss-selector-parser": "^6.0.4" - } - }, - "postcss-modules-values": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", - "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", - "dev": true, - "requires": { - "icss-utils": "^5.0.0" - } - }, - "postcss-normalize-charset": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.0.1.tgz", - "integrity": "sha512-6J40l6LNYnBdPSk+BHZ8SF+HAkS4q2twe5jnocgd+xWpz/mx/5Sa32m3W1AA8uE8XaXN+eg8trIlfu8V9x61eg==", - "dev": true - }, - "postcss-normalize-display-values": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.0.1.tgz", - "integrity": "sha512-uupdvWk88kLDXi5HEyI9IaAJTE3/Djbcrqq8YgjvAVuzgVuqIk3SuJWUisT2gaJbZm1H9g5k2w1xXilM3x8DjQ==", - "dev": true, - "requires": { - "cssnano-utils": "^2.0.1", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-normalize-positions": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.0.1.tgz", - "integrity": "sha512-rvzWAJai5xej9yWqlCb1OWLd9JjW2Ex2BCPzUJrbaXmtKtgfL8dBMOOMTX6TnvQMtjk3ei1Lswcs78qKO1Skrg==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-normalize-repeat-style": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.0.1.tgz", - "integrity": "sha512-syZ2itq0HTQjj4QtXZOeefomckiV5TaUO6ReIEabCh3wgDs4Mr01pkif0MeVwKyU/LHEkPJnpwFKRxqWA/7O3w==", - "dev": true, - "requires": { - "cssnano-utils": "^2.0.1", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-normalize-string": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.0.1.tgz", - "integrity": "sha512-Ic8GaQ3jPMVl1OEn2U//2pm93AXUcF3wz+OriskdZ1AOuYV25OdgS7w9Xu2LO5cGyhHCgn8dMXh9bO7vi3i9pA==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-normalize-timing-functions": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.0.1.tgz", - "integrity": "sha512-cPcBdVN5OsWCNEo5hiXfLUnXfTGtSFiBU9SK8k7ii8UD7OLuznzgNRYkLZow11BkQiiqMcgPyh4ZqXEEUrtQ1Q==", - "dev": true, - "requires": { - "cssnano-utils": "^2.0.1", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-normalize-unicode": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.0.1.tgz", - "integrity": "sha512-kAtYD6V3pK0beqrU90gpCQB7g6AOfP/2KIPCVBKJM2EheVsBQmx/Iof+9zR9NFKLAx4Pr9mDhogB27pmn354nA==", - "dev": true, - "requires": { - "browserslist": "^4.16.0", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-normalize-url": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.0.3.tgz", - "integrity": "sha512-qWiUMbvkRx3kc1Dp5opzUwc7MBWZcSDK2yofCmdvFBCpx+zFPkxBC1FASQ59Pt+flYfj/nTZSkmF56+XG5elSg==", - "dev": true, - "requires": { - "is-absolute-url": "^3.0.3", - "normalize-url": "^6.0.1", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-normalize-whitespace": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.0.1.tgz", - "integrity": "sha512-iPklmI5SBnRvwceb/XH568yyzK0qRVuAG+a1HFUsFRf11lEJTiQQa03a4RSCQvLKdcpX7XsI1Gen9LuLoqwiqA==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-ordered-values": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.0.2.tgz", - "integrity": "sha512-8AFYDSOYWebJYLyJi3fyjl6CqMEG/UVworjiyK1r573I56kb3e879sCJLGvR3merj+fAdPpVplXKQZv+ey6CgQ==", - "dev": true, - "requires": { - "cssnano-utils": "^2.0.1", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-reduce-initial": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.0.1.tgz", - "integrity": "sha512-zlCZPKLLTMAqA3ZWH57HlbCjkD55LX9dsRyxlls+wfuRfqCi5mSlZVan0heX5cHr154Dq9AfbH70LyhrSAezJw==", - "dev": true, - "requires": { - "browserslist": "^4.16.0", - "caniuse-api": "^3.0.0" - } - }, - "postcss-reduce-transforms": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.0.1.tgz", - "integrity": "sha512-a//FjoPeFkRuAguPscTVmRQUODP+f3ke2HqFNgGPwdYnpeC29RZdCBvGRGTsKpMURb/I3p6jdKoBQ2zI+9Q7kA==", - "dev": true, - "requires": { - "cssnano-utils": "^2.0.1", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-selector-parser": { - "version": "6.0.6", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", - "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", - "dev": true, - "requires": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - } - }, - "postcss-svgo": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.0.3.tgz", - "integrity": "sha512-41XZUA1wNDAZrQ3XgWREL/M2zSw8LJPvb5ZWivljBsUQAGoEKMYm6okHsTjJxKYI4M75RQEH4KYlEM52VwdXVA==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.1.0", - "svgo": "^2.7.0" - } - }, - "postcss-unique-selectors": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.0.2.tgz", - "integrity": "sha512-w3zBVlrtZm7loQWRPVC0yjUwwpty7OM6DnEHkxcSQXO1bMS3RJ+JUS5LFMSDZHJcvGsRwhZinCWVqn8Kej4EDA==", - "dev": true, - "requires": { - "alphanum-sort": "^1.0.2", - "postcss-selector-parser": "^6.0.5" - } - }, - "postcss-value-parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", - "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", - "dev": true - }, - "preferred-pm": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/preferred-pm/-/preferred-pm-3.0.3.tgz", - "integrity": "sha512-+wZgbxNES/KlJs9q40F/1sfOd/j7f1O9JaHcW5Dsn3aUUOZg3L2bjpVUcKV2jvtElYfoTuQiNeMfQJ4kwUAhCQ==", - "dev": true, - "requires": { - "find-up": "^5.0.0", - "find-yarn-workspace-root2": "1.2.16", - "path-exists": "^4.0.0", - "which-pm": "2.0.0" - }, - "dependencies": { - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - } - } - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "prettier": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz", - "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==", - "dev": true - }, - "prettier-plugin-java": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/prettier-plugin-java/-/prettier-plugin-java-1.5.0.tgz", - "integrity": "sha512-ULiWgCuZaMdpUwoQIocB+RREv0dIEbcxwM7ewUy7yZgQfE9bVYMhQ6YVtS5y2g3AVodHJc+ki+wRidt4l0q3Uw==", - "dev": true, - "requires": { - "java-parser": "2.0.0", - "lodash": "4.17.21", - "prettier": "2.3.1" - }, - "dependencies": { - "prettier": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.1.tgz", - "integrity": "sha512-p+vNbgpLjif/+D+DwAZAbndtRrR0md0MwfmOVN9N+2RgyACMT+7tfaRnT+WDPkqnuVwleyuBIG2XBxKDme3hPA==", - "dev": true - } - } - }, - "prettier-plugin-packagejson": { - "version": "2.2.13", - "resolved": "https://registry.npmjs.org/prettier-plugin-packagejson/-/prettier-plugin-packagejson-2.2.13.tgz", - "integrity": "sha512-AUsRlYHn7jjMck1X54wYTsKj6/E3wf0d0joPFSnSqY3Sxz/e2qqe2x7w0AiMdVeeQcRAkakjp7Qes/riT7J0zA==", - "dev": true, - "requires": { - "sort-package-json": "1.52.0" - } - }, - "pretty-bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", - "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", - "dev": true - }, - "pretty-error": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-3.0.4.tgz", - "integrity": "sha512-ytLFLfv1So4AO1UkoBF6GXQgJRaKbiSiGFICaOPNwQ3CMvBvXpLRubeQWyPGnsbV/t9ml9qto6IeCsho0aEvwQ==", - "dev": true, - "requires": { - "lodash": "^4.17.20", - "renderkid": "^2.0.6" - } - }, - "pretty-format": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.1.tgz", - "integrity": "sha512-DR/c+pvFc52nLimLROYjnXPtolawm+uWDxr4FjuLDLUn+ktWnSN851KoHwHzzqq6rfCOjkzN8FLgDrSub6UDuA==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - } - } - }, - "proc-log": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-1.0.0.tgz", - "integrity": "sha512-aCk8AO51s+4JyuYGg3Q/a6gnrlDO09NpVWePtjp7xwphcoQ04x5WAfCyugcsbLooWcMJ87CLkD4+604IckEdhg==", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "promise": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", - "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", - "dev": true, - "requires": { - "asap": "~2.0.6" - } - }, - "promise-all-reject-late": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz", - "integrity": "sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==", - "dev": true - }, - "promise-call-limit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-call-limit/-/promise-call-limit-1.0.1.tgz", - "integrity": "sha512-3+hgaa19jzCGLuSCbieeRsu5C2joKfYn8pY6JAuXFRVfF4IO+L7UPpFWNTeWT9pM7uhskvbPPd/oEOktCn317Q==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "promise-retry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", - "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", - "dev": true, - "requires": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - } - }, - "prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "requires": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - } - }, - "prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - } - }, - "proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dev": true, - "requires": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "dependencies": { - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true - } - } - }, - "psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "qs": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.3.tgz", - "integrity": "sha1-HPyyXBCpsrSDBT/zn138kjOQjP4=", - "dev": true - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "randexp": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.5.3.tgz", - "integrity": "sha512-U+5l2KrcMNOUPYvazA3h5ekF80FHTUG+87SEAmHZmolh1M+i/WyTCxVzmi+tidIa1tM4BSe8g2Y/D3loWDjj+w==", - "dev": true, - "requires": { - "drange": "^1.0.2", - "ret": "^0.2.0" - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true - }, - "raw-body": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz", - "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==", - "dev": true, - "requires": { - "bytes": "3.1.1", - "http-errors": "1.8.1", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "react": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.1.tgz", - "integrity": "sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "react-dom": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.1.tgz", - "integrity": "sha512-6eV150oJZ9U2t9svnsspTMrWNyHc6chX0KzDeAOXftRa8bNeOKTTfCJ7KorIwenkHd2xqVTBTCZd79yk/lx/Ug==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.1" - } - }, - "react-hook-form": { - "version": "7.17.4", - "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.17.4.tgz", - "integrity": "sha512-7XhbCr7d9fDC1TgcK/BUbt7D3q0VJMu7jPErfsa0JrxVjv/nni41xWdJcy0Zb7R+Np8OsCkQ2lMyloAtE3DLiQ==" - }, - "react-infinite-scroller": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/react-infinite-scroller/-/react-infinite-scroller-1.2.4.tgz", - "integrity": "sha512-/oOa0QhZjXPqaD6sictN2edFMsd3kkMiE19Vcz5JDgHpzEJVqYcmq+V3mkwO88087kvKGe1URNksHEOt839Ubw==", - "dev": true, - "requires": { - "prop-types": "^15.5.8" - } - }, - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "react-jhipster": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/react-jhipster/-/react-jhipster-0.17.0.tgz", - "integrity": "sha512-Yjc0X5UCtG7++JYdx+8Pj16r4XIRoxBJ0I9dALP+zsSrOvzmpjEmlycPzAeMNN6Xqo/tqX0DRJt9D3NViy0NuQ==", - "requires": { - "lodash.get": "^4.4.2", - "numeral": "^2.0.6", - "sanitize-html": "^2.3.1" - } - }, - "react-lifecycles-compat": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", - "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" - }, - "react-loadable": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/react-loadable/-/react-loadable-5.5.0.tgz", - "integrity": "sha512-C8Aui0ZpMd4KokxRdVAm2bQtI03k2RMRNzOB+IipV3yxFTSVICv7WoUr5L9ALB5BmKO1iHgZtWM8EvYG83otdg==", - "requires": { - "prop-types": "^15.5.0" - } - }, - "react-popper": { - "version": "1.3.11", - "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.3.11.tgz", - "integrity": "sha512-VSA/bS+pSndSF2fiasHK/PTEEAyOpX60+H5EPAjoArr8JGm+oihu4UbrqcEBpQibJxBVCpYyjAX7abJ+7DoYVg==", - "requires": { - "@babel/runtime": "^7.1.2", - "@hypnosphi/create-react-context": "^0.3.1", - "deep-equal": "^1.1.1", - "popper.js": "^1.14.4", - "prop-types": "^15.6.1", - "typed-styles": "^0.0.7", - "warning": "^4.0.2" - } - }, - "react-redux": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.5.tgz", - "integrity": "sha512-Dt29bNyBsbQaysp6s/dN0gUodcq+dVKKER8Qv82UrpeygwYeX1raTtil7O/fftw/rFqzaf6gJhDZRkkZnn6bjg==", - "requires": { - "@babel/runtime": "^7.12.1", - "@types/react-redux": "^7.1.16", - "hoist-non-react-statics": "^3.3.2", - "loose-envify": "^1.4.0", - "prop-types": "^15.7.2", - "react-is": "^16.13.1" - }, - "dependencies": { - "@types/react": { - "version": "17.0.35", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.35.tgz", - "integrity": "sha512-r3C8/TJuri/SLZiiwwxQoLAoavaczARfT9up9b4Jr65+ErAUX3MIkU0oMOQnrpfgHme8zIqZLX7O5nnjm5Wayw==", - "requires": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" - } - }, - "@types/react-redux": { - "version": "7.1.20", - "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.20.tgz", - "integrity": "sha512-q42es4c8iIeTgcnB+yJgRTTzftv3eYYvCZOh1Ckn2eX/3o5TdsQYKUWpLoLuGlcY/p+VAhV9IOEZJcWk/vfkXw==", - "requires": { - "@types/hoist-non-react-statics": "^3.3.0", - "@types/react": "*", - "hoist-non-react-statics": "^3.3.0", - "redux": "^4.0.0" - } - } - } - }, - "react-redux-loading-bar": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/react-redux-loading-bar/-/react-redux-loading-bar-5.0.2.tgz", - "integrity": "sha512-M+gK/Q79UG3iVljv6myRJptdQ5sIKdYDigeukwGocvWLCgWFdtpeP8IY8lBIYsqHXtuFBP/gj7E3qvGwCtcpRQ==", - "requires": { - "prop-types": "^15.7.2", - "react-lifecycles-compat": "^3.0.4" - } - }, - "react-router": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.1.tgz", - "integrity": "sha512-lIboRiOtDLFdg1VTemMwud9vRVuOCZmUIT/7lUoZiSpPODiiH1UQlfXy+vPLC/7IWdFYnhRwAyNqA/+I7wnvKQ==", - "requires": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "hoist-non-react-statics": "^3.1.0", - "loose-envify": "^1.3.1", - "mini-create-react-context": "^0.4.0", - "path-to-regexp": "^1.7.0", - "prop-types": "^15.6.2", - "react-is": "^16.6.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" - } - }, - "react-router-dom": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.0.tgz", - "integrity": "sha512-ObVBLjUZsphUUMVycibxgMdh5jJ1e3o+KpAZBVeHcNQZ4W+uUGGWsokurzlF4YOldQYRQL4y6yFRWM4m3svmuQ==", - "requires": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "loose-envify": "^1.3.1", - "prop-types": "^15.6.2", - "react-router": "5.2.1", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" - } - }, - "react-toastify": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-8.0.3.tgz", - "integrity": "sha512-rv3koC7f9lKKSkdpYgo/TGzgWlrB/aaiUInF1DyV7BpiM4kyTs+uhu6/r8XDMtBY2FOIHK+FlK3Iv7OzpA/tCA==", - "requires": { - "clsx": "^1.1.1" - } - }, - "react-transition-group": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz", - "integrity": "sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==", - "requires": { - "@babel/runtime": "^7.5.5", - "dom-helpers": "^5.0.1", - "loose-envify": "^1.4.0", - "prop-types": "^15.6.2" - } - }, - "reactstrap": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/reactstrap/-/reactstrap-8.10.0.tgz", - "integrity": "sha512-MsFUB/fRZj6Orf8Mxc93iYuAs+9ngnFmy2cfYlzkmc4vi5oM4u6ziY/DsO71lDG3cotxHRyS3Flr51cuYv+IEQ==", - "requires": { - "@babel/runtime": "^7.12.5", - "classnames": "^2.2.3", - "prop-types": "^15.5.8", - "react-popper": "^1.3.6", - "react-transition-group": "^2.3.1" - }, - "dependencies": { - "dom-helpers": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", - "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==", - "requires": { - "@babel/runtime": "^7.1.2" - } - }, - "react-transition-group": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz", - "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==", - "requires": { - "dom-helpers": "^3.4.0", - "loose-envify": "^1.4.0", - "prop-types": "^15.6.2", - "react-lifecycles-compat": "^3.0.4" - } - } - } - }, - "read-cmd-shim": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-2.0.0.tgz", - "integrity": "sha512-HJpV9bQpkl6KwjxlJcBoqu9Ba0PQg8TqSNIOrulGt54a0uup0HtevreFHzYzkm0lpnleRdNBzXznKrgxglEHQw==", - "dev": true - }, - "read-package-json-fast": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-2.0.3.tgz", - "integrity": "sha512-W/BKtbL+dUjTuRL2vziuYhp76s5HZ9qQhd/dKfWIZveD0O40453QNyZhC0e63lqZrAQ4jiOapVoeJ7JrszenQQ==", - "dev": true, - "requires": { - "json-parse-even-better-errors": "^2.3.0", - "npm-normalize-package-bin": "^1.0.1" - } - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } - } - }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "dependencies": { - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true - } - } - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdir-scoped-modules": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz", - "integrity": "sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw==", - "dev": true, - "requires": { - "debuglog": "^1.0.1", - "dezalgo": "^1.0.0", - "graceful-fs": "^4.1.2", - "once": "^1.3.0" - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, - "requires": { - "resolve": "^1.1.6" - }, - "dependencies": { - "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "dev": true, - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - } - } - }, - "redux": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/redux/-/redux-4.1.1.tgz", - "integrity": "sha512-hZQZdDEM25UY2P493kPYuKqviVwZ58lEmGQNeQ+gXa+U0gYPUBf7NKYazbe3m+bs/DzM/ahN12DbF+NG8i0CWw==", - "requires": { - "@babel/runtime": "^7.9.2" - } - }, - "redux-mock-store": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/redux-mock-store/-/redux-mock-store-1.5.4.tgz", - "integrity": "sha512-xmcA0O/tjCLXhh9Fuiq6pMrJCwFRaouA8436zcikdIpYWWCjU76CRk+i2bHx8EeiSiMGnB85/lZdU3wIJVXHTA==", - "dev": true, - "requires": { - "lodash.isplainobject": "^4.0.6" - } - }, - "redux-thunk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz", - "integrity": "sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw==" - }, - "regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true - }, - "regenerate-unicode-properties": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz", - "integrity": "sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA==", - "dev": true, - "requires": { - "regenerate": "^1.4.2" - } - }, - "regenerator-transform": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", - "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", - "dev": true, - "requires": { - "@babel/runtime": "^7.8.4" - } - }, - "regexp-to-ast": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/regexp-to-ast/-/regexp-to-ast-0.5.0.tgz", - "integrity": "sha512-tlbJqcMHnPKI9zSrystikWKwHkBqu2a/Sgw01h3zFjvYrMxEDYHzzoMZnUrbIfpTFEsoRnnviOXNCzFiSc54Qw==", - "dev": true - }, - "regexp.prototype.flags": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", - "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, - "regexpu-core": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.8.0.tgz", - "integrity": "sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg==", - "dev": true, - "requires": { - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^9.0.0", - "regjsgen": "^0.5.2", - "regjsparser": "^0.7.0", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.0.0" - } - }, - "regjsgen": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", - "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", - "dev": true - }, - "regjsparser": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.7.0.tgz", - "integrity": "sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ==", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true - } - } - }, - "relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", - "dev": true - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "renderkid": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.7.tgz", - "integrity": "sha512-oCcFyxaMrKsKcTY59qnCAtmDVSLfPbrv6A3tVbPdFMMrv5jaK10V6m40cKsoPNhAqN6rmHW9sswW4o3ruSrwUQ==", - "dev": true, - "requires": { - "css-select": "^4.1.3", - "dom-converter": "^0.2.0", - "htmlparser2": "^6.1.0", - "lodash": "^4.17.21", - "strip-ansi": "^3.0.1" - } - }, - "replace-ext": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", - "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", - "dev": true - }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true - }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "reselect": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.4.tgz", - "integrity": "sha512-i1LgXw8DKSU5qz1EV0ZIKz4yIUHJ7L3bODh+Da6HmVSm9vdL/hG7IpbgzQ3k2XSirzf8/eI7OMEs81gb1VV2fQ==" - }, - "resolve": { - "version": "2.0.0-next.3", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz", - "integrity": "sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==", - "dev": true, - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - }, - "resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "requires": { - "resolve-from": "^5.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "resolve-pathname": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", - "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" - }, - "resolve.exports": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", - "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", - "dev": true - }, - "resp-modifier": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/resp-modifier/-/resp-modifier-6.0.2.tgz", - "integrity": "sha1-sSTeXE+6/LpUH0j/pzlw9KpFa08=", - "dev": true, - "requires": { - "debug": "^2.2.0", - "minimatch": "^3.0.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - }, - "dependencies": { - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - } - } - }, - "ret": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.2.2.tgz", - "integrity": "sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==", - "dev": true - }, - "retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", - "dev": true - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "rollup": { - "version": "2.60.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.60.0.tgz", - "integrity": "sha512-cHdv9GWd58v58rdseC8e8XIaPUo8a9cgZpnCMMDGZFDZKEODOiPPEQFXLriWr/TjXzhPPmG5bkAztPsOARIcGQ==", - "dev": true, - "requires": { - "fsevents": "~2.3.2" - } - }, - "rollup-plugin-terser": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", - "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "jest-worker": "^26.2.1", - "serialize-javascript": "^4.0.0", - "terser": "^5.0.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "dev": true, - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - } - }, - "serialize-javascript": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", - "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "rx": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", - "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=", - "dev": true - }, - "rxjs": { - "version": "5.5.12", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz", - "integrity": "sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==", - "dev": true, - "requires": { - "symbol-observable": "1.0.1" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - }, - "safe-stable-stringify": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz", - "integrity": "sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw==", - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "sanitize-html": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.5.3.tgz", - "integrity": "sha512-DGATXd1fs/Rm287/i5FBKVYSBBUL0iAaztOA1/RFhEs4yqo39/X52i/q/CwsfCUG5cilmXSBmnQmyWfnKhBlOg==", - "requires": { - "deepmerge": "^4.2.2", - "escape-string-regexp": "^4.0.0", - "htmlparser2": "^6.0.0", - "is-plain-object": "^5.0.0", - "parse-srcset": "^1.0.2", - "postcss": "^8.3.11" - }, - "dependencies": { - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" - }, - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" - }, - "postcss": { - "version": "8.3.11", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.11.tgz", - "integrity": "sha512-hCmlUAIlUiav8Xdqw3Io4LcpA1DOt7h3LSTAC4G6JGHFFaWzI6qvFt9oilvl8BmkbBRX1IhM90ZAmpk68zccQA==", - "requires": { - "nanoid": "^3.1.30", - "picocolors": "^1.0.0", - "source-map-js": "^0.6.2" - } - } - } - }, - "sass": { - "version": "1.43.2", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.43.2.tgz", - "integrity": "sha512-DncYhjl3wBaPMMJR0kIUaH3sF536rVrOcqqVGmTZHQRRzj7LQlyGV7Mb8aCKFyILMr5VsPHwRYtyKpnKYlmQSQ==", - "dev": true, - "requires": { - "chokidar": ">=3.0.0 <4.0.0" - } - }, - "sass-loader": { - "version": "12.2.0", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.2.0.tgz", - "integrity": "sha512-qducnp5vSV+8A8MZxuH6zV0MUg4MOVISScl2wDTCAn/2WJX+9Auxh92O/rnkdR2bvi5QxZBafnzkzRrWGZvm7w==", - "dev": true, - "requires": { - "klona": "^2.0.4", - "neo-async": "^2.6.2" - } - }, - "sax": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", - "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=", - "dev": true - }, - "saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dev": true, - "requires": { - "xmlchars": "^2.2.0" - } - }, - "scheduler": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.1.tgz", - "integrity": "sha512-LKTe+2xNJBNxu/QhHvDR14wUXHRQbVY5ZOYpOGWRzhydZUqrLb2JBvLPY7cAqFmqrWuDED0Mjk7013SZiOz6Bw==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - }, - "scoped-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/scoped-regex/-/scoped-regex-2.1.0.tgz", - "integrity": "sha512-g3WxHrqSWCZHGHlSrF51VXFdjImhwvH8ZO/pryFH56Qi0cDsZfylQa/t0jCzVQFNbNvM00HfHjkDPEuarKDSWQ==", - "dev": true - }, - "select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", - "dev": true - }, - "selfsigned": { - "version": "1.10.11", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.11.tgz", - "integrity": "sha512-aVmbPOfViZqOZPgRBT0+3u4yZFHpmnIghLMlAcb5/xhp5ZtB/RVnKhz5vl2M32CLXAqR4kha9zfhNg0Lf/sxKA==", - "dev": true, - "requires": { - "node-forge": "^0.10.0" - } - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", - "dev": true - }, - "send": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", - "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", - "dev": true, - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.6.2", - "mime": "1.4.1", - "ms": "2.0.0", - "on-finished": "~2.3.0", - "range-parser": "~1.2.0", - "statuses": "~1.4.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true - }, - "statuses": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", - "dev": true - } - } - }, - "serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", - "dev": true, - "requires": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true - } - } - }, - "serve-static": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", - "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", - "dev": true, - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.2", - "send": "0.16.2" - } - }, - "server-destroy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz", - "integrity": "sha1-8Tv5KOQrnD55OD5hzDmYtdFObN0=", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true - }, - "shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "requires": { - "kind-of": "^6.0.2" - } - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "shelljs": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz", - "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==", - "dev": true, - "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - } - }, - "shellwords": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", - "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", - "dev": true - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", - "dev": true - }, - "simple-git": { - "version": "2.46.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-2.46.0.tgz", - "integrity": "sha512-6eumII1vfP4NpRqxZcVWCcIT5xHH6dRyvBZSjkH4dJRDRpv+0f75hrN5ysp++y23Mfr3AbRC/dO2NDbfj1lJpQ==", - "dev": true, - "requires": { - "@kwsites/file-exists": "^1.1.1", - "@kwsites/promise-deferred": "^1.1.1", - "debug": "^4.3.1" - } - }, - "simple-progress-webpack-plugin": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/simple-progress-webpack-plugin/-/simple-progress-webpack-plugin-2.0.0.tgz", - "integrity": "sha512-Ji8b05YHc9R8iHHbEX8kOqvR2CB8bUqqqP481DbY+j5ImqBhLXk9sXFZZdcSEK3Ld0hZl9i+5CzXWLXzw1NV9g==", - "dev": true, - "requires": { - "chalk": "4.1.x", - "figures": "3.2.x", - "log-update": "4.0.x" - }, - "dependencies": { - "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - } - } - }, - "simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", - "dev": true, - "requires": { - "is-arrayish": "^0.3.1" - }, - "dependencies": { - "is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", - "dev": true - } - } - }, - "sinon": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-11.1.2.tgz", - "integrity": "sha512-59237HChms4kg7/sXhiRcUzdSkKuydDeTiamT/jesUVHshBgL8XAmhgFo0GfK6RruMDM/iRSij1EybmMog9cJw==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.8.3", - "@sinonjs/fake-timers": "^7.1.2", - "@sinonjs/samsam": "^6.0.2", - "diff": "^5.0.0", - "nise": "^5.1.0", - "supports-color": "^7.2.0" - }, - "dependencies": { - "@sinonjs/fake-timers": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz", - "integrity": "sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - } - } - }, - "smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "dev": true - }, - "socket.io": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.4.0.tgz", - "integrity": "sha512-9UPJ1UTvKayuQfVv2IQ3k7tCQC/fboDyIK62i99dAQIyHKaBsNdTpwHLgKJ6guRWxRtC9H+138UwpaGuQO9uWQ==", - "dev": true, - "requires": { - "debug": "~4.1.0", - "engine.io": "~3.5.0", - "has-binary2": "~1.0.2", - "socket.io-adapter": "~1.1.0", - "socket.io-client": "2.4.0", - "socket.io-parser": "~3.4.0" - }, - "dependencies": { - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "socket.io-parser": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.1.tgz", - "integrity": "sha512-11hMgzL+WCLWf1uFtHSNvliI++tcRUWdoeYuwIl+Axvwy9z2gQM+7nJyN3STj1tLj5JyIUH8/gpDGxzAlDdi0A==", - "dev": true, - "requires": { - "component-emitter": "1.2.1", - "debug": "~4.1.0", - "isarray": "2.0.1" - } - } - } - }, - "socket.io-adapter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz", - "integrity": "sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g==", - "dev": true - }, - "socket.io-client": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.4.0.tgz", - "integrity": "sha512-M6xhnKQHuuZd4Ba9vltCLT9oa+YvTsP8j9NcEiLElfIg8KeYPyhWOes6x4t+LTAC8enQbE/995AdTem2uNyKKQ==", - "dev": true, - "requires": { - "backo2": "1.0.2", - "component-bind": "1.0.0", - "component-emitter": "~1.3.0", - "debug": "~3.1.0", - "engine.io-client": "~3.5.0", - "has-binary2": "~1.0.2", - "indexof": "0.0.1", - "parseqs": "0.0.6", - "parseuri": "0.0.6", - "socket.io-parser": "~3.3.0", - "to-array": "0.1.4" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "socket.io-parser": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.2.tgz", - "integrity": "sha512-FJvDBuOALxdCI9qwRrO/Rfp9yfndRtc1jSgVgV8FDraihmSP/MLGD5PEuJrNfjALvcQ+vMDM/33AWOYP/JSjDg==", - "dev": true, - "requires": { - "component-emitter": "~1.3.0", - "debug": "~3.1.0", - "isarray": "2.0.1" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "sockjs": { - "version": "0.3.21", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.21.tgz", - "integrity": "sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw==", - "dev": true, - "requires": { - "faye-websocket": "^0.11.3", - "uuid": "^3.4.0", - "websocket-driver": "^0.7.4" - }, - "dependencies": { - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - } - } - }, - "socks": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.1.tgz", - "integrity": "sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA==", - "dev": true, - "requires": { - "ip": "^1.1.5", - "smart-buffer": "^4.1.0" - } - }, - "socks-proxy-agent": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.1.0.tgz", - "integrity": "sha512-57e7lwCN4Tzt3mXz25VxOErJKXlPfXmkMLnk310v/jwW20jWRVcgsOit+xNkN3eIEdB47GwnfAEBLacZ/wVIKg==", - "dev": true, - "requires": { - "agent-base": "^6.0.2", - "debug": "^4.3.1", - "socks": "^2.6.1" - } - }, - "sort-object-keys": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sort-object-keys/-/sort-object-keys-1.1.3.tgz", - "integrity": "sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg==", - "dev": true - }, - "sort-package-json": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/sort-package-json/-/sort-package-json-1.52.0.tgz", - "integrity": "sha512-TsKDXgH3kPsaSrjAszQgg+n2/FDYdPrBrXD4YxMxExpogsi8LCek0YzK/jZ70i5Gi53WcpV+mVzvb5CHB5LpZw==", - "dev": true, - "requires": { - "detect-indent": "^6.0.0", - "detect-newline": "3.1.0", - "git-hooks-list": "1.0.3", - "globby": "10.0.0", - "is-plain-obj": "2.1.0", - "sort-object-keys": "^1.1.3" - }, - "dependencies": { - "globby": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.0.tgz", - "integrity": "sha512-3LifW9M4joGZasyYPz2A1U74zbC/45fvpXUvO/9KbSa+VV0aGZarWkfdgKyR9sExNP0t0x0ss/UMJpNpcaTspw==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" - } - } - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-js": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz", - "integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==" - }, - "source-map-loader": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-3.0.0.tgz", - "integrity": "sha512-GKGWqWvYr04M7tn8dryIWvb0s8YM41z82iQv01yBtIylgxax0CwvSy6gc2Y02iuXwEfGWRlMicH0nvms9UZphw==", - "dev": true, - "requires": { - "abab": "^2.0.5", - "iconv-lite": "^0.6.2", - "source-map-js": "^0.6.2" - }, - "dependencies": { - "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - } - } - }, - "source-map-support": { - "version": "0.5.20", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", - "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "dev": true - }, - "sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", - "dev": true - }, - "sourcemap-istanbul-instrumenter-loader": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/sourcemap-istanbul-instrumenter-loader/-/sourcemap-istanbul-instrumenter-loader-0.2.0.tgz", - "integrity": "sha1-j9cuir0W3tWJGKdHTbW7PQ27ys0=", - "dev": true, - "requires": { - "istanbul": "0.x.x", - "loader-utils": "0.x.x", - "object-assign": "4.x.x" - }, - "dependencies": { - "big.js": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", - "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", - "dev": true - }, - "emojis-list": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", - "dev": true - }, - "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true - }, - "loader-utils": { - "version": "0.2.17", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", - "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", - "dev": true, - "requires": { - "big.js": "^3.1.3", - "emojis-list": "^2.0.0", - "json5": "^0.5.0", - "object-assign": "^4.0.1" - } - } - } - }, - "spawn-command": { - "version": "0.0.2-1", - "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", - "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=", - "dev": true - }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", - "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", - "dev": true - }, - "spdy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - } - }, - "spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "ssri": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", - "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", - "dev": true, - "requires": { - "minipass": "^3.1.1" - } - }, - "stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "dev": true - }, - "stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", - "dev": true - }, - "stack-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - } - } - }, - "statuses": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", - "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", - "dev": true - }, - "stream-throttle": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/stream-throttle/-/stream-throttle-0.1.3.tgz", - "integrity": "sha1-rdV8jXzHOoFjDTHNVdOWHPr7qcM=", - "dev": true, - "requires": { - "commander": "^2.2.0", - "limiter": "^1.0.5" - } - }, - "streamfilter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/streamfilter/-/streamfilter-3.0.0.tgz", - "integrity": "sha512-kvKNfXCmUyC8lAXSSHCIXBUlo/lhsLcCU/OmzACZYpRUdtKIH68xYhm/+HI15jFJYtNJGYtCgn2wmIiExY1VwA==", - "dev": true, - "requires": { - "readable-stream": "^3.0.6" - } - }, - "string-argv": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", - "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", - "dev": true - }, - "string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, - "requires": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } - } - }, - "string.prototype.matchall": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.6.tgz", - "integrity": "sha512-6WgDX8HmQqvEd7J+G6VtAahhsQIssiZ8zl7zKh1VDMFyL3hRTJP4FTNA3RbIp2TOQ9AYNDcc7e3fH0Qbup+DBg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", - "get-intrinsic": "^1.1.1", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "regexp.prototype.flags": "^1.3.1", - "side-channel": "^1.0.4" - } - }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "stringify-object": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", - "dev": true, - "requires": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" - }, - "dependencies": { - "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", - "dev": true - } - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - } - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - }, - "strip-bom-buf": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-buf/-/strip-bom-buf-1.0.0.tgz", - "integrity": "sha1-HLRar1dTD0yvhsf3UXnSyaUd1XI=", - "dev": true, - "requires": { - "is-utf8": "^0.2.1" - } - }, - "strip-bom-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-2.0.0.tgz", - "integrity": "sha1-+H217yYT9paKpUWr/h7HKLaoKco=", - "dev": true, - "requires": { - "first-chunk-stream": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "style-loader": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.0.tgz", - "integrity": "sha512-szANub7ksJtQioJYtpbWwh1hUl99uK15n5HDlikeCRil/zYMZgSxucHddyF/4A3qJMUiAjPhFowrrQuNMA7jwQ==", - "dev": true - }, - "stylehacks": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.0.1.tgz", - "integrity": "sha512-Es0rVnHIqbWzveU1b24kbw92HsebBepxfcqe5iix7t9j0PQqhs0IxXVXv0pY2Bxa08CgMkzD6OWql7kbGOuEdA==", - "dev": true, - "requires": { - "browserslist": "^4.16.0", - "postcss-selector-parser": "^6.0.4" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "supports-hyperlinks": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", - "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", - "dev": true, - "requires": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "svgo": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", - "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", - "dev": true, - "requires": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^4.1.3", - "css-tree": "^1.1.3", - "csso": "^4.2.0", - "picocolors": "^1.0.0", - "stable": "^0.1.8" - }, - "dependencies": { - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true - } - } - }, - "swagger-ui-dist": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.1.3.tgz", - "integrity": "sha512-WvfPSfAAMlE/sKS6YkW47nX/hA7StmhYnAHc6wWCXNL0oclwLj6UXv0hQCkLnDgvebi0MEV40SJJpVjKUgH1IQ==", - "dev": true - }, - "symbol-observable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", - "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=", - "dev": true - }, - "symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true - }, - "table": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/table/-/table-6.7.3.tgz", - "integrity": "sha512-5DkIxeA7XERBqMwJq0aHZOdMadBx4e6eDoFRuyT5VR82J0Ycg2DwM6GfA/EQAhJ+toRTaS1lIdSQCqgrmhPnlw==", - "dev": true, - "requires": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "ajv": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.1.tgz", - "integrity": "sha512-6CiMNDrzv0ZR916u2T+iRunnD60uWmNn8SkdB44/6stVORUg0aAkWO7PkOhpCmjmW8f2I/G/xnowD66fxGyQJg==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "tar": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", - "dev": true, - "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "dependencies": { - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - } - } - }, - "temp-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", - "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", - "dev": true - }, - "tempy": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz", - "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==", - "dev": true, - "requires": { - "is-stream": "^2.0.0", - "temp-dir": "^2.0.0", - "type-fest": "^0.16.0", - "unique-string": "^2.0.0" - }, - "dependencies": { - "type-fest": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", - "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", - "dev": true - } - } - }, - "terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - }, - "dependencies": { - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "requires": { - "type-fest": "^0.21.3" - } - }, - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true - } - } - }, - "terser": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.10.0.tgz", - "integrity": "sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.7.2", - "source-map-support": "~0.5.20" - }, - "dependencies": { - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.2.4.tgz", - "integrity": "sha512-E2CkNMN+1cho04YpdANyRrn8CyN4yMy+WdFKZIySFZrGXZxJwJP6PMNGGc/Mcr6qygQHUUqRxnAPmi0M9f00XA==", - "dev": true, - "requires": { - "jest-worker": "^27.0.6", - "p-limit": "^3.1.0", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1", - "terser": "^5.7.2" - }, - "dependencies": { - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - } - } - }, - "test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "requires": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - } - }, - "text-hex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", - "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==", - "dev": true - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "textextensions": { - "version": "5.14.0", - "resolved": "https://registry.npmjs.org/textextensions/-/textextensions-5.14.0.tgz", - "integrity": "sha512-4cAYwNFNYlIAHBUo7p6zw8POUvWbZor+/R0Tanv+rIhsauEyV9QSrEXL40pI+GfTQxKX8k6Tyw6CmdSDSmASrg==", - "dev": true - }, - "tfunk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tfunk/-/tfunk-4.0.0.tgz", - "integrity": "sha512-eJQ0dGfDIzWNiFNYFVjJ+Ezl/GmwHaFTBTjrtqNPW0S7cuVDBrZrmzUz6VkMeCR4DZFqhd4YtLwsw3i2wYHswQ==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "dlv": "^1.1.3" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "then-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", - "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", - "dev": true, - "requires": { - "@types/concat-stream": "^1.6.0", - "@types/form-data": "0.0.33", - "@types/node": "^8.0.0", - "@types/qs": "^6.2.31", - "caseless": "~0.12.0", - "concat-stream": "^1.6.0", - "form-data": "^2.2.0", - "http-basic": "^8.1.1", - "http-response-object": "^3.0.1", - "promise": "^8.0.0", - "qs": "^6.4.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.66", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", - "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", - "dev": true - }, - "qs": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", - "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } - } - } - }, - "thread-loader": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/thread-loader/-/thread-loader-3.0.4.tgz", - "integrity": "sha512-ByaL2TPb+m6yArpqQUZvP+5S1mZtXsEP7nWKKlAUTm7fCml8kB5s1uI3+eHRP2bk5mVYfRSBI7FFf+tWEyLZwA==", - "dev": true, - "requires": { - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.1.0", - "loader-utils": "^2.0.0", - "neo-async": "^2.6.2", - "schema-utils": "^3.0.0" - }, - "dependencies": { - "@types/json-schema": { - "version": "7.0.8", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.8.tgz", - "integrity": "sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg==", - "dev": true - }, - "loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - } - } - }, - "throat": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", - "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", - "dev": true - }, - "timsort": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", - "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", - "dev": true - }, - "tiny-invariant": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.2.0.tgz", - "integrity": "sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg==" - }, - "tiny-warning": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", - "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true - }, - "to-absolute-glob": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", - "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", - "dev": true, - "requires": { - "is-absolute": "^1.0.0", - "is-negated-glob": "^1.0.0" - } - }, - "to-array": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", - "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", - "dev": true - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true - }, - "tough-cookie": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", - "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", - "dev": true, - "requires": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.1.2" - } - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", - "dev": true - }, - "tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", - "dev": true - }, - "treeverse": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/treeverse/-/treeverse-1.0.4.tgz", - "integrity": "sha512-whw60l7r+8ZU8Tu/Uc2yxtc4ZTZbR/PF3u1IPNKGQ6p8EICLb3Z2lAgoqw9bqYd8IkgnsaOcLzYHFckjqNsf0g==", - "dev": true - }, - "triple-beam": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", - "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==", - "dev": true - }, - "ts-jest": { - "version": "27.0.7", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.0.7.tgz", - "integrity": "sha512-O41shibMqzdafpuP+CkrOL7ykbmLh+FqQrXEmV9CydQ5JBk0Sj0uAEF5TNNe94fZWKm3yYvWa/IbyV4Yg1zK2Q==", - "dev": true, - "requires": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^27.0.0", - "json5": "2.x", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "7.x", - "yargs-parser": "20.x" - } - }, - "ts-loader": { - "version": "9.2.6", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.2.6.tgz", - "integrity": "sha512-QMTC4UFzHmu9wU2VHZEmWWE9cUajjfcdcws+Gh7FhiO+Dy0RnR1bNz0YCHqhI0yRowCE9arVnNxYHqELOy9Hjw==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "enhanced-resolve": "^5.0.0", - "micromatch": "^4.0.0", - "semver": "^7.3.4" - } - }, - "tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - } - } - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typed-styles": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/typed-styles/-/typed-styles-0.0.7.tgz", - "integrity": "sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q==" - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "typescript": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", - "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", - "dev": true - }, - "ua-parser-js": { - "version": "0.7.31", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.31.tgz", - "integrity": "sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==", - "dev": true - }, - "uglify-js": { - "version": "3.12.8", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.12.8.tgz", - "integrity": "sha512-fvBeuXOsvqjecUtF/l1dwsrrf5y2BCUk9AOJGzGcm6tE7vegku5u/YvqjyDaAGr422PLoLnrxg3EnRvTqsdC1w==", - "dev": true, - "optional": true - }, - "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - } - }, - "unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", - "dev": true - }, - "unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", - "dev": true - }, - "unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "dev": true, - "requires": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - } - }, - "unicode-match-property-value-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", - "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==", - "dev": true - }, - "unicode-property-aliases-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz", - "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==", - "dev": true - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "dev": true, - "requires": { - "crypto-random-string": "^2.0.0" - } - }, - "universal-user-agent": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", - "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==", - "dev": true - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true - }, - "untildify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", - "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", - "dev": true - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "url": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", - "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=", - "dev": true - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "dev": true - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" - }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "v8-to-istanbul": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz", - "integrity": "sha512-/PRhfd8aTNp9Ggr62HPzXg2XasNFGy5PBt0Rp04du7/8GNNSgxFL6WBTkgMKSL9bFjH+8kKEG3f37FmxiTqUUA==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" - }, - "dependencies": { - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true - } - } - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "validate-npm-package-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", - "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=", - "dev": true, - "requires": { - "builtins": "^1.0.3" - } - }, - "value-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", - "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vinyl": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", - "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", - "dev": true, - "requires": { - "clone": "^2.1.1", - "clone-buffer": "^1.0.0", - "clone-stats": "^1.0.0", - "cloneable-readable": "^1.0.0", - "remove-trailing-separator": "^1.0.1", - "replace-ext": "^1.0.0" - }, - "dependencies": { - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", - "dev": true - } - } - }, - "vinyl-file": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/vinyl-file/-/vinyl-file-3.0.0.tgz", - "integrity": "sha1-sQTZ5ECf+jJfqt1SBkLQo7SIs2U=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.3.0", - "strip-bom-buf": "^1.0.0", - "strip-bom-stream": "^2.0.0", - "vinyl": "^2.0.1" - } - }, - "w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "dev": true, - "requires": { - "browser-process-hrtime": "^1.0.0" - } - }, - "w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "dev": true, - "requires": { - "xml-name-validator": "^3.0.0" - } - }, - "wait-on": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-6.0.0.tgz", - "integrity": "sha512-tnUJr9p5r+bEYXPUdRseolmz5XqJTTj98JgOsfBn7Oz2dxfE2g3zw1jE+Mo8lopM3j3et/Mq1yW7kKX6qw7RVw==", - "dev": true, - "requires": { - "axios": "^0.21.1", - "joi": "^17.4.0", - "lodash": "^4.17.21", - "minimist": "^1.2.5", - "rxjs": "^7.1.0" - }, - "dependencies": { - "rxjs": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.4.0.tgz", - "integrity": "sha512-7SQDi7xeTMCJpqViXh8gL/lebcwlp3d831F05+9B44A4B0WfsEwUQHR64gsH1kvJ+Ep/J9K2+n1hVl1CsGN23w==", - "dev": true, - "requires": { - "tslib": "~2.1.0" - } - }, - "tslib": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", - "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", - "dev": true - } - } - }, - "walk-up-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/walk-up-path/-/walk-up-path-1.0.0.tgz", - "integrity": "sha512-hwj/qMDUEjCU5h0xr90KGCf0tg0/LgJbmOWgrWKYlcJZM7XvquvUJZ0G/HMGr7F7OQMOUuPHWP9JpriinkAlkg==", - "dev": true - }, - "walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, - "requires": { - "makeerror": "1.0.12" - } - }, - "warning": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", - "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", - "requires": { - "loose-envify": "^1.0.0" - } - }, - "watchpack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.2.0.tgz", - "integrity": "sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA==", - "dev": true, - "requires": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - } - }, - "wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "dev": true, - "requires": { - "minimalistic-assert": "^1.0.0" - } - }, - "wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", - "dev": true, - "requires": { - "defaults": "^1.0.3" - } - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", - "dev": true - }, - "webpack": { - "version": "5.58.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.58.2.tgz", - "integrity": "sha512-3S6e9Vo1W2ijk4F4PPWRIu6D/uGgqaPmqw+av3W3jLDujuNkdxX5h5c+RQ6GkjVR+WwIPOfgY8av+j5j4tMqJw==", - "dev": true, - "requires": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.50", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "acorn": "^8.4.1", - "acorn-import-assertions": "^1.7.6", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.3", - "es-module-lexer": "^0.9.0", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.2.0", - "webpack-sources": "^3.2.0" - }, - "dependencies": { - "acorn": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", - "dev": true - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true - }, - "tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true - } - } - }, - "webpack-cli": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.9.1.tgz", - "integrity": "sha512-JYRFVuyFpzDxMDB+v/nanUdQYcZtqFPGzmlW4s+UkPMFhSpfRNmf1z4AwYcHJVdvEFAM7FFCQdNTpsBYhDLusQ==", - "dev": true, - "requires": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.1.0", - "@webpack-cli/info": "^1.4.0", - "@webpack-cli/serve": "^1.6.0", - "colorette": "^2.0.14", - "commander": "^7.0.0", - "execa": "^5.0.0", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^2.2.0", - "rechoir": "^0.7.0", - "webpack-merge": "^5.7.3" - }, - "dependencies": { - "colorette": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", - "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", - "dev": true - }, - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true - }, - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true - }, - "interpret": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", - "dev": true - }, - "rechoir": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", - "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", - "dev": true, - "requires": { - "resolve": "^1.9.0" - } - }, - "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "dev": true, - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - } - } - }, - "webpack-dev-middleware": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.2.2.tgz", - "integrity": "sha512-DjZyYrsHhkikAFNvSNKrpnziXukU1EChFAh9j4LAm6ndPLPW8cN0KhM7T+RAiOqsQ6ABfQ8hoKIs9IWMTjov+w==", - "dev": true, - "requires": { - "colorette": "^2.0.10", - "memfs": "^3.2.2", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - }, - "dependencies": { - "ajv": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.1.tgz", - "integrity": "sha512-6CiMNDrzv0ZR916u2T+iRunnD60uWmNn8SkdB44/6stVORUg0aAkWO7PkOhpCmjmW8f2I/G/xnowD66fxGyQJg==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.0.0.tgz", - "integrity": "sha512-ULd1QMjRoH6JDNUQIfDLrlE+OgZlFaxyYCjzt58uNuUQtKXt8/U+vK/8Ql0gyn/C5mqZzUWtKMqr/4YquvTrWA==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.3" - } - }, - "colorette": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", - "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", - "dev": true - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - } - } - } - }, - "webpack-dev-server": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.3.1.tgz", - "integrity": "sha512-qNXQCVYo1kYhH9pgLtm8LRNkXX3XzTfHSj/zqzaqYzGPca+Qjr+81wj1jgPMCHhIhso9WEQ+kX9z23iG9PzQ7w==", - "dev": true, - "requires": { - "ansi-html-community": "^0.0.8", - "bonjour": "^3.5.0", - "chokidar": "^3.5.1", - "colorette": "^2.0.10", - "compression": "^1.7.4", - "connect-history-api-fallback": "^1.6.0", - "del": "^6.0.0", - "express": "^4.17.1", - "graceful-fs": "^4.2.6", - "html-entities": "^2.3.2", - "http-proxy-middleware": "^2.0.0", - "internal-ip": "^6.2.0", - "ipaddr.js": "^2.0.1", - "open": "^8.0.9", - "p-retry": "^4.5.0", - "portfinder": "^1.0.28", - "schema-utils": "^3.1.0", - "selfsigned": "^1.10.11", - "serve-index": "^1.9.1", - "sockjs": "^0.3.21", - "spdy": "^4.0.2", - "strip-ansi": "^7.0.0", - "url": "^0.11.0", - "webpack-dev-middleware": "^5.2.1", - "ws": "^8.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true - }, - "colorette": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", - "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", - "dev": true - }, - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - }, - "strip-ansi": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", - "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", - "dev": true, - "requires": { - "ansi-regex": "^6.0.1" - } - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - } - }, - "ws": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", - "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", - "dev": true - } - } - }, - "webpack-merge": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", - "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", - "dev": true, - "requires": { - "clone-deep": "^4.0.1", - "wildcard": "^2.0.0" - } - }, - "webpack-notifier": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/webpack-notifier/-/webpack-notifier-1.14.1.tgz", - "integrity": "sha512-OVOoiOyKHS3z9pN1nLdPY2Pf/R3wiBsN0KiPc3K6ApwMBfHbyUomQc2Mr0naeKxfqXyCBPHfQuqpL9yoL0rgkA==", - "dev": true, - "requires": { - "node-notifier": "^9.0.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "webpack-sources": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.2.tgz", - "integrity": "sha512-cp5qdmHnu5T8wRg2G3vZZHoJPN14aqQ89SyQ11NpGH5zEMDCclt49rzo+MaRazk7/UeILhAI+/sEtcM+7Fr0nw==", - "dev": true - }, - "websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "dev": true, - "requires": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - } - }, - "websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "dev": true - }, - "whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, - "requires": { - "iconv-lite": "0.4.24" - } - }, - "whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "dev": true - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "dev": true, - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "which-pm": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-pm/-/which-pm-2.0.0.tgz", - "integrity": "sha512-Lhs9Pmyph0p5n5Z3mVnN0yWcbQYUAD7rbQUiMsQxOJ3T57k7RFe35SUwWMf7dsbDZks1uOmw4AecB/JMDj3v/w==", - "dev": true, - "requires": { - "load-yaml-file": "^0.2.0", - "path-exists": "^4.0.0" - } - }, - "wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "wildcard": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", - "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", - "dev": true - }, - "windows-release": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-4.0.0.tgz", - "integrity": "sha512-OxmV4wzDKB1x7AZaZgXMVsdJ1qER1ed83ZrTYd5Bwq2HfJVg3DJS8nqlAG4sMoJ7mu8cuRmLEYyU13BKwctRAg==", - "dev": true, - "requires": { - "execa": "^4.0.2" - } - }, - "winston": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.3.3.tgz", - "integrity": "sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw==", - "dev": true, - "requires": { - "@dabh/diagnostics": "^2.0.2", - "async": "^3.1.0", - "is-stream": "^2.0.0", - "logform": "^2.2.0", - "one-time": "^1.0.0", - "readable-stream": "^3.4.0", - "stack-trace": "0.0.x", - "triple-beam": "^1.3.0", - "winston-transport": "^4.4.0" - }, - "dependencies": { - "async": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.2.tgz", - "integrity": "sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g==", - "dev": true - } - } - }, - "winston-transport": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.4.0.tgz", - "integrity": "sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw==", - "dev": true, - "requires": { - "readable-stream": "^2.3.7", - "triple-beam": "^1.2.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - }, - "workbox-background-sync": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.3.0.tgz", - "integrity": "sha512-79Wznt6oO8xMmLiErRS4zENUEldFHj1/5IiuHsY3NgGRN5rJdvGW6hz+RERhWzoB7rd/vXyAQdKYahGdsiYG1A==", - "dev": true, - "requires": { - "idb": "^6.0.0", - "workbox-core": "6.3.0" - } - }, - "workbox-broadcast-update": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.3.0.tgz", - "integrity": "sha512-hp7Du6GJzK99wak5cQFhcSBxvcS+2fkFcxiMmz/RsQ5GQNxVcbiovq74w5aNCzuv3muQvICyC1XELZhZ4GYRTQ==", - "dev": true, - "requires": { - "workbox-core": "6.3.0" - } - }, - "workbox-build": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-6.3.0.tgz", - "integrity": "sha512-Th93AaC+88ZvJje0acTjCCCvU3tGenxJht5xUALXHW+Mzk3I5SMzTFwKn5F3e1iZ+M7U2jjfpMXe/sJ4UMx46A==", - "dev": true, - "requires": { - "@apideck/better-ajv-errors": "^0.2.4", - "@babel/core": "^7.11.1", - "@babel/preset-env": "^7.11.0", - "@babel/runtime": "^7.11.2", - "@rollup/plugin-babel": "^5.2.0", - "@rollup/plugin-node-resolve": "^11.2.1", - "@rollup/plugin-replace": "^2.4.1", - "@surma/rollup-plugin-off-main-thread": "^1.4.1", - "ajv": "^8.6.0", - "common-tags": "^1.8.0", - "fast-json-stable-stringify": "^2.1.0", - "fs-extra": "^9.0.1", - "glob": "^7.1.6", - "lodash": "^4.17.20", - "pretty-bytes": "^5.3.0", - "rollup": "^2.43.1", - "rollup-plugin-terser": "^7.0.0", - "source-map": "^0.8.0-beta.0", - "source-map-url": "^0.4.0", - "stringify-object": "^3.3.0", - "strip-comments": "^2.0.1", - "tempy": "^0.6.0", - "upath": "^1.2.0", - "workbox-background-sync": "6.3.0", - "workbox-broadcast-update": "6.3.0", - "workbox-cacheable-response": "6.3.0", - "workbox-core": "6.3.0", - "workbox-expiration": "6.3.0", - "workbox-google-analytics": "6.3.0", - "workbox-navigation-preload": "6.3.0", - "workbox-precaching": "6.3.0", - "workbox-range-requests": "6.3.0", - "workbox-recipes": "6.3.0", - "workbox-routing": "6.3.0", - "workbox-strategies": "6.3.0", - "workbox-streams": "6.3.0", - "workbox-sw": "6.3.0", - "workbox-window": "6.3.0" - }, - "dependencies": { - "ajv": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.1.tgz", - "integrity": "sha512-6CiMNDrzv0ZR916u2T+iRunnD60uWmNn8SkdB44/6stVORUg0aAkWO7PkOhpCmjmW8f2I/G/xnowD66fxGyQJg==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "source-map": { - "version": "0.8.0-beta.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", - "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", - "dev": true, - "requires": { - "whatwg-url": "^7.0.0" - } - }, - "strip-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz", - "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==", - "dev": true - }, - "tr46": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", - "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - }, - "webidl-conversions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", - "dev": true - }, - "whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", - "dev": true, - "requires": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - } - } - }, - "workbox-cacheable-response": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.3.0.tgz", - "integrity": "sha512-oYCRGF6PFEmJJkktdxYw/tcrU8N5u/2ihxVSHd+9sNqjNMDiXLqsewcEG544f1yx7gq5/u6VcvUA5N62KzN1GQ==", - "dev": true, - "requires": { - "workbox-core": "6.3.0" - } - }, - "workbox-core": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.3.0.tgz", - "integrity": "sha512-SufToEV3SOLwwz3j+P4pgkfpzLRUlR17sX3p/LrMHP/brYKvJQqjTwtSvaCkkAX0RPHX2TFHmN8xhPP1bpmomg==", - "dev": true - }, - "workbox-expiration": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.3.0.tgz", - "integrity": "sha512-teYuYfM3HFbwAD/nlZDw/dCMOrCKjsAiMRhz0uOy9IkfBb7vBynO3xf118lY62X6BfqjZdeahiHh10N0/aYICg==", - "dev": true, - "requires": { - "idb": "^6.0.0", - "workbox-core": "6.3.0" - } - }, - "workbox-google-analytics": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.3.0.tgz", - "integrity": "sha512-6u0y21rtimnrCKpvayTkwh9y4Y5Xdn6X87x895WzwcOcWA2j/Nl7nmCpB0wjjhqU9pMj7B2lChqfypP+xUs5IA==", - "dev": true, - "requires": { - "workbox-background-sync": "6.3.0", - "workbox-core": "6.3.0", - "workbox-routing": "6.3.0", - "workbox-strategies": "6.3.0" - } - }, - "workbox-navigation-preload": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.3.0.tgz", - "integrity": "sha512-D7bomh9SCn1u6n32FqAWfyHe2dkK6mWbwcTsoeBnFSD0p8Gr9Zq1Mpt/DitEfGIQHck90Zd024xcTFLkjczS/Q==", - "dev": true, - "requires": { - "workbox-core": "6.3.0" - } - }, - "workbox-precaching": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.3.0.tgz", - "integrity": "sha512-bND3rUxiuzFmDfeKywdvOqK0LQ5LLbOPk0eX22PlMQNOOduHRxzglMpgHo/MR6h+8cPJ3GpxT8hZ895/7bHMqQ==", - "dev": true, - "requires": { - "workbox-core": "6.3.0", - "workbox-routing": "6.3.0", - "workbox-strategies": "6.3.0" - } - }, - "workbox-range-requests": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.3.0.tgz", - "integrity": "sha512-AHnGtfSvc/fBt+8NCVT6jVcshv7oFkiuS94YsedQu2sIN1jKHkxLaj7qMBl818FoY6x7r0jw1WLmG/QDmI1/oA==", - "dev": true, - "requires": { - "workbox-core": "6.3.0" - } - }, - "workbox-recipes": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.3.0.tgz", - "integrity": "sha512-f0AZyxd48E4t+PV+ifgIf8WodfJqRj8/E0t+PwppDIdTPyD59cIh0HZBtgPKFdIMVnltodpMz4zioxym1H3GjQ==", - "dev": true, - "requires": { - "workbox-cacheable-response": "6.3.0", - "workbox-core": "6.3.0", - "workbox-expiration": "6.3.0", - "workbox-precaching": "6.3.0", - "workbox-routing": "6.3.0", - "workbox-strategies": "6.3.0" - } - }, - "workbox-routing": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.3.0.tgz", - "integrity": "sha512-asajX5UPkaoU4PB9pEpxKWKkcpA+KJQUEeYU6NlK0rXTCpdWQ6iieMRDoBTZBjTzUdL3j3s1Zo2qCOSvtXSYGg==", - "dev": true, - "requires": { - "workbox-core": "6.3.0" - } - }, - "workbox-strategies": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.3.0.tgz", - "integrity": "sha512-SYZt40y+Iu5nA+UEPQOrAuAMMNTxtUBPLCIaMMb4lcADpBYrNP1CD+/s2QsrxzS651a8hfi06REKt+uTp1tqfw==", - "dev": true, - "requires": { - "workbox-core": "6.3.0" - } - }, - "workbox-streams": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.3.0.tgz", - "integrity": "sha512-CiRsuoXJOytA7IQriRu6kVCa0L4OdNi0DdniiSageu/EZuxTswNXpgVzkGE4IDArU/5jlzgRtwqrqIWCJX+OMA==", - "dev": true, - "requires": { - "workbox-core": "6.3.0", - "workbox-routing": "6.3.0" - } - }, - "workbox-sw": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.3.0.tgz", - "integrity": "sha512-xwrXRBzw5jwJ7VdAQkTSNTbNZ4S6VhXtbZZ0vY6XKNQARO5nuGphNdif+hJFIejHUgtV6ESpQnixPj5hYB2jKQ==", - "dev": true - }, - "workbox-webpack-plugin": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-6.3.0.tgz", - "integrity": "sha512-3l5H8h7O2eUgTAISQoglDe4VJDDYTZaDnkRY0FY2+eFOXA+fZoWuDSmLiMnA0uYqPC4NWVTZwP549E0dWgiWjw==", - "dev": true, - "requires": { - "fast-json-stable-stringify": "^2.1.0", - "pretty-bytes": "^5.4.1", - "source-map-url": "^0.4.0", - "upath": "^1.2.0", - "webpack-sources": "^1.4.3", - "workbox-build": "6.3.0" - }, - "dependencies": { - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - } - } - }, - "workbox-window": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-6.3.0.tgz", - "integrity": "sha512-CFP84assX9srH/TOx4OD8z4EBPO/Cq4WKdV2YLcJIFJmVTS/cB63XKeidKl2KJk8qOOLVIKnaO7BLmb0MxGFtA==", - "dev": true, - "requires": { - "@types/trusted-types": "^2.0.2", - "workbox-core": "6.3.0" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "dev": true - }, - "xml": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", - "integrity": "sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=", - "dev": true - }, - "xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "dev": true - }, - "xml2js": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", - "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", - "dev": true, - "requires": { - "sax": ">=0.6.0", - "xmlbuilder": "~9.0.1" - } - }, - "xmlbuilder": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", - "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", - "dev": true - }, - "xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true - }, - "xmlhttprequest-ssl": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.3.tgz", - "integrity": "sha512-3XfeQE/wNkvrIktn2Kf0869fC0BN6UpydVasGIeSm2B1Llihf7/0UfZM+eCkOw3P7bP4+qPgqhm7ZoxuJtFU0Q==", - "dev": true - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true - }, - "yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true - }, - "yeast": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", - "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", - "dev": true - }, - "yeoman-environment": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/yeoman-environment/-/yeoman-environment-3.6.0.tgz", - "integrity": "sha512-X16N9lhzRdUKFT8MZrpwjLDKsdgAUqh4VPR2wAXeAqjJJaUxYBxCQGFxtZVTf3vbyNuIHXPunwOLtK60bpapbg==", - "dev": true, - "requires": { - "@npmcli/arborist": "^2.2.2", - "are-we-there-yet": "^1.1.5", - "arrify": "^2.0.1", - "binaryextensions": "^4.15.0", - "chalk": "^4.1.0", - "cli-table": "^0.3.1", - "commander": "7.1.0", - "dateformat": "^4.5.0", - "debug": "^4.1.1", - "diff": "^5.0.0", - "error": "^10.4.0", - "escape-string-regexp": "^4.0.0", - "execa": "^5.0.0", - "find-up": "^5.0.0", - "globby": "^11.0.1", - "grouped-queue": "^2.0.0", - "inquirer": "^8.0.0", - "is-scoped": "^2.1.0", - "lodash": "^4.17.10", - "log-symbols": "^4.0.0", - "mem-fs": "^1.2.0 || ^2.0.0", - "mem-fs-editor": "^8.1.2 || ^9.0.0", - "minimatch": "^3.0.4", - "npmlog": "^4.1.2", - "p-queue": "^6.6.2", - "pacote": "^11.2.6", - "preferred-pm": "^3.0.3", - "pretty-bytes": "^5.3.0", - "semver": "^7.1.3", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0", - "text-table": "^0.2.0", - "textextensions": "^5.12.0", - "untildify": "^4.0.0" - }, - "dependencies": { - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "requires": { - "type-fest": "^0.21.3" - } - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "requires": { - "restore-cursor": "^3.1.0" - } - }, - "cli-width": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", - "dev": true - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "commander": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.1.0.tgz", - "integrity": "sha512-pRxBna3MJe6HKnBGsDyMv8ETbptw3axEdYHoqNh7gu5oDcew8fs0xnivZGm06Ogk8zGAJ9VX+OPEr2GXEQK4dg==", - "dev": true - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - }, - "dependencies": { - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - } - } - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true - }, - "inquirer": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.0.tgz", - "integrity": "sha512-0crLweprevJ02tTuA6ThpoAERAGyVILC4sS74uib58Xf/zSr1/ZWtmm7D5CI+bSQEaA04f0K7idaHpQbSWgiVQ==", - "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.1", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.21", - "mute-stream": "0.0.8", - "ora": "^5.4.1", - "run-async": "^2.4.0", - "rxjs": "^7.2.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6" - }, - "dependencies": { - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, - "rxjs": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.4.0.tgz", - "integrity": "sha512-7SQDi7xeTMCJpqViXh8gL/lebcwlp3d831F05+9B44A4B0WfsEwUQHR64gsH1kvJ+Ep/J9K2+n1hVl1CsGN23w==", - "dev": true, - "requires": { - "tslib": "~2.1.0" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "tslib": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", - "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", - "dev": true - }, - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true - } - } - }, - "yeoman-generator": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/yeoman-generator/-/yeoman-generator-5.4.2.tgz", - "integrity": "sha512-xgS3A4r5VoEYq3vPdk1fWPVZ30y5NHlT2hn0OEyhKG79xojCtPkPkfWcKQamgvC9QLhaotVGvambBxwxwBeDTg==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "dargs": "^7.0.0", - "debug": "^4.1.1", - "execa": "^4.1.0", - "github-username": "^6.0.0", - "lodash": "^4.17.11", - "minimist": "^1.2.5", - "read-pkg-up": "^7.0.1", - "run-async": "^2.0.0", - "semver": "^7.2.1", - "shelljs": "^0.8.4", - "text-table": "^0.2.0" - } - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true - } - } -} diff --git a/package.json b/package.json index a70cdba20..5e9960c04 100644 --- a/package.json +++ b/package.json @@ -1,69 +1,74 @@ { - "name": "oncokb-transcript", + "name": "oncokb-curation", "version": "0.0.1-SNAPSHOT", "private": true, - "description": "Description for oncokb-transcript", + "description": "Description for oncokb-curation", "license": "UNLICENSED", "scripts": { - "app:start": "./mvnw", "backend:build-cache": "./mvnw dependency:go-offline", "backend:debug": "./mvnw -Dspring-boot.run.jvmArguments=\"-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8000\"", "backend:doc:test": "./mvnw -ntp javadoc:javadoc --batch-mode", "backend:info": "./mvnw -ntp enforcer:display-info --batch-mode", "backend:nohttp:test": "./mvnw -ntp checkstyle:check --batch-mode", "backend:start": "./mvnw -P-webapp", - "backend:unit:test": "./mvnw -ntp -P-webapp verify --batch-mode -Dlogging.level.ROOT=OFF -Dlogging.level.org.zalando=OFF -Dlogging.level.tech.jhipster=OFF -Dlogging.level.org.mskcc.oncokb.transcript=OFF -Dlogging.level.org.springframework=OFF -Dlogging.level.org.springframework.web=OFF -Dlogging.level.org.springframework.security=OFF", - "ci:backend:test": "npm run backend:info && npm run backend:doc:test && npm run backend:nohttp:test && npm run backend:unit:test", - "ci:e2e:package": "npm run java:$npm_package_config_packaging:$npm_package_config_default_environment -- -Pe2e -Denforcer.skip=true", - "ci:e2e:prepare": "npm run ci:e2e:prepare:docker", - "ci:e2e:prepare:docker": "npm run docker:db:up && npm run docker:others:up && docker ps -a", - "preci:e2e:server:start": "npm run docker:db:await --if-present && npm run docker:others:await --if-present", - "ci:e2e:server:start": "java -jar target/e2e.$npm_package_config_packaging --spring.profiles.active=$npm_package_config_default_environment -Dlogging.level.ROOT=OFF -Dlogging.level.org.zalando=OFF -Dlogging.level.tech.jhipster=OFF -Dlogging.level.org.mskcc.oncokb.transcript=OFF -Dlogging.level.org.springframework=OFF -Dlogging.level.org.springframework.web=OFF -Dlogging.level.org.springframework.security=OFF --logging.level.org.springframework.web=ERROR", - "ci:e2e:teardown": "npm run ci:e2e:teardown:docker", - "ci:e2e:teardown:docker": "npm run docker:db:down --if-present && npm run docker:others:down && docker ps -a", - "ci:frontend:test": "npm run webapp:build:$npm_package_config_default_environment && npm run test-ci", - "ci:server:package": "npm run java:$npm_package_config_packaging:$npm_package_config_default_environment", + "backend:unit:test": "./mvnw -ntp -P-webapp verify --batch-mode -Dlogging.level.ROOT=OFF -Dlogging.level.org.zalando=OFF -Dlogging.level.tech.jhipster=OFF -Dlogging.level.org.mskcc.oncokb.curation=OFF -Dlogging.level.org.springframework=OFF -Dlogging.level.org.springframework.web=OFF -Dlogging.level.org.springframework.security=OFF", + "ci:backend:test": "yarn run backend:info && yarn run backend:doc:test && yarn run backend:nohttp:test && yarn run backend:unit:test", + "ci:e2e:package": "yarn run java:$yarn_package_config_packaging:$yarn_package_config_default_environment -- -Pe2e -Denforcer.skip=true", + "ci:e2e:prepare": "yarn run ci:e2e:prepare:docker", + "ci:e2e:prepare:docker": "yarn run docker:db:up && yarn run docker:others:up && docker ps -a", + "preci:e2e:server:start": "yarn run docker:db:await --if-present && yarn run docker:others:await --if-present", + "ci:e2e:server:start": "java -jar target/e2e.$yarn_package_config_packaging --spring.profiles.active=$yarn_package_config_default_environment -Dlogging.level.ROOT=OFF -Dlogging.level.org.zalando=OFF -Dlogging.level.tech.jhipster=OFF -Dlogging.level.org.mskcc.oncokb.curation=OFF -Dlogging.level.org.springframework=OFF -Dlogging.level.org.springframework.web=OFF -Dlogging.level.org.springframework.security=OFF --logging.level.org.springframework.web=ERROR", + "ci:e2e:teardown": "yarn run ci:e2e:teardown:docker", + "ci:e2e:teardown:docker": "yarn run docker:db:down --if-present && yarn run docker:others:down && docker ps -a", + "ci:server:package": "yarn run java:$yarn_package_config_packaging:$yarn_package_config_default_environment", "clean-www": "rimraf target/classes/static/app/{src,target/}", "cleanup": "rimraf target/classes/static/", - "docker:app:up": "docker-compose -f src/main/docker/app.yml up -d", + "docker:app:up": "docker-compose -f src/main/docker/app.yml up -d oncokb-curation-app", "docker:db:down": "docker-compose -f src/main/docker/mysql.yml down -v --remove-orphans", "docker:db:up": "docker-compose -f src/main/docker/mysql.yml up -d", - "docker:others:await": "", - "docker:others:down": "npm run docker:redis:down", + "docker:keycloak:down": "docker-compose -f src/main/docker/keycloak.yml down -v --remove-orphans", + "docker:keycloak:up": "docker-compose -f src/main/docker/keycloak.yml up -d", + "docker:others:await": "echo \"Waiting for keycloak to start\" && wait-on http-get://localhost:8080/auth/realms/oncokb-curation -t 30000 && echo \"keycloak started\" || echo \"keycloak not running, make sure oauth2 server is running\"", + "docker:others:down": "yarn run docker:keycloak:down && yarn run docker:redis:down", "predocker:others:up": "", - "docker:others:up": "npm run docker:redis:up", + "docker:others:up": "yarn run docker:keycloak:up && yarn run docker:redis:up", "docker:redis:down": "docker-compose -f src/main/docker/redis.yml down -v --remove-orphans", "docker:redis:up": "docker-compose -f src/main/docker/redis.yml up -d", + "firebase-emulator": "node node_modules/firebase-tools/lib/bin/firebase.js emulators:start --import src/test/javascript/firebase --project oncokb-curation-test-54b6c", "java:docker": "./mvnw -ntp verify -DskipTests jib:dockerBuild", - "java:docker:arm64": "npm run java:docker -- -Djib-maven-plugin.architecture=arm64", - "java:docker:dev": "npm run java:docker -- -Pdev,webapp", - "java:docker:prod": "npm run java:docker -- -Pprod", + "java:docker:arm64": "yarn run java:docker -- -Djib-maven-plugin.architecture=arm64", + "java:docker:dev": "yarn run java:docker -- -Pdev,webapp", + "java:docker:prod": "yarn run java:docker -- -Pprod", "java:jar": "./mvnw -ntp verify -DskipTests --batch-mode", - "java:jar:dev": "npm run java:jar -- -Pdev,webapp", - "java:jar:prod": "npm run java:jar -- -Pprod", + "java:jar:dev": "yarn run java:jar -- -Pdev,webapp", + "java:jar:prod": "yarn run java:jar -- -Pprod", "java:war": "./mvnw -ntp verify -DskipTests --batch-mode -Pwar", - "java:war:dev": "npm run java:war -- -Pdev,webapp", - "java:war:prod": "npm run java:war -- -Pprod", + "java:war:dev": "yarn run java:war -- -Pdev,webapp", + "java:war:prod": "yarn run java:war -- -Pprod", "jest": "jest --coverage --logHeapUsage --maxWorkers=2 --config jest.conf.js", - "jest:update": "npm run jest -- --updateSnapshot", + "jest:update": "yarn run jest -- --updateSnapshot", "lint": "eslint . --ext .js,.ts,.jsx,.tsx", - "lint:fix": "npm run lint -- --fix", - "prepare": "husky install", + "lint:fix": "yarn run lint -- --fix", + "prepare": "husky", "prettier:check": "prettier --check \"{,src/**/,webpack/}*.{md,json,yml,html,cjs,mjs,js,ts,tsx,css,scss,java}\"", "prettier:format": "prettier --write \"{,src/**/,webpack/}*.{md,json,yml,html,cjs,mjs,js,ts,tsx,css,scss,java}\"", - "start": "npm run webapp:dev --", - "start-tls": "npm run webapp:dev -- --env.tls", - "pretest": "npm run lint", - "test": "npm run jest --", - "test-ci": "npm run lint && npm run jest:update --", - "test:watch": "npm run jest -- --watch", - "webapp:build": "npm run clean-www && npm run webapp:build:dev --", + "screenshot-test": "yarn start & yarn run firebase-emulator & wait-on http-get://localhost:9000 & wait-on http-get://localhost:9095 & wait-on http-get://localhost:9099 && yarn run wdio && kill $(lsof -t -i:9000) kill $(lsof -t -i:4400)", + "start": "yarn run webapp:dev --", + "start-tls": "yarn run webapp:dev --env tls", + "pretest": "yarn run lint", + "test": "yarn run jest --", + "test-ci": "yarn run lint && yarn run jest:update --", + "test:watch": "yarn run jest -- --watch", + "updateAPI": "openapi-generator-cli generate -i http://localhost:9090/v3/api-docs -g typescript-axios -o src/main/webapp/app/shared/api/generated/curation --type-mappings set=Array", + "updateCoreAPI": "curl http://localhost:8000/oncokb/api/v1/v2/api-docs?group=Private%20APIs | jq '.definitions.ResponseEntity.properties.statusCode.enum |= unique' > /tmp/updateCoreAPI.json && openapi-generator-cli generate -i /tmp/updateCoreAPI.json -g typescript-axios -o src/main/webapp/app/shared/api/generated/core --type-mappings List=any", + "wdio": "cross-env TS_NODE_PROJECT=src/test/javascript/tsconfig.json wdio run ./wdio.conf.ts", + "webapp:build": "yarn run clean-www && yarn run webapp:build:dev --", "webapp:build:dev": "webpack --config webpack/webpack.dev.js --env stats=minimal", "webapp:build:prod": "webpack --config webpack/webpack.prod.js --progress=profile", - "webapp:dev": "npm run webpack-dev-server -- --config webpack/webpack.dev.js --env stats=minimal", - "webapp:dev-verbose": "npm run webpack-dev-server -- --config webpack/webpack.dev.js --progress=profile --env stats=normal", - "webapp:prod": "npm run clean-www && npm run webapp:build:prod --", - "webapp:test": "npm run test --", + "webapp:dev": "yarn run webpack-dev-server -- --config webpack/webpack.dev.js --env stats=minimal", + "webapp:dev-verbose": "yarn run webpack-dev-server -- --config webpack/webpack.dev.js --progress=profile --env stats=normal", + "webapp:prod": "yarn run clean-www && yarn run webapp:build:prod --", + "webapp:test": "yarn run test --", "webpack-dev-server": "webpack serve" }, "config": { @@ -72,99 +77,145 @@ "packaging": "jar" }, "dependencies": { - "@fortawesome/fontawesome-svg-core": "1.2.36", - "@fortawesome/free-solid-svg-icons": "5.15.4", - "@fortawesome/react-fontawesome": "0.1.16", - "@reduxjs/toolkit": "1.6.2", - "axios": "0.21.4", - "bootstrap": "4.6.0", - "dayjs": "1.10.7", + "@fortawesome/fontawesome-svg-core": "6.5.2", + "@fortawesome/free-regular-svg-icons": "^6.5.2", + "@fortawesome/free-solid-svg-icons": "^6.5.2", + "@fortawesome/react-fontawesome": "0.2.0", + "@larryyangsen/react-infinite-scroller": "1.2.6", + "@mskcc/core": "^10.4.1", + "@sentry/react": "^7.112.2", + "@sentry/webpack-plugin": "^2.17.0", + "@superwf/mobx-react-router": "^7.4.0", + "availity-reactstrap-validation": "^2.7.1", + "axios": "1.6.8", + "bootstrap": "5.3.3", + "classnames": "^2.5.1", + "date-fns": "^4.1.0", + "dayjs": "1.11.11", + "diff-match-patch": "^1.0.5", + "firebase": "^10.11.1", + "firebase-admin": "^12.2.0", + "history": "^5.3.0", + "jest-mock-extended": "^3.0.7", + "loaders.css": "", "lodash": "4.17.21", + "mobx": "^6.12.3", + "mobx-react": "^9.1.1", + "oncokb-styles": "^1.5.0", "path-browserify": "1.0.1", - "postcss": "^8.3.11", + "pluralize": "^8.0.0", + "rc-tooltip": "^6.2.0", "react": "17.0.1", + "react-date-range": "^2.0.1", "react-dom": "17.0.1", - "react-hook-form": "7.17.4", - "react-jhipster": "0.17.0", + "react-event-timeline": "^1.6.3", + "react-firebase-hooks": "^5.1.1", + "react-highlight-words": "^0.20.0", + "react-hook-form": "7.51.3", + "react-icons": "^5.1.0", + "react-jhipster": "0.25.3", "react-loadable": "5.5.0", - "react-redux": "7.2.5", - "react-redux-loading-bar": "5.0.2", + "react-pro-sidebar": "^1.1.0", + "react-range-slider-input": "^3.2.1", "react-router-dom": "5.3.0", - "react-toastify": "8.0.3", - "react-transition-group": "4.4.2", - "reactstrap": "8.10.0", - "redux": "4.1.1", - "redux-thunk": "2.3.0", - "tslib": "2.3.1", - "uuid": "8.3.2" + "react-select": "^5.8.0", + "react-select-async-paginate": "^0.7.4", + "react-spinkit": "^3.0.0", + "react-table": "^6.10.3", + "react-toastify": "8.0.2", + "react-transition-group": "4.4.5", + "react-with-separator": "^1.2.1", + "reactstrap": "9.2.2", + "tslib": "2.6.2", + "uuid": "^9.0.1", + "webpack-cli": "^5.1.4" }, "devDependencies": { - "@testing-library/react": "12.1.2", - "@types/jest": "27.0.2", - "@types/lodash": "4.14.175", - "@types/node": "16.11.1", - "@types/react": "17.0.30", + "@openapitools/openapi-generator-cli": "^2.13.4", + "@testing-library/jest-dom": "^6.4.5", + "@testing-library/react": "12.1.5", + "@types/jest": "29.5.12", + "@types/lodash": "4.17.0", + "@types/node": "20.12.7", + "@types/pluralize": "^0.0.33", + "@types/react": "17.0.20", + "@types/react-date-range": "^1.4.10", "@types/react-dom": "17.0.9", - "@types/react-redux": "7.1.19", - "@types/react-router-dom": "5.3.1", - "@types/redux": "3.6.31", - "@types/webpack-env": "1.16.3", - "@typescript-eslint/eslint-plugin": "4.33.0", - "@typescript-eslint/parser": "4.33.0", - "autoprefixer": "10.3.7", - "browser-sync": "2.27.5", + "@types/react-highlight-words": "^0.16.7", + "@types/react-router-dom": "5.3.3", + "@types/react-spinkit": "^3.0.10", + "@types/react-table": "^6.8.1", + "@types/uuid": "^9.0.8", + "@types/webpack-env": "1.18.4", + "@typescript-eslint/eslint-plugin": "7.8.0", + "@typescript-eslint/parser": "7.8.0", + "@wdio/cli": "^8.36.1", + "@wdio/local-runner": "^8.36.1", + "@wdio/mocha-framework": "^8.36.1", + "@wdio/spec-reporter": "^8.36.1", + "@wdio/visual-service": "^4.1.2", + "autoprefixer": "10.4.19", + "browser-sync": "3.0.2", "browser-sync-webpack-plugin": "2.3.0", - "concurrently": "6.3.0", - "copy-webpack-plugin": "9.0.1", - "core-js": "3.18.3", + "concurrently": "8.2.2", + "copy-webpack-plugin": "12.0.2", + "core-js": "3.37.0", "cross-env": "7.0.3", - "css-loader": "6.4.0", - "css-minimizer-webpack-plugin": "3.1.1", - "eslint": "7.32.0", - "eslint-config-prettier": "8.3.0", - "eslint-plugin-react": "7.26.1", - "eslint-webpack-plugin": "3.0.1", - "fork-ts-checker-webpack-plugin": "6.3.4", - "generator-jhipster": "7.3.1", - "html-webpack-plugin": "5.4.0", - "husky": "7.0.2", + "css-loader": "7.1.1", + "css-minimizer-webpack-plugin": "6.0.0", + "enzyme": "^3.11.0", + "eslint": "^8.57.0", + "eslint-config-prettier": "9.1.0", + "eslint-plugin-react": "7.34.1", + "eslint-webpack-plugin": "4.1.0", + "file-loader": "^6.2.0", + "firebase-tools": "^13.8.0", + "fork-ts-checker-webpack-plugin": "9.0.2", + "generator-jhipster": "8.3.0", + "generator-jhipster-react-mobx": "1.3.0", + "html-webpack-plugin": "5.6.0", + "husky": "9.0.11", "identity-obj-proxy": "3.0.0", - "jest": "27.3.0", - "jest-junit": "13.0.0", + "jest": "29.7.0", + "jest-environment-jsdom": "^29.7.0", + "jest-expect-message": "^1.1.3", + "jest-junit": "16.0.0", "jest-sonar-reporter": "2.0.0", "json-loader": "0.5.7", - "lint-staged": "11.2.3", - "mini-css-extract-plugin": "2.4.2", - "postcss-loader": "6.2.0", - "prettier": "2.4.1", - "prettier-plugin-java": "1.5.0", - "prettier-plugin-packagejson": "2.2.13", - "react-infinite-scroller": "1.2.4", - "redux-mock-store": "1.5.4", - "rimraf": "3.0.2", - "sass": "1.43.2", - "sass-loader": "12.2.0", + "lint-staged": "11.1.2", + "mini-css-extract-plugin": "2.9.0", + "node-sass": "^9.0.0", + "postcss-loader": "8.1.1", + "prettier": "3.2.5", + "prettier-plugin-java": "2.6.0", + "prettier-plugin-packagejson": "2.5.0", + "react-if": "^4.1.5", + "react-progressive-image": "^0.6.0", + "rimraf": "5.0.5", + "sass": "1.75.0", + "sass-loader": "14.2.1", + "sass-resources-loader": "^2.2.5", "simple-progress-webpack-plugin": "2.0.0", - "sinon": "11.1.2", - "source-map-loader": "3.0.0", + "sinon": "17.0.1", + "source-map-loader": "5.0.0", "sourcemap-istanbul-instrumenter-loader": "0.2.0", - "style-loader": "3.3.0", - "swagger-ui-dist": "4.1.3", - "terser-webpack-plugin": "5.2.4", - "thread-loader": "3.0.4", - "ts-jest": "27.0.7", - "ts-loader": "9.2.6", - "typescript": "4.4.4", - "wait-on": "6.0.0", - "webpack": "5.58.2", - "webpack-cli": "4.9.1", - "webpack-dev-server": "4.3.1", - "webpack-merge": "5.8.0", - "webpack-notifier": "1.14.1", - "workbox-webpack-plugin": "6.3.0" + "style-loader": "4.0.0", + "swagger-ui-dist": "5.17.2", + "terser-webpack-plugin": "5.3.10", + "thread-loader": "4.0.2", + "ts-jest": "29.1.2", + "ts-loader": "9.5.1", + "ts-node": "^10.9.2", + "typescript": "5.4.5", + "wait-on": "7.2.0", + "webpack": "5.91.0", + "webpack-dev-server": "5.0.4", + "webpack-merge": "5.10.0", + "webpack-notifier": "1.15.0", + "workbox-webpack-plugin": "7.1.0" }, "engines": { - "node": ">=14.17.6 <15" + "node": ">=20.12.2" }, "cacheDirectories": [ "node_modules" diff --git a/pom.xml b/pom.xml index 8e632ffe9..ffcbe2f6b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,12 +5,19 @@ https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.mskcc.oncokb.transcript - oncokb-transcript - 0.9.4 + org.mskcc.oncokb.curation + oncokb-curation + 2.2.12 jar - OncoKB Transcript - Description for oncokb-transcript + OncoKB Curation + Description for oncokb-curation + + org.springframework.boot + spring-boot-starter-parent + 3.3.0 + + + @@ -20,115 +27,164 @@ - - - - - 3.3.9 - 11 - - v14.17.6 - 6.14.15 - + 17 + v20.12.2 + v1.22.22 UTF-8 UTF-8 yyyyMMddHHmmss ${java.version} ${java.version} - org.mskcc.oncokb.transcript.OncokbTranscriptApp - -Djava.security.egd=file:/dev/./urandom -Xmx256m + org.mskcc.oncokb.curation.OncokbCurationApp + -Djava.security.egd=file:/dev/./urandom -Xmx1G jdt_apt false - - - - + ${project.parent.version} - - 7.3.1 - - 2.5.5 - - 5.4.32.Final - - 3.27.0-GA - - 4.5.0 - 4.5.0 - 2.0.1.Final - 2.3.3 - 0.21.0 - 1.4.2.Final - - 3.1.0 - 3.9.1 - 3.8.1 - 3.3.1 - 2.10 - 3.0.0 - 3.0.0-M5 - 2.2.1 - 3.2.0 - 3.0.0-M5 - 3.3.1 - 3.1.2 - 9.0 - 0.0.9 - 1.12.0 + 1.3.0 + 10.17.0 1.11 - 3.0.0 - 5.0.0 - 2.3.0 - 0.8.7 - 3.3.1 - eclipse-temurin:11-jre-focal + 1.15.0 + 8.0.2 + 0.8.12 + 7.5.0 + 20240303 + 1.17.2 + 0.12.6 + 8.5.0 + eclipse-temurin:17-jre-focal + 3.4.2 1.0.0 - 1.0.0 - 3.9.0.2155 - + + + + 1.5.5.Final + 3.1.0 + 3.3.1 + 3.3.2 + 3.13.0 + 3.5.0 + 3.2.5 + 3.4.1 + 3.6.3 + 3.3.1 + 3.12.1 + 3.2.5 + 3.4.0 + 2.9.0 + 0.0.11 + + + + + + 1.2.1 + 3.30.0 + 3.11.0.3922 + 2.43.0 + 2.5.0 - - - - tech.jhipster - jhipster-dependencies - ${jhipster-dependencies.version} - pom - import - - - - - tech.jhipster jhipster-framework + ${jhipster-framework.version} + + + org.springframework.boot + spring-boot-configuration-processor + provided + + + org.springframework.boot + spring-boot-loader-tools + + + org.springframework.boot + spring-boot-starter-actuator - javax.annotation - javax.annotation-api + org.springframework.boot + spring-boot-starter-aop org.springframework.boot spring-boot-starter-cache - com.fasterxml.jackson.module - jackson-module-jaxb-annotations + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-logging + + + org.springframework.boot + spring-boot-starter-mail + + + org.springframework.boot + spring-boot-starter-oauth2-client + + + org.springframework.boot + spring-boot-starter-oauth2-resource-server + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.springframework.boot + spring-boot-starter-undertow + + + org.springframework.boot + spring-boot-starter-validation + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + org.springframework.boot + spring-boot-test + test + + + org.springframework.security + spring-security-data + + + org.springframework.security + spring-security-test + test + + + org.springdoc + springdoc-openapi-starter-webmvc-api + ${springdoc-openapi-starter-webmvc-api.version} com.fasterxml.jackson.datatype - jackson-datatype-hibernate5 + jackson-datatype-hibernate6 com.fasterxml.jackson.datatype @@ -139,57 +195,61 @@ jackson-datatype-jsr310 - com.h2database - h2 - test + com.fasterxml.jackson.module + jackson-module-jaxb-annotations - org.redisson - redisson + com.github.ben-manes.caffeine + caffeine - org.testcontainers - testcontainers + com.mysql + mysql-connector-j + + + com.tngtech.archunit + archunit-junit5-api + ${archunit-junit5.version} test - io.springfox - springfox-oas + + + com.tngtech.archunit + archunit-junit5-engine + ${archunit-junit5.version} + test - io.springfox - springfox-swagger2 + com.zaxxer + HikariCP - io.springfox - springfox-bean-validators + io.micrometer + micrometer-registry-prometheus-simpleclient - com.zaxxer - HikariCP + jakarta.annotation + jakarta.annotation-api org.apache.commons commons-lang3 - org.testcontainers - mysql - test + org.glassfish.jaxb + jaxb-runtime + provided - mysql - mysql-connector-java + org.hibernate.orm + hibernate-core - org.hibernate + org.hibernate.orm hibernate-jpamodelgen provided - - org.hibernate - hibernate-core - org.hibernate.validator hibernate-validator @@ -197,7 +257,6 @@ org.liquibase liquibase-core - ${liquibase.version} @@ -212,129 +271,115 @@ provided - org.springframework.boot - spring-boot-configuration-processor - provided - - - org.springframework.boot - spring-boot-loader-tools - - - org.springframework.boot - spring-boot-starter-actuator - - - org.springframework.boot - spring-boot-starter-data-jpa - - - org.springframework.boot - spring-boot-starter-logging + org.redisson + redisson + ${redisson.version} - org.springframework.boot - spring-boot-starter-mail + org.testcontainers + jdbc + test - org.springframework.boot - spring-boot-starter-security + org.testcontainers + junit-jupiter + test - org.springframework.boot - spring-boot-starter-thymeleaf + org.testcontainers + mysql + test - org.springframework.boot - spring-boot-starter-web + org.testcontainers + testcontainers + test + + org.springframework.boot - spring-boot-starter-test - test - - - org.junit.vintage - junit-vintage-engine - - + spring-boot-starter-websocket - org.springframework.boot - spring-boot-test - test + com.github.genome-nexus + genome-nexus-java-api-client + c8ba14d555 - org.springframework.security - spring-security-test - test + com.github.oncokb + oncokb-java-api-client + 04138bd57c - com.tngtech.archunit - archunit-junit5-api - ${archunit-junit5.version} - test + com.github.oncokb + oncokb-meta + b2d8daff89 - - - com.tngtech.archunit - archunit-junit5-engine - ${archunit-junit5.version} - test + com.google.firebase + firebase-admin + 9.1.1 - org.zalando - problem-spring-web + io.sentry + sentry-spring-boot-starter-jakarta + 7.14.0 io.jsonwebtoken jjwt-api + ${jsonwebtoken.version} io.jsonwebtoken jjwt-impl + ${jsonwebtoken.version} runtime io.jsonwebtoken jjwt-jackson + ${jsonwebtoken.version} runtime - - - - org.springframework.security - spring-security-data - - io.micrometer - micrometer-registry-prometheus + org.json + json + ${json.version} - io.dropwizard.metrics - metrics-core + org.jsoup + jsoup + ${jsoup.version} - - com.github.genome-nexus - genome-nexus-java-api-client - 0709b8232b + org.javers + javers-spring-boot-starter-sql + ${javers.version} + - com.github.oncokb - oncokb-java-api-client - d6420c10dd + com.squareup.okio + okio + 2.8.0 + + + + + - com.github.oncokb - oncokb-meta - b2d8daff89 + javax.xml.bind + jaxb-api + 2.3.1 - org.json - json - 20201115 + com.sun.xml.bind + jaxb-impl + 2.3.6 @@ -342,24 +387,28 @@ spring-boot:run - org.apache.maven.plugins - maven-compiler-plugin - - 11 - 11 - + org.springframework.boot + spring-boot-maven-plugin - org.apache.maven.plugins - maven-checkstyle-plugin + com.diffplug.spotless + spotless-maven-plugin + + + com.google.cloud.tools + jib-maven-plugin org.apache.maven.plugins - maven-javadoc-plugin + maven-checkstyle-plugin org.apache.maven.plugins - maven-eclipse-plugin + maven-compiler-plugin + + 16 + 16 + org.apache.maven.plugins @@ -371,7 +420,7 @@ org.apache.maven.plugins - maven-idea-plugin + maven-javadoc-plugin org.apache.maven.plugins @@ -381,26 +430,6 @@ org.apache.maven.plugins maven-surefire-plugin - - org.jacoco - jacoco-maven-plugin - - - org.sonarsource.scanner.maven - sonar-maven-plugin - - - org.liquibase - liquibase-maven-plugin - - - org.springframework.boot - spring-boot-maven-plugin - - - com.google.cloud.tools - jib-maven-plugin - org.codehaus.mojo properties-maven-plugin @@ -409,107 +438,53 @@ org.gaul modernizer-maven-plugin - + + org.jacoco + jacoco-maven-plugin + + + org.sonarsource.scanner.maven + sonar-maven-plugin + - org.apache.maven.plugins - maven-checkstyle-plugin - ${maven-checkstyle-plugin.version} - - - com.puppycrawl.tools - checkstyle - ${checkstyle.version} - - - io.spring.nohttp - nohttp-checkstyle - ${nohttp-checkstyle.version} - - - - checkstyle.xml - pom.xml,README.md - .git/**/*,target/**/*,node_modules/**/*,node/**/* - ./ - + org.springframework.boot + spring-boot-maven-plugin - check + repackage - - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - ${java.version} - ${java.version} - - - org.springframework.boot - spring-boot-configuration-processor - ${spring-boot.version} - - - org.mapstruct - mapstruct-processor - ${mapstruct.version} - - - - org.hibernate - hibernate-jpamodelgen - ${hibernate.version} - - - org.glassfish.jaxb - jaxb-runtime - ${jaxb-runtime.version} - - - + ${start-class} + - org.apache.maven.plugins - maven-javadoc-plugin - ${maven-javadoc-plugin.version} + com.diffplug.spotless + spotless-maven-plugin + ${spotless-maven-plugin.version} - ${maven.compiler.source} + + + - - - org.apache.maven.plugins - maven-war-plugin - ${maven-war-plugin.version} - default-war + spotless + process-sources - war + apply - package - - WEB-INF/**,META-INF/** - false - target/classes/static/ - - - src/main/webapp - - WEB-INF/** - - - - com.github.eirslett @@ -517,101 +492,10 @@ ${frontend-maven-plugin.version} target + ${node.version} + ${yarn.version} - - org.codehaus.mojo - properties-maven-plugin - ${properties-maven-plugin.version} - - - initialize - - read-project-properties - - - - sonar-project.properties - - - - - - - - io.github.git-commit-id - git-commit-id-maven-plugin - ${git-commit-id-plugin.version} - - - - revision - - - - - false - false - true - - ^git.commit.id.abbrev$ - ^git.commit.id.describe$ - ^git.branch$ - - - - - org.gaul - modernizer-maven-plugin - ${modernizer-maven-plugin.version} - - - modernizer - package - - modernizer - - - - - ${java.version} - - - - org.jacoco - jacoco-maven-plugin - ${jacoco-maven-plugin.version} - - - pre-unit-tests - - prepare-agent - - - - - post-unit-test - test - - report - - - - pre-integration-tests - - prepare-agent-integration - - - - - post-integration-tests - post-integration-test - - report-integration - - - - com.google.cloud.tools jib-maven-plugin @@ -631,7 +515,7 @@ - oncokb/oncokb-transcript:latest + oncokb/oncokb-curation:latest @@ -644,7 +528,7 @@ ALWAYS - 0 + 0 USE_CURRENT_TIMESTAMP 1000 @@ -661,65 +545,99 @@ - org.liquibase - liquibase-maven-plugin - ${liquibase.version} + io.github.git-commit-id + git-commit-id-maven-plugin + ${git-commit-id-maven-plugin.version} + + + + revision + + + - ${project.basedir}/src/main/resources/config/liquibase/master.xml - ${project.basedir}/src/main/resources/config/liquibase/changelog/${maven.build.timestamp}_changelog.xml - com.mysql.cj.jdbc.Driver - jdbc:mysql://localhost:3306/oncokb-transcript - oncokb-transcript - root - root - hibernate:spring:org.mskcc.oncokb.transcript.domain?dialect=org.hibernate.dialect.MySQL8Dialect&hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy&hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy - true - debug - !test + false + false + true + + ^git.commit.id.abbrev$ + ^git.commit.id.describe$ + ^git.branch$ + + + + net.nicoulaj.maven.plugins + checksum-maven-plugin + ${checksum-maven-plugin.version} + + + org.apache.maven.plugins + maven-antrun-plugin + ${maven-antrun-plugin.version} + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${maven-checkstyle-plugin.version} - org.liquibase - liquibase-core - ${liquibase.version} - - - org.liquibase.ext - liquibase-hibernate5 - ${liquibase-hibernate5.version} - - - org.springframework.boot - spring-boot-starter-data-jpa - ${spring-boot.version} - - - javax.validation - validation-api - ${validation-api.version} + com.puppycrawl.tools + checkstyle + ${checkstyle.version} - org.javassist - javassist - ${javassist.version} + io.spring.nohttp + nohttp-checkstyle + ${nohttp-checkstyle.version} + + checkstyle.xml + pom.xml,README.md + .git/**/*,target/**/*,node_modules/**/* + ./ + + + + + check + + + + org.apache.maven.plugins maven-clean-plugin ${maven-clean-plugin.version} - - maven-site-plugin - ${maven-site-plugin.version} - org.apache.maven.plugins - maven-eclipse-plugin - ${maven-eclipse-plugin.version} + maven-compiler-plugin + ${maven-compiler-plugin.version} - true - true + ${java.version} + ${java.version} + true + + + org.springframework.boot + spring-boot-configuration-processor + + + org.mapstruct + mapstruct-processor + ${mapstruct.version} + + + org.hibernate.orm + hibernate-jpamodelgen + + + org.glassfish.jaxb + jaxb-runtime + + @@ -737,7 +655,7 @@ enforce-dependencyConvergence - + false @@ -753,37 +671,69 @@ [${maven.version},) - You are running an incompatible version of Java. JHipster supports JDK 17 to 11. - [11,17) + You are running an incompatible version of Java. JHipster supports JDK 17 to 21. + [17,18),[18,19),[19,20),[20,21),[21,22) org.apache.maven.plugins - maven-idea-plugin - ${maven-idea-plugin.version} + maven-failsafe-plugin + ${maven-failsafe-plugin.version} - node_modules + + + ${project.build.outputDirectory} + alphabetical + + **/*IT* + **/*IntTest* + + @{argLine} -Dspring.profiles.active=${profile.test} - - - org.apache.maven.plugins - maven-resources-plugin - ${maven-resources-plugin.version} - default-resources - validate + integration-test - copy-resources + integration-test + + + + verify + + verify + + + + + + org.apache.maven.plugins + maven-jar-plugin + ${maven-jar-plugin.version} + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven-javadoc-plugin.version} + + ${maven.compiler.source} + + + + org.apache.maven.plugins + maven-resources-plugin + ${maven-resources-plugin.version} + + + config-resources + validate + + copy-resources ${project.build.directory}/classes - false - - # - src/main/resources/ @@ -792,18 +742,16 @@ config/*.yml - - src/main/resources/ - false - - config/*.yml - - + + org.apache.maven.plugins + maven-site-plugin + ${maven-site-plugin.version} + org.apache.maven.plugins maven-surefire-plugin @@ -815,69 +763,270 @@ **/*IT* **/*IntTest* + + src/test/resources/logback.xml + org.apache.maven.plugins - maven-failsafe-plugin - ${maven-failsafe-plugin.version} - - - ${project.build.outputDirectory} - - alphabetical - - **/*IT* - **/*IntTest* - - + maven-war-plugin + ${maven-war-plugin.version} - integration-test + default-war - integration-test + war + package + + + WEB-INF/**,META-INF/** + false + target/classes/static/ + + + src/main/webapp + + WEB-INF/** + + + + + + + org.codehaus.mojo + properties-maven-plugin + ${properties-maven-plugin.version} + - verify + initialize - verify + read-project-properties + + + sonar-project.properties + + - org.sonarsource.scanner.maven - sonar-maven-plugin - ${sonar-maven-plugin.version} + org.gaul + modernizer-maven-plugin + ${modernizer-maven-plugin.version} + + + modernizer + package + + modernizer + + + + + ${java.version} + - org.springframework.boot - spring-boot-maven-plugin - ${spring-boot.version} + org.jacoco + jacoco-maven-plugin + ${jacoco-maven-plugin.version} + pre-unit-tests - repackage + prepare-agent + + + + + post-unit-test + test + + report + + + + pre-integration-tests + + prepare-agent-integration + + + + + post-integration-tests + post-integration-test + + report-integration + + + org.liquibase + liquibase-maven-plugin + ${liquibase.version} - ${start-class} - true - + config/liquibase/master.xml + ${project.basedir}/src/main/resources/config/liquibase/changelog/${maven.build.timestamp}_changelog.xml + com.mysql.cj.jdbc.Driver + ${liquibase-plugin.url} + + ${liquibase-plugin.username} + ${liquibase-plugin.password} + hibernate:spring:org.mskcc.oncokb.curation.domain?dialect=org.hibernate.dialect.MySQL8Dialect&hibernate.physical_naming_strategy=org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy&hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy + true + debug + !test + oauth_access_token, oauth_approvals, oauth_client_details, oauth_client_token, oauth_code, oauth_refresh_token - + + + org.liquibase + liquibase-core + ${liquibase.version} + + + org.liquibase.ext + liquibase-hibernate6 + ${liquibase.version} + + + jakarta.validation + jakarta.validation-api + ${jakarta-validation.version} + + + org.springframework.boot + spring-boot-starter-data-jpa + ${spring-boot.version} + + + + + org.sonarsource.scanner.maven + sonar-maven-plugin + ${sonar-maven-plugin.version} - + + + api-docs + + ,api-docs + + + + dev + + true + + + + dev${profile.tls}${profile.no-liquibase} + testdev + jdbc:mysql://localhost:3306/oncokb-curation + root + root + + + + org.springframework.boot + spring-boot-devtools + true + + + + + + eclipse + + + m2e.version + + + + + + org.springframework.boot + spring-boot-starter-undertow + + + + + + + + org.eclipse.m2e + lifecycle-mapping + ${lifecycle-mapping.version} + + + + + + org.jacoco + jacoco-maven-plugin + ${jacoco-maven-plugin.version} + + prepare-agent + + + + + + + + + com.github.eirslett + frontend-maven-plugin + ${frontend-maven-plugin.version} + + install-node-and-yarn + yarn + + + + + + + + + + + + + + + + + IDE + + + org.mapstruct + mapstruct-processor + ${mapstruct.version} + + + org.hibernate.orm + hibernate-jpamodelgen + + + no-liquibase @@ -885,10 +1034,92 @@ - api-docs + prod - ,api-docs + + prod${profile.api-docs}${profile.tls}${profile.e2e}${profile.no-liquibase} + testprod + jdbc:mysql://localhost:3306/oncokb-curation + root + root + + + + org.apache.maven.plugins + maven-clean-plugin + + + + target/classes/static/ + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + build-info + + + + + + io.github.git-commit-id + git-commit-id-maven-plugin + + + com.github.eirslett + frontend-maven-plugin + + + install-node-and-yarn + + install-node-and-yarn + + + ${node.version} + ${yarn.version} + + + + yarn install + + yarn + + + + webapp build test + + yarn + + test + + run webapp:test + false + + + + webapp build prod + + yarn + + generate-resources + + run webapp:prod + + ${project.version} + + false + + + + + + tls @@ -896,19 +1127,31 @@ ,tls + + war + + + + org.apache.maven.plugins + maven-war-plugin + + + + webapp true - - + + + dev${profile.no-liquibase} + net.nicoulaj.maven.plugins checksum-maven-plugin - ${checksum-maven-plugin.version} create-pre-compiled-webapp-checksum @@ -937,9 +1180,9 @@ target/classes/static/**/*.* package-lock.json package.json - webpack/*.* tsconfig.json .postcss.config.js + webpack/*.* **/app/**/service-worker.js @@ -960,7 +1203,6 @@ org.apache.maven.plugins maven-antrun-plugin - ${maven-antrun-plugin.version} eval-frontend-checksum @@ -970,11 +1212,11 @@ - + - - - + + + @@ -988,25 +1230,25 @@ frontend-maven-plugin - install-node-and-npm + install-node-and-yarn - install-node-and-npm + install-node-and-yarn ${node.version} - ${npm.version} + ${yarn.version} - npm install + yarn install - npm + yarn webapp build dev - npm + yarn generate-resources @@ -1014,227 +1256,13 @@ ${project.version} - false - - - - - - - - - dev${profile.no-liquibase} - - - - dev - - true - - - - org.springframework.boot - spring-boot-starter-undertow - - - org.springframework.boot - spring-boot-devtools - true - - - - - dev${profile.tls}${profile.no-liquibase} - - - - prod - - - org.springframework.boot - spring-boot-starter-undertow - - - - - - maven-clean-plugin - - - - target/classes/static/ - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - build-info - - - - - - com.github.eirslett - frontend-maven-plugin - - - install-node-and-npm - - install-node-and-npm - - - ${node.version} - ${npm.version} - - - - npm install - - npm - - - - webapp build test - - npm - - test - - run webapp:test - false - - - - webapp build prod - - npm - - generate-resources - - run webapp:prod - - ${project.version} - - false + false - - io.github.git-commit-id - git-commit-id-maven-plugin - - - - - - prod${profile.api-docs}${profile.tls}${profile.no-liquibase} - - - - war - - - - org.apache.maven.plugins - maven-war-plugin - - - - IDE - - - org.mapstruct - mapstruct-processor - ${mapstruct.version} - - - org.hibernate - hibernate-jpamodelgen - - - - - - eclipse - - - m2e.version - - - - - - org.springframework.boot - spring-boot-starter-undertow - - - - - - - - org.eclipse.m2e - lifecycle-mapping - ${lifecycle-mapping.version} - - - - - - org.jacoco - - jacoco-maven-plugin - - - ${jacoco-maven-plugin.version} - - - prepare-agent - - - - - - - - - com.github.eirslett - frontend-maven-plugin - ${frontend-maven-plugin.version} - - install-node-and-npm - npm - - - - - - - - - - - - - - - diff --git a/sonar-project.properties b/sonar-project.properties index ff39fec7a..6e49acc18 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,5 +1,5 @@ -sonar.projectKey=oncokb-transcript -sonar.projectName=oncokb-transcript generated by jhipster +sonar.projectKey=oncokb-curation +sonar.projectName=oncokb-curation generated by jhipster sonar.projectVersion=1.0 sonar.sources=src/main/ @@ -15,16 +15,13 @@ sonar.javascript.lcov.reportPaths=target/test-results/lcov.info sonar.sourceEncoding=UTF-8 sonar.exclusions=src/main/webapp/content/**/*.*, src/main/webapp/i18n/*.js, target/classes/static/**/*.* -sonar.issue.ignore.multicriteria=S3437,S4502,S4684,UndocumentedApi +sonar.issue.ignore.multicriteria=S3437,S4684,UndocumentedApi # Rule https://rules.sonarsource.com/java/RSPEC-3437 is ignored, as a JPA-managed field cannot be transient sonar.issue.ignore.multicriteria.S3437.resourceKey=src/main/java/**/* sonar.issue.ignore.multicriteria.S3437.ruleKey=squid:S3437 # Rule https://rules.sonarsource.com/java/RSPEC-1176 is ignored, as we want to follow "clean code" guidelines and classes, methods and arguments names should be self-explanatory sonar.issue.ignore.multicriteria.UndocumentedApi.resourceKey=src/main/java/**/* sonar.issue.ignore.multicriteria.UndocumentedApi.ruleKey=squid:UndocumentedApi -# Rule https://rules.sonarsource.com/java/RSPEC-4502 is ignored, as for JWT tokens we are not subject to CSRF attack -sonar.issue.ignore.multicriteria.S4502.resourceKey=src/main/java/**/* -sonar.issue.ignore.multicriteria.S4502.ruleKey=squid:S4502 # Rule https://rules.sonarsource.com/java/RSPEC-4684 sonar.issue.ignore.multicriteria.S4684.resourceKey=src/main/java/**/* sonar.issue.ignore.multicriteria.S4684.ruleKey=java:S4684 diff --git a/src/main/docker/app.yml b/src/main/docker/app.yml index 87b18c931..7323f4f3e 100644 --- a/src/main/docker/app.yml +++ b/src/main/docker/app.yml @@ -1,38 +1,64 @@ # This configuration is intended for development purpose, it's **your** responsibility to harden it for production version: '3.8' services: - oncokb-transcript-app: - image: oncokb-transcript + oncokb-curation-app: + image: oncokb-curation environment: - _JAVA_OPTIONS=-Xmx512m -Xms256m - SPRING_PROFILES_ACTIVE=prod,api-docs - MANAGEMENT_METRICS_EXPORT_PROMETHEUS_ENABLED=true - - SPRING_DATASOURCE_URL=jdbc:mysql://oncokb-transcript-mysql:3306/oncokb-transcript?useUnicode=true&characterEncoding=utf8&useSSL=false&useLegacyDatetimeCode=false&serverTimezone=UTC&createDatabaseIfNotExist=true - - SPRING_LIQUIBASE_URL=jdbc:mysql://oncokb-transcript-mysql:3306/oncokb-transcript?useUnicode=true&characterEncoding=utf8&useSSL=false&useLegacyDatetimeCode=false&serverTimezone=UTC&createDatabaseIfNotExist=true - - JHIPSTER_CACHE_REDIS_SERVER=redis://oncokb-transcript-redis:6379 + - SPRING_DATASOURCE_URL=jdbc:mysql://oncokb-curation-mysql:3306/oncokb-curation?useUnicode=true&characterEncoding=utf8&useSSL=false&useLegacyDatetimeCode=false&serverTimezone=UTC&createDatabaseIfNotExist=true + - SPRING_LIQUIBASE_URL=jdbc:mysql://oncokb-curation-mysql:3306/oncokb-curation?useUnicode=true&characterEncoding=utf8&useSSL=false&useLegacyDatetimeCode=false&serverTimezone=UTC&createDatabaseIfNotExist=true + - JHIPSTER_CACHE_REDIS_SERVER=redis://oncokb-curation-redis:6379 - JHIPSTER_CACHE_REDIS_CLUSTER=false - # - JHIPSTER_CACHE_REDIS_SERVER=redis://oncokb-transcript-redis:6379 + # - JHIPSTER_CACHE_REDIS_SERVER=redis://oncokb-curation-redis:6379 # - JHIPSTER_CACHE_REDIS_CLUSTER=true - - JHIPSTER_SLEEP=30 # gives time for other services to boot before the application + - SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_OIDC_ISSUER_URI=http://keycloak:8080/auth/realms/oncokb-curation + - SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_OIDC_CLIENT_ID=web_app + - SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_OIDC_CLIENT_SECRET=web_app + - ONCOKB_SLEEP=30 # gives time for other services to boot before the application # If you want to expose these ports outside your dev PC, # remove the "127.0.0.1:" prefix ports: - 127.0.0.1:9090:9090 - oncokb-transcript-mysql: + oncokb-curation-mysql: image: mysql:8.0.26 - # volumes: - # - ~/volumes/jhipster/oncokb-transcript/mysql/:/var/lib/mysql/ environment: - MYSQL_ALLOW_EMPTY_PASSWORD=yes - - MYSQL_DATABASE=oncokb-transcript + - MYSQL_DATABASE=oncokb-curation # If you want to expose these ports outside your dev PC, # remove the "127.0.0.1:" prefix ports: - 127.0.0.1:3306:3306 command: mysqld --lower_case_table_names=1 --skip-ssl --character_set_server=utf8mb4 --explicit_defaults_for_timestamp - oncokb-transcript-redis: + oncokb-curation-redis: image: redis:6.2.5 # If you want to expose these ports outside your dev PC, # remove the "127.0.0.1:" prefix ports: - 127.0.0.1:6379:6379 + keycloak: + image: jboss/keycloak:14.0.0 + command: + [ + '-b', + '0.0.0.0', + '-Dkeycloak.migration.action=import', + '-Dkeycloak.migration.provider=dir', + '-Dkeycloak.migration.dir=/opt/jboss/keycloak/realm-config', + '-Dkeycloak.migration.strategy=OVERWRITE_EXISTING', + '-Djboss.socket.binding.port-offset=1000', + '-Dkeycloak.profile.feature.upload_scripts=enabled', + ] + volumes: + - ./realm-config:/opt/jboss/keycloak/realm-config + environment: + - KEYCLOAK_USER=admin + - KEYCLOAK_PASSWORD=admin + - DB_VENDOR=h2 + # If you want to expose these ports outside your dev PC, + # remove the "127.0.0.1:" prefix + ports: + - 127.0.0.1:8080:8080 + - 127.0.0.1:9443:9443 + - 127.0.0.1:10990:10990 diff --git a/src/main/docker/jhipster-control-center.yml b/src/main/docker/jhipster-control-center.yml deleted file mode 100644 index a275dab5b..000000000 --- a/src/main/docker/jhipster-control-center.yml +++ /dev/null @@ -1,52 +0,0 @@ -## How to use JHCC docker compose -# To allow JHCC to reach JHipster application from a docker container note that we set the host as host.docker.internal -# To reach the application from a browser, you need to add '127.0.0.1 host.docker.internal' to your hosts file. -### Discovery mode -# JHCC support 3 kinds of discovery mode: Consul, Eureka and static -# In order to use one, please set SPRING_PROFILES_ACTIVE to one (and only one) of this values: consul,eureka,static -### Discovery properties -# According to the discovery mode choose as Spring profile, you have to set the right properties -# please note that current properties are set to run JHCC with default values, personalize them if needed -# and remove those from other modes. You can only have one mode active. -#### Eureka -# - EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE=http://admin:admin@host.docker.internal:8761/eureka/ -#### Consul -# - SPRING_CLOUD_CONSUL_HOST=host.docker.internal -# - SPRING_CLOUD_CONSUL_PORT=8500 -#### Static -# Add instances to "MyApp" -# - SPRING_CLOUD_DISCOVERY_CLIENT_SIMPLE_INSTANCES_MYAPP_0_URI=http://host.docker.internal:8081 -# - SPRING_CLOUD_DISCOVERY_CLIENT_SIMPLE_INSTANCES_MYAPP_1_URI=http://host.docker.internal:8082 -# Or add a new application named MyNewApp -# - SPRING_CLOUD_DISCOVERY_CLIENT_SIMPLE_INSTANCES_MYNEWAPP_0_URI=http://host.docker.internal:8080 -# This configuration is intended for development purpose, it's **your** responsibility to harden it for production - -#### IMPORTANT -# If you choose Consul or Eureka mode: -# Do not forget to remove the prefix "127.0.0.1" in front of their port in order to expose them. -# This is required because JHCC need to communicate with Consul or Eureka. -# - In Consul mode, the ports are in the consul.yml file. -# - In Eureka mode, the ports are in the jhipster-registry.yml file. - -version: '3.8' -services: - jhipster-control-center: - image: 'jhipster/jhipster-control-center:v0.5.0' - command: - - /bin/sh - - -c - # Patch /etc/hosts to support resolving host.docker.internal to the internal IP address used by the host in all OSes - - echo "`ip route | grep default | cut -d ' ' -f3` host.docker.internal" | tee -a /etc/hosts > /dev/null && java -jar /jhipster-control-center.jar - environment: - - _JAVA_OPTIONS=-Xmx512m -Xms256m - - SPRING_PROFILES_ACTIVE=prod,api-docs,static - - JHIPSTER_SLEEP=30 # gives time for other services to boot before the application - - SPRING_SECURITY_USER_PASSWORD=admin - # The token should have the same value than the one declared in you Spring configuration under the jhipster.security.authentication.jwt.base64-secret configuration's entry - - JHIPSTER_SECURITY_AUTHENTICATION_JWT_BASE64_SECRET=NGUwNTlhNDNhOWQ2ZGJlMmEzODczOWJjYWM2MWY4NDAwOTM4YTBmNGFjM2UxNjczZDU2YWZjZjc3MjdkNmU4YjVhZmIwYzI1NDhjMDFkZThiYmE5Mjc5MjM0MGVhODU5MGFhMTAyOTE0M2I3ODA1MGUzZWFhYWUwNWY2ZDgyNjQ= - - SPRING_CLOUD_DISCOVERY_CLIENT_SIMPLE_INSTANCES_ONCOKB-TRANSCRIPT_0_URI=http://host.docker.internal:9090 - - LOGGING_FILE_NAME=/tmp/jhipster-control-center.log - # If you want to expose these ports outside your dev PC, - # remove the "127.0.0.1:" prefix - ports: - - 127.0.0.1:7419:7419 diff --git a/src/main/docker/jib/entrypoint.sh b/src/main/docker/jib/entrypoint.sh index 083b29c58..141e465c6 100644 --- a/src/main/docker/jib/entrypoint.sh +++ b/src/main/docker/jib/entrypoint.sh @@ -1,4 +1,4 @@ #!/bin/sh -echo "The application will start in ${JHIPSTER_SLEEP}s..." && sleep ${JHIPSTER_SLEEP} -exec java ${JAVA_OPTS} -noverify -XX:+AlwaysPreTouch -Djava.security.egd=file:/dev/./urandom -cp /app/resources/:/app/classes/:/app/libs/* "org.mskcc.oncokb.transcript.OncokbTranscriptApp" "$@" +echo "The application will start in ${ONCOKB_SLEEP}s..." && sleep ${ONCOKB_SLEEP} +exec java ${JAVA_OPTS} -noverify -XX:+AlwaysPreTouch -Djava.security.egd=file:/dev/./urandom -cp /app/resources/:/app/classes/:/app/libs/* "org.mskcc.oncokb.curation.OncokbCurationApp" "$@" diff --git a/src/main/docker/keycloak.yml b/src/main/docker/keycloak.yml new file mode 100644 index 000000000..878560692 --- /dev/null +++ b/src/main/docker/keycloak.yml @@ -0,0 +1,41 @@ +# This configuration is intended for development purpose, it's **your** responsibility to harden it for production +version: '3.8' +services: + keycloak-db: + image: postgres + restart: unless-stopped + environment: + POSTGRES_DB: keycloak + POSTGRES_USER: root + POSTGRES_PASSWORD: root + volumes: + - kc-db:/var/lib/mysql + networks: + - kc-network + keycloak: + image: quay.io/keycloak/keycloak:17.0.1 + command: start-dev + #volumes: + #- ./realm-config:/opt/bitnami/keycloak/data/import + environment: + KEYCLOAK_ADMIN: admin + KEYCLOAK_ADMIN_PASSWORD: admin + KC_DB: postgres + KC_DB_URL_HOST: keycloak-db + KC_DB_URL_PORT: 5432 + KC_DB_URL_DATABASE: keycloak + KC_DB_USERNAME: root + KC_DB_PASSWORD: root + #KEYCLOAK_EXTRA_ARGS_PREPENDED: --import-realm + #KEYCLOAK_BIND_ADDRESS: keycloak-db + depends_on: + - keycloak-db + networks: + - kc-network + + ports: + - 8080:8080 +volumes: + kc-db: +networks: + kc-network: diff --git a/src/main/docker/monitoring.yml b/src/main/docker/monitoring.yml index 4d99bde2e..0ba9e7285 100644 --- a/src/main/docker/monitoring.yml +++ b/src/main/docker/monitoring.yml @@ -1,7 +1,7 @@ # This configuration is intended for development purpose, it's **your** responsibility to harden it for production version: '3.8' services: - oncokb-transcript-prometheus: + oncokb-curation-prometheus: image: prom/prometheus:v2.29.2 volumes: - ./prometheus/:/etc/prometheus/ @@ -14,7 +14,7 @@ services: # On MacOS, remove next line and replace localhost by host.docker.internal in prometheus/prometheus.yml and # grafana/provisioning/datasources/datasource.yml network_mode: 'host' # to test locally running service - oncokb-transcript-grafana: + oncokb-curation-grafana: image: grafana/grafana:8.1.3 volumes: - ./grafana/provisioning/:/etc/grafana/provisioning/ diff --git a/src/main/docker/mysql.yml b/src/main/docker/mysql.yml index cdafb2974..bc8aacca9 100644 --- a/src/main/docker/mysql.yml +++ b/src/main/docker/mysql.yml @@ -1,13 +1,11 @@ # This configuration is intended for development purpose, it's **your** responsibility to harden it for production version: '3.8' services: - oncokb-transcript-mysql: + oncokb-curation-mysql: image: mysql:8.0.26 - # volumes: - # - ~/volumes/jhipster/oncokb-transcript/mysql/:/var/lib/mysql/ environment: - MYSQL_ALLOW_EMPTY_PASSWORD=yes - - MYSQL_DATABASE=oncokb-transcript + - MYSQL_DATABASE=oncokb-curation # If you want to expose these ports outside your dev PC, # remove the "127.0.0.1:" prefix ports: diff --git a/src/main/docker/prometheus/prometheus.yml b/src/main/docker/prometheus/prometheus.yml index bfccaab83..ad50b562f 100644 --- a/src/main/docker/prometheus/prometheus.yml +++ b/src/main/docker/prometheus/prometheus.yml @@ -1,4 +1,4 @@ -# Sample global config for monitoring JHipster applications +# Sample global config for monitoring application global: scrape_interval: 15s # By default, scrape targets every 15 seconds. evaluation_interval: 15s # By default, scrape targets every 15 seconds. @@ -7,7 +7,7 @@ global: # Attach these labels to any time series or alerts when communicating with # external systems (federation, remote storage, Alertmanager). external_labels: - monitor: 'jhipster' + monitor: 'oncokb' # A scrape configuration containing exactly one endpoint to scrape: # Here it's Prometheus itself. diff --git a/src/main/docker/realm-config/oncokb-curation-realm.json b/src/main/docker/realm-config/oncokb-curation-realm.json new file mode 100644 index 000000000..7f1012cec --- /dev/null +++ b/src/main/docker/realm-config/oncokb-curation-realm.json @@ -0,0 +1,2181 @@ +{ + "id": "oncokb-curation", + "realm": "oncokb-curation", + "notBefore": 0, + "defaultSignatureAlgorithm": "RS256", + "revokeRefreshToken": false, + "refreshTokenMaxReuse": 0, + "accessTokenLifespan": 300, + "accessTokenLifespanForImplicitFlow": 900, + "ssoSessionIdleTimeout": 1800, + "ssoSessionMaxLifespan": 36000, + "ssoSessionIdleTimeoutRememberMe": 0, + "ssoSessionMaxLifespanRememberMe": 0, + "offlineSessionIdleTimeout": 2592000, + "offlineSessionMaxLifespanEnabled": false, + "offlineSessionMaxLifespan": 5184000, + "clientSessionIdleTimeout": 0, + "clientSessionMaxLifespan": 0, + "clientOfflineSessionIdleTimeout": 0, + "clientOfflineSessionMaxLifespan": 0, + "accessCodeLifespan": 60, + "accessCodeLifespanUserAction": 300, + "accessCodeLifespanLogin": 1800, + "actionTokenGeneratedByAdminLifespan": 43200, + "actionTokenGeneratedByUserLifespan": 300, + "oauth2DeviceCodeLifespan": 600, + "oauth2DevicePollingInterval": 5, + "enabled": true, + "sslRequired": "external", + "registrationAllowed": false, + "registrationEmailAsUsername": false, + "rememberMe": false, + "verifyEmail": false, + "loginWithEmailAllowed": true, + "duplicateEmailsAllowed": false, + "resetPasswordAllowed": false, + "editUsernameAllowed": false, + "bruteForceProtected": false, + "permanentLockout": false, + "maxFailureWaitSeconds": 900, + "minimumQuickLoginWaitSeconds": 60, + "waitIncrementSeconds": 60, + "quickLoginCheckMilliSeconds": 1000, + "maxDeltaTimeSeconds": 43200, + "failureFactor": 30, + "roles": { + "realm": [ + { + "id": "e1b19afd-f612-4a79-bdf8-26a99b89b10b", + "name": "offline_access", + "description": "${role_offline-access}", + "composite": false, + "clientRole": false, + "containerId": "oncokb-curation", + "attributes": {} + }, + { + "id": "2eec61d0-9581-4dbf-8c7b-f32dc5fac3ce", + "name": "uma_authorization", + "description": "${role_uma_authorization}", + "composite": false, + "clientRole": false, + "containerId": "oncokb-curation", + "attributes": {} + } + ], + "client": { + "internal": [], + "realm-management": [ + { + "id": "a6249a12-d76c-4514-b137-e3018b243e25", + "name": "manage-authorization", + "description": "${role_manage-authorization}", + "composite": false, + "clientRole": true, + "containerId": "898488c8-e260-41c5-a463-7ceea14d587a", + "attributes": {} + }, + { + "id": "a28bc401-c5ad-4fab-aef4-42629988c10b", + "name": "view-realm", + "description": "${role_view-realm}", + "composite": false, + "clientRole": true, + "containerId": "898488c8-e260-41c5-a463-7ceea14d587a", + "attributes": {} + }, + { + "id": "464bca1f-136f-45de-a7fc-b976a185ce7e", + "name": "view-users", + "description": "${role_view-users}", + "composite": true, + "composites": { + "client": { + "realm-management": ["query-users", "query-groups"] + } + }, + "clientRole": true, + "containerId": "898488c8-e260-41c5-a463-7ceea14d587a", + "attributes": {} + }, + { + "id": "98c2fa77-d3c8-4f68-b9f4-b79f87efd4a9", + "name": "query-users", + "description": "${role_query-users}", + "composite": false, + "clientRole": true, + "containerId": "898488c8-e260-41c5-a463-7ceea14d587a", + "attributes": {} + }, + { + "id": "3c6b9cfe-80c4-41d5-a5ac-0cadebacfc8d", + "name": "manage-identity-providers", + "description": "${role_manage-identity-providers}", + "composite": false, + "clientRole": true, + "containerId": "898488c8-e260-41c5-a463-7ceea14d587a", + "attributes": {} + }, + { + "id": "6b82bfdb-c8de-4274-95b4-a683eb4ead50", + "name": "view-identity-providers", + "description": "${role_view-identity-providers}", + "composite": false, + "clientRole": true, + "containerId": "898488c8-e260-41c5-a463-7ceea14d587a", + "attributes": {} + }, + { + "id": "b71fe952-bb06-4e4a-91ef-2d2714f770e1", + "name": "impersonation", + "description": "${role_impersonation}", + "composite": false, + "clientRole": true, + "containerId": "898488c8-e260-41c5-a463-7ceea14d587a", + "attributes": {} + }, + { + "id": "23676fb8-235a-4e54-a0d0-9bed1ccbe2f8", + "name": "query-groups", + "description": "${role_query-groups}", + "composite": false, + "clientRole": true, + "containerId": "898488c8-e260-41c5-a463-7ceea14d587a", + "attributes": {} + }, + { + "id": "0813cbd0-c73d-469d-a54d-84a865c302af", + "name": "manage-events", + "description": "${role_manage-events}", + "composite": false, + "clientRole": true, + "containerId": "898488c8-e260-41c5-a463-7ceea14d587a", + "attributes": {} + }, + { + "id": "2e1bc884-e9d3-45d2-909c-2777a78ca8ae", + "name": "manage-realm", + "description": "${role_manage-realm}", + "composite": false, + "clientRole": true, + "containerId": "898488c8-e260-41c5-a463-7ceea14d587a", + "attributes": {} + }, + { + "id": "0a05451e-7d64-4e87-b585-f1143ce5752e", + "name": "query-clients", + "description": "${role_query-clients}", + "composite": false, + "clientRole": true, + "containerId": "898488c8-e260-41c5-a463-7ceea14d587a", + "attributes": {} + }, + { + "id": "c7a4f4c1-9089-458c-a765-f6d22ea94690", + "name": "view-authorization", + "description": "${role_view-authorization}", + "composite": false, + "clientRole": true, + "containerId": "898488c8-e260-41c5-a463-7ceea14d587a", + "attributes": {} + }, + { + "id": "dfad4d08-6d75-42b6-8699-4886e47bc464", + "name": "view-events", + "description": "${role_view-events}", + "composite": false, + "clientRole": true, + "containerId": "898488c8-e260-41c5-a463-7ceea14d587a", + "attributes": {} + }, + { + "id": "392ed0a3-f6ad-48a1-b201-648037d2b4bd", + "name": "realm-admin", + "description": "${role_realm-admin}", + "composite": true, + "composites": { + "client": { + "realm-management": [ + "manage-authorization", + "view-realm", + "view-users", + "query-users", + "manage-identity-providers", + "view-identity-providers", + "query-groups", + "impersonation", + "manage-events", + "query-clients", + "manage-realm", + "view-authorization", + "view-events", + "view-clients", + "create-client", + "manage-clients", + "manage-users", + "query-realms" + ] + } + }, + "clientRole": true, + "containerId": "898488c8-e260-41c5-a463-7ceea14d587a", + "attributes": {} + }, + { + "id": "d7efdf61-affb-42a1-bcb0-b2c30d87a39e", + "name": "view-clients", + "description": "${role_view-clients}", + "composite": true, + "composites": { + "client": { + "realm-management": ["query-clients"] + } + }, + "clientRole": true, + "containerId": "898488c8-e260-41c5-a463-7ceea14d587a", + "attributes": {} + }, + { + "id": "14da8e56-5c8b-4764-96da-250449a32fd4", + "name": "create-client", + "description": "${role_create-client}", + "composite": false, + "clientRole": true, + "containerId": "898488c8-e260-41c5-a463-7ceea14d587a", + "attributes": {} + }, + { + "id": "88e6a9f5-259c-487d-af35-2a98da066816", + "name": "manage-clients", + "description": "${role_manage-clients}", + "composite": false, + "clientRole": true, + "containerId": "898488c8-e260-41c5-a463-7ceea14d587a", + "attributes": {} + }, + { + "id": "932273a7-c02b-43db-81c5-96a0dc45e454", + "name": "manage-users", + "description": "${role_manage-users}", + "composite": false, + "clientRole": true, + "containerId": "898488c8-e260-41c5-a463-7ceea14d587a", + "attributes": {} + }, + { + "id": "e3edf335-cec5-4012-a00d-fcac045052e1", + "name": "query-realms", + "description": "${role_query-realms}", + "composite": false, + "clientRole": true, + "containerId": "898488c8-e260-41c5-a463-7ceea14d587a", + "attributes": {} + } + ], + "security-admin-console": [], + "web_app": [], + "admin-cli": [], + "account-console": [], + "broker": [ + { + "id": "5b08a930-9f1d-4030-ae75-92c1e4c9352c", + "name": "read-token", + "description": "${role_read-token}", + "composite": false, + "clientRole": true, + "containerId": "88e1225b-f0b9-46ba-8efd-f2c10ce23058", + "attributes": {} + } + ], + "account": [ + { + "id": "a88c56b8-6bc9-418a-92bc-7a17e7707f60", + "name": "view-profile", + "description": "${role_view-profile}", + "composite": false, + "clientRole": true, + "containerId": "6cc5a716-0880-47dc-b714-9a4967246b2f", + "attributes": {} + }, + { + "id": "0cb954ab-987f-482a-b2d7-0d481ba1d532", + "name": "view-applications", + "description": "${role_view-applications}", + "composite": false, + "clientRole": true, + "containerId": "6cc5a716-0880-47dc-b714-9a4967246b2f", + "attributes": {} + }, + { + "id": "6450156d-7526-48f2-8ea0-bb1e51f9eefa", + "name": "manage-account", + "description": "${role_manage-account}", + "composite": true, + "composites": { + "client": { + "account": ["manage-account-links"] + } + }, + "clientRole": true, + "containerId": "6cc5a716-0880-47dc-b714-9a4967246b2f", + "attributes": {} + }, + { + "id": "35537940-67a6-4217-881b-1ff98109b374", + "name": "manage-consent", + "description": "${role_manage-consent}", + "composite": true, + "composites": { + "client": { + "account": ["view-consent"] + } + }, + "clientRole": true, + "containerId": "6cc5a716-0880-47dc-b714-9a4967246b2f", + "attributes": {} + }, + { + "id": "e5b2ba76-4c36-4ba1-b210-89a1ac3c6bbe", + "name": "view-consent", + "description": "${role_view-consent}", + "composite": false, + "clientRole": true, + "containerId": "6cc5a716-0880-47dc-b714-9a4967246b2f", + "attributes": {} + }, + { + "id": "5ebf404b-7805-4da2-abb4-9db7d3b36120", + "name": "delete-account", + "description": "${role_delete-account}", + "composite": false, + "clientRole": true, + "containerId": "6cc5a716-0880-47dc-b714-9a4967246b2f", + "attributes": {} + }, + { + "id": "a7f45fab-19c3-4c48-aca3-85f828ca0fed", + "name": "manage-account-links", + "description": "${role_manage-account-links}", + "composite": false, + "clientRole": true, + "containerId": "6cc5a716-0880-47dc-b714-9a4967246b2f", + "attributes": {} + } + ] + } + }, + "groups": [], + "requiredCredentials": ["password"], + "otpPolicyType": "totp", + "otpPolicyAlgorithm": "HmacSHA1", + "otpPolicyInitialCounter": 0, + "otpPolicyDigits": 6, + "otpPolicyLookAheadWindow": 1, + "otpPolicyPeriod": 30, + "otpSupportedApplications": ["FreeOTP", "Google Authenticator"], + "webAuthnPolicyRpEntityName": "keycloak", + "webAuthnPolicySignatureAlgorithms": ["ES256"], + "webAuthnPolicyRpId": "", + "webAuthnPolicyAttestationConveyancePreference": "not specified", + "webAuthnPolicyAuthenticatorAttachment": "not specified", + "webAuthnPolicyRequireResidentKey": "not specified", + "webAuthnPolicyUserVerificationRequirement": "not specified", + "webAuthnPolicyCreateTimeout": 0, + "webAuthnPolicyAvoidSameAuthenticatorRegister": false, + "webAuthnPolicyAcceptableAaguids": [], + "webAuthnPolicyPasswordlessRpEntityName": "keycloak", + "webAuthnPolicyPasswordlessSignatureAlgorithms": ["ES256"], + "webAuthnPolicyPasswordlessRpId": "", + "webAuthnPolicyPasswordlessAttestationConveyancePreference": "not specified", + "webAuthnPolicyPasswordlessAuthenticatorAttachment": "not specified", + "webAuthnPolicyPasswordlessRequireResidentKey": "not specified", + "webAuthnPolicyPasswordlessUserVerificationRequirement": "not specified", + "webAuthnPolicyPasswordlessCreateTimeout": 0, + "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister": false, + "webAuthnPolicyPasswordlessAcceptableAaguids": [], + "users": [ + { + "id": "f742ba6f-1d8a-4dec-bf15-e02dab508283", + "createdTimestamp": 1598681172054, + "username": "service-account-internal", + "enabled": true, + "totp": false, + "emailVerified": false, + "serviceAccountClientId": "internal", + "disableableCredentialTypes": [], + "requiredActions": [], + "realmRoles": ["offline_access", "uma_authorization"], + "clientRoles": { + "account": ["view-profile", "manage-account"] + }, + "notBefore": 0, + "groups": [] + } + ], + "scopeMappings": [ + { + "clientScope": "offline_access", + "roles": ["offline_access"] + } + ], + "clientScopeMappings": { + "account": [ + { + "client": "account-console", + "roles": ["manage-account"] + } + ] + }, + "clients": [ + { + "id": "6cc5a716-0880-47dc-b714-9a4967246b2f", + "clientId": "account", + "name": "${client_account}", + "rootUrl": "${authBaseUrl}", + "baseUrl": "/realms/oncokb-curation/account/", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "secret": "**********", + "redirectUris": ["/realms/oncokb-curation/account/*"], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": false, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": {}, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "defaultClientScopes": ["web-origins", "roles", "profile", "email"], + "optionalClientScopes": ["address", "phone", "offline_access", "microprofile-jwt"] + }, + { + "id": "fb0a4870-06db-4f9d-9d44-baf51a00cc34", + "clientId": "account-console", + "name": "${client_account-console}", + "rootUrl": "${authBaseUrl}", + "baseUrl": "/realms/oncokb-curation/account/", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "secret": "**********", + "redirectUris": ["/realms/oncokb-curation/account/*"], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": true, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": { + "pkce.code.challenge.method": "S256" + }, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "protocolMappers": [ + { + "id": "c5c4ebe5-d009-4f96-b143-1b36d770eafb", + "name": "audience resolve", + "protocol": "openid-connect", + "protocolMapper": "oidc-audience-resolve-mapper", + "consentRequired": false, + "config": {} + } + ], + "defaultClientScopes": ["web-origins", "roles", "profile", "email"], + "optionalClientScopes": ["address", "phone", "offline_access", "microprofile-jwt"] + }, + { + "id": "bb166356-838d-445e-94e3-9330ad7ab51b", + "clientId": "admin-cli", + "name": "${client_admin-cli}", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "secret": "**********", + "redirectUris": [], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": false, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": true, + "serviceAccountsEnabled": false, + "publicClient": true, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": {}, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "defaultClientScopes": ["web-origins", "roles", "profile", "email"], + "optionalClientScopes": ["address", "phone", "offline_access", "microprofile-jwt"] + }, + { + "id": "88e1225b-f0b9-46ba-8efd-f2c10ce23058", + "clientId": "broker", + "name": "${client_broker}", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "secret": "**********", + "redirectUris": [], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": false, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": {}, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "defaultClientScopes": ["web-origins", "roles", "profile", "email"], + "optionalClientScopes": ["address", "phone", "offline_access", "microprofile-jwt"] + }, + { + "id": "10e6ea34-9f1e-49ef-8e28-7eb851459694", + "clientId": "internal", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "secret": "**********", + "redirectUris": [], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": false, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": true, + "publicClient": false, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": { + "saml.assertion.signature": "false", + "saml.force.post.binding": "false", + "saml.multivalued.roles": "false", + "saml.encrypt": "false", + "saml.server.signature": "false", + "saml.server.signature.keyinfo.ext": "false", + "exclude.session.state.from.auth.response": "false", + "saml_force_name_id_format": "false", + "saml.client.signature": "false", + "tls.client.certificate.bound.access.tokens": "false", + "saml.authnstatement": "false", + "display.on.consent.screen": "false", + "saml.onetimeuse.condition": "false" + }, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": true, + "nodeReRegistrationTimeout": -1, + "protocolMappers": [ + { + "id": "ff2f50b4-5409-4789-bdda-fe731f14fbff", + "name": "Client IP Address", + "protocol": "openid-connect", + "protocolMapper": "oidc-usersessionmodel-note-mapper", + "consentRequired": false, + "config": { + "user.session.note": "clientAddress", + "userinfo.token.claim": "true", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "clientAddress", + "jsonType.label": "String" + } + }, + { + "id": "72f9ae74-9e95-4b7b-a709-5086137410bb", + "name": "Client ID", + "protocol": "openid-connect", + "protocolMapper": "oidc-usersessionmodel-note-mapper", + "consentRequired": false, + "config": { + "user.session.note": "clientId", + "userinfo.token.claim": "true", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "clientId", + "jsonType.label": "String" + } + }, + { + "id": "029bf6c8-5a19-4798-984c-bdb205d752d5", + "name": "Client Host", + "protocol": "openid-connect", + "protocolMapper": "oidc-usersessionmodel-note-mapper", + "consentRequired": false, + "config": { + "user.session.note": "clientHost", + "userinfo.token.claim": "true", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "clientHost", + "jsonType.label": "String" + } + } + ], + "defaultClientScopes": ["web-origins", "roles", "profile", "email"], + "optionalClientScopes": ["address", "phone", "offline_access", "microprofile-jwt"] + }, + { + "id": "898488c8-e260-41c5-a463-7ceea14d587a", + "clientId": "realm-management", + "name": "${client_realm-management}", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "secret": "**********", + "redirectUris": [], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": true, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": false, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": {}, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "defaultClientScopes": ["web-origins", "roles", "profile", "email"], + "optionalClientScopes": ["address", "phone", "offline_access", "microprofile-jwt"] + }, + { + "id": "989d2b96-b820-4f9b-aa17-55e6488b08c8", + "clientId": "security-admin-console", + "name": "${client_security-admin-console}", + "rootUrl": "${authAdminUrl}", + "baseUrl": "/admin/oncokb-curation/console/", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "secret": "**********", + "redirectUris": ["/admin/oncokb-curation/console/*"], + "webOrigins": ["+"], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": true, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": { + "pkce.code.challenge.method": "S256" + }, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "protocolMappers": [ + { + "id": "5fd34289-c644-411a-874c-849475d9d102", + "name": "locale", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "locale", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "locale", + "jsonType.label": "String" + } + } + ], + "defaultClientScopes": ["web-origins", "roles", "profile", "email"], + "optionalClientScopes": ["address", "phone", "offline_access", "microprofile-jwt"] + }, + { + "id": "6e8deddb-b4d6-4e2e-b389-b397d3f74fcd", + "clientId": "web_app", + "rootUrl": "http://localhost:9090", + "adminUrl": "http://localhost:9090", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "secret": "**********", + "redirectUris": ["dev.localhost.ionic:*", "http://127.0.0.1:*", "http://localhost:*", "https://127.0.0.1:*", "https://localhost:*"], + "webOrigins": ["*"], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": true, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": false, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": { + "saml.assertion.signature": "false", + "saml.force.post.binding": "false", + "saml.multivalued.roles": "false", + "saml.encrypt": "false", + "saml.server.signature": "false", + "saml.server.signature.keyinfo.ext": "false", + "exclude.session.state.from.auth.response": "false", + "saml_force_name_id_format": "false", + "saml.client.signature": "false", + "tls.client.certificate.bound.access.tokens": "false", + "saml.authnstatement": "false", + "display.on.consent.screen": "false", + "saml.onetimeuse.condition": "false" + }, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": true, + "nodeReRegistrationTimeout": -1, + "defaultClientScopes": ["web-origins", "oncokb", "roles", "profile", "email"], + "optionalClientScopes": ["address", "phone", "offline_access", "microprofile-jwt"] + } + ], + "clientScopes": [ + { + "id": "44d24405-87bf-4b37-a627-e3fdabb93f50", + "name": "email", + "description": "OpenID Connect built-in scope: email", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "true", + "consent.screen.text": "${emailScopeConsentText}" + }, + "protocolMappers": [ + { + "id": "36800088-6d17-4c18-93e8-2bc93901d8b7", + "name": "email", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "email", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "email", + "jsonType.label": "String" + } + }, + { + "id": "3ea34afd-30b5-4e5d-a836-dbda439dce6f", + "name": "email verified", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "emailVerified", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "email_verified", + "jsonType.label": "boolean" + } + } + ] + }, + { + "id": "87d299f2-434f-4abd-8cb0-a16231acd713", + "name": "microprofile-jwt", + "description": "Microprofile - JWT built-in scope", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "false" + }, + "protocolMappers": [ + { + "id": "fce09d51-cb85-4ccd-b83d-865a4d4bf650", + "name": "groups", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-realm-role-mapper", + "consentRequired": false, + "config": { + "multivalued": "true", + "userinfo.token.claim": "true", + "user.attribute": "foo", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "groups", + "jsonType.label": "String" + } + }, + { + "id": "3d1ee7e2-b7e1-4504-bd52-b47a2cb10eec", + "name": "upn", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "username", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "upn", + "jsonType.label": "String" + } + } + ] + }, + { + "id": "915fcb95-81da-4e4c-86ee-73f3b52c83e9", + "name": "roles", + "description": "OpenID Connect scope for add user roles to the access token", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "false", + "display.on.consent.screen": "true", + "consent.screen.text": "${rolesScopeConsentText}" + }, + "protocolMappers": [ + { + "id": "12f0b32d-8911-4028-809b-fc1c0e5e9207", + "name": "audience resolve", + "protocol": "openid-connect", + "protocolMapper": "oidc-audience-resolve-mapper", + "consentRequired": false, + "config": {} + }, + { + "id": "5b997b66-937f-46d3-9e8b-70dca949f682", + "name": "realm roles", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-realm-role-mapper", + "consentRequired": false, + "config": { + "user.attribute": "foo", + "access.token.claim": "true", + "claim.name": "realm_access.roles", + "jsonType.label": "String", + "multivalued": "true" + } + }, + { + "id": "cdcd6969-a9aa-4de5-adbe-dc83da4184c5", + "name": "client roles", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-client-role-mapper", + "consentRequired": false, + "config": { + "user.attribute": "foo", + "access.token.claim": "true", + "claim.name": "resource_access.${client_id}.roles", + "jsonType.label": "String", + "multivalued": "true" + } + } + ] + }, + { + "id": "52d73c82-423c-44a8-b2ec-1e13f4cd6065", + "name": "address", + "description": "OpenID Connect built-in scope: address", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "true", + "consent.screen.text": "${addressScopeConsentText}" + }, + "protocolMappers": [ + { + "id": "98230752-36b9-4755-8661-a7de1926d0d4", + "name": "address", + "protocol": "openid-connect", + "protocolMapper": "oidc-address-mapper", + "consentRequired": false, + "config": { + "user.attribute.formatted": "formatted", + "user.attribute.country": "country", + "user.attribute.postal_code": "postal_code", + "userinfo.token.claim": "true", + "user.attribute.street": "street", + "id.token.claim": "true", + "user.attribute.region": "region", + "access.token.claim": "true", + "user.attribute.locality": "locality" + } + } + ] + }, + { + "id": "2b867b2d-3373-43ff-b50f-ea37a5e1c390", + "name": "phone", + "description": "OpenID Connect built-in scope: phone", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "true", + "consent.screen.text": "${phoneScopeConsentText}" + }, + "protocolMappers": [ + { + "id": "daa0191b-20d1-4f71-b191-6c48a37e3677", + "name": "phone number", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "phoneNumber", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "phone_number", + "jsonType.label": "String" + } + }, + { + "id": "32213de7-12f7-4864-b696-c8e6c5e0c26e", + "name": "phone number verified", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "phoneNumberVerified", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "phone_number_verified", + "jsonType.label": "boolean" + } + } + ] + }, + { + "id": "9816de82-24b7-42fe-a85a-1264868ec293", + "name": "oncokb", + "description": "OncoKB specific claims", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "false", + "display.on.consent.screen": "false" + }, + "protocolMappers": [ + { + "id": "0f9c9347-aad6-4bff-94f4-e11937f2ad33", + "name": "langKey", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "langKey", + "id.token.claim": "false", + "access.token.claim": "false", + "claim.name": "langKey", + "jsonType.label": "String" + } + }, + { + "id": "69729907-8d1c-4961-81c0-91766f548cc9", + "name": "roles", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-realm-role-mapper", + "consentRequired": false, + "config": { + "multivalued": "true", + "userinfo.token.claim": "true", + "id.token.claim": "false", + "access.token.claim": "true", + "claim.name": "roles", + "jsonType.label": "String" + } + }, + { + "id": "336acfe2-a717-492a-9055-5b70e808f42f", + "name": "login", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "preferred_username", + "id.token.claim": "false", + "access.token.claim": "false", + "claim.name": "login", + "jsonType.label": "String" + } + } + ] + }, + { + "id": "d181691e-b4a6-4063-9eba-6b984402a9a7", + "name": "role_list", + "description": "SAML role list", + "protocol": "saml", + "attributes": { + "consent.screen.text": "${samlRoleListScopeConsentText}", + "display.on.consent.screen": "true" + }, + "protocolMappers": [ + { + "id": "724b16d4-8a9b-42d8-850f-99ca1ab3c958", + "name": "role list", + "protocol": "saml", + "protocolMapper": "saml-role-list-mapper", + "consentRequired": false, + "config": { + "single": "false", + "attribute.nameformat": "Basic", + "attribute.name": "Role" + } + } + ] + }, + { + "id": "60a44832-9776-449f-94cd-fa8c24a75f35", + "name": "profile", + "description": "OpenID Connect built-in scope: profile", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "true", + "consent.screen.text": "${profileScopeConsentText}" + }, + "protocolMappers": [ + { + "id": "a59584ab-7a7c-4b23-95b5-be8dbbfadc6f", + "name": "family name", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "lastName", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "family_name", + "jsonType.label": "String" + } + }, + { + "id": "d382c1dc-d5d8-479e-8809-f0a618113a07", + "name": "website", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "website", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "website", + "jsonType.label": "String" + } + }, + { + "id": "559f86c1-1187-498d-8354-723f4ea5721c", + "name": "full name", + "protocol": "openid-connect", + "protocolMapper": "oidc-full-name-mapper", + "consentRequired": false, + "config": { + "id.token.claim": "true", + "access.token.claim": "true", + "userinfo.token.claim": "true" + } + }, + { + "id": "0925e106-a8e2-4ad1-b75e-4147d185894a", + "name": "updated at", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "updatedAt", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "updated_at", + "jsonType.label": "String" + } + }, + { + "id": "eb8e2c73-5c65-4b53-8d55-46edef61315b", + "name": "locale", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "locale", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "locale", + "jsonType.label": "String" + } + }, + { + "id": "4c109376-01bc-4b69-a3c0-4b830ecad674", + "name": "middle name", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "middleName", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "middle_name", + "jsonType.label": "String" + } + }, + { + "id": "b3813956-e556-4b57-a06b-f71b0d6f3d47", + "name": "nickname", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "nickname", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "nickname", + "jsonType.label": "String" + } + }, + { + "id": "28beb4c0-029b-4aa5-ad5f-6d824ca67e15", + "name": "username", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "username", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "preferred_username", + "jsonType.label": "String" + } + }, + { + "id": "53d681bc-ec29-4f57-924b-ff5bd22d4093", + "name": "profile", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "profile", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "profile", + "jsonType.label": "String" + } + }, + { + "id": "12ba8e12-157d-4729-918b-0d74fa444fba", + "name": "picture", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "picture", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "picture", + "jsonType.label": "String" + } + }, + { + "id": "ddb818fe-8e4a-4b26-9c5d-2467a26af6dc", + "name": "gender", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "gender", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "gender", + "jsonType.label": "String" + } + }, + { + "id": "f78b1746-2be1-45f4-9c1e-1f6141ccdb65", + "name": "birthdate", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "birthdate", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "birthdate", + "jsonType.label": "String" + } + }, + { + "id": "7723245c-4952-4822-86ae-084048b1f2f2", + "name": "given name", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "firstName", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "given_name", + "jsonType.label": "String" + } + }, + { + "id": "b192fe9f-aa82-4d7d-b8c7-eb7d1ba888d4", + "name": "zoneinfo", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "zoneinfo", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "zoneinfo", + "jsonType.label": "String" + } + } + ] + }, + { + "id": "2daaac74-636f-4074-87a9-d1aba9dffb96", + "name": "web-origins", + "description": "OpenID Connect scope for add allowed web origins to the access token", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "false", + "display.on.consent.screen": "false", + "consent.screen.text": "" + }, + "protocolMappers": [ + { + "id": "752e035f-038d-46ac-b65d-91f863fdd986", + "name": "allowed web origins", + "protocol": "openid-connect", + "protocolMapper": "oidc-allowed-origins-mapper", + "consentRequired": false, + "config": {} + } + ] + }, + { + "id": "0399b625-22d7-4d68-b4db-fd1dc2effacc", + "name": "offline_access", + "description": "OpenID Connect built-in scope: offline_access", + "protocol": "openid-connect", + "attributes": { + "consent.screen.text": "${offlineAccessScopeConsentText}", + "display.on.consent.screen": "true" + } + } + ], + "defaultDefaultClientScopes": ["web-origins", "email", "profile", "roles", "role_list"], + "defaultOptionalClientScopes": ["offline_access", "phone", "address", "microprofile-jwt"], + "browserSecurityHeaders": { + "contentSecurityPolicyReportOnly": "", + "xContentTypeOptions": "nosniff", + "xRobotsTag": "none", + "xFrameOptions": "SAMEORIGIN", + "contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", + "xXSSProtection": "1; mode=block", + "strictTransportSecurity": "max-age=31536000; includeSubDomains" + }, + "smtpServer": {}, + "eventsEnabled": false, + "eventsListeners": ["jboss-logging"], + "enabledEventTypes": [], + "adminEventsEnabled": false, + "adminEventsDetailsEnabled": false, + "identityProviders": [ + { + "alias": "google", + "internalId": "a4e10ab5-e8ac-46d5-a72c-2f72876b3a6c", + "providerId": "google", + "enabled": true, + "updateProfileFirstLoginMode": "on", + "trustEmail": true, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "syncMode": "FORCE", + "clientSecret": "GOOGLE_CLIENT_SECRET", + "clientId": "GOOGLE_CLIENT_ID", + "useJwksUrl": "true" + } + } + ], + "identityProviderMappers": [ + { + "id": "4f2bdff6-b374-472a-9ede-afcc575c311b", + "name": "picture", + "identityProviderAlias": "google", + "identityProviderMapper": "google-user-attribute-mapper", + "config": { + "syncMode": "INHERIT", + "jsonField": "picture", + "userAttribute": "picture" + } + } + ], + "components": { + "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy": [ + { + "id": "827fde01-dc1b-4c1f-a529-9ef833ca3432", + "name": "Allowed Protocol Mapper Types", + "providerId": "allowed-protocol-mappers", + "subType": "authenticated", + "subComponents": {}, + "config": { + "allowed-protocol-mapper-types": [ + "oidc-usermodel-property-mapper", + "saml-role-list-mapper", + "oidc-full-name-mapper", + "oidc-address-mapper", + "saml-user-property-mapper", + "oidc-sha256-pairwise-sub-mapper", + "oidc-usermodel-attribute-mapper", + "saml-user-attribute-mapper" + ] + } + }, + { + "id": "0a429e7e-be7a-46b4-b42a-d1f8b265ff16", + "name": "Allowed Client Scopes", + "providerId": "allowed-client-templates", + "subType": "authenticated", + "subComponents": {}, + "config": { + "allow-default-scopes": ["true"] + } + }, + { + "id": "5a1ff0b4-250f-48ee-8169-abff30cf7534", + "name": "Allowed Client Scopes", + "providerId": "allowed-client-templates", + "subType": "anonymous", + "subComponents": {}, + "config": { + "allow-default-scopes": ["true"] + } + }, + { + "id": "c79f6629-84a9-467c-81d0-63e20b19f916", + "name": "Full Scope Disabled", + "providerId": "scope", + "subType": "anonymous", + "subComponents": {}, + "config": {} + }, + { + "id": "b6b23ef8-96e8-4e2e-8efe-8003057a8d42", + "name": "Max Clients Limit", + "providerId": "max-clients", + "subType": "anonymous", + "subComponents": {}, + "config": { + "max-clients": ["200"] + } + }, + { + "id": "36dfaa02-0252-4448-9cdf-a17abf239f78", + "name": "Trusted Hosts", + "providerId": "trusted-hosts", + "subType": "anonymous", + "subComponents": {}, + "config": { + "host-sending-registration-request-must-match": ["true"], + "client-uris-must-match": ["true"] + } + }, + { + "id": "8216421d-34fb-4726-8331-137217657bdb", + "name": "Allowed Protocol Mapper Types", + "providerId": "allowed-protocol-mappers", + "subType": "anonymous", + "subComponents": {}, + "config": { + "allowed-protocol-mapper-types": [ + "oidc-sha256-pairwise-sub-mapper", + "saml-user-property-mapper", + "oidc-usermodel-property-mapper", + "saml-role-list-mapper", + "saml-user-attribute-mapper", + "oidc-usermodel-attribute-mapper", + "oidc-address-mapper", + "oidc-full-name-mapper" + ] + } + }, + { + "id": "d045f3f9-15e6-4e69-a419-0e7ff8a635ef", + "name": "Consent Required", + "providerId": "consent-required", + "subType": "anonymous", + "subComponents": {}, + "config": {} + } + ], + "org.keycloak.keys.KeyProvider": [ + { + "id": "62707fae-58f9-4fc2-89fb-0c5d212dc3dc", + "name": "rsa-generated", + "providerId": "rsa-generated", + "subComponents": {}, + "config": { + "priority": ["100"] + } + }, + { + "id": "4a8480bc-96fd-4906-a907-f948a73bab38", + "name": "hmac-generated", + "providerId": "hmac-generated", + "subComponents": {}, + "config": { + "priority": ["100"], + "algorithm": ["HS256"] + } + }, + { + "id": "40c01a32-0c0b-4dbb-9595-e5a5c8d26bc4", + "name": "aes-generated", + "providerId": "aes-generated", + "subComponents": {}, + "config": { + "priority": ["100"] + } + } + ] + }, + "internationalizationEnabled": false, + "supportedLocales": [], + "authenticationFlows": [ + { + "id": "989689e4-041f-4ace-9dc2-ae1a810deea4", + "alias": "Account verification options", + "description": "Method with which to verity the existing account", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "idp-email-verification", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorFlow": true, + "requirement": "ALTERNATIVE", + "priority": 20, + "flowAlias": "Verify Existing Account by Re-authentication", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "7c35cd1a-f2cb-4eb2-91e8-ba9763b6a561", + "alias": "Authentication Options", + "description": "Authentication options.", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "basic-auth", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "basic-auth-otp", + "authenticatorFlow": false, + "requirement": "DISABLED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "auth-spnego", + "authenticatorFlow": false, + "requirement": "DISABLED", + "priority": 30, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "1bd0cad8-431b-4ddd-9535-704df420baf7", + "alias": "Browser - Conditional OTP", + "description": "Flow to determine if the OTP is required for the authentication", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "conditional-user-configured", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "auth-otp-form", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "78499f05-cd6f-4ce4-af0c-db6cc63e7b8f", + "alias": "Direct Grant - Conditional OTP", + "description": "Flow to determine if the OTP is required for the authentication", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "conditional-user-configured", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "direct-grant-validate-otp", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "36dbf0aa-219d-4208-b140-40c2002aa8e5", + "alias": "First broker login - Conditional OTP", + "description": "Flow to determine if the OTP is required for the authentication", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "conditional-user-configured", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "auth-otp-form", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "ced1ee9f-c91b-436e-8543-69d5991e68cd", + "alias": "Handle Existing Account", + "description": "Handle what to do if there is existing account with same email/username like authenticated identity provider", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "idp-confirm-link", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorFlow": true, + "requirement": "REQUIRED", + "priority": 20, + "flowAlias": "Account verification options", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "015865c0-d47f-4fda-8995-b16acf71fd34", + "alias": "Reset - Conditional OTP", + "description": "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "conditional-user-configured", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "reset-otp", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "a1b2464b-5409-4777-8c2a-649dc53ae265", + "alias": "User creation or linking", + "description": "Flow for the existing/non-existing user alternatives", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticatorConfig": "create unique user config", + "authenticator": "idp-create-user-if-unique", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorFlow": true, + "requirement": "ALTERNATIVE", + "priority": 20, + "flowAlias": "Handle Existing Account", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "7f76cd66-a846-4ae6-a83f-b8db129dad21", + "alias": "Verify Existing Account by Re-authentication", + "description": "Reauthentication of existing account", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "idp-username-password-form", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorFlow": true, + "requirement": "CONDITIONAL", + "priority": 20, + "flowAlias": "First broker login - Conditional OTP", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "eadb45e6-5355-4609-936a-8077f60de7d4", + "alias": "browser", + "description": "browser based authentication", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "auth-cookie", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "auth-spnego", + "authenticatorFlow": false, + "requirement": "DISABLED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "identity-provider-redirector", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 25, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorFlow": true, + "requirement": "ALTERNATIVE", + "priority": 30, + "flowAlias": "forms", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "281497dc-213e-4a64-b4ef-3495c7e18e47", + "alias": "clients", + "description": "Base authentication for clients", + "providerId": "client-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "client-secret", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "client-jwt", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "client-secret-jwt", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 30, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "client-x509", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 40, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "534a057b-6a60-4e80-9183-08990bd6d117", + "alias": "direct grant", + "description": "OpenID Connect Resource Owner Grant", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "direct-grant-validate-username", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "direct-grant-validate-password", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorFlow": true, + "requirement": "CONDITIONAL", + "priority": 30, + "flowAlias": "Direct Grant - Conditional OTP", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "3333cff7-28f0-4d09-b2ca-2f550e565258", + "alias": "docker auth", + "description": "Used by Docker clients to authenticate against the IDP", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "docker-http-basic-authenticator", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "89619e12-b266-429e-ab4e-79a84161dd13", + "alias": "first broker login", + "description": "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticatorConfig": "review profile config", + "authenticator": "idp-review-profile", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorFlow": true, + "requirement": "REQUIRED", + "priority": 20, + "flowAlias": "User creation or linking", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "a33d2f3c-5158-46bb-a606-b2c92e617521", + "alias": "forms", + "description": "Username, password, otp and other auth forms.", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "auth-username-password-form", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorFlow": true, + "requirement": "CONDITIONAL", + "priority": 20, + "flowAlias": "Browser - Conditional OTP", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "745b428f-5d81-4d8c-8952-078815010fe8", + "alias": "http challenge", + "description": "An authentication flow based on challenge-response HTTP Authentication Schemes", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "no-cookie-redirect", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorFlow": true, + "requirement": "REQUIRED", + "priority": 20, + "flowAlias": "Authentication Options", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "675aeddf-e64c-40c4-9a2a-01eb09003656", + "alias": "registration", + "description": "registration flow", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "registration-page-form", + "authenticatorFlow": true, + "requirement": "REQUIRED", + "priority": 10, + "flowAlias": "registration form", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "4aee0f8e-68cf-42fb-a7a9-1788b27bffe8", + "alias": "registration form", + "description": "registration form", + "providerId": "form-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "registration-user-creation", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "registration-profile-action", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 40, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "registration-password-action", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 50, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "registration-recaptcha-action", + "authenticatorFlow": false, + "requirement": "DISABLED", + "priority": 60, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "8b1c6cb8-c419-49bd-8702-cb504b116f73", + "alias": "reset credentials", + "description": "Reset credentials for a user if they forgot their password or something", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "reset-credentials-choose-user", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "reset-credential-email", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticator": "reset-password", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 30, + "userSetupAllowed": false, + "autheticatorFlow": false + }, + { + "authenticatorFlow": true, + "requirement": "CONDITIONAL", + "priority": 40, + "flowAlias": "Reset - Conditional OTP", + "userSetupAllowed": false, + "autheticatorFlow": true + } + ] + }, + { + "id": "6da630da-ba41-4d8f-aa45-7724a626b4d2", + "alias": "saml ecp", + "description": "SAML ECP Profile Authentication Flow", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "http-basic-authenticator", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + } + ], + "authenticatorConfig": [ + { + "id": "51a222a3-8269-4291-9272-5cbf2457c8e9", + "alias": "create unique user config", + "config": { + "require.password.update.after.registration": "false" + } + }, + { + "id": "89943727-2441-41e8-87f2-c0dd07d24ea8", + "alias": "review profile config", + "config": { + "update.profile.on.first.login": "missing" + } + } + ], + "requiredActions": [ + { + "alias": "CONFIGURE_TOTP", + "name": "Configure OTP", + "providerId": "CONFIGURE_TOTP", + "enabled": true, + "defaultAction": false, + "priority": 10, + "config": {} + }, + { + "alias": "terms_and_conditions", + "name": "Terms and Conditions", + "providerId": "terms_and_conditions", + "enabled": false, + "defaultAction": false, + "priority": 20, + "config": {} + }, + { + "alias": "UPDATE_PASSWORD", + "name": "Update Password", + "providerId": "UPDATE_PASSWORD", + "enabled": true, + "defaultAction": false, + "priority": 30, + "config": {} + }, + { + "alias": "UPDATE_PROFILE", + "name": "Update Profile", + "providerId": "UPDATE_PROFILE", + "enabled": true, + "defaultAction": false, + "priority": 40, + "config": {} + }, + { + "alias": "VERIFY_EMAIL", + "name": "Verify Email", + "providerId": "VERIFY_EMAIL", + "enabled": true, + "defaultAction": false, + "priority": 50, + "config": {} + }, + { + "alias": "delete_account", + "name": "Delete Account", + "providerId": "delete_account", + "enabled": false, + "defaultAction": false, + "priority": 60, + "config": {} + }, + { + "alias": "update_user_locale", + "name": "Update User Locale", + "providerId": "update_user_locale", + "enabled": true, + "defaultAction": false, + "priority": 1000, + "config": {} + } + ], + "browserFlow": "browser", + "registrationFlow": "registration", + "directGrantFlow": "direct grant", + "resetCredentialsFlow": "reset credentials", + "clientAuthenticationFlow": "clients", + "dockerAuthenticationFlow": "docker auth", + "attributes": { + "cibaBackchannelTokenDeliveryMode": "poll", + "cibaExpiresIn": "120", + "cibaAuthRequestedUserHint": "login_hint", + "oauth2DeviceCodeLifespan": "600", + "clientOfflineSessionMaxLifespan": "0", + "oauth2DevicePollingInterval": "5", + "clientSessionIdleTimeout": "0", + "clientSessionMaxLifespan": "0", + "clientOfflineSessionIdleTimeout": "0", + "cibaInterval": "5" + }, + "keycloakVersion": "14.0.0", + "userManagedAccessAllowed": false, + "clientProfiles": { + "profiles": [] + }, + "clientPolicies": { + "policies": [] + } +} diff --git a/src/main/docker/realm-config/oncokb-curation-users-0.json b/src/main/docker/realm-config/oncokb-curation-users-0.json new file mode 100644 index 000000000..171b7395f --- /dev/null +++ b/src/main/docker/realm-config/oncokb-curation-users-0.json @@ -0,0 +1,61 @@ +{ + "realm": "oncokb-curation", + "users": [ + { + "id": "4c973896-5761-41fc-8217-07c5d13a004b", + "createdTimestamp": 1505479415590, + "username": "admin", + "enabled": true, + "totp": false, + "emailVerified": true, + "firstName": "Admin", + "lastName": "Administrator", + "email": "admin@localhost", + "credentials": [ + { + "id": "b860462b-9b02-48ba-9523-d3a8926a917b", + "type": "password", + "createdDate": 1505479429154, + "secretData": "{\"value\":\"4pf9K2jWSCcHC+CwsZP/qidN5pSmDUe6AX6wBerSGdBVKkExay8MWKx+EKmaaObZW6FVsD8vdW/ZsyUFD9gJ1Q==\",\"salt\":\"1/qNkZ5kr77jOMOBPBogGw==\"}", + "credentialData": "{\"hashIterations\":27500,\"algorithm\":\"pbkdf2-sha256\"}" + } + ], + "disableableCredentialTypes": [], + "requiredActions": [], + "realmRoles": ["offline_access", "uma_authorization"], + "clientRoles": { + "account": ["view-profile", "manage-account"] + }, + "notBefore": 0, + "groups": ["/Admins", "/Users"] + }, + { + "id": "c4af4e2f-b432-4c3b-8405-cca86cd5b97b", + "createdTimestamp": 1505479373742, + "username": "user", + "enabled": true, + "totp": false, + "emailVerified": true, + "firstName": "", + "lastName": "User", + "email": "user@localhost", + "credentials": [ + { + "id": "7821832b-1e82-45a2-b8d3-f1a6ad909e64", + "type": "password", + "createdDate": 1505479392766, + "secretData": "{\"value\":\"MbKsMgWPnZyImih8s4SaoCSCq+XIY/c6S9F93sXEidHF1TjPWxCqMkec0+o3860CMLXHt3az61cIJOWI0FW9aw==\",\"salt\":\"fmpBI1r8R1u75hDLMUlwBw==\"}", + "credentialData": "{\"hashIterations\":27500,\"algorithm\":\"pbkdf2-sha256\"}" + } + ], + "disableableCredentialTypes": [], + "requiredActions": [], + "realmRoles": ["offline_access", "uma_authorization"], + "clientRoles": { + "account": ["view-profile", "manage-account"] + }, + "notBefore": 0, + "groups": ["/Users"] + } + ] +} diff --git a/src/main/docker/redis-cluster.yml b/src/main/docker/redis-cluster.yml index 3505e1c0f..c64a63fe3 100644 --- a/src/main/docker/redis-cluster.yml +++ b/src/main/docker/redis-cluster.yml @@ -1,7 +1,7 @@ # This configuration is intended for development purpose, it's **your** responsibility to harden it for production version: '3.8' services: - oncokb-transcript-redis: + oncokb-curation-redis: image: redis:6.2.5 command: - 'redis-server' @@ -12,7 +12,7 @@ services: - '--appendonly yes' ports: - '6379:6379' - oncokb-transcript-redis-1: + oncokb-curation-redis-1: image: redis:6.2.5 command: - 'redis-server' @@ -23,7 +23,7 @@ services: - '--appendonly yes' ports: - '16379:6379' - oncokb-transcript-redis-2: + oncokb-curation-redis-2: image: redis:6.2.5 command: - 'redis-server' @@ -34,7 +34,7 @@ services: - '--appendonly yes' ports: - '26379:6379' - oncokb-transcript-redis-3: + oncokb-curation-redis-3: image: redis:6.2.5 command: - 'redis-server' @@ -45,7 +45,7 @@ services: - '--appendonly yes' ports: - '36379:6379' - oncokb-transcript-redis-4: + oncokb-curation-redis-4: image: redis:6.2.5 command: - 'redis-server' @@ -56,7 +56,7 @@ services: - '--appendonly yes' ports: - '46379:6379' - oncokb-transcript-redis-5: + oncokb-curation-redis-5: image: redis:6.2.5 command: - 'redis-server' @@ -67,7 +67,7 @@ services: - '--appendonly yes' ports: - '56379:6379' - oncokb-transcript-redis-cluster-builder: + oncokb-curation-redis-cluster-builder: build: context: . dockerfile: redis/Redis-Cluster.Dockerfile diff --git a/src/main/docker/redis.yml b/src/main/docker/redis.yml index f68448f84..dea428afb 100644 --- a/src/main/docker/redis.yml +++ b/src/main/docker/redis.yml @@ -1,7 +1,7 @@ # This configuration is intended for development purpose, it's **your** responsibility to harden it for production version: '3.8' services: - oncokb-transcript-redis: + oncokb-curation-redis: image: redis:6.2.5 # If you want to expose these ports outside your dev PC, # remove the "127.0.0.1:" prefix diff --git a/src/main/docker/redis/connectRedisCluster.sh b/src/main/docker/redis/connectRedisCluster.sh index e81ac5532..dd864cd42 100644 --- a/src/main/docker/redis/connectRedisCluster.sh +++ b/src/main/docker/redis/connectRedisCluster.sh @@ -12,9 +12,9 @@ redis-cli \ --cluster-replicas 1 \ --cluster-yes \ --cluster create \ - $(host oncokb-transcript-redis|awk '{print $4}'):6379 \ - $(host oncokb-transcript-redis-1|awk '{print $4}'):6379 \ - $(host oncokb-transcript-redis-2|awk '{print $4}'):6379 \ - $(host oncokb-transcript-redis-3|awk '{print $4}'):6379 \ - $(host oncokb-transcript-redis-4|awk '{print $4}'):6379 \ - $(host oncokb-transcript-redis-5|awk '{print $4}'):6379 + $(host oncokb-curation-redis|awk '{print $4}'):6379 \ + $(host oncokb-curation-redis-1|awk '{print $4}'):6379 \ + $(host oncokb-curation-redis-2|awk '{print $4}'):6379 \ + $(host oncokb-curation-redis-3|awk '{print $4}'):6379 \ + $(host oncokb-curation-redis-4|awk '{print $4}'):6379 \ + $(host oncokb-curation-redis-5|awk '{print $4}'):6379 diff --git a/src/main/docker/sonar.yml b/src/main/docker/sonar.yml index 31ed25549..84ced8ecd 100644 --- a/src/main/docker/sonar.yml +++ b/src/main/docker/sonar.yml @@ -1,7 +1,7 @@ # This configuration is intended for development purpose, it's **your** responsibility to harden it for production version: '3.8' services: - oncokb-transcript-sonar: + oncokb-curation-sonar: image: sonarqube:8.9.2-community # Authentication is turned off for out of the box experience while trying out SonarQube # For real use cases delete sonar.forceAuthentication variable or set sonar.forceAuthentication=true diff --git a/src/main/java/org/mskcc/oncokb/transcript/ApplicationWebXml.java b/src/main/java/org/mskcc/oncokb/curation/ApplicationWebXml.java similarity index 87% rename from src/main/java/org/mskcc/oncokb/transcript/ApplicationWebXml.java rename to src/main/java/org/mskcc/oncokb/curation/ApplicationWebXml.java index f6c2f33b0..0887d8915 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/ApplicationWebXml.java +++ b/src/main/java/org/mskcc/oncokb/curation/ApplicationWebXml.java @@ -1,4 +1,4 @@ -package org.mskcc.oncokb.transcript; +package org.mskcc.oncokb.curation; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; @@ -14,6 +14,6 @@ public class ApplicationWebXml extends SpringBootServletInitializer { protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { // set a default to use when no profile is configured. DefaultProfileUtil.addDefaultProfile(application.application()); - return application.sources(OncokbTranscriptApp.class); + return application.sources(OncokbCurationApp.class); } } diff --git a/src/main/java/org/mskcc/oncokb/curation/OncokbCurationApp.java b/src/main/java/org/mskcc/oncokb/curation/OncokbCurationApp.java new file mode 100644 index 000000000..c830cdef9 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/OncokbCurationApp.java @@ -0,0 +1,211 @@ +package org.mskcc.oncokb.curation; + +import com.google.auth.oauth2.GoogleCredentials; +import com.google.firebase.FirebaseApp; +import com.google.firebase.FirebaseOptions; +import io.sentry.Sentry; +import java.io.IOException; +import java.net.InetAddress; +import java.net.URL; +import java.net.UnknownHostException; +import java.util.Arrays; +import java.util.Collection; +import java.util.Optional; +import javax.annotation.PostConstruct; +import org.apache.commons.lang3.StringUtils; +import org.mskcc.oncokb.curation.config.CRLFLogConverter; +import org.mskcc.oncokb.curation.config.application.ApplicationProperties; +import org.mskcc.oncokb.curation.config.application.FrontendProperties; +import org.mskcc.oncokb.curation.importer.CdxImporter; +import org.mskcc.oncokb.curation.importer.Importer; +import org.oncokb.ApiException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.core.env.Environment; +import tech.jhipster.config.DefaultProfileUtil; +import tech.jhipster.config.JHipsterConstants; + +@SpringBootApplication +@EnableConfigurationProperties({ LiquibaseProperties.class, ApplicationProperties.class }) +public class OncokbCurationApp { + + @Autowired + private Importer importer; + + @Autowired + private ApplicationProperties applicationProperties; + + @Autowired + CdxImporter cdxImporter; + + private static final Logger log = LoggerFactory.getLogger(OncokbCurationApp.class); + + private final Environment env; + + public OncokbCurationApp(Environment env) { + this.env = env; + } + + /** + * Initializes oncokb-curation. + *

+ * Spring profiles can be configured with a program argument --spring.profiles.active=your-active-profile + *

+ * You can find more information on how profiles work with JHipster on https://www.jhipster.tech/profiles/. + */ + @PostConstruct + public void initApplication() { + Collection activeProfiles = Arrays.asList(env.getActiveProfiles()); + if ( + activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) && + activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_PRODUCTION) + ) { + log.error( + "You have misconfigured your application! It should not run " + "with both the 'dev' and 'prod' profiles at the same time." + ); + } + if ( + activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) && + activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_CLOUD) + ) { + log.error( + "You have misconfigured your application! It should not " + "run with both the 'dev' and 'cloud' profiles at the same time." + ); + } + + // Copy firebase properties to FrontendProperties + if (applicationProperties.getFirebase() != null) { + if (applicationProperties.getFrontend() == null) { + applicationProperties.setFrontend(new FrontendProperties()); + } + applicationProperties.getFrontend().setFirebase(applicationProperties.getFirebase()); + } + } + + @PostConstruct + public void importOncoKbSequence() throws ApiException, IOException { + Collection activeProfiles = Arrays.asList( + env.getActiveProfiles().length == 0 ? env.getDefaultProfiles() : env.getActiveProfiles() + ); + if (activeProfiles.contains("importer")) { + importer.generalImport(); + } + } + + @PostConstruct + public void initFirebase() throws IOException { + if (applicationProperties.getFirebase().isEnabled()) { + String serviceAccountPath = applicationProperties.getFirebase().getServiceAccountCredentialsPath(); + if (serviceAccountPath == null) { + log.error("application.firebase.service-account-credentials-path is not specified"); + return; + } + URL serviceAccountFileUrl = getClass().getClassLoader().getResource(serviceAccountPath); + if (serviceAccountFileUrl == null) { + log.error("Cannot find the firebase service account file"); + return; + } + try { + FirebaseOptions options = FirebaseOptions.builder() + .setCredentials(GoogleCredentials.fromStream(serviceAccountFileUrl.openStream())) + .setDatabaseUrl(applicationProperties.getFirebase().getDatabaseUrl()) + .build(); + + FirebaseApp.initializeApp(options); + log.info("Firebase Admin SDK successfully initialized"); + } catch (Exception e) { + log.error("Failed to initialize Firebase", e.getMessage()); + } + } else { + log.info( + "Skipping Firebase Admin SDK initialization because application.firebase.enabled={}", + applicationProperties.getFirebase().isEnabled() + ); + } + } + + @PostConstruct + public void importInitialCdxData() throws IOException { + Collection activeProfiles = Arrays.asList( + env.getActiveProfiles().length == 0 ? env.getDefaultProfiles() : env.getActiveProfiles() + ); + if (activeProfiles.contains("cdx-importer")) { + cdxImporter.importCdxMain(); + } + } + + /** + * Main method, used to run the application. + * + * @param args the command line arguments. + */ + public static void main(String[] args) { + SpringApplication app = new SpringApplication(OncokbCurationApp.class); + DefaultProfileUtil.addDefaultProfile(app); + Environment env = app.run(args).getEnvironment(); + logApplicationStartup(env); + initSentry(env); + } + + private static void initSentry(Environment env) { + Collection activeProfiles = Arrays.asList(env.getActiveProfiles()); + if (activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_PRODUCTION)) { + Sentry.init(options -> { + options.setEnableExternalConfiguration(true); + options.setEnableUncaughtExceptionHandler(true); + + // Completed disable the traces sampling + options.setTracesSampler(null); + options.setTracesSampleRate(null); + // Ignore the following exceptions + // options.addIgnoredExceptionForType(IOException.class); + // options.addIgnoredExceptionForType(HttpClientErrorException.class); + // options.addIgnoredExceptionForType(HttpServerErrorException.class); + // options.addIgnoredExceptionForType(ResponseStatusException.class); + // options.addIgnoredExceptionForType(HttpRequestMethodNotSupportedException.class); + // options.addIgnoredExceptionForType(InternalAuthenticationServiceException.class); + // options.addIgnoredExceptionForType(BadRequestAlertException.class); + // options.addIgnoredExceptionForType(ResourceAccessException.class); + }); + } + } + + private static void logApplicationStartup(Environment env) { + String protocol = Optional.ofNullable(env.getProperty("server.ssl.key-store")).map(key -> "https").orElse("http"); + String serverPort = env.getProperty("server.port"); + String contextPath = Optional.ofNullable(env.getProperty("server.servlet.context-path")) + .filter(StringUtils::isNotBlank) + .orElse("/"); + String hostAddress = "localhost"; + try { + hostAddress = InetAddress.getLocalHost().getHostAddress(); + } catch (UnknownHostException e) { + log.warn("The host name could not be determined, using `localhost` as fallback"); + } + log.info( + CRLFLogConverter.CRLF_SAFE_MARKER, + """ + + ---------------------------------------------------------- + \tApplication '{}' is running! Access URLs: + \tLocal: \t\t{}://localhost:{}{} + \tExternal: \t{}://{}:{}{} + \tProfile(s): \t{} + ----------------------------------------------------------""", + env.getProperty("spring.application.name"), + protocol, + serverPort, + contextPath, + protocol, + hostAddress, + serverPort, + contextPath, + env.getActiveProfiles().length == 0 ? env.getDefaultProfiles() : env.getActiveProfiles() + ); + } +} diff --git a/src/main/java/org/mskcc/oncokb/transcript/aop/logging/LoggingAspect.java b/src/main/java/org/mskcc/oncokb/curation/aop/logging/LoggingAspect.java similarity index 80% rename from src/main/java/org/mskcc/oncokb/transcript/aop/logging/LoggingAspect.java rename to src/main/java/org/mskcc/oncokb/curation/aop/logging/LoggingAspect.java index a4d25e955..f88bfddab 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/aop/logging/LoggingAspect.java +++ b/src/main/java/org/mskcc/oncokb/curation/aop/logging/LoggingAspect.java @@ -1,4 +1,4 @@ -package org.mskcc.oncokb.transcript.aop.logging; +package org.mskcc.oncokb.curation.aop.logging; import java.util.Arrays; import org.aspectj.lang.JoinPoint; @@ -43,9 +43,9 @@ public void springBeanPointcut() { * Pointcut that matches all Spring beans in the application's main packages. */ @Pointcut( - "within(org.mskcc.oncokb.transcript.repository..*)" + - " || within(org.mskcc.oncokb.transcript.service..*)" + - " || within(org.mskcc.oncokb.transcript.web.rest..*)" + "within(org.mskcc.oncokb.curation.repository..*)" + + " || within(org.mskcc.oncokb.curation.service..*)" + + " || within(org.mskcc.oncokb.curation.web.rest..*)" ) public void applicationPackagePointcut() { // Method is empty as this is just a Pointcut, the implementations are in the advices. @@ -70,21 +70,19 @@ private Logger logger(JoinPoint joinPoint) { @AfterThrowing(pointcut = "applicationPackagePointcut() && springBeanPointcut()", throwing = "e") public void logAfterThrowing(JoinPoint joinPoint, Throwable e) { if (env.acceptsProfiles(Profiles.of(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT))) { - logger(joinPoint) - .error( - "Exception in {}() with cause = '{}' and exception = '{}'", - joinPoint.getSignature().getName(), - e.getCause() != null ? e.getCause() : "NULL", - e.getMessage(), - e - ); + logger(joinPoint).error( + "Exception in {}() with cause = '{}' and exception = '{}'", + joinPoint.getSignature().getName(), + e.getCause() != null ? e.getCause() : "NULL", + e.getMessage(), + e + ); } else { - logger(joinPoint) - .error( - "Exception in {}() with cause = {}", - joinPoint.getSignature().getName(), - e.getCause() != null ? e.getCause() : "NULL" - ); + logger(joinPoint).error( + "Exception in {}() with cause = {}", + joinPoint.getSignature().getName(), + e.getCause() != null ? e.getCause() : "NULL" + ); } } diff --git a/src/main/java/org/mskcc/oncokb/transcript/config/AsyncConfiguration.java b/src/main/java/org/mskcc/oncokb/curation/config/AsyncConfiguration.java similarity index 93% rename from src/main/java/org/mskcc/oncokb/transcript/config/AsyncConfiguration.java rename to src/main/java/org/mskcc/oncokb/curation/config/AsyncConfiguration.java index f6dd4f85e..d6f31a4f4 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/config/AsyncConfiguration.java +++ b/src/main/java/org/mskcc/oncokb/curation/config/AsyncConfiguration.java @@ -1,4 +1,4 @@ -package org.mskcc.oncokb.transcript.config; +package org.mskcc.oncokb.curation.config; import java.util.concurrent.Executor; import org.slf4j.Logger; @@ -8,6 +8,7 @@ import org.springframework.boot.autoconfigure.task.TaskExecutionProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; import org.springframework.scheduling.annotation.AsyncConfigurer; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; @@ -17,6 +18,7 @@ @Configuration @EnableAsync @EnableScheduling +@Profile("!testdev & !testprod") public class AsyncConfiguration implements AsyncConfigurer { private final Logger log = LoggerFactory.getLogger(AsyncConfiguration.class); diff --git a/src/main/java/org/mskcc/oncokb/curation/config/CRLFLogConverter.java b/src/main/java/org/mskcc/oncokb/curation/config/CRLFLogConverter.java new file mode 100644 index 000000000..72aa59135 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/config/CRLFLogConverter.java @@ -0,0 +1,69 @@ +package org.mskcc.oncokb.curation.config; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.pattern.CompositeConverter; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.slf4j.Marker; +import org.slf4j.MarkerFactory; +import org.springframework.boot.ansi.AnsiColor; +import org.springframework.boot.ansi.AnsiElement; +import org.springframework.boot.ansi.AnsiOutput; +import org.springframework.boot.ansi.AnsiStyle; + +/** + * Log filter to prevent attackers from forging log entries by submitting input containing CRLF characters. + * CRLF characters are replaced with a red colored _ character. + * + * @see Log Forging Description + * @see JHipster issue + */ +public class CRLFLogConverter extends CompositeConverter { + + public static final Marker CRLF_SAFE_MARKER = MarkerFactory.getMarker("CRLF_SAFE"); + + private static final String[] SAFE_LOGGERS = { + "org.hibernate", + "org.springframework.boot.autoconfigure", + "org.springframework.boot.diagnostics", + }; + private static final Map ELEMENTS; + + static { + Map ansiElements = new HashMap<>(); + ansiElements.put("faint", AnsiStyle.FAINT); + ansiElements.put("red", AnsiColor.RED); + ansiElements.put("green", AnsiColor.GREEN); + ansiElements.put("yellow", AnsiColor.YELLOW); + ansiElements.put("blue", AnsiColor.BLUE); + ansiElements.put("magenta", AnsiColor.MAGENTA); + ansiElements.put("cyan", AnsiColor.CYAN); + ELEMENTS = Collections.unmodifiableMap(ansiElements); + } + + @Override + protected String transform(ILoggingEvent event, String in) { + AnsiElement element = ELEMENTS.get(getFirstOption()); + List markers = event.getMarkerList(); + if ((markers != null && !markers.isEmpty() && markers.get(0).contains(CRLF_SAFE_MARKER)) || isLoggerSafe(event)) { + return in; + } + String replacement = element == null ? "_" : toAnsiString("_", element); + return in.replaceAll("[\n\r\t]", replacement); + } + + protected boolean isLoggerSafe(ILoggingEvent event) { + for (String safeLogger : SAFE_LOGGERS) { + if (event.getLoggerName().startsWith(safeLogger)) { + return true; + } + } + return false; + } + + protected String toAnsiString(String in, AnsiElement element) { + return AnsiOutput.toString(element, in); + } +} diff --git a/src/main/java/org/mskcc/oncokb/transcript/config/CacheConfiguration.java b/src/main/java/org/mskcc/oncokb/curation/config/CacheConfiguration.java similarity index 79% rename from src/main/java/org/mskcc/oncokb/transcript/config/CacheConfiguration.java rename to src/main/java/org/mskcc/oncokb/curation/config/CacheConfiguration.java index 0adde66cd..f8c37a93c 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/config/CacheConfiguration.java +++ b/src/main/java/org/mskcc/oncokb/curation/config/CacheConfiguration.java @@ -1,11 +1,12 @@ -package org.mskcc.oncokb.transcript.config; +package org.mskcc.oncokb.curation.config; import java.util.concurrent.TimeUnit; import javax.cache.configuration.MutableConfiguration; import javax.cache.expiry.CreatedExpiryPolicy; import javax.cache.expiry.Duration; +import org.mskcc.oncokb.curation.config.application.ApplicationProperties; +import org.mskcc.oncokb.curation.config.cache.*; import org.mskcc.oncokb.meta.enumeration.RedisType; -import org.mskcc.oncokb.transcript.config.cache.*; import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.Config; @@ -37,6 +38,8 @@ public class CacheConfiguration extends CachingConfigurerSupport { public RedissonClient redissonClient(org.mskcc.oncokb.meta.model.application.ApplicationProperties applicationProperties) throws Exception { Config config = new Config(); + // Fix Hibernate lazy initialization https://github.com/jhipster/generator-jhipster/issues/22889 + config.setCodec(new org.redisson.codec.SerializationCodec()); if (applicationProperties.getRedis().getType().equals(RedisType.SINGLE.getType())) { config .useSingleServer() @@ -111,6 +114,8 @@ public JCacheManagerCustomizer cacheManagerCustomizer( createCache(cm, CacheCategory.GENE, CacheKeys.GENES_BY_ENTREZ_GENE_ID, jcacheConfiguration, cacheNameResolver); createCache(cm, CacheCategory.GENE, CacheKeys.GENES_BY_HUGO_SYMBOL, jcacheConfiguration, cacheNameResolver); createCache(cm, CacheCategory.GENE, CacheKeys.GENE_ALIASES_BY_NAME, jcacheConfiguration, cacheNameResolver); + createCache(cm, CacheCategory.USER, CacheKeys.USERS_BY_LOGIN_CACHE, jcacheConfiguration, cacheNameResolver); + createCache(cm, CacheCategory.USER, CacheKeys.USERS_BY_EMAIL_CACHE, jcacheConfiguration, cacheNameResolver); createCache( cm, CacheCategory.TRANSCRIPT, @@ -118,7 +123,15 @@ public JCacheManagerCustomizer cacheManagerCustomizer( jcacheConfiguration, cacheNameResolver ); - // jhipster-needle-redis-add-entry + createCache( + cm, + CacheCategory.TRANSCRIPT, + CacheKeys.TRANSCRIPTS_BY_ENSEMBL_GENE_CANONICAL, + jcacheConfiguration, + cacheNameResolver + ); + createCache(cm, CacheCategory.SEQUENCE, CacheKeys.SEQUENCE_BY_TRASCRIPT_AND_TYPE, jcacheConfiguration, cacheNameResolver); + createCache(cm, CacheCategory.DRUG, CacheKeys.DRUGS_ALL, jcacheConfiguration, cacheNameResolver); }; } @@ -131,6 +144,15 @@ public CacheResolver geneCacheResolver( return new GeneCacheResolver(cm, applicationProperties, cacheNameResolver); } + @Bean + public CacheResolver userCacheResolver( + CacheManager cm, + ApplicationProperties applicationProperties, + CacheNameResolver cacheNameResolver + ) { + return new UserCacheResolver(cm, applicationProperties, cacheNameResolver); + } + @Bean public CacheResolver transcriptCacheResolver( CacheManager cm, @@ -140,6 +162,20 @@ public CacheResolver transcriptCacheResolver( return new TranscriptCacheResolver(cm, applicationProperties, cacheNameResolver); } + @Bean + public CacheResolver sequenceCacheResolver( + CacheManager cm, + ApplicationProperties applicationProperties, + CacheNameResolver cacheNameResolver + ) { + return new SequenceCacheResolver(cm, applicationProperties, cacheNameResolver); + } + + @Bean + public CacheResolver drugCacheResolver(CacheManager cm, CacheNameResolver cacheNameResolver) { + return new DrugCacheResolver(cm, cacheNameResolver); + } + @Autowired(required = false) public void setGitProperties(GitProperties gitProperties) { this.gitProperties = gitProperties; diff --git a/src/main/java/org/mskcc/oncokb/curation/config/Constants.java b/src/main/java/org/mskcc/oncokb/curation/config/Constants.java new file mode 100644 index 000000000..34c461b95 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/config/Constants.java @@ -0,0 +1,26 @@ +package org.mskcc.oncokb.curation.config; + +/** + * Application constants. + */ +public final class Constants { + + // Regex for acceptable logins + public static final String LOGIN_REGEX = "^(?>[a-zA-Z0-9!$&*+=?^_`{|}~.-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*)|(?>[_.@A-Za-z0-9-]+)$"; + + public static final String SYSTEM = "system"; + public static final Integer ENSEMBL_POST_THRESHOLD = 100; + public static final String DEFAULT_LANGUAGE = "en"; + + // Firebase authentication custom token key + public static final String FIREBASE_CUSTOM_TOKEN = "firebaseCustomToken"; + // Name of additional JWT claim added for authorization to firebase. + public static final String FIREBASE_AUTHORIZED_CLAIM = "firebaseAuthorizedUser"; + + public static final String NY_ZONE_ID = "US/Eastern"; + public static final String UTC_ZONE_ID = "UTC"; + + public static final String DEFAULT_GENE_SYNONMN_SOURCE = "cBioPortal"; + + private Constants() {} +} diff --git a/src/main/java/org/mskcc/oncokb/curation/config/DataVersions.java b/src/main/java/org/mskcc/oncokb/curation/config/DataVersions.java new file mode 100644 index 000000000..a14991e35 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/config/DataVersions.java @@ -0,0 +1,12 @@ +package org.mskcc.oncokb.curation.config; + +/** + * Data versions used by application. + */ +public final class DataVersions { + + public static final String NCIT_VERSION = "23.11d"; + public static final String ONCOKB_CORE_VERSION = "v4.13"; + + private DataVersions() {} +} diff --git a/src/main/java/org/mskcc/oncokb/curation/config/DatabaseConfiguration.java b/src/main/java/org/mskcc/oncokb/curation/config/DatabaseConfiguration.java new file mode 100644 index 000000000..2eb5526a7 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/config/DatabaseConfiguration.java @@ -0,0 +1,12 @@ +package org.mskcc.oncokb.curation.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@Configuration +@EnableJpaRepositories("org.mskcc.oncokb.curation.repository") +@EnableJpaAuditing(auditorAwareRef = "springSecurityAuditorAware") +@EnableTransactionManagement +public class DatabaseConfiguration {} diff --git a/src/main/java/org/mskcc/oncokb/transcript/config/DateTimeFormatConfiguration.java b/src/main/java/org/mskcc/oncokb/curation/config/DateTimeFormatConfiguration.java similarity index 94% rename from src/main/java/org/mskcc/oncokb/transcript/config/DateTimeFormatConfiguration.java rename to src/main/java/org/mskcc/oncokb/curation/config/DateTimeFormatConfiguration.java index 3bbc53840..fae20fcf4 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/config/DateTimeFormatConfiguration.java +++ b/src/main/java/org/mskcc/oncokb/curation/config/DateTimeFormatConfiguration.java @@ -1,4 +1,4 @@ -package org.mskcc.oncokb.transcript.config; +package org.mskcc.oncokb.curation.config; import org.springframework.context.annotation.Configuration; import org.springframework.format.FormatterRegistry; diff --git a/src/main/java/org/mskcc/oncokb/curation/config/InstantTypeAdapter.java b/src/main/java/org/mskcc/oncokb/curation/config/InstantTypeAdapter.java new file mode 100644 index 000000000..04d8c2b95 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/config/InstantTypeAdapter.java @@ -0,0 +1,29 @@ +package org.mskcc.oncokb.curation.config; + +import com.google.gson.*; +import java.lang.reflect.Type; +import java.time.Instant; + +public class InstantTypeAdapter implements JsonSerializer, JsonDeserializer { + + @Override + public Instant deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) { + if (json.isJsonPrimitive()) { + // Handle the ISO 8601 string format + return Instant.parse(json.getAsString()); + } else if (json.isJsonObject()) { + // Handle the {"seconds":..., "nanos":...} object format + JsonObject jsonObject = json.getAsJsonObject(); + long seconds = jsonObject.get("seconds").getAsLong(); + int nanos = jsonObject.get("nanos").getAsInt(); + return Instant.ofEpochSecond(seconds, nanos); + } else { + throw new JsonParseException("Unexpected JSON type: " + json.getClass().getSimpleName()); + } + } + + @Override + public JsonElement serialize(Instant instant, Type type, JsonSerializationContext JsonDeserializationContext) { + return new JsonPrimitive(instant.toString()); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/config/JacksonConfiguration.java b/src/main/java/org/mskcc/oncokb/curation/config/JacksonConfiguration.java new file mode 100644 index 000000000..708da68fe --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/config/JacksonConfiguration.java @@ -0,0 +1,34 @@ +package org.mskcc.oncokb.curation.config; + +import com.fasterxml.jackson.datatype.hibernate6.Hibernate6Module; +import com.fasterxml.jackson.datatype.hibernate6.Hibernate6Module.Feature; +import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class JacksonConfiguration { + + /** + * Support for Java date and time API. + * @return the corresponding Jackson module. + */ + @Bean + public JavaTimeModule javaTimeModule() { + return new JavaTimeModule(); + } + + @Bean + public Jdk8Module jdk8TimeModule() { + return new Jdk8Module(); + } + + /* + * Support for Hibernate types in Jackson. + */ + @Bean + public Hibernate6Module hibernate6Module() { + return new Hibernate6Module().configure(Feature.SERIALIZE_IDENTIFIER_FOR_LAZY_NOT_LOADED_OBJECTS, true); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/config/LiquibaseConfiguration.java b/src/main/java/org/mskcc/oncokb/curation/config/LiquibaseConfiguration.java new file mode 100644 index 000000000..6e05e70de --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/config/LiquibaseConfiguration.java @@ -0,0 +1,81 @@ +package org.mskcc.oncokb.curation.config; + +import java.util.concurrent.Executor; +import javax.sql.DataSource; +import liquibase.integration.spring.SpringLiquibase; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; +import org.springframework.boot.autoconfigure.liquibase.LiquibaseDataSource; +import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.core.env.Profiles; +import tech.jhipster.config.JHipsterConstants; +import tech.jhipster.config.liquibase.SpringLiquibaseUtil; + +@Configuration +public class LiquibaseConfiguration { + + private final Logger log = LoggerFactory.getLogger(LiquibaseConfiguration.class); + + private final Environment env; + + public LiquibaseConfiguration(Environment env) { + this.env = env; + } + + @Value("${application.liquibase.async-start:true}") + private Boolean asyncStart; + + @Bean + public SpringLiquibase liquibase( + @Qualifier("taskExecutor") Executor executor, + LiquibaseProperties liquibaseProperties, + @LiquibaseDataSource ObjectProvider liquibaseDataSource, + ObjectProvider dataSource, + DataSourceProperties dataSourceProperties + ) { + SpringLiquibase liquibase; + if (Boolean.TRUE.equals(asyncStart)) { + liquibase = SpringLiquibaseUtil.createAsyncSpringLiquibase( + this.env, + executor, + liquibaseDataSource.getIfAvailable(), + liquibaseProperties, + dataSource.getIfUnique(), + dataSourceProperties + ); + } else { + liquibase = SpringLiquibaseUtil.createSpringLiquibase( + liquibaseDataSource.getIfAvailable(), + liquibaseProperties, + dataSource.getIfUnique(), + dataSourceProperties + ); + } + liquibase.setChangeLog("classpath:config/liquibase/master.xml"); + liquibase.setContexts(liquibaseProperties.getContexts()); + liquibase.setDefaultSchema(liquibaseProperties.getDefaultSchema()); + liquibase.setLiquibaseSchema(liquibaseProperties.getLiquibaseSchema()); + liquibase.setLiquibaseTablespace(liquibaseProperties.getLiquibaseTablespace()); + liquibase.setDatabaseChangeLogLockTable(liquibaseProperties.getDatabaseChangeLogLockTable()); + liquibase.setDatabaseChangeLogTable(liquibaseProperties.getDatabaseChangeLogTable()); + liquibase.setDropFirst(liquibaseProperties.isDropFirst()); + liquibase.setLabelFilter(liquibaseProperties.getLabelFilter()); + liquibase.setChangeLogParameters(liquibaseProperties.getParameters()); + liquibase.setRollbackFile(liquibaseProperties.getRollbackFile()); + liquibase.setTestRollbackOnUpdate(liquibaseProperties.isTestRollbackOnUpdate()); + if (env.acceptsProfiles(Profiles.of(JHipsterConstants.SPRING_PROFILE_NO_LIQUIBASE))) { + liquibase.setShouldRun(false); + } else { + liquibase.setShouldRun(liquibaseProperties.isEnabled()); + log.debug("Configuring Liquibase"); + } + return liquibase; + } +} diff --git a/src/main/java/org/mskcc/oncokb/transcript/config/LoggingAspectConfiguration.java b/src/main/java/org/mskcc/oncokb/curation/config/LoggingAspectConfiguration.java similarity index 79% rename from src/main/java/org/mskcc/oncokb/transcript/config/LoggingAspectConfiguration.java rename to src/main/java/org/mskcc/oncokb/curation/config/LoggingAspectConfiguration.java index d88cc6b53..ea832e7f3 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/config/LoggingAspectConfiguration.java +++ b/src/main/java/org/mskcc/oncokb/curation/config/LoggingAspectConfiguration.java @@ -1,6 +1,6 @@ -package org.mskcc.oncokb.transcript.config; +package org.mskcc.oncokb.curation.config; -import org.mskcc.oncokb.transcript.aop.logging.LoggingAspect; +import org.mskcc.oncokb.curation.aop.logging.LoggingAspect; import org.springframework.context.annotation.*; import org.springframework.core.env.Environment; import tech.jhipster.config.JHipsterConstants; diff --git a/src/main/java/org/mskcc/oncokb/transcript/config/LoggingConfiguration.java b/src/main/java/org/mskcc/oncokb/curation/config/LoggingConfiguration.java similarity index 97% rename from src/main/java/org/mskcc/oncokb/transcript/config/LoggingConfiguration.java rename to src/main/java/org/mskcc/oncokb/curation/config/LoggingConfiguration.java index fbe264335..04744a633 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/config/LoggingConfiguration.java +++ b/src/main/java/org/mskcc/oncokb/curation/config/LoggingConfiguration.java @@ -1,4 +1,4 @@ -package org.mskcc.oncokb.transcript.config; +package org.mskcc.oncokb.curation.config; import static tech.jhipster.config.logging.LoggingUtils.*; diff --git a/src/main/java/org/mskcc/oncokb/curation/config/OAuth2Configuration.java b/src/main/java/org/mskcc/oncokb/curation/config/OAuth2Configuration.java new file mode 100644 index 000000000..98b0f713e --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/config/OAuth2Configuration.java @@ -0,0 +1,41 @@ +package org.mskcc.oncokb.curation.config; + +import java.time.Duration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager; +import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProviderBuilder; +import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; +import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizedClientManager; +import org.springframework.security.oauth2.client.web.HttpSessionOAuth2AuthorizedClientRepository; +import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository; + +@Configuration +public class OAuth2Configuration { + + @Bean + public OAuth2AuthorizedClientRepository authorizedClientRepository() { + return new HttpSessionOAuth2AuthorizedClientRepository(); + } + + @Bean + public OAuth2AuthorizedClientManager authorizedClientManager( + ClientRegistrationRepository clientRegistrationRepository, + OAuth2AuthorizedClientRepository authorizedClientRepository + ) { + DefaultOAuth2AuthorizedClientManager authorizedClientManager = new DefaultOAuth2AuthorizedClientManager( + clientRegistrationRepository, + authorizedClientRepository + ); + + authorizedClientManager.setAuthorizedClientProvider( + OAuth2AuthorizedClientProviderBuilder.builder() + .authorizationCode() + .refreshToken(builder -> builder.clockSkew(Duration.ofMinutes(1))) + .clientCredentials() + .build() + ); + + return authorizedClientManager; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/config/RedirectConfiguration.java b/src/main/java/org/mskcc/oncokb/curation/config/RedirectConfiguration.java new file mode 100644 index 000000000..49352a0c6 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/config/RedirectConfiguration.java @@ -0,0 +1,26 @@ +package org.mskcc.oncokb.curation.config; + +import org.springframework.boot.web.server.ErrorPage; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpStatus; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class RedirectConfiguration implements WebMvcConfigurer { + + @Override + public void addViewControllers(ViewControllerRegistry registry) { + registry.addViewController("/notFound").setViewName("forward:/"); + } + + @Bean + public WebServerFactoryCustomizer containerCustomizer() { + return container -> { + container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/notFound")); + }; + } +} diff --git a/src/main/java/org/mskcc/oncokb/transcript/config/StaticResourcesWebConfiguration.java b/src/main/java/org/mskcc/oncokb/curation/config/StaticResourcesWebConfiguration.java similarity index 98% rename from src/main/java/org/mskcc/oncokb/transcript/config/StaticResourcesWebConfiguration.java rename to src/main/java/org/mskcc/oncokb/curation/config/StaticResourcesWebConfiguration.java index c8804f4d2..8846d0d92 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/config/StaticResourcesWebConfiguration.java +++ b/src/main/java/org/mskcc/oncokb/curation/config/StaticResourcesWebConfiguration.java @@ -1,4 +1,4 @@ -package org.mskcc.oncokb.transcript.config; +package org.mskcc.oncokb.curation.config; import java.util.concurrent.TimeUnit; import org.springframework.context.annotation.Configuration; diff --git a/src/main/java/org/mskcc/oncokb/curation/config/ThymeleafConfig.java b/src/main/java/org/mskcc/oncokb/curation/config/ThymeleafConfig.java new file mode 100644 index 000000000..51bb4a393 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/config/ThymeleafConfig.java @@ -0,0 +1,47 @@ +package org.mskcc.oncokb.curation.config; + +import java.util.HashSet; +import java.util.Set; +import javax.annotation.PostConstruct; +import org.springframework.context.annotation.Configuration; +import org.thymeleaf.spring6.SpringTemplateEngine; +import org.thymeleaf.templatemode.TemplateMode; +import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver; +import org.thymeleaf.templateresolver.ITemplateResolver; + +@Configuration +public class ThymeleafConfig { + + public static final String STRING_ENCODING = "UTF-8"; + + private SpringTemplateEngine templateEngine; + + /* ******************************************************************** */ + /* THYMELEAF-SPECIFIC ARTIFACTS */ + /* TemplateResolver(3) <- TemplateEngine */ + /* ******************************************************************** */ + + public ThymeleafConfig(SpringTemplateEngine templateEngine) { + this.templateEngine = templateEngine; + } + + @PostConstruct + public void extension() { + // Adding resolves with resolvable patters + templateEngine.addTemplateResolver(indexTemplateResolver()); + } + + private ITemplateResolver indexTemplateResolver() { + final ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver(); + templateResolver.setOrder(Integer.valueOf(1)); + templateResolver.setPrefix("/static/"); + Set patterns = new HashSet<>(); + patterns.add("index"); + templateResolver.setResolvablePatterns(patterns); + templateResolver.setSuffix(".html"); + templateResolver.setTemplateMode(TemplateMode.HTML); + templateResolver.setCharacterEncoding(STRING_ENCODING); + templateResolver.setCacheable(false); + return templateResolver; + } +} diff --git a/src/main/java/org/mskcc/oncokb/transcript/config/WebConfigurer.java b/src/main/java/org/mskcc/oncokb/curation/config/WebConfigurer.java similarity index 87% rename from src/main/java/org/mskcc/oncokb/transcript/config/WebConfigurer.java rename to src/main/java/org/mskcc/oncokb/curation/config/WebConfigurer.java index 8147ed11d..0be83d4df 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/config/WebConfigurer.java +++ b/src/main/java/org/mskcc/oncokb/curation/config/WebConfigurer.java @@ -1,12 +1,11 @@ -package org.mskcc.oncokb.transcript.config; +package org.mskcc.oncokb.curation.config; import static java.net.URLDecoder.decode; +import jakarta.servlet.*; import java.io.File; import java.nio.charset.StandardCharsets; import java.nio.file.Paths; -import java.util.*; -import javax.servlet.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.web.server.*; @@ -15,12 +14,10 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; -import org.springframework.core.env.Profiles; import org.springframework.util.CollectionUtils; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; -import tech.jhipster.config.JHipsterConstants; import tech.jhipster.config.JHipsterProperties; /** @@ -41,7 +38,7 @@ public WebConfigurer(Environment env, JHipsterProperties jHipsterProperties) { } @Override - public void onStartup(ServletContext servletContext) throws ServletException { + public void onStartup(ServletContext servletContext) { if (env.getActiveProfiles().length != 0) { log.info("Web application configuration, using profiles: {}", (Object[]) env.getActiveProfiles()); } @@ -59,8 +56,7 @@ public void customize(WebServerFactory server) { } private void setLocationForStaticAssets(WebServerFactory server) { - if (server instanceof ConfigurableServletWebServerFactory) { - ConfigurableServletWebServerFactory servletWebServer = (ConfigurableServletWebServerFactory) server; + if (server instanceof ConfigurableServletWebServerFactory servletWebServer) { File root; String prefixPath = resolvePathPrefix(); root = new File(prefixPath + "target/classes/static/"); @@ -92,9 +88,7 @@ public CorsFilter corsFilter() { log.debug("Registering CORS filter"); source.registerCorsConfiguration("/api/**", config); source.registerCorsConfiguration("/management/**", config); - source.registerCorsConfiguration("/v2/api-docs", config); source.registerCorsConfiguration("/v3/api-docs", config); - source.registerCorsConfiguration("/swagger-resources", config); source.registerCorsConfiguration("/swagger-ui/**", config); } return new CorsFilter(source); diff --git a/src/main/java/org/mskcc/oncokb/curation/config/WebSocketConfiguration.java b/src/main/java/org/mskcc/oncokb/curation/config/WebSocketConfiguration.java new file mode 100644 index 000000000..6b585ce74 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/config/WebSocketConfiguration.java @@ -0,0 +1,40 @@ +package org.mskcc.oncokb.curation.config; + +import java.util.List; +import org.mskcc.oncokb.curation.config.application.ApplicationProperties; +import org.mskcc.oncokb.curation.web.websocket.ProxyWebSocketHandler; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.config.annotation.EnableWebSocket; +import org.springframework.web.socket.config.annotation.WebSocketConfigurer; +import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; +import tech.jhipster.config.JHipsterProperties; + +@Configuration +@EnableWebSocket +public class WebSocketConfiguration implements WebSocketConfigurer { + + private JHipsterProperties jHipsterProperties; + private ApplicationProperties applicationProperties; + + @Autowired + public void setJHipsterProperties(JHipsterProperties jHipsterProperties) { + this.jHipsterProperties = jHipsterProperties; + } + + @Autowired + public void setJHipsterProperties(ApplicationProperties applicationProperties) { + this.applicationProperties = applicationProperties; + } + + // @Override + public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { + var handler = registry.addHandler(new ProxyWebSocketHandler(this.applicationProperties), "/websocket/**"); + + List allowOrigins = jHipsterProperties.getCors().getAllowedOrigins(); + + if (allowOrigins != null) { + handler.setAllowedOrigins(allowOrigins.toArray(new String[0])); + } + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/config/application/ApplicationProperties.java b/src/main/java/org/mskcc/oncokb/curation/config/application/ApplicationProperties.java new file mode 100644 index 000000000..b401a3be0 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/config/application/ApplicationProperties.java @@ -0,0 +1,75 @@ +package org.mskcc.oncokb.curation.config.application; + +import org.mskcc.oncokb.curation.config.model.OncoKbConfig; +import org.mskcc.oncokb.curation.config.model.OncoKbCoreConfig; +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * Properties specific to OncoKB Curation. + *

+ * Properties are configured in the {@code application.yml} file. + * See {@link tech.jhipster.config.JHipsterProperties} for a good example. + */ +@ConfigurationProperties(prefix = "application", ignoreUnknownFields = false) +public class ApplicationProperties extends org.mskcc.oncokb.meta.model.application.ApplicationProperties { + + private OncoKbConfig oncokb; + + private FrontendProperties frontend; + + private FirebaseProperties firebase; + + private String oncokbDataRepoDir; + + private OncoKbCoreConfig oncokbCore; + + private String nihEutilsToken; + + public OncoKbCoreConfig getOncokbCore() { + return oncokbCore; + } + + public void setOncokbCore(OncoKbCoreConfig oncokbCore) { + this.oncokbCore = oncokbCore; + } + + public OncoKbConfig getOncokb() { + return oncokb; + } + + public void setOncokb(OncoKbConfig oncokb) { + this.oncokb = oncokb; + } + + public FrontendProperties getFrontend() { + return this.frontend; + } + + public void setFrontend(FrontendProperties frontend) { + this.frontend = frontend; + } + + public FirebaseProperties getFirebase() { + return this.firebase; + } + + public void setFirebase(FirebaseProperties firebase) { + this.firebase = firebase; + } + + public String getOncokbDataRepoDir() { + return oncokbDataRepoDir; + } + + public void setOncokbDataRepoDir(String oncokbDataRepoDir) { + this.oncokbDataRepoDir = oncokbDataRepoDir; + } + + public String getNihEutilsToken() { + return nihEutilsToken; + } + + public void setNihEutilsToken(String nihEutilsToken) { + this.nihEutilsToken = nihEutilsToken; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/config/application/FirebaseProperties.java b/src/main/java/org/mskcc/oncokb/curation/config/application/FirebaseProperties.java new file mode 100644 index 000000000..1008abd63 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/config/application/FirebaseProperties.java @@ -0,0 +1,104 @@ +package org.mskcc.oncokb.curation.config.application; + +public class FirebaseProperties { + + private Boolean enabled = false; + + private String apiKey; + + private String authDomain; + + private String databaseUrl; + + private String projectId; + + private String storageBucket; + + private String messagingSenderId; + + private String appId; + + private String measurementId; + + private String serviceAccountCredentialsPath; + + public Boolean isEnabled() { + return this.enabled; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + public String getApiKey() { + return this.apiKey; + } + + public void setApiKey(String apiKey) { + this.apiKey = apiKey; + } + + public String getAuthDomain() { + return this.authDomain; + } + + public void setAuthDomain(String authDomain) { + this.authDomain = authDomain; + } + + public String getDatabaseUrl() { + return this.databaseUrl; + } + + public void setDatabaseUrl(String databaseUrl) { + this.databaseUrl = databaseUrl; + } + + public String getProjectId() { + return this.projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getStorageBucket() { + return this.storageBucket; + } + + public void setStorageBucket(String storageBucket) { + this.storageBucket = storageBucket; + } + + public String getMessagingSenderId() { + return this.messagingSenderId; + } + + public void setMessagingSenderId(String messagingSenderId) { + this.messagingSenderId = messagingSenderId; + } + + public String getAppId() { + return this.appId; + } + + public void setAppId(String appId) { + this.appId = appId; + } + + public String getMeasurementId() { + return this.measurementId; + } + + public void setMeasurementId(String measurementId) { + this.measurementId = measurementId; + } + + public String getServiceAccountCredentialsPath() { + return this.serviceAccountCredentialsPath; + } + + public void setServiceAccountCredentialsPath(String serviceAccountCredentialsPath) { + this.serviceAccountCredentialsPath = serviceAccountCredentialsPath; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/config/application/FrontendProperties.java b/src/main/java/org/mskcc/oncokb/curation/config/application/FrontendProperties.java new file mode 100644 index 000000000..0ccbc1cf2 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/config/application/FrontendProperties.java @@ -0,0 +1,34 @@ +package org.mskcc.oncokb.curation.config.application; + +public class FrontendProperties { + + private FirebaseProperties firebase; + + public FirebaseProperties getFirebase() { + return this.firebase; + } + + public void setFirebase(FirebaseProperties firebase) { + this.firebase = firebase; + } + + private String sentryDsn; + + public String getSentryDsn() { + return sentryDsn; + } + + public void setSentryDsn(String sentryDsn) { + this.sentryDsn = sentryDsn; + } + + private Boolean stopReviewIfCoreSubmissionFails; + + public Boolean getStopReviewIfCoreSubmissionFails() { + return stopReviewIfCoreSubmissionFails; + } + + public void setStopReviewIfCoreSubmissionFails(Boolean stopReviewIfCoreSubmissionFails) { + this.stopReviewIfCoreSubmissionFails = stopReviewIfCoreSubmissionFails; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/config/cache/CacheCategory.java b/src/main/java/org/mskcc/oncokb/curation/config/cache/CacheCategory.java new file mode 100644 index 000000000..cd328d2b1 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/config/cache/CacheCategory.java @@ -0,0 +1,9 @@ +package org.mskcc.oncokb.curation.config.cache; + +public enum CacheCategory { + GENE, + TRANSCRIPT, + USER, + SEQUENCE, + DRUG, +} diff --git a/src/main/java/org/mskcc/oncokb/curation/config/cache/CacheKeys.java b/src/main/java/org/mskcc/oncokb/curation/config/cache/CacheKeys.java new file mode 100644 index 000000000..046ad5a50 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/config/cache/CacheKeys.java @@ -0,0 +1,17 @@ +package org.mskcc.oncokb.curation.config.cache; + +public final class CacheKeys { + + public static final String GENES_BY_ENTREZ_GENE_ID = "genesByEntrezGeneId"; + public static final String GENES_BY_HUGO_SYMBOL = "genesByHugoSymbol"; + public static final String GENE_ALIASES_BY_NAME = "geneAliasesByName"; + + public static final String USERS_BY_LOGIN_CACHE = "usersByLogin"; + public static final String USERS_BY_EMAIL_CACHE = "usersByEmail"; + + public static final String TRANSCRIPTS_BY_ENSEMBL_TRANSCRIPT_IDS = "findByReferenceGenomeAndEnsemblTranscriptIdIsIn"; + public static final String TRANSCRIPTS_BY_ENSEMBL_GENE_CANONICAL = "findByEnsemblGeneAndCanonicalIsTrue"; + public static final String SEQUENCE_BY_TRASCRIPT_AND_TYPE = "findOneByTranscriptAndSequenceType"; + + public static final String DRUGS_ALL = "findAll"; +} diff --git a/src/main/java/org/mskcc/oncokb/curation/config/cache/CacheNameResolver.java b/src/main/java/org/mskcc/oncokb/curation/config/cache/CacheNameResolver.java new file mode 100644 index 000000000..dd0709029 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/config/cache/CacheNameResolver.java @@ -0,0 +1,37 @@ +package org.mskcc.oncokb.curation.config.cache; + +import org.mskcc.oncokb.curation.config.application.ApplicationProperties; +import org.springframework.stereotype.Component; + +@Component +public class CacheNameResolver { + + private final ApplicationProperties applicationProperties; + + private final Liquibase liquibase = new Liquibase(); + + public Liquibase getLiquibase() { + return liquibase; + } + + public static class Liquibase { + + private Boolean asyncStart; + + public Boolean getAsyncStart() { + return asyncStart; + } + + public void setAsyncStart(Boolean asyncStart) { + this.asyncStart = asyncStart; + } + } + + public CacheNameResolver(ApplicationProperties applicationProperties) { + this.applicationProperties = applicationProperties; + } + + public String getCacheName(CacheCategory cacheCategory, String cacheKey) { + return applicationProperties.getName() + "-" + cacheCategory + "-" + cacheKey; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/config/cache/DrugCacheResolver.java b/src/main/java/org/mskcc/oncokb/curation/config/cache/DrugCacheResolver.java new file mode 100644 index 000000000..ff1a41edd --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/config/cache/DrugCacheResolver.java @@ -0,0 +1,29 @@ +package org.mskcc.oncokb.curation.config.cache; + +import java.util.ArrayList; +import java.util.Collection; +import org.springframework.cache.Cache; +import org.springframework.cache.CacheManager; +import org.springframework.cache.interceptor.CacheOperationInvocationContext; +import org.springframework.cache.interceptor.CacheResolver; + +public class DrugCacheResolver implements CacheResolver { + + private final CacheManager cacheManager; + private final CacheNameResolver cacheNameResolver; + + public DrugCacheResolver(CacheManager cacheManager, CacheNameResolver cacheNameResolver) { + this.cacheManager = cacheManager; + this.cacheNameResolver = cacheNameResolver; + } + + @Override + public Collection resolveCaches(CacheOperationInvocationContext context) { + Collection caches = new ArrayList<>(); + + if (context.getMethod().getName() == "findAll") { + caches.add(cacheManager.getCache(this.cacheNameResolver.getCacheName(CacheCategory.DRUG, CacheKeys.DRUGS_ALL))); + } + return caches; + } +} diff --git a/src/main/java/org/mskcc/oncokb/transcript/config/cache/GeneCacheResolver.java b/src/main/java/org/mskcc/oncokb/curation/config/cache/GeneCacheResolver.java similarity index 93% rename from src/main/java/org/mskcc/oncokb/transcript/config/cache/GeneCacheResolver.java rename to src/main/java/org/mskcc/oncokb/curation/config/cache/GeneCacheResolver.java index bd4fe7962..c3bf80231 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/config/cache/GeneCacheResolver.java +++ b/src/main/java/org/mskcc/oncokb/curation/config/cache/GeneCacheResolver.java @@ -1,8 +1,8 @@ -package org.mskcc.oncokb.transcript.config.cache; +package org.mskcc.oncokb.curation.config.cache; import java.util.ArrayList; import java.util.Collection; -import org.mskcc.oncokb.transcript.config.ApplicationProperties; +import org.mskcc.oncokb.curation.config.application.ApplicationProperties; import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; import org.springframework.cache.interceptor.CacheOperationInvocationContext; diff --git a/src/main/java/org/mskcc/oncokb/transcript/config/cache/LoggingCacheErrorHandler.java b/src/main/java/org/mskcc/oncokb/curation/config/cache/LoggingCacheErrorHandler.java similarity index 97% rename from src/main/java/org/mskcc/oncokb/transcript/config/cache/LoggingCacheErrorHandler.java rename to src/main/java/org/mskcc/oncokb/curation/config/cache/LoggingCacheErrorHandler.java index 25a2944d3..9b16542e7 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/config/cache/LoggingCacheErrorHandler.java +++ b/src/main/java/org/mskcc/oncokb/curation/config/cache/LoggingCacheErrorHandler.java @@ -1,4 +1,4 @@ -package org.mskcc.oncokb.transcript.config.cache; +package org.mskcc.oncokb.curation.config.cache; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/mskcc/oncokb/curation/config/cache/SequenceCacheResolver.java b/src/main/java/org/mskcc/oncokb/curation/config/cache/SequenceCacheResolver.java new file mode 100644 index 000000000..cda75322b --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/config/cache/SequenceCacheResolver.java @@ -0,0 +1,39 @@ +package org.mskcc.oncokb.curation.config.cache; + +import java.util.ArrayList; +import java.util.Collection; +import org.mskcc.oncokb.curation.config.application.ApplicationProperties; +import org.springframework.cache.Cache; +import org.springframework.cache.CacheManager; +import org.springframework.cache.interceptor.CacheOperationInvocationContext; +import org.springframework.cache.interceptor.CacheResolver; + +public class SequenceCacheResolver implements CacheResolver { + + private final ApplicationProperties applicationProperties; + private final CacheManager cacheManager; + private final CacheNameResolver cacheNameResolver; + + public SequenceCacheResolver( + CacheManager cacheManager, + ApplicationProperties applicationProperties, + CacheNameResolver cacheNameResolver + ) { + this.cacheManager = cacheManager; + this.applicationProperties = applicationProperties; + this.cacheNameResolver = cacheNameResolver; + } + + @Override + public Collection resolveCaches(CacheOperationInvocationContext context) { + Collection caches = new ArrayList<>(); + + if (context.getMethod().getName() == "findOneByTranscriptAndSequenceType") { + caches.add( + cacheManager.getCache(this.cacheNameResolver.getCacheName(CacheCategory.SEQUENCE, CacheKeys.SEQUENCE_BY_TRASCRIPT_AND_TYPE)) + ); + } + + return caches; + } +} diff --git a/src/main/java/org/mskcc/oncokb/transcript/config/cache/TranscriptCacheResolver.java b/src/main/java/org/mskcc/oncokb/curation/config/cache/TranscriptCacheResolver.java similarity index 75% rename from src/main/java/org/mskcc/oncokb/transcript/config/cache/TranscriptCacheResolver.java rename to src/main/java/org/mskcc/oncokb/curation/config/cache/TranscriptCacheResolver.java index cb6f8ece8..6317b292e 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/config/cache/TranscriptCacheResolver.java +++ b/src/main/java/org/mskcc/oncokb/curation/config/cache/TranscriptCacheResolver.java @@ -1,8 +1,8 @@ -package org.mskcc.oncokb.transcript.config.cache; +package org.mskcc.oncokb.curation.config.cache; import java.util.ArrayList; import java.util.Collection; -import org.mskcc.oncokb.transcript.config.ApplicationProperties; +import org.mskcc.oncokb.curation.config.application.ApplicationProperties; import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; import org.springframework.cache.interceptor.CacheOperationInvocationContext; @@ -34,6 +34,12 @@ public Collection resolveCaches(CacheOperationInvocationContext this.cacheNameResolver.getCacheName(CacheCategory.TRANSCRIPT, CacheKeys.TRANSCRIPTS_BY_ENSEMBL_TRANSCRIPT_IDS) ) ); + } else if (context.getMethod().getName() == "findByEnsemblGeneAndCanonicalIsTrue") { + caches.add( + cacheManager.getCache( + this.cacheNameResolver.getCacheName(CacheCategory.TRANSCRIPT, CacheKeys.TRANSCRIPTS_BY_ENSEMBL_GENE_CANONICAL) + ) + ); } return caches; diff --git a/src/main/java/org/mskcc/oncokb/curation/config/cache/UserCacheResolver.java b/src/main/java/org/mskcc/oncokb/curation/config/cache/UserCacheResolver.java new file mode 100644 index 000000000..7784bf1f7 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/config/cache/UserCacheResolver.java @@ -0,0 +1,35 @@ +package org.mskcc.oncokb.curation.config.cache; + +import java.util.ArrayList; +import java.util.Collection; +import org.mskcc.oncokb.curation.config.application.ApplicationProperties; +import org.springframework.cache.Cache; +import org.springframework.cache.CacheManager; +import org.springframework.cache.interceptor.CacheOperationInvocationContext; +import org.springframework.cache.interceptor.CacheResolver; + +public class UserCacheResolver implements CacheResolver { + + private final ApplicationProperties applicationProperties; + private final CacheManager cacheManager; + private final CacheNameResolver cacheNameResolver; + + public UserCacheResolver(CacheManager cacheManager, ApplicationProperties applicationProperties, CacheNameResolver cacheNameResolver) { + this.cacheManager = cacheManager; + this.applicationProperties = applicationProperties; + this.cacheNameResolver = cacheNameResolver; + } + + @Override + public Collection resolveCaches(CacheOperationInvocationContext context) { + Collection caches = new ArrayList<>(); + + if (context.getMethod().getName() == "findOneWithAuthoritiesByLogin") { + caches.add(cacheManager.getCache(this.cacheNameResolver.getCacheName(CacheCategory.USER, CacheKeys.USERS_BY_LOGIN_CACHE))); + } else if (context.getMethod().getName() == "findOneWithAuthoritiesByEmailIgnoreCase") { + caches.add(cacheManager.getCache(this.cacheNameResolver.getCacheName(CacheCategory.USER, CacheKeys.USERS_BY_EMAIL_CACHE))); + } + + return caches; + } +} diff --git a/src/main/java/org/mskcc/oncokb/transcript/config/model/OncoKbConfig.java b/src/main/java/org/mskcc/oncokb/curation/config/model/OncoKbConfig.java similarity index 88% rename from src/main/java/org/mskcc/oncokb/transcript/config/model/OncoKbConfig.java rename to src/main/java/org/mskcc/oncokb/curation/config/model/OncoKbConfig.java index dde066713..d068df545 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/config/model/OncoKbConfig.java +++ b/src/main/java/org/mskcc/oncokb/curation/config/model/OncoKbConfig.java @@ -1,4 +1,4 @@ -package org.mskcc.oncokb.transcript.config.model; +package org.mskcc.oncokb.curation.config.model; /** * Created by Hongxin Zhang on 1/29/21. diff --git a/src/main/java/org/mskcc/oncokb/curation/config/model/OncoKbCoreConfig.java b/src/main/java/org/mskcc/oncokb/curation/config/model/OncoKbCoreConfig.java new file mode 100644 index 000000000..c0911248d --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/config/model/OncoKbCoreConfig.java @@ -0,0 +1,14 @@ +package org.mskcc.oncokb.curation.config.model; + +public class OncoKbCoreConfig { + + String url; + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/config/package-info.java b/src/main/java/org/mskcc/oncokb/curation/config/package-info.java new file mode 100644 index 000000000..0a2ea044c --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/config/package-info.java @@ -0,0 +1,4 @@ +/** + * Spring Framework configuration files. + */ +package org.mskcc.oncokb.curation.config; diff --git a/src/main/java/org/mskcc/oncokb/curation/config/security/SecurityConfigurationJWT.java b/src/main/java/org/mskcc/oncokb/curation/config/security/SecurityConfigurationJWT.java new file mode 100644 index 000000000..d930cba7e --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/config/security/SecurityConfigurationJWT.java @@ -0,0 +1,86 @@ +package org.mskcc.oncokb.curation.config.security; + +import static org.springframework.security.config.Customizer.withDefaults; + +import org.mskcc.oncokb.curation.security.jwt.JWTConfigurer; +import org.mskcc.oncokb.curation.security.jwt.JWTFilter; +import org.mskcc.oncokb.curation.security.jwt.TokenProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationEntryPoint; +import org.springframework.security.oauth2.server.resource.web.access.BearerTokenAccessDeniedHandler; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter; +import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher; +import org.springframework.security.web.util.matcher.RequestHeaderRequestMatcher; +import tech.jhipster.config.JHipsterProperties; + +/** + * We use OAuth2 authentication for the frontend. We also have oncokb-core that needs + * to make API requests to this application, so we also need to support JWT token authentication. + * In order to use multiple WebSecurityConfigurerAdapter, we need to use requestMatcher() to + * let spring know which SecurityConfiguration to use. Our requestMatcher() condition is that any request + * with an 'Authorization' header will use SecurityConfigurationJWT, while others will use SecurityConfigurationOAuth. + */ + +@Order(1) +@Configuration +@EnableWebSecurity +@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) +public class SecurityConfigurationJWT { + + private static final Logger log = LoggerFactory.getLogger(SecurityConfigurationJWT.class); + + private final JHipsterProperties jHipsterProperties; + private final TokenProvider tokenProvider; + + public SecurityConfigurationJWT(TokenProvider tokenProvider, JHipsterProperties jHipsterProperties) { + this.tokenProvider = tokenProvider; + this.jHipsterProperties = jHipsterProperties; + } + + @Bean + public SecurityFilterChain jwtFilterChain(HttpSecurity http, MvcRequestMatcher.Builder mvc) throws Exception { + http + .securityMatcher(new RequestHeaderRequestMatcher(JWTFilter.AUTHORIZATION_HEADER)) + .cors(withDefaults()) + .csrf(csrf -> csrf.disable()) + .authorizeHttpRequests(authz -> authz.requestMatchers(mvc.pattern("/api/**")).authenticated()) + .headers( + headers -> + headers + .contentSecurityPolicy(csp -> csp.policyDirectives(jHipsterProperties.getSecurity().getContentSecurityPolicy())) + .frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin) + .referrerPolicy( + referrer -> referrer.policy(ReferrerPolicyHeaderWriter.ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN) + ) + .permissionsPolicy( + permissions -> + permissions.policy( + "camera=(), fullscreen=(self), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), sync-xhr=()" + ) + ) + ) + .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) + .exceptionHandling( + exceptions -> + exceptions + .authenticationEntryPoint(new BearerTokenAuthenticationEntryPoint()) + .accessDeniedHandler(new BearerTokenAccessDeniedHandler()) + ) + .with(securityConfigurerAdapter(), withDefaults()); + return http.build(); + } + + private JWTConfigurer securityConfigurerAdapter() { + return new JWTConfigurer(tokenProvider); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/config/security/SecurityConfigurationOAuth.java b/src/main/java/org/mskcc/oncokb/curation/config/security/SecurityConfigurationOAuth.java new file mode 100644 index 000000000..2ada4ec46 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/config/security/SecurityConfigurationOAuth.java @@ -0,0 +1,179 @@ +package org.mskcc.oncokb.curation.config.security; + +import static org.springframework.security.config.Customizer.withDefaults; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.util.*; +import java.util.function.Supplier; +import org.mskcc.oncokb.curation.security.*; +import org.mskcc.oncokb.curation.web.filter.SpaWebFilter; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; +import org.springframework.security.oauth2.core.oidc.user.OidcUserAuthority; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; +import org.springframework.security.web.csrf.*; +import org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter; +import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher; +import org.springframework.util.StringUtils; +import org.springframework.web.filter.CorsFilter; +import org.springframework.web.servlet.handler.HandlerMappingIntrospector; +import tech.jhipster.config.JHipsterProperties; +import tech.jhipster.web.filter.CookieCsrfFilter; + +@Order(2) +@Configuration +@EnableWebSecurity +public class SecurityConfigurationOAuth { + + private final JHipsterProperties jHipsterProperties; + + private final CorsFilter corsFilter; + + @Value("${spring.security.oauth2.client.provider.oidc.issuer-uri}") + private String issuerUri; + + public SecurityConfigurationOAuth(CorsFilter corsFilter, JHipsterProperties jHipsterProperties) { + this.corsFilter = corsFilter; + this.jHipsterProperties = jHipsterProperties; + } + + @Bean + public SecurityFilterChain oauthFilterChain(HttpSecurity http, MvcRequestMatcher.Builder mvc) throws Exception { + // @formatter:off + http + .cors(withDefaults()) + .csrf( + csrf -> + csrf + .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) + .csrfTokenRequestHandler(new SpaCsrfTokenRequestHandler()) + ) + .addFilterAfter(new SpaWebFilter(), BasicAuthenticationFilter.class) + .addFilterAfter(new CookieCsrfFilter(), BasicAuthenticationFilter.class) + .headers( + headers -> + headers + .contentSecurityPolicy(csp -> csp.policyDirectives(jHipsterProperties.getSecurity().getContentSecurityPolicy())) + .frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin) + .referrerPolicy( + referrer -> referrer.policy(ReferrerPolicyHeaderWriter.ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN) + ) + .permissionsPolicy( + permissions -> + permissions.policy( + "camera=(), fullscreen=(self), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), sync-xhr=()" + ) + ) + ) + .authorizeHttpRequests( + authz -> + // prettier-ignore + authz + .requestMatchers(mvc.pattern("/index.html"), mvc.pattern("/*.js"), mvc.pattern("/*.txt"), mvc.pattern("/*.json"), mvc.pattern("/*.map"), mvc.pattern("/*.css")).permitAll() + .requestMatchers(mvc.pattern("/*.ico"), mvc.pattern("/*.png"), mvc.pattern("/*.svg"), mvc.pattern("/*.webapp")).permitAll() + .requestMatchers(mvc.pattern("/app/**")).permitAll() + .requestMatchers(mvc.pattern("/i18n/**")).permitAll() + .requestMatchers(mvc.pattern("/content/**")).permitAll() + .requestMatchers(mvc.pattern("/swagger-ui/**")).permitAll() + .requestMatchers(mvc.pattern("/api/authenticate")).permitAll() + .requestMatchers(mvc.pattern("/api/auth-info")).permitAll() + .requestMatchers(mvc.pattern("/api/logout")).permitAll() + .requestMatchers(mvc.pattern("/api/admin/**")).hasAuthority(AuthoritiesConstants.ADMIN) + .requestMatchers(mvc.pattern("/api/audit/**")).hasAuthority(AuthoritiesConstants.ADMIN) + .requestMatchers(mvc.pattern("/api/account/firebase-token")).hasAnyAuthority(AuthoritiesConstants.CURATOR, AuthoritiesConstants.USER) + .requestMatchers(mvc.pattern("/websocket/**")).hasAnyAuthority(AuthoritiesConstants.CURATOR, AuthoritiesConstants.USER) + .requestMatchers(mvc.pattern("/api/**")).hasAnyAuthority(AuthoritiesConstants.CURATOR, AuthoritiesConstants.USER, AuthoritiesConstants.ADMIN) + .requestMatchers(mvc.pattern("/legacy-api/**")).hasAnyAuthority(AuthoritiesConstants.CURATOR, AuthoritiesConstants.USER, AuthoritiesConstants.ADMIN) + .requestMatchers(mvc.pattern("/v3/api-docs/**")).hasAuthority(AuthoritiesConstants.ADMIN) + .requestMatchers(mvc.pattern("/management/**")).hasAuthority(AuthoritiesConstants.ADMIN) + ) + .oauth2Login(oauth2 -> oauth2.loginPage("/oauth2/authorization/oidc").successHandler(customOAuthSuccessHandler())) + .oauth2Client(withDefaults()); + return http.build(); + } + + @Bean + MvcRequestMatcher.Builder mvc(HandlerMappingIntrospector introspector) { + return new MvcRequestMatcher.Builder(introspector); + } + + @Bean + public CustomOAuthSuccessHandler customOAuthSuccessHandler() { + return new CustomOAuthSuccessHandler(); + } + + /** + * Map authorities from "groups" or "roles" claim in ID Token. + * + * @return a {@link GrantedAuthoritiesMapper} that maps groups from + * the IdP to Spring Security Authorities. + */ + @Bean + public GrantedAuthoritiesMapper userAuthoritiesMapper() { + return authorities -> { + Set mappedAuthorities = new HashSet<>(); + + authorities.forEach(authority -> { + // Check for OidcUserAuthority because Spring Security 5.2 returns + // each scope as a GrantedAuthority, which we don't care about. + if (authority instanceof OidcUserAuthority oidcUserAuthority) { + mappedAuthorities.addAll(SecurityUtils.extractAuthorityFromClaims(oidcUserAuthority.getUserInfo().getClaims())); + }else if (authority instanceof SimpleGrantedAuthority simpleGrantedAuthority) { + mappedAuthorities.add(simpleGrantedAuthority); + } + }); + return mappedAuthorities; + }; + } + + /** + * Custom CSRF handler to provide BREACH protection. + * + * @see Spring Security Documentation - Integrating with CSRF Protection + * @see JHipster - use customized SpaCsrfTokenRequestHandler to handle CSRF token + * @see CSRF protection not working with Spring Security 6 + */ + static final class SpaCsrfTokenRequestHandler extends CsrfTokenRequestAttributeHandler { + + private final CsrfTokenRequestHandler delegate = new XorCsrfTokenRequestAttributeHandler(); + + @Override + public void handle(HttpServletRequest request, HttpServletResponse response, Supplier csrfToken) { + /* + * Always use XorCsrfTokenRequestAttributeHandler to provide BREACH protection of + * the CsrfToken when it is rendered in the response body. + */ + this.delegate.handle(request, response, csrfToken); + } + + @Override + public String resolveCsrfTokenValue(HttpServletRequest request, CsrfToken csrfToken) { + /* + * If the request contains a request header, use CsrfTokenRequestAttributeHandler + * to resolve the CsrfToken. This applies when a single-page application includes + * the header value automatically, which was obtained via a cookie containing the + * raw CsrfToken. + */ + if (StringUtils.hasText(request.getHeader(csrfToken.getHeaderName()))) { + return super.resolveCsrfTokenValue(request, csrfToken); + } + /* + * In all other cases (e.g. if the request contains a request parameter), use + * XorCsrfTokenRequestAttributeHandler to resolve the CsrfToken. This applies + * when a server-side rendered form includes the _csrf request parameter as a + * hidden input. + */ + return this.delegate.resolveCsrfTokenValue(request, csrfToken); + } + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/converters/EntityToMapConverter.java b/src/main/java/org/mskcc/oncokb/curation/converters/EntityToMapConverter.java new file mode 100644 index 000000000..95c8923c1 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/converters/EntityToMapConverter.java @@ -0,0 +1,71 @@ +package org.mskcc.oncokb.curation.converters; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import org.mskcc.oncokb.curation.domain.Alteration; +import org.mskcc.oncokb.curation.domain.Article; +import org.mskcc.oncokb.curation.domain.CancerType; +import org.mskcc.oncokb.curation.domain.CompanionDiagnosticDevice; +import org.mskcc.oncokb.curation.domain.Drug; +import org.mskcc.oncokb.curation.domain.FdaSubmission; +import org.mskcc.oncokb.curation.domain.Gene; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.converter.GenericConverter; +import org.springframework.data.convert.WritingConverter; +import org.springframework.stereotype.Component; + +@Component +@WritingConverter +public class EntityToMapConverter implements GenericConverter { + + private static final Logger logger = LoggerFactory.getLogger(EntityToMapConverter.class); + + private static final List> convertibleClasses = Arrays.asList( + CompanionDiagnosticDevice.class, + FdaSubmission.class, + Article.class, + Drug.class, + Gene.class, + Alteration.class, + CancerType.class + ); + + private final ObjectMapper objectMapper; + + public EntityToMapConverter(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + + @Override + public Set getConvertibleTypes() { + return convertibleClasses + .stream() + .map(sourceClass -> { + return new ConvertiblePair(sourceClass, Map.class); + }) + .collect(Collectors.toSet()); + } + + @Override + public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { + if (sourceType.getType() == Map.class) { + return source; + } + + if (convertibleClasses.contains(sourceType.getType())) { + try { + return objectMapper.readValue(objectMapper.writeValueAsString(source), Map.class); + } catch (JsonProcessingException e) { + logger.error("Cannot convert entity", e); + } + } + return null; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/converters/MapToEntityConverter.java b/src/main/java/org/mskcc/oncokb/curation/converters/MapToEntityConverter.java new file mode 100644 index 000000000..952da5023 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/converters/MapToEntityConverter.java @@ -0,0 +1,66 @@ +package org.mskcc.oncokb.curation.converters; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import org.mskcc.oncokb.curation.domain.Alteration; +import org.mskcc.oncokb.curation.domain.Article; +import org.mskcc.oncokb.curation.domain.CancerType; +import org.mskcc.oncokb.curation.domain.CompanionDiagnosticDevice; +import org.mskcc.oncokb.curation.domain.Drug; +import org.mskcc.oncokb.curation.domain.FdaSubmission; +import org.mskcc.oncokb.curation.domain.Gene; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.converter.GenericConverter; +import org.springframework.data.convert.ReadingConverter; +import org.springframework.stereotype.Component; + +@Component +@ReadingConverter +public class MapToEntityConverter implements GenericConverter { + + private static final Logger logger = LoggerFactory.getLogger(MapToEntityConverter.class); + + private static final List> convertibleClasses = Arrays.asList( + CompanionDiagnosticDevice.class, + FdaSubmission.class, + Article.class, + Drug.class, + Gene.class, + Alteration.class, + CancerType.class + ); + + private final ObjectMapper objectMapper; + + public MapToEntityConverter(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + + @Override + public Set getConvertibleTypes() { + return convertibleClasses + .stream() + .map(targetClass -> { + return new ConvertiblePair(Map.class, targetClass); + }) + .collect(Collectors.toSet()); + } + + @Override + public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { + try { + return objectMapper.readValue(objectMapper.writeValueAsString(source), targetType.getType()); + } catch (JsonProcessingException e) { + logger.error("Cannot convert entity", e); + } + + return null; + } +} diff --git a/src/main/java/org/mskcc/oncokb/transcript/domain/AbstractAuditingEntity.java b/src/main/java/org/mskcc/oncokb/curation/domain/AbstractAuditingEntity.java similarity index 80% rename from src/main/java/org/mskcc/oncokb/transcript/domain/AbstractAuditingEntity.java rename to src/main/java/org/mskcc/oncokb/curation/domain/AbstractAuditingEntity.java index 2371edd69..898709221 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/domain/AbstractAuditingEntity.java +++ b/src/main/java/org/mskcc/oncokb/curation/domain/AbstractAuditingEntity.java @@ -1,11 +1,11 @@ -package org.mskcc.oncokb.transcript.domain; +package org.mskcc.oncokb.curation.domain; -import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.Column; +import jakarta.persistence.EntityListeners; +import jakarta.persistence.MappedSuperclass; import java.io.Serializable; import java.time.Instant; -import javax.persistence.Column; -import javax.persistence.EntityListeners; -import javax.persistence.MappedSuperclass; import org.springframework.data.annotation.CreatedBy; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedBy; @@ -18,28 +18,27 @@ */ @MappedSuperclass @EntityListeners(AuditingEntityListener.class) -public abstract class AbstractAuditingEntity implements Serializable { +@JsonIgnoreProperties(value = { "createdBy", "createdDate", "lastModifiedBy", "lastModifiedDate" }, allowGetters = true) +public abstract class AbstractAuditingEntity implements Serializable { private static final long serialVersionUID = 1L; + public abstract T getId(); + @CreatedBy @Column(name = "created_by", nullable = false, length = 50, updatable = false) - @JsonIgnore private String createdBy; @CreatedDate @Column(name = "created_date", updatable = false) - @JsonIgnore private Instant createdDate = Instant.now(); @LastModifiedBy @Column(name = "last_modified_by", length = 50) - @JsonIgnore private String lastModifiedBy; @LastModifiedDate @Column(name = "last_modified_date") - @JsonIgnore private Instant lastModifiedDate = Instant.now(); public String getCreatedBy() { diff --git a/src/main/java/org/mskcc/oncokb/transcript/domain/Alignment.java b/src/main/java/org/mskcc/oncokb/curation/domain/Alignment.java similarity index 90% rename from src/main/java/org/mskcc/oncokb/transcript/domain/Alignment.java rename to src/main/java/org/mskcc/oncokb/curation/domain/Alignment.java index 20d613707..70b9c7a8d 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/domain/Alignment.java +++ b/src/main/java/org/mskcc/oncokb/curation/domain/Alignment.java @@ -1,4 +1,4 @@ -package org.mskcc.oncokb.transcript.domain; +package org.mskcc.oncokb.curation.domain; /** * Created by Hongxin Zhang on 10/23/20. diff --git a/src/main/java/org/mskcc/oncokb/transcript/domain/AlignmentResult.java b/src/main/java/org/mskcc/oncokb/curation/domain/AlignmentResult.java similarity index 90% rename from src/main/java/org/mskcc/oncokb/transcript/domain/AlignmentResult.java rename to src/main/java/org/mskcc/oncokb/curation/domain/AlignmentResult.java index 273b3a3dd..c8fc51d60 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/domain/AlignmentResult.java +++ b/src/main/java/org/mskcc/oncokb/curation/domain/AlignmentResult.java @@ -1,4 +1,4 @@ -package org.mskcc.oncokb.transcript.domain; +package org.mskcc.oncokb.curation.domain; /** * Created by Hongxin Zhang on 10/23/20. diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/AlleleState.java b/src/main/java/org/mskcc/oncokb/curation/domain/AlleleState.java new file mode 100644 index 000000000..2ed84db02 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/AlleleState.java @@ -0,0 +1,121 @@ +package org.mskcc.oncokb.curation.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; + +@Entity +@Table(name = "allele_state") +public class AlleleState implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @NotNull + @Column(name = "name", nullable = false, unique = true) + private String name; + + @ManyToMany(mappedBy = "alleleStates") + @JsonIgnoreProperties(value = { "alleleStates", "associations" }, allowSetters = true) + private Set genomicIndicators = new HashSet<>(); + + // jhipster-needle-entity-add-field - JHipster will add fields here + + public AlleleState(String name) { + this.name = name; + } + + public Long getId() { + return this.id; + } + + public AlleleState id(Long id) { + this.setId(id); + return this; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return this.name; + } + + public AlleleState() {} + + public AlleleState name(String name) { + this.setName(name); + return this; + } + + public void setName(String name) { + this.name = name; + } + + public Set getGenomicIndicators() { + return this.genomicIndicators; + } + + public void setGenomicIndicators(Set genomicIndicators) { + if (this.genomicIndicators != null) { + this.genomicIndicators.forEach(i -> i.removeAlleleState(this)); + } + if (genomicIndicators != null) { + genomicIndicators.forEach(i -> i.addAlleleState(this)); + } + this.genomicIndicators = genomicIndicators; + } + + public AlleleState genomicIndicators(Set genomicIndicators) { + this.setGenomicIndicators(genomicIndicators); + return this; + } + + public AlleleState addGenomicIndicator(GenomicIndicator genomicIndicator) { + this.genomicIndicators.add(genomicIndicator); + genomicIndicator.getAlleleStates().add(this); + return this; + } + + public AlleleState removeGenomicIndicator(GenomicIndicator genomicIndicator) { + this.genomicIndicators.remove(genomicIndicator); + genomicIndicator.getAlleleStates().remove(this); + return this; + } + + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof AlleleState)) { + return false; + } + return id != null && id.equals(((AlleleState) o).id); + } + + @Override + public int hashCode() { + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); + } + + // prettier-ignore + @Override + public String toString() { + return "AlleleState{" + + "id=" + getId() + + ", name='" + getName() + "'" + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/Alteration.java b/src/main/java/org/mskcc/oncokb/curation/domain/Alteration.java new file mode 100644 index 000000000..a5f61f457 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/Alteration.java @@ -0,0 +1,383 @@ +package org.mskcc.oncokb.curation.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; +import org.javers.core.metamodel.annotation.DiffIgnore; +import org.javers.core.metamodel.annotation.ShallowReference; +import org.mskcc.oncokb.curation.domain.enumeration.AlterationType; +import org.mskcc.oncokb.curation.util.AminoAcidConverterUtils; + +/** + * A Alteration. + */ +@Entity +@Table(name = "alteration") +public class Alteration implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @NotNull + @Enumerated(EnumType.STRING) + @Column(name = "type", nullable = false) + private AlterationType type; + + @NotNull + @Column(name = "name", nullable = false) + private String name = ""; + + @NotNull + @Column(name = "alteration", nullable = false) + private String alteration = ""; + + @NotNull + @Column(name = "protein_change", nullable = false) + private String proteinChange = ""; + + @Column(name = "start") + private Integer start; + + @Column(name = "end") + private Integer end; + + @Column(name = "ref_residues") + private String refResidues; + + @Column(name = "variant_residues") + private String variantResidues; + + @ShallowReference + @ManyToMany + @JoinTable( + name = "rel_alteration__flag", + joinColumns = @JoinColumn(name = "alteration_id"), + inverseJoinColumns = @JoinColumn(name = "flag_id") + ) + @JsonIgnoreProperties(value = { "alterations", "articles", "drugs", "genes", "transcripts" }, allowSetters = true) + private Set flags = new HashSet<>(); + + @ShallowReference + @ManyToMany + @JoinTable( + name = "rel_alteration__gene", + joinColumns = @JoinColumn(name = "alteration_id"), + inverseJoinColumns = @JoinColumn(name = "gene_id") + ) + @JsonIgnoreProperties(value = { "ensemblGenes", "evidences", "transcripts", "flags", "synonyms", "alterations" }, allowSetters = true) + private Set genes = new HashSet<>(); + + @DiffIgnore + @ManyToMany + @JoinTable( + name = "rel_alteration__transcript", + joinColumns = @JoinColumn(name = "alteration_id"), + inverseJoinColumns = @JoinColumn(name = "transcript_id") + ) + @JsonIgnoreProperties(value = { "sequences", "fragments", "flags", "ensemblGene", "gene", "alterations" }, allowSetters = true) + private Set transcripts = new HashSet<>(); + + @ShallowReference + @ManyToOne + @JsonIgnoreProperties(value = { "alterations", "categoricalAlterations" }, allowSetters = true) + @JoinColumn(name = "consequence", referencedColumnName = "term") + private Consequence consequence; + + @DiffIgnore + @ManyToMany(mappedBy = "alterations") + @JsonIgnoreProperties( + value = { + "rules", + "alterations", + "articles", + "cancerTypes", + "drugs", + "evidence", + "clinicalTrials", + "clinicalTrialArms", + "eligibilityCriteria", + "fdaSubmissions", + "genomicIndicators", + }, + allowSetters = true + ) + private Set associations = new HashSet<>(); + + // jhipster-needle-entity-add-field - JHipster will add fields here + + public Long getId() { + return this.id; + } + + public Alteration id(Long id) { + this.setId(id); + return this; + } + + public void setId(Long id) { + this.id = id; + } + + public AlterationType getType() { + return this.type; + } + + public Alteration type(AlterationType type) { + this.setType(type); + return this; + } + + public void setType(AlterationType type) { + this.type = type; + } + + public String getName() { + return this.name; + } + + public Alteration name(String name) { + this.setName(name); + return this; + } + + public void setName(String name) { + this.name = name; + } + + public String getAlteration() { + return this.alteration; + } + + public Alteration alteration(String alteration) { + this.setAlteration(alteration); + return this; + } + + public void setAlteration(String alteration) { + this.alteration = AminoAcidConverterUtils.resolveHgvspShortFromHgvsp(alteration); + } + + public String getProteinChange() { + return this.proteinChange; + } + + public Alteration proteinChange(String proteinChange) { + this.setProteinChange(proteinChange); + return this; + } + + public void setProteinChange(String proteinChange) { + this.proteinChange = proteinChange; + } + + public Integer getStart() { + return this.start; + } + + public Alteration start(Integer start) { + this.setStart(start); + return this; + } + + public void setStart(Integer start) { + this.start = start; + } + + public Integer getEnd() { + return this.end; + } + + public Alteration end(Integer end) { + this.setEnd(end); + return this; + } + + public void setEnd(Integer end) { + this.end = end; + } + + public String getRefResidues() { + return this.refResidues; + } + + public Alteration refResidues(String refResidues) { + this.setRefResidues(refResidues); + return this; + } + + public void setRefResidues(String refResidues) { + this.refResidues = refResidues; + } + + public String getVariantResidues() { + return this.variantResidues; + } + + public Alteration variantResidues(String variantResidues) { + this.setVariantResidues(variantResidues); + return this; + } + + public void setVariantResidues(String variantResidues) { + this.variantResidues = variantResidues; + } + + public Set getFlags() { + return this.flags; + } + + public void setFlags(Set flags) { + this.flags = flags; + } + + public Alteration flags(Set flags) { + this.setFlags(flags); + return this; + } + + public Alteration addFlag(Flag flag) { + this.flags.add(flag); + return this; + } + + public Alteration removeFlag(Flag flag) { + this.flags.remove(flag); + return this; + } + + public Set getGenes() { + return this.genes; + } + + public void setGenes(Set genes) { + this.genes = genes; + } + + public Alteration genes(Set genes) { + this.setGenes(genes); + return this; + } + + public Alteration addGene(Gene gene) { + this.genes.add(gene); + gene.getAlterations().add(this); + return this; + } + + public Alteration removeGene(Gene gene) { + this.genes.remove(gene); + gene.getAlterations().remove(this); + return this; + } + + public Set getTranscripts() { + return this.transcripts; + } + + public void setTranscripts(Set transcripts) { + this.transcripts = transcripts; + } + + public Alteration transcripts(Set transcripts) { + this.setTranscripts(transcripts); + return this; + } + + public Alteration addTranscript(Transcript transcript) { + this.transcripts.add(transcript); + transcript.getAlterations().add(this); + return this; + } + + public Alteration removeTranscript(Transcript transcript) { + this.transcripts.remove(transcript); + transcript.getAlterations().remove(this); + return this; + } + + public Consequence getConsequence() { + return this.consequence; + } + + public void setConsequence(Consequence consequence) { + this.consequence = consequence; + } + + public Alteration consequence(Consequence consequence) { + this.setConsequence(consequence); + return this; + } + + public Set getAssociations() { + return this.associations; + } + + public void setAssociations(Set associations) { + if (this.associations != null) { + this.associations.forEach(i -> i.removeAlteration(this)); + } + if (associations != null) { + associations.forEach(i -> i.addAlteration(this)); + } + this.associations = associations; + } + + public Alteration associations(Set associations) { + this.setAssociations(associations); + return this; + } + + public Alteration addAssociation(Association association) { + this.associations.add(association); + association.getAlterations().add(this); + return this; + } + + public Alteration removeAssociation(Association association) { + this.associations.remove(association); + association.getAlterations().remove(this); + return this; + } + + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Alteration)) { + return false; + } + return id != null && id.equals(((Alteration) o).id); + } + + @Override + public int hashCode() { + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); + } + + // prettier-ignore + @Override + public String toString() { + return "Alteration{" + + "id=" + getId() + + ", type='" + getType() + "'" + + ", name='" + getName() + "'" + + ", alteration='" + getAlteration() + "'" + + ", proteinChange='" + getProteinChange() + "'" + + ", start=" + getStart() + + ", end=" + getEnd() + + ", refResidues='" + getRefResidues() + "'" + + ", variantResidues='" + getVariantResidues() + "'" + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/AlterationAnnotationStatus.java b/src/main/java/org/mskcc/oncokb/curation/domain/AlterationAnnotationStatus.java new file mode 100644 index 000000000..0040e91b5 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/AlterationAnnotationStatus.java @@ -0,0 +1,26 @@ +package org.mskcc.oncokb.curation.domain; + +import org.mskcc.oncokb.curation.domain.dto.AnnotationDTO; + +public class AlterationAnnotationStatus extends EntityStatus { + + String queryId; + + AnnotationDTO annotation = new AnnotationDTO(); + + public String getQueryId() { + return queryId; + } + + public void setQueryId(String queryId) { + this.queryId = queryId; + } + + public AnnotationDTO getAnnotation() { + return annotation; + } + + public void setAnnotation(AnnotationDTO annotation) { + this.annotation = annotation; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/Article.java b/src/main/java/org/mskcc/oncokb/curation/domain/Article.java new file mode 100644 index 000000000..24edb2a58 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/Article.java @@ -0,0 +1,363 @@ +package org.mskcc.oncokb.curation.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; +import java.io.Serializable; +import java.time.Instant; +import java.util.HashSet; +import java.util.Set; +import org.javers.core.metamodel.annotation.DiffIgnore; +import org.javers.core.metamodel.annotation.ShallowReference; +import org.mskcc.oncokb.curation.domain.enumeration.ArticleType; + +/** + * A Article. + */ +@Entity +@Table(name = "article") +public class Article implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @NotNull + @Enumerated(EnumType.STRING) + @Column(name = "type", nullable = false) + private ArticleType type; + + @Column(name = "uid") + private String uid; + + @Lob + @Column(name = "title") + private String title; + + @DiffIgnore + @Lob + @Column(name = "content") + private String content; + + @Column(name = "link") + private String link; + + @Column(name = "authors") + private String authors; + + @Column(name = "date") + private Instant date; + + @DiffIgnore + @Lob + @Column(name = "additional_info") + private String additionalInfo; + + @ShallowReference + @ManyToMany + @JoinTable( + name = "rel_article__flag", + joinColumns = @JoinColumn(name = "article_id"), + inverseJoinColumns = @JoinColumn(name = "flag_id") + ) + @JsonIgnoreProperties(value = { "alterations", "articles", "drugs", "genes", "transcripts" }, allowSetters = true) + private Set flags = new HashSet<>(); + + @DiffIgnore + @ManyToMany + @JoinTable( + name = "rel_article__synonym", + joinColumns = @JoinColumn(name = "article_id"), + inverseJoinColumns = @JoinColumn(name = "synonym_id") + ) + @JsonIgnoreProperties(value = { "articles", "cancerTypes", "genes", "nciThesauruses" }, allowSetters = true) + private Set synonyms = new HashSet<>(); + + @DiffIgnore + @ManyToMany(mappedBy = "articles") + @JsonIgnoreProperties( + value = { + "rules", + "alterations", + "articles", + "cancerTypes", + "drugs", + "evidence", + "clinicalTrials", + "clinicalTrialArms", + "eligibilityCriteria", + "fdaSubmissions", + "genomicIndicators", + }, + allowSetters = true + ) + private Set associations = new HashSet<>(); + + @DiffIgnore + @ManyToMany(mappedBy = "articles") + @JsonIgnoreProperties(value = { "articles", "associations", "companionDiagnosticDevice", "fdaDrug", "type" }, allowSetters = true) + private Set fdaSubmissions = new HashSet<>(); + + // jhipster-needle-entity-add-field - JHipster will add fields here + + public Long getId() { + return this.id; + } + + public Article id(Long id) { + this.setId(id); + return this; + } + + public void setId(Long id) { + this.id = id; + } + + public ArticleType getType() { + return this.type; + } + + public Article type(ArticleType type) { + this.setType(type); + return this; + } + + public void setType(ArticleType type) { + this.type = type; + } + + public String getUid() { + return this.uid; + } + + public Article uid(String uid) { + this.setUid(uid); + return this; + } + + public void setUid(String uid) { + this.uid = uid; + } + + public String getTitle() { + return this.title; + } + + public Article title(String title) { + this.setTitle(title); + return this; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getContent() { + return this.content; + } + + public Article content(String content) { + this.setContent(content); + return this; + } + + public void setContent(String content) { + this.content = content; + } + + public String getLink() { + return this.link; + } + + public Article link(String link) { + this.setLink(link); + return this; + } + + public void setLink(String link) { + this.link = link; + } + + public String getAuthors() { + return this.authors; + } + + public Article authors(String authors) { + this.setAuthors(authors); + return this; + } + + public void setAuthors(String authors) { + this.authors = authors; + } + + public Instant getDate() { + return this.date; + } + + public Article date(Instant date) { + this.setDate(date); + return this; + } + + public void setDate(Instant date) { + this.date = date; + } + + public Set getFlags() { + return this.flags; + } + + public void setFlags(Set flags) { + this.flags = flags; + } + + public Article flags(Set flags) { + this.setFlags(flags); + return this; + } + + public Article addFlag(Flag flag) { + this.flags.add(flag); + flag.getArticles().add(this); + return this; + } + + public Article removeFlag(Flag flag) { + this.flags.remove(flag); + flag.getArticles().remove(this); + return this; + } + + public Set getSynonyms() { + return this.synonyms; + } + + public void setSynonyms(Set synonyms) { + this.synonyms = synonyms; + } + + public Article synonyms(Set synonyms) { + this.setSynonyms(synonyms); + return this; + } + + public Article addSynonym(Synonym synonym) { + this.synonyms.add(synonym); + synonym.getArticles().add(this); + return this; + } + + public Article removeSynonym(Synonym synonym) { + this.synonyms.remove(synonym); + synonym.getArticles().remove(this); + return this; + } + + public Set getAssociations() { + return this.associations; + } + + public void setAssociations(Set associations) { + if (this.associations != null) { + this.associations.forEach(i -> i.removeArticle(this)); + } + if (associations != null) { + associations.forEach(i -> i.addArticle(this)); + } + this.associations = associations; + } + + public Article associations(Set associations) { + this.setAssociations(associations); + return this; + } + + public Article addAssociation(Association association) { + this.associations.add(association); + association.getArticles().add(this); + return this; + } + + public Article removeAssociation(Association association) { + this.associations.remove(association); + association.getArticles().remove(this); + return this; + } + + public String getAdditionalInfo() { + return additionalInfo; + } + + public void setAdditionalInfo(String additionalInfo) { + this.additionalInfo = additionalInfo; + } + + public Set getFdaSubmissions() { + return this.fdaSubmissions; + } + + public void setFdaSubmissions(Set fdaSubmissions) { + if (this.fdaSubmissions != null) { + this.fdaSubmissions.forEach(i -> i.removeArticle(this)); + } + if (fdaSubmissions != null) { + fdaSubmissions.forEach(i -> i.addArticle(this)); + } + this.fdaSubmissions = fdaSubmissions; + } + + public Article fdaSubmissions(Set fdaSubmissions) { + this.setFdaSubmissions(fdaSubmissions); + return this; + } + + public Article addFdaSubmission(FdaSubmission fdaSubmission) { + this.fdaSubmissions.add(fdaSubmission); + fdaSubmission.getArticles().add(this); + return this; + } + + public Article removeFdaSubmission(FdaSubmission fdaSubmission) { + this.fdaSubmissions.remove(fdaSubmission); + fdaSubmission.getArticles().remove(this); + return this; + } + + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Article)) { + return false; + } + return id != null && id.equals(((Article) o).id); + } + + @Override + public int hashCode() { + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); + } + + // prettier-ignore + @Override + public String toString() { + return "Article{" + + "id=" + getId() + + ", type='" + getType() + "'" + + ", uid='" + getUid() + "'" + + ", title='" + getTitle() + "'" + + ", content='" + getContent() + "'" + + ", link='" + getLink() + "'" + + ", authors='" + getAuthors() + "'" + + ", date='" + getDate() + "'" + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/Association.java b/src/main/java/org/mskcc/oncokb/curation/domain/Association.java new file mode 100644 index 000000000..fabce4c64 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/Association.java @@ -0,0 +1,462 @@ +package org.mskcc.oncokb.curation.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; +import org.javers.core.metamodel.annotation.ShallowReference; + +/** + * An Association. + */ +@Entity +@Table(name = "association") +public class Association implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @Column(name = "name") + private String name; + + @ShallowReference + @OneToMany(mappedBy = "association", cascade = CascadeType.ALL) + @JsonIgnoreProperties(value = { "association" }, allowSetters = true) + private Set rules = new HashSet<>(); + + @ShallowReference + @ManyToMany + @JoinTable( + name = "rel_association__alteration", + joinColumns = @JoinColumn(name = "association_id"), + inverseJoinColumns = @JoinColumn(name = "alteration_id") + ) + @JsonIgnoreProperties(value = { "transcripts", "associations" }, allowSetters = true) + private Set alterations = new HashSet<>(); + + @ShallowReference + @ManyToMany + @JoinTable( + name = "rel_association__article", + joinColumns = @JoinColumn(name = "association_id"), + inverseJoinColumns = @JoinColumn(name = "article_id") + ) + @JsonIgnoreProperties(value = { "associations" }, allowSetters = true) + private Set

articles = new HashSet<>(); + + @ShallowReference + @ManyToMany + @JoinTable( + name = "rel_association__cancer_type", + joinColumns = @JoinColumn(name = "association_id"), + inverseJoinColumns = @JoinColumn(name = "cancer_type_id") + ) + @JsonIgnoreProperties(value = { "children", "synonyms", "parent", "associations" }, allowSetters = true) + private Set cancerTypes = new HashSet<>(); + + @ShallowReference + @ManyToMany + @JoinTable( + name = "rel_association__drug", + joinColumns = @JoinColumn(name = "association_id"), + inverseJoinColumns = @JoinColumn(name = "drug_id") + ) + @JsonIgnoreProperties(value = { "nciThesaurus", "fdaDrug", "flags", "associations" }, allowSetters = true) + private Set drugs = new HashSet<>(); + + @ShallowReference + @JsonIgnoreProperties(value = { "association", "gene", "levelOfEvidences" }, allowSetters = true) + @OneToOne(mappedBy = "association") + private Evidence evidence; + + @ShallowReference + @ManyToMany(mappedBy = "associations") + @JsonIgnoreProperties(value = { "clinicalTrialArms", "eligibilityCriteria", "associations" }, allowSetters = true) + private Set clinicalTrials = new HashSet<>(); + + @ShallowReference + @ManyToMany(mappedBy = "associations") + @JsonIgnoreProperties(value = { "associations", "clinicalTrial" }, allowSetters = true) + private Set clinicalTrialArms = new HashSet<>(); + + @ShallowReference + @ManyToMany(mappedBy = "associations") + @JsonIgnoreProperties(value = { "associations", "clinicalTrial" }, allowSetters = true) + private Set eligibilityCriteria = new HashSet<>(); + + @ShallowReference + @ManyToMany(mappedBy = "associations") + @JsonIgnoreProperties(value = { "associations", "companionDiagnosticDevice" }, allowSetters = true) + private Set fdaSubmissions = new HashSet<>(); + + @ShallowReference + @ManyToMany(mappedBy = "associations") + @JsonIgnoreProperties(value = { "associations" }, allowSetters = true) + private Set genomicIndicators = new HashSet<>(); + + // jhipster-needle-entity-add-field - JHipster will add fields here + + public Long getId() { + return this.id; + } + + public Association id(Long id) { + this.setId(id); + return this; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return this.name; + } + + public Association name(String name) { + this.setName(name); + return this; + } + + public void setName(String name) { + this.name = name; + } + + public Set getRules() { + return this.rules; + } + + public void setRules(Set rules) { + if (this.rules != null) { + this.rules.forEach(i -> i.setAssociation(null)); + } + if (rules != null) { + rules.forEach(i -> i.setAssociation(this)); + } + this.rules = rules; + } + + public Association rules(Set rules) { + this.setRules(rules); + return this; + } + + public Association addRule(Rule rule) { + this.rules.add(rule); + rule.setAssociation(this); + return this; + } + + public Association removeRule(Rule rule) { + this.rules.remove(rule); + rule.setAssociation(null); + return this; + } + + public Set getAlterations() { + return this.alterations; + } + + public void setAlterations(Set alterations) { + this.alterations = alterations; + } + + public Association alterations(Set alterations) { + this.setAlterations(alterations); + return this; + } + + public Association addAlteration(Alteration alteration) { + this.alterations.add(alteration); + alteration.getAssociations().add(this); + return this; + } + + public Association removeAlteration(Alteration alteration) { + this.alterations.remove(alteration); + alteration.getAssociations().remove(this); + return this; + } + + public Set
getArticles() { + return this.articles; + } + + public void setArticles(Set
articles) { + this.articles = articles; + } + + public Association articles(Set
articles) { + this.setArticles(articles); + return this; + } + + public Association addArticle(Article article) { + this.articles.add(article); + article.getAssociations().add(this); + return this; + } + + public Association removeArticle(Article article) { + this.articles.remove(article); + article.getAssociations().remove(this); + return this; + } + + public Set getCancerTypes() { + return this.cancerTypes; + } + + public void setCancerTypes(Set cancerTypes) { + this.cancerTypes = cancerTypes; + } + + public Association cancerTypes(Set cancerTypes) { + this.setCancerTypes(cancerTypes); + return this; + } + + public Association addCancerType(CancerType cancerType) { + this.cancerTypes.add(cancerType); + cancerType.getAssociations().add(this); + return this; + } + + public Association removeCancerType(CancerType cancerType) { + this.cancerTypes.remove(cancerType); + cancerType.getAssociations().remove(this); + return this; + } + + public Set getDrugs() { + return this.drugs; + } + + public void setDrugs(Set drugs) { + this.drugs = drugs; + } + + public Association drugs(Set drugs) { + this.setDrugs(drugs); + return this; + } + + public Association addDrug(Drug drug) { + this.drugs.add(drug); + drug.getAssociations().add(this); + return this; + } + + public Association removeDrug(Drug drug) { + this.drugs.remove(drug); + drug.getAssociations().remove(this); + return this; + } + + public Evidence getEvidence() { + return this.evidence; + } + + public void setEvidence(Evidence evidence) { + if (this.evidence != null) { + this.evidence.setAssociation(null); + } + if (evidence != null) { + evidence.setAssociation(this); + } + this.evidence = evidence; + } + + public Association evidence(Evidence evidence) { + this.setEvidence(evidence); + return this; + } + + public Set getClinicalTrials() { + return this.clinicalTrials; + } + + public void setClinicalTrials(Set clinicalTrials) { + if (this.clinicalTrials != null) { + this.clinicalTrials.forEach(i -> i.removeAssociation(this)); + } + if (clinicalTrials != null) { + clinicalTrials.forEach(i -> i.addAssociation(this)); + } + this.clinicalTrials = clinicalTrials; + } + + public Association clinicalTrials(Set clinicalTrials) { + this.setClinicalTrials(clinicalTrials); + return this; + } + + public Association addClinicalTrial(ClinicalTrial clinicalTrial) { + this.clinicalTrials.add(clinicalTrial); + clinicalTrial.getAssociations().add(this); + return this; + } + + public Association removeClinicalTrial(ClinicalTrial clinicalTrial) { + this.clinicalTrials.remove(clinicalTrial); + clinicalTrial.getAssociations().remove(this); + return this; + } + + public Set getClinicalTrialArms() { + return this.clinicalTrialArms; + } + + public void setClinicalTrialArms(Set clinicalTrialArms) { + if (this.clinicalTrialArms != null) { + this.clinicalTrialArms.forEach(i -> i.removeAssociation(this)); + } + if (clinicalTrialArms != null) { + clinicalTrialArms.forEach(i -> i.addAssociation(this)); + } + this.clinicalTrialArms = clinicalTrialArms; + } + + public Association clinicalTrialArms(Set clinicalTrialArms) { + this.setClinicalTrialArms(clinicalTrialArms); + return this; + } + + public Association addClinicalTrialArm(ClinicalTrialArm clinicalTrialArm) { + this.clinicalTrialArms.add(clinicalTrialArm); + clinicalTrialArm.getAssociations().add(this); + return this; + } + + public Association removeClinicalTrialArm(ClinicalTrialArm clinicalTrialArm) { + this.clinicalTrialArms.remove(clinicalTrialArm); + clinicalTrialArm.getAssociations().remove(this); + return this; + } + + public Set getEligibilityCriteria() { + return this.eligibilityCriteria; + } + + public void setEligibilityCriteria(Set eligibilityCriteria) { + if (this.eligibilityCriteria != null) { + this.eligibilityCriteria.forEach(i -> i.removeAssociation(this)); + } + if (eligibilityCriteria != null) { + eligibilityCriteria.forEach(i -> i.addAssociation(this)); + } + this.eligibilityCriteria = eligibilityCriteria; + } + + public Association eligibilityCriteria(Set eligibilityCriteria) { + this.setEligibilityCriteria(eligibilityCriteria); + return this; + } + + public Association addEligibilityCriteria(EligibilityCriteria eligibilityCriteria) { + this.eligibilityCriteria.add(eligibilityCriteria); + eligibilityCriteria.getAssociations().add(this); + return this; + } + + public Association removeEligibilityCriteria(EligibilityCriteria eligibilityCriteria) { + this.eligibilityCriteria.remove(eligibilityCriteria); + eligibilityCriteria.getAssociations().remove(this); + return this; + } + + public Set getFdaSubmissions() { + return this.fdaSubmissions; + } + + public void setFdaSubmissions(Set fdaSubmissions) { + if (this.fdaSubmissions != null) { + this.fdaSubmissions.forEach(i -> i.removeAssociation(this)); + } + if (fdaSubmissions != null) { + fdaSubmissions.forEach(i -> i.addAssociation(this)); + } + this.fdaSubmissions = fdaSubmissions; + } + + public Association fdaSubmissions(Set fdaSubmissions) { + this.setFdaSubmissions(fdaSubmissions); + return this; + } + + public Association addFdaSubmission(FdaSubmission fdaSubmission) { + this.fdaSubmissions.add(fdaSubmission); + fdaSubmission.getAssociations().add(this); + return this; + } + + public Association removeFdaSubmission(FdaSubmission fdaSubmission) { + this.fdaSubmissions.remove(fdaSubmission); + fdaSubmission.getAssociations().remove(this); + return this; + } + + public Set getGenomicIndicators() { + return this.genomicIndicators; + } + + public void setGenomicIndicators(Set genomicIndicators) { + if (this.genomicIndicators != null) { + this.genomicIndicators.forEach(i -> i.removeAssociation(this)); + } + if (genomicIndicators != null) { + genomicIndicators.forEach(i -> i.addAssociation(this)); + } + this.genomicIndicators = genomicIndicators; + } + + public Association genomicIndicators(Set genomicIndicators) { + this.setGenomicIndicators(genomicIndicators); + return this; + } + + public Association addGenomicIndicator(GenomicIndicator genomicIndicator) { + this.genomicIndicators.add(genomicIndicator); + genomicIndicator.getAssociations().add(this); + return this; + } + + public Association removeGenomicIndicator(GenomicIndicator genomicIndicator) { + this.genomicIndicators.remove(genomicIndicator); + genomicIndicator.getAssociations().remove(this); + return this; + } + + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Association)) { + return false; + } + return id != null && id.equals(((Association) o).id); + } + + @Override + public int hashCode() { + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); + } + + // prettier-ignore + @Override + public String toString() { + return "Association{" + + "id=" + getId() + + ", name='" + getName() + "'" + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/Authority.java b/src/main/java/org/mskcc/oncokb/curation/domain/Authority.java new file mode 100644 index 000000000..a22ebfec2 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/Authority.java @@ -0,0 +1,58 @@ +package org.mskcc.oncokb.curation.domain; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import java.io.Serializable; +import java.util.Objects; + +/** + * An authority (a security role) used by Spring Security. + */ +@Entity +@Table(name = "authority") +public class Authority implements Serializable { + + private static final long serialVersionUID = 1L; + + @NotNull + @Size(max = 50) + @Id + @Column(length = 50) + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Authority)) { + return false; + } + return Objects.equals(name, ((Authority) o).name); + } + + @Override + public int hashCode() { + return Objects.hashCode(name); + } + + // prettier-ignore + @Override + public String toString() { + return "Authority{" + + "name='" + name + '\'' + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/CancerType.java b/src/main/java/org/mskcc/oncokb/curation/domain/CancerType.java new file mode 100644 index 000000000..2fd2c4919 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/CancerType.java @@ -0,0 +1,331 @@ +package org.mskcc.oncokb.curation.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; +import org.javers.core.metamodel.annotation.DiffIgnore; +import org.javers.core.metamodel.annotation.ShallowReference; +import org.mskcc.oncokb.curation.domain.enumeration.TumorForm; + +/** + * A CancerType. + */ +@Entity +@Table(name = "cancer_type") +public class CancerType implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @Column(name = "code") + private String code; + + @Column(name = "color") + private String color; + + @NotNull + @Column(name = "level", nullable = false) + private Integer level; + + @NotNull + @Column(name = "main_type", nullable = false) + private String mainType; + + @Column(name = "subtype") + private String subtype; + + @Column(name = "tissue") + private String tissue; + + @NotNull + @Enumerated(EnumType.STRING) + @Column(name = "tumor_form", nullable = false) + private TumorForm tumorForm; + + @ShallowReference + @OneToMany(mappedBy = "parent") + @JsonIgnoreProperties(value = { "children", "synonyms", "parent", "associations" }, allowSetters = true) + private Set children = new HashSet<>(); + + @DiffIgnore + @ManyToMany + @JoinTable( + name = "rel_cancer_type__synonym", + joinColumns = @JoinColumn(name = "cancer_type_id"), + inverseJoinColumns = @JoinColumn(name = "synonym_id") + ) + @JsonIgnoreProperties(value = { "cancerTypes", "genes", "nciThesauruses" }, allowSetters = true) + private Set synonyms = new HashSet<>(); + + @ShallowReference + @ManyToOne + @JsonIgnoreProperties(value = { "children", "synonyms", "parent", "associations" }, allowSetters = true) + private CancerType parent; + + @DiffIgnore + @ManyToMany(mappedBy = "cancerTypes") + @JsonIgnoreProperties( + value = { + "rules", + "alterations", + "articles", + "cancerTypes", + "drugs", + "evidence", + "clinicalTrials", + "clinicalTrialArms", + "eligibilityCriteria", + "fdaSubmissions", + "genomicIndicators", + }, + allowSetters = true + ) + private Set associations = new HashSet<>(); + + // jhipster-needle-entity-add-field - JHipster will add fields here + + public Long getId() { + return this.id; + } + + public CancerType id(Long id) { + this.setId(id); + return this; + } + + public void setId(Long id) { + this.id = id; + } + + public String getCode() { + return this.code; + } + + public CancerType code(String code) { + this.setCode(code); + return this; + } + + public void setCode(String code) { + this.code = code; + } + + public String getColor() { + return this.color; + } + + public CancerType color(String color) { + this.setColor(color); + return this; + } + + public void setColor(String color) { + this.color = color; + } + + public Integer getLevel() { + return this.level; + } + + public CancerType level(Integer level) { + this.setLevel(level); + return this; + } + + public void setLevel(Integer level) { + this.level = level; + } + + public String getMainType() { + return this.mainType; + } + + public CancerType mainType(String mainType) { + this.setMainType(mainType); + return this; + } + + public void setMainType(String mainType) { + this.mainType = mainType; + } + + public String getSubtype() { + return this.subtype; + } + + public CancerType subtype(String subtype) { + this.setSubtype(subtype); + return this; + } + + public void setSubtype(String subtype) { + this.subtype = subtype; + } + + public String getTissue() { + return this.tissue; + } + + public CancerType tissue(String tissue) { + this.setTissue(tissue); + return this; + } + + public void setTissue(String tissue) { + this.tissue = tissue; + } + + public TumorForm getTumorForm() { + return this.tumorForm; + } + + public CancerType tumorForm(TumorForm tumorForm) { + this.setTumorForm(tumorForm); + return this; + } + + public void setTumorForm(TumorForm tumorForm) { + this.tumorForm = tumorForm; + } + + public Set getChildren() { + return this.children; + } + + public void setChildren(Set cancerTypes) { + if (this.children != null) { + this.children.forEach(i -> i.setParent(null)); + } + if (cancerTypes != null) { + cancerTypes.forEach(i -> i.setParent(this)); + } + this.children = cancerTypes; + } + + public CancerType children(Set cancerTypes) { + this.setChildren(cancerTypes); + return this; + } + + public CancerType addChildren(CancerType cancerType) { + this.children.add(cancerType); + cancerType.setParent(this); + return this; + } + + public CancerType removeChildren(CancerType cancerType) { + this.children.remove(cancerType); + cancerType.setParent(null); + return this; + } + + public Set getSynonyms() { + return this.synonyms; + } + + public void setSynonyms(Set synonyms) { + this.synonyms = synonyms; + } + + public CancerType synonyms(Set synonyms) { + this.setSynonyms(synonyms); + return this; + } + + public CancerType addSynonym(Synonym synonym) { + this.synonyms.add(synonym); + synonym.getCancerTypes().add(this); + return this; + } + + public CancerType removeSynonym(Synonym synonym) { + this.synonyms.remove(synonym); + synonym.getCancerTypes().remove(this); + return this; + } + + public CancerType getParent() { + return this.parent; + } + + public void setParent(CancerType cancerType) { + this.parent = cancerType; + } + + public CancerType parent(CancerType cancerType) { + this.setParent(cancerType); + return this; + } + + public Set getAssociations() { + return this.associations; + } + + public void setAssociations(Set associations) { + if (this.associations != null) { + this.associations.forEach(i -> i.removeCancerType(this)); + } + if (associations != null) { + associations.forEach(i -> i.addCancerType(this)); + } + this.associations = associations; + } + + public CancerType associations(Set associations) { + this.setAssociations(associations); + return this; + } + + public CancerType addAssociation(Association association) { + this.associations.add(association); + association.getCancerTypes().add(this); + return this; + } + + public CancerType removeAssociation(Association association) { + this.associations.remove(association); + association.getCancerTypes().remove(this); + return this; + } + + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof CancerType)) { + return false; + } + return id != null && id.equals(((CancerType) o).id); + } + + @Override + public int hashCode() { + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); + } + + // prettier-ignore + @Override + public String toString() { + return "CancerType{" + + "id=" + getId() + + ", code='" + getCode() + "'" + + ", color='" + getColor() + "'" + + ", level=" + getLevel() + + ", mainType='" + getMainType() + "'" + + ", subtype='" + getSubtype() + "'" + + ", tissue='" + getTissue() + "'" + + ", tumorForm='" + getTumorForm() + "'" + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/CategoricalAlteration.java b/src/main/java/org/mskcc/oncokb/curation/domain/CategoricalAlteration.java new file mode 100644 index 000000000..5e8abf244 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/CategoricalAlteration.java @@ -0,0 +1,137 @@ +package org.mskcc.oncokb.curation.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; +import java.io.Serializable; +import org.mskcc.oncokb.curation.domain.enumeration.AlterationType; + +/** + * A CategoricalAlteration. + */ +@Entity +@Table(name = "categorical_alteration") +public class CategoricalAlteration implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @NotNull + @Enumerated(EnumType.STRING) + @Column(name = "alteration_type", nullable = false) + private AlterationType alterationType; + + @NotNull + @Column(name = "type", nullable = false, unique = true) + private String type; + + @NotNull + @Column(name = "name", nullable = false) + private String name; + + @ManyToOne + @JsonIgnoreProperties(value = { "alterations", "categoricalAlterations" }, allowSetters = true) + @JoinColumn(name = "consequence", referencedColumnName = "term") + private Consequence consequence; + + // jhipster-needle-entity-add-field - JHipster will add fields here + + public Long getId() { + return this.id; + } + + public CategoricalAlteration id(Long id) { + this.setId(id); + return this; + } + + public void setId(Long id) { + this.id = id; + } + + public AlterationType getAlterationType() { + return this.alterationType; + } + + public CategoricalAlteration alterationType(AlterationType alterationType) { + this.setAlterationType(alterationType); + return this; + } + + public void setAlterationType(AlterationType alterationType) { + this.alterationType = alterationType; + } + + public String getType() { + return this.type; + } + + public CategoricalAlteration type(String type) { + this.setType(type); + return this; + } + + public void setType(String type) { + this.type = type; + } + + public String getName() { + return this.name; + } + + public CategoricalAlteration name(String name) { + this.setName(name); + return this; + } + + public void setName(String name) { + this.name = name; + } + + public Consequence getConsequence() { + return this.consequence; + } + + public void setConsequence(Consequence consequence) { + this.consequence = consequence; + } + + public CategoricalAlteration consequence(Consequence consequence) { + this.setConsequence(consequence); + return this; + } + + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof CategoricalAlteration)) { + return false; + } + return id != null && id.equals(((CategoricalAlteration) o).id); + } + + @Override + public int hashCode() { + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); + } + + // prettier-ignore + @Override + public String toString() { + return "CategoricalAlteration{" + + "id=" + getId() + + ", alterationType='" + getAlterationType() + "'" + + ", type='" + getType() + "'" + + ", name='" + getName() + "'" + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/ClinicalTrial.java b/src/main/java/org/mskcc/oncokb/curation/domain/ClinicalTrial.java new file mode 100644 index 000000000..a148f637d --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/ClinicalTrial.java @@ -0,0 +1,257 @@ +package org.mskcc.oncokb.curation.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; +import org.javers.core.metamodel.annotation.ShallowReference; + +/** + * A ClinicalTrial. + */ +@Entity +@Table(name = "clinical_trial") +public class ClinicalTrial implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @Column(name = "nct_id") + private String nctId; + + @NotNull + @Column(name = "brief_title", nullable = false) + private String briefTitle; + + @Column(name = "phase") + private String phase; + + @Column(name = "status") + private String status; + + @ShallowReference + @OneToMany(mappedBy = "clinicalTrial") + @JsonIgnoreProperties(value = { "associations", "clinicalTrial" }, allowSetters = true) + private Set clinicalTrialArms = new HashSet<>(); + + @ShallowReference + @OneToMany(mappedBy = "clinicalTrial") + @JsonIgnoreProperties(value = { "associations", "clinicalTrial" }, allowSetters = true) + private Set eligibilityCriteria = new HashSet<>(); + + @ShallowReference + @ManyToMany(cascade = CascadeType.ALL) + @JoinTable( + name = "rel_clinical_trial__association", + joinColumns = @JoinColumn(name = "clinical_trial_id"), + inverseJoinColumns = @JoinColumn(name = "association_id") + ) + @JsonIgnoreProperties( + value = { + "rules", + "alterations", + "articles", + "cancerTypes", + "drugs", + "evidence", + "clinicalTrials", + "clinicalTrialArms", + "eligibilityCriteria", + "fdaSubmissions", + "genomicIndicators", + }, + allowSetters = true + ) + private Set associations = new HashSet<>(); + + // jhipster-needle-entity-add-field - JHipster will add fields here + + public Long getId() { + return this.id; + } + + public ClinicalTrial id(Long id) { + this.setId(id); + return this; + } + + public void setId(Long id) { + this.id = id; + } + + public String getNctId() { + return this.nctId; + } + + public ClinicalTrial nctId(String nctId) { + this.setNctId(nctId); + return this; + } + + public void setNctId(String nctId) { + this.nctId = nctId; + } + + public String getBriefTitle() { + return this.briefTitle; + } + + public ClinicalTrial briefTitle(String briefTitle) { + this.setBriefTitle(briefTitle); + return this; + } + + public void setBriefTitle(String briefTitle) { + this.briefTitle = briefTitle; + } + + public String getPhase() { + return this.phase; + } + + public ClinicalTrial phase(String phase) { + this.setPhase(phase); + return this; + } + + public void setPhase(String phase) { + this.phase = phase; + } + + public String getStatus() { + return this.status; + } + + public ClinicalTrial status(String status) { + this.setStatus(status); + return this; + } + + public void setStatus(String status) { + this.status = status; + } + + public Set getClinicalTrialArms() { + return this.clinicalTrialArms; + } + + public void setClinicalTrialArms(Set clinicalTrialArms) { + if (this.clinicalTrialArms != null) { + this.clinicalTrialArms.forEach(i -> i.setClinicalTrial(null)); + } + if (clinicalTrialArms != null) { + clinicalTrialArms.forEach(i -> i.setClinicalTrial(this)); + } + this.clinicalTrialArms = clinicalTrialArms; + } + + public ClinicalTrial clinicalTrialArms(Set clinicalTrialArms) { + this.setClinicalTrialArms(clinicalTrialArms); + return this; + } + + public ClinicalTrial addClinicalTrialArm(ClinicalTrialArm clinicalTrialArm) { + this.clinicalTrialArms.add(clinicalTrialArm); + clinicalTrialArm.setClinicalTrial(this); + return this; + } + + public ClinicalTrial removeClinicalTrialArm(ClinicalTrialArm clinicalTrialArm) { + this.clinicalTrialArms.remove(clinicalTrialArm); + clinicalTrialArm.setClinicalTrial(null); + return this; + } + + public Set getEligibilityCriteria() { + return this.eligibilityCriteria; + } + + public void setEligibilityCriteria(Set eligibilityCriteria) { + if (this.eligibilityCriteria != null) { + this.eligibilityCriteria.forEach(i -> i.setClinicalTrial(null)); + } + if (eligibilityCriteria != null) { + eligibilityCriteria.forEach(i -> i.setClinicalTrial(this)); + } + this.eligibilityCriteria = eligibilityCriteria; + } + + public ClinicalTrial eligibilityCriteria(Set eligibilityCriteria) { + this.setEligibilityCriteria(eligibilityCriteria); + return this; + } + + public ClinicalTrial addEligibilityCriteria(EligibilityCriteria eligibilityCriteria) { + this.eligibilityCriteria.add(eligibilityCriteria); + eligibilityCriteria.setClinicalTrial(this); + return this; + } + + public ClinicalTrial removeEligibilityCriteria(EligibilityCriteria eligibilityCriteria) { + this.eligibilityCriteria.remove(eligibilityCriteria); + eligibilityCriteria.setClinicalTrial(null); + return this; + } + + public Set getAssociations() { + return this.associations; + } + + public void setAssociations(Set associations) { + this.associations = associations; + } + + public ClinicalTrial associations(Set associations) { + this.setAssociations(associations); + return this; + } + + public ClinicalTrial addAssociation(Association association) { + this.associations.add(association); + association.getClinicalTrials().add(this); + return this; + } + + public ClinicalTrial removeAssociation(Association association) { + this.associations.remove(association); + association.getClinicalTrials().remove(this); + return this; + } + + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof ClinicalTrial)) { + return false; + } + return id != null && id.equals(((ClinicalTrial) o).id); + } + + @Override + public int hashCode() { + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); + } + + // prettier-ignore + @Override + public String toString() { + return "ClinicalTrial{" + + "id=" + getId() + + ", nctId='" + getNctId() + "'" + + ", briefTitle='" + getBriefTitle() + "'" + + ", phase='" + getPhase() + "'" + + ", status='" + getStatus() + "'" + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/ClinicalTrialArm.java b/src/main/java/org/mskcc/oncokb/curation/domain/ClinicalTrialArm.java new file mode 100644 index 000000000..4156b2351 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/ClinicalTrialArm.java @@ -0,0 +1,152 @@ +package org.mskcc.oncokb.curation.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; +import org.javers.core.metamodel.annotation.ShallowReference; + +/** + * A ClinicalTrialArm. + */ +@Entity +@Table(name = "clinical_trial_arm") +public class ClinicalTrialArm implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @NotNull + @Column(name = "name", nullable = false) + private String name; + + @ShallowReference + @ManyToMany(cascade = CascadeType.ALL) + @JoinTable( + name = "rel_clinical_trial_arm__association", + joinColumns = @JoinColumn(name = "clinical_trial_arm_id"), + inverseJoinColumns = @JoinColumn(name = "association_id") + ) + @JsonIgnoreProperties( + value = { + "rules", + "alterations", + "articles", + "cancerTypes", + "drugs", + "evidence", + "clinicalTrials", + "clinicalTrialArms", + "eligibilityCriteria", + "fdaSubmissions", + "genomicIndicators", + }, + allowSetters = true + ) + private Set associations = new HashSet<>(); + + @ShallowReference + @ManyToOne + @JsonIgnoreProperties(value = { "clinicalTrialArms", "eligibilityCriteria", "associations" }, allowSetters = true) + private ClinicalTrial clinicalTrial; + + // jhipster-needle-entity-add-field - JHipster will add fields here + + public Long getId() { + return this.id; + } + + public ClinicalTrialArm id(Long id) { + this.setId(id); + return this; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return this.name; + } + + public ClinicalTrialArm name(String name) { + this.setName(name); + return this; + } + + public void setName(String name) { + this.name = name; + } + + public Set getAssociations() { + return this.associations; + } + + public void setAssociations(Set associations) { + this.associations = associations; + } + + public ClinicalTrialArm associations(Set associations) { + this.setAssociations(associations); + return this; + } + + public ClinicalTrialArm addAssociation(Association association) { + this.associations.add(association); + association.getClinicalTrialArms().add(this); + return this; + } + + public ClinicalTrialArm removeAssociation(Association association) { + this.associations.remove(association); + association.getClinicalTrialArms().remove(this); + return this; + } + + public ClinicalTrial getClinicalTrial() { + return this.clinicalTrial; + } + + public void setClinicalTrial(ClinicalTrial clinicalTrial) { + this.clinicalTrial = clinicalTrial; + } + + public ClinicalTrialArm clinicalTrial(ClinicalTrial clinicalTrial) { + this.setClinicalTrial(clinicalTrial); + return this; + } + + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof ClinicalTrialArm)) { + return false; + } + return id != null && id.equals(((ClinicalTrialArm) o).id); + } + + @Override + public int hashCode() { + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); + } + + // prettier-ignore + @Override + public String toString() { + return "ClinicalTrialArm{" + + "id=" + getId() + + ", name='" + getName() + "'" + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/CompanionDiagnosticDevice.java b/src/main/java/org/mskcc/oncokb/curation/domain/CompanionDiagnosticDevice.java new file mode 100644 index 000000000..150bac4e6 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/CompanionDiagnosticDevice.java @@ -0,0 +1,223 @@ +package org.mskcc.oncokb.curation.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; +import java.io.Serializable; +import java.time.Instant; +import java.util.HashSet; +import java.util.Set; +import org.javers.core.metamodel.annotation.ShallowReference; + +/** + * A CompanionDiagnosticDevice. + */ +@Entity +@Table(name = "companion_diagnostic_device") +public class CompanionDiagnosticDevice implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @NotNull + @Column(name = "name", nullable = false) + private String name; + + @NotNull + @Column(name = "manufacturer", nullable = false) + private String manufacturer; + + @Column(name = "indication_details") + private String indicationDetails; + + @Column(name = "platform_type") + private String platformType; + + @Column(name = "last_updated") + private Instant lastUpdated; + + @ShallowReference + @OneToMany(mappedBy = "companionDiagnosticDevice") + @JsonIgnoreProperties(value = { "companionDiagnosticDevice" }, allowSetters = true) + private Set fdaSubmissions = new HashSet<>(); + + @ShallowReference + @ManyToMany + @JoinTable( + name = "rel_companion_diagnostic_device__specimen_type", + joinColumns = @JoinColumn(name = "companion_diagnostic_device_id"), + inverseJoinColumns = @JoinColumn(name = "specimen_type_id") + ) + @JsonIgnoreProperties(value = { "companionDiagnosticDevices" }, allowSetters = true) + private Set specimenTypes = new HashSet<>(); + + // jhipster-needle-entity-add-field - JHipster will add fields here + + public Long getId() { + return this.id; + } + + public CompanionDiagnosticDevice id(Long id) { + this.setId(id); + return this; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return this.name; + } + + public CompanionDiagnosticDevice name(String name) { + this.setName(name); + return this; + } + + public void setName(String name) { + this.name = name; + } + + public String getManufacturer() { + return this.manufacturer; + } + + public CompanionDiagnosticDevice manufacturer(String manufacturer) { + this.setManufacturer(manufacturer); + return this; + } + + public void setManufacturer(String manufacturer) { + this.manufacturer = manufacturer; + } + + public String getIndicationDetails() { + return this.indicationDetails; + } + + public CompanionDiagnosticDevice indicationDetails(String indicationDetails) { + this.setIndicationDetails(indicationDetails); + return this; + } + + public void setIndicationDetails(String indicationDetails) { + this.indicationDetails = indicationDetails; + } + + public String getPlatformType() { + return this.platformType; + } + + public CompanionDiagnosticDevice platformType(String platformType) { + this.setPlatformType(platformType); + return this; + } + + public void setPlatformType(String platformType) { + this.platformType = platformType; + } + + public Instant getLastUpdated() { + return this.lastUpdated; + } + + public CompanionDiagnosticDevice lastUpdated(Instant lastUpdated) { + this.setLastUpdated(lastUpdated); + return this; + } + + public void setLastUpdated(Instant lastUpdated) { + this.lastUpdated = lastUpdated; + } + + public Set getFdaSubmissions() { + return this.fdaSubmissions; + } + + public void setFdaSubmissions(Set fdaSubmissions) { + if (this.fdaSubmissions != null) { + this.fdaSubmissions.forEach(i -> i.setCompanionDiagnosticDevice(null)); + } + if (fdaSubmissions != null) { + fdaSubmissions.forEach(i -> i.setCompanionDiagnosticDevice(this)); + } + this.fdaSubmissions = fdaSubmissions; + } + + public CompanionDiagnosticDevice fdaSubmissions(Set fdaSubmissions) { + this.setFdaSubmissions(fdaSubmissions); + return this; + } + + public CompanionDiagnosticDevice addFdaSubmission(FdaSubmission fdaSubmission) { + this.fdaSubmissions.add(fdaSubmission); + fdaSubmission.setCompanionDiagnosticDevice(this); + return this; + } + + public CompanionDiagnosticDevice removeFdaSubmission(FdaSubmission fdaSubmission) { + this.fdaSubmissions.remove(fdaSubmission); + fdaSubmission.setCompanionDiagnosticDevice(null); + return this; + } + + public Set getSpecimenTypes() { + return this.specimenTypes; + } + + public void setSpecimenTypes(Set specimenTypes) { + this.specimenTypes = specimenTypes; + } + + public CompanionDiagnosticDevice specimenTypes(Set specimenTypes) { + this.setSpecimenTypes(specimenTypes); + return this; + } + + public CompanionDiagnosticDevice addSpecimenType(SpecimenType specimenType) { + this.specimenTypes.add(specimenType); + return this; + } + + public CompanionDiagnosticDevice removeSpecimenType(SpecimenType specimenType) { + this.specimenTypes.remove(specimenType); + return this; + } + + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof CompanionDiagnosticDevice)) { + return false; + } + return id != null && id.equals(((CompanionDiagnosticDevice) o).id); + } + + @Override + public int hashCode() { + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); + } + + // prettier-ignore + @Override + public String toString() { + return "CompanionDiagnosticDevice{" + + "id=" + getId() + + ", name='" + getName() + "'" + + ", manufacturer='" + getManufacturer() + "'" + + ", indicationDetails='" + getIndicationDetails() + "'" + + ", platformType='" + getPlatformType() + "'" + + ", lastUpdated='" + getLastUpdated() + "'" + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/Consequence.java b/src/main/java/org/mskcc/oncokb/curation/domain/Consequence.java new file mode 100644 index 000000000..816d9aaea --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/Consequence.java @@ -0,0 +1,208 @@ +package org.mskcc.oncokb.curation.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; +import org.javers.core.metamodel.annotation.DiffIgnore; + +/** + * A Consequence. + */ +@Entity +@Table(name = "consequence") +public class Consequence implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @NotNull + @Column(name = "term", nullable = false, unique = true) + private String term; + + @NotNull + @Column(name = "name", nullable = false) + private String name; + + @NotNull + @Column(name = "is_generally_truncating", nullable = false) + private Boolean isGenerallyTruncating; + + @Column(name = "description") + private String description; + + @DiffIgnore + @OneToMany(mappedBy = "consequence") + @JsonIgnoreProperties(value = { "flags", "genes", "transcripts", "consequence", "associations" }, allowSetters = true) + private Set alterations = new HashSet<>(); + + @OneToMany(mappedBy = "consequence") + @JsonIgnoreProperties(value = { "consequence" }, allowSetters = true) + private Set categoricalAlterations = new HashSet<>(); + + // jhipster-needle-entity-add-field - JHipster will add fields here + + public Long getId() { + return this.id; + } + + public Consequence id(Long id) { + this.setId(id); + return this; + } + + public void setId(Long id) { + this.id = id; + } + + public String getTerm() { + return this.term; + } + + public Consequence term(String term) { + this.setTerm(term); + return this; + } + + public void setTerm(String term) { + this.term = term; + } + + public String getName() { + return this.name; + } + + public Consequence name(String name) { + this.setName(name); + return this; + } + + public void setName(String name) { + this.name = name; + } + + public Boolean getIsGenerallyTruncating() { + return this.isGenerallyTruncating; + } + + public Consequence isGenerallyTruncating(Boolean isGenerallyTruncating) { + this.setIsGenerallyTruncating(isGenerallyTruncating); + return this; + } + + public void setIsGenerallyTruncating(Boolean isGenerallyTruncating) { + this.isGenerallyTruncating = isGenerallyTruncating; + } + + public String getDescription() { + return this.description; + } + + public Consequence description(String description) { + this.setDescription(description); + return this; + } + + public void setDescription(String description) { + this.description = description; + } + + public Set getAlterations() { + return this.alterations; + } + + public void setAlterations(Set alterations) { + if (this.alterations != null) { + this.alterations.forEach(i -> i.setConsequence(null)); + } + if (alterations != null) { + alterations.forEach(i -> i.setConsequence(this)); + } + this.alterations = alterations; + } + + public Consequence alterations(Set alterations) { + this.setAlterations(alterations); + return this; + } + + public Consequence addAlteration(Alteration alteration) { + this.alterations.add(alteration); + alteration.setConsequence(this); + return this; + } + + public Consequence removeAlteration(Alteration alteration) { + this.alterations.remove(alteration); + alteration.setConsequence(null); + return this; + } + + public Set getCategoricalAlterations() { + return this.categoricalAlterations; + } + + public void setCategoricalAlterations(Set categoricalAlterations) { + if (this.categoricalAlterations != null) { + this.categoricalAlterations.forEach(i -> i.setConsequence(null)); + } + if (categoricalAlterations != null) { + categoricalAlterations.forEach(i -> i.setConsequence(this)); + } + this.categoricalAlterations = categoricalAlterations; + } + + public Consequence categoricalAlterations(Set categoricalAlterations) { + this.setCategoricalAlterations(categoricalAlterations); + return this; + } + + public Consequence addCategoricalAlteration(CategoricalAlteration categoricalAlteration) { + this.categoricalAlterations.add(categoricalAlteration); + categoricalAlteration.setConsequence(this); + return this; + } + + public Consequence removeCategoricalAlteration(CategoricalAlteration categoricalAlteration) { + this.categoricalAlterations.remove(categoricalAlteration); + categoricalAlteration.setConsequence(null); + return this; + } + + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Consequence)) { + return false; + } + return id != null && id.equals(((Consequence) o).id); + } + + @Override + public int hashCode() { + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); + } + + // prettier-ignore + @Override + public String toString() { + return "Consequence{" + + "id=" + getId() + + ", term='" + getTerm() + "'" + + ", name='" + getName() + "'" + + ", isGenerallyTruncating='" + getIsGenerallyTruncating() + "'" + + ", description='" + getDescription() + "'" + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/Drug.java b/src/main/java/org/mskcc/oncokb/curation/domain/Drug.java new file mode 100644 index 000000000..44f91289e --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/Drug.java @@ -0,0 +1,225 @@ +package org.mskcc.oncokb.curation.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; +import org.javers.core.metamodel.annotation.DiffIgnore; +import org.javers.core.metamodel.annotation.ShallowReference; + +/** + * A Drug. + */ +@Entity +@Table(name = "drug") +public class Drug implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @NotNull + @Column(name = "uuid", nullable = false, unique = true) + private String uuid; + + @Lob + @Column(name = "name", nullable = false) + private String name; + + @OneToOne + @JoinColumn(unique = true, name = "ncit_code", referencedColumnName = "code") + private NciThesaurus nciThesaurus; + + @ShallowReference + @OneToMany(mappedBy = "drug") + @JsonIgnoreProperties(value = { "fdaSubmissions", "drug" }, allowSetters = true) + private Set fdaDrugs = new HashSet<>(); + + @ManyToMany + @JoinTable(name = "rel_drug__flag", joinColumns = @JoinColumn(name = "drug_id"), inverseJoinColumns = @JoinColumn(name = "flag_id")) + @JsonIgnoreProperties(value = { "alterations", "articles", "drugs", "genes", "transcripts" }, allowSetters = true) + private Set flags = new HashSet<>(); + + @DiffIgnore + @ManyToMany(mappedBy = "drugs") + @JsonIgnoreProperties( + value = { "evidence", "clinicalTrials", "clinicalTrialArms", "eligibilityCriteria", "fdaSubmissions", "genomicIndicators" }, + allowSetters = true + ) + private Set associations = new HashSet<>(); + + // jhipster-needle-entity-add-field - JHipster will add fields here + + public Long getId() { + return this.id; + } + + public Drug id(Long id) { + this.setId(id); + return this; + } + + public void setId(Long id) { + this.id = id; + } + + public String getUuid() { + return this.uuid; + } + + public Drug uuid(String uuid) { + this.setUuid(uuid); + return this; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getName() { + return this.name; + } + + public Drug name(String name) { + this.setName(name); + return this; + } + + public void setName(String name) { + this.name = name; + } + + public NciThesaurus getNciThesaurus() { + return this.nciThesaurus; + } + + public void setNciThesaurus(NciThesaurus nciThesaurus) { + this.nciThesaurus = nciThesaurus; + } + + public Drug nciThesaurus(NciThesaurus nciThesaurus) { + this.setNciThesaurus(nciThesaurus); + return this; + } + + public Set getFdaDrugs() { + return this.fdaDrugs; + } + + public void setFdaDrugs(Set fdaDrugs) { + if (this.fdaDrugs != null) { + this.fdaDrugs.forEach(i -> i.setDrug(null)); + } + if (fdaDrugs != null) { + fdaDrugs.forEach(i -> i.setDrug(this)); + } + this.fdaDrugs = fdaDrugs; + } + + public Drug fdaDrugs(Set fdaDrugs) { + this.setFdaDrugs(fdaDrugs); + return this; + } + + public Drug addFdaDrug(FdaDrug fdaDrug) { + this.fdaDrugs.add(fdaDrug); + fdaDrug.setDrug(this); + return this; + } + + public Drug removeFdaDrug(FdaDrug fdaDrug) { + this.fdaDrugs.remove(fdaDrug); + fdaDrug.setDrug(null); + return this; + } + + public Set getFlags() { + return this.flags; + } + + public void setFlags(Set flags) { + this.flags = flags; + } + + public Drug flags(Set flags) { + this.setFlags(flags); + return this; + } + + public Drug addFlag(Flag flag) { + this.flags.add(flag); + flag.getDrugs().add(this); + return this; + } + + public Drug removeFlag(Flag flag) { + this.flags.remove(flag); + flag.getDrugs().remove(this); + return this; + } + + public Set getAssociations() { + return this.associations; + } + + public void setAssociations(Set associations) { + if (this.associations != null) { + this.associations.forEach(i -> i.removeDrug(this)); + } + if (associations != null) { + associations.forEach(i -> i.addDrug(this)); + } + this.associations = associations; + } + + public Drug associations(Set associations) { + this.setAssociations(associations); + return this; + } + + public Drug addAssociation(Association association) { + this.associations.add(association); + association.getDrugs().add(this); + return this; + } + + public Drug removeAssociation(Association association) { + this.associations.remove(association); + association.getDrugs().remove(this); + return this; + } + + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Drug)) { + return false; + } + return id != null && id.equals(((Drug) o).id); + } + + @Override + public int hashCode() { + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); + } + + // prettier-ignore + @Override + public String toString() { + return "Drug{" + + "id=" + getId() + + ", uuid='" + getUuid() + "'" + + ", name='" + getName() + "'" + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/EligibilityCriteria.java b/src/main/java/org/mskcc/oncokb/curation/domain/EligibilityCriteria.java new file mode 100644 index 000000000..25550a61b --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/EligibilityCriteria.java @@ -0,0 +1,191 @@ +package org.mskcc.oncokb.curation.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; +import org.javers.core.metamodel.annotation.DiffIgnore; +import org.javers.core.metamodel.annotation.ShallowReference; +import org.mskcc.oncokb.curation.domain.enumeration.EligibilityCriteriaType; + +/** + * A EligibilityCriteria. + */ +@Entity +@Table(name = "eligibility_criteria") +public class EligibilityCriteria implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @NotNull + @Enumerated(EnumType.STRING) + @Column(name = "type", nullable = false) + private EligibilityCriteriaType type; + + @Column(name = "priority") + private Integer priority; + + @DiffIgnore + @Lob + @Column(name = "criteria") + private String criteria; + + @ShallowReference + @ManyToMany(cascade = CascadeType.ALL) + @JoinTable( + name = "rel_eligibility_criteria__association", + joinColumns = @JoinColumn(name = "eligibility_criteria_id"), + inverseJoinColumns = @JoinColumn(name = "association_id") + ) + @JsonIgnoreProperties( + value = { + "rules", + "alterations", + "articles", + "cancerTypes", + "drugs", + "evidence", + "clinicalTrials", + "clinicalTrialArms", + "eligibilityCriteria", + "fdaSubmissions", + "genomicIndicators", + }, + allowSetters = true + ) + private Set associations = new HashSet<>(); + + @ShallowReference + @ManyToOne + @JsonIgnoreProperties(value = { "clinicalTrialArms", "eligibilityCriteria", "associations" }, allowSetters = true) + private ClinicalTrial clinicalTrial; + + // jhipster-needle-entity-add-field - JHipster will add fields here + + public Long getId() { + return this.id; + } + + public EligibilityCriteria id(Long id) { + this.setId(id); + return this; + } + + public void setId(Long id) { + this.id = id; + } + + public EligibilityCriteriaType getType() { + return this.type; + } + + public EligibilityCriteria type(EligibilityCriteriaType type) { + this.setType(type); + return this; + } + + public void setType(EligibilityCriteriaType type) { + this.type = type; + } + + public Integer getPriority() { + return this.priority; + } + + public EligibilityCriteria priority(Integer priority) { + this.setPriority(priority); + return this; + } + + public void setPriority(Integer priority) { + this.priority = priority; + } + + public String getCriteria() { + return this.criteria; + } + + public EligibilityCriteria criteria(String criteria) { + this.setCriteria(criteria); + return this; + } + + public void setCriteria(String criteria) { + this.criteria = criteria; + } + + public Set getAssociations() { + return this.associations; + } + + public void setAssociations(Set associations) { + this.associations = associations; + } + + public EligibilityCriteria associations(Set associations) { + this.setAssociations(associations); + return this; + } + + public EligibilityCriteria addAssociation(Association association) { + this.associations.add(association); + association.getEligibilityCriteria().add(this); + return this; + } + + public EligibilityCriteria removeAssociation(Association association) { + this.associations.remove(association); + association.getEligibilityCriteria().remove(this); + return this; + } + + public ClinicalTrial getClinicalTrial() { + return this.clinicalTrial; + } + + public void setClinicalTrial(ClinicalTrial clinicalTrial) { + this.clinicalTrial = clinicalTrial; + } + + public EligibilityCriteria clinicalTrial(ClinicalTrial clinicalTrial) { + this.setClinicalTrial(clinicalTrial); + return this; + } + + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof EligibilityCriteria)) { + return false; + } + return id != null && id.equals(((EligibilityCriteria) o).id); + } + + @Override + public int hashCode() { + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); + } + + // prettier-ignore + @Override + public String toString() { + return "EligibilityCriteria{" + + "id=" + getId() + + ", type='" + getType() + "'" + + ", priority=" + getPriority() + + ", criteria='" + getCriteria() + "'" + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/transcript/domain/EnrichedAlignmentResult.java b/src/main/java/org/mskcc/oncokb/curation/domain/EnrichedAlignmentResult.java similarity index 95% rename from src/main/java/org/mskcc/oncokb/transcript/domain/EnrichedAlignmentResult.java rename to src/main/java/org/mskcc/oncokb/curation/domain/EnrichedAlignmentResult.java index 120dd1dbf..3a2f475d2 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/domain/EnrichedAlignmentResult.java +++ b/src/main/java/org/mskcc/oncokb/curation/domain/EnrichedAlignmentResult.java @@ -1,4 +1,4 @@ -package org.mskcc.oncokb.transcript.domain; +package org.mskcc.oncokb.curation.domain; import org.genome_nexus.client.EnsemblTranscript; diff --git a/src/main/java/org/mskcc/oncokb/transcript/domain/EnsemblGene.java b/src/main/java/org/mskcc/oncokb/curation/domain/EnsemblGene.java similarity index 78% rename from src/main/java/org/mskcc/oncokb/transcript/domain/EnsemblGene.java rename to src/main/java/org/mskcc/oncokb/curation/domain/EnsemblGene.java index d94f8804f..43a39df58 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/domain/EnsemblGene.java +++ b/src/main/java/org/mskcc/oncokb/curation/domain/EnsemblGene.java @@ -1,11 +1,13 @@ -package org.mskcc.oncokb.transcript.domain; +package org.mskcc.oncokb.curation.domain; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; import java.io.Serializable; import java.util.HashSet; import java.util.Set; -import javax.persistence.*; -import javax.validation.constraints.*; +import org.javers.core.metamodel.annotation.ShallowReference; +import org.mskcc.oncokb.curation.domain.enumeration.ReferenceGenome; /** * A EnsemblGene. @@ -21,9 +23,9 @@ public class EnsemblGene implements Serializable { @Column(name = "id") private Long id; - @NotNull - @Column(name = "reference_genome", nullable = false) - private String referenceGenome; + @Enumerated(EnumType.STRING) + @Column(name = "reference_genome") + private ReferenceGenome referenceGenome; @NotNull @Column(name = "ensembl_gene_id", nullable = false) @@ -33,10 +35,6 @@ public class EnsemblGene implements Serializable { @Column(name = "canonical", nullable = false) private Boolean canonical = false; - @NotNull - @Column(name = "chromosome", nullable = false) - private String chromosome; - @NotNull @Column(name = "start", nullable = false) private Integer start; @@ -49,14 +47,21 @@ public class EnsemblGene implements Serializable { @Column(name = "strand", nullable = false) private Integer strand; + @ShallowReference @OneToMany(mappedBy = "ensemblGene") - @JsonIgnoreProperties(value = { "fragments", "sequences", "ensemblGene" }, allowSetters = true) + @JsonIgnoreProperties(value = { "sequences", "fragments", "flags", "ensemblGene", "gene", "alterations" }, allowSetters = true) private Set transcripts = new HashSet<>(); @ManyToOne - @JsonIgnoreProperties(value = { "geneAliases", "ensemblGenes" }, allowSetters = true) + @JsonIgnoreProperties(value = { "ensemblGenes", "evidences", "transcripts", "flags", "synonyms", "alterations" }, allowSetters = true) private Gene gene; + @ShallowReference + @ManyToOne + @JsonIgnoreProperties(value = { "ensemblGenes", "genomeFragments" }, allowSetters = true) + @JoinColumn(name = "seq_region", referencedColumnName = "name") + private SeqRegion seqRegion; + // jhipster-needle-entity-add-field - JHipster will add fields here public Long getId() { @@ -72,16 +77,16 @@ public void setId(Long id) { this.id = id; } - public String getReferenceGenome() { + public ReferenceGenome getReferenceGenome() { return this.referenceGenome; } - public EnsemblGene referenceGenome(String referenceGenome) { + public EnsemblGene referenceGenome(ReferenceGenome referenceGenome) { this.setReferenceGenome(referenceGenome); return this; } - public void setReferenceGenome(String referenceGenome) { + public void setReferenceGenome(ReferenceGenome referenceGenome) { this.referenceGenome = referenceGenome; } @@ -111,19 +116,6 @@ public void setCanonical(Boolean canonical) { this.canonical = canonical; } - public String getChromosome() { - return this.chromosome; - } - - public EnsemblGene chromosome(String chromosome) { - this.setChromosome(chromosome); - return this; - } - - public void setChromosome(String chromosome) { - this.chromosome = chromosome; - } - public Integer getStart() { return this.start; } @@ -207,6 +199,19 @@ public EnsemblGene gene(Gene gene) { return this; } + public SeqRegion getSeqRegion() { + return this.seqRegion; + } + + public void setSeqRegion(SeqRegion seqRegion) { + this.seqRegion = seqRegion; + } + + public EnsemblGene seqRegion(SeqRegion seqRegion) { + this.setSeqRegion(seqRegion); + return this; + } + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here @Override @@ -234,7 +239,6 @@ public String toString() { ", referenceGenome='" + getReferenceGenome() + "'" + ", ensemblGeneId='" + getEnsemblGeneId() + "'" + ", canonical='" + getCanonical() + "'" + - ", chromosome='" + getChromosome() + "'" + ", start=" + getStart() + ", end=" + getEnd() + ", strand=" + getStrand() + diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/EntityStatus.java b/src/main/java/org/mskcc/oncokb/curation/domain/EntityStatus.java new file mode 100644 index 000000000..bb702be5d --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/EntityStatus.java @@ -0,0 +1,46 @@ +package org.mskcc.oncokb.curation.domain; + +import org.mskcc.oncokb.curation.domain.enumeration.EntityStatusType; + +public class EntityStatus { + + T entity; + String message; + EntityStatusType type; + + public T getEntity() { + return entity; + } + + public void setEntity(T entity) { + this.entity = entity; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public EntityStatusType getType() { + return type; + } + + public void setType(EntityStatusType type) { + this.type = type; + } + + public boolean isOk() { + return type.equals(EntityStatusType.OK); + } + + public boolean isWarning() { + return type.equals(EntityStatusType.WARNING); + } + + public boolean isError() { + return type.equals(EntityStatusType.ERROR); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/Evidence.java b/src/main/java/org/mskcc/oncokb/curation/domain/Evidence.java new file mode 100644 index 000000000..5d0b4898d --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/Evidence.java @@ -0,0 +1,242 @@ +package org.mskcc.oncokb.curation.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; +import org.javers.core.metamodel.annotation.DiffIgnore; +import org.javers.core.metamodel.annotation.ShallowReference; + +/** + * A Evidence. + */ +@Entity +@Table(name = "evidence") +public class Evidence implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @Column(name = "uuid") + private String uuid; + + @NotNull + @Column(name = "evidence_type", nullable = false) + private String evidenceType; + + @Column(name = "known_effect") + private String knownEffect; + + @Lob + @Column(name = "description") + private String description; + + @DiffIgnore + @Lob + @Column(name = "note") + private String note; + + @JsonIgnoreProperties( + value = { + "rules", + "alterations", + "articles", + "cancerTypes", + "drugs", + "evidence", + "clinicalTrials", + "clinicalTrialArms", + "eligibilityCriteria", + "fdaSubmissions", + "genomicIndicators", + }, + allowSetters = true + ) + @ShallowReference + @OneToOne + @JoinColumn(unique = true) + private Association association; + + @ManyToMany + @JoinTable( + name = "rel_evidence__level_of_evidence", + joinColumns = @JoinColumn(name = "evidence_id"), + inverseJoinColumns = @JoinColumn(name = "level_of_evidence_id") + ) + @JsonIgnoreProperties(value = { "evidences" }, allowSetters = true) + private Set levelOfEvidences = new HashSet<>(); + + @ShallowReference + @ManyToOne + @JsonIgnoreProperties(value = { "ensemblGenes", "evidences", "transcripts", "flags", "synonyms", "alterations" }, allowSetters = true) + private Gene gene; + + // jhipster-needle-entity-add-field - JHipster will add fields here + + public Long getId() { + return this.id; + } + + public Evidence id(Long id) { + this.setId(id); + return this; + } + + public void setId(Long id) { + this.id = id; + } + + public String getUuid() { + return this.uuid; + } + + public Evidence uuid(String uuid) { + this.setUuid(uuid); + return this; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getEvidenceType() { + return this.evidenceType; + } + + public Evidence evidenceType(String evidenceType) { + this.setEvidenceType(evidenceType); + return this; + } + + public void setEvidenceType(String evidenceType) { + this.evidenceType = evidenceType; + } + + public String getKnownEffect() { + return this.knownEffect; + } + + public Evidence knownEffect(String knownEffect) { + this.setKnownEffect(knownEffect); + return this; + } + + public void setKnownEffect(String knownEffect) { + this.knownEffect = knownEffect; + } + + public String getDescription() { + return this.description; + } + + public Evidence description(String description) { + this.setDescription(description); + return this; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getNote() { + return this.note; + } + + public Evidence note(String note) { + this.setNote(note); + return this; + } + + public void setNote(String note) { + this.note = note; + } + + public Association getAssociation() { + return this.association; + } + + public void setAssociation(Association association) { + this.association = association; + } + + public Evidence association(Association association) { + this.setAssociation(association); + return this; + } + + public Set getLevelOfEvidences() { + return this.levelOfEvidences; + } + + public void setLevelOfEvidences(Set levelOfEvidences) { + this.levelOfEvidences = levelOfEvidences; + } + + public Evidence levelOfEvidences(Set levelOfEvidences) { + this.setLevelOfEvidences(levelOfEvidences); + return this; + } + + public Evidence addLevelOfEvidence(LevelOfEvidence levelOfEvidence) { + this.levelOfEvidences.add(levelOfEvidence); + levelOfEvidence.getEvidences().add(this); + return this; + } + + public Evidence removeLevelOfEvidence(LevelOfEvidence levelOfEvidence) { + this.levelOfEvidences.remove(levelOfEvidence); + levelOfEvidence.getEvidences().remove(this); + return this; + } + + public Gene getGene() { + return this.gene; + } + + public void setGene(Gene gene) { + this.gene = gene; + } + + public Evidence gene(Gene gene) { + this.setGene(gene); + return this; + } + + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Evidence)) { + return false; + } + return id != null && id.equals(((Evidence) o).id); + } + + @Override + public int hashCode() { + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); + } + + // prettier-ignore + @Override + public String toString() { + return "Evidence{" + + "id=" + getId() + + ", uuid='" + getUuid() + "'" + + ", evidenceType='" + getEvidenceType() + "'" + + ", knownEffect='" + getKnownEffect() + "'" + + ", description='" + getDescription() + "'" + + ", note='" + getNote() + "'" + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/FdaDrug.java b/src/main/java/org/mskcc/oncokb/curation/domain/FdaDrug.java new file mode 100644 index 000000000..463276109 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/FdaDrug.java @@ -0,0 +1,172 @@ +package org.mskcc.oncokb.curation.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; +import org.javers.core.metamodel.annotation.ShallowReference; + +/** + * A FdaDrug. + */ +@Entity +@Table(name = "fda_drug") +public class FdaDrug implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @NotNull + @Column(name = "application_number", nullable = false, unique = true) + private String applicationNumber; + + @Column(name = "sponsor_name") + private String sponsorName; + + @Column(name = "overall_marketing_status") + private String overallMarketingStatus; + + @ShallowReference + @OneToMany(mappedBy = "fdaDrug") + @JsonIgnoreProperties(value = { "articles", "associations", "companionDiagnosticDevice", "fdaDrug", "type" }, allowSetters = true) + private Set fdaSubmissions = new HashSet<>(); + + @ShallowReference + @ManyToOne + @JsonIgnoreProperties(value = { "nciThesaurus", "fdaDrugs", "flags", "associations" }, allowSetters = true) + private Drug drug; + + // jhipster-needle-entity-add-field - JHipster will add fields here + + public Long getId() { + return this.id; + } + + public FdaDrug id(Long id) { + this.setId(id); + return this; + } + + public void setId(Long id) { + this.id = id; + } + + public String getApplicationNumber() { + return this.applicationNumber; + } + + public FdaDrug applicationNumber(String applicationNumber) { + this.setApplicationNumber(applicationNumber); + return this; + } + + public void setApplicationNumber(String applicationNumber) { + this.applicationNumber = applicationNumber; + } + + public String getSponsorName() { + return this.sponsorName; + } + + public FdaDrug sponsorName(String sponsorName) { + this.setSponsorName(sponsorName); + return this; + } + + public void setSponsorName(String sponsorName) { + this.sponsorName = sponsorName; + } + + public String getOverallMarketingStatus() { + return this.overallMarketingStatus; + } + + public FdaDrug overallMarketingStatus(String overallMarketingStatus) { + this.setOverallMarketingStatus(overallMarketingStatus); + return this; + } + + public void setOverallMarketingStatus(String overallMarketingStatus) { + this.overallMarketingStatus = overallMarketingStatus; + } + + public Set getFdaSubmissions() { + return this.fdaSubmissions; + } + + public void setFdaSubmissions(Set fdaSubmissions) { + if (this.fdaSubmissions != null) { + this.fdaSubmissions.forEach(i -> i.setFdaDrug(null)); + } + if (fdaSubmissions != null) { + fdaSubmissions.forEach(i -> i.setFdaDrug(this)); + } + this.fdaSubmissions = fdaSubmissions; + } + + public FdaDrug fdaSubmissions(Set fdaSubmissions) { + this.setFdaSubmissions(fdaSubmissions); + return this; + } + + public FdaDrug addFdaSubmission(FdaSubmission fdaSubmission) { + this.fdaSubmissions.add(fdaSubmission); + fdaSubmission.setFdaDrug(this); + return this; + } + + public FdaDrug removeFdaSubmission(FdaSubmission fdaSubmission) { + this.fdaSubmissions.remove(fdaSubmission); + fdaSubmission.setFdaDrug(null); + return this; + } + + public Drug getDrug() { + return this.drug; + } + + public void setDrug(Drug drug) { + this.drug = drug; + } + + public FdaDrug drug(Drug drug) { + this.setDrug(drug); + return this; + } + + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof FdaDrug)) { + return false; + } + return id != null && id.equals(((FdaDrug) o).id); + } + + @Override + public int hashCode() { + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); + } + + // prettier-ignore + @Override + public String toString() { + return "FdaDrug{" + + "id=" + getId() + + ", applicationNumber='" + getApplicationNumber() + "'" + + ", sponsorName='" + getSponsorName() + "'" + + ", overallMarketingStatus='" + getOverallMarketingStatus() + "'" + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/FdaSubmission.java b/src/main/java/org/mskcc/oncokb/curation/domain/FdaSubmission.java new file mode 100644 index 000000000..a9b879f39 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/FdaSubmission.java @@ -0,0 +1,371 @@ +package org.mskcc.oncokb.curation.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; +import java.io.Serializable; +import java.time.LocalDate; +import java.util.HashSet; +import java.util.Set; +import org.javers.core.metamodel.annotation.DiffIgnore; +import org.javers.core.metamodel.annotation.ShallowReference; + +/** + * A FdaSubmission. + */ +@Entity +@Table(name = "fda_submission") +public class FdaSubmission implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @NotNull + @Column(name = "number", nullable = false) + private String number = ""; + + @NotNull + @Column(name = "supplement_number", nullable = false) + private String supplementNumber = ""; + + @NotNull + @Column(name = "device_name", nullable = false) + private String deviceName = ""; + + @Column(name = "generic_name") + private String genericName; + + @Column(name = "date_received") + private LocalDate dateReceived; + + @Column(name = "decision_date") + private LocalDate decisionDate; + + @DiffIgnore + @Lob + @Column(name = "description") + private String description; + + @NotNull + @Column(name = "curated", nullable = false) + private Boolean curated = false; + + @NotNull + @Column(name = "genetic", nullable = false) + private Boolean genetic = false; + + @DiffIgnore + @Lob + @Column(name = "note") + private String note; + + @ShallowReference + @ManyToMany + @JoinTable( + name = "rel_fda_submission__article", + joinColumns = @JoinColumn(name = "fda_submission_id"), + inverseJoinColumns = @JoinColumn(name = "article_id") + ) + @JsonIgnoreProperties(value = { "flags", "synonyms", "associations", "fdaSubmissions" }, allowSetters = true) + private Set
articles = new HashSet<>(); + + @ShallowReference + @ManyToMany(cascade = CascadeType.ALL) + @JoinTable( + name = "rel_fda_submission__association", + joinColumns = @JoinColumn(name = "fda_submission_id"), + inverseJoinColumns = @JoinColumn(name = "association_id") + ) + @JsonIgnoreProperties( + value = { "evidence", "clinicalTrials", "clinicalTrialArms", "eligibilityCriteria", "fdaSubmissions", "genomicIndicators" }, + allowSetters = true + ) + private Set associations = new HashSet<>(); + + @ManyToOne + @JsonIgnoreProperties(value = { "fdaSubmissions", "specimenTypes" }, allowSetters = true) + private CompanionDiagnosticDevice companionDiagnosticDevice; + + @ManyToOne + @JsonIgnoreProperties(value = { "fdaSubmissions", "drug" }, allowSetters = true) + private FdaDrug fdaDrug; + + @ManyToOne + @JsonIgnoreProperties(value = { "fdaSubmissions" }, allowSetters = true) + private FdaSubmissionType type; + + // jhipster-needle-entity-add-field - JHipster will add fields here + + public Long getId() { + return this.id; + } + + public FdaSubmission id(Long id) { + this.setId(id); + return this; + } + + public void setId(Long id) { + this.id = id; + } + + public String getNumber() { + return this.number; + } + + public FdaSubmission number(String number) { + this.setNumber(number); + return this; + } + + public void setNumber(String number) { + this.number = number; + } + + public String getSupplementNumber() { + return this.supplementNumber; + } + + public FdaSubmission supplementNumber(String supplementNumber) { + this.setSupplementNumber(supplementNumber); + return this; + } + + public void setSupplementNumber(String supplementNumber) { + this.supplementNumber = supplementNumber; + } + + public String getDeviceName() { + return this.deviceName; + } + + public FdaSubmission deviceName(String deviceName) { + this.setDeviceName(deviceName); + return this; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getGenericName() { + return this.genericName; + } + + public FdaSubmission genericName(String genericName) { + this.setGenericName(genericName); + return this; + } + + public void setGenericName(String genericName) { + this.genericName = genericName; + } + + public LocalDate getDateReceived() { + return this.dateReceived; + } + + public FdaSubmission dateReceived(LocalDate dateReceived) { + this.setDateReceived(dateReceived); + return this; + } + + public void setDateReceived(LocalDate dateReceived) { + this.dateReceived = dateReceived; + } + + public LocalDate getDecisionDate() { + return this.decisionDate; + } + + public FdaSubmission decisionDate(LocalDate decisionDate) { + this.setDecisionDate(decisionDate); + return this; + } + + public void setDecisionDate(LocalDate decisionDate) { + this.decisionDate = decisionDate; + } + + public String getDescription() { + return this.description; + } + + public FdaSubmission description(String description) { + this.setDescription(description); + return this; + } + + public void setDescription(String description) { + this.description = description; + } + + public Boolean getCurated() { + return this.curated; + } + + public FdaSubmission curated(Boolean curated) { + this.setCurated(curated); + return this; + } + + public void setCurated(Boolean curated) { + this.curated = curated; + } + + public Boolean getGenetic() { + return this.genetic; + } + + public FdaSubmission genetic(Boolean genetic) { + this.setGenetic(genetic); + return this; + } + + public void setGenetic(Boolean genetic) { + this.genetic = genetic; + } + + public String getNote() { + return this.note; + } + + public FdaSubmission note(String note) { + this.setNote(note); + return this; + } + + public void setNote(String note) { + this.note = note; + } + + public Set
getArticles() { + return this.articles; + } + + public void setArticles(Set
articles) { + this.articles = articles; + } + + public FdaSubmission articles(Set
articles) { + this.setArticles(articles); + return this; + } + + public FdaSubmission addArticle(Article article) { + this.articles.add(article); + article.getFdaSubmissions().add(this); + return this; + } + + public FdaSubmission removeArticle(Article article) { + this.articles.remove(article); + article.getFdaSubmissions().remove(this); + return this; + } + + public Set getAssociations() { + return this.associations; + } + + public void setAssociations(Set associations) { + this.associations = associations; + } + + public FdaSubmission associations(Set associations) { + this.setAssociations(associations); + return this; + } + + public FdaSubmission addAssociation(Association association) { + this.associations.add(association); + association.getFdaSubmissions().add(this); + return this; + } + + public FdaSubmission removeAssociation(Association association) { + this.associations.remove(association); + association.getFdaSubmissions().remove(this); + return this; + } + + public CompanionDiagnosticDevice getCompanionDiagnosticDevice() { + return this.companionDiagnosticDevice; + } + + public void setCompanionDiagnosticDevice(CompanionDiagnosticDevice companionDiagnosticDevice) { + this.companionDiagnosticDevice = companionDiagnosticDevice; + } + + public FdaSubmission companionDiagnosticDevice(CompanionDiagnosticDevice companionDiagnosticDevice) { + this.setCompanionDiagnosticDevice(companionDiagnosticDevice); + return this; + } + + public FdaDrug getFdaDrug() { + return this.fdaDrug; + } + + public void setFdaDrug(FdaDrug fdaDrug) { + this.fdaDrug = fdaDrug; + } + + public FdaSubmission fdaDrug(FdaDrug fdaDrug) { + this.setFdaDrug(fdaDrug); + return this; + } + + public FdaSubmissionType getType() { + return this.type; + } + + public void setType(FdaSubmissionType fdaSubmissionType) { + this.type = fdaSubmissionType; + } + + public FdaSubmission type(FdaSubmissionType fdaSubmissionType) { + this.setType(fdaSubmissionType); + return this; + } + + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof FdaSubmission)) { + return false; + } + return id != null && id.equals(((FdaSubmission) o).id); + } + + @Override + public int hashCode() { + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); + } + + // prettier-ignore + @Override + public String toString() { + return "FdaSubmission{" + + "id=" + getId() + + ", number='" + getNumber() + "'" + + ", supplementNumber='" + getSupplementNumber() + "'" + + ", deviceName='" + getDeviceName() + "'" + + ", genericName='" + getGenericName() + "'" + + ", dateReceived='" + getDateReceived() + "'" + + ", decisionDate='" + getDecisionDate() + "'" + + ", description='" + getDescription() + "'" + + ", curated='" + getCurated() + "'" + + ", genetic='" + getGenetic() + "'" + + ", note='" + getNote() + "'" + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/FdaSubmissionType.java b/src/main/java/org/mskcc/oncokb/curation/domain/FdaSubmissionType.java new file mode 100644 index 000000000..1d2440c71 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/FdaSubmissionType.java @@ -0,0 +1,209 @@ +package org.mskcc.oncokb.curation.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; +import org.javers.core.metamodel.annotation.DiffIgnore; +import org.mskcc.oncokb.curation.domain.enumeration.FdaSubmissionTypeKey; + +/** + * A FdaSubmissionType. + */ +@Entity +@Table(name = "fda_submission_type") +public class FdaSubmissionType implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @NotNull + @Enumerated(EnumType.STRING) + @Column(name = "type", nullable = false, unique = true) + private FdaSubmissionTypeKey type; + + @NotNull + @Column(name = "name", nullable = false) + private String name; + + @Column(name = "short_name") + private String shortName; + + @Column(name = "submission_prefix") + private String submissionPrefix; + + @Column(name = "submission_link") + private String submissionLink; + + @Lob + @Column(name = "description") + private String description; + + @DiffIgnore + @OneToMany(mappedBy = "type") + @JsonIgnoreProperties(value = { "articles", "associations", "companionDiagnosticDevice", "fdaDrug", "type" }, allowSetters = true) + private Set fdaSubmissions = new HashSet<>(); + + // jhipster-needle-entity-add-field - JHipster will add fields here + + public Long getId() { + return this.id; + } + + public FdaSubmissionType id(Long id) { + this.setId(id); + return this; + } + + public void setId(Long id) { + this.id = id; + } + + public FdaSubmissionTypeKey getType() { + return this.type; + } + + public FdaSubmissionType type(FdaSubmissionTypeKey type) { + this.setType(type); + return this; + } + + public void setType(FdaSubmissionTypeKey type) { + this.type = type; + } + + public String getName() { + return this.name; + } + + public FdaSubmissionType name(String name) { + this.setName(name); + return this; + } + + public void setName(String name) { + this.name = name; + } + + public String getShortName() { + return this.shortName; + } + + public FdaSubmissionType shortName(String shortName) { + this.setShortName(shortName); + return this; + } + + public void setShortName(String shortName) { + this.shortName = shortName; + } + + public String getSubmissionPrefix() { + return this.submissionPrefix; + } + + public FdaSubmissionType submissionPrefix(String submissionPrefix) { + this.setSubmissionPrefix(submissionPrefix); + return this; + } + + public void setSubmissionPrefix(String submissionPrefix) { + this.submissionPrefix = submissionPrefix; + } + + public String getSubmissionLink() { + return this.submissionLink; + } + + public FdaSubmissionType submissionLink(String submissionLink) { + this.setSubmissionLink(submissionLink); + return this; + } + + public void setSubmissionLink(String submissionLink) { + this.submissionLink = submissionLink; + } + + public String getDescription() { + return this.description; + } + + public FdaSubmissionType description(String description) { + this.setDescription(description); + return this; + } + + public void setDescription(String description) { + this.description = description; + } + + public Set getFdaSubmissions() { + return this.fdaSubmissions; + } + + public void setFdaSubmissions(Set fdaSubmissions) { + if (this.fdaSubmissions != null) { + this.fdaSubmissions.forEach(i -> i.setType(null)); + } + if (fdaSubmissions != null) { + fdaSubmissions.forEach(i -> i.setType(this)); + } + this.fdaSubmissions = fdaSubmissions; + } + + public FdaSubmissionType fdaSubmissions(Set fdaSubmissions) { + this.setFdaSubmissions(fdaSubmissions); + return this; + } + + public FdaSubmissionType addFdaSubmission(FdaSubmission fdaSubmission) { + this.fdaSubmissions.add(fdaSubmission); + fdaSubmission.setType(this); + return this; + } + + public FdaSubmissionType removeFdaSubmission(FdaSubmission fdaSubmission) { + this.fdaSubmissions.remove(fdaSubmission); + fdaSubmission.setType(null); + return this; + } + + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof FdaSubmissionType)) { + return false; + } + return id != null && id.equals(((FdaSubmissionType) o).id); + } + + @Override + public int hashCode() { + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); + } + + // prettier-ignore + @Override + public String toString() { + return "FdaSubmissionType{" + + "id=" + getId() + + ", type='" + getType() + "'" + + ", name='" + getName() + "'" + + ", shortName='" + getShortName() + "'" + + ", submissionPrefix='" + getSubmissionPrefix() + "'" + + ", submissionLink='" + getSubmissionLink() + "'" + + ", description='" + getDescription() + "'" + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/Flag.java b/src/main/java/org/mskcc/oncokb/curation/domain/Flag.java new file mode 100644 index 000000000..edce9e12c --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/Flag.java @@ -0,0 +1,319 @@ +package org.mskcc.oncokb.curation.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; +import org.javers.core.metamodel.annotation.DiffIgnore; +import org.javers.core.metamodel.annotation.ShallowReference; + +/** + * A Flag. + */ +@Entity +@Table(name = "flag") +public class Flag implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @NotNull + @Column(name = "type", nullable = false) + private String type; + + @NotNull + @Column(name = "flag", nullable = false) + private String flag; + + @NotNull + @Column(name = "name", nullable = false) + private String name; + + @Lob + @Column(name = "description", nullable = false) + private String description; + + @DiffIgnore + @ManyToMany(mappedBy = "flags") + @JsonIgnoreProperties(value = { "flags", "genes", "transcripts", "consequence", "associations" }, allowSetters = true) + private Set alterations = new HashSet<>(); + + @DiffIgnore + @ManyToMany(mappedBy = "flags") + @JsonIgnoreProperties(value = { "flags", "associations" }, allowSetters = true) + private Set
articles = new HashSet<>(); + + @DiffIgnore + @ManyToMany(mappedBy = "flags") + @JsonIgnoreProperties(value = { "nciThesaurus", "fdaDrug", "flags", "associations" }, allowSetters = true) + private Set drugs = new HashSet<>(); + + @DiffIgnore + @ManyToMany(mappedBy = "flags") + @JsonIgnoreProperties(value = { "ensemblGenes", "evidences", "transcripts", "flags", "synonyms", "alterations" }, allowSetters = true) + private Set genes = new HashSet<>(); + + @DiffIgnore + @ManyToMany(mappedBy = "flags") + @JsonIgnoreProperties(value = { "sequences", "fragments", "flags", "ensemblGene", "gene", "alterations" }, allowSetters = true) + private Set transcripts = new HashSet<>(); + + // jhipster-needle-entity-add-field - JHipster will add fields here + + public Long getId() { + return this.id; + } + + public Flag id(Long id) { + this.setId(id); + return this; + } + + public void setId(Long id) { + this.id = id; + } + + public String getType() { + return this.type; + } + + public Flag type(String type) { + this.setType(type); + return this; + } + + public void setType(String type) { + this.type = type; + } + + public String getFlag() { + return this.flag; + } + + public Flag flag(String flag) { + this.setFlag(flag); + return this; + } + + public void setFlag(String flag) { + this.flag = flag; + } + + public String getName() { + return this.name; + } + + public Flag name(String name) { + this.setName(name); + return this; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return this.description; + } + + public Flag description(String description) { + this.setDescription(description); + return this; + } + + public void setDescription(String description) { + this.description = description; + } + + public Set getAlterations() { + return this.alterations; + } + + public void setAlterations(Set alterations) { + if (this.alterations != null) { + this.alterations.forEach(i -> i.removeFlag(this)); + } + if (alterations != null) { + alterations.forEach(i -> i.addFlag(this)); + } + this.alterations = alterations; + } + + public Flag alterations(Set alterations) { + this.setAlterations(alterations); + return this; + } + + public Flag addAlteration(Alteration alteration) { + this.alterations.add(alteration); + alteration.getFlags().add(this); + return this; + } + + public Flag removeAlteration(Alteration alteration) { + this.alterations.remove(alteration); + alteration.getFlags().remove(this); + return this; + } + + public Set
getArticles() { + return this.articles; + } + + public void setArticles(Set
articles) { + if (this.articles != null) { + this.articles.forEach(i -> i.removeFlag(this)); + } + if (articles != null) { + articles.forEach(i -> i.addFlag(this)); + } + this.articles = articles; + } + + public Flag articles(Set
articles) { + this.setArticles(articles); + return this; + } + + public Flag addArticle(Article article) { + this.articles.add(article); + article.getFlags().add(this); + return this; + } + + public Flag removeArticle(Article article) { + this.articles.remove(article); + article.getFlags().remove(this); + return this; + } + + public Set getDrugs() { + return this.drugs; + } + + public void setDrugs(Set drugs) { + if (this.drugs != null) { + this.drugs.forEach(i -> i.removeFlag(this)); + } + if (drugs != null) { + drugs.forEach(i -> i.addFlag(this)); + } + this.drugs = drugs; + } + + public Flag drugs(Set drugs) { + this.setDrugs(drugs); + return this; + } + + public Flag addDrug(Drug drug) { + this.drugs.add(drug); + drug.getFlags().add(this); + return this; + } + + public Flag removeDrug(Drug drug) { + this.drugs.remove(drug); + drug.getFlags().remove(this); + return this; + } + + public Set getGenes() { + return this.genes; + } + + public void setGenes(Set genes) { + if (this.genes != null) { + this.genes.forEach(i -> i.removeFlag(this)); + } + if (genes != null) { + genes.forEach(i -> i.addFlag(this)); + } + this.genes = genes; + } + + public Flag genes(Set genes) { + this.setGenes(genes); + return this; + } + + public Flag addGene(Gene gene) { + this.genes.add(gene); + gene.getFlags().add(this); + return this; + } + + public Flag removeGene(Gene gene) { + this.genes.remove(gene); + gene.getFlags().remove(this); + return this; + } + + public Set getTranscripts() { + return this.transcripts; + } + + public void setTranscripts(Set transcripts) { + if (this.transcripts != null) { + this.transcripts.forEach(i -> i.removeFlag(this)); + } + if (transcripts != null) { + transcripts.forEach(i -> i.addFlag(this)); + } + this.transcripts = transcripts; + } + + public Flag transcripts(Set transcripts) { + this.setTranscripts(transcripts); + return this; + } + + public Flag addTranscript(Transcript transcript) { + this.transcripts.add(transcript); + transcript.getFlags().add(this); + return this; + } + + public Flag removeTranscript(Transcript transcript) { + this.transcripts.remove(transcript); + transcript.getFlags().remove(this); + return this; + } + + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Flag)) { + return false; + } + return id != null && id.equals(((Flag) o).id); + } + + @Override + public int hashCode() { + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); + } + + // prettier-ignore + @Override + public String toString() { + return "Flag{" + + "id=" + getId() + + ", type='" + getType() + "'" + + ", flag='" + getFlag() + "'" + + ", name='" + getName() + "'" + + ", description='" + getDescription() + "'" + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/Gene.java b/src/main/java/org/mskcc/oncokb/curation/domain/Gene.java new file mode 100644 index 000000000..3fbbeea3e --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/Gene.java @@ -0,0 +1,330 @@ +package org.mskcc.oncokb.curation.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; +import org.javers.core.metamodel.annotation.DiffIgnore; +import org.javers.core.metamodel.annotation.ShallowReference; + +/** + * A Gene. + */ +@Entity +@Table(name = "gene") +public class Gene implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @NotNull + @Column(name = "entrez_gene_id", nullable = false, unique = true) + private Integer entrezGeneId; + + @NotNull + @Column(name = "hugo_symbol", nullable = false) + private String hugoSymbol; + + @Column(name = "hgnc_id") + private String hgncId; + + @DiffIgnore + @OneToMany(mappedBy = "gene") + @JsonIgnoreProperties(value = { "transcripts", "gene", "seqRegion" }, allowSetters = true) + private Set ensemblGenes = new HashSet<>(); + + @DiffIgnore + @OneToMany(mappedBy = "gene") + @JsonIgnoreProperties(value = { "association", "gene", "levelOfEvidences" }, allowSetters = true) + private Set evidences = new HashSet<>(); + + @DiffIgnore + @OneToMany(mappedBy = "gene") + @JsonIgnoreProperties(value = { "sequences", "fragments", "flags", "ensemblGene", "gene", "alterations" }, allowSetters = true) + private Set transcripts = new HashSet<>(); + + @ShallowReference + @ManyToMany + @JoinTable(name = "rel_gene__flag", joinColumns = @JoinColumn(name = "gene_id"), inverseJoinColumns = @JoinColumn(name = "flag_id")) + @JsonIgnoreProperties(value = { "alterations", "articles", "drugs", "genes", "transcripts" }, allowSetters = true) + private Set flags = new HashSet<>(); + + @DiffIgnore + @ManyToMany + @JoinTable( + name = "rel_gene__synonym", + joinColumns = @JoinColumn(name = "gene_id"), + inverseJoinColumns = @JoinColumn(name = "synonym_id") + ) + @JsonIgnoreProperties(value = { "cancerTypes", "genes", "nciThesauruses" }, allowSetters = true) + private Set synonyms = new HashSet<>(); + + @DiffIgnore + @ManyToMany(mappedBy = "genes") + @JsonIgnoreProperties(value = { "genes", "transcripts", "consequence", "associations" }, allowSetters = true) + private Set alterations = new HashSet<>(); + + // jhipster-needle-entity-add-field - JHipster will add fields here + + public Long getId() { + return this.id; + } + + public Gene id(Long id) { + this.setId(id); + return this; + } + + public void setId(Long id) { + this.id = id; + } + + public Integer getEntrezGeneId() { + return this.entrezGeneId; + } + + public Gene entrezGeneId(Integer entrezGeneId) { + this.setEntrezGeneId(entrezGeneId); + return this; + } + + public void setEntrezGeneId(Integer entrezGeneId) { + this.entrezGeneId = entrezGeneId; + } + + public String getHugoSymbol() { + return this.hugoSymbol; + } + + public Gene hugoSymbol(String hugoSymbol) { + this.setHugoSymbol(hugoSymbol); + return this; + } + + public void setHugoSymbol(String hugoSymbol) { + this.hugoSymbol = hugoSymbol; + } + + public String getHgncId() { + return this.hgncId; + } + + public Gene hgncId(String hgncId) { + this.setHgncId(hgncId); + return this; + } + + public void setHgncId(String hgncId) { + this.hgncId = hgncId; + } + + public Set getEnsemblGenes() { + return this.ensemblGenes; + } + + public void setEnsemblGenes(Set ensemblGenes) { + if (this.ensemblGenes != null) { + this.ensemblGenes.forEach(i -> i.setGene(null)); + } + if (ensemblGenes != null) { + ensemblGenes.forEach(i -> i.setGene(this)); + } + this.ensemblGenes = ensemblGenes; + } + + public Gene ensemblGenes(Set ensemblGenes) { + this.setEnsemblGenes(ensemblGenes); + return this; + } + + public Gene addEnsemblGene(EnsemblGene ensemblGene) { + this.ensemblGenes.add(ensemblGene); + ensemblGene.setGene(this); + return this; + } + + public Gene removeEnsemblGene(EnsemblGene ensemblGene) { + this.ensemblGenes.remove(ensemblGene); + ensemblGene.setGene(null); + return this; + } + + public Set getEvidences() { + return this.evidences; + } + + public void setEvidences(Set evidences) { + if (this.evidences != null) { + this.evidences.forEach(i -> i.setGene(null)); + } + if (evidences != null) { + evidences.forEach(i -> i.setGene(this)); + } + this.evidences = evidences; + } + + public Gene evidences(Set evidences) { + this.setEvidences(evidences); + return this; + } + + public Gene addEvidence(Evidence evidence) { + this.evidences.add(evidence); + evidence.setGene(this); + return this; + } + + public Gene removeEvidence(Evidence evidence) { + this.evidences.remove(evidence); + evidence.setGene(null); + return this; + } + + public Set getTranscripts() { + return this.transcripts; + } + + public void setTranscripts(Set transcripts) { + if (this.transcripts != null) { + this.transcripts.forEach(i -> i.setGene(null)); + } + if (transcripts != null) { + transcripts.forEach(i -> i.setGene(this)); + } + this.transcripts = transcripts; + } + + public Gene transcripts(Set transcripts) { + this.setTranscripts(transcripts); + return this; + } + + public Gene addTranscript(Transcript transcript) { + this.transcripts.add(transcript); + transcript.setGene(this); + return this; + } + + public Gene removeTranscript(Transcript transcript) { + this.transcripts.remove(transcript); + transcript.setGene(null); + return this; + } + + public Set getFlags() { + return this.flags; + } + + public void setFlags(Set flags) { + this.flags = flags; + } + + public Gene flags(Set flags) { + this.setFlags(flags); + return this; + } + + public Gene addFlag(Flag flag) { + this.flags.add(flag); + flag.getGenes().add(this); + return this; + } + + public Gene removeFlag(Flag flag) { + this.flags.remove(flag); + flag.getGenes().remove(this); + return this; + } + + public Set getSynonyms() { + return this.synonyms; + } + + public void setSynonyms(Set synonyms) { + this.synonyms = synonyms; + } + + public Gene synonyms(Set synonyms) { + this.setSynonyms(synonyms); + return this; + } + + public Gene addSynonym(Synonym synonym) { + this.synonyms.add(synonym); + synonym.getGenes().add(this); + return this; + } + + public Gene removeSynonym(Synonym synonym) { + this.synonyms.remove(synonym); + synonym.getGenes().remove(this); + return this; + } + + public Set getAlterations() { + return this.alterations; + } + + public void setAlterations(Set alterations) { + if (this.alterations != null) { + this.alterations.forEach(i -> i.removeGene(this)); + } + if (alterations != null) { + alterations.forEach(i -> i.addGene(this)); + } + this.alterations = alterations; + } + + public Gene alterations(Set alterations) { + this.setAlterations(alterations); + return this; + } + + public Gene addAlteration(Alteration alteration) { + this.alterations.add(alteration); + alteration.getGenes().add(this); + return this; + } + + public Gene removeAlteration(Alteration alteration) { + this.alterations.remove(alteration); + alteration.getGenes().remove(this); + return this; + } + + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Gene)) { + return false; + } + return id != null && id.equals(((Gene) o).id); + } + + @Override + public int hashCode() { + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); + } + + // prettier-ignore + @Override + public String toString() { + return "Gene{" + + "id=" + getId() + + ", entrezGeneId=" + getEntrezGeneId() + + ", hugoSymbol='" + getHugoSymbol() + "'" + + ", hgncId='" + getHgncId() + "'" + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/GenomeFragment.java b/src/main/java/org/mskcc/oncokb/curation/domain/GenomeFragment.java new file mode 100644 index 000000000..021ae4592 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/GenomeFragment.java @@ -0,0 +1,175 @@ +package org.mskcc.oncokb.curation.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; +import java.io.Serializable; +import org.javers.core.metamodel.annotation.ShallowReference; +import org.mskcc.oncokb.curation.domain.enumeration.GenomeFragmentType; + +/** + * A GenomeFragment. + */ +@Entity +@Table(name = "genome_fragment") +public class GenomeFragment implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @NotNull + @Column(name = "start", nullable = false) + private Integer start; + + @NotNull + @Column(name = "end", nullable = false) + private Integer end; + + @NotNull + @Column(name = "strand", nullable = false) + private Integer strand; + + @NotNull + @Enumerated(EnumType.STRING) + @Column(name = "type", nullable = false) + private GenomeFragmentType type; + + @ShallowReference + @ManyToOne + @JsonIgnoreProperties(value = { "ensemblGenes", "genomeFragments" }, allowSetters = true) + @JoinColumn(name = "seq_region", referencedColumnName = "name") + private SeqRegion seqRegion; + + @ShallowReference + @ManyToOne + @JsonIgnoreProperties(value = { "sequences", "fragments", "flags", "ensemblGene", "gene", "alterations" }, allowSetters = true) + private Transcript transcript; + + // jhipster-needle-entity-add-field - JHipster will add fields here + + public Long getId() { + return this.id; + } + + public GenomeFragment id(Long id) { + this.setId(id); + return this; + } + + public void setId(Long id) { + this.id = id; + } + + public Integer getStart() { + return this.start; + } + + public GenomeFragment start(Integer start) { + this.setStart(start); + return this; + } + + public void setStart(Integer start) { + this.start = start; + } + + public Integer getEnd() { + return this.end; + } + + public GenomeFragment end(Integer end) { + this.setEnd(end); + return this; + } + + public void setEnd(Integer end) { + this.end = end; + } + + public Integer getStrand() { + return this.strand; + } + + public GenomeFragment strand(Integer strand) { + this.setStrand(strand); + return this; + } + + public void setStrand(Integer strand) { + this.strand = strand; + } + + public GenomeFragmentType getType() { + return this.type; + } + + public GenomeFragment type(GenomeFragmentType type) { + this.setType(type); + return this; + } + + public void setType(GenomeFragmentType type) { + this.type = type; + } + + public SeqRegion getSeqRegion() { + return this.seqRegion; + } + + public void setSeqRegion(SeqRegion seqRegion) { + this.seqRegion = seqRegion; + } + + public GenomeFragment seqRegion(SeqRegion seqRegion) { + this.setSeqRegion(seqRegion); + return this; + } + + public Transcript getTranscript() { + return this.transcript; + } + + public void setTranscript(Transcript transcript) { + this.transcript = transcript; + } + + public GenomeFragment transcript(Transcript transcript) { + this.setTranscript(transcript); + return this; + } + + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof GenomeFragment)) { + return false; + } + return id != null && id.equals(((GenomeFragment) o).id); + } + + @Override + public int hashCode() { + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); + } + + // prettier-ignore + @Override + public String toString() { + return "GenomeFragment{" + + "id=" + getId() + + ", start=" + getStart() + + ", end=" + getEnd() + + ", strand=" + getStrand() + + ", type='" + getType() + "'" + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/GenomicIndicator.java b/src/main/java/org/mskcc/oncokb/curation/domain/GenomicIndicator.java new file mode 100644 index 000000000..7838a6f63 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/GenomicIndicator.java @@ -0,0 +1,223 @@ +package org.mskcc.oncokb.curation.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; +import org.javers.core.metamodel.annotation.ShallowReference; + +/** + * A GenomicIndicator. + */ +@Entity +@Table(name = "genomic_indicator") +public class GenomicIndicator implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @NotNull + @Column(name = "uuid", nullable = false, unique = true) + private String uuid; + + @NotNull + @Column(name = "type", nullable = false) + private String type; + + @NotNull + @Column(name = "name", nullable = false) + private String name; + + @Lob + @Column(name = "description") + private String description; + + @ShallowReference + @ManyToMany + @JoinTable( + name = "rel_genomic_indicator__allele_state", + joinColumns = @JoinColumn(name = "genomic_indicator_id"), + inverseJoinColumns = @JoinColumn(name = "allele_state_id") + ) + @JsonIgnoreProperties(value = { "genomicIndicators" }, allowSetters = true) + private Set alleleStates = new HashSet<>(); + + @ShallowReference + @ManyToMany(cascade = CascadeType.ALL) + @JoinTable( + name = "rel_genomic_indicator__association", + joinColumns = @JoinColumn(name = "genomic_indicator_id"), + inverseJoinColumns = @JoinColumn(name = "association_id") + ) + @JsonIgnoreProperties( + value = { + "rules", + "alterations", + "articles", + "cancerTypes", + "drugs", + "evidence", + "clinicalTrials", + "clinicalTrialArms", + "eligibilityCriteria", + "fdaSubmissions", + "genomicIndicators", + }, + allowSetters = true + ) + private Set associations = new HashSet<>(); + + // jhipster-needle-entity-add-field - JHipster will add fields here + + public Long getId() { + return this.id; + } + + public GenomicIndicator id(Long id) { + this.setId(id); + return this; + } + + public void setId(Long id) { + this.id = id; + } + + public String getUuid() { + return this.uuid; + } + + public GenomicIndicator uuid(String uuid) { + this.setUuid(uuid); + return this; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getType() { + return this.type; + } + + public GenomicIndicator type(String type) { + this.setType(type); + return this; + } + + public void setType(String type) { + this.type = type; + } + + public String getName() { + return this.name; + } + + public GenomicIndicator name(String name) { + this.setName(name); + return this; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return this.description; + } + + public GenomicIndicator description(String description) { + this.setDescription(description); + return this; + } + + public void setDescription(String description) { + this.description = description; + } + + public Set getAlleleStates() { + return this.alleleStates; + } + + public void setAlleleStates(Set alleleStates) { + this.alleleStates = alleleStates; + } + + public GenomicIndicator alleleStates(Set alleleStates) { + this.setAlleleStates(alleleStates); + return this; + } + + public GenomicIndicator addAlleleState(AlleleState alleleState) { + this.alleleStates.add(alleleState); + alleleState.getGenomicIndicators().add(this); + return this; + } + + public GenomicIndicator removeAlleleState(AlleleState alleleState) { + this.alleleStates.remove(alleleState); + alleleState.getGenomicIndicators().remove(this); + return this; + } + + public Set getAssociations() { + return this.associations; + } + + public void setAssociations(Set associations) { + this.associations = associations; + } + + public GenomicIndicator associations(Set associations) { + this.setAssociations(associations); + return this; + } + + public GenomicIndicator addAssociation(Association association) { + this.associations.add(association); + association.getGenomicIndicators().add(this); + return this; + } + + public GenomicIndicator removeAssociation(Association association) { + this.associations.remove(association); + association.getGenomicIndicators().remove(this); + return this; + } + + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof GenomicIndicator)) { + return false; + } + return id != null && id.equals(((GenomicIndicator) o).id); + } + + @Override + public int hashCode() { + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); + } + + // prettier-ignore + @Override + public String toString() { + return "GenomicIndicator{" + + "id=" + getId() + + ", uuid='" + getUuid() + "'" + + ", type='" + getType() + "'" + + ", name='" + getName() + "'" + + ", description='" + getDescription() + "'" + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/transcript/domain/Info.java b/src/main/java/org/mskcc/oncokb/curation/domain/Info.java similarity index 77% rename from src/main/java/org/mskcc/oncokb/transcript/domain/Info.java rename to src/main/java/org/mskcc/oncokb/curation/domain/Info.java index a4738c7ce..1839f09d3 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/domain/Info.java +++ b/src/main/java/org/mskcc/oncokb/curation/domain/Info.java @@ -1,10 +1,9 @@ -package org.mskcc.oncokb.transcript.domain; +package org.mskcc.oncokb.curation.domain; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; import java.io.Serializable; import java.time.Instant; -import javax.persistence.*; -import javax.validation.constraints.*; -import org.mskcc.oncokb.transcript.domain.enumeration.InfoType; /** * A Info. @@ -21,13 +20,16 @@ public class Info implements Serializable { private Long id; @NotNull - @Enumerated(EnumType.STRING) @Column(name = "type", nullable = false, unique = true) - private InfoType type; + private String type; @Column(name = "value") private String value; + @NotNull + @Column(name = "created", nullable = false) + private Instant created; + @Column(name = "last_updated") private Instant lastUpdated; @@ -46,16 +48,16 @@ public void setId(Long id) { this.id = id; } - public InfoType getType() { + public String getType() { return this.type; } - public Info type(InfoType type) { + public Info type(String type) { this.setType(type); return this; } - public void setType(InfoType type) { + public void setType(String type) { this.type = type; } @@ -72,6 +74,19 @@ public void setValue(String value) { this.value = value; } + public Instant getCreated() { + return this.created; + } + + public Info created(Instant created) { + this.setCreated(created); + return this; + } + + public void setCreated(Instant created) { + this.created = created; + } + public Instant getLastUpdated() { return this.lastUpdated; } @@ -111,6 +126,7 @@ public String toString() { "id=" + getId() + ", type='" + getType() + "'" + ", value='" + getValue() + "'" + + ", created='" + getCreated() + "'" + ", lastUpdated='" + getLastUpdated() + "'" + "}"; } diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/LevelOfEvidence.java b/src/main/java/org/mskcc/oncokb/curation/domain/LevelOfEvidence.java new file mode 100644 index 000000000..f40fa431f --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/LevelOfEvidence.java @@ -0,0 +1,192 @@ +package org.mskcc.oncokb.curation.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; +import org.javers.core.metamodel.annotation.DiffIgnore; + +/** + * A LevelOfEvidence. + */ +@Entity +@Table(name = "level_of_evidence") +public class LevelOfEvidence implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @NotNull + @Column(name = "type", nullable = false) + private String type; + + @NotNull + @Column(name = "level", nullable = false, unique = true) + private String level; + + @NotNull + @Column(name = "description", nullable = false) + private String description; + + @NotNull + @Column(name = "html_description", nullable = false) + private String htmlDescription; + + @NotNull + @Column(name = "color", nullable = false) + private String color; + + @DiffIgnore + @ManyToMany(mappedBy = "levelOfEvidences") + @JsonIgnoreProperties(value = { "association", "levelOfEvidences", "gene" }, allowSetters = true) + private Set evidences = new HashSet<>(); + + // jhipster-needle-entity-add-field - JHipster will add fields here + + public Long getId() { + return this.id; + } + + public LevelOfEvidence id(Long id) { + this.setId(id); + return this; + } + + public void setId(Long id) { + this.id = id; + } + + public String getType() { + return this.type; + } + + public LevelOfEvidence type(String type) { + this.setType(type); + return this; + } + + public void setType(String type) { + this.type = type; + } + + public String getLevel() { + return this.level; + } + + public LevelOfEvidence level(String level) { + this.setLevel(level); + return this; + } + + public void setLevel(String level) { + this.level = level; + } + + public String getDescription() { + return this.description; + } + + public LevelOfEvidence description(String description) { + this.setDescription(description); + return this; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getHtmlDescription() { + return this.htmlDescription; + } + + public LevelOfEvidence htmlDescription(String htmlDescription) { + this.setHtmlDescription(htmlDescription); + return this; + } + + public void setHtmlDescription(String htmlDescription) { + this.htmlDescription = htmlDescription; + } + + public String getColor() { + return this.color; + } + + public LevelOfEvidence color(String color) { + this.setColor(color); + return this; + } + + public void setColor(String color) { + this.color = color; + } + + public Set getEvidences() { + return this.evidences; + } + + public void setEvidences(Set evidences) { + if (this.evidences != null) { + this.evidences.forEach(i -> i.removeLevelOfEvidence(this)); + } + if (evidences != null) { + evidences.forEach(i -> i.addLevelOfEvidence(this)); + } + this.evidences = evidences; + } + + public LevelOfEvidence evidences(Set evidences) { + this.setEvidences(evidences); + return this; + } + + public LevelOfEvidence addEvidence(Evidence evidence) { + this.evidences.add(evidence); + evidence.getLevelOfEvidences().add(this); + return this; + } + + public LevelOfEvidence removeEvidence(Evidence evidence) { + this.evidences.remove(evidence); + evidence.getLevelOfEvidences().remove(this); + return this; + } + + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof LevelOfEvidence)) { + return false; + } + return id != null && id.equals(((LevelOfEvidence) o).id); + } + + @Override + public int hashCode() { + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); + } + + // prettier-ignore + @Override + public String toString() { + return "LevelOfEvidence{" + + "id=" + getId() + + ", type='" + getType() + "'" + + ", level='" + getLevel() + "'" + + ", description='" + getDescription() + "'" + + ", htmlDescription='" + getHtmlDescription() + "'" + + ", color='" + getColor() + "'" + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/NciThesaurus.java b/src/main/java/org/mskcc/oncokb/curation/domain/NciThesaurus.java new file mode 100644 index 000000000..0a1d41cb5 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/NciThesaurus.java @@ -0,0 +1,171 @@ +package org.mskcc.oncokb.curation.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import jakarta.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; +import org.javers.core.metamodel.annotation.DiffIgnore; + +/** + * A NciThesaurus. + */ +@Entity +@Table(name = "nci_thesaurus") +public class NciThesaurus implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @NotNull + @Column(name = "version", nullable = false) + private String version; + + @NotNull + @Column(name = "code", nullable = false, unique = true) + private String code; + + @Column(name = "preferred_name") + private String preferredName; + + @Column(name = "display_name") + private String displayName; + + @DiffIgnore + @ManyToMany + @JoinTable( + name = "rel_nci_thesaurus__synonym", + joinColumns = @JoinColumn(name = "nci_thesaurus_id"), + inverseJoinColumns = @JoinColumn(name = "synonym_id") + ) + @JsonIgnoreProperties(value = { "cancerTypes", "genes", "nciThesauruses" }, allowSetters = true) + private Set synonyms = new HashSet<>(); + + // jhipster-needle-entity-add-field - JHipster will add fields here + + public Long getId() { + return this.id; + } + + public NciThesaurus id(Long id) { + this.setId(id); + return this; + } + + public void setId(Long id) { + this.id = id; + } + + public String getVersion() { + return this.version; + } + + public NciThesaurus version(String version) { + this.setVersion(version); + return this; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getCode() { + return this.code; + } + + public NciThesaurus code(String code) { + this.setCode(code); + return this; + } + + public void setCode(String code) { + this.code = code; + } + + public String getPreferredName() { + return this.preferredName; + } + + public NciThesaurus preferredName(String preferredName) { + this.setPreferredName(preferredName); + return this; + } + + public void setPreferredName(String preferredName) { + this.preferredName = preferredName; + } + + public String getDisplayName() { + return this.displayName; + } + + public NciThesaurus displayName(String displayName) { + this.setDisplayName(displayName); + return this; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + public Set getSynonyms() { + return this.synonyms; + } + + public void setSynonyms(Set synonyms) { + this.synonyms = synonyms; + } + + public NciThesaurus synonyms(Set synonyms) { + this.setSynonyms(synonyms); + return this; + } + + public NciThesaurus addSynonym(Synonym synonym) { + this.synonyms.add(synonym); + synonym.getNciThesauruses().add(this); + return this; + } + + public NciThesaurus removeSynonym(Synonym synonym) { + this.synonyms.remove(synonym); + synonym.getNciThesauruses().remove(this); + return this; + } + + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof NciThesaurus)) { + return false; + } + return id != null && id.equals(((NciThesaurus) o).id); + } + + @Override + public int hashCode() { + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); + } + + // prettier-ignore + @Override + public String toString() { + return "NciThesaurus{" + + "id=" + getId() + + ", version='" + getVersion() + "'" + + ", code='" + getCode() + "'" + + ", preferredName='" + getPreferredName() + "'" + + ", displayName='" + getDisplayName() + "'" + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/RelevantCancerTypeBody.java b/src/main/java/org/mskcc/oncokb/curation/domain/RelevantCancerTypeBody.java new file mode 100644 index 000000000..470fc4f99 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/RelevantCancerTypeBody.java @@ -0,0 +1,25 @@ +package org.mskcc.oncokb.curation.domain; + +import java.util.List; + +public class RelevantCancerTypeBody { + + List relevantCancerTypeQueries; + List excludedRelevantCancerTypeQueries; + + public List getRelevantCancerTypeQueries() { + return relevantCancerTypeQueries; + } + + public void setRelevantCancerTypeQueries(List relevantCancerTypeQueries) { + this.relevantCancerTypeQueries = relevantCancerTypeQueries; + } + + public List getExcludedRelevantCancerTypeQueries() { + return excludedRelevantCancerTypeQueries; + } + + public void setExcludedRelevantCancerTypeQueries(List excludedRelevantCancerTypeQueries) { + this.excludedRelevantCancerTypeQueries = excludedRelevantCancerTypeQueries; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/RelevantCancerTypeQuery.java b/src/main/java/org/mskcc/oncokb/curation/domain/RelevantCancerTypeQuery.java new file mode 100644 index 000000000..a3e1e88f5 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/RelevantCancerTypeQuery.java @@ -0,0 +1,23 @@ +package org.mskcc.oncokb.curation.domain; + +public class RelevantCancerTypeQuery implements java.io.Serializable { + + String mainType; + String code; + + public String getMainType() { + return mainType; + } + + public void setMainType(String mainType) { + this.mainType = mainType; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/Rule.java b/src/main/java/org/mskcc/oncokb/curation/domain/Rule.java new file mode 100644 index 000000000..8c923fa68 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/Rule.java @@ -0,0 +1,149 @@ +package org.mskcc.oncokb.curation.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; +import java.io.Serializable; +import org.javers.core.metamodel.annotation.ShallowReference; + +/** + * A Rule. + */ +@Entity +@Table(name = "rule") +public class Rule implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @NotNull + @Column(name = "entity", nullable = false) + private String entity; + + @Column(name = "rule") + private String rule; + + @Column(name = "name") + private String name; + + @ShallowReference + @ManyToOne + @JsonIgnoreProperties( + value = { + "rules", + "alterations", + "articles", + "cancerTypes", + "drugs", + "evidence", + "clinicalTrials", + "clinicalTrialArms", + "eligibilityCriteria", + "fdaSubmissions", + "genomicIndicators", + }, + allowSetters = true + ) + private Association association; + + // jhipster-needle-entity-add-field - JHipster will add fields here + + public Long getId() { + return this.id; + } + + public Rule id(Long id) { + this.setId(id); + return this; + } + + public void setId(Long id) { + this.id = id; + } + + public String getEntity() { + return this.entity; + } + + public Rule entity(String entity) { + this.setEntity(entity); + return this; + } + + public void setEntity(String entity) { + this.entity = entity; + } + + public String getRule() { + return this.rule; + } + + public Rule rule(String rule) { + this.setRule(rule); + return this; + } + + public void setRule(String rule) { + this.rule = rule; + } + + public String getName() { + return this.name; + } + + public Rule name(String name) { + this.setName(name); + return this; + } + + public void setName(String name) { + this.name = name; + } + + public Association getAssociation() { + return this.association; + } + + public void setAssociation(Association association) { + this.association = association; + } + + public Rule association(Association association) { + this.setAssociation(association); + return this; + } + + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Rule)) { + return false; + } + return id != null && id.equals(((Rule) o).id); + } + + @Override + public int hashCode() { + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); + } + + // prettier-ignore + @Override + public String toString() { + return "Rule{" + + "id=" + getId() + + ", entity='" + getEntity() + "'" + + ", rule='" + getRule() + "'" + + ", name='" + getName() + "'" + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/SeqRegion.java b/src/main/java/org/mskcc/oncokb/curation/domain/SeqRegion.java new file mode 100644 index 000000000..57a8f52b4 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/SeqRegion.java @@ -0,0 +1,191 @@ +package org.mskcc.oncokb.curation.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; +import org.javers.core.metamodel.annotation.DiffIgnore; + +/** + * A SeqRegion. + */ +@Entity +@Table(name = "seq_region") +public class SeqRegion implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @NotNull + @Column(name = "name", nullable = false, unique = true) + private String name; + + @Column(name = "chromosome") + private String chromosome; + + @Lob + @Column(name = "description") + private String description; + + @DiffIgnore + @OneToMany(mappedBy = "seqRegion") + @JsonIgnoreProperties(value = { "transcripts", "gene", "seqRegion" }, allowSetters = true) + private Set ensemblGenes = new HashSet<>(); + + @DiffIgnore + @OneToMany(mappedBy = "seqRegion") + @JsonIgnoreProperties(value = { "seqRegion", "transcript" }, allowSetters = true) + private Set genomeFragments = new HashSet<>(); + + // jhipster-needle-entity-add-field - JHipster will add fields here + + public Long getId() { + return this.id; + } + + public SeqRegion id(Long id) { + this.setId(id); + return this; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return this.name; + } + + public SeqRegion name(String name) { + this.setName(name); + return this; + } + + public void setName(String name) { + this.name = name; + } + + public String getChromosome() { + return this.chromosome; + } + + public SeqRegion chromosome(String chromosome) { + this.setChromosome(chromosome); + return this; + } + + public void setChromosome(String chromosome) { + this.chromosome = chromosome; + } + + public String getDescription() { + return this.description; + } + + public SeqRegion description(String description) { + this.setDescription(description); + return this; + } + + public void setDescription(String description) { + this.description = description; + } + + public Set getEnsemblGenes() { + return this.ensemblGenes; + } + + public void setEnsemblGenes(Set ensemblGenes) { + if (this.ensemblGenes != null) { + this.ensemblGenes.forEach(i -> i.setSeqRegion(null)); + } + if (ensemblGenes != null) { + ensemblGenes.forEach(i -> i.setSeqRegion(this)); + } + this.ensemblGenes = ensemblGenes; + } + + public SeqRegion ensemblGenes(Set ensemblGenes) { + this.setEnsemblGenes(ensemblGenes); + return this; + } + + public SeqRegion addEnsemblGene(EnsemblGene ensemblGene) { + this.ensemblGenes.add(ensemblGene); + ensemblGene.setSeqRegion(this); + return this; + } + + public SeqRegion removeEnsemblGene(EnsemblGene ensemblGene) { + this.ensemblGenes.remove(ensemblGene); + ensemblGene.setSeqRegion(null); + return this; + } + + public Set getGenomeFragments() { + return this.genomeFragments; + } + + public void setGenomeFragments(Set genomeFragments) { + if (this.genomeFragments != null) { + this.genomeFragments.forEach(i -> i.setSeqRegion(null)); + } + if (genomeFragments != null) { + genomeFragments.forEach(i -> i.setSeqRegion(this)); + } + this.genomeFragments = genomeFragments; + } + + public SeqRegion genomeFragments(Set genomeFragments) { + this.setGenomeFragments(genomeFragments); + return this; + } + + public SeqRegion addGenomeFragment(GenomeFragment genomeFragment) { + this.genomeFragments.add(genomeFragment); + genomeFragment.setSeqRegion(this); + return this; + } + + public SeqRegion removeGenomeFragment(GenomeFragment genomeFragment) { + this.genomeFragments.remove(genomeFragment); + genomeFragment.setSeqRegion(null); + return this; + } + + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof SeqRegion)) { + return false; + } + return id != null && id.equals(((SeqRegion) o).id); + } + + @Override + public int hashCode() { + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); + } + + // prettier-ignore + @Override + public String toString() { + return "SeqRegion{" + + "id=" + getId() + + ", name='" + getName() + "'" + + ", chromosome='" + getChromosome() + "'" + + ", description='" + getDescription() + "'" + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/transcript/domain/Sequence.java b/src/main/java/org/mskcc/oncokb/curation/domain/Sequence.java similarity index 81% rename from src/main/java/org/mskcc/oncokb/transcript/domain/Sequence.java rename to src/main/java/org/mskcc/oncokb/curation/domain/Sequence.java index ea60c772a..66fb7b527 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/domain/Sequence.java +++ b/src/main/java/org/mskcc/oncokb/curation/domain/Sequence.java @@ -1,9 +1,12 @@ -package org.mskcc.oncokb.transcript.domain; +package org.mskcc.oncokb.curation.domain; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; import java.io.Serializable; -import javax.persistence.*; -import org.mskcc.oncokb.transcript.domain.enumeration.SequenceType; +import org.javers.core.metamodel.annotation.DiffIgnore; +import org.javers.core.metamodel.annotation.ShallowReference; +import org.mskcc.oncokb.curation.domain.enumeration.SequenceType; /** * A Sequence. @@ -19,16 +22,19 @@ public class Sequence implements Serializable { @Column(name = "id") private Long id; + @NotNull @Enumerated(EnumType.STRING) - @Column(name = "sequence_type") + @Column(name = "sequence_type", nullable = false) private SequenceType sequenceType; + @DiffIgnore @Lob - @Column(name = "sequence") + @Column(name = "sequence", nullable = false) private String sequence; + @ShallowReference @ManyToOne - @JsonIgnoreProperties(value = { "fragments", "sequences", "ensemblGene" }, allowSetters = true) + @JsonIgnoreProperties(value = { "sequences", "fragments", "flags", "ensemblGene", "gene", "alterations" }, allowSetters = true) private Transcript transcript; // jhipster-needle-entity-add-field - JHipster will add fields here diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/SpecimenType.java b/src/main/java/org/mskcc/oncokb/curation/domain/SpecimenType.java new file mode 100644 index 000000000..b6199d5d5 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/SpecimenType.java @@ -0,0 +1,138 @@ +package org.mskcc.oncokb.curation.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; +import org.javers.core.metamodel.annotation.DiffIgnore; + +/** + * A SpecimenType. + */ +@Entity +@Table(name = "specimen_type") +public class SpecimenType implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @NotNull + @Column(name = "type", nullable = false) + private String type; + + @NotNull + @Column(name = "name", nullable = false) + private String name; + + @DiffIgnore + @ManyToMany(mappedBy = "specimenTypes") + @JsonIgnoreProperties(value = { "fdaSubmissions", "specimenTypes" }, allowSetters = true) + private Set companionDiagnosticDevices = new HashSet<>(); + + // jhipster-needle-entity-add-field - JHipster will add fields here + + public Long getId() { + return this.id; + } + + public SpecimenType id(Long id) { + this.setId(id); + return this; + } + + public void setId(Long id) { + this.id = id; + } + + public String getType() { + return this.type; + } + + public SpecimenType type(String type) { + this.setType(type); + return this; + } + + public void setType(String type) { + this.type = type; + } + + public String getName() { + return this.name; + } + + public SpecimenType name(String name) { + this.setName(name); + return this; + } + + public void setName(String name) { + this.name = name; + } + + public Set getCompanionDiagnosticDevices() { + return this.companionDiagnosticDevices; + } + + public void setCompanionDiagnosticDevices(Set companionDiagnosticDevices) { + if (this.companionDiagnosticDevices != null) { + this.companionDiagnosticDevices.forEach(i -> i.removeSpecimenType(this)); + } + if (companionDiagnosticDevices != null) { + companionDiagnosticDevices.forEach(i -> i.addSpecimenType(this)); + } + this.companionDiagnosticDevices = companionDiagnosticDevices; + } + + public SpecimenType companionDiagnosticDevices(Set companionDiagnosticDevices) { + this.setCompanionDiagnosticDevices(companionDiagnosticDevices); + return this; + } + + public SpecimenType addCompanionDiagnosticDevice(CompanionDiagnosticDevice companionDiagnosticDevice) { + this.companionDiagnosticDevices.add(companionDiagnosticDevice); + companionDiagnosticDevice.getSpecimenTypes().add(this); + return this; + } + + public SpecimenType removeCompanionDiagnosticDevice(CompanionDiagnosticDevice companionDiagnosticDevice) { + this.companionDiagnosticDevices.remove(companionDiagnosticDevice); + companionDiagnosticDevice.getSpecimenTypes().remove(this); + return this; + } + + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof SpecimenType)) { + return false; + } + return id != null && id.equals(((SpecimenType) o).id); + } + + @Override + public int hashCode() { + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); + } + + // prettier-ignore + @Override + public String toString() { + return "SpecimenType{" + + "id=" + getId() + + ", type='" + getType() + "'" + + ", name='" + getName() + "'" + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/Synonym.java b/src/main/java/org/mskcc/oncokb/curation/domain/Synonym.java new file mode 100644 index 000000000..f64386da4 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/Synonym.java @@ -0,0 +1,296 @@ +package org.mskcc.oncokb.curation.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; +import org.javers.core.metamodel.annotation.DiffIgnore; + +/** + * A Synonym. + */ +@Entity +@Table(name = "synonym") +public class Synonym implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @NotNull + @Column(name = "type", nullable = false) + private String type; + + @NotNull + @Column(name = "source", nullable = false) + private String source; + + @Column(name = "code") + private String code; + + @NotNull + @Column(name = "name", nullable = false) + private String name; + + @DiffIgnore + @Lob + @Column(name = "note") + private String note; + + @ManyToMany(mappedBy = "synonyms") + @JsonIgnoreProperties(value = { "flags", "synonyms", "associations", "fdaSubmissions" }, allowSetters = true) + private Set
articles = new HashSet<>(); + + @ManyToMany(mappedBy = "synonyms") + @JsonIgnoreProperties(value = { "children", "synonyms", "parent", "associations" }, allowSetters = true) + private Set cancerTypes = new HashSet<>(); + + @ManyToMany(mappedBy = "synonyms") + @JsonIgnoreProperties(value = { "ensemblGenes", "evidences", "transcripts", "flags", "synonyms", "alterations" }, allowSetters = true) + private Set genes = new HashSet<>(); + + @ManyToMany(mappedBy = "synonyms") + @JsonIgnoreProperties(value = { "synonyms" }, allowSetters = true) + private Set nciThesauruses = new HashSet<>(); + + // jhipster-needle-entity-add-field - JHipster will add fields here + + public Long getId() { + return this.id; + } + + public Synonym id(Long id) { + this.setId(id); + return this; + } + + public void setId(Long id) { + this.id = id; + } + + public String getType() { + return this.type; + } + + public Synonym type(String type) { + this.setType(type); + return this; + } + + public void setType(String type) { + this.type = type; + } + + public String getSource() { + return this.source; + } + + public Synonym source(String source) { + this.setSource(source); + return this; + } + + public void setSource(String source) { + this.source = source; + } + + public String getCode() { + return this.code; + } + + public Synonym code(String code) { + this.setCode(code); + return this; + } + + public void setCode(String code) { + this.code = code; + } + + public String getName() { + return this.name; + } + + public Synonym name(String name) { + this.setName(name); + return this; + } + + public void setName(String name) { + this.name = name; + } + + public String getNote() { + return this.note; + } + + public Synonym note(String note) { + this.setNote(note); + return this; + } + + public void setNote(String note) { + this.note = note; + } + + public Set
getArticles() { + return this.articles; + } + + public void setArticles(Set
articles) { + if (this.articles != null) { + this.articles.forEach(i -> i.removeSynonym(this)); + } + if (articles != null) { + articles.forEach(i -> i.addSynonym(this)); + } + this.articles = articles; + } + + public Synonym articles(Set
articles) { + this.setArticles(articles); + return this; + } + + public Synonym addArticle(Article article) { + this.articles.add(article); + article.getSynonyms().add(this); + return this; + } + + public Synonym removeArticle(Article article) { + this.articles.remove(article); + article.getSynonyms().remove(this); + return this; + } + + public Set getCancerTypes() { + return this.cancerTypes; + } + + public void setCancerTypes(Set cancerTypes) { + if (this.cancerTypes != null) { + this.cancerTypes.forEach(i -> i.removeSynonym(this)); + } + if (cancerTypes != null) { + cancerTypes.forEach(i -> i.addSynonym(this)); + } + this.cancerTypes = cancerTypes; + } + + public Synonym cancerTypes(Set cancerTypes) { + this.setCancerTypes(cancerTypes); + return this; + } + + public Synonym addCancerType(CancerType cancerType) { + this.cancerTypes.add(cancerType); + cancerType.getSynonyms().add(this); + return this; + } + + public Synonym removeCancerType(CancerType cancerType) { + this.cancerTypes.remove(cancerType); + cancerType.getSynonyms().remove(this); + return this; + } + + public Set getGenes() { + return this.genes; + } + + public void setGenes(Set genes) { + if (this.genes != null) { + this.genes.forEach(i -> i.removeSynonym(this)); + } + if (genes != null) { + genes.forEach(i -> i.addSynonym(this)); + } + this.genes = genes; + } + + public Synonym genes(Set genes) { + this.setGenes(genes); + return this; + } + + public Synonym addGene(Gene gene) { + this.genes.add(gene); + gene.getSynonyms().add(this); + return this; + } + + public Synonym removeGene(Gene gene) { + this.genes.remove(gene); + gene.getSynonyms().remove(this); + return this; + } + + public Set getNciThesauruses() { + return this.nciThesauruses; + } + + public void setNciThesauruses(Set nciThesauruses) { + if (this.nciThesauruses != null) { + this.nciThesauruses.forEach(i -> i.removeSynonym(this)); + } + if (nciThesauruses != null) { + nciThesauruses.forEach(i -> i.addSynonym(this)); + } + this.nciThesauruses = nciThesauruses; + } + + public Synonym nciThesauruses(Set nciThesauruses) { + this.setNciThesauruses(nciThesauruses); + return this; + } + + public Synonym addNciThesaurus(NciThesaurus nciThesaurus) { + this.nciThesauruses.add(nciThesaurus); + nciThesaurus.getSynonyms().add(this); + return this; + } + + public Synonym removeNciThesaurus(NciThesaurus nciThesaurus) { + this.nciThesauruses.remove(nciThesaurus); + nciThesaurus.getSynonyms().remove(this); + return this; + } + + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Synonym)) { + return false; + } + return id != null && id.equals(((Synonym) o).id); + } + + @Override + public int hashCode() { + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); + } + + // prettier-ignore + @Override + public String toString() { + return "Synonym{" + + "id=" + getId() + + ", type='" + getType() + "'" + + ", source='" + getSource() + "'" + + ", code='" + getCode() + "'" + + ", name='" + getName() + "'" + + ", note='" + getNote() + "'" + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/Transcript.java b/src/main/java/org/mskcc/oncokb/curation/domain/Transcript.java new file mode 100644 index 000000000..9d463fe7e --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/Transcript.java @@ -0,0 +1,352 @@ +package org.mskcc.oncokb.curation.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; +import org.javers.core.metamodel.annotation.ShallowReference; +import org.mskcc.oncokb.curation.domain.enumeration.ReferenceGenome; + +/** + * A Transcript. + */ +@Entity +@Table(name = "transcript") +public class Transcript implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @Enumerated(EnumType.STRING) + @Column(name = "reference_genome") + private ReferenceGenome referenceGenome; + + @Column(name = "ensembl_transcript_id") + private String ensemblTranscriptId; + + @NotNull + @Column(name = "canonical", nullable = false) + private Boolean canonical; + + @Column(name = "ensembl_protein_id") + private String ensemblProteinId; + + @Column(name = "reference_sequence_id") + private String referenceSequenceId; + + @Column(name = "description") + private String description; + + @ShallowReference + @OneToMany(mappedBy = "transcript") + @JsonIgnoreProperties(value = { "transcript" }, allowSetters = true) + private Set sequences = new HashSet<>(); + + @ShallowReference + @OneToMany(mappedBy = "transcript") + @JsonIgnoreProperties(value = { "seqRegion", "transcript" }, allowSetters = true) + private Set fragments = new HashSet<>(); + + @ShallowReference + @ManyToMany + @JoinTable( + name = "rel_transcript__flag", + joinColumns = @JoinColumn(name = "transcript_id"), + inverseJoinColumns = @JoinColumn(name = "flag_id") + ) + @JsonIgnoreProperties(value = { "alterations", "articles", "drugs", "genes", "transcripts" }, allowSetters = true) + private Set flags = new HashSet<>(); + + @NotNull + @ShallowReference + @ManyToOne + @JsonIgnoreProperties(value = { "transcripts", "gene", "seqRegion" }, allowSetters = true) + private EnsemblGene ensemblGene; + + @NotNull + @ShallowReference + @ManyToOne + @JsonIgnoreProperties(value = { "ensemblGenes", "evidences", "transcripts", "flags", "synonyms", "alterations" }, allowSetters = true) + private Gene gene; + + @ShallowReference + @ManyToMany(mappedBy = "transcripts") + @JsonIgnoreProperties(value = { "flags", "genes", "transcripts", "consequence", "associations" }, allowSetters = true) + private Set alterations = new HashSet<>(); + + // jhipster-needle-entity-add-field - JHipster will add fields here + + public Long getId() { + return this.id; + } + + public Transcript id(Long id) { + this.setId(id); + return this; + } + + public void setId(Long id) { + this.id = id; + } + + public ReferenceGenome getReferenceGenome() { + return this.referenceGenome; + } + + public Transcript referenceGenome(ReferenceGenome referenceGenome) { + this.setReferenceGenome(referenceGenome); + return this; + } + + public void setReferenceGenome(ReferenceGenome referenceGenome) { + this.referenceGenome = referenceGenome; + } + + public String getEnsemblTranscriptId() { + return this.ensemblTranscriptId; + } + + public Transcript ensemblTranscriptId(String ensemblTranscriptId) { + this.setEnsemblTranscriptId(ensemblTranscriptId); + return this; + } + + public void setEnsemblTranscriptId(String ensemblTranscriptId) { + this.ensemblTranscriptId = ensemblTranscriptId; + } + + public Boolean getCanonical() { + return this.canonical; + } + + public Transcript canonical(Boolean canonical) { + this.setCanonical(canonical); + return this; + } + + public void setCanonical(Boolean canonical) { + this.canonical = canonical; + } + + public String getEnsemblProteinId() { + return this.ensemblProteinId; + } + + public Transcript ensemblProteinId(String ensemblProteinId) { + this.setEnsemblProteinId(ensemblProteinId); + return this; + } + + public void setEnsemblProteinId(String ensemblProteinId) { + this.ensemblProteinId = ensemblProteinId; + } + + public String getReferenceSequenceId() { + return this.referenceSequenceId; + } + + public Transcript referenceSequenceId(String referenceSequenceId) { + this.setReferenceSequenceId(referenceSequenceId); + return this; + } + + public void setReferenceSequenceId(String referenceSequenceId) { + this.referenceSequenceId = referenceSequenceId; + } + + public String getDescription() { + return this.description; + } + + public Transcript description(String description) { + this.setDescription(description); + return this; + } + + public void setDescription(String description) { + this.description = description; + } + + public Set getSequences() { + return this.sequences; + } + + public void setSequences(Set sequences) { + if (this.sequences != null) { + this.sequences.forEach(i -> i.setTranscript(null)); + } + if (sequences != null) { + sequences.forEach(i -> i.setTranscript(this)); + } + this.sequences = sequences; + } + + public Transcript sequences(Set sequences) { + this.setSequences(sequences); + return this; + } + + public Transcript addSequence(Sequence sequence) { + this.sequences.add(sequence); + sequence.setTranscript(this); + return this; + } + + public Transcript removeSequence(Sequence sequence) { + this.sequences.remove(sequence); + sequence.setTranscript(null); + return this; + } + + public Set getFragments() { + return this.fragments; + } + + public void setFragments(Set genomeFragments) { + if (this.fragments != null) { + this.fragments.forEach(i -> i.setTranscript(null)); + } + if (genomeFragments != null) { + genomeFragments.forEach(i -> i.setTranscript(this)); + } + this.fragments = genomeFragments; + } + + public Transcript fragments(Set genomeFragments) { + this.setFragments(genomeFragments); + return this; + } + + public Transcript addFragments(GenomeFragment genomeFragment) { + this.fragments.add(genomeFragment); + genomeFragment.setTranscript(this); + return this; + } + + public Transcript removeFragments(GenomeFragment genomeFragment) { + this.fragments.remove(genomeFragment); + genomeFragment.setTranscript(null); + return this; + } + + public Set getFlags() { + return this.flags; + } + + public void setFlags(Set flags) { + this.flags = flags; + } + + public Transcript flags(Set flags) { + this.setFlags(flags); + return this; + } + + public Transcript addFlag(Flag flag) { + this.flags.add(flag); + flag.getTranscripts().add(this); + return this; + } + + public Transcript removeFlag(Flag flag) { + this.flags.remove(flag); + flag.getTranscripts().remove(this); + return this; + } + + public EnsemblGene getEnsemblGene() { + return this.ensemblGene; + } + + public void setEnsemblGene(EnsemblGene ensemblGene) { + this.ensemblGene = ensemblGene; + } + + public Transcript ensemblGene(EnsemblGene ensemblGene) { + this.setEnsemblGene(ensemblGene); + return this; + } + + public Gene getGene() { + return this.gene; + } + + public void setGene(Gene gene) { + this.gene = gene; + } + + public Transcript gene(Gene gene) { + this.setGene(gene); + return this; + } + + public Set getAlterations() { + return this.alterations; + } + + public void setAlterations(Set alterations) { + if (this.alterations != null) { + this.alterations.forEach(i -> i.removeTranscript(this)); + } + if (alterations != null) { + alterations.forEach(i -> i.addTranscript(this)); + } + this.alterations = alterations; + } + + public Transcript alterations(Set alterations) { + this.setAlterations(alterations); + return this; + } + + public Transcript addAlteration(Alteration alteration) { + this.alterations.add(alteration); + alteration.getTranscripts().add(this); + return this; + } + + public Transcript removeAlteration(Alteration alteration) { + this.alterations.remove(alteration); + alteration.getTranscripts().remove(this); + return this; + } + + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Transcript)) { + return false; + } + return id != null && id.equals(((Transcript) o).id); + } + + @Override + public int hashCode() { + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); + } + + // prettier-ignore + @Override + public String toString() { + return "Transcript{" + + "id=" + getId() + + ", referenceGenome='" + getReferenceGenome() + "'" + + ", ensemblTranscriptId='" + getEnsemblTranscriptId() + "'" + + ", canonical='" + getCanonical() + "'" + + ", ensemblProteinId='" + getEnsemblProteinId() + "'" + + ", referenceSequenceId='" + getReferenceSequenceId() + "'" + + ", description='" + getDescription() + "'" + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/User.java b/src/main/java/org/mskcc/oncokb/curation/domain/User.java new file mode 100644 index 000000000..0971350a8 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/User.java @@ -0,0 +1,174 @@ +package org.mskcc.oncokb.curation.domain; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import jakarta.persistence.*; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; +import java.io.Serializable; +import java.util.HashSet; +import java.util.Locale; +import java.util.Set; +import org.apache.commons.lang3.StringUtils; +import org.hibernate.annotations.BatchSize; +import org.mskcc.oncokb.curation.config.Constants; + +/** + * A user. + */ +@Entity +@Table(name = "user") +public class User extends AbstractAuditingEntity implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @NotNull + @Pattern(regexp = Constants.LOGIN_REGEX) + @Size(min = 1, max = 50) + @Column(length = 50, unique = true, nullable = false) + private String login; + + @Size(max = 50) + @Column(name = "first_name", length = 50, nullable = false) + private String firstName; + + @Size(max = 50) + @Column(name = "last_name", length = 50, nullable = false) + private String lastName; + + @Email + @Size(min = 5, max = 254) + @Column(length = 254, unique = true, nullable = false) + private String email; + + @NotNull + @Column(nullable = false) + private boolean activated = false; + + @Size(min = 2, max = 10) + @Column(name = "lang_key", length = 10) + private String langKey; + + @Size(max = 256) + @Column(name = "image_url", length = 256) + private String imageUrl; + + @JsonIgnore + @ManyToMany(fetch = FetchType.EAGER) + @JoinTable( + name = "user_authority", + joinColumns = { @JoinColumn(name = "user_id", referencedColumnName = "id") }, + inverseJoinColumns = { @JoinColumn(name = "authority_name", referencedColumnName = "name") } + ) + @BatchSize(size = 20) + private Set authorities = new HashSet<>(); + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getLogin() { + return login; + } + + // Lowercase the login before saving it in database + public void setLogin(String login) { + this.login = StringUtils.lowerCase(login, Locale.ENGLISH); + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getImageUrl() { + return imageUrl; + } + + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + } + + public boolean isActivated() { + return activated; + } + + public void setActivated(boolean activated) { + this.activated = activated; + } + + public String getLangKey() { + return langKey; + } + + public void setLangKey(String langKey) { + this.langKey = langKey; + } + + public Set getAuthorities() { + return authorities; + } + + public void setAuthorities(Set authorities) { + this.authorities = authorities; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof User)) { + return false; + } + return id != null && id.equals(((User) o).id); + } + + @Override + public int hashCode() { + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); + } + + // prettier-ignore + @Override + public String toString() { + return "User{" + + "login='" + login + '\'' + + ", firstName='" + firstName + '\'' + + ", lastName='" + lastName + '\'' + + ", email='" + email + '\'' + + ", imageUrl='" + imageUrl + '\'' + + ", activated='" + activated + '\'' + + ", langKey='" + langKey + '\'' + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/dto/AnnotationDTO.java b/src/main/java/org/mskcc/oncokb/curation/domain/dto/AnnotationDTO.java new file mode 100644 index 000000000..0f302eb86 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/dto/AnnotationDTO.java @@ -0,0 +1,27 @@ +package org.mskcc.oncokb.curation.domain.dto; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +public class AnnotationDTO implements Serializable { + + HotspotInfoDTO hotspot = new HotspotInfoDTO(); + List exons = new ArrayList<>(); + + public HotspotInfoDTO getHotspot() { + return hotspot; + } + + public void setHotspot(HotspotInfoDTO hotspot) { + this.hotspot = hotspot; + } + + public List getExons() { + return exons; + } + + public void setExons(List exons) { + this.exons = exons; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/dto/HotspotDTO.java b/src/main/java/org/mskcc/oncokb/curation/domain/dto/HotspotDTO.java new file mode 100644 index 000000000..1e0aa816e --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/dto/HotspotDTO.java @@ -0,0 +1,28 @@ +package org.mskcc.oncokb.curation.domain.dto; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import org.mskcc.oncokb.curation.domain.Alteration; + +public class HotspotDTO implements Serializable { + + String type; + String alteration; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getAlteration() { + return alteration; + } + + public void setAlteration(String alteration) { + this.alteration = alteration; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/dto/HotspotInfoDTO.java b/src/main/java/org/mskcc/oncokb/curation/domain/dto/HotspotInfoDTO.java new file mode 100644 index 000000000..08a40b7b1 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/dto/HotspotInfoDTO.java @@ -0,0 +1,27 @@ +package org.mskcc.oncokb.curation.domain.dto; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +public class HotspotInfoDTO implements Serializable { + + Boolean isHotspot = false; + List associatedHotspots = new ArrayList<>(); + + public Boolean getHotspot() { + return isHotspot; + } + + public void setHotspot(Boolean hotspot) { + isHotspot = hotspot; + } + + public List getAssociatedHotspots() { + return associatedHotspots; + } + + public void setAssociatedHotspots(List associatedHotspots) { + this.associatedHotspots = associatedHotspots; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/dto/ProteinExonDTO.java b/src/main/java/org/mskcc/oncokb/curation/domain/dto/ProteinExonDTO.java new file mode 100644 index 000000000..df022100d --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/dto/ProteinExonDTO.java @@ -0,0 +1,26 @@ +package org.mskcc.oncokb.curation.domain.dto; + +import java.io.Serializable; +import org.mskcc.oncokb.curation.model.IntegerRange; + +public class ProteinExonDTO implements Serializable { + + IntegerRange range; + Integer exon; + + public IntegerRange getRange() { + return range; + } + + public void setRange(IntegerRange range) { + this.range = range; + } + + public Integer getExon() { + return exon; + } + + public void setExon(Integer exon) { + this.exon = exon; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/AlterationType.java b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/AlterationType.java new file mode 100644 index 000000000..0c19ebd6a --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/AlterationType.java @@ -0,0 +1,16 @@ +package org.mskcc.oncokb.curation.domain.enumeration; + +/** + * The AlterationType enumeration. + */ +public enum AlterationType { + GENOMIC_CHANGE, + CDNA_CHANGE, + PROTEIN_CHANGE, + MUTATION, + COPY_NUMBER_ALTERATION, + STRUCTURAL_VARIANT, + ANY, + UNKNOWN, + NA, +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/ArticleType.java b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/ArticleType.java new file mode 100644 index 000000000..a655cb396 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/ArticleType.java @@ -0,0 +1,14 @@ +package org.mskcc.oncokb.curation.domain.enumeration; + +/** + * The ArticleType enumeration. + */ +public enum ArticleType { + PUBMED, + ABSTRACT, + REFERENCE, + FDADRUG_LETTER, + FDADRUG_LABEL, + FDADRUG_SUMMARY, + FDADRUG_SUMMARY_REVIEW, +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/AssociationCancerTypeRelation.java b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/AssociationCancerTypeRelation.java new file mode 100644 index 000000000..7ee52e850 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/AssociationCancerTypeRelation.java @@ -0,0 +1,10 @@ +package org.mskcc.oncokb.curation.domain.enumeration; + +/** + * The AssociationCancerTypeRelation enumeration. + */ +public enum AssociationCancerTypeRelation { + INCLUSION, + EXCLUSION, + RELEVANT, +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/AuditEntity.java b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/AuditEntity.java new file mode 100644 index 000000000..d043ab44b --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/AuditEntity.java @@ -0,0 +1,44 @@ +package org.mskcc.oncokb.curation.domain.enumeration; + +public enum AuditEntity { + ALTERATION("Alteration"), + ARTICLE("Article"), + ASSOCIATION("Association"), + AUTHORITY("Authority"), + CANCER_TYPE("CancerType"), + CATEGORICAL_ALTERATION("CategoricalAlteration"), + CLINICAL_TRIAL("ClinicalTrial"), + CLINICAL_TRIAL_ARM("ClinicalTrialArm"), + COMPANION_DIAGNOSTIC_DEVICE("CompanionDiagnosticDevice"), + CONSEQUENCE("Consequence"), + DRUG("Drug"), + ELIGIBILITY_CRITERIA("EligibilityCriteria"), + ENSEMBL_GENE("EnsemblGene"), + EVIDENCE("Evidence"), + FDA_DRUG("FdaDrug"), + FDA_SUBMISSION("FdaSubmission"), + FDA_SUBMISSION_TYPE("FdaSubmissionType"), + FLAG("Flag"), + GENE("Gene"), + GENOME_FRAGMENT("GenomeFragment"), + GENOMIC_INDICATOR("GenomicIndicator"), + INFO("Info"), + LEVEL_OF_EVIDENCE("LevelOfEvidence"), + NCI_THESAURUS("NciThesaurus"), + SEQ_REGION("SeqRegion"), + SEQUENCE("Sequence"), + SPECIMEN_TYPE("SpecimenType"), + SYNONYM("Synonym"), + TRANSCRIPT("Transcript"), + USER("User"); + + private String className; + + AuditEntity(String className) { + this.className = className; + } + + public String getClassName() { + return className; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/CNAConsequence.java b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/CNAConsequence.java new file mode 100644 index 000000000..fc3a29e2d --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/CNAConsequence.java @@ -0,0 +1,9 @@ +package org.mskcc.oncokb.curation.domain.enumeration; + +public enum CNAConsequence { + AMPLIFICATION, + DELETION, + GAIN, + LOSS, + UNKNOWN, +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/CategoricalAlterationType.java b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/CategoricalAlterationType.java new file mode 100644 index 000000000..7e697e23d --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/CategoricalAlterationType.java @@ -0,0 +1,33 @@ +package org.mskcc.oncokb.curation.domain.enumeration; + +/** + * The CategoricalAlterationType enumeration. + */ +public enum CategoricalAlterationType { + ONCOGENIC_MUTATIONS, + GAIN_OF_FUNCTION_MUTATIONS, + LOSS_OF_FUNCTION_MUTATIONS, + SWITCH_OF_FUNCTION_MUTATIONS, + KINASE_DOMAIN_DUPLICATION, + INTERNAL_TANDEM_DUPLICATION, + PARTIAL_TANDEM_DUPLICATION, + OVEREXPRESSION, + HYPERMETHYLATION, + MSIH, + TMBH, + EPIGENETIC_SILENCING, + VI, + VII, + VIII, + VIV, + VV, + VUS, + TRUNCATING_MUTATIONS, + FUSIONS, + AMPLIFICATION, + DELETION, + GAIN, + LOSS, + PROMOTER, + WILDTYPE, +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/EligibilityCriteriaType.java b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/EligibilityCriteriaType.java new file mode 100644 index 000000000..d0590afa2 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/EligibilityCriteriaType.java @@ -0,0 +1,9 @@ +package org.mskcc.oncokb.curation.domain.enumeration; + +/** + * The EligibilityCriteriaType enumeration. + */ +public enum EligibilityCriteriaType { + INCLUSION, + EXCLUSION, +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/EntityStatusType.java b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/EntityStatusType.java new file mode 100644 index 000000000..a9b079fc0 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/EntityStatusType.java @@ -0,0 +1,7 @@ +package org.mskcc.oncokb.curation.domain.enumeration; + +public enum EntityStatusType { + OK, + WARNING, + ERROR, +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/EvidenceType.java b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/EvidenceType.java new file mode 100644 index 000000000..c05e02240 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/EvidenceType.java @@ -0,0 +1,20 @@ +package org.mskcc.oncokb.curation.domain.enumeration; + +public enum EvidenceType { + GENE_SUMMARY, + MUTATION_SUMMARY, + TUMOR_TYPE_SUMMARY, + GENE_TUMOR_TYPE_SUMMARY, + PROGNOSTIC_SUMMARY, + DIAGNOSTIC_SUMMARY, + GENE_BACKGROUND, + ONCOGENIC, + MUTATION_EFFECT, + VUS, + PROGNOSTIC_IMPLICATION, + DIAGNOSTIC_IMPLICATION, + STANDARD_THERAPEUTIC_IMPLICATIONS_FOR_DRUG_SENSITIVITY, + STANDARD_THERAPEUTIC_IMPLICATIONS_FOR_DRUG_RESISTANCE, + INVESTIGATIONAL_THERAPEUTIC_IMPLICATIONS_DRUG_SENSITIVITY, + INVESTIGATIONAL_THERAPEUTIC_IMPLICATIONS_DRUG_RESISTANCE, +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/FdaSubmissionTypeKey.java b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/FdaSubmissionTypeKey.java new file mode 100644 index 000000000..d1ba516ed --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/FdaSubmissionTypeKey.java @@ -0,0 +1,32 @@ +package org.mskcc.oncokb.curation.domain.enumeration; + +/** + * The FdaSubmissionTypeKey enumeration. + */ +public enum FdaSubmissionTypeKey { + DEVICE_PMA("P"), + DEVICE_DENOVO("DEN"), + DEVICE_HDE("H"), + DEVICE_PMN("K"), + DRUG_NDA("NDA"), + DRUG_BLA("BLA"); + + String prefix; + + FdaSubmissionTypeKey(String prefix) { + this.prefix = prefix; + } + + public String getPrefix() { + return this.prefix; + } + + public static FdaSubmissionTypeKey getTypeByPrefix(String prefix) { + for (FdaSubmissionTypeKey type : FdaSubmissionTypeKey.values()) { + if (type.prefix.equalsIgnoreCase(prefix)) { + return type; + } + } + return null; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/FlagType.java b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/FlagType.java new file mode 100644 index 000000000..9ea1db8f2 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/FlagType.java @@ -0,0 +1,12 @@ +package org.mskcc.oncokb.curation.domain.enumeration; + +/** + * The FlagType enumeration. + */ +public enum FlagType { + GENE_TYPE, + GENE_PANEL, + TRANSCRIPT, + DRUG, + HOTSPOT, +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/GenePanelFlagEnum.java b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/GenePanelFlagEnum.java new file mode 100644 index 000000000..c6efb1e97 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/GenePanelFlagEnum.java @@ -0,0 +1,27 @@ +package org.mskcc.oncokb.curation.domain.enumeration; + +/** + * The GenePanelFlagEnum enumeration. + */ +public enum GenePanelFlagEnum { + ONCOKB, + MSK_IMPACT_505, + MSK_ACCESS, + MSK_HEME, + VOGELSTEIN, + CGC_T1, + FOUNDATION_ONE, + FOUNDATION_HEME, + TEMPUS_XT, + TEMPUS_XR, + TEMPUS_XF, + TEMPUS_XG, + TEMPUS_XG_PLUS, + TEMPUS_XE, + GUARDANT_360, + ONCOMINE_DX, + ONCOMINE_CA_V3, + ONCOMINE_CA_PLUS, + CARIS_MI, + TRUSIGHT_ONCOLOGY_500, +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/GenomeFragmentType.java b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/GenomeFragmentType.java new file mode 100644 index 000000000..b38b6b027 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/GenomeFragmentType.java @@ -0,0 +1,11 @@ +package org.mskcc.oncokb.curation.domain.enumeration; + +/** + * The GenomeFragmentType enumeration. + */ +public enum GenomeFragmentType { + GENE, + EXON, + FIVE_PRIME_UTR, + THREE_PRIME_UTR, +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/GenomicIndicatorType.java b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/GenomicIndicatorType.java new file mode 100644 index 000000000..6fa549208 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/GenomicIndicatorType.java @@ -0,0 +1,5 @@ +package org.mskcc.oncokb.curation.domain.enumeration; + +public enum GenomicIndicatorType { + GERMLINE, +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/GeographicRegion.java b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/GeographicRegion.java new file mode 100644 index 000000000..e3c4cdad7 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/GeographicRegion.java @@ -0,0 +1,9 @@ +package org.mskcc.oncokb.curation.domain.enumeration; + +/** + * The GeographicRegion enumeration. + */ +public enum GeographicRegion { + US, + EU, +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/HotspotFlagEnum.java b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/HotspotFlagEnum.java new file mode 100644 index 000000000..a8d2df6ce --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/HotspotFlagEnum.java @@ -0,0 +1,9 @@ +package org.mskcc.oncokb.curation.domain.enumeration; + +/** + * The TranscriptFlagEnum enumeration. + */ +public enum HotspotFlagEnum { + HOTSPOT_V1, + THREE_D, +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/InfoType.java b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/InfoType.java new file mode 100644 index 000000000..7819074af --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/InfoType.java @@ -0,0 +1,12 @@ +package org.mskcc.oncokb.curation.domain.enumeration; + +/** + * The InfoType enumeration. + */ +public enum InfoType { + NCIT_VERSION, + GENE_VERSION, + ONCOKB_TRANSCRIPT_VERSION, + MANE_TRANSCRIPT_VERSION, + ENSEMBL_VERSION, +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/LevelOfEvidenceType.java b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/LevelOfEvidenceType.java new file mode 100644 index 000000000..fb3a81e54 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/LevelOfEvidenceType.java @@ -0,0 +1,8 @@ +package org.mskcc.oncokb.curation.domain.enumeration; + +public enum LevelOfEvidenceType { + TX, + DX, + PX, + FDA, +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/MutationConsequence.java b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/MutationConsequence.java new file mode 100644 index 000000000..17d1009e9 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/MutationConsequence.java @@ -0,0 +1,42 @@ +package org.mskcc.oncokb.curation.domain.enumeration; + +public enum MutationConsequence { + UTR_3_PRIME_VARIANT, + UTR_5_PRIME_VARIANT, + ANY, + CODING_SEQUENCE_VARIANT, + DOWNSTREAM_GENE_VARIANT, + FEATURE_ELONGATION, + FEATURE_TRUNCATION, + FRAMESHIFT_VARIANT, + INCOMPLETE_TERMINAL_CODON_VARIANT, + INFRAME_DELETION, + INFRAME_INSERTION, + INTERGENIC_VARIANT, + INTRON_VARIANT, + MATURE_MIRNA_VARIANT, + MISSENSE_VARIANT, + NA, + NMD_TRANSCRIPT_VARIANT, + NON_CODING_TRANSCRIPT_EXON_VARIANT, + NON_CODING_TRANSCRIPT_VARIANT, + NON_TRUNCATING_VARIANT, + REGULATORY_REGION_ABLATION, + REGULATORY_REGION_AMPLIFICATION, + REGULATORY_REGION_VARIANT, + SPLICE_ACCEPTOR_VARIANT, + SPLICE_DONOR_VARIANT, + SPLICE_REGION_VARIANT, + START_LOST, + STOP_GAINED, + STOP_LOST, + STOP_RETAINED_VARIANT, + SYNONYMOUS_VARIANT, + TFBS_ABLATION, + TFBS_AMPLIFICATION, + TF_BINDING_SITE_VARIANT, + TRANSCRIPT_ABLATION, + TRANSCRIPT_AMPLIFICATION, + UPSTREAM_GENE_VARIANT, + UNKNOWN, +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/ReferenceGenome.java b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/ReferenceGenome.java new file mode 100644 index 000000000..07774946b --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/ReferenceGenome.java @@ -0,0 +1,9 @@ +package org.mskcc.oncokb.curation.domain.enumeration; + +/** + * The ReferenceGenome enumeration. + */ +public enum ReferenceGenome { + GRCh37, + GRCh38, +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/RuleEntity.java b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/RuleEntity.java new file mode 100644 index 000000000..de8ef23ab --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/RuleEntity.java @@ -0,0 +1,6 @@ +package org.mskcc.oncokb.curation.domain.enumeration; + +public enum RuleEntity { + DRUG, + CANCER_TYPE, +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/SVConsequence.java b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/SVConsequence.java new file mode 100644 index 000000000..aea1fd65b --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/SVConsequence.java @@ -0,0 +1,11 @@ +package org.mskcc.oncokb.curation.domain.enumeration; + +public enum SVConsequence { + DELETION, + TRANSLOCATION, + DUPLICATION, + INSERTION, + INVERSION, + FUSION, + UNKNOWN, +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/SequenceType.java b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/SequenceType.java new file mode 100644 index 000000000..daf886f2e --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/SequenceType.java @@ -0,0 +1,10 @@ +package org.mskcc.oncokb.curation.domain.enumeration; + +/** + * The SequenceType enumeration. + */ +public enum SequenceType { + PROTEIN, + CDNA, + GENOMIC, +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/SynonymType.java b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/SynonymType.java new file mode 100644 index 000000000..1f559522c --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/SynonymType.java @@ -0,0 +1,11 @@ +package org.mskcc.oncokb.curation.domain.enumeration; + +/** + * The AlterationType enumeration. + */ +public enum SynonymType { + GENE, + NCIT, + CANCER_TYPE, + ARTICLE, +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/TranscriptFlagEnum.java b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/TranscriptFlagEnum.java new file mode 100644 index 000000000..6be4edd0f --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/TranscriptFlagEnum.java @@ -0,0 +1,12 @@ +package org.mskcc.oncokb.curation.domain.enumeration; + +/** + * The TranscriptFlagEnum enumeration. + */ +public enum TranscriptFlagEnum { + MANE_SELECT, + MANE_PLUS_CLINICAL, + GN_CANONICAL, + ONCOKB, + ENSEMBL_CANONICAL, +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/TumorForm.java b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/TumorForm.java new file mode 100644 index 000000000..e6462b6e3 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/enumeration/TumorForm.java @@ -0,0 +1,10 @@ +package org.mskcc.oncokb.curation.domain.enumeration; + +/** + * The TumorForm enumeration. + */ +public enum TumorForm { + SOLID, + LIQUID, + MIXED, +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/firebase/CancerType.java b/src/main/java/org/mskcc/oncokb/curation/domain/firebase/CancerType.java new file mode 100644 index 000000000..f14c8e2ad --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/firebase/CancerType.java @@ -0,0 +1,32 @@ +package org.mskcc.oncokb.curation.domain.firebase; + +public class CancerType { + + String code; + String mainType; + String subtype; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getMainType() { + return mainType; + } + + public void setMainType(String mainType) { + this.mainType = mainType; + } + + public String getSubtype() { + return subtype; + } + + public void setSubtype(String subtype) { + this.subtype = subtype; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/firebase/Drug.java b/src/main/java/org/mskcc/oncokb/curation/domain/firebase/Drug.java new file mode 100644 index 000000000..7b8ecaccc --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/firebase/Drug.java @@ -0,0 +1,41 @@ +package org.mskcc.oncokb.curation.domain.firebase; + +public class Drug { + + String uuid; + String ncitCode; + String ncitName; + String drugName; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getNcitCode() { + return ncitCode; + } + + public void setNcitCode(String ncitCode) { + this.ncitCode = ncitCode; + } + + public String getNcitName() { + return ncitName; + } + + public void setNcitName(String ncitName) { + this.ncitName = ncitName; + } + + public String getDrugName() { + return drugName; + } + + public void setDrugName(String drugName) { + this.drugName = drugName; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/firebase/Gene.java b/src/main/java/org/mskcc/oncokb/curation/domain/firebase/Gene.java new file mode 100644 index 000000000..66fbc0bc8 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/firebase/Gene.java @@ -0,0 +1,53 @@ +package org.mskcc.oncokb.curation.domain.firebase; + +import java.util.ArrayList; +import java.util.List; + +public class Gene { + + String name; + String summary; + String background; + GeneType type; + List mutations = new ArrayList<>(); + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getSummary() { + return summary; + } + + public void setSummary(String summary) { + this.summary = summary; + } + + public String getBackground() { + return background; + } + + public void setBackground(String background) { + this.background = background; + } + + public GeneType getType() { + return type; + } + + public void setType(GeneType type) { + this.type = type; + } + + public List getMutations() { + return mutations; + } + + public void setMutations(List mutations) { + this.mutations = mutations; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/firebase/GeneType.java b/src/main/java/org/mskcc/oncokb/curation/domain/firebase/GeneType.java new file mode 100644 index 000000000..8b704c639 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/firebase/GeneType.java @@ -0,0 +1,23 @@ +package org.mskcc.oncokb.curation.domain.firebase; + +public class GeneType { + + String ocg; + String tsg; + + public String getOcg() { + return ocg; + } + + public void setOcg(String ocg) { + this.ocg = ocg; + } + + public String getTsg() { + return tsg; + } + + public void setTsg(String tsg) { + this.tsg = tsg; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/firebase/GermlineMutation.java b/src/main/java/org/mskcc/oncokb/curation/domain/firebase/GermlineMutation.java new file mode 100644 index 000000000..24aa3cba4 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/firebase/GermlineMutation.java @@ -0,0 +1,41 @@ +package org.mskcc.oncokb.curation.domain.firebase; + +public class GermlineMutation { + + String pathogenic; + String penetrance; + String inheritanceMechanism; + String cancerRisk; + + public String getPathogenic() { + return pathogenic; + } + + public void setPathogenic(String pathogenic) { + this.pathogenic = pathogenic; + } + + public String getPenetrance() { + return penetrance; + } + + public void setPenetrance(String penetrance) { + this.penetrance = penetrance; + } + + public String getInheritanceMechanism() { + return inheritanceMechanism; + } + + public void setInheritanceMechanism(String inheritanceMechanism) { + this.inheritanceMechanism = inheritanceMechanism; + } + + public String getCancerRisk() { + return cancerRisk; + } + + public void setCancerRisk(String cancerRisk) { + this.cancerRisk = cancerRisk; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/firebase/Implication.java b/src/main/java/org/mskcc/oncokb/curation/domain/firebase/Implication.java new file mode 100644 index 000000000..590370103 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/firebase/Implication.java @@ -0,0 +1,23 @@ +package org.mskcc.oncokb.curation.domain.firebase; + +public class Implication { + + String level; + String description; + + public String getLevel() { + return level; + } + + public void setLevel(String level) { + this.level = level; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/firebase/Mutation.java b/src/main/java/org/mskcc/oncokb/curation/domain/firebase/Mutation.java new file mode 100644 index 000000000..15294207b --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/firebase/Mutation.java @@ -0,0 +1,39 @@ +package org.mskcc.oncokb.curation.domain.firebase; + +import com.google.firebase.database.Exclude; +import com.google.firebase.database.PropertyName; +import java.util.ArrayList; +import java.util.List; + +public class Mutation { + + String name; + MutationEffect mutationEffect; + List tumors = new ArrayList<>(); + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @PropertyName("mutation_effect") + public MutationEffect getMutationEffect() { + return mutationEffect; + } + + @PropertyName("mutation_effect") + public void setMutationEffect(MutationEffect mutationEffect) { + this.mutationEffect = mutationEffect; + } + + public List getTumors() { + return tumors; + } + + public void setTumors(List tumors) { + this.tumors = tumors; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/firebase/MutationEffect.java b/src/main/java/org/mskcc/oncokb/curation/domain/firebase/MutationEffect.java new file mode 100644 index 000000000..2ec1ffc44 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/firebase/MutationEffect.java @@ -0,0 +1,41 @@ +package org.mskcc.oncokb.curation.domain.firebase; + +public class MutationEffect { + + String effect; + String description; + String oncogenic; + GermlineMutation germline; + + public String getEffect() { + return effect; + } + + public void setEffect(String effect) { + this.effect = effect; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getOncogenic() { + return oncogenic; + } + + public void setOncogenic(String oncogenic) { + this.oncogenic = oncogenic; + } + + public GermlineMutation getGermline() { + return germline; + } + + public void setGermline(GermlineMutation germline) { + this.germline = germline; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/firebase/TI.java b/src/main/java/org/mskcc/oncokb/curation/domain/firebase/TI.java new file mode 100644 index 000000000..0e44e7d1e --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/firebase/TI.java @@ -0,0 +1,26 @@ +package org.mskcc.oncokb.curation.domain.firebase; + +import java.util.ArrayList; +import java.util.List; + +public class TI { + + String name; + List treatments = new ArrayList<>(); + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getTreatments() { + return treatments; + } + + public void setTreatments(List treatments) { + this.treatments = treatments; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/firebase/Treatment.java b/src/main/java/org/mskcc/oncokb/curation/domain/firebase/Treatment.java new file mode 100644 index 000000000..59c0ffdbe --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/firebase/Treatment.java @@ -0,0 +1,70 @@ +package org.mskcc.oncokb.curation.domain.firebase; + +import com.google.firebase.database.PropertyName; + +public class Treatment { + + String description; + String indication; + String level; + String fdaLevel; + String name; + String propagation; + String propagationLiquid; + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getIndication() { + return indication; + } + + public void setIndication(String indication) { + this.indication = indication; + } + + public String getLevel() { + return level; + } + + public void setLevel(String level) { + this.level = level; + } + + public String getFdaLevel() { + return fdaLevel; + } + + public void setFdaLevel(String fdaLevel) { + this.fdaLevel = fdaLevel; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPropagation() { + return propagation; + } + + public void setPropagation(String propagation) { + this.propagation = propagation; + } + + public String getPropagationLiquid() { + return propagationLiquid; + } + + public void setPropagationLiquid(String propagationLiquid) { + this.propagationLiquid = propagationLiquid; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/firebase/Tumor.java b/src/main/java/org/mskcc/oncokb/curation/domain/firebase/Tumor.java new file mode 100644 index 000000000..d5591eee3 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/firebase/Tumor.java @@ -0,0 +1,75 @@ +package org.mskcc.oncokb.curation.domain.firebase; + +import com.google.firebase.database.PropertyName; +import java.util.ArrayList; +import java.util.List; + +public class Tumor { + + String summary; + + @PropertyName("TIs") + List tis = new ArrayList<>(); + + List cancerTypes; + Implication diagnostic; + String diagnosticSummary; + Implication prognostic; + String prognosticSummary; + + public String getSummary() { + return summary; + } + + public void setSummary(String summary) { + this.summary = summary; + } + + public List getTis() { + return tis; + } + + public void setTis(List tis) { + this.tis = tis; + } + + public List getCancerTypes() { + return cancerTypes; + } + + public void setCancerTypes(List cancerTypes) { + this.cancerTypes = cancerTypes; + } + + public Implication getDiagnostic() { + return diagnostic; + } + + public void setDiagnostic(Implication diagnostic) { + this.diagnostic = diagnostic; + } + + public String getDiagnosticSummary() { + return diagnosticSummary; + } + + public void setDiagnosticSummary(String diagnosticSummary) { + this.diagnosticSummary = diagnosticSummary; + } + + public Implication getPrognostic() { + return prognostic; + } + + public void setPrognostic(Implication prognostic) { + this.prognostic = prognostic; + } + + public String getPrognosticSummary() { + return prognosticSummary; + } + + public void setPrognosticSummary(String prognosticSummary) { + this.prognosticSummary = prognosticSummary; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/README.md b/src/main/java/org/mskcc/oncokb/curation/domain/nih/README.md new file mode 100644 index 000000000..4ed1fc261 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/README.md @@ -0,0 +1,20 @@ +# Info + +The models under this folder come from https://github.com/bhsingh/utility + +We modified the property `value` in AbstractText and Abstract because the value also includes HTML Tags. We have to trim the tag but keep the text. + +#### New + +```new + @XmlMixed + @XmlAnyElement + protected List value; +``` + +#### Old + +```old + @XmlValue + protected String value; +``` diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Abstract.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Abstract.java new file mode 100644 index 000000000..a62d65182 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Abstract.java @@ -0,0 +1,77 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "abstractText", "copyrightInformation" }) +@XmlRootElement(name = "Abstract") +public class Abstract { + + @XmlElement(name = "AbstractText", required = true) + protected List abstractText; + + @XmlElement(name = "CopyrightInformation") + protected String copyrightInformation; + + /** + * Gets the value of the abstractText property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the abstractText property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getAbstractText().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link AbstractText } + * + * + */ + public List getAbstractText() { + if (abstractText == null) { + abstractText = new ArrayList(); + } + return this.abstractText; + } + + /** + * Gets the value of the copyrightInformation property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getCopyrightInformation() { + return copyrightInformation; + } + + /** + * Sets the value of the copyrightInformation property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setCopyrightInformation(String value) { + this.copyrightInformation = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/AbstractText.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/AbstractText.java new file mode 100644 index 000000000..890e98acb --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/AbstractText.java @@ -0,0 +1,76 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.List; +import javax.xml.bind.annotation.*; +import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; +import javax.xml.bind.annotation.adapters.NormalizedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "AbstractText") +public class AbstractText { + + @XmlAttribute(name = "Label") + @XmlJavaTypeAdapter(NormalizedStringAdapter.class) + protected String label; + + @XmlAttribute(name = "NlmCategory") + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + protected String nlmCategory; + + @XmlMixed + @XmlAnyElement + protected List value; + + /** + * Gets the value of the label property. + * + * @return possible object is + * {@link String } + */ + public String getLabel() { + return label; + } + + /** + * Sets the value of the label property. + * + * @param value allowed object is + * {@link String } + */ + public void setLabel(String value) { + this.label = value; + } + + /** + * Gets the value of the nlmCategory property. + * + * @return possible object is + * {@link String } + */ + public String getNlmCategory() { + return nlmCategory; + } + + /** + * Sets the value of the nlmCategory property. + * + * @param value allowed object is + * {@link String } + */ + public void setNlmCategory(String value) { + this.nlmCategory = value; + } + + public List getValue() { + return value; + } + + public void setValue(List value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/AccessionNumber.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/AccessionNumber.java new file mode 100644 index 000000000..6774aacac --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/AccessionNumber.java @@ -0,0 +1,43 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "AccessionNumber") +public class AccessionNumber { + + @XmlValue + protected String value; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/AccessionNumberList.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/AccessionNumberList.java new file mode 100644 index 000000000..51c4651d5 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/AccessionNumberList.java @@ -0,0 +1,50 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "accessionNumber" }) +@XmlRootElement(name = "AccessionNumberList") +public class AccessionNumberList { + + @XmlElement(name = "AccessionNumber", required = true) + protected List accessionNumber; + + /** + * Gets the value of the accessionNumber property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the accessionNumber property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getAccessionNumber().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link AccessionNumber } + * + * + */ + public List getAccessionNumber() { + if (accessionNumber == null) { + accessionNumber = new ArrayList(); + } + return this.accessionNumber; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Article.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Article.java new file mode 100644 index 000000000..53b9220d3 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Article.java @@ -0,0 +1,411 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElements; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType( + name = "", + propOrder = { + "journal", + "articleTitle", + "paginationOrELocationID", + "_abstract", + "affiliation", + "authorList", + "language", + "dataBankList", + "grantList", + "publicationTypeList", + "vernacularTitle", + "articleDate", + } +) +@XmlRootElement(name = "Article") +public class Article { + + @XmlAttribute(name = "PubModel", required = true) + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + protected String pubModel; + + @XmlElement(name = "Journal", required = true) + protected Journal journal; + + @XmlElement(name = "ArticleTitle", required = true) + protected ArticleTitle articleTitle; + + @XmlElements( + { + @XmlElement(name = "Pagination", required = true, type = Pagination.class), + @XmlElement(name = "ELocationID", required = true, type = ELocationID.class), + } + ) + protected List paginationOrELocationID; + + @XmlElement(name = "Abstract") + protected Abstract _abstract; + + @XmlElement(name = "Affiliation") + protected String affiliation; + + @XmlElement(name = "AuthorList") + protected AuthorList authorList; + + @XmlElement(name = "Language", required = true) + protected List language; + + @XmlElement(name = "DataBankList") + protected DataBankList dataBankList; + + @XmlElement(name = "GrantList") + protected GrantList grantList; + + @XmlElement(name = "PublicationTypeList", required = true) + protected PublicationTypeList publicationTypeList; + + @XmlElement(name = "VernacularTitle") + protected String vernacularTitle; + + @XmlElement(name = "ArticleDate") + protected List articleDate; + + /** + * Gets the value of the pubModel property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getPubModel() { + return pubModel; + } + + /** + * Sets the value of the pubModel property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setPubModel(String value) { + this.pubModel = value; + } + + /** + * Gets the value of the journal property. + * + * @return + * possible object is + * {@link Journal } + * + */ + public Journal getJournal() { + return journal; + } + + /** + * Sets the value of the journal property. + * + * @param value + * allowed object is + * {@link Journal } + * + */ + public void setJournal(Journal value) { + this.journal = value; + } + + /** + * Gets the value of the articleTitle property. + * + * @return + * possible object is + * {@link ArticleTitle } + * + */ + public ArticleTitle getArticleTitle() { + return articleTitle; + } + + /** + * Sets the value of the articleTitle property. + * + * @param value + * allowed object is + * {@link ArticleTitle } + * + */ + public void setArticleTitle(ArticleTitle value) { + this.articleTitle = value; + } + + /** + * Gets the value of the paginationOrELocationID property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the paginationOrELocationID property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getPaginationOrELocationID().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Pagination } + * {@link ELocationID } + * + * + */ + public List getPaginationOrELocationID() { + if (paginationOrELocationID == null) { + paginationOrELocationID = new ArrayList(); + } + return this.paginationOrELocationID; + } + + /** + * Gets the value of the abstract property. + * + * @return + * possible object is + * {@link Abstract } + * + */ + public Abstract getAbstract() { + return _abstract; + } + + /** + * Sets the value of the abstract property. + * + * @param value + * allowed object is + * {@link Abstract } + * + */ + public void setAbstract(Abstract value) { + this._abstract = value; + } + + /** + * Gets the value of the affiliation property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getAffiliation() { + return affiliation; + } + + /** + * Sets the value of the affiliation property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setAffiliation(String value) { + this.affiliation = value; + } + + /** + * Gets the value of the authorList property. + * + * @return + * possible object is + * {@link AuthorList } + * + */ + public AuthorList getAuthorList() { + return authorList; + } + + /** + * Sets the value of the authorList property. + * + * @param value + * allowed object is + * {@link AuthorList } + * + */ + public void setAuthorList(AuthorList value) { + this.authorList = value; + } + + /** + * Gets the value of the language property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the language property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getLanguage().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Language } + * + * + */ + public List getLanguage() { + if (language == null) { + language = new ArrayList(); + } + return this.language; + } + + /** + * Gets the value of the dataBankList property. + * + * @return + * possible object is + * {@link DataBankList } + * + */ + public DataBankList getDataBankList() { + return dataBankList; + } + + /** + * Sets the value of the dataBankList property. + * + * @param value + * allowed object is + * {@link DataBankList } + * + */ + public void setDataBankList(DataBankList value) { + this.dataBankList = value; + } + + /** + * Gets the value of the grantList property. + * + * @return + * possible object is + * {@link GrantList } + * + */ + public GrantList getGrantList() { + return grantList; + } + + /** + * Sets the value of the grantList property. + * + * @param value + * allowed object is + * {@link GrantList } + * + */ + public void setGrantList(GrantList value) { + this.grantList = value; + } + + /** + * Gets the value of the publicationTypeList property. + * + * @return + * possible object is + * {@link PublicationTypeList } + * + */ + public PublicationTypeList getPublicationTypeList() { + return publicationTypeList; + } + + /** + * Sets the value of the publicationTypeList property. + * + * @param value + * allowed object is + * {@link PublicationTypeList } + * + */ + public void setPublicationTypeList(PublicationTypeList value) { + this.publicationTypeList = value; + } + + /** + * Gets the value of the vernacularTitle property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getVernacularTitle() { + return vernacularTitle; + } + + /** + * Sets the value of the vernacularTitle property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setVernacularTitle(String value) { + this.vernacularTitle = value; + } + + /** + * Gets the value of the articleDate property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the articleDate property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getArticleDate().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link ArticleDate } + * + * + */ + public List getArticleDate() { + if (articleDate == null) { + articleDate = new ArrayList(); + } + return this.articleDate; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ArticleDate.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ArticleDate.java new file mode 100644 index 000000000..e09e82492 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ArticleDate.java @@ -0,0 +1,132 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.adapters.NormalizedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "year", "month", "day" }) +@XmlRootElement(name = "ArticleDate") +public class ArticleDate { + + @XmlAttribute(name = "DateType") + @XmlJavaTypeAdapter(NormalizedStringAdapter.class) + protected String dateType; + + @XmlElement(name = "Year", required = true) + protected Year year; + + @XmlElement(name = "Month", required = true) + protected Month month; + + @XmlElement(name = "Day", required = true) + protected Day day; + + /** + * Gets the value of the dateType property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getDateType() { + if (dateType == null) { + return "Electronic"; + } else { + return dateType; + } + } + + /** + * Sets the value of the dateType property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setDateType(String value) { + this.dateType = value; + } + + /** + * Gets the value of the year property. + * + * @return + * possible object is + * {@link Year } + * + */ + public Year getYear() { + return year; + } + + /** + * Sets the value of the year property. + * + * @param value + * allowed object is + * {@link Year } + * + */ + public void setYear(Year value) { + this.year = value; + } + + /** + * Gets the value of the month property. + * + * @return + * possible object is + * {@link Month } + * + */ + public Month getMonth() { + return month; + } + + /** + * Sets the value of the month property. + * + * @param value + * allowed object is + * {@link Month } + * + */ + public void setMonth(Month value) { + this.month = value; + } + + /** + * Gets the value of the day property. + * + * @return + * possible object is + * {@link Day } + * + */ + public Day getDay() { + return day; + } + + /** + * Sets the value of the day property. + * + * @param value + * allowed object is + * {@link Day } + * + */ + public void setDay(Day value) { + this.day = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ArticleId.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ArticleId.java new file mode 100644 index 000000000..f8c954da1 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ArticleId.java @@ -0,0 +1,78 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; +import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "ArticleId") +public class ArticleId { + + @XmlAttribute(name = "IdType") + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + protected String idType; + + @XmlValue + protected String value; + + /** + * Gets the value of the idType property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getIdType() { + if (idType == null) { + return "pubmed"; + } else { + return idType; + } + } + + /** + * Sets the value of the idType property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setIdType(String value) { + this.idType = value; + } + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ArticleIdList.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ArticleIdList.java new file mode 100644 index 000000000..caabc0057 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ArticleIdList.java @@ -0,0 +1,50 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "articleId" }) +@XmlRootElement(name = "ArticleIdList") +public class ArticleIdList { + + @XmlElement(name = "ArticleId", required = true) + protected List articleId; + + /** + * Gets the value of the articleId property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the articleId property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getArticleId().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link ArticleId } + * + * + */ + public List getArticleId() { + if (articleId == null) { + articleId = new ArrayList(); + } + return this.articleId; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ArticleTitle.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ArticleTitle.java new file mode 100644 index 000000000..9857acd96 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ArticleTitle.java @@ -0,0 +1,111 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.List; +import javax.xml.bind.annotation.*; +import javax.xml.bind.annotation.adapters.NormalizedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "ArticleTitle") +public class ArticleTitle { + + @XmlAttribute(name = "book") + @XmlJavaTypeAdapter(NormalizedStringAdapter.class) + protected String book; + + @XmlAttribute(name = "part") + @XmlJavaTypeAdapter(NormalizedStringAdapter.class) + protected String part; + + @XmlAttribute(name = "sec") + @XmlJavaTypeAdapter(NormalizedStringAdapter.class) + protected String sec; + + @XmlMixed + @XmlAnyElement + protected List value; + + /** + * Gets the value of the book property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getBook() { + return book; + } + + /** + * Sets the value of the book property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setBook(String value) { + this.book = value; + } + + /** + * Gets the value of the part property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getPart() { + return part; + } + + /** + * Sets the value of the part property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setPart(String value) { + this.part = value; + } + + /** + * Gets the value of the sec property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getSec() { + return sec; + } + + /** + * Sets the value of the sec property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setSec(String value) { + this.sec = value; + } + + public List getValue() { + return value; + } + + public void setValue(List value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Author.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Author.java new file mode 100644 index 000000000..3c3c788ca --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Author.java @@ -0,0 +1,130 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElements; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "lastNameOrForeNameOrInitialsOrSuffixOrCollectiveName", "identifier" }) +@XmlRootElement(name = "Author") +public class Author { + + @XmlAttribute(name = "ValidYN") + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + protected String validYN; + + @XmlElements( + { + @XmlElement(name = "LastName", required = true, type = LastName.class), + @XmlElement(name = "ForeName", required = true, type = ForeName.class), + @XmlElement(name = "Initials", required = true, type = Initials.class), + @XmlElement(name = "Suffix", required = true, type = Suffix.class), + @XmlElement(name = "CollectiveName", required = true, type = CollectiveName.class), + } + ) + protected List lastNameOrForeNameOrInitialsOrSuffixOrCollectiveName; + + @XmlElement(name = "Identifier") + protected List identifier; + + /** + * Gets the value of the validYN property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getValidYN() { + if (validYN == null) { + return "Y"; + } else { + return validYN; + } + } + + /** + * Sets the value of the validYN property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setValidYN(String value) { + this.validYN = value; + } + + /** + * Gets the value of the lastNameOrForeNameOrInitialsOrSuffixOrCollectiveName property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the lastNameOrForeNameOrInitialsOrSuffixOrCollectiveName property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getLastNameOrForeNameOrInitialsOrSuffixOrCollectiveName().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link LastName } + * {@link ForeName } + * {@link Initials } + * {@link Suffix } + * {@link CollectiveName } + * + * + */ + public List getLastNameOrForeNameOrInitialsOrSuffixOrCollectiveName() { + if (lastNameOrForeNameOrInitialsOrSuffixOrCollectiveName == null) { + lastNameOrForeNameOrInitialsOrSuffixOrCollectiveName = new ArrayList(); + } + return this.lastNameOrForeNameOrInitialsOrSuffixOrCollectiveName; + } + + /** + * Gets the value of the identifier property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the identifier property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getIdentifier().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Identifier } + * + * + */ + public List getIdentifier() { + if (identifier == null) { + identifier = new ArrayList(); + } + return this.identifier; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/AuthorList.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/AuthorList.java new file mode 100644 index 000000000..567245774 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/AuthorList.java @@ -0,0 +1,117 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "author" }) +@XmlRootElement(name = "AuthorList") +public class AuthorList { + + @XmlAttribute(name = "CompleteYN") + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + protected String completeYN; + + @XmlAttribute(name = "Type") + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + protected String type; + + @XmlElement(name = "Author", required = true) + protected List author; + + /** + * Gets the value of the completeYN property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getCompleteYN() { + if (completeYN == null) { + return "Y"; + } else { + return completeYN; + } + } + + /** + * Sets the value of the completeYN property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setCompleteYN(String value) { + this.completeYN = value; + } + + /** + * Gets the value of the type property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getType() { + if (type == null) { + return "authors"; + } else { + return type; + } + } + + /** + * Sets the value of the type property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setType(String value) { + this.type = value; + } + + /** + * Gets the value of the author property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the author property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getAuthor().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Author } + * + * + */ + public List getAuthor() { + if (author == null) { + author = new ArrayList(); + } + return this.author; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/B.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/B.java new file mode 100644 index 000000000..d96a261a0 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/B.java @@ -0,0 +1,43 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "b") +public class B { + + @XmlValue + protected String value; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/BeginningDate.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/BeginningDate.java new file mode 100644 index 000000000..4fa7c9e44 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/BeginningDate.java @@ -0,0 +1,86 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElements; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "year", "monthOrDayOrSeason" }) +@XmlRootElement(name = "BeginningDate") +public class BeginningDate { + + @XmlElement(name = "Year", required = true) + protected Year year; + + @XmlElements( + { + @XmlElement(name = "Month", type = Month.class), + @XmlElement(name = "Day", type = Day.class), + @XmlElement(name = "Season", type = Season.class), + } + ) + protected List monthOrDayOrSeason; + + /** + * Gets the value of the year property. + * + * @return + * possible object is + * {@link Year } + * + */ + public Year getYear() { + return year; + } + + /** + * Sets the value of the year property. + * + * @param value + * allowed object is + * {@link Year } + * + */ + public void setYear(Year value) { + this.year = value; + } + + /** + * Gets the value of the monthOrDayOrSeason property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the monthOrDayOrSeason property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getMonthOrDayOrSeason().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Month } + * {@link Day } + * {@link Season } + * + * + */ + public List getMonthOrDayOrSeason() { + if (monthOrDayOrSeason == null) { + monthOrDayOrSeason = new ArrayList(); + } + return this.monthOrDayOrSeason; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Book.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Book.java new file mode 100644 index 000000000..4f909fdd9 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Book.java @@ -0,0 +1,429 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType( + name = "", + propOrder = { + "publisher", + "bookTitle", + "pubDate", + "beginningDate", + "endingDate", + "authorList", + "volume", + "volumeTitle", + "edition", + "collectionTitle", + "isbn", + "eLocationID", + "medium", + "reportNumber", + } +) +@XmlRootElement(name = "Book") +public class Book { + + @XmlElement(name = "Publisher", required = true) + protected Publisher publisher; + + @XmlElement(name = "BookTitle", required = true) + protected BookTitle bookTitle; + + @XmlElement(name = "PubDate", required = true) + protected PubDate pubDate; + + @XmlElement(name = "BeginningDate") + protected BeginningDate beginningDate; + + @XmlElement(name = "EndingDate") + protected EndingDate endingDate; + + @XmlElement(name = "AuthorList") + protected List authorList; + + @XmlElement(name = "Volume") + protected String volume; + + @XmlElement(name = "VolumeTitle") + protected String volumeTitle; + + @XmlElement(name = "Edition") + protected String edition; + + @XmlElement(name = "CollectionTitle") + protected CollectionTitle collectionTitle; + + @XmlElement(name = "Isbn") + protected List isbn; + + @XmlElement(name = "ELocationID") + protected List eLocationID; + + @XmlElement(name = "Medium") + protected String medium; + + @XmlElement(name = "ReportNumber") + protected String reportNumber; + + /** + * Gets the value of the publisher property. + * + * @return + * possible object is + * {@link Publisher } + * + */ + public Publisher getPublisher() { + return publisher; + } + + /** + * Sets the value of the publisher property. + * + * @param value + * allowed object is + * {@link Publisher } + * + */ + public void setPublisher(Publisher value) { + this.publisher = value; + } + + /** + * Gets the value of the bookTitle property. + * + * @return + * possible object is + * {@link BookTitle } + * + */ + public BookTitle getBookTitle() { + return bookTitle; + } + + /** + * Sets the value of the bookTitle property. + * + * @param value + * allowed object is + * {@link BookTitle } + * + */ + public void setBookTitle(BookTitle value) { + this.bookTitle = value; + } + + /** + * Gets the value of the pubDate property. + * + * @return + * possible object is + * {@link PubDate } + * + */ + public PubDate getPubDate() { + return pubDate; + } + + /** + * Sets the value of the pubDate property. + * + * @param value + * allowed object is + * {@link PubDate } + * + */ + public void setPubDate(PubDate value) { + this.pubDate = value; + } + + /** + * Gets the value of the beginningDate property. + * + * @return + * possible object is + * {@link BeginningDate } + * + */ + public BeginningDate getBeginningDate() { + return beginningDate; + } + + /** + * Sets the value of the beginningDate property. + * + * @param value + * allowed object is + * {@link BeginningDate } + * + */ + public void setBeginningDate(BeginningDate value) { + this.beginningDate = value; + } + + /** + * Gets the value of the endingDate property. + * + * @return + * possible object is + * {@link EndingDate } + * + */ + public EndingDate getEndingDate() { + return endingDate; + } + + /** + * Sets the value of the endingDate property. + * + * @param value + * allowed object is + * {@link EndingDate } + * + */ + public void setEndingDate(EndingDate value) { + this.endingDate = value; + } + + /** + * Gets the value of the authorList property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the authorList property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getAuthorList().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link AuthorList } + * + * + */ + public List getAuthorList() { + if (authorList == null) { + authorList = new ArrayList(); + } + return this.authorList; + } + + /** + * Gets the value of the volume property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getVolume() { + return volume; + } + + /** + * Sets the value of the volume property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setVolume(String value) { + this.volume = value; + } + + /** + * Gets the value of the volumeTitle property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getVolumeTitle() { + return volumeTitle; + } + + /** + * Sets the value of the volumeTitle property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setVolumeTitle(String value) { + this.volumeTitle = value; + } + + /** + * Gets the value of the edition property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getEdition() { + return edition; + } + + /** + * Sets the value of the edition property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setEdition(String value) { + this.edition = value; + } + + /** + * Gets the value of the collectionTitle property. + * + * @return + * possible object is + * {@link CollectionTitle } + * + */ + public CollectionTitle getCollectionTitle() { + return collectionTitle; + } + + /** + * Sets the value of the collectionTitle property. + * + * @param value + * allowed object is + * {@link CollectionTitle } + * + */ + public void setCollectionTitle(CollectionTitle value) { + this.collectionTitle = value; + } + + /** + * Gets the value of the isbn property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the isbn property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getIsbn().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Isbn } + * + * + */ + public List getIsbn() { + if (isbn == null) { + isbn = new ArrayList(); + } + return this.isbn; + } + + /** + * Gets the value of the eLocationID property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the eLocationID property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getELocationID().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link ELocationID } + * + * + */ + public List getELocationID() { + if (eLocationID == null) { + eLocationID = new ArrayList(); + } + return this.eLocationID; + } + + /** + * Gets the value of the medium property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getMedium() { + return medium; + } + + /** + * Sets the value of the medium property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setMedium(String value) { + this.medium = value; + } + + /** + * Gets the value of the reportNumber property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getReportNumber() { + return reportNumber; + } + + /** + * Sets the value of the reportNumber property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setReportNumber(String value) { + this.reportNumber = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/BookDocument.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/BookDocument.java new file mode 100644 index 000000000..b88530070 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/BookDocument.java @@ -0,0 +1,584 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType( + name = "", + propOrder = { + "pmid", + "articleIdList", + "book", + "locationLabel", + "articleTitle", + "vernacularTitle", + "pagination", + "language", + "authorList", + "groupList", + "publicationType", + "_abstract", + "sections", + "keywordList", + "contributionDate", + "dateRevised", + "citationString", + "grantList", + "itemList", + } +) +@XmlRootElement(name = "BookDocument") +public class BookDocument { + + @XmlElement(name = "PMID", required = true) + protected PMID pmid; + + @XmlElement(name = "ArticleIdList", required = true) + protected ArticleIdList articleIdList; + + @XmlElement(name = "Book", required = true) + protected Book book; + + @XmlElement(name = "LocationLabel") + protected List locationLabel; + + @XmlElement(name = "ArticleTitle") + protected ArticleTitle articleTitle; + + @XmlElement(name = "VernacularTitle") + protected String vernacularTitle; + + @XmlElement(name = "Pagination") + protected Pagination pagination; + + @XmlElement(name = "Language") + protected List language; + + @XmlElement(name = "AuthorList") + protected List authorList; + + @XmlElement(name = "GroupList") + protected GroupList groupList; + + @XmlElement(name = "PublicationType") + protected List publicationType; + + @XmlElement(name = "Abstract") + protected Abstract _abstract; + + @XmlElement(name = "Sections") + protected Sections sections; + + @XmlElement(name = "KeywordList") + protected List keywordList; + + @XmlElement(name = "ContributionDate") + protected ContributionDate contributionDate; + + @XmlElement(name = "DateRevised") + protected DateRevised dateRevised; + + @XmlElement(name = "CitationString") + protected String citationString; + + @XmlElement(name = "GrantList") + protected GrantList grantList; + + @XmlElement(name = "ItemList") + protected List itemList; + + /** + * Gets the value of the pmid property. + * + * @return + * possible object is + * {@link PMID } + * + */ + public PMID getPMID() { + return pmid; + } + + /** + * Sets the value of the pmid property. + * + * @param value + * allowed object is + * {@link PMID } + * + */ + public void setPMID(PMID value) { + this.pmid = value; + } + + /** + * Gets the value of the articleIdList property. + * + * @return + * possible object is + * {@link ArticleIdList } + * + */ + public ArticleIdList getArticleIdList() { + return articleIdList; + } + + /** + * Sets the value of the articleIdList property. + * + * @param value + * allowed object is + * {@link ArticleIdList } + * + */ + public void setArticleIdList(ArticleIdList value) { + this.articleIdList = value; + } + + /** + * Gets the value of the book property. + * + * @return + * possible object is + * {@link Book } + * + */ + public Book getBook() { + return book; + } + + /** + * Sets the value of the book property. + * + * @param value + * allowed object is + * {@link Book } + * + */ + public void setBook(Book value) { + this.book = value; + } + + /** + * Gets the value of the locationLabel property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the locationLabel property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getLocationLabel().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link LocationLabel } + * + * + */ + public List getLocationLabel() { + if (locationLabel == null) { + locationLabel = new ArrayList(); + } + return this.locationLabel; + } + + /** + * Gets the value of the articleTitle property. + * + * @return + * possible object is + * {@link ArticleTitle } + * + */ + public ArticleTitle getArticleTitle() { + return articleTitle; + } + + /** + * Sets the value of the articleTitle property. + * + * @param value + * allowed object is + * {@link ArticleTitle } + * + */ + public void setArticleTitle(ArticleTitle value) { + this.articleTitle = value; + } + + /** + * Gets the value of the vernacularTitle property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getVernacularTitle() { + return vernacularTitle; + } + + /** + * Sets the value of the vernacularTitle property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setVernacularTitle(String value) { + this.vernacularTitle = value; + } + + /** + * Gets the value of the pagination property. + * + * @return + * possible object is + * {@link Pagination } + * + */ + public Pagination getPagination() { + return pagination; + } + + /** + * Sets the value of the pagination property. + * + * @param value + * allowed object is + * {@link Pagination } + * + */ + public void setPagination(Pagination value) { + this.pagination = value; + } + + /** + * Gets the value of the language property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the language property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getLanguage().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Language } + * + * + */ + public List getLanguage() { + if (language == null) { + language = new ArrayList(); + } + return this.language; + } + + /** + * Gets the value of the authorList property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the authorList property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getAuthorList().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link AuthorList } + * + * + */ + public List getAuthorList() { + if (authorList == null) { + authorList = new ArrayList(); + } + return this.authorList; + } + + /** + * Gets the value of the groupList property. + * + * @return + * possible object is + * {@link GroupList } + * + */ + public GroupList getGroupList() { + return groupList; + } + + /** + * Sets the value of the groupList property. + * + * @param value + * allowed object is + * {@link GroupList } + * + */ + public void setGroupList(GroupList value) { + this.groupList = value; + } + + /** + * Gets the value of the publicationType property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the publicationType property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getPublicationType().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link PublicationType } + * + * + */ + public List getPublicationType() { + if (publicationType == null) { + publicationType = new ArrayList(); + } + return this.publicationType; + } + + /** + * Gets the value of the abstract property. + * + * @return + * possible object is + * {@link Abstract } + * + */ + public Abstract getAbstract() { + return _abstract; + } + + /** + * Sets the value of the abstract property. + * + * @param value + * allowed object is + * {@link Abstract } + * + */ + public void setAbstract(Abstract value) { + this._abstract = value; + } + + /** + * Gets the value of the sections property. + * + * @return + * possible object is + * {@link Sections } + * + */ + public Sections getSections() { + return sections; + } + + /** + * Sets the value of the sections property. + * + * @param value + * allowed object is + * {@link Sections } + * + */ + public void setSections(Sections value) { + this.sections = value; + } + + /** + * Gets the value of the keywordList property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the keywordList property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getKeywordList().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link KeywordList } + * + * + */ + public List getKeywordList() { + if (keywordList == null) { + keywordList = new ArrayList(); + } + return this.keywordList; + } + + /** + * Gets the value of the contributionDate property. + * + * @return + * possible object is + * {@link ContributionDate } + * + */ + public ContributionDate getContributionDate() { + return contributionDate; + } + + /** + * Sets the value of the contributionDate property. + * + * @param value + * allowed object is + * {@link ContributionDate } + * + */ + public void setContributionDate(ContributionDate value) { + this.contributionDate = value; + } + + /** + * Gets the value of the dateRevised property. + * + * @return + * possible object is + * {@link DateRevised } + * + */ + public DateRevised getDateRevised() { + return dateRevised; + } + + /** + * Sets the value of the dateRevised property. + * + * @param value + * allowed object is + * {@link DateRevised } + * + */ + public void setDateRevised(DateRevised value) { + this.dateRevised = value; + } + + /** + * Gets the value of the citationString property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getCitationString() { + return citationString; + } + + /** + * Sets the value of the citationString property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setCitationString(String value) { + this.citationString = value; + } + + /** + * Gets the value of the grantList property. + * + * @return + * possible object is + * {@link GrantList } + * + */ + public GrantList getGrantList() { + return grantList; + } + + /** + * Sets the value of the grantList property. + * + * @param value + * allowed object is + * {@link GrantList } + * + */ + public void setGrantList(GrantList value) { + this.grantList = value; + } + + /** + * Gets the value of the itemList property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the itemList property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getItemList().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link ItemList } + * + * + */ + public List getItemList() { + if (itemList == null) { + itemList = new ArrayList(); + } + return this.itemList; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/BookDocumentSet.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/BookDocumentSet.java new file mode 100644 index 000000000..745ab2318 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/BookDocumentSet.java @@ -0,0 +1,77 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "bookDocument", "deleteDocument" }) +@XmlRootElement(name = "BookDocumentSet") +public class BookDocumentSet { + + @XmlElement(name = "BookDocument") + protected List bookDocument; + + @XmlElement(name = "DeleteDocument") + protected DeleteDocument deleteDocument; + + /** + * Gets the value of the bookDocument property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the bookDocument property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getBookDocument().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link BookDocument } + * + * + */ + public List getBookDocument() { + if (bookDocument == null) { + bookDocument = new ArrayList(); + } + return this.bookDocument; + } + + /** + * Gets the value of the deleteDocument property. + * + * @return + * possible object is + * {@link DeleteDocument } + * + */ + public DeleteDocument getDeleteDocument() { + return deleteDocument; + } + + /** + * Sets the value of the deleteDocument property. + * + * @param value + * allowed object is + * {@link DeleteDocument } + * + */ + public void setDeleteDocument(DeleteDocument value) { + this.deleteDocument = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/BookTitle.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/BookTitle.java new file mode 100644 index 000000000..c15ee2841 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/BookTitle.java @@ -0,0 +1,130 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; +import javax.xml.bind.annotation.adapters.NormalizedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "BookTitle") +public class BookTitle { + + @XmlAttribute(name = "book") + @XmlJavaTypeAdapter(NormalizedStringAdapter.class) + protected String book; + + @XmlAttribute(name = "part") + @XmlJavaTypeAdapter(NormalizedStringAdapter.class) + protected String part; + + @XmlAttribute(name = "sec") + @XmlJavaTypeAdapter(NormalizedStringAdapter.class) + protected String sec; + + @XmlValue + protected String value; + + /** + * Gets the value of the book property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getBook() { + return book; + } + + /** + * Sets the value of the book property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setBook(String value) { + this.book = value; + } + + /** + * Gets the value of the part property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getPart() { + return part; + } + + /** + * Sets the value of the part property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setPart(String value) { + this.part = value; + } + + /** + * Gets the value of the sec property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getSec() { + return sec; + } + + /** + * Sets the value of the sec property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setSec(String value) { + this.sec = value; + } + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Chemical.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Chemical.java new file mode 100644 index 000000000..dfd17d979 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Chemical.java @@ -0,0 +1,70 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "registryNumber", "nameOfSubstance" }) +@XmlRootElement(name = "Chemical") +public class Chemical { + + @XmlElement(name = "RegistryNumber", required = true) + protected String registryNumber; + + @XmlElement(name = "NameOfSubstance", required = true) + protected String nameOfSubstance; + + /** + * Gets the value of the registryNumber property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getRegistryNumber() { + return registryNumber; + } + + /** + * Sets the value of the registryNumber property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setRegistryNumber(String value) { + this.registryNumber = value; + } + + /** + * Gets the value of the nameOfSubstance property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getNameOfSubstance() { + return nameOfSubstance; + } + + /** + * Sets the value of the nameOfSubstance property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setNameOfSubstance(String value) { + this.nameOfSubstance = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ChemicalList.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ChemicalList.java new file mode 100644 index 000000000..22076d553 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ChemicalList.java @@ -0,0 +1,50 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "chemical" }) +@XmlRootElement(name = "ChemicalList") +public class ChemicalList { + + @XmlElement(name = "Chemical", required = true) + protected List chemical; + + /** + * Gets the value of the chemical property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the chemical property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getChemical().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Chemical } + * + * + */ + public List getChemical() { + if (chemical == null) { + chemical = new ArrayList(); + } + return this.chemical; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/CitationSubset.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/CitationSubset.java new file mode 100644 index 000000000..2275c6b28 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/CitationSubset.java @@ -0,0 +1,43 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "CitationSubset") +public class CitationSubset { + + @XmlValue + protected String value; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/CollectionTitle.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/CollectionTitle.java new file mode 100644 index 000000000..cd9b64eb5 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/CollectionTitle.java @@ -0,0 +1,130 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; +import javax.xml.bind.annotation.adapters.NormalizedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "CollectionTitle") +public class CollectionTitle { + + @XmlAttribute(name = "book") + @XmlJavaTypeAdapter(NormalizedStringAdapter.class) + protected String book; + + @XmlAttribute(name = "part") + @XmlJavaTypeAdapter(NormalizedStringAdapter.class) + protected String part; + + @XmlAttribute(name = "sec") + @XmlJavaTypeAdapter(NormalizedStringAdapter.class) + protected String sec; + + @XmlValue + protected String value; + + /** + * Gets the value of the book property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getBook() { + return book; + } + + /** + * Sets the value of the book property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setBook(String value) { + this.book = value; + } + + /** + * Gets the value of the part property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getPart() { + return part; + } + + /** + * Sets the value of the part property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setPart(String value) { + this.part = value; + } + + /** + * Gets the value of the sec property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getSec() { + return sec; + } + + /** + * Sets the value of the sec property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setSec(String value) { + this.sec = value; + } + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/CollectiveName.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/CollectiveName.java new file mode 100644 index 000000000..66620e4ae --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/CollectiveName.java @@ -0,0 +1,43 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "CollectiveName") +public class CollectiveName { + + @XmlValue + protected String value; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/CommentsCorrections.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/CommentsCorrections.java new file mode 100644 index 000000000..aa1eff352 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/CommentsCorrections.java @@ -0,0 +1,128 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "refSource", "pmid", "note" }) +@XmlRootElement(name = "CommentsCorrections") +public class CommentsCorrections { + + @XmlAttribute(name = "RefType", required = true) + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + protected String refType; + + @XmlElement(name = "RefSource", required = true) + protected String refSource; + + @XmlElement(name = "PMID") + protected PMID pmid; + + @XmlElement(name = "Note") + protected String note; + + /** + * Gets the value of the refType property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getRefType() { + return refType; + } + + /** + * Sets the value of the refType property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setRefType(String value) { + this.refType = value; + } + + /** + * Gets the value of the refSource property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getRefSource() { + return refSource; + } + + /** + * Sets the value of the refSource property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setRefSource(String value) { + this.refSource = value; + } + + /** + * Gets the value of the pmid property. + * + * @return + * possible object is + * {@link PMID } + * + */ + public PMID getPMID() { + return pmid; + } + + /** + * Sets the value of the pmid property. + * + * @param value + * allowed object is + * {@link PMID } + * + */ + public void setPMID(PMID value) { + this.pmid = value; + } + + /** + * Gets the value of the note property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getNote() { + return note; + } + + /** + * Sets the value of the note property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setNote(String value) { + this.note = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/CommentsCorrectionsList.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/CommentsCorrectionsList.java new file mode 100644 index 000000000..385e06aaa --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/CommentsCorrectionsList.java @@ -0,0 +1,50 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "commentsCorrections" }) +@XmlRootElement(name = "CommentsCorrectionsList") +public class CommentsCorrectionsList { + + @XmlElement(name = "CommentsCorrections", required = true) + protected List commentsCorrections; + + /** + * Gets the value of the commentsCorrections property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the commentsCorrections property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getCommentsCorrections().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link CommentsCorrections } + * + * + */ + public List getCommentsCorrections() { + if (commentsCorrections == null) { + commentsCorrections = new ArrayList(); + } + return this.commentsCorrections; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ContractNumber.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ContractNumber.java new file mode 100644 index 000000000..62aa71b6d --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ContractNumber.java @@ -0,0 +1,43 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "ContractNumber") +public class ContractNumber { + + @XmlValue + protected String value; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ContributionDate.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ContributionDate.java new file mode 100644 index 000000000..10dad57bf --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ContributionDate.java @@ -0,0 +1,86 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElements; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "year", "monthOrDayOrSeason" }) +@XmlRootElement(name = "ContributionDate") +public class ContributionDate { + + @XmlElement(name = "Year", required = true) + protected Year year; + + @XmlElements( + { + @XmlElement(name = "Month", type = Month.class), + @XmlElement(name = "Day", type = Day.class), + @XmlElement(name = "Season", type = Season.class), + } + ) + protected List monthOrDayOrSeason; + + /** + * Gets the value of the year property. + * + * @return + * possible object is + * {@link Year } + * + */ + public Year getYear() { + return year; + } + + /** + * Sets the value of the year property. + * + * @param value + * allowed object is + * {@link Year } + * + */ + public void setYear(Year value) { + this.year = value; + } + + /** + * Gets the value of the monthOrDayOrSeason property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the monthOrDayOrSeason property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getMonthOrDayOrSeason().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Month } + * {@link Day } + * {@link Season } + * + * + */ + public List getMonthOrDayOrSeason() { + if (monthOrDayOrSeason == null) { + monthOrDayOrSeason = new ArrayList(); + } + return this.monthOrDayOrSeason; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/DataBank.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/DataBank.java new file mode 100644 index 000000000..b85d8c4f4 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/DataBank.java @@ -0,0 +1,70 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "dataBankName", "accessionNumberList" }) +@XmlRootElement(name = "DataBank") +public class DataBank { + + @XmlElement(name = "DataBankName", required = true) + protected String dataBankName; + + @XmlElement(name = "AccessionNumberList") + protected AccessionNumberList accessionNumberList; + + /** + * Gets the value of the dataBankName property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getDataBankName() { + return dataBankName; + } + + /** + * Sets the value of the dataBankName property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setDataBankName(String value) { + this.dataBankName = value; + } + + /** + * Gets the value of the accessionNumberList property. + * + * @return + * possible object is + * {@link AccessionNumberList } + * + */ + public AccessionNumberList getAccessionNumberList() { + return accessionNumberList; + } + + /** + * Sets the value of the accessionNumberList property. + * + * @param value + * allowed object is + * {@link AccessionNumberList } + * + */ + public void setAccessionNumberList(AccessionNumberList value) { + this.accessionNumberList = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/DataBankList.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/DataBankList.java new file mode 100644 index 000000000..3d6ce2deb --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/DataBankList.java @@ -0,0 +1,85 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "dataBank" }) +@XmlRootElement(name = "DataBankList") +public class DataBankList { + + @XmlAttribute(name = "CompleteYN") + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + protected String completeYN; + + @XmlElement(name = "DataBank", required = true) + protected List dataBank; + + /** + * Gets the value of the completeYN property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getCompleteYN() { + if (completeYN == null) { + return "Y"; + } else { + return completeYN; + } + } + + /** + * Sets the value of the completeYN property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setCompleteYN(String value) { + this.completeYN = value; + } + + /** + * Gets the value of the dataBank property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the dataBank property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getDataBank().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link DataBank } + * + * + */ + public List getDataBank() { + if (dataBank == null) { + dataBank = new ArrayList(); + } + return this.dataBank; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/DateCompleted.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/DateCompleted.java new file mode 100644 index 000000000..6210c0de0 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/DateCompleted.java @@ -0,0 +1,97 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "year", "month", "day" }) +@XmlRootElement(name = "DateCompleted") +public class DateCompleted { + + @XmlElement(name = "Year", required = true) + protected Year year; + + @XmlElement(name = "Month", required = true) + protected Month month; + + @XmlElement(name = "Day", required = true) + protected Day day; + + /** + * Gets the value of the year property. + * + * @return + * possible object is + * {@link Year } + * + */ + public Year getYear() { + return year; + } + + /** + * Sets the value of the year property. + * + * @param value + * allowed object is + * {@link Year } + * + */ + public void setYear(Year value) { + this.year = value; + } + + /** + * Gets the value of the month property. + * + * @return + * possible object is + * {@link Month } + * + */ + public Month getMonth() { + return month; + } + + /** + * Sets the value of the month property. + * + * @param value + * allowed object is + * {@link Month } + * + */ + public void setMonth(Month value) { + this.month = value; + } + + /** + * Gets the value of the day property. + * + * @return + * possible object is + * {@link Day } + * + */ + public Day getDay() { + return day; + } + + /** + * Sets the value of the day property. + * + * @param value + * allowed object is + * {@link Day } + * + */ + public void setDay(Day value) { + this.day = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/DateCreated.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/DateCreated.java new file mode 100644 index 000000000..69f6b8242 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/DateCreated.java @@ -0,0 +1,97 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "year", "month", "day" }) +@XmlRootElement(name = "DateCreated") +public class DateCreated { + + @XmlElement(name = "Year", required = true) + protected Year year; + + @XmlElement(name = "Month", required = true) + protected Month month; + + @XmlElement(name = "Day", required = true) + protected Day day; + + /** + * Gets the value of the year property. + * + * @return + * possible object is + * {@link Year } + * + */ + public Year getYear() { + return year; + } + + /** + * Sets the value of the year property. + * + * @param value + * allowed object is + * {@link Year } + * + */ + public void setYear(Year value) { + this.year = value; + } + + /** + * Gets the value of the month property. + * + * @return + * possible object is + * {@link Month } + * + */ + public Month getMonth() { + return month; + } + + /** + * Sets the value of the month property. + * + * @param value + * allowed object is + * {@link Month } + * + */ + public void setMonth(Month value) { + this.month = value; + } + + /** + * Gets the value of the day property. + * + * @return + * possible object is + * {@link Day } + * + */ + public Day getDay() { + return day; + } + + /** + * Sets the value of the day property. + * + * @param value + * allowed object is + * {@link Day } + * + */ + public void setDay(Day value) { + this.day = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/DateRevised.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/DateRevised.java new file mode 100644 index 000000000..8105a10e6 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/DateRevised.java @@ -0,0 +1,97 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "year", "month", "day" }) +@XmlRootElement(name = "DateRevised") +public class DateRevised { + + @XmlElement(name = "Year", required = true) + protected Year year; + + @XmlElement(name = "Month", required = true) + protected Month month; + + @XmlElement(name = "Day", required = true) + protected Day day; + + /** + * Gets the value of the year property. + * + * @return + * possible object is + * {@link Year } + * + */ + public Year getYear() { + return year; + } + + /** + * Sets the value of the year property. + * + * @param value + * allowed object is + * {@link Year } + * + */ + public void setYear(Year value) { + this.year = value; + } + + /** + * Gets the value of the month property. + * + * @return + * possible object is + * {@link Month } + * + */ + public Month getMonth() { + return month; + } + + /** + * Sets the value of the month property. + * + * @param value + * allowed object is + * {@link Month } + * + */ + public void setMonth(Month value) { + this.month = value; + } + + /** + * Gets the value of the day property. + * + * @return + * possible object is + * {@link Day } + * + */ + public Day getDay() { + return day; + } + + /** + * Sets the value of the day property. + * + * @param value + * allowed object is + * {@link Day } + * + */ + public void setDay(Day value) { + this.day = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Day.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Day.java new file mode 100644 index 000000000..3574e8489 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Day.java @@ -0,0 +1,43 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "Day") +public class Day { + + @XmlValue + protected String value; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/DeleteCitation.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/DeleteCitation.java new file mode 100644 index 000000000..1a5132e3b --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/DeleteCitation.java @@ -0,0 +1,50 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "pmid" }) +@XmlRootElement(name = "DeleteCitation") +public class DeleteCitation { + + @XmlElement(name = "PMID", required = true) + protected List pmid; + + /** + * Gets the value of the pmid property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the pmid property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getPMID().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link PMID } + * + * + */ + public List getPMID() { + if (pmid == null) { + pmid = new ArrayList(); + } + return this.pmid; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/DeleteDocument.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/DeleteDocument.java new file mode 100644 index 000000000..5ea1cc2ea --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/DeleteDocument.java @@ -0,0 +1,50 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "pmid" }) +@XmlRootElement(name = "DeleteDocument") +public class DeleteDocument { + + @XmlElement(name = "PMID") + protected List pmid; + + /** + * Gets the value of the pmid property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the pmid property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getPMID().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link PMID } + * + * + */ + public List getPMID() { + if (pmid == null) { + pmid = new ArrayList(); + } + return this.pmid; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/DescriptorName.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/DescriptorName.java new file mode 100644 index 000000000..f233b9c6a --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/DescriptorName.java @@ -0,0 +1,106 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; +import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "DescriptorName") +public class DescriptorName { + + @XmlAttribute(name = "MajorTopicYN") + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + protected String majorTopicYN; + + @XmlAttribute(name = "Type") + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + protected String type; + + @XmlValue + protected String value; + + /** + * Gets the value of the majorTopicYN property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getMajorTopicYN() { + if (majorTopicYN == null) { + return "N"; + } else { + return majorTopicYN; + } + } + + /** + * Sets the value of the majorTopicYN property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setMajorTopicYN(String value) { + this.majorTopicYN = value; + } + + /** + * Gets the value of the type property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getType() { + return type; + } + + /** + * Sets the value of the type property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setType(String value) { + this.type = value; + } + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ELocationID.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ELocationID.java new file mode 100644 index 000000000..776cb0652 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ELocationID.java @@ -0,0 +1,106 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; +import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "ELocationID") +public class ELocationID { + + @XmlAttribute(name = "EIdType", required = true) + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + protected String eIdType; + + @XmlAttribute(name = "ValidYN") + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + protected String validYN; + + @XmlValue + protected String value; + + /** + * Gets the value of the eIdType property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getEIdType() { + return eIdType; + } + + /** + * Sets the value of the eIdType property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setEIdType(String value) { + this.eIdType = value; + } + + /** + * Gets the value of the validYN property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getValidYN() { + if (validYN == null) { + return "Y"; + } else { + return validYN; + } + } + + /** + * Sets the value of the validYN property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setValidYN(String value) { + this.validYN = value; + } + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/EndPage.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/EndPage.java new file mode 100644 index 000000000..230e73047 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/EndPage.java @@ -0,0 +1,43 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "EndPage") +public class EndPage { + + @XmlValue + protected String value; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/EndingDate.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/EndingDate.java new file mode 100644 index 000000000..c0a4b2722 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/EndingDate.java @@ -0,0 +1,86 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElements; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "year", "monthOrDayOrSeason" }) +@XmlRootElement(name = "EndingDate") +public class EndingDate { + + @XmlElement(name = "Year", required = true) + protected Year year; + + @XmlElements( + { + @XmlElement(name = "Month", type = Month.class), + @XmlElement(name = "Day", type = Day.class), + @XmlElement(name = "Season", type = Season.class), + } + ) + protected List monthOrDayOrSeason; + + /** + * Gets the value of the year property. + * + * @return + * possible object is + * {@link Year } + * + */ + public Year getYear() { + return year; + } + + /** + * Sets the value of the year property. + * + * @param value + * allowed object is + * {@link Year } + * + */ + public void setYear(Year value) { + this.year = value; + } + + /** + * Gets the value of the monthOrDayOrSeason property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the monthOrDayOrSeason property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getMonthOrDayOrSeason().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Month } + * {@link Day } + * {@link Season } + * + * + */ + public List getMonthOrDayOrSeason() { + if (monthOrDayOrSeason == null) { + monthOrDayOrSeason = new ArrayList(); + } + return this.monthOrDayOrSeason; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ForeName.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ForeName.java new file mode 100644 index 000000000..8d67de970 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ForeName.java @@ -0,0 +1,43 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "ForeName") +public class ForeName { + + @XmlValue + protected String value; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/GeneSymbol.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/GeneSymbol.java new file mode 100644 index 000000000..abb53119a --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/GeneSymbol.java @@ -0,0 +1,43 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "GeneSymbol") +public class GeneSymbol { + + @XmlValue + protected String value; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/GeneSymbolList.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/GeneSymbolList.java new file mode 100644 index 000000000..dc7257c32 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/GeneSymbolList.java @@ -0,0 +1,50 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "geneSymbol" }) +@XmlRootElement(name = "GeneSymbolList") +public class GeneSymbolList { + + @XmlElement(name = "GeneSymbol", required = true) + protected List geneSymbol; + + /** + * Gets the value of the geneSymbol property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the geneSymbol property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getGeneSymbol().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link GeneSymbol } + * + * + */ + public List getGeneSymbol() { + if (geneSymbol == null) { + geneSymbol = new ArrayList(); + } + return this.geneSymbol; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/GeneralNote.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/GeneralNote.java new file mode 100644 index 000000000..19d6c4e08 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/GeneralNote.java @@ -0,0 +1,78 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; +import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "GeneralNote") +public class GeneralNote { + + @XmlAttribute(name = "Owner") + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + protected String owner; + + @XmlValue + protected String value; + + /** + * Gets the value of the owner property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getOwner() { + if (owner == null) { + return "NLM"; + } else { + return owner; + } + } + + /** + * Sets the value of the owner property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setOwner(String value) { + this.owner = value; + } + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Grant.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Grant.java new file mode 100644 index 000000000..2a43258d7 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Grant.java @@ -0,0 +1,124 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "grantID", "acronym", "agency", "country" }) +@XmlRootElement(name = "Grant") +public class Grant { + + @XmlElement(name = "GrantID") + protected String grantID; + + @XmlElement(name = "Acronym") + protected String acronym; + + @XmlElement(name = "Agency", required = true) + protected String agency; + + @XmlElement(name = "Country", required = true) + protected String country; + + /** + * Gets the value of the grantID property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getGrantID() { + return grantID; + } + + /** + * Sets the value of the grantID property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setGrantID(String value) { + this.grantID = value; + } + + /** + * Gets the value of the acronym property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getAcronym() { + return acronym; + } + + /** + * Sets the value of the acronym property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setAcronym(String value) { + this.acronym = value; + } + + /** + * Gets the value of the agency property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getAgency() { + return agency; + } + + /** + * Sets the value of the agency property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setAgency(String value) { + this.agency = value; + } + + /** + * Gets the value of the country property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getCountry() { + return country; + } + + /** + * Sets the value of the country property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setCountry(String value) { + this.country = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/GrantList.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/GrantList.java new file mode 100644 index 000000000..96db551dc --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/GrantList.java @@ -0,0 +1,85 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "grant" }) +@XmlRootElement(name = "GrantList") +public class GrantList { + + @XmlAttribute(name = "CompleteYN") + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + protected String completeYN; + + @XmlElement(name = "Grant", required = true) + protected List grant; + + /** + * Gets the value of the completeYN property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getCompleteYN() { + if (completeYN == null) { + return "Y"; + } else { + return completeYN; + } + } + + /** + * Sets the value of the completeYN property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setCompleteYN(String value) { + this.completeYN = value; + } + + /** + * Gets the value of the grant property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the grant property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getGrant().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Grant } + * + * + */ + public List getGrant() { + if (grant == null) { + grant = new ArrayList(); + } + return this.grant; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/GroupList.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/GroupList.java new file mode 100644 index 000000000..2fc2a21ba --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/GroupList.java @@ -0,0 +1,14 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "") +@XmlRootElement(name = "GroupList") +public class GroupList {} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/History.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/History.java new file mode 100644 index 000000000..8f1ba5bda --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/History.java @@ -0,0 +1,50 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "pubMedPubDate" }) +@XmlRootElement(name = "History") +public class History { + + @XmlElement(name = "PubMedPubDate", required = true) + protected List pubMedPubDate; + + /** + * Gets the value of the pubMedPubDate property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the pubMedPubDate property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getPubMedPubDate().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link PubMedPubDate } + * + * + */ + public List getPubMedPubDate() { + if (pubMedPubDate == null) { + pubMedPubDate = new ArrayList(); + } + return this.pubMedPubDate; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/I.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/I.java new file mode 100644 index 000000000..c463ec8a7 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/I.java @@ -0,0 +1,43 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "i") +public class I { + + @XmlValue + protected String value; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ISSN.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ISSN.java new file mode 100644 index 000000000..8e87c55f2 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ISSN.java @@ -0,0 +1,74 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; +import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "ISSN") +public class ISSN { + + @XmlAttribute(name = "IssnType", required = true) + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + protected String issnType; + + @XmlValue + protected String value; + + /** + * Gets the value of the issnType property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getIssnType() { + return issnType; + } + + /** + * Sets the value of the issnType property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setIssnType(String value) { + this.issnType = value; + } + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Identifier.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Identifier.java new file mode 100644 index 000000000..849bcfd83 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Identifier.java @@ -0,0 +1,74 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; +import javax.xml.bind.annotation.adapters.NormalizedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "Identifier") +public class Identifier { + + @XmlAttribute(name = "Source", required = true) + @XmlJavaTypeAdapter(NormalizedStringAdapter.class) + protected String source; + + @XmlValue + protected String value; + + /** + * Gets the value of the source property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getSource() { + return source; + } + + /** + * Sets the value of the source property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setSource(String value) { + this.source = value; + } + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Initials.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Initials.java new file mode 100644 index 000000000..d764895fd --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Initials.java @@ -0,0 +1,43 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "Initials") +public class Initials { + + @XmlValue + protected String value; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Investigator.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Investigator.java new file mode 100644 index 000000000..b60daf30b --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Investigator.java @@ -0,0 +1,220 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "lastName", "foreName", "initials", "suffix", "identifier", "affiliation" }) +@XmlRootElement(name = "Investigator") +public class Investigator { + + @XmlAttribute(name = "ValidYN") + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + protected String validYN; + + @XmlElement(name = "LastName", required = true) + protected LastName lastName; + + @XmlElement(name = "ForeName") + protected ForeName foreName; + + @XmlElement(name = "Initials") + protected Initials initials; + + @XmlElement(name = "Suffix") + protected Suffix suffix; + + @XmlElement(name = "Identifier") + protected List identifier; + + @XmlElement(name = "Affiliation") + protected String affiliation; + + /** + * Gets the value of the validYN property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getValidYN() { + if (validYN == null) { + return "Y"; + } else { + return validYN; + } + } + + /** + * Sets the value of the validYN property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setValidYN(String value) { + this.validYN = value; + } + + /** + * Gets the value of the lastName property. + * + * @return + * possible object is + * {@link LastName } + * + */ + public LastName getLastName() { + return lastName; + } + + /** + * Sets the value of the lastName property. + * + * @param value + * allowed object is + * {@link LastName } + * + */ + public void setLastName(LastName value) { + this.lastName = value; + } + + /** + * Gets the value of the foreName property. + * + * @return + * possible object is + * {@link ForeName } + * + */ + public ForeName getForeName() { + return foreName; + } + + /** + * Sets the value of the foreName property. + * + * @param value + * allowed object is + * {@link ForeName } + * + */ + public void setForeName(ForeName value) { + this.foreName = value; + } + + /** + * Gets the value of the initials property. + * + * @return + * possible object is + * {@link Initials } + * + */ + public Initials getInitials() { + return initials; + } + + /** + * Sets the value of the initials property. + * + * @param value + * allowed object is + * {@link Initials } + * + */ + public void setInitials(Initials value) { + this.initials = value; + } + + /** + * Gets the value of the suffix property. + * + * @return + * possible object is + * {@link Suffix } + * + */ + public Suffix getSuffix() { + return suffix; + } + + /** + * Sets the value of the suffix property. + * + * @param value + * allowed object is + * {@link Suffix } + * + */ + public void setSuffix(Suffix value) { + this.suffix = value; + } + + /** + * Gets the value of the identifier property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the identifier property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getIdentifier().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Identifier } + * + * + */ + public List getIdentifier() { + if (identifier == null) { + identifier = new ArrayList(); + } + return this.identifier; + } + + /** + * Gets the value of the affiliation property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getAffiliation() { + return affiliation; + } + + /** + * Sets the value of the affiliation property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setAffiliation(String value) { + this.affiliation = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/InvestigatorList.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/InvestigatorList.java new file mode 100644 index 000000000..69cad234f --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/InvestigatorList.java @@ -0,0 +1,50 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "investigator" }) +@XmlRootElement(name = "InvestigatorList") +public class InvestigatorList { + + @XmlElement(name = "Investigator", required = true) + protected List investigator; + + /** + * Gets the value of the investigator property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the investigator property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getInvestigator().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Investigator } + * + * + */ + public List getInvestigator() { + if (investigator == null) { + investigator = new ArrayList(); + } + return this.investigator; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Isbn.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Isbn.java new file mode 100644 index 000000000..cd71ff601 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Isbn.java @@ -0,0 +1,43 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "Isbn") +public class Isbn { + + @XmlValue + protected String value; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Item.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Item.java new file mode 100644 index 000000000..f857940aa --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Item.java @@ -0,0 +1,43 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "Item") +public class Item { + + @XmlValue + protected String value; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ItemList.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ItemList.java new file mode 100644 index 000000000..cc93fd554 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ItemList.java @@ -0,0 +1,81 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.adapters.NormalizedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "item" }) +@XmlRootElement(name = "ItemList") +public class ItemList { + + @XmlAttribute(name = "ListType", required = true) + @XmlJavaTypeAdapter(NormalizedStringAdapter.class) + protected String listType; + + @XmlElement(name = "Item", required = true) + protected List item; + + /** + * Gets the value of the listType property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getListType() { + return listType; + } + + /** + * Sets the value of the listType property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setListType(String value) { + this.listType = value; + } + + /** + * Gets the value of the item property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the item property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getItem().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Item } + * + * + */ + public List getItem() { + if (item == null) { + item = new ArrayList(); + } + return this.item; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Journal.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Journal.java new file mode 100644 index 000000000..1990f4aab --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Journal.java @@ -0,0 +1,124 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "issn", "journalIssue", "title", "isoAbbreviation" }) +@XmlRootElement(name = "Journal") +public class Journal { + + @XmlElement(name = "ISSN") + protected ISSN issn; + + @XmlElement(name = "JournalIssue", required = true) + protected JournalIssue journalIssue; + + @XmlElement(name = "Title") + protected String title; + + @XmlElement(name = "ISOAbbreviation") + protected String isoAbbreviation; + + /** + * Gets the value of the issn property. + * + * @return + * possible object is + * {@link ISSN } + * + */ + public ISSN getISSN() { + return issn; + } + + /** + * Sets the value of the issn property. + * + * @param value + * allowed object is + * {@link ISSN } + * + */ + public void setISSN(ISSN value) { + this.issn = value; + } + + /** + * Gets the value of the journalIssue property. + * + * @return + * possible object is + * {@link JournalIssue } + * + */ + public JournalIssue getJournalIssue() { + return journalIssue; + } + + /** + * Sets the value of the journalIssue property. + * + * @param value + * allowed object is + * {@link JournalIssue } + * + */ + public void setJournalIssue(JournalIssue value) { + this.journalIssue = value; + } + + /** + * Gets the value of the title property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getTitle() { + return title; + } + + /** + * Sets the value of the title property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setTitle(String value) { + this.title = value; + } + + /** + * Gets the value of the isoAbbreviation property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getISOAbbreviation() { + return isoAbbreviation; + } + + /** + * Sets the value of the isoAbbreviation property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setISOAbbreviation(String value) { + this.isoAbbreviation = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/JournalIssue.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/JournalIssue.java new file mode 100644 index 000000000..cdab61707 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/JournalIssue.java @@ -0,0 +1,128 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "volume", "issue", "pubDate" }) +@XmlRootElement(name = "JournalIssue") +public class JournalIssue { + + @XmlAttribute(name = "CitedMedium", required = true) + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + protected String citedMedium; + + @XmlElement(name = "Volume") + protected String volume; + + @XmlElement(name = "Issue") + protected String issue; + + @XmlElement(name = "PubDate", required = true) + protected PubDate pubDate; + + /** + * Gets the value of the citedMedium property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getCitedMedium() { + return citedMedium; + } + + /** + * Sets the value of the citedMedium property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setCitedMedium(String value) { + this.citedMedium = value; + } + + /** + * Gets the value of the volume property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getVolume() { + return volume; + } + + /** + * Sets the value of the volume property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setVolume(String value) { + this.volume = value; + } + + /** + * Gets the value of the issue property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getIssue() { + return issue; + } + + /** + * Sets the value of the issue property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setIssue(String value) { + this.issue = value; + } + + /** + * Gets the value of the pubDate property. + * + * @return + * possible object is + * {@link PubDate } + * + */ + public PubDate getPubDate() { + return pubDate; + } + + /** + * Sets the value of the pubDate property. + * + * @param value + * allowed object is + * {@link PubDate } + * + */ + public void setPubDate(PubDate value) { + this.pubDate = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Keyword.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Keyword.java new file mode 100644 index 000000000..e85fa116a --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Keyword.java @@ -0,0 +1,78 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; +import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "Keyword") +public class Keyword { + + @XmlAttribute(name = "MajorTopicYN") + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + protected String majorTopicYN; + + @XmlValue + protected String value; + + /** + * Gets the value of the majorTopicYN property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getMajorTopicYN() { + if (majorTopicYN == null) { + return "N"; + } else { + return majorTopicYN; + } + } + + /** + * Sets the value of the majorTopicYN property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setMajorTopicYN(String value) { + this.majorTopicYN = value; + } + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/KeywordList.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/KeywordList.java new file mode 100644 index 000000000..44b1dd962 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/KeywordList.java @@ -0,0 +1,85 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "keyword" }) +@XmlRootElement(name = "KeywordList") +public class KeywordList { + + @XmlAttribute(name = "Owner") + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + protected String owner; + + @XmlElement(name = "Keyword", required = true) + protected List keyword; + + /** + * Gets the value of the owner property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getOwner() { + if (owner == null) { + return "NLM"; + } else { + return owner; + } + } + + /** + * Sets the value of the owner property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setOwner(String value) { + this.owner = value; + } + + /** + * Gets the value of the keyword property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the keyword property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getKeyword().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Keyword } + * + * + */ + public List getKeyword() { + if (keyword == null) { + keyword = new ArrayList(); + } + return this.keyword; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Language.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Language.java new file mode 100644 index 000000000..d5f33ac5e --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Language.java @@ -0,0 +1,43 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "Language") +public class Language { + + @XmlValue + protected String value; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/LastName.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/LastName.java new file mode 100644 index 000000000..cace5f079 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/LastName.java @@ -0,0 +1,43 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "LastName") +public class LastName { + + @XmlValue + protected String value; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/LocationLabel.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/LocationLabel.java new file mode 100644 index 000000000..aed4912da --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/LocationLabel.java @@ -0,0 +1,74 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; +import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "LocationLabel") +public class LocationLabel { + + @XmlAttribute(name = "Type") + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + protected String type; + + @XmlValue + protected String value; + + /** + * Gets the value of the type property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getType() { + return type; + } + + /** + * Sets the value of the type property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setType(String value) { + this.type = value; + } + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/MedlineCitation.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/MedlineCitation.java new file mode 100644 index 000000000..814b0086c --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/MedlineCitation.java @@ -0,0 +1,732 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; +import javax.xml.bind.annotation.adapters.NormalizedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType( + name = "", + propOrder = { + "pmid", + "dateCreated", + "dateCompleted", + "dateRevised", + "article", + "medlineJournalInfo", + "chemicalList", + "supplMeshList", + "citationSubset", + "commentsCorrectionsList", + "geneSymbolList", + "meshHeadingList", + "numberOfReferences", + "personalNameSubjectList", + "otherID", + "otherAbstract", + "keywordList", + "spaceFlightMission", + "investigatorList", + "generalNote", + } +) +@XmlRootElement(name = "MedlineCitation") +public class MedlineCitation { + + @XmlAttribute(name = "Owner") + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + protected String owner; + + @XmlAttribute(name = "Status", required = true) + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + protected String status; + + @XmlAttribute(name = "VersionID") + @XmlJavaTypeAdapter(NormalizedStringAdapter.class) + protected String versionID; + + @XmlAttribute(name = "VersionDate") + @XmlJavaTypeAdapter(NormalizedStringAdapter.class) + protected String versionDate; + + @XmlElement(name = "PMID", required = true) + protected PMID pmid; + + @XmlElement(name = "DateCreated", required = true) + protected DateCreated dateCreated; + + @XmlElement(name = "DateCompleted") + protected DateCompleted dateCompleted; + + @XmlElement(name = "DateRevised") + protected DateRevised dateRevised; + + @XmlElement(name = "Article", required = true) + protected Article article; + + @XmlElement(name = "MedlineJournalInfo", required = true) + protected MedlineJournalInfo medlineJournalInfo; + + @XmlElement(name = "ChemicalList") + protected ChemicalList chemicalList; + + @XmlElement(name = "SupplMeshList") + protected SupplMeshList supplMeshList; + + @XmlElement(name = "CitationSubset") + protected List citationSubset; + + @XmlElement(name = "CommentsCorrectionsList") + protected CommentsCorrectionsList commentsCorrectionsList; + + @XmlElement(name = "GeneSymbolList") + protected GeneSymbolList geneSymbolList; + + @XmlElement(name = "MeshHeadingList") + protected MeshHeadingList meshHeadingList; + + @XmlElement(name = "NumberOfReferences") + protected String numberOfReferences; + + @XmlElement(name = "PersonalNameSubjectList") + protected PersonalNameSubjectList personalNameSubjectList; + + @XmlElement(name = "OtherID") + protected List otherID; + + @XmlElement(name = "OtherAbstract") + protected List otherAbstract; + + @XmlElement(name = "KeywordList") + protected List keywordList; + + @XmlElement(name = "SpaceFlightMission") + protected List spaceFlightMission; + + @XmlElement(name = "InvestigatorList") + protected InvestigatorList investigatorList; + + @XmlElement(name = "GeneralNote") + protected List generalNote; + + /** + * Gets the value of the owner property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getOwner() { + if (owner == null) { + return "NLM"; + } else { + return owner; + } + } + + /** + * Sets the value of the owner property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setOwner(String value) { + this.owner = value; + } + + /** + * Gets the value of the status property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getStatus() { + return status; + } + + /** + * Sets the value of the status property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setStatus(String value) { + this.status = value; + } + + /** + * Gets the value of the versionID property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getVersionID() { + return versionID; + } + + /** + * Sets the value of the versionID property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setVersionID(String value) { + this.versionID = value; + } + + /** + * Gets the value of the versionDate property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getVersionDate() { + return versionDate; + } + + /** + * Sets the value of the versionDate property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setVersionDate(String value) { + this.versionDate = value; + } + + /** + * Gets the value of the pmid property. + * + * @return + * possible object is + * {@link PMID } + * + */ + public PMID getPMID() { + return pmid; + } + + /** + * Sets the value of the pmid property. + * + * @param value + * allowed object is + * {@link PMID } + * + */ + public void setPMID(PMID value) { + this.pmid = value; + } + + /** + * Gets the value of the dateCreated property. + * + * @return + * possible object is + * {@link DateCreated } + * + */ + public DateCreated getDateCreated() { + return dateCreated; + } + + /** + * Sets the value of the dateCreated property. + * + * @param value + * allowed object is + * {@link DateCreated } + * + */ + public void setDateCreated(DateCreated value) { + this.dateCreated = value; + } + + /** + * Gets the value of the dateCompleted property. + * + * @return + * possible object is + * {@link DateCompleted } + * + */ + public DateCompleted getDateCompleted() { + return dateCompleted; + } + + /** + * Sets the value of the dateCompleted property. + * + * @param value + * allowed object is + * {@link DateCompleted } + * + */ + public void setDateCompleted(DateCompleted value) { + this.dateCompleted = value; + } + + /** + * Gets the value of the dateRevised property. + * + * @return + * possible object is + * {@link DateRevised } + * + */ + public DateRevised getDateRevised() { + return dateRevised; + } + + /** + * Sets the value of the dateRevised property. + * + * @param value + * allowed object is + * {@link DateRevised } + * + */ + public void setDateRevised(DateRevised value) { + this.dateRevised = value; + } + + /** + * Gets the value of the article property. + * + * @return + * possible object is + * {@link Article } + * + */ + public Article getArticle() { + return article; + } + + /** + * Sets the value of the article property. + * + * @param value + * allowed object is + * {@link Article } + * + */ + public void setArticle(Article value) { + this.article = value; + } + + /** + * Gets the value of the medlineJournalInfo property. + * + * @return + * possible object is + * {@link MedlineJournalInfo } + * + */ + public MedlineJournalInfo getMedlineJournalInfo() { + return medlineJournalInfo; + } + + /** + * Sets the value of the medlineJournalInfo property. + * + * @param value + * allowed object is + * {@link MedlineJournalInfo } + * + */ + public void setMedlineJournalInfo(MedlineJournalInfo value) { + this.medlineJournalInfo = value; + } + + /** + * Gets the value of the chemicalList property. + * + * @return + * possible object is + * {@link ChemicalList } + * + */ + public ChemicalList getChemicalList() { + return chemicalList; + } + + /** + * Sets the value of the chemicalList property. + * + * @param value + * allowed object is + * {@link ChemicalList } + * + */ + public void setChemicalList(ChemicalList value) { + this.chemicalList = value; + } + + /** + * Gets the value of the supplMeshList property. + * + * @return + * possible object is + * {@link SupplMeshList } + * + */ + public SupplMeshList getSupplMeshList() { + return supplMeshList; + } + + /** + * Sets the value of the supplMeshList property. + * + * @param value + * allowed object is + * {@link SupplMeshList } + * + */ + public void setSupplMeshList(SupplMeshList value) { + this.supplMeshList = value; + } + + /** + * Gets the value of the citationSubset property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the citationSubset property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getCitationSubset().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link CitationSubset } + * + * + */ + public List getCitationSubset() { + if (citationSubset == null) { + citationSubset = new ArrayList(); + } + return this.citationSubset; + } + + /** + * Gets the value of the commentsCorrectionsList property. + * + * @return + * possible object is + * {@link CommentsCorrectionsList } + * + */ + public CommentsCorrectionsList getCommentsCorrectionsList() { + return commentsCorrectionsList; + } + + /** + * Sets the value of the commentsCorrectionsList property. + * + * @param value + * allowed object is + * {@link CommentsCorrectionsList } + * + */ + public void setCommentsCorrectionsList(CommentsCorrectionsList value) { + this.commentsCorrectionsList = value; + } + + /** + * Gets the value of the geneSymbolList property. + * + * @return + * possible object is + * {@link GeneSymbolList } + * + */ + public GeneSymbolList getGeneSymbolList() { + return geneSymbolList; + } + + /** + * Sets the value of the geneSymbolList property. + * + * @param value + * allowed object is + * {@link GeneSymbolList } + * + */ + public void setGeneSymbolList(GeneSymbolList value) { + this.geneSymbolList = value; + } + + /** + * Gets the value of the meshHeadingList property. + * + * @return + * possible object is + * {@link MeshHeadingList } + * + */ + public MeshHeadingList getMeshHeadingList() { + return meshHeadingList; + } + + /** + * Sets the value of the meshHeadingList property. + * + * @param value + * allowed object is + * {@link MeshHeadingList } + * + */ + public void setMeshHeadingList(MeshHeadingList value) { + this.meshHeadingList = value; + } + + /** + * Gets the value of the numberOfReferences property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getNumberOfReferences() { + return numberOfReferences; + } + + /** + * Sets the value of the numberOfReferences property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setNumberOfReferences(String value) { + this.numberOfReferences = value; + } + + /** + * Gets the value of the personalNameSubjectList property. + * + * @return + * possible object is + * {@link PersonalNameSubjectList } + * + */ + public PersonalNameSubjectList getPersonalNameSubjectList() { + return personalNameSubjectList; + } + + /** + * Sets the value of the personalNameSubjectList property. + * + * @param value + * allowed object is + * {@link PersonalNameSubjectList } + * + */ + public void setPersonalNameSubjectList(PersonalNameSubjectList value) { + this.personalNameSubjectList = value; + } + + /** + * Gets the value of the otherID property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the otherID property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getOtherID().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link OtherID } + * + * + */ + public List getOtherID() { + if (otherID == null) { + otherID = new ArrayList(); + } + return this.otherID; + } + + /** + * Gets the value of the otherAbstract property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the otherAbstract property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getOtherAbstract().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link OtherAbstract } + * + * + */ + public List getOtherAbstract() { + if (otherAbstract == null) { + otherAbstract = new ArrayList(); + } + return this.otherAbstract; + } + + /** + * Gets the value of the keywordList property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the keywordList property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getKeywordList().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link KeywordList } + * + * + */ + public List getKeywordList() { + if (keywordList == null) { + keywordList = new ArrayList(); + } + return this.keywordList; + } + + /** + * Gets the value of the spaceFlightMission property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the spaceFlightMission property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getSpaceFlightMission().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link SpaceFlightMission } + * + * + */ + public List getSpaceFlightMission() { + if (spaceFlightMission == null) { + spaceFlightMission = new ArrayList(); + } + return this.spaceFlightMission; + } + + /** + * Gets the value of the investigatorList property. + * + * @return + * possible object is + * {@link InvestigatorList } + * + */ + public InvestigatorList getInvestigatorList() { + return investigatorList; + } + + /** + * Sets the value of the investigatorList property. + * + * @param value + * allowed object is + * {@link InvestigatorList } + * + */ + public void setInvestigatorList(InvestigatorList value) { + this.investigatorList = value; + } + + /** + * Gets the value of the generalNote property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the generalNote property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getGeneralNote().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link GeneralNote } + * + * + */ + public List getGeneralNote() { + if (generalNote == null) { + generalNote = new ArrayList(); + } + return this.generalNote; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/MedlineCitationSet.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/MedlineCitationSet.java new file mode 100644 index 000000000..b79753bb6 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/MedlineCitationSet.java @@ -0,0 +1,77 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "medlineCitation", "deleteCitation" }) +@XmlRootElement(name = "MedlineCitationSet") +public class MedlineCitationSet { + + @XmlElement(name = "MedlineCitation") + protected List medlineCitation; + + @XmlElement(name = "DeleteCitation") + protected DeleteCitation deleteCitation; + + /** + * Gets the value of the medlineCitation property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the medlineCitation property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getMedlineCitation().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link MedlineCitation } + * + * + */ + public List getMedlineCitation() { + if (medlineCitation == null) { + medlineCitation = new ArrayList(); + } + return this.medlineCitation; + } + + /** + * Gets the value of the deleteCitation property. + * + * @return + * possible object is + * {@link DeleteCitation } + * + */ + public DeleteCitation getDeleteCitation() { + return deleteCitation; + } + + /** + * Sets the value of the deleteCitation property. + * + * @param value + * allowed object is + * {@link DeleteCitation } + * + */ + public void setDeleteCitation(DeleteCitation value) { + this.deleteCitation = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/MedlineDate.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/MedlineDate.java new file mode 100644 index 000000000..a5fdf6e1a --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/MedlineDate.java @@ -0,0 +1,43 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "MedlineDate") +public class MedlineDate { + + @XmlValue + protected String value; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/MedlineJournalInfo.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/MedlineJournalInfo.java new file mode 100644 index 000000000..456aeeffc --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/MedlineJournalInfo.java @@ -0,0 +1,124 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "country", "medlineTA", "nlmUniqueID", "issnLinking" }) +@XmlRootElement(name = "MedlineJournalInfo") +public class MedlineJournalInfo { + + @XmlElement(name = "Country") + protected String country; + + @XmlElement(name = "MedlineTA", required = true) + protected String medlineTA; + + @XmlElement(name = "NlmUniqueID") + protected String nlmUniqueID; + + @XmlElement(name = "ISSNLinking") + protected String issnLinking; + + /** + * Gets the value of the country property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getCountry() { + return country; + } + + /** + * Sets the value of the country property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setCountry(String value) { + this.country = value; + } + + /** + * Gets the value of the medlineTA property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getMedlineTA() { + return medlineTA; + } + + /** + * Sets the value of the medlineTA property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setMedlineTA(String value) { + this.medlineTA = value; + } + + /** + * Gets the value of the nlmUniqueID property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getNlmUniqueID() { + return nlmUniqueID; + } + + /** + * Sets the value of the nlmUniqueID property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setNlmUniqueID(String value) { + this.nlmUniqueID = value; + } + + /** + * Gets the value of the issnLinking property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getISSNLinking() { + return issnLinking; + } + + /** + * Sets the value of the issnLinking property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setISSNLinking(String value) { + this.issnLinking = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/MedlinePgn.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/MedlinePgn.java new file mode 100644 index 000000000..0a9d59430 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/MedlinePgn.java @@ -0,0 +1,43 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "MedlinePgn") +public class MedlinePgn { + + @XmlValue + protected String value; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/MeshHeading.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/MeshHeading.java new file mode 100644 index 000000000..767b33146 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/MeshHeading.java @@ -0,0 +1,77 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "descriptorName", "qualifierName" }) +@XmlRootElement(name = "MeshHeading") +public class MeshHeading { + + @XmlElement(name = "DescriptorName", required = true) + protected DescriptorName descriptorName; + + @XmlElement(name = "QualifierName") + protected List qualifierName; + + /** + * Gets the value of the descriptorName property. + * + * @return + * possible object is + * {@link DescriptorName } + * + */ + public DescriptorName getDescriptorName() { + return descriptorName; + } + + /** + * Sets the value of the descriptorName property. + * + * @param value + * allowed object is + * {@link DescriptorName } + * + */ + public void setDescriptorName(DescriptorName value) { + this.descriptorName = value; + } + + /** + * Gets the value of the qualifierName property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the qualifierName property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getQualifierName().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link QualifierName } + * + * + */ + public List getQualifierName() { + if (qualifierName == null) { + qualifierName = new ArrayList(); + } + return this.qualifierName; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/MeshHeadingList.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/MeshHeadingList.java new file mode 100644 index 000000000..68f093ef0 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/MeshHeadingList.java @@ -0,0 +1,50 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "meshHeading" }) +@XmlRootElement(name = "MeshHeadingList") +public class MeshHeadingList { + + @XmlElement(name = "MeshHeading", required = true) + protected List meshHeading; + + /** + * Gets the value of the meshHeading property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the meshHeading property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getMeshHeading().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link MeshHeading } + * + * + */ + public List getMeshHeading() { + if (meshHeading == null) { + meshHeading = new ArrayList(); + } + return this.meshHeading; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Month.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Month.java new file mode 100644 index 000000000..03a5aa391 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Month.java @@ -0,0 +1,43 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "Month") +public class Month { + + @XmlValue + protected String value; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Object.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Object.java new file mode 100644 index 000000000..ed5174967 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Object.java @@ -0,0 +1,81 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.adapters.NormalizedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "param" }) +@XmlRootElement(name = "Object") +public class Object { + + @XmlAttribute(name = "Type", required = true) + @XmlJavaTypeAdapter(NormalizedStringAdapter.class) + protected String type; + + @XmlElement(name = "Param") + protected List param; + + /** + * Gets the value of the type property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getType() { + return type; + } + + /** + * Sets the value of the type property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setType(String value) { + this.type = value; + } + + /** + * Gets the value of the param property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the param property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getParam().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Param } + * + * + */ + public List getParam() { + if (param == null) { + param = new ArrayList(); + } + return this.param; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ObjectFactory.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ObjectFactory.java new file mode 100644 index 000000000..87cb50870 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ObjectFactory.java @@ -0,0 +1,871 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlRegistry; + +/** + * This object contains factory methods for each + * Java content interface and Java element interface + * generated in the gov.nih.nlm.ncbi.eutils.generated.efetch package. + *

An ObjectFactory allows you to programatically + * construct new instances of the Java representation + * for XML content. The Java representation of XML + * content can consist of schema derived interfaces + * and classes representing the binding of schema + * type definitions, element declarations and model + * groups. Factory methods for each of these are + * provided in this class. + * + */ +@XmlRegistry +public class ObjectFactory { + + /** + * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: gov.nih.nlm.ncbi.eutils.generated.efetch + * + */ + public ObjectFactory() {} + + /** + * Create an instance of {@link AbstractText } + * + */ + public AbstractText createAbstractText() { + return new AbstractText(); + } + + /** + * Create an instance of {@link PubMedPubDate } + * + */ + public PubMedPubDate createPubMedPubDate() { + return new PubMedPubDate(); + } + + /** + * Create an instance of {@link Year } + * + */ + public Year createYear() { + return new Year(); + } + + public Value createValue() { + return new Value(); + } + + /** + * Create an instance of {@link Month } + * + */ + public Month createMonth() { + return new Month(); + } + + /** + * Create an instance of {@link Day } + * + */ + public Day createDay() { + return new Day(); + } + + /** + * Create an instance of {@link ArticleTitle } + * + */ + public ArticleTitle createArticleTitle() { + return new ArticleTitle(); + } + + /** + * Create an instance of {@link LastName } + * + */ + public LastName createLastName() { + return new LastName(); + } + + /** + * Create an instance of {@link Chemical } + * + */ + public Chemical createChemical() { + return new Chemical(); + } + + /** + * Create an instance of {@link BookDocument } + * + */ + public BookDocument createBookDocument() { + return new BookDocument(); + } + + /** + * Create an instance of {@link PMID } + * + */ + public PMID createPMID() { + return new PMID(); + } + + /** + * Create an instance of {@link ArticleIdList } + * + */ + public ArticleIdList createArticleIdList() { + return new ArticleIdList(); + } + + /** + * Create an instance of {@link Book } + * + */ + public Book createBook() { + return new Book(); + } + + /** + * Create an instance of {@link LocationLabel } + * + */ + public LocationLabel createLocationLabel() { + return new LocationLabel(); + } + + /** + * Create an instance of {@link Pagination } + * + */ + public Pagination createPagination() { + return new Pagination(); + } + + /** + * Create an instance of {@link Language } + * + */ + public Language createLanguage() { + return new Language(); + } + + /** + * Create an instance of {@link AuthorList } + * + */ + public AuthorList createAuthorList() { + return new AuthorList(); + } + + /** + * Create an instance of {@link GroupList } + * + */ + public GroupList createGroupList() { + return new GroupList(); + } + + /** + * Create an instance of {@link PublicationType } + * + */ + public PublicationType createPublicationType() { + return new PublicationType(); + } + + /** + * Create an instance of {@link Abstract } + * + */ + public Abstract createAbstract() { + return new Abstract(); + } + + /** + * Create an instance of {@link Sections } + * + */ + public Sections createSections() { + return new Sections(); + } + + /** + * Create an instance of {@link KeywordList } + * + */ + public KeywordList createKeywordList() { + return new KeywordList(); + } + + /** + * Create an instance of {@link ContributionDate } + * + */ + public ContributionDate createContributionDate() { + return new ContributionDate(); + } + + /** + * Create an instance of {@link DateRevised } + * + */ + public DateRevised createDateRevised() { + return new DateRevised(); + } + + /** + * Create an instance of {@link GrantList } + * + */ + public GrantList createGrantList() { + return new GrantList(); + } + + /** + * Create an instance of {@link ItemList } + * + */ + public ItemList createItemList() { + return new ItemList(); + } + + /** + * Create an instance of {@link PersonalNameSubjectList } + * + */ + public PersonalNameSubjectList createPersonalNameSubjectList() { + return new PersonalNameSubjectList(); + } + + /** + * Create an instance of {@link PersonalNameSubject } + * + */ + public PersonalNameSubject createPersonalNameSubject() { + return new PersonalNameSubject(); + } + + /** + * Create an instance of {@link Item } + * + */ + public Item createItem() { + return new Item(); + } + + /** + * Create an instance of {@link InvestigatorList } + * + */ + public InvestigatorList createInvestigatorList() { + return new InvestigatorList(); + } + + /** + * Create an instance of {@link Investigator } + * + */ + public Investigator createInvestigator() { + return new Investigator(); + } + + /** + * Create an instance of {@link MedlineCitation } + * + */ + public MedlineCitation createMedlineCitation() { + return new MedlineCitation(); + } + + /** + * Create an instance of {@link DateCreated } + * + */ + public DateCreated createDateCreated() { + return new DateCreated(); + } + + /** + * Create an instance of {@link DateCompleted } + * + */ + public DateCompleted createDateCompleted() { + return new DateCompleted(); + } + + /** + * Create an instance of {@link Article } + * + */ + public Article createArticle() { + return new Article(); + } + + /** + * Create an instance of {@link MedlineJournalInfo } + * + */ + public MedlineJournalInfo createMedlineJournalInfo() { + return new MedlineJournalInfo(); + } + + /** + * Create an instance of {@link ChemicalList } + * + */ + public ChemicalList createChemicalList() { + return new ChemicalList(); + } + + /** + * Create an instance of {@link SupplMeshList } + * + */ + public SupplMeshList createSupplMeshList() { + return new SupplMeshList(); + } + + /** + * Create an instance of {@link CitationSubset } + * + */ + public CitationSubset createCitationSubset() { + return new CitationSubset(); + } + + /** + * Create an instance of {@link CommentsCorrectionsList } + * + */ + public CommentsCorrectionsList createCommentsCorrectionsList() { + return new CommentsCorrectionsList(); + } + + /** + * Create an instance of {@link GeneSymbolList } + * + */ + public GeneSymbolList createGeneSymbolList() { + return new GeneSymbolList(); + } + + /** + * Create an instance of {@link MeshHeadingList } + * + */ + public MeshHeadingList createMeshHeadingList() { + return new MeshHeadingList(); + } + + /** + * Create an instance of {@link OtherID } + * + */ + public OtherID createOtherID() { + return new OtherID(); + } + + /** + * Create an instance of {@link OtherAbstract } + * + */ + public OtherAbstract createOtherAbstract() { + return new OtherAbstract(); + } + + /** + * Create an instance of {@link SpaceFlightMission } + * + */ + public SpaceFlightMission createSpaceFlightMission() { + return new SpaceFlightMission(); + } + + /** + * Create an instance of {@link GeneralNote } + * + */ + public GeneralNote createGeneralNote() { + return new GeneralNote(); + } + + /** + * Create an instance of {@link DataBank } + * + */ + public DataBank createDataBank() { + return new DataBank(); + } + + /** + * Create an instance of {@link AccessionNumberList } + * + */ + public AccessionNumberList createAccessionNumberList() { + return new AccessionNumberList(); + } + + /** + * Create an instance of {@link ForeName } + * + */ + public ForeName createForeName() { + return new ForeName(); + } + + /** + * Create an instance of {@link Initials } + * + */ + public Initials createInitials() { + return new Initials(); + } + + /** + * Create an instance of {@link Suffix } + * + */ + public Suffix createSuffix() { + return new Suffix(); + } + + /** + * Create an instance of {@link Identifier } + * + */ + public Identifier createIdentifier() { + return new Identifier(); + } + + /** + * Create an instance of {@link DataBankList } + * + */ + public DataBankList createDataBankList() { + return new DataBankList(); + } + + /** + * Create an instance of {@link Season } + * + */ + public Season createSeason() { + return new Season(); + } + + /** + * Create an instance of {@link PubDate } + * + */ + public PubDate createPubDate() { + return new PubDate(); + } + + /** + * Create an instance of {@link MedlineDate } + * + */ + public MedlineDate createMedlineDate() { + return new MedlineDate(); + } + + /** + * Create an instance of {@link StartPage } + * + */ + public StartPage createStartPage() { + return new StartPage(); + } + + /** + * Create an instance of {@link EndPage } + * + */ + public EndPage createEndPage() { + return new EndPage(); + } + + /** + * Create an instance of {@link MedlinePgn } + * + */ + public MedlinePgn createMedlinePgn() { + return new MedlinePgn(); + } + + /** + * Create an instance of {@link Publisher } + * + */ + public Publisher createPublisher() { + return new Publisher(); + } + + /** + * Create an instance of {@link ArticleId } + * + */ + public ArticleId createArticleId() { + return new ArticleId(); + } + + /** + * Create an instance of {@link AccessionNumber } + * + */ + public AccessionNumber createAccessionNumber() { + return new AccessionNumber(); + } + + /** + * Create an instance of {@link MedlineCitationSet } + * + */ + public MedlineCitationSet createMedlineCitationSet() { + return new MedlineCitationSet(); + } + + /** + * Create an instance of {@link DeleteCitation } + * + */ + public DeleteCitation createDeleteCitation() { + return new DeleteCitation(); + } + + /** + * Create an instance of {@link CommentsCorrections } + * + */ + public CommentsCorrections createCommentsCorrections() { + return new CommentsCorrections(); + } + + /** + * Create an instance of {@link BookTitle } + * + */ + public BookTitle createBookTitle() { + return new BookTitle(); + } + + /** + * Create an instance of {@link BeginningDate } + * + */ + public BeginningDate createBeginningDate() { + return new BeginningDate(); + } + + /** + * Create an instance of {@link EndingDate } + * + */ + public EndingDate createEndingDate() { + return new EndingDate(); + } + + /** + * Create an instance of {@link CollectionTitle } + * + */ + public CollectionTitle createCollectionTitle() { + return new CollectionTitle(); + } + + /** + * Create an instance of {@link Isbn } + * + */ + public Isbn createIsbn() { + return new Isbn(); + } + + /** + * Create an instance of {@link ELocationID } + * + */ + public ELocationID createELocationID() { + return new ELocationID(); + } + + /** + * Create an instance of {@link Author } + * + */ + public Author createAuthor() { + return new Author(); + } + + /** + * Create an instance of {@link CollectiveName } + * + */ + public CollectiveName createCollectiveName() { + return new CollectiveName(); + } + + /** + * Create an instance of {@link PubmedArticle } + * + */ + public PubmedArticle createPubmedArticle() { + return new PubmedArticle(); + } + + /** + * Create an instance of {@link PubmedData } + * + */ + public PubmedData createPubmedData() { + return new PubmedData(); + } + + /** + * Create an instance of {@link Grant } + * + */ + public Grant createGrant() { + return new Grant(); + } + + /** + * Create an instance of {@link URL } + * + */ + public URL createURL() { + return new URL(); + } + + /** + * Create an instance of {@link History } + * + */ + public History createHistory() { + return new History(); + } + + /** + * Create an instance of {@link ObjectList } + * + */ + public ObjectList createObjectList() { + return new ObjectList(); + } + + /** + * Create an instance of {@link Object } + * + */ + public Object createObject() { + return new Object(); + } + + /** + * Create an instance of {@link Param } + * + */ + public Param createParam() { + return new Param(); + } + + /** + * Create an instance of {@link MeshHeading } + * + */ + public MeshHeading createMeshHeading() { + return new MeshHeading(); + } + + /** + * Create an instance of {@link DescriptorName } + * + */ + public DescriptorName createDescriptorName() { + return new DescriptorName(); + } + + /** + * Create an instance of {@link QualifierName } + * + */ + public QualifierName createQualifierName() { + return new QualifierName(); + } + + /** + * Create an instance of {@link B } + * + */ + public B createB() { + return new B(); + } + + /** + * Create an instance of {@link Section } + * + */ + public Section createSection() { + return new Section(); + } + + /** + * Create an instance of {@link I } + * + */ + public I createI() { + return new I(); + } + + /** + * Create an instance of {@link Journal } + * + */ + public Journal createJournal() { + return new Journal(); + } + + /** + * Create an instance of {@link PublicationTypeList } + * + */ + public PublicationTypeList createPublicationTypeList() { + return new PublicationTypeList(); + } + + /** + * Create an instance of {@link ArticleDate } + * + */ + public ArticleDate createArticleDate() { + return new ArticleDate(); + } + + /** + * Create an instance of {@link U } + * + */ + public U createU() { + return new U(); + } + + /** + * Create an instance of {@link SupplMeshName } + * + */ + public SupplMeshName createSupplMeshName() { + return new SupplMeshName(); + } + + /** + * Create an instance of {@link DeleteDocument } + * + */ + public DeleteDocument createDeleteDocument() { + return new DeleteDocument(); + } + + /** + * Create an instance of {@link Keyword } + * + */ + public Keyword createKeyword() { + return new Keyword(); + } + + /** + * Create an instance of {@link PubmedBookData } + * + */ + public PubmedBookData createPubmedBookData() { + return new PubmedBookData(); + } + + /** + * Create an instance of {@link ISSN } + * + */ + public ISSN createISSN() { + return new ISSN(); + } + + /** + * Create an instance of {@link JournalIssue } + * + */ + public JournalIssue createJournalIssue() { + return new JournalIssue(); + } + + /** + * Create an instance of {@link SectionTitle } + * + */ + public SectionTitle createSectionTitle() { + return new SectionTitle(); + } + + /** + * Create an instance of {@link Sub } + * + */ + public Sub createSub() { + return new Sub(); + } + + /** + * Create an instance of {@link GeneSymbol } + * + */ + public GeneSymbol createGeneSymbol() { + return new GeneSymbol(); + } + + /** + * Create an instance of {@link Sup } + * + */ + public Sup createSup() { + return new Sup(); + } + + /** + * Create an instance of {@link ContractNumber } + * + */ + public ContractNumber createContractNumber() { + return new ContractNumber(); + } + + /** + * Create an instance of {@link PubmedBookArticle } + * + */ + public PubmedBookArticle createPubmedBookArticle() { + return new PubmedBookArticle(); + } + + /** + * Create an instance of {@link PubmedBookArticleSet } + * + */ + public PubmedBookArticleSet createPubmedBookArticleSet() { + return new PubmedBookArticleSet(); + } + + /** + * Create an instance of {@link PubmedArticleSet } + * + */ + public PubmedArticleSet createPubmedArticleSet() { + return new PubmedArticleSet(); + } + + /** + * Create an instance of {@link BookDocumentSet } + * + */ + public BookDocumentSet createBookDocumentSet() { + return new BookDocumentSet(); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ObjectList.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ObjectList.java new file mode 100644 index 000000000..a800aa1c8 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/ObjectList.java @@ -0,0 +1,50 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "object" }) +@XmlRootElement(name = "ObjectList") +public class ObjectList { + + @XmlElement(name = "Object", required = true) + protected List object; + + /** + * Gets the value of the object property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the object property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getObject().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Object } + * + * + */ + public List getObject() { + if (object == null) { + object = new ArrayList(); + } + return this.object; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/OtherAbstract.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/OtherAbstract.java new file mode 100644 index 000000000..c861b917c --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/OtherAbstract.java @@ -0,0 +1,141 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; +import javax.xml.bind.annotation.adapters.NormalizedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "abstractText", "copyrightInformation" }) +@XmlRootElement(name = "OtherAbstract") +public class OtherAbstract { + + @XmlAttribute(name = "Type", required = true) + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + protected String type; + + @XmlAttribute(name = "Language") + @XmlJavaTypeAdapter(NormalizedStringAdapter.class) + protected String language; + + @XmlElement(name = "AbstractText", required = true) + protected List abstractText; + + @XmlElement(name = "CopyrightInformation") + protected String copyrightInformation; + + /** + * Gets the value of the type property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getType() { + return type; + } + + /** + * Sets the value of the type property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setType(String value) { + this.type = value; + } + + /** + * Gets the value of the language property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getLanguage() { + if (language == null) { + return "eng"; + } else { + return language; + } + } + + /** + * Sets the value of the language property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setLanguage(String value) { + this.language = value; + } + + /** + * Gets the value of the abstractText property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the abstractText property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getAbstractText().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link AbstractText } + * + * + */ + public List getAbstractText() { + if (abstractText == null) { + abstractText = new ArrayList(); + } + return this.abstractText; + } + + /** + * Gets the value of the copyrightInformation property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getCopyrightInformation() { + return copyrightInformation; + } + + /** + * Sets the value of the copyrightInformation property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setCopyrightInformation(String value) { + this.copyrightInformation = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/OtherID.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/OtherID.java new file mode 100644 index 000000000..685add227 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/OtherID.java @@ -0,0 +1,74 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; +import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "OtherID") +public class OtherID { + + @XmlAttribute(name = "Source", required = true) + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + protected String source; + + @XmlValue + protected String value; + + /** + * Gets the value of the source property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getSource() { + return source; + } + + /** + * Sets the value of the source property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setSource(String value) { + this.source = value; + } + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PMID.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PMID.java new file mode 100644 index 000000000..e7ef09be2 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PMID.java @@ -0,0 +1,74 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; +import javax.xml.bind.annotation.adapters.NormalizedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "PMID") +public class PMID { + + @XmlAttribute(name = "Version", required = true) + @XmlJavaTypeAdapter(NormalizedStringAdapter.class) + protected String version; + + @XmlValue + protected String value; + + /** + * Gets the value of the version property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getVersion() { + return version; + } + + /** + * Sets the value of the version property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setVersion(String value) { + this.version = value; + } + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Pagination.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Pagination.java new file mode 100644 index 000000000..29c9b04ae --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Pagination.java @@ -0,0 +1,59 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElements; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "startPageOrEndPageOrMedlinePgn" }) +@XmlRootElement(name = "Pagination") +public class Pagination { + + @XmlElements( + { + @XmlElement(name = "StartPage", required = true, type = StartPage.class), + @XmlElement(name = "EndPage", required = true, type = EndPage.class), + @XmlElement(name = "MedlinePgn", required = true, type = MedlinePgn.class), + } + ) + protected List startPageOrEndPageOrMedlinePgn; + + /** + * Gets the value of the startPageOrEndPageOrMedlinePgn property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the startPageOrEndPageOrMedlinePgn property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getStartPageOrEndPageOrMedlinePgn().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link StartPage } + * {@link EndPage } + * {@link MedlinePgn } + * + * + */ + public List getStartPageOrEndPageOrMedlinePgn() { + if (startPageOrEndPageOrMedlinePgn == null) { + startPageOrEndPageOrMedlinePgn = new ArrayList(); + } + return this.startPageOrEndPageOrMedlinePgn; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Param.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Param.java new file mode 100644 index 000000000..6f849471e --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Param.java @@ -0,0 +1,74 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; +import javax.xml.bind.annotation.adapters.NormalizedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "Param") +public class Param { + + @XmlAttribute(name = "Name", required = true) + @XmlJavaTypeAdapter(NormalizedStringAdapter.class) + protected String name; + + @XmlValue + protected String value; + + /** + * Gets the value of the name property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getName() { + return name; + } + + /** + * Sets the value of the name property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setName(String value) { + this.name = value; + } + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PersonalNameSubject.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PersonalNameSubject.java new file mode 100644 index 000000000..909ebe40f --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PersonalNameSubject.java @@ -0,0 +1,124 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "lastName", "foreName", "initials", "suffix" }) +@XmlRootElement(name = "PersonalNameSubject") +public class PersonalNameSubject { + + @XmlElement(name = "LastName", required = true) + protected LastName lastName; + + @XmlElement(name = "ForeName") + protected ForeName foreName; + + @XmlElement(name = "Initials") + protected Initials initials; + + @XmlElement(name = "Suffix") + protected Suffix suffix; + + /** + * Gets the value of the lastName property. + * + * @return + * possible object is + * {@link LastName } + * + */ + public LastName getLastName() { + return lastName; + } + + /** + * Sets the value of the lastName property. + * + * @param value + * allowed object is + * {@link LastName } + * + */ + public void setLastName(LastName value) { + this.lastName = value; + } + + /** + * Gets the value of the foreName property. + * + * @return + * possible object is + * {@link ForeName } + * + */ + public ForeName getForeName() { + return foreName; + } + + /** + * Sets the value of the foreName property. + * + * @param value + * allowed object is + * {@link ForeName } + * + */ + public void setForeName(ForeName value) { + this.foreName = value; + } + + /** + * Gets the value of the initials property. + * + * @return + * possible object is + * {@link Initials } + * + */ + public Initials getInitials() { + return initials; + } + + /** + * Sets the value of the initials property. + * + * @param value + * allowed object is + * {@link Initials } + * + */ + public void setInitials(Initials value) { + this.initials = value; + } + + /** + * Gets the value of the suffix property. + * + * @return + * possible object is + * {@link Suffix } + * + */ + public Suffix getSuffix() { + return suffix; + } + + /** + * Sets the value of the suffix property. + * + * @param value + * allowed object is + * {@link Suffix } + * + */ + public void setSuffix(Suffix value) { + this.suffix = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PersonalNameSubjectList.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PersonalNameSubjectList.java new file mode 100644 index 000000000..bb9b0da6a --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PersonalNameSubjectList.java @@ -0,0 +1,50 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "personalNameSubject" }) +@XmlRootElement(name = "PersonalNameSubjectList") +public class PersonalNameSubjectList { + + @XmlElement(name = "PersonalNameSubject", required = true) + protected List personalNameSubject; + + /** + * Gets the value of the personalNameSubject property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the personalNameSubject property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getPersonalNameSubject().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link PersonalNameSubject } + * + * + */ + public List getPersonalNameSubject() { + if (personalNameSubject == null) { + personalNameSubject = new ArrayList(); + } + return this.personalNameSubject; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PubDate.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PubDate.java new file mode 100644 index 000000000..de4bec643 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PubDate.java @@ -0,0 +1,63 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElements; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "yearOrMonthOrDayOrSeasonOrMedlineDate" }) +@XmlRootElement(name = "PubDate") +public class PubDate { + + @XmlElements( + { + @XmlElement(name = "Year", required = true, type = Year.class), + @XmlElement(name = "Month", required = true, type = Month.class), + @XmlElement(name = "Day", required = true, type = Day.class), + @XmlElement(name = "Season", required = true, type = Season.class), + @XmlElement(name = "MedlineDate", required = true, type = MedlineDate.class), + } + ) + protected List yearOrMonthOrDayOrSeasonOrMedlineDate; + + /** + * Gets the value of the yearOrMonthOrDayOrSeasonOrMedlineDate property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the yearOrMonthOrDayOrSeasonOrMedlineDate property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getYearOrMonthOrDayOrSeasonOrMedlineDate().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Year } + * {@link Month } + * {@link Day } + * {@link Season } + * {@link MedlineDate } + * + * + */ + public List getYearOrMonthOrDayOrSeasonOrMedlineDate() { + if (yearOrMonthOrDayOrSeasonOrMedlineDate == null) { + yearOrMonthOrDayOrSeasonOrMedlineDate = new ArrayList(); + } + return this.yearOrMonthOrDayOrSeasonOrMedlineDate; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PubMedPubDate.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PubMedPubDate.java new file mode 100644 index 000000000..5076be0f4 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PubMedPubDate.java @@ -0,0 +1,209 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "year", "month", "day", "hour", "minute", "second" }) +@XmlRootElement(name = "PubMedPubDate") +public class PubMedPubDate { + + @XmlAttribute(name = "PubStatus", required = true) + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + protected String pubStatus; + + @XmlElement(name = "Year", required = true) + protected Year year; + + @XmlElement(name = "Month", required = true) + protected Month month; + + @XmlElement(name = "Day", required = true) + protected Day day; + + @XmlElement(name = "Hour") + protected String hour; + + @XmlElement(name = "Minute") + protected String minute; + + @XmlElement(name = "Second") + protected String second; + + /** + * Gets the value of the pubStatus property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getPubStatus() { + return pubStatus; + } + + /** + * Sets the value of the pubStatus property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setPubStatus(String value) { + this.pubStatus = value; + } + + /** + * Gets the value of the year property. + * + * @return + * possible object is + * {@link Year } + * + */ + public Year getYear() { + return year; + } + + /** + * Sets the value of the year property. + * + * @param value + * allowed object is + * {@link Year } + * + */ + public void setYear(Year value) { + this.year = value; + } + + /** + * Gets the value of the month property. + * + * @return + * possible object is + * {@link Month } + * + */ + public Month getMonth() { + return month; + } + + /** + * Sets the value of the month property. + * + * @param value + * allowed object is + * {@link Month } + * + */ + public void setMonth(Month value) { + this.month = value; + } + + /** + * Gets the value of the day property. + * + * @return + * possible object is + * {@link Day } + * + */ + public Day getDay() { + return day; + } + + /** + * Sets the value of the day property. + * + * @param value + * allowed object is + * {@link Day } + * + */ + public void setDay(Day value) { + this.day = value; + } + + /** + * Gets the value of the hour property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getHour() { + return hour; + } + + /** + * Sets the value of the hour property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setHour(String value) { + this.hour = value; + } + + /** + * Gets the value of the minute property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getMinute() { + return minute; + } + + /** + * Sets the value of the minute property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setMinute(String value) { + this.minute = value; + } + + /** + * Gets the value of the second property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getSecond() { + return second; + } + + /** + * Sets the value of the second property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setSecond(String value) { + this.second = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PublicationType.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PublicationType.java new file mode 100644 index 000000000..206c35fb5 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PublicationType.java @@ -0,0 +1,43 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "PublicationType") +public class PublicationType { + + @XmlValue + protected String value; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PublicationTypeList.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PublicationTypeList.java new file mode 100644 index 000000000..f83c2aebe --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PublicationTypeList.java @@ -0,0 +1,50 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "publicationType" }) +@XmlRootElement(name = "PublicationTypeList") +public class PublicationTypeList { + + @XmlElement(name = "PublicationType", required = true) + protected List publicationType; + + /** + * Gets the value of the publicationType property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the publicationType property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getPublicationType().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link PublicationType } + * + * + */ + public List getPublicationType() { + if (publicationType == null) { + publicationType = new ArrayList(); + } + return this.publicationType; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Publisher.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Publisher.java new file mode 100644 index 000000000..12f9cd94a --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Publisher.java @@ -0,0 +1,70 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "publisherName", "publisherLocation" }) +@XmlRootElement(name = "Publisher") +public class Publisher { + + @XmlElement(name = "PublisherName", required = true) + protected String publisherName; + + @XmlElement(name = "PublisherLocation") + protected String publisherLocation; + + /** + * Gets the value of the publisherName property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getPublisherName() { + return publisherName; + } + + /** + * Sets the value of the publisherName property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setPublisherName(String value) { + this.publisherName = value; + } + + /** + * Gets the value of the publisherLocation property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getPublisherLocation() { + return publisherLocation; + } + + /** + * Sets the value of the publisherLocation property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setPublisherLocation(String value) { + this.publisherLocation = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PubmedArticle.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PubmedArticle.java new file mode 100644 index 000000000..9a41e4d6a --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PubmedArticle.java @@ -0,0 +1,70 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "medlineCitation", "pubmedData" }) +@XmlRootElement(name = "PubmedArticle") +public class PubmedArticle { + + @XmlElement(name = "MedlineCitation", required = true) + protected MedlineCitation medlineCitation; + + @XmlElement(name = "PubmedData") + protected PubmedData pubmedData; + + /** + * Gets the value of the medlineCitation property. + * + * @return + * possible object is + * {@link MedlineCitation } + * + */ + public MedlineCitation getMedlineCitation() { + return medlineCitation; + } + + /** + * Sets the value of the medlineCitation property. + * + * @param value + * allowed object is + * {@link MedlineCitation } + * + */ + public void setMedlineCitation(MedlineCitation value) { + this.medlineCitation = value; + } + + /** + * Gets the value of the pubmedData property. + * + * @return + * possible object is + * {@link PubmedData } + * + */ + public PubmedData getPubmedData() { + return pubmedData; + } + + /** + * Sets the value of the pubmedData property. + * + * @param value + * allowed object is + * {@link PubmedData } + * + */ + public void setPubmedData(PubmedData value) { + this.pubmedData = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PubmedArticleSet.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PubmedArticleSet.java new file mode 100644 index 000000000..874a4fc20 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PubmedArticleSet.java @@ -0,0 +1,57 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElements; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "pubmedArticleOrPubmedBookArticle" }) +@XmlRootElement(name = "PubmedArticleSet") +public class PubmedArticleSet { + + @XmlElements( + { + @XmlElement(name = "PubmedArticle", required = true, type = PubmedArticle.class), + @XmlElement(name = "PubmedBookArticle", required = true, type = PubmedBookArticle.class), + } + ) + protected List pubmedArticleOrPubmedBookArticle; + + /** + * Gets the value of the pubmedArticleOrPubmedBookArticle property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the pubmedArticleOrPubmedBookArticle property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getPubmedArticleOrPubmedBookArticle().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link PubmedArticle } + * {@link PubmedBookArticle } + * + * + */ + public List getPubmedArticleOrPubmedBookArticle() { + if (pubmedArticleOrPubmedBookArticle == null) { + pubmedArticleOrPubmedBookArticle = new ArrayList(); + } + return this.pubmedArticleOrPubmedBookArticle; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PubmedBookArticle.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PubmedBookArticle.java new file mode 100644 index 000000000..fc8bba107 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PubmedBookArticle.java @@ -0,0 +1,70 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "bookDocument", "pubmedBookData" }) +@XmlRootElement(name = "PubmedBookArticle") +public class PubmedBookArticle { + + @XmlElement(name = "BookDocument", required = true) + protected BookDocument bookDocument; + + @XmlElement(name = "PubmedBookData") + protected PubmedBookData pubmedBookData; + + /** + * Gets the value of the bookDocument property. + * + * @return + * possible object is + * {@link BookDocument } + * + */ + public BookDocument getBookDocument() { + return bookDocument; + } + + /** + * Sets the value of the bookDocument property. + * + * @param value + * allowed object is + * {@link BookDocument } + * + */ + public void setBookDocument(BookDocument value) { + this.bookDocument = value; + } + + /** + * Gets the value of the pubmedBookData property. + * + * @return + * possible object is + * {@link PubmedBookData } + * + */ + public PubmedBookData getPubmedBookData() { + return pubmedBookData; + } + + /** + * Sets the value of the pubmedBookData property. + * + * @param value + * allowed object is + * {@link PubmedBookData } + * + */ + public void setPubmedBookData(PubmedBookData value) { + this.pubmedBookData = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PubmedBookArticleSet.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PubmedBookArticleSet.java new file mode 100644 index 000000000..cc6208471 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PubmedBookArticleSet.java @@ -0,0 +1,50 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "pubmedBookArticle" }) +@XmlRootElement(name = "PubmedBookArticleSet") +public class PubmedBookArticleSet { + + @XmlElement(name = "PubmedBookArticle") + protected List pubmedBookArticle; + + /** + * Gets the value of the pubmedBookArticle property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the pubmedBookArticle property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getPubmedBookArticle().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link PubmedBookArticle } + * + * + */ + public List getPubmedBookArticle() { + if (pubmedBookArticle == null) { + pubmedBookArticle = new ArrayList(); + } + return this.pubmedBookArticle; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PubmedBookData.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PubmedBookData.java new file mode 100644 index 000000000..bda06db79 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PubmedBookData.java @@ -0,0 +1,124 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "history", "publicationStatus", "articleIdList", "objectList" }) +@XmlRootElement(name = "PubmedBookData") +public class PubmedBookData { + + @XmlElement(name = "History") + protected History history; + + @XmlElement(name = "PublicationStatus", required = true) + protected String publicationStatus; + + @XmlElement(name = "ArticleIdList", required = true) + protected ArticleIdList articleIdList; + + @XmlElement(name = "ObjectList") + protected ObjectList objectList; + + /** + * Gets the value of the history property. + * + * @return + * possible object is + * {@link History } + * + */ + public History getHistory() { + return history; + } + + /** + * Sets the value of the history property. + * + * @param value + * allowed object is + * {@link History } + * + */ + public void setHistory(History value) { + this.history = value; + } + + /** + * Gets the value of the publicationStatus property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getPublicationStatus() { + return publicationStatus; + } + + /** + * Sets the value of the publicationStatus property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setPublicationStatus(String value) { + this.publicationStatus = value; + } + + /** + * Gets the value of the articleIdList property. + * + * @return + * possible object is + * {@link ArticleIdList } + * + */ + public ArticleIdList getArticleIdList() { + return articleIdList; + } + + /** + * Sets the value of the articleIdList property. + * + * @param value + * allowed object is + * {@link ArticleIdList } + * + */ + public void setArticleIdList(ArticleIdList value) { + this.articleIdList = value; + } + + /** + * Gets the value of the objectList property. + * + * @return + * possible object is + * {@link ObjectList } + * + */ + public ObjectList getObjectList() { + return objectList; + } + + /** + * Sets the value of the objectList property. + * + * @param value + * allowed object is + * {@link ObjectList } + * + */ + public void setObjectList(ObjectList value) { + this.objectList = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PubmedData.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PubmedData.java new file mode 100644 index 000000000..13bb70f1e --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/PubmedData.java @@ -0,0 +1,124 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "history", "publicationStatus", "articleIdList", "objectList" }) +@XmlRootElement(name = "PubmedData") +public class PubmedData { + + @XmlElement(name = "History") + protected History history; + + @XmlElement(name = "PublicationStatus", required = true) + protected String publicationStatus; + + @XmlElement(name = "ArticleIdList", required = true) + protected ArticleIdList articleIdList; + + @XmlElement(name = "ObjectList") + protected ObjectList objectList; + + /** + * Gets the value of the history property. + * + * @return + * possible object is + * {@link History } + * + */ + public History getHistory() { + return history; + } + + /** + * Sets the value of the history property. + * + * @param value + * allowed object is + * {@link History } + * + */ + public void setHistory(History value) { + this.history = value; + } + + /** + * Gets the value of the publicationStatus property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getPublicationStatus() { + return publicationStatus; + } + + /** + * Sets the value of the publicationStatus property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setPublicationStatus(String value) { + this.publicationStatus = value; + } + + /** + * Gets the value of the articleIdList property. + * + * @return + * possible object is + * {@link ArticleIdList } + * + */ + public ArticleIdList getArticleIdList() { + return articleIdList; + } + + /** + * Sets the value of the articleIdList property. + * + * @param value + * allowed object is + * {@link ArticleIdList } + * + */ + public void setArticleIdList(ArticleIdList value) { + this.articleIdList = value; + } + + /** + * Gets the value of the objectList property. + * + * @return + * possible object is + * {@link ObjectList } + * + */ + public ObjectList getObjectList() { + return objectList; + } + + /** + * Sets the value of the objectList property. + * + * @param value + * allowed object is + * {@link ObjectList } + * + */ + public void setObjectList(ObjectList value) { + this.objectList = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/QualifierName.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/QualifierName.java new file mode 100644 index 000000000..57bcb7e1f --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/QualifierName.java @@ -0,0 +1,78 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; +import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "QualifierName") +public class QualifierName { + + @XmlAttribute(name = "MajorTopicYN") + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + protected String majorTopicYN; + + @XmlValue + protected String value; + + /** + * Gets the value of the majorTopicYN property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getMajorTopicYN() { + if (majorTopicYN == null) { + return "N"; + } else { + return majorTopicYN; + } + } + + /** + * Sets the value of the majorTopicYN property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setMajorTopicYN(String value) { + this.majorTopicYN = value; + } + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Season.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Season.java new file mode 100644 index 000000000..4e6fe5ca4 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Season.java @@ -0,0 +1,43 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "Season") +public class Season { + + @XmlValue + protected String value; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Section.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Section.java new file mode 100644 index 000000000..ac8b412a4 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Section.java @@ -0,0 +1,104 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "locationLabel", "sectionTitle", "section" }) +@XmlRootElement(name = "Section") +public class Section { + + @XmlElement(name = "LocationLabel") + protected LocationLabel locationLabel; + + @XmlElement(name = "SectionTitle", required = true) + protected SectionTitle sectionTitle; + + @XmlElement(name = "Section") + protected List

section; + + /** + * Gets the value of the locationLabel property. + * + * @return + * possible object is + * {@link LocationLabel } + * + */ + public LocationLabel getLocationLabel() { + return locationLabel; + } + + /** + * Sets the value of the locationLabel property. + * + * @param value + * allowed object is + * {@link LocationLabel } + * + */ + public void setLocationLabel(LocationLabel value) { + this.locationLabel = value; + } + + /** + * Gets the value of the sectionTitle property. + * + * @return + * possible object is + * {@link SectionTitle } + * + */ + public SectionTitle getSectionTitle() { + return sectionTitle; + } + + /** + * Sets the value of the sectionTitle property. + * + * @param value + * allowed object is + * {@link SectionTitle } + * + */ + public void setSectionTitle(SectionTitle value) { + this.sectionTitle = value; + } + + /** + * Gets the value of the section property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the section property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getSection().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Section } + * + * + */ + public List

getSection() { + if (section == null) { + section = new ArrayList
(); + } + return this.section; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/SectionTitle.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/SectionTitle.java new file mode 100644 index 000000000..7f459affe --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/SectionTitle.java @@ -0,0 +1,130 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; +import javax.xml.bind.annotation.adapters.NormalizedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "SectionTitle") +public class SectionTitle { + + @XmlAttribute(name = "book") + @XmlJavaTypeAdapter(NormalizedStringAdapter.class) + protected String book; + + @XmlAttribute(name = "part") + @XmlJavaTypeAdapter(NormalizedStringAdapter.class) + protected String part; + + @XmlAttribute(name = "sec") + @XmlJavaTypeAdapter(NormalizedStringAdapter.class) + protected String sec; + + @XmlValue + protected String value; + + /** + * Gets the value of the book property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getBook() { + return book; + } + + /** + * Sets the value of the book property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setBook(String value) { + this.book = value; + } + + /** + * Gets the value of the part property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getPart() { + return part; + } + + /** + * Sets the value of the part property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setPart(String value) { + this.part = value; + } + + /** + * Gets the value of the sec property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getSec() { + return sec; + } + + /** + * Sets the value of the sec property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setSec(String value) { + this.sec = value; + } + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Sections.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Sections.java new file mode 100644 index 000000000..6d3448940 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Sections.java @@ -0,0 +1,50 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "section" }) +@XmlRootElement(name = "Sections") +public class Sections { + + @XmlElement(name = "Section", required = true) + protected List
section; + + /** + * Gets the value of the section property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the section property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getSection().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Section } + * + * + */ + public List

getSection() { + if (section == null) { + section = new ArrayList
(); + } + return this.section; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/SpaceFlightMission.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/SpaceFlightMission.java new file mode 100644 index 000000000..320c94096 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/SpaceFlightMission.java @@ -0,0 +1,43 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "SpaceFlightMission") +public class SpaceFlightMission { + + @XmlValue + protected String value; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/StartPage.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/StartPage.java new file mode 100644 index 000000000..b75f6b0ba --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/StartPage.java @@ -0,0 +1,43 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "StartPage") +public class StartPage { + + @XmlValue + protected String value; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Sub.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Sub.java new file mode 100644 index 000000000..6e8c06a3a --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Sub.java @@ -0,0 +1,43 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "sub") +public class Sub { + + @XmlValue + protected String value; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Suffix.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Suffix.java new file mode 100644 index 000000000..2cf6ac905 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Suffix.java @@ -0,0 +1,43 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "Suffix") +public class Suffix { + + @XmlValue + protected String value; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Sup.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Sup.java new file mode 100644 index 000000000..f71cea9ad --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Sup.java @@ -0,0 +1,43 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "sup") +public class Sup { + + @XmlValue + protected String value; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/SupplMeshList.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/SupplMeshList.java new file mode 100644 index 000000000..e33579f4a --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/SupplMeshList.java @@ -0,0 +1,50 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "supplMeshName" }) +@XmlRootElement(name = "SupplMeshList") +public class SupplMeshList { + + @XmlElement(name = "SupplMeshName", required = true) + protected List supplMeshName; + + /** + * Gets the value of the supplMeshName property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the supplMeshName property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getSupplMeshName().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link SupplMeshName } + * + * + */ + public List getSupplMeshName() { + if (supplMeshName == null) { + supplMeshName = new ArrayList(); + } + return this.supplMeshName; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/SupplMeshName.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/SupplMeshName.java new file mode 100644 index 000000000..67e69a2c2 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/SupplMeshName.java @@ -0,0 +1,74 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; +import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "SupplMeshName") +public class SupplMeshName { + + @XmlAttribute(name = "Type", required = true) + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + protected String type; + + @XmlValue + protected String value; + + /** + * Gets the value of the type property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getType() { + return type; + } + + /** + * Sets the value of the type property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setType(String value) { + this.type = value; + } + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/U.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/U.java new file mode 100644 index 000000000..a678a02ed --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/U.java @@ -0,0 +1,43 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "u") +public class U { + + @XmlValue + protected String value; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/URL.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/URL.java new file mode 100644 index 000000000..75b1d039f --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/URL.java @@ -0,0 +1,102 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; +import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "URL") +public class URL { + + @XmlAttribute(name = "lang") + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + protected String lang; + + @XmlAttribute(name = "Type") + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + protected String type; + + @XmlValue + protected String value; + + /** + * Gets the value of the lang property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getLang() { + return lang; + } + + /** + * Sets the value of the lang property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setLang(String value) { + this.lang = value; + } + + /** + * Gets the value of the type property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getType() { + return type; + } + + /** + * Sets the value of the type property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setType(String value) { + this.type = value; + } + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Value.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Value.java new file mode 100644 index 000000000..fd99bad20 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Value.java @@ -0,0 +1,23 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.*; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "") +@XmlRootElement +public class Value { + + @XmlAnyElement(lax = true) + protected Object[] value; + + public Object[] getValue() { + return value; + } + + public void setValue(Object[] value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Year.java b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Year.java new file mode 100644 index 000000000..11abe5067 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/nih/efetch/Year.java @@ -0,0 +1,43 @@ +package org.mskcc.oncokb.curation.domain.nih.efetch; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; + +/** + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { "value" }) +@XmlRootElement(name = "Year") +public class Year { + + @XmlValue + protected String value; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getvalue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setvalue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/domain/package-info.java b/src/main/java/org/mskcc/oncokb/curation/domain/package-info.java new file mode 100644 index 000000000..93a449640 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/domain/package-info.java @@ -0,0 +1,4 @@ +/** + * JPA domain objects. + */ +package org.mskcc.oncokb.curation.domain; diff --git a/src/main/java/org/mskcc/oncokb/curation/importer/CanonicalTranscriptFlagImporter.java b/src/main/java/org/mskcc/oncokb/curation/importer/CanonicalTranscriptFlagImporter.java new file mode 100644 index 000000000..d0ea5978e --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/importer/CanonicalTranscriptFlagImporter.java @@ -0,0 +1,129 @@ +package org.mskcc.oncokb.curation.importer; + +import static org.mskcc.oncokb.curation.util.FileUtils.readDelimitedLinesStream; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.*; +import java.util.stream.Collectors; +import org.apache.commons.lang3.StringUtils; +import org.mskcc.oncokb.curation.domain.Flag; +import org.mskcc.oncokb.curation.domain.Transcript; +import org.mskcc.oncokb.curation.domain.enumeration.FlagType; +import org.mskcc.oncokb.curation.domain.enumeration.ReferenceGenome; +import org.mskcc.oncokb.curation.service.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.CommandLineRunner; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Component; + +/** + * To backfill the OncoKB canonical transcripts + */ + +@Component +@Profile("transcript-flag-importer") +public class CanonicalTranscriptFlagImporter implements CommandLineRunner { + + private final Logger log = LoggerFactory.getLogger(CanonicalTranscriptFlagImporter.class); + + final String ONCOKB_GENE_LIST_FILE_PATH = "data/oncokb_core/cancer_gene_list_v4_24.tsv"; + + final GeneService geneService; + final TranscriptService transcriptService; + final FlagService flagService; + + public CanonicalTranscriptFlagImporter( + GeneService geneService, + GenomeNexusService genomeNexusService, + EnsemblGeneService ensemblGeneService, + TranscriptService transcriptService, + FlagService flagService, + InfoService infoService, + MainService mainService + ) { + this.geneService = geneService; + this.transcriptService = transcriptService; + this.flagService = flagService; + } + + @Override + public void run(String... args) throws Exception { + log.info("Running canonical transcript flag importer..."); + importCanonicalTranscripts(); + log.info("Finished importer."); + } + + private void importCanonicalTranscripts() { + URL geneListUrl = getClass().getClassLoader().getResource(ONCOKB_GENE_LIST_FILE_PATH); + try { + InputStream is = geneListUrl.openStream(); + List> tsvFile = readDelimitedLinesStream(is, "\t", true); + for (int i = 0; i < tsvFile.size(); i++) { + if (i == 0) { + continue; + } + List line = tsvFile.get(i); + if (line.size() < 8) { + throw new IOException(String.format("Line %i has less than 8 columns", i)); + } + Integer entrezGeneId; + if (StringUtils.isNumeric(line.get(1))) { + entrezGeneId = Integer.parseInt(line.get(1), 10); + } else { + log.warn(String.format("Entrez Id not found on line %i", i)); + continue; + } + + String grch37Isoform = line.get(2); + String grch37RefSeq = line.get(3); + if (StringUtils.isBlank(grch37Isoform)) { + log.warn(String.format("No GRCh37 isoform found for gene %s, skipping...", line.get(0))); + } else { + findAndSaveTranscriptInfo(entrezGeneId, grch37Isoform, grch37RefSeq, ReferenceGenome.GRCh37); + } + + String grch38Isoform = line.get(4); + String grch38RefSeq = line.get(5); + if (StringUtils.isBlank(grch38Isoform)) { + log.warn(String.format("No GRCh38 isoform found for gene %s, skipping...", line.get(0))); + } else { + findAndSaveTranscriptInfo(entrezGeneId, grch38Isoform, grch38RefSeq, ReferenceGenome.GRCh38); + } + } + } catch (IOException e) { + log.error(e.getMessage()); + } + } + + private void findAndSaveTranscriptInfo(Integer entrezGeneId, String isoform, String refSeq, ReferenceGenome referenceGenome) { + List transcripts = transcriptService + .findByEntrezGeneIdAndReferenceGenome(entrezGeneId, referenceGenome) + .stream() + .filter(transcript -> transcript.getEnsemblTranscriptId().startsWith(isoform)) + .collect(Collectors.toList()); + Flag oncokbCanonicalFlag = flagService.findByTypeAndFlag(FlagType.TRANSCRIPT, "ONCOKB").orElseThrow(); + Transcript transcript; + if (transcripts.size() > 0) { + if (transcripts.size() > 1) { + log.warn("Found more than one matching transcripts with different subversions, skipping..."); + return; + } + transcript = transcripts.get(0); + transcript.setCanonical(true); + transcript.setEnsemblTranscriptId(isoform); + transcript.setReferenceSequenceId(refSeq); + transcript.getFlags().add(oncokbCanonicalFlag); + try { + transcriptService.save(transcript); + } catch (Exception e) { + log.error(e.getMessage()); + } + log.info(String.format("Successfully saved transcript %s %s %s", isoform, refSeq, referenceGenome.toString())); + } else { + log.warn("Transcript does not exist in database, skipping..."); + } + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/importer/CdxImporter.java b/src/main/java/org/mskcc/oncokb/curation/importer/CdxImporter.java new file mode 100644 index 000000000..ef9e40da9 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/importer/CdxImporter.java @@ -0,0 +1,336 @@ +package org.mskcc.oncokb.curation.importer; + +import static org.mskcc.oncokb.curation.util.FileUtils.readDelimitedLinesStream; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.time.Instant; +import java.time.LocalDate; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import jodd.util.StringUtil; +import org.mskcc.oncokb.curation.domain.*; +import org.mskcc.oncokb.curation.domain.enumeration.AssociationCancerTypeRelation; +import org.mskcc.oncokb.curation.domain.enumeration.ReferenceGenome; +import org.mskcc.oncokb.curation.domain.enumeration.RuleEntity; +import org.mskcc.oncokb.curation.service.*; +import org.mskcc.oncokb.curation.service.dto.TreatmentDTO; +import org.mskcc.oncokb.curation.util.CdxUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class CdxImporter { + + @Autowired + private CdxUtils cdxUtils; + + @Autowired + private AssociationService associationService; + + @Autowired + private CompanionDiagnosticDeviceService companionDiagnosticDeviceService; + + @Autowired + private FdaSubmissionService fdaSubmissionService; + + @Autowired + private SpecimenTypeService specimenTypeService; + + @Autowired + private GeneService geneService; + + @Autowired + private AlterationService alterationService; + + @Autowired + private CancerTypeService cancerTypeService; + + @Autowired + private DrugService drugService; + + @Autowired + private MainService mainService; + + private final Logger log = LoggerFactory.getLogger(Importer.class); + + public void importCdxMain() throws IOException { + List> parsedCdxContent = readInitialCdxFile(); + if (parsedCdxContent == null) { + return; + } + + for (int i = 0; i < parsedCdxContent.size(); i++) { + if (i == 0) { + continue; // Skipping header row + } + log.info("Processing row " + i); + List row = parsedCdxContent.get(i); + try { + CompanionDiagnosticDevice cdx = null; + List fdaSubmissions = new ArrayList<>(); + List treatments = new ArrayList<>(); + List genes = new ArrayList<>(); + Map> geneAlterationMap = new HashMap<>(); + List cancerTypes = new ArrayList<>(); + + // Parse row + for (int colIndex = 0; colIndex < row.size(); colIndex++) { + String columnValue = row.get(colIndex).trim(); + switch (colIndex) { + case 0: + cdx = parseCdxNameColumn(columnValue); + break; + case 5: + genes = parseGeneColumn(columnValue); + break; + case 6: + geneAlterationMap = parseAlterationColumn(columnValue, genes); + break; + case 7: + cancerTypes = parseCancerTypesColumn(columnValue); + break; + case 8: + treatments = parseTreatmentColumn(columnValue); + break; + case 9: + cdx.setPlatformType(columnValue); + break; + case 10: + parseSpecimenTypeColumn(columnValue, cdx); + break; + case 12: + for (String val : columnValue.split("and")) { + Optional fdaSubmissionOptional = parseFdaSubmissionColumn(val); + if (fdaSubmissionOptional.isPresent()) { + fdaSubmissions.add(fdaSubmissionOptional.orElseThrow()); + } + } + break; + default: + break; + } + } + saveCdxInformation(cdx, fdaSubmissions, cancerTypes, treatments, geneAlterationMap); + log.info("Successfully imported row {}", i); + } catch (IllegalArgumentException e) { + String message = e.getMessage(); + if (message == null) { + message = String.format("Could not parse column in row %s", i); + } + log.error(message); + log.error("Issue processing row {} {}, skipping...", i, row); + continue; + } + } + } + + private void saveCdxInformation( + CompanionDiagnosticDevice cdx, + List fdaSubmissions, + List cancerTypes, + List treatments, + Map> geneAlterationMap + ) { + CompanionDiagnosticDevice savedCdx = companionDiagnosticDeviceService.save(cdx); + fdaSubmissions = fdaSubmissions + .stream() + .map(pma -> { + pma.setCompanionDiagnosticDevice(savedCdx); + return fdaSubmissionService.save(pma); + }) + .collect(Collectors.toList()); + + Association biomarkerAssociation = new Association(); + if (!treatments.isEmpty()) { + Set drugSet = new HashSet<>(); + treatments.forEach(treatmentDTO -> drugSet.addAll(treatmentDTO.getDrugs())); + biomarkerAssociation.setDrugs(drugSet); + Rule rule = new Rule(); + rule.setEntity(RuleEntity.DRUG.name()); + rule.setRule( + treatments + .stream() + .map( + treatmentDTO -> + treatmentDTO.getDrugs().stream().map(drug -> drug.getId().toString()).collect(Collectors.joining("+")) + ) + .collect(Collectors.joining(",")) + ); + biomarkerAssociation.addRule(rule); + } + Set allAlts = new HashSet<>(); + for (Map.Entry> entry : geneAlterationMap.entrySet()) { + allAlts.addAll(entry.getValue()); + } + if (!cancerTypes.isEmpty()) { + biomarkerAssociation.setCancerTypes(new HashSet<>(cancerTypes)); + Rule rule = new Rule(); + rule.setEntity(RuleEntity.CANCER_TYPE.name()); + rule.setRule(cancerTypes.stream().map(cancerType -> cancerType.getId().toString()).collect(Collectors.joining(","))); + biomarkerAssociation.addRule(rule); + } + fdaSubmissions.forEach(biomarkerAssociation::addFdaSubmission); + biomarkerAssociation.setAlterations(allAlts); + associationService.save(biomarkerAssociation); + } + + private CompanionDiagnosticDevice parseCdxNameColumn(String columnValue) throws IllegalArgumentException { + Pattern pattern = Pattern.compile("^(.*)\\((.*?)\\)"); + Matcher matcher = pattern.matcher(columnValue); + if (matcher.find() && matcher.group(1) != null && matcher.group(2) != null) { + String cdxName = matcher.group(1); + String cdxManufacturer = matcher.group(2); + CompanionDiagnosticDevice cdx = companionDiagnosticDeviceService + .findByNameAndManufacturer(cdxName, cdxManufacturer) + .stream() + .findFirst() + .orElse(new CompanionDiagnosticDevice()); + cdx.setName(cdxName); + cdx.setManufacturer(cdxManufacturer); + return cdx; + } else { + throw new IllegalArgumentException(); + } + } + + private Optional parseFdaSubmissionColumn(String columnValue) { + columnValue = columnValue.trim(); + Pattern pattern = Pattern.compile("^([A-Za-z\\d]+)(\\/([A-Za-z\\d]+))?\\s*(\\((.*)\\))?"); + Matcher matcher = pattern.matcher(columnValue); + if (matcher.find() && matcher.group(1) != null) { + String number = matcher.group(1); + String supplementNumber = Optional.ofNullable(matcher.group(3)).orElse(""); + Optional optionalFdaSubmission = fdaSubmissionService.findOrFetchFdaSubmissionByNumber( + number, + supplementNumber, + false + ); + if (optionalFdaSubmission.isPresent()) { + LocalDate fdaSubmissionDate = cdxUtils.convertDateToLocalDate(matcher.group(5)); + if (fdaSubmissionDate != null) { + optionalFdaSubmission.orElseThrow().setDecisionDate(fdaSubmissionDate); + optionalFdaSubmission.orElseThrow().curated(true); + } + return optionalFdaSubmission; + } else { + log.error("Could not find FDA Submission {}", columnValue); + } + } else { + log.error("Cannot find FDA Submission {}", columnValue); + } + return Optional.empty(); + } + + private List parseCancerTypesColumn(String columnValue) throws IllegalArgumentException { + List cancerTypes = new ArrayList<>(); + for (String cancerType : columnValue.split("\\|")) { + cancerType = cancerType.trim(); + Optional optionalCancerType = cancerTypeService.findOneBySubtypeIgnoreCase(cancerType); + if (optionalCancerType.isPresent()) { + cancerTypes.add(optionalCancerType.orElseThrow()); + } else { + optionalCancerType = cancerTypeService.findByMainTypeAndSubtypeIsNull(cancerType); + if (optionalCancerType.isPresent()) { + cancerTypes.add(optionalCancerType.orElseThrow()); + } else { + throw new IllegalArgumentException(); + } + } + } + return cancerTypes; + } + + private List parseTreatmentColumn(String columnValue) { + List treatments = new ArrayList<>(); + for (String drugsString : columnValue.split(",\\s+")) { + TreatmentDTO treatment = new TreatmentDTO(); + for (String drugString : drugsString.split("\\+")) { + drugString = drugString.trim(); + Optional optionalDrug = drugService.findByName(drugString).stream().findFirst(); + if (optionalDrug.isPresent()) { + treatment.addDrug(optionalDrug.orElseThrow()); + } else { + log.error("Could not find drug {}", drugString); + } + } + treatments.add(treatment); + } + return treatments; + } + + private List parseGeneColumn(String columnValue) throws IllegalArgumentException { + List genes = new ArrayList<>(); + String[] geneStrings = columnValue.split("(and)|,"); + for (String geneString : geneStrings) { + geneString = geneString.replaceAll("\\(\\S+\\)", "").trim(); + Optional optionalGene = geneService.findGeneByHugoSymbol(geneString); + if (optionalGene.isEmpty()) { + log.error("Could not find gene " + geneString); + } else { + genes.add(optionalGene.orElseThrow()); + } + } + return genes; + } + + private Map> parseAlterationColumn(String columnValue, List genes) throws IllegalArgumentException { + Map> geneAlterationMap = new HashMap<>(); + String[] alterationStrings = { columnValue }; + if (columnValue.contains(",")) { + alterationStrings = columnValue.split(","); + } + + for (Gene gene : genes) { + Long geneId = gene.getId(); + List alterations = new ArrayList<>(); + for (String alterationString : alterationStrings) { + alterationString = alterationString.trim(); + List alterationList = alterationService.findByNameOrAlterationAndGenesId(alterationString, geneId); + if (alterationList.isEmpty()) { + log.error("Cannot find alteration {} for gene {}, adding...", alterationString, gene.getHugoSymbol()); + Alteration alteration = new Alteration(); + alteration.setAlteration(alterationString); + alteration.setGenes(Collections.singleton(gene)); + mainService.annotateAlteration(ReferenceGenome.GRCh37, alteration); + alterationList.add(alterationService.save(alteration)); + } + geneAlterationMap.putIfAbsent(gene, alterations); + geneAlterationMap.get(gene).addAll(alterationList); + } + } + return geneAlterationMap; + } + + private void parseSpecimenTypeColumn(String columnValue, CompanionDiagnosticDevice cdx) throws IllegalArgumentException { + if (StringUtil.isEmpty(columnValue) || StringUtil.isEmpty(columnValue.trim())) { + return; + } + columnValue = columnValue.trim(); + Arrays.stream(columnValue.split(" or ")).forEach(name -> { + name = name.trim(); + Optional optionalSpecimenType = specimenTypeService.findOneByName(name); + if (optionalSpecimenType.isPresent() && cdx != null) { + cdx.addSpecimenType(optionalSpecimenType.orElseThrow()); + } else { + log.error("Cannot find the CDx specimen type {}", name); + throw new IllegalArgumentException(); + } + }); + } + + private List> readInitialCdxFile() throws IOException { + URL cdxFileUrl = getClass().getClassLoader().getResource("data/initial_cdx_data.tsv"); + if (cdxFileUrl == null) { + log.error("Cannot find CDx file"); + return null; + } + InputStream is = cdxFileUrl.openStream(); + return readDelimitedLinesStream(is, "\\t", true); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/importer/CoreImporter.java b/src/main/java/org/mskcc/oncokb/curation/importer/CoreImporter.java new file mode 100644 index 000000000..26f7db93c --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/importer/CoreImporter.java @@ -0,0 +1,186 @@ +package org.mskcc.oncokb.curation.importer; + +import static org.mskcc.oncokb.curation.config.DataVersions.ONCOKB_CORE_VERSION; +import static org.mskcc.oncokb.curation.util.FileUtils.parseDelimitedFile; + +import java.io.IOException; +import java.sql.Ref; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import jodd.util.StringUtil; +import org.apache.commons.lang3.StringUtils; +import org.mskcc.oncokb.curation.config.application.ApplicationProperties; +import org.mskcc.oncokb.curation.domain.*; +import org.mskcc.oncokb.curation.domain.enumeration.ArticleType; +import org.mskcc.oncokb.curation.domain.enumeration.ReferenceGenome; +import org.mskcc.oncokb.curation.service.*; +import org.mskcc.oncokb.curation.service.dto.pubmed.PubMedDTO; +import org.mskcc.oncokb.curation.service.mapper.PubMedMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component +public class CoreImporter { + + private final Logger log = LoggerFactory.getLogger(CoreImporter.class); + final CancerTypeService cancerTypeService; + final ArticleService articleService; + final GeneService geneService; + final AlterationService alterationService; + final DrugService drugService; + final NciThesaurusService nciThesaurusService; + final MainService mainService; + final NihEutilsService nihEutilsService; + final PubMedMapper pubMedMapper; + final ApplicationProperties applicationProperties; + final String DATA_DIRECTORY_PATH; + final String MIXED = "MIXED"; + + public CoreImporter( + CancerTypeService cancerTypeService, + ArticleService articleService, + GeneService geneService, + AlterationService alterationService, + DrugService drugService, + NciThesaurusService nciThesaurusService, + MainService mainService, + NihEutilsService nihEutilsService, + PubMedMapper pubMedMapper, + ApplicationProperties applicationProperties + ) { + this.cancerTypeService = cancerTypeService; + this.articleService = articleService; + this.geneService = geneService; + this.alterationService = alterationService; + this.drugService = drugService; + this.nciThesaurusService = nciThesaurusService; + this.mainService = mainService; + this.nihEutilsService = nihEutilsService; + this.pubMedMapper = pubMedMapper; + this.applicationProperties = applicationProperties; + + DATA_DIRECTORY_PATH = applicationProperties.getOncokbDataRepoDir() + "/curation/oncokb/"; + } + + public void generalImport() throws IOException { + importAlteration(); + verifyGene(); + } + + private String getVersionInFileName() { + return ONCOKB_CORE_VERSION.replace(".", "_"); + } + + public void importArticle() throws IOException { + List> articleLines = parseDelimitedFile( + DATA_DIRECTORY_PATH + "article_" + getVersionInFileName() + ".tsv", + "\t", + true + ); + articleLines.forEach(line -> { + String pmid = line.get(8); + if (StringUtils.isNotEmpty(pmid)) { + Optional

articleOptional = articleService.findByPmid(pmid); + if (articleOptional.isEmpty()) { + articleService.fetchAndSavePubMed(pmid); + } + } else { + String content = line.get(1); + String link = line.get(6); + if (StringUtil.isNotEmpty(content) && StringUtils.isNotEmpty(link)) { + Article article = new Article(); + article.setType(ArticleType.ABSTRACT); + article.setTitle(content); + article.setLink(link); + articleService.save(article); + } + } + }); + } + + private void importAlteration() throws IOException { + List> alterationLines = parseDelimitedFile( + DATA_DIRECTORY_PATH + "alteration_" + getVersionInFileName() + ".tsv", + "\t", + true + ); + alterationLines.forEach(line -> { + Optional geneOptional = geneService.findGeneByEntrezGeneId(Integer.parseInt(line.get(0))); + if (geneOptional.isEmpty()) { + log.error("Gene cannot be found {}", line.get(0)); + return; + } + Alteration alteration = new Alteration(); + alteration.setName(line.get(2)); + alteration.setAlteration(line.get(3)); + alteration.setGenes(Collections.singleton(geneOptional.orElseThrow())); + mainService.annotateAlteration(ReferenceGenome.GRCh37, alteration); + alterationService.save(alteration); + }); + } + + // Verify the gene hugo symbol is the latest from the cBioPortal genes + public void verifyGene() throws IOException { + List> geneLines = parseDelimitedFile(DATA_DIRECTORY_PATH + "gene_" + getVersionInFileName() + ".tsv", "\t", true); + geneLines.forEach(line -> { + Optional geneOptional = geneService.findGeneByEntrezGeneId(Integer.parseInt(line.get(0))); + if (geneOptional.isEmpty()) { + log.error("Gene cannot be found {} {} ", line.get(0)); + return; + } + String oncokbHugo = line.get(6); + if (StringUtil.isEmpty(oncokbHugo)) { + log.error("Line does not have hugo symbol {}", line); + } else { + if (!oncokbHugo.equals(geneOptional.orElseThrow().getHugoSymbol())) { + log.error( + "Hugo Symbol does not match oncokb: {}, cbioportal: {}", + oncokbHugo, + geneOptional.orElseThrow().getHugoSymbol() + ); + } + } + }); + } + + public void importDrug() throws IOException { + List> drugLines = parseDelimitedFile(DATA_DIRECTORY_PATH + "drug_" + getVersionInFileName() + ".tsv", "\t", true); + drugLines.forEach(line -> { + String name = line.get(2); + String code = line.get(3); + + Drug drug = new Drug(); + drug.setName(name); + Optional nciThesaurusOptional = Optional.empty(); + + Optional drugOptional = Optional.empty(); + if (StringUtils.isEmpty(code)) { + drugOptional = drugService.findByName(name); + } else { + drugOptional = drugService.findByCode(code); + } + + if (drugOptional.isPresent()) { + log.info("Drug exists {} {}, skipping", name, code); + return; + } + + if (StringUtil.isEmpty(code)) { + log.warn("The drug does not have a code {}, will look for the name", name); + nciThesaurusOptional = nciThesaurusService.findOneByNamePriority(name); + } else { + nciThesaurusOptional = nciThesaurusService.findByCode(code); + } + if (nciThesaurusOptional.isPresent()) { + drug.setNciThesaurus(nciThesaurusOptional.orElseThrow()); + } else { + log.warn("The code cannot be found {}", code); + } + drug.setUuid(UUID.randomUUID().toString()); + drugService.save(drug); + }); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/importer/EnsemblImporter.java b/src/main/java/org/mskcc/oncokb/curation/importer/EnsemblImporter.java new file mode 100644 index 000000000..3d4bb67a1 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/importer/EnsemblImporter.java @@ -0,0 +1,102 @@ +package org.mskcc.oncokb.curation.importer; + +import static org.mskcc.oncokb.curation.util.FileUtils.readDelimitedLinesStream; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.*; +import java.util.stream.Collectors; +import org.mskcc.oncokb.curation.domain.SeqRegion; +import org.mskcc.oncokb.curation.service.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component +public class EnsemblImporter { + + private final String ENSEMBL_VERSION = "v110"; + + private final SeqRegionService seqRegionService; + + private final Logger log = LoggerFactory.getLogger(EnsemblImporter.class); + + public EnsemblImporter(SeqRegionService seqRegionService) { + this.seqRegionService = seqRegionService; + } + + public void importSeqRegion() throws IOException { + // Import all chromosomes + List chromosomes = Arrays.asList( + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + "12", + "13", + "14", + "15", + "16", + "17", + "18", + "19", + "20", + "21", + "22", + "23", + "24", + "X", + "Y", + "MT" + ); + for (String chromosome : chromosomes) { + SeqRegion seqRegion = new SeqRegion(); + seqRegion.setName(chromosome); + if (chromosome.equals("23")) { + seqRegion.setChromosome("X"); + } else if (chromosome.equals("24")) { + seqRegion.setChromosome("Y"); + } else { + seqRegion.setChromosome(chromosome); + } + seqRegionService.save(seqRegion); + } + List> seqRegions = readFile("seq_region.tsv", true); + for (List line : seqRegions) { + SeqRegion seqRegion = new SeqRegion(); + seqRegion.setName(line.get(0)); + if (line.size() >= 2) { + seqRegion.setChromosome(line.get(1)); + } + seqRegionService.save(seqRegion); + } + } + + private List> readFile(String filePath, boolean hasHeader) { + URL fileUrl = getClass().getClassLoader().getResource("data/transcript/ensembl/" + ENSEMBL_VERSION + "/" + filePath); + if (fileUrl == null) { + log.error("Cannot find the file"); + return null; + } + InputStream is = null; + try { + is = fileUrl.openStream(); + List> lines = readDelimitedLinesStream(is, "\\t", true); + if (hasHeader && lines.size() > 0) { + lines.remove(0); + } + return lines.stream().filter(line -> line.size() > 0 && !line.get(0).startsWith("#")).collect(Collectors.toList()); + } catch (IOException e) { + log.error("Fail to open file", e.getMessage()); + return new ArrayList<>(); + } + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/importer/GeneImporter.java b/src/main/java/org/mskcc/oncokb/curation/importer/GeneImporter.java new file mode 100644 index 000000000..d95a628d4 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/importer/GeneImporter.java @@ -0,0 +1,172 @@ +package org.mskcc.oncokb.curation.importer; + +import static org.mskcc.oncokb.curation.util.FileUtils.readTrimmedLinesStream; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.*; +import java.util.stream.Collectors; +import org.apache.commons.lang3.StringUtils; +import org.mskcc.oncokb.curation.domain.Flag; +import org.mskcc.oncokb.curation.domain.Gene; +import org.mskcc.oncokb.curation.domain.Synonym; +import org.mskcc.oncokb.curation.domain.enumeration.FlagType; +import org.mskcc.oncokb.curation.domain.enumeration.InfoType; +import org.mskcc.oncokb.curation.domain.enumeration.SynonymType; +import org.mskcc.oncokb.curation.service.FlagService; +import org.mskcc.oncokb.curation.service.GeneService; +import org.mskcc.oncokb.curation.service.InfoService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component +public class GeneImporter { + + private final Logger log = LoggerFactory.getLogger(GeneImporter.class); + private final String SYNONYM_SEPARATOR = "\\|"; + private final String GENE_FILE_PATH = "data/gene/cbioportal_v4/gene-info-Apr-11-2023.txt"; + private final String GENE_PANEL_FILE_PATH = "data/gene/all_gene_panels_09152023.txt"; + private final String GENE_VERSION = "v4"; + private final String GENE_VERSION_DATE = "2023-04-11"; // see allowed format https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html + + final InfoService infoService; + final GeneService geneService; + final FlagService flagService; + + public GeneImporter(InfoService infoService, GeneService geneService, FlagService flagService) { + this.infoService = infoService; + this.geneService = geneService; + this.flagService = flagService; + } + + private List getPortalGenes() { + URL geneFileUrl = getClass().getClassLoader().getResource(GENE_FILE_PATH); + List readmeFileLines; + try { + InputStream is = geneFileUrl.openStream(); + readmeFileLines = readTrimmedLinesStream(is); + } catch (IOException e) { + throw new RuntimeException(e); + } + + return readmeFileLines + .stream() + .map(line -> line.split("\t")) + .filter(line -> { + // as long as gene has entrez gene id and hugo symbol, we import + if (line.length >= 2) { + return StringUtils.isNumeric(line[0]) && Integer.parseInt(line[0]) > 0; + } else { + return false; + } + }) + .sorted(Comparator.comparingInt(o -> Integer.parseInt(o[0]))) + .collect(Collectors.toList()); + } + + public void importPortalGenes() { + List portalGenes = getPortalGenes(); + for (var i = 0; i < portalGenes.size(); i++) { + String[] line = portalGenes.get(i); + Integer entrezGeneId = Integer.parseInt(line[0]); + String hugoSymbol = line[1]; + Set geneSynonyms = new HashSet<>(); + + if (line.length > 5) { + geneSynonyms = Arrays.stream(line[5].split(SYNONYM_SEPARATOR)) + .filter(synonym -> StringUtils.isNotEmpty(synonym.trim())) + .map(synonym -> { + Synonym geneSynonym = new Synonym(); + geneSynonym.setName(synonym.trim()); + geneSynonym.setType(SynonymType.GENE.name()); + return geneSynonym; + }) + .collect(Collectors.toSet()); + } + + Optional geneOptional = this.geneService.findGeneByEntrezGeneId(entrezGeneId); + if (geneOptional.isPresent()) { + Gene gene = geneOptional.orElseThrow(); + gene.setHugoSymbol(hugoSymbol); + gene.setSynonyms(geneSynonyms); + this.geneService.partialUpdate(gene); + log.debug("Updated gene {}", gene); + } else { + Gene gene = new Gene(); + gene.setEntrezGeneId(entrezGeneId); + gene.setHugoSymbol(hugoSymbol); + gene.setSynonyms(geneSynonyms); + this.geneService.save(gene); + log.debug("Saved gene {}", gene); + } + if ((i + 1) % 1000 == 0) { + log.info("Saved/updated {} genes", i + 1); + } + } + + this.infoService.updateInfo(InfoType.GENE_VERSION, GENE_VERSION, GENE_VERSION_DATE); + } + + private List getGenePanels() { + URL fileUrl = getClass().getClassLoader().getResource(GENE_PANEL_FILE_PATH); + List readmeFileLines; + try { + InputStream is = fileUrl.openStream(); + readmeFileLines = readTrimmedLinesStream(is); + if (readmeFileLines.size() > 0) { + readmeFileLines.remove(0); + } else { + log.error("Empty gene panel file."); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + + return readmeFileLines.stream().map(line -> line.split("\t")).collect(Collectors.toList()); + } + + public void importGenePanels() { + List genePanels = getGenePanels(); + for (var i = 0; i < genePanels.size(); i++) { + String[] line = genePanels.get(i); + // as long as gene has entrez gene id or hugo symbol, we import + if (line.length < 2) { + log.error("The line does not have necessary data points {}", line); + } + String panel = line[0]; + Integer entrezGeneId = StringUtils.isEmpty(line[1]) ? null : Integer.parseInt(line[1]); + String hugoSymbol = line.length > 2 ? line[2] : null; + Optional geneFlagOptional = flagService.findByTypeAndFlag(FlagType.GENE_PANEL, panel); + if (geneFlagOptional.isEmpty()) { + log.error("Cannot find panel {}", panel); + continue; + } + Optional geneOptional = Optional.empty(); + if (entrezGeneId != null) { + geneOptional = geneService.findGeneByEntrezGeneId(entrezGeneId); + } else if (StringUtils.isNotEmpty(hugoSymbol)) { + List genes = geneService.findGeneByHugoSymbolOrGeneAliasesIn(hugoSymbol); + if (genes.size() > 0) { + geneOptional = Optional.of(genes.get(0)); + } + } + + if (geneOptional.isEmpty()) { + log.error("Cannot find gene {} {} {}", panel, entrezGeneId, hugoSymbol); + } else { + if (geneOptional.orElseThrow().getFlags().contains(geneFlagOptional.orElseThrow())) { + log.error("The gene flag already included {} {}", geneFlagOptional.orElseThrow().getFlag(), line); + } else { + geneOptional.orElseThrow().getFlags().add(geneFlagOptional.orElseThrow()); + geneService.partialUpdate(geneOptional.orElseThrow()); + } + } + + if ((i + 1) % 1000 == 0) { + log.info("Saved/updated {} panel genes", i + 1); + } + } + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/importer/Importer.java b/src/main/java/org/mskcc/oncokb/curation/importer/Importer.java new file mode 100644 index 000000000..46c7acc31 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/importer/Importer.java @@ -0,0 +1,176 @@ +package org.mskcc.oncokb.curation.importer; + +import java.io.IOException; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; +import org.mskcc.oncokb.curation.domain.Alteration; +import org.mskcc.oncokb.curation.domain.Consequence; +import org.mskcc.oncokb.curation.domain.EnsemblGene; +import org.mskcc.oncokb.curation.domain.Sequence; +import org.mskcc.oncokb.curation.domain.enumeration.AlterationType; +import org.mskcc.oncokb.curation.domain.enumeration.ReferenceGenome; +import org.mskcc.oncokb.curation.domain.enumeration.SequenceType; +import org.mskcc.oncokb.curation.service.*; +import org.mskcc.oncokb.curation.service.dto.TranscriptDTO; +import org.mskcc.oncokb.curation.service.mapper.TranscriptMapper; +import org.oncokb.ApiException; +import org.oncokb.client.Gene; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Component; + +/** + * Created by Hongxin Zhang on 1/27/21. + */ +@Component +public class Importer { + + @Autowired + private MetaImporter metaImporter; + + @Autowired + private CoreImporter coreImporter; + + @Autowired + private CdxImporter cdxImporter; + + @Autowired + private GeneImporter geneImporter; + + @Autowired + private TranscriptImporter transcriptImporter; + + @Autowired + private EnsemblImporter ensemblImporter; + + @Autowired + private OncoKbUrlService oncoKbUrlService; + + @Autowired + private GeneService geneService; + + @Autowired + private MainService mainService; + + @Autowired + private TranscriptService transcriptService; + + @Autowired + private TranscriptMapper transcriptMapper; + + @Autowired + private GenomeNexusService genomeNexusService; + + @Autowired + private EnsemblService ensemblService; + + @Autowired + private EnsemblGeneService ensemblGeneService; + + @Autowired + private SequenceService sequenceService; + + @Autowired + private AlignmentService alignmentService; + + @Autowired + private AlterationService alterationService; + + @Autowired + private ConsequenceService consequenceService; + + @Autowired + private FirebaseService firebaseService; + + private final Logger log = LoggerFactory.getLogger(Importer.class); + + public void generalImport() throws ApiException, IOException { + // this.geneImporter.importPortalGenes(); + // this.transcriptImporter.importCanonicalEnsemblGenes(); + // checkOncoKbTranscriptSequenceAcrossRG(); + // importAlteration(); + // this.transcriptImporter.importTranscripts(); + // this.ensemblImporter.importSeqRegion(); + this.metaImporter.generalImport(); + firebaseService.importDrugs(); + cdxImporter.importCdxMain(); + this.coreImporter.importArticle(); + // firebaseService.readGene(); + } + + private void checkOncoKbTranscriptSequenceAcrossRG() throws ApiException { + for (Gene gene : oncoKbUrlService.getGenes()) { + if (gene.getEntrezGeneId() <= 0) { + continue; + } + // check grch37 + Optional geneOptional = geneService.findGeneByEntrezGeneId(gene.getEntrezGeneId()); + if (geneOptional.isEmpty()) { + log.error("The OncoKB gene does not exist in transcript {}:{}", gene.getEntrezGeneId(), gene.getHugoSymbol()); + } else { + log.info("Checking gene {}:{}", gene.getEntrezGeneId(), gene.getHugoSymbol()); + Optional grch37TranscriptDtoOptional = transcriptService.findByReferenceGenomeAndEnsemblTranscriptId( + ReferenceGenome.GRCh37, + gene.getGrch37Isoform() + ); + Optional grch38TranscriptDtoOptional = transcriptService.findByReferenceGenomeAndEnsemblTranscriptId( + ReferenceGenome.GRCh38, + gene.getGrch38Isoform() + ); + + Optional sequenceGrch37Optional = Optional.empty(); + Optional sequenceGrch38Optional = Optional.empty(); + if (grch37TranscriptDtoOptional.isEmpty()) { + log.warn("\tNo GRCh37 transcript available"); + } else { + sequenceGrch37Optional = sequenceService.findOneByTranscriptAndSequenceType( + transcriptMapper.toEntity(grch37TranscriptDtoOptional.orElseThrow()), + SequenceType.PROTEIN + ); + if (sequenceGrch37Optional.isEmpty()) { + log.warn("\t\tNo GRCh37 transcript sequence"); + } + } + if (grch38TranscriptDtoOptional.isEmpty()) { + log.warn("\tNo GRCh38 transcript available"); + } else { + sequenceGrch38Optional = sequenceService.findOneByTranscriptAndSequenceType( + transcriptMapper.toEntity(grch38TranscriptDtoOptional.orElseThrow()), + SequenceType.PROTEIN + ); + if (sequenceGrch38Optional.isEmpty()) { + log.warn("\t\tNo GRCh38 transcript sequence"); + } + } + + if (sequenceGrch37Optional.isPresent() && sequenceGrch38Optional.isPresent()) { + if (sequenceGrch37Optional.orElseThrow().getSequence().equals(sequenceGrch38Optional.orElseThrow().getSequence())) { + log.info("\t\t Sequences match"); + } else { + log.warn("\t\t Sequences do not match"); + log.info( + "\t\t\t Alignment penalty {}", + alignmentService + .calcOptimalAlignment( + sequenceGrch37Optional.orElseThrow().getSequence(), + sequenceGrch38Optional.orElseThrow().getSequence(), + false + ) + .getPenalty() + ); + } + } + } + } + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/importer/MetaImporter.java b/src/main/java/org/mskcc/oncokb/curation/importer/MetaImporter.java new file mode 100644 index 000000000..bd1fc7124 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/importer/MetaImporter.java @@ -0,0 +1,622 @@ +package org.mskcc.oncokb.curation.importer; + +import static org.mskcc.oncokb.curation.config.Constants.DEFAULT_GENE_SYNONMN_SOURCE; +import static org.mskcc.oncokb.curation.config.DataVersions.NCIT_VERSION; +import static org.mskcc.oncokb.curation.util.FileUtils.parseDelimitedFile; + +import java.io.IOException; +import java.util.*; +import java.util.stream.Collectors; +import org.apache.commons.lang3.StringUtils; +import org.mskcc.oncokb.curation.config.application.ApplicationProperties; +import org.mskcc.oncokb.curation.domain.*; +import org.mskcc.oncokb.curation.domain.enumeration.*; +import org.mskcc.oncokb.curation.model.IntegerRange; +import org.mskcc.oncokb.curation.service.*; +import org.mskcc.oncokb.curation.service.dto.TranscriptDTO; +import org.mskcc.oncokb.curation.service.mapper.TranscriptMapper; +import org.mskcc.oncokb.curation.util.HotspotUtils; +import org.oncokb.ApiException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * Created by Hongxin Zhang on 1/27/21. + */ +@Component +public class MetaImporter { + + @Autowired + private GeneImporter geneImporter; + + @Autowired + private TranscriptImporter transcriptImporter; + + @Autowired + private EnsemblImporter ensemblImporter; + + @Autowired + private OncoKbUrlService oncoKbUrlService; + + @Autowired + private GeneService geneService; + + @Autowired + private MainService mainService; + + @Autowired + private TranscriptService transcriptService; + + @Autowired + private TranscriptMapper transcriptMapper; + + @Autowired + private GenomeNexusService genomeNexusService; + + @Autowired + private EnsemblService ensemblService; + + @Autowired + private EnsemblGeneService ensemblGeneService; + + @Autowired + private SequenceService sequenceService; + + @Autowired + private AlignmentService alignmentService; + + @Autowired + private AlterationService alterationService; + + @Autowired + private ConsequenceService consequenceService; + + @Autowired + private FlagService flagService; + + @Autowired + private CompanionDiagnosticDeviceService cdxService; + + @Autowired + private FdaSubmissionTypeService fdaSubmissionTypeService; + + @Autowired + private FdaSubmissionService fdaSubmissionService; + + @Autowired + private SeqRegionService seqRegionService; + + @Autowired + private GenomeFragmentService genomeFragmentService; + + @Autowired + private SynonymService synonymService; + + @Autowired + private CancerTypeService cancerTypeService; + + @Autowired + private DrugService drugService; + + @Autowired + private AssociationService associationService; + + @Autowired + private OncoTreeImporter oncoTreeImporter; + + @Autowired + private NciThesaurusService nciThesaurusService; + + @Autowired + private CoreImporter coreImporter; + + @Autowired + private GenomicIndicatorService genomicIndicatorService; + + @Autowired + private AlleleStateService alleleStateService; + + private final ApplicationProperties applicationProperties; + + private final Logger log = LoggerFactory.getLogger(MetaImporter.class); + + final String DATA_DIRECTORY; + final String META_DATA_FOLDER_PATH; + + public MetaImporter(ApplicationProperties applicationProperties) { + this.applicationProperties = applicationProperties; + + DATA_DIRECTORY = applicationProperties.getOncokbDataRepoDir() + "/curation"; + META_DATA_FOLDER_PATH = DATA_DIRECTORY + "/meta"; + } + + public void generalImport() throws ApiException, IOException { + log.info("Importing flag..."); + this.importFlag(); + + log.info("Importing FDA submission type..."); + this.importFdaSubmissionType(); + + log.info("Importing gene..."); + this.importGene(); + + log.info("Importing gene panel..."); + this.importGenePanelFlag(); + + log.info("Importing seq region..."); + this.importSeqRegion(); + + log.info("Importing ensembl gene..."); + this.importEnsemblGene(); + + log.info("Importing transcript..."); + this.importTranscript(); + + log.info("Importing transcript flag..."); + this.importTranscriptFlag(); + + log.info("Importing sequence..."); + this.importSequence(); + + log.info("Importing genome fragment..."); + this.importGenomeFragment(); + + log.info("Importing genomic indicator..."); + this.importGenomicIndicator(); + + log.info("Importing NCIT..."); + this.importNcit(); + + log.info("Importing core dataset..."); + coreImporter.generalImport(); + + log.info("Importing hotspots..."); + importHotspot(); + } + + private List fetchAndSaveHotspotAlteration(Gene gene, String altName) { + List existingAlts = alterationService.findByNameOrAlterationAndGenesId(altName, gene.getId()); + if (existingAlts.isEmpty()) { + Alteration alteration = new Alteration(); + alteration.setName(altName); + alteration.setAlteration(altName); + alteration.setProteinChange(altName); + alteration.setGenes(Collections.singleton(gene)); + mainService.annotateAlteration(ReferenceGenome.GRCh37, alteration); + return Collections.singletonList(alterationService.save(alteration)); + } else { + return existingAlts; + } + } + + private void importHotspot() throws IOException { + Flag hotspotFlag = flagService.findByTypeAndFlag(FlagType.HOTSPOT, HotspotFlagEnum.HOTSPOT_V1.name()).orElseThrow(); + Flag threeDFlag = flagService.findByTypeAndFlag(FlagType.HOTSPOT, HotspotFlagEnum.THREE_D.name()).orElseThrow(); + + List> hotspotLines = parseTsvMetaFile("cancer_hotspots_gn.tsv"); + hotspotLines.forEach(line -> { + String hugoSymbol = line.get(0); + log.info("Search for gene {}", hugoSymbol); + List geneList = geneService.findGeneByHugoSymbolOrGeneAliasesIn(hugoSymbol); + if (geneList.isEmpty()) { + log.error("Gene cannot be found {}", line.get(0)); + return; + } + Gene gene = geneList.iterator().next(); + + String type = line.get(3); + String residue = line.get(1); + + List alterations = new ArrayList<>(); + if ("splice residue".equals(type) || "splice site".equals(type)) { + String proteinChange = residue + "_splice"; + alterations.addAll(fetchAndSaveHotspotAlteration(gene, proteinChange)); + } else if ("in-frame indel".equals(type)) { + IntegerRange integerRange = HotspotUtils.extractProteinPos(residue); + String proteinName = integerRange.getStart() + "_" + integerRange.getEnd(); + alterations.addAll(fetchAndSaveHotspotAlteration(gene, proteinName + "ins")); + alterations.addAll(fetchAndSaveHotspotAlteration(gene, proteinName + "del")); + } else if ("single residue".equals(type) || "3d".equals(type)) { + alterations.addAll(fetchAndSaveHotspotAlteration(gene, residue)); + } else { + log.error("Unhandled type of hotspot {}", type); + } + for (Alteration alteration : alterations) { + if ("3d".equals(type)) { + alteration.addFlag(threeDFlag); + } else { + alteration.addFlag(hotspotFlag); + } + alterationService.save(alteration); + } + }); + } + + private void importFlag() throws IOException { + List> flagLines = parseTsvMetaFile("flag.tsv"); + flagLines.forEach(flagLine -> { + Flag flagEntity = new Flag(); + String type = flagLine.get(1); + String flag = flagLine.get(2); + String name = flagLine.get(3); + String description = flagLine.get(4); + flagEntity.setType(type); + flagEntity.setFlag(flag); + flagEntity.setName(name); + flagEntity.setDescription(description); + flagService.save(flagEntity); + }); + } + + private void importFdaSubmissionType() throws IOException { + List> lines = parseTsvMetaFile("fda_submission_type.tsv"); + lines.forEach(line -> { + FdaSubmissionType fdaSubmissionType = new FdaSubmissionType(); + String type = line.get(1); + String name = line.get(2); + String shortName = line.get(3); + String description = line.get(4); + fdaSubmissionType.setType(type == null ? null : FdaSubmissionTypeKey.valueOf(type)); + fdaSubmissionType.setName(name); + fdaSubmissionType.setShortName(shortName); + fdaSubmissionType.setDescription(description); + fdaSubmissionTypeService.save(fdaSubmissionType); + }); + } + + private void importGene() throws IOException { + List> lines = parseTsvMetaFile("gene_10_2023.tsv"); + for (int i = 0; i < lines.size(); i++) { + List line = lines.get(i); + Integer entrezGeneId = Integer.parseInt(line.get(0)); + String hugoSymbol = line.get(1); + + Gene gene = new Gene(); + gene.setEntrezGeneId(entrezGeneId); + gene.setHugoSymbol(hugoSymbol); + gene.setHgncId(Optional.ofNullable(line.get(6)).orElse("").replace("HGNC:", "")); + Gene savedGene = this.geneService.save(gene); + + Set savedSynonyms = new HashSet<>(); + Arrays.stream(Optional.ofNullable(line.get(5)).orElse("").split("\\|")) + .filter(synonym -> StringUtils.isNotEmpty(synonym.trim())) + .forEach(synonym -> { + String trimmedSynonym = synonym.trim(); + Optional synonymOptional = synonymService.findByTypeAndSourceAndName( + SynonymType.GENE, + DEFAULT_GENE_SYNONMN_SOURCE, + trimmedSynonym + ); + if (synonymOptional.isEmpty()) { + Synonym geneSynonym = new Synonym(); + geneSynonym.setName(synonym.trim()); + geneSynonym.setSource(DEFAULT_GENE_SYNONMN_SOURCE); + geneSynonym.setType(SynonymType.GENE.name()); + savedSynonyms.add(synonymService.save(geneSynonym)); + } else { + savedSynonyms.add(synonymOptional.orElseThrow()); + } + }); + savedGene.setSynonyms(savedSynonyms); + geneService.partialUpdate(savedGene); + log.debug("Saved gene {}", gene); + if ((i + 1) % 1000 == 0) { + log.info("Imported {}/{} gene", i + 1, lines.size()); + } + } + + // import special genes + Gene gene = new Gene(); + gene.setEntrezGeneId(-2); + gene.setHugoSymbol("Other Biomarkers"); + this.geneService.save(gene); + } + + private void importGenePanelFlag() throws IOException { + List> lines = parseTsvMetaFile("gene_panel_flag.tsv"); + lines.forEach(line -> { + if (StringUtils.isNotEmpty(line.get(2))) { + Integer entrezGeneId = Integer.parseInt(line.get(0)); + String flag = line.get(2); + + Optional geneOptional = geneService.findGeneByEntrezGeneId(entrezGeneId); + Optional flagOptional = flagService.findByTypeAndFlag(FlagType.GENE_PANEL, flag); + geneOptional.orElseThrow().getFlags().add(flagOptional.orElseThrow()); + geneService.partialUpdate(geneOptional.orElseThrow()); + } + }); + } + + private void importSeqRegion() throws IOException { + List> lines = parseTsvMetaFile("seq_region.tsv"); + lines.forEach(line -> { + SeqRegion seqRegion = new SeqRegion(); + seqRegion.setName(line.get(1)); + seqRegion.setChromosome(line.get(2)); + seqRegion.setDescription(line.get(3)); + seqRegionService.save(seqRegion); + }); + } + + private void importEnsemblGene() throws IOException { + List> lines = parseTsvMetaFile("ensembl_gene.tsv"); + for (int i = 0; i < lines.size(); i++) { + List line = lines.get(i); + EnsemblGene ensemblGene = new EnsemblGene(); + Optional geneOptional = geneService.findGeneByEntrezGeneId(Integer.parseInt(line.get(0))); + if (geneOptional.isEmpty()) { + log.error("Can't find gene {}", line.get(0)); + continue; + } + ensemblGene.setGene(geneOptional.orElseThrow()); + ensemblGene.setReferenceGenome(ReferenceGenome.valueOf(line.get(2))); + ensemblGene.setEnsemblGeneId(line.get(3)); + ensemblGene.setCanonical(Boolean.valueOf(line.get(4))); + Optional seqRegionOptional = seqRegionService.findByName(line.get(5)); + ensemblGene.setSeqRegion(seqRegionOptional.orElseThrow()); + ensemblGene.setStart(Integer.valueOf(line.get(6))); + ensemblGene.setEnd(Integer.valueOf(line.get(7))); + ensemblGene.setStrand(Integer.valueOf(line.get(8))); + ensemblGeneService.save(ensemblGene); + if ((i + 1) % 1000 == 0) { + log.info("Imported {}/{} ensembl gene", i + 1, lines.size()); + } + } + } + + private void importGenomeFragment() throws IOException { + List> lines = parseTsvMetaFile("genome_fragment.tsv"); + for (int i = 0; i < lines.size(); i++) { + List line = lines.get(i); + GenomeFragment genomeFragment = new GenomeFragment(); + Optional ensemblGeneOptional = ensemblGeneService.findByEnsemblGeneIdAndReferenceGenome( + line.get(3), + ReferenceGenome.valueOf(line.get(2)) + ); + if (ensemblGeneOptional.isEmpty()) { + log.error("Cannot find ensembl gene {} {}", line.get(3), ReferenceGenome.valueOf(line.get(2))); + continue; + } + Optional transcriptOptional = transcriptService.findByEnsemblGeneAndEnsemblTranscriptId( + ensemblGeneOptional.orElseThrow(), + line.get(4) + ); + if (transcriptOptional.isEmpty()) { + log.error("Can't find transcript {}", line.get(4)); + continue; + } + genomeFragment.setTranscript(transcriptMapper.toEntity(transcriptOptional.orElseThrow())); + genomeFragment.setType(GenomeFragmentType.valueOf(line.get(5))); + Optional seqRegionOptional = seqRegionService.findByName(line.get(6)); + genomeFragment.setSeqRegion(seqRegionOptional.orElseThrow()); + genomeFragment.setStart(Integer.parseInt(line.get(7))); + genomeFragment.setEnd(Integer.parseInt(line.get(8))); + genomeFragment.setStrand(Integer.parseInt(line.get(9))); + genomeFragmentService.save(genomeFragment); + if ((i + 1) % 1000 == 0) { + log.info("Imported {}/{} genome fragment", i + 1, lines.size()); + } + } + } + + private void importGenomicIndicator() throws IOException { + List> lines = parseTsvMetaFile("genomic_indicator.tsv"); + for (int i = 0; i < lines.size(); i++) { + List line = lines.get(i); + + Optional existingGIOptional = genomicIndicatorService.findByTypeAndName( + GenomicIndicatorType.GERMLINE, + line.get(3) + ); + if (existingGIOptional.isEmpty()) { + GenomicIndicator genomicIndicator = new GenomicIndicator(); + genomicIndicator.setType(GenomicIndicatorType.GERMLINE.name()); + genomicIndicator.setUuid(line.get(5)); + genomicIndicator.setName(line.get(3)); + genomicIndicator = genomicIndicatorService.save(genomicIndicator); + if (StringUtils.isNotEmpty(line.get(4))) { + Set alleleStateList = Arrays.stream(line.get(4).split(",")) + .map(alleleState -> alleleStateService.findByNameIgnoreCase(alleleState.trim()).orElseThrow()) + .collect(Collectors.toSet()); + genomicIndicator.setAlleleStates(alleleStateList); + genomicIndicatorService.partialUpdate(genomicIndicator); + } + existingGIOptional = Optional.of(genomicIndicatorService.save(genomicIndicator)); + } + + Optional geneOptional = geneService.findGeneByHugoSymbol(line.get(0)); + if (geneOptional.isEmpty()) { + log.error("Cannot find the gene {}", line.get(0)); + continue; + } + Alteration alteration; + List alterationList = alterationService.findByNameOrAlterationAndGenesId( + line.get(1), + geneOptional.orElseThrow().getId() + ); + if (alterationList.isEmpty()) { + log.warn("Cannot find alteration {} in {}, will create a new one.", line.get(1), line.get(0)); + Alteration newAlt = new Alteration(); + newAlt.setGenes(Collections.singleton(geneOptional.orElseThrow())); + newAlt.setAlteration(line.get(1)); + newAlt.setType(AlterationType.ANY); + newAlt.setProteinChange(line.get(2)); + alteration = alterationService.save(newAlt); + } else { + alteration = alterationList.get(0); + if (alterationList.size() > 1) { + log.warn("Multiple alteration matches found, picked the first match"); + } + } + + if (alteration != null) { + Association association = new Association(); + association.setAlterations(Collections.singleton(alteration)); + existingGIOptional.orElseThrow().setAssociations(Collections.singleton(association)); + genomicIndicatorService.partialUpdate(existingGIOptional.orElseThrow()); + } + } + } + + private void importTranscript() throws IOException { + List> lines = parseTsvMetaFile("transcript.tsv"); + for (int i = 0; i < lines.size(); i++) { + List line = lines.get(i); + Transcript transcript = new Transcript(); + Optional geneOptional = geneService.findGeneByEntrezGeneId(Integer.parseInt(line.get(0))); + if (geneOptional.isEmpty()) { + log.error("Can't find gene {}", line.get(0)); + continue; + } + transcript.setGene(geneOptional.orElseThrow()); + Optional ensemblGeneOptional = ensemblGeneService.findByEnsemblGeneIdAndReferenceGenome( + line.get(3), + ReferenceGenome.valueOf(line.get(2)) + ); + if (ensemblGeneOptional.isEmpty()) { + log.error("Error find ensembl gene {} {}", line.get(2), line.get(3)); + continue; + } + transcript.setReferenceGenome(ReferenceGenome.valueOf(line.get(2))); + transcript.setEnsemblGene(ensemblGeneOptional.orElseThrow()); + + transcript.setEnsemblTranscriptId(line.get(4)); + transcript.setCanonical(Boolean.valueOf(line.get(5))); + transcript.setEnsemblProteinId(line.get(6)); + transcript.setReferenceSequenceId(line.get(7)); + transcript.setDescription(line.get(8)); + transcriptService.save(transcript); + if ((i + 1) % 1000 == 0) { + log.info("Imported {}/{} transcript", i + 1, lines.size()); + } + } + } + + private void importTranscriptFlag() throws IOException { + List> lines = parseTsvMetaFile("transcript_flag.tsv"); + for (int i = 0; i < lines.size(); i++) { + List line = lines.get(i); + if (StringUtils.isNotEmpty(line.get(5))) { + String referenceGenome = line.get(2); + String transcriptId = line.get(4); + String flag = line.get(5); + + Optional transcriptOptional = transcriptService.findByReferenceGenomeAndEnsemblTranscriptId( + ReferenceGenome.valueOf(referenceGenome), + transcriptId + ); + if (transcriptOptional.isEmpty()) { + log.error("Error find transcript {} {}", referenceGenome, transcriptId); + continue; + } + Optional flagOptional = flagService.findByTypeAndFlag(FlagType.TRANSCRIPT, flag); + transcriptOptional.orElseThrow().getFlags().add(flagOptional.orElseThrow()); + if (TranscriptFlagEnum.ONCOKB.name().equals(flag)) { + transcriptOptional.orElseThrow().setCanonical(true); + } + transcriptService.partialUpdate(transcriptOptional.orElseThrow()); + } + if ((i + 1) % 1000 == 0) { + log.info("Imported {}/{} transcript flag", i + 1, lines.size()); + } + } + } + + private void importSequence() throws IOException { + List> lines = parseTsvMetaFile("sequence.tsv"); + for (int i = 0; i < lines.size(); i++) { + List line = lines.get(i); + Sequence sequence = new Sequence(); + Optional ensemblGeneOptional = ensemblGeneService.findByEnsemblGeneIdAndReferenceGenome( + line.get(3), + ReferenceGenome.valueOf(line.get(2)) + ); + if (ensemblGeneOptional.isEmpty()) { + log.error("Error find ensembl gene {} {}", line.get(2), line.get(3)); + continue; + } + Optional transcriptOptional = transcriptService.findByEnsemblGeneAndEnsemblTranscriptId( + ensemblGeneOptional.orElseThrow(), + line.get(4) + ); + if (transcriptOptional.isEmpty()) { + log.error("Error find transcript {}", line.get(4)); + continue; + } + sequence.setTranscript(transcriptMapper.toEntity(transcriptOptional.orElseThrow())); + sequence.setSequenceType(SequenceType.valueOf(line.get(5))); + sequence.setSequence(line.get(6)); + sequenceService.save(sequence); + if ((i + 1) % 1000 == 0) { + log.info("Imported {}/{} sequence", i + 1, lines.size()); + } + } + } + + public void saveAllNcitData(List> lines) { + String SYNONYMS_SEPARATOR_REGEX = "\\|"; + for (int i = 0; i < lines.size(); i++) { + List line = lines.get(i); + Optional nciThesaurusOptional = nciThesaurusService.findByCode(line.get(0)); + if (nciThesaurusOptional.isPresent()) { + continue; + } + NciThesaurus nciThesaurus = new NciThesaurus(); + nciThesaurus.setCode(line.get(0)); + nciThesaurus.setDisplayName(line.get(5)); + nciThesaurus.setVersion(NCIT_VERSION); + + List synonymStrs = new ArrayList<>( + Arrays.asList((Optional.ofNullable(line.get(3)).orElse("")).split(SYNONYMS_SEPARATOR_REGEX)) + ); + if (synonymStrs.size() > 0) { + nciThesaurus.setPreferredName(synonymStrs.remove(0)); + if (StringUtils.isEmpty(nciThesaurus.getDisplayName())) { + nciThesaurus.setDisplayName(nciThesaurus.getPreferredName()); + } + } else { + nciThesaurus.setPreferredName(nciThesaurus.getDisplayName()); + } + Set synonyms = synonymStrs + .stream() + .map(synonymStr -> synonymStr.trim()) + .distinct() + .map(synonymStr -> { + Synonym synonym = new Synonym(); + synonym.setType(SynonymType.NCIT.name()); + synonym.setName(synonymStr); + synonym.setSource("NCIT"); + return synonym; + }) + .map(synonym -> { + Optional synonymOptional = synonymService.findByTypeAndSourceAndName( + SynonymType.NCIT, + "NCIT", + synonym.getName() + ); + if (synonymOptional.isEmpty()) { + return synonymService.save(synonym); + } else { + return synonymOptional.orElseThrow(); + } + }) + .collect(Collectors.toSet()); + nciThesaurus.setSynonyms(synonyms); + nciThesaurusService.save(nciThesaurus); + if ((i + 1) % 1000 == 0) { + log.info("Imported {}/{} NCIT", i + 1, lines.size()); + } + } + } + + public void importNcit() throws IOException { + List> lines = parseDelimitedFile(DATA_DIRECTORY + "/ncit/Thesaurus_" + NCIT_VERSION + ".tsv", "\t", true); + saveAllNcitData(lines); + } + + private List> parseTsvMetaFile(String fileName) throws IOException { + return parseDelimitedFile(META_DATA_FOLDER_PATH + "/" + fileName, "\t", true); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/importer/OncoTreeImporter.java b/src/main/java/org/mskcc/oncokb/curation/importer/OncoTreeImporter.java new file mode 100644 index 000000000..dfd7bf400 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/importer/OncoTreeImporter.java @@ -0,0 +1,109 @@ +package org.mskcc.oncokb.curation.importer; + +import static org.mskcc.oncokb.curation.util.CancerTypeUtils.getTumorForm; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import java.io.*; +import java.util.*; +import java.util.stream.Collectors; +import org.apache.commons.lang3.StringUtils; +import org.mskcc.oncokb.curation.config.application.ApplicationProperties; +import org.mskcc.oncokb.curation.domain.CancerType; +import org.mskcc.oncokb.curation.domain.enumeration.TumorForm; +import org.mskcc.oncokb.curation.importer.model.OncotreeCancerType; +import org.mskcc.oncokb.curation.service.CancerTypeService; +import org.mskcc.oncokb.curation.util.enumeration.SpecialCancerType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component +public class OncoTreeImporter { + + private final Logger log = LoggerFactory.getLogger(OncoTreeImporter.class); + final CancerTypeService cancerTypeService; + final ApplicationProperties applicationProperties; + final String FILE_PATH; + final String MIXED = "MIXED"; + + public OncoTreeImporter(CancerTypeService cancerTypeService, ApplicationProperties applicationProperties) { + this.cancerTypeService = cancerTypeService; + this.applicationProperties = applicationProperties; + + FILE_PATH = applicationProperties.getOncokbDataRepoDir() + "/curation/oncotree/oncotree_2019_12_01.json"; + } + + public void generalImport() throws FileNotFoundException { + Gson gson = new GsonBuilder().create(); + File file = new File(FILE_PATH); + InputStream is = new FileInputStream(file); + + // import special types + Arrays.stream(SpecialCancerType.values()).forEach(specialCancerType -> { + CancerType cancerType = new CancerType(); + cancerType.setLevel(-1); + cancerType.setCode(specialCancerType.name()); + cancerType.setMainType(specialCancerType.getTumorType()); + cancerType.setTumorForm(getTumorForm(specialCancerType)); + cancerType.setColor(MIXED); + cancerType.setTissue(MIXED); + cancerTypeService.save(cancerType); + }); + + // Import subtypes + OncotreeCancerType[] oncotreeCancerTypes = gson.fromJson(new BufferedReader(new InputStreamReader(is)), OncotreeCancerType[].class); + List cancerTypes = new ArrayList<>(); + Arrays.stream(oncotreeCancerTypes) + .sorted(Comparator.comparing(OncotreeCancerType::getLevel)) + .forEach(oncotreeCancerType -> { + CancerType cancerType = new CancerType(); + cancerType.setCode(oncotreeCancerType.getCode()); + cancerType.setColor(oncotreeCancerType.getColor()); + cancerType.setSubtype(oncotreeCancerType.getName()); + cancerType.setMainType(Optional.ofNullable(oncotreeCancerType.getMainType()).orElse(oncotreeCancerType.getName())); + cancerType.setTissue(oncotreeCancerType.getTissue()); + cancerType.setLevel(oncotreeCancerType.getLevel()); + if (cancerType.getLevel() == null) { + log.error("No level associated {}", oncotreeCancerType); + } else { + if (cancerType.getLevel() == 0) { + cancerType.setTumorForm(TumorForm.MIXED); + } else { + cancerType.setTumorForm(getTumorForm(cancerType.getTissue())); + } + if (StringUtils.isNotEmpty(oncotreeCancerType.getParent())) { + Optional parentNodeOptional = cancerTypeService.findOneByCode(oncotreeCancerType.getParent()); + if (parentNodeOptional.isEmpty()) { + log.error("Cannot find the parent node {}", oncotreeCancerType.getParent()); + } else { + cancerType.setParent(parentNodeOptional.orElseThrow()); + } + } + cancerTypes.add(cancerTypeService.save(cancerType)); + } + }); + + // Import main types + cancerTypes + .stream() + .map(CancerType::getMainType) + .collect(Collectors.toSet()) + .forEach(maintype -> { + List subtypes = cancerTypeService.findAllByMainTypeIs(maintype); + Set colors = subtypes.stream().map(CancerType::getColor).collect(Collectors.toSet()); + String color = colors.size() > 1 ? MIXED : Optional.ofNullable(colors.iterator().next()).orElse(""); + + Set tissues = subtypes.stream().map(CancerType::getTissue).collect(Collectors.toSet()); + String tissue = tissues.size() > 1 ? MIXED : Optional.ofNullable(tissues.iterator().next()).orElse(""); + + CancerType cancerType = new CancerType(); + cancerType.setLevel(0); + cancerType.setMainType(maintype); + cancerType.setColor(color); + cancerType.setTissue(tissue); + cancerType.setTumorForm(getTumorForm(new HashSet<>(subtypes))); + cancerTypeService.save(cancerType); + }); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/importer/TranscriptImporter.java b/src/main/java/org/mskcc/oncokb/curation/importer/TranscriptImporter.java new file mode 100644 index 000000000..ff23a5cd8 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/importer/TranscriptImporter.java @@ -0,0 +1,308 @@ +package org.mskcc.oncokb.curation.importer; + +import static org.mskcc.oncokb.curation.util.FileUtils.readDelimitedLinesStream; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.*; +import java.util.stream.Collectors; +import org.apache.commons.lang3.StringUtils; +import org.genome_nexus.ApiException; +import org.genome_nexus.client.EnsemblTranscript; +import org.mskcc.oncokb.curation.domain.Gene; +import org.mskcc.oncokb.curation.domain.enumeration.InfoType; +import org.mskcc.oncokb.curation.domain.enumeration.ReferenceGenome; +import org.mskcc.oncokb.curation.domain.enumeration.TranscriptFlagEnum; +import org.mskcc.oncokb.curation.importer.model.ManeTranscript; +import org.mskcc.oncokb.curation.importer.model.OncokbTranscript; +import org.mskcc.oncokb.curation.service.*; +import org.mskcc.oncokb.curation.service.dto.TranscriptDTO; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Component; + +// To import transcript info and sequence form Ensembl for both GRCh37 and 38 +@Component +public class TranscriptImporter { + + private final Logger log = LoggerFactory.getLogger(TranscriptImporter.class); + final String MANE_FILE_PATH = "data/transcript/mane/MANE.GRCh38.v1.2.summary.txt"; + final String MANE_VERSION = "v1.2"; + final String MANE_VERSION_DATE = "2023-01-01"; + + final String ONCOKB_FILE_PATH = "data/transcript/oncokb_transcript_v4_8.tsv"; + final String ONCOKB_VERSION = "v4.8"; + final String ONCOKB_VERSION_DATE = "2023-01-01"; + final GeneService geneService; + + final GenomeNexusService genomeNexusService; + final EnsemblGeneService ensemblGeneService; + final TranscriptService transcriptService; + final FlagService flagService; + final InfoService infoService; + final MainService mainService; + + public TranscriptImporter( + GeneService geneService, + GenomeNexusService genomeNexusService, + EnsemblGeneService ensemblGeneService, + TranscriptService transcriptService, + FlagService flagService, + InfoService infoService, + MainService mainService + ) { + this.geneService = geneService; + this.genomeNexusService = genomeNexusService; + this.ensemblGeneService = ensemblGeneService; + this.transcriptService = transcriptService; + this.flagService = flagService; + this.infoService = infoService; + this.mainService = mainService; + } + + private List getManeTranscript() { + URL geneFileUrl = getClass().getClassLoader().getResource(MANE_FILE_PATH); + try { + InputStream is = geneFileUrl.openStream(); + return readDelimitedLinesStream(is, "\t", true) + .stream() + .filter(line -> line.size() > 0 && !line.get(0).startsWith("#")) + .map(line -> { + ManeTranscript maneTranscript = new ManeTranscript(); + if (line.size() < 10) { + log.error("Line does not have all required columns {}", line); + } else { + maneTranscript.setEntrezGeneId(Integer.parseInt(line.get(0).replace("GeneID:", ""))); + maneTranscript.setEnsemblGeneId(line.get(1)); + maneTranscript.setHugoSymbol(line.get(4)); + maneTranscript.setRefSeqTranscriptId(line.get(5)); + maneTranscript.setRefSeqProteinId(line.get(6)); + maneTranscript.setEnsemblTranscriptId(line.get(7)); + maneTranscript.setEnsemblProteinId(line.get(8)); + maneTranscript.setManeStatus(line.get(9)); + } + return maneTranscript; + }) + .collect(Collectors.toList()); + } catch (IOException e) { + log.error(e.getMessage()); + return new ArrayList<>(); + } + } + + private List getOncokbTranscript() { + URL geneFileUrl = getClass().getClassLoader().getResource(ONCOKB_FILE_PATH); + try { + InputStream is = geneFileUrl.openStream(); + return readDelimitedLinesStream(is, "\t", true) + .stream() + .filter(line -> line.size() > 0 && StringUtils.isNumeric(line.get(0)) && Integer.parseInt(line.get(0)) > 0) + .map(line -> { + OncokbTranscript oncokbTranscript = new OncokbTranscript(); + oncokbTranscript.setEntrezGeneId(Integer.parseInt(line.get(0))); + if (line.size() >= 3) { + oncokbTranscript.setGrch37EnsemblTranscript(line.get(2)); + if (line.size() >= 4) { + oncokbTranscript.setGrch37refSeq(line.get(3)); + if (line.size() >= 5) { + oncokbTranscript.setGrch38EnsemblTranscript(line.get(4)); + if (line.size() >= 6) { + oncokbTranscript.setGrch38refSeq(line.get(5)); + } + } + } + } + return oncokbTranscript; + }) + .collect(Collectors.toList()); + } catch (IOException e) { + log.error(e.getMessage()); + return new ArrayList<>(); + } + } + + public void importCanonicalEnsemblGenes() { + int pageSize = 10; + final PageRequest pageable = PageRequest.of(0, pageSize); + Page firstPageGeneIds = geneService.findAllGeneIds(pageable); + List allGenes = new ArrayList<>(); + for (int i = 0; i < firstPageGeneIds.getTotalPages(); i++) { + PageRequest genePage = PageRequest.of(i, pageSize); + Page pageGeneIds = geneService.findAllGeneIds(genePage); + allGenes.addAll(geneService.findAllByIdInWithGeneAliasAndEnsemblGenes(pageGeneIds.getContent())); + } + for (ReferenceGenome rg : ReferenceGenome.values()) { + for (org.mskcc.oncokb.curation.domain.Gene gene : allGenes) { + mainService.createCanonicalEnsemblGene(rg, gene.getEntrezGeneId()); + } + } + } + + public void importTranscripts() { + // import GN canonical(uniport) transcripts for 37/38 + int pageSize = 10; + final PageRequest pageable = PageRequest.of(0, pageSize); + Page firstPageGeneIds = geneService.findAllGeneIds(pageable); + + for (int i = 0; i < firstPageGeneIds.getTotalPages(); i++) { + PageRequest genePage = PageRequest.of(i, pageSize); + Page geneIdPage = geneService.findAllGeneIds(genePage); + for (Gene gene : geneService.findAllByIdInWithGeneAliasAndEnsemblGenes(geneIdPage.getContent())) { + log.info("Saving GN canonical for gene {} {}", gene.getEntrezGeneId(), gene.getHugoSymbol()); + Arrays.asList(new ReferenceGenome[] { ReferenceGenome.GRCh37, ReferenceGenome.GRCh38 }).forEach(referenceGenome -> { + try { + org.genome_nexus.client.EnsemblGene gnEnsemblGene = genomeNexusService.findCanonicalEnsemblGeneTranscript( + referenceGenome, + gene.getEntrezGeneId() + ); + if (gnEnsemblGene != null) { + EnsemblTranscript gnEnsemblTranscript = genomeNexusService.findCanonicalEnsemblTranscript( + referenceGenome, + gene.getHugoSymbol() + ); + Optional transcriptDTOOptional = mainService.createTranscript( + referenceGenome, + gnEnsemblTranscript.getTranscriptId(), + gene.getEntrezGeneId(), + // do not pass protein id when on GRCh37. We assume the GRCh37 version has the only one transcript, and we can save the subversion + ReferenceGenome.GRCh37.equals(referenceGenome) ? null : gnEnsemblTranscript.getProteinId(), + gnEnsemblTranscript.getRefseqMrnaId(), + null, + Collections.singletonList(TranscriptFlagEnum.GN_CANONICAL) + ); + if (transcriptDTOOptional.isEmpty()) { + log.error( + "Failed to create transcript {} {} {}", + referenceGenome, + gene.getEntrezGeneId(), + gnEnsemblTranscript.getTranscriptId() + ); + } else { + log.info("Saved/updated for {}.", referenceGenome); + } + } else { + log.error( + "Failed to find canonical ensemble gene id {} {} {}", + referenceGenome, + gene.getEntrezGeneId(), + gene.getHugoSymbol() + ); + } + } catch (ApiException e) { + log.error( + "Failed to find canonical ensemble gene id {} {} {}", + referenceGenome, + gene.getEntrezGeneId(), + gene.getHugoSymbol() + ); + } + }); + } + } + + // import MANE 38 + for (ManeTranscript maneTranscript : getManeTranscript()) { + log.info("Saving MANE transcript {} ", maneTranscript); + ReferenceGenome referenceGenome = ReferenceGenome.GRCh38; + Optional geneOptional = geneService.findGeneByEntrezGeneId(maneTranscript.getEntrezGeneId()); + if (geneOptional.isEmpty()) { + log.warn("Gene {} in MANE list cannot be found in DB", maneTranscript.getEntrezGeneId()); + continue; + } + try { + org.genome_nexus.client.EnsemblGene gnEnsemblGene = genomeNexusService.findCanonicalEnsemblGeneTranscript( + referenceGenome, + maneTranscript.getEntrezGeneId() + ); + if (gnEnsemblGene != null) { + String maneStatus = maneTranscript.getManeStatus(); + Optional transcriptDTOOptional = Optional.empty(); + if ("MANE Select".equals(maneStatus)) { + transcriptDTOOptional = mainService.createTranscript( + referenceGenome, + maneTranscript.getEnsemblTranscriptId(), + maneTranscript.getEntrezGeneId(), + maneTranscript.getEnsemblProteinId(), + maneTranscript.getRefSeqTranscriptId(), + null, + Collections.singletonList(TranscriptFlagEnum.MANE_SELECT) + ); + } else if ("MANE Plus Clinical".equals(maneStatus)) { + transcriptDTOOptional = mainService.createTranscript( + referenceGenome, + maneTranscript.getEnsemblTranscriptId(), + maneTranscript.getEntrezGeneId(), + maneTranscript.getEnsemblProteinId(), + maneTranscript.getRefSeqTranscriptId(), + null, + Collections.singletonList(TranscriptFlagEnum.MANE_PLUS_CLINICAL) + ); + } + if (transcriptDTOOptional.isEmpty()) { + log.error("Failed to create MANE transcript {}", maneTranscript); + } else { + log.info("Saved/updated."); + } + } + } catch (ApiException e) { + log.error( + "Failed to find canonical ensemble gene id {} {} {}", + referenceGenome, + maneTranscript.getEntrezGeneId(), + maneTranscript.getHugoSymbol() + ); + } + } + this.infoService.updateInfo(InfoType.MANE_TRANSCRIPT_VERSION, MANE_VERSION, MANE_VERSION_DATE); + + // import OncoKB canonical 37/38 + for (OncokbTranscript oncokbTranscript : getOncokbTranscript()) { + log.info("Saving OncoKB transcript {}", oncokbTranscript); + Optional geneOptional = geneService.findGeneByEntrezGeneId(oncokbTranscript.getEntrezGeneId()); + if (geneOptional.isEmpty()) { + log.error("Cannot find gene {} from OncoKB list", oncokbTranscript.getEntrezGeneId()); + continue; + } + Optional transcriptDTOOptional = mainService.createTranscript( + ReferenceGenome.GRCh37, + oncokbTranscript.getGrch37EnsemblTranscript(), + oncokbTranscript.getEntrezGeneId(), + null, + oncokbTranscript.getGrch37refSeq(), + null, + Collections.singletonList(TranscriptFlagEnum.ONCOKB) + ); + if (transcriptDTOOptional.isEmpty()) { + log.error( + "Failed to create OncoKB transcript {} {}", + oncokbTranscript.getEntrezGeneId(), + oncokbTranscript.getGrch37EnsemblTranscript() + ); + } else { + log.info("Saved/updated grch37."); + } + transcriptDTOOptional = mainService.createTranscript( + ReferenceGenome.GRCh38, + oncokbTranscript.getGrch38EnsemblTranscript(), + oncokbTranscript.getEntrezGeneId(), + null, + oncokbTranscript.getGrch38refSeq(), + null, + Collections.singletonList(TranscriptFlagEnum.ONCOKB) + ); + if (transcriptDTOOptional.isEmpty()) { + log.error( + "Failed to create OncoKB transcript {} {}", + oncokbTranscript.getEntrezGeneId(), + oncokbTranscript.getGrch37EnsemblTranscript() + ); + } else { + log.info("Saved/updated grch38."); + } + } + this.infoService.updateInfo(InfoType.ONCOKB_TRANSCRIPT_VERSION, ONCOKB_VERSION, ONCOKB_VERSION_DATE); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/importer/model/ManeTranscript.java b/src/main/java/org/mskcc/oncokb/curation/importer/model/ManeTranscript.java new file mode 100644 index 000000000..dc56e64d0 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/importer/model/ManeTranscript.java @@ -0,0 +1,108 @@ +package org.mskcc.oncokb.curation.importer.model; + +public class ManeTranscript { + + Integer entrezGeneId; + String hugoSymbol; + String ensemblGeneId; + String refSeqTranscriptId; + String refSeqProteinId; + String ensemblTranscriptId; + String ensemblProteinId; + String maneStatus; + + public Integer getEntrezGeneId() { + return entrezGeneId; + } + + public void setEntrezGeneId(Integer entrezGeneId) { + this.entrezGeneId = entrezGeneId; + } + + public String getHugoSymbol() { + return hugoSymbol; + } + + public void setHugoSymbol(String hugoSymbol) { + this.hugoSymbol = hugoSymbol; + } + + public String getEnsemblGeneId() { + return ensemblGeneId; + } + + public void setEnsemblGeneId(String ensemblGeneId) { + this.ensemblGeneId = ensemblGeneId; + } + + public String getRefSeqTranscriptId() { + return refSeqTranscriptId; + } + + public void setRefSeqTranscriptId(String refSeqTranscriptId) { + this.refSeqTranscriptId = refSeqTranscriptId; + } + + public String getRefSeqProteinId() { + return refSeqProteinId; + } + + public void setRefSeqProteinId(String refSeqProteinId) { + this.refSeqProteinId = refSeqProteinId; + } + + public String getEnsemblTranscriptId() { + return ensemblTranscriptId; + } + + public void setEnsemblTranscriptId(String ensemblTranscriptId) { + this.ensemblTranscriptId = ensemblTranscriptId; + } + + public String getEnsemblProteinId() { + return ensemblProteinId; + } + + public void setEnsemblProteinId(String ensemblProteinId) { + this.ensemblProteinId = ensemblProteinId; + } + + public String getManeStatus() { + return maneStatus; + } + + public void setManeStatus(String maneStatus) { + this.maneStatus = maneStatus; + } + + @Override + public String toString() { + return ( + "ManeTranscript{" + + "entrezGeneId=" + + entrezGeneId + + ", hugoSymbol='" + + hugoSymbol + + '\'' + + ", ensemblGeneId='" + + ensemblGeneId + + '\'' + + ", refSeqTranscriptId='" + + refSeqTranscriptId + + '\'' + + ", refSeqProteinId='" + + refSeqProteinId + + '\'' + + ", ensemblTranscriptId='" + + ensemblTranscriptId + + '\'' + + ", ensemblProteinId='" + + ensemblProteinId + + '\'' + + ", maneStatus='" + + maneStatus + + '\'' + + '}' + ); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/importer/model/OncokbTranscript.java b/src/main/java/org/mskcc/oncokb/curation/importer/model/OncokbTranscript.java new file mode 100644 index 000000000..a723677e4 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/importer/model/OncokbTranscript.java @@ -0,0 +1,74 @@ +package org.mskcc.oncokb.curation.importer.model; + +public class OncokbTranscript { + + Integer entrezGeneId; + String grch37refSeq; + String grch37EnsemblTranscript; + String grch38refSeq; + String grch38EnsemblTranscript; + + public OncokbTranscript() {} + + public Integer getEntrezGeneId() { + return entrezGeneId; + } + + public void setEntrezGeneId(Integer entrezGeneId) { + this.entrezGeneId = entrezGeneId; + } + + public String getGrch37refSeq() { + return grch37refSeq; + } + + public void setGrch37refSeq(String grch37refSeq) { + this.grch37refSeq = grch37refSeq; + } + + public String getGrch37EnsemblTranscript() { + return grch37EnsemblTranscript; + } + + public void setGrch37EnsemblTranscript(String grch37EnsemblTranscript) { + this.grch37EnsemblTranscript = grch37EnsemblTranscript; + } + + public String getGrch38refSeq() { + return grch38refSeq; + } + + public void setGrch38refSeq(String grch38refSeq) { + this.grch38refSeq = grch38refSeq; + } + + public String getGrch38EnsemblTranscript() { + return grch38EnsemblTranscript; + } + + public void setGrch38EnsemblTranscript(String grch38EnsemblTranscript) { + this.grch38EnsemblTranscript = grch38EnsemblTranscript; + } + + @Override + public String toString() { + return ( + "OncokbTranscript{" + + "entrezGeneId=" + + entrezGeneId + + ", grch37refSeq='" + + grch37refSeq + + '\'' + + ", grch37EnsemblTranscript='" + + grch37EnsemblTranscript + + '\'' + + ", grch38refSeq='" + + grch38refSeq + + '\'' + + ", grch38EnsemblTranscript='" + + grch38EnsemblTranscript + + '\'' + + '}' + ); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/importer/model/OncotreeCancerType.java b/src/main/java/org/mskcc/oncokb/curation/importer/model/OncotreeCancerType.java new file mode 100644 index 000000000..1e2374318 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/importer/model/OncotreeCancerType.java @@ -0,0 +1,118 @@ +package org.mskcc.oncokb.curation.importer.model; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class OncotreeCancerType { + + private String code = null; + private String color = null; + private String name = null; + private String mainType = null; + private Map> externalReferences = new HashMap<>(); + private String tissue = null; + private Map children = new HashMap<>(); + private String parent = null; + private List history = new ArrayList<>(); + private Integer level = null; + private List revocations = new ArrayList<>(); + private List precursors = new ArrayList<>(); + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getMainType() { + return mainType; + } + + public void setMainType(String mainType) { + this.mainType = mainType; + } + + public Map> getExternalReferences() { + return externalReferences; + } + + public void setExternalReferences(Map> externalReferences) { + this.externalReferences = externalReferences; + } + + public String getTissue() { + return tissue; + } + + public void setTissue(String tissue) { + this.tissue = tissue; + } + + public Map getChildren() { + return children; + } + + public void setChildren(Map children) { + this.children = children; + } + + public String getParent() { + return parent; + } + + public void setParent(String parent) { + this.parent = parent; + } + + public List getHistory() { + return history; + } + + public void setHistory(List history) { + this.history = history; + } + + public Integer getLevel() { + return level; + } + + public void setLevel(Integer level) { + this.level = level; + } + + public List getRevocations() { + return revocations; + } + + public void setRevocations(List revocations) { + this.revocations = revocations; + } + + public List getPrecursors() { + return precursors; + } + + public void setPrecursors(List precursors) { + this.precursors = precursors; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/management/SecurityMetersService.java b/src/main/java/org/mskcc/oncokb/curation/management/SecurityMetersService.java new file mode 100644 index 000000000..656253579 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/management/SecurityMetersService.java @@ -0,0 +1,50 @@ +package org.mskcc.oncokb.curation.management; + +import io.micrometer.core.instrument.Counter; +import io.micrometer.core.instrument.MeterRegistry; +import org.springframework.stereotype.Service; + +@Service +public class SecurityMetersService { + + public static final String INVALID_TOKENS_METER_NAME = "security.authentication.invalid-tokens"; + public static final String INVALID_TOKENS_METER_DESCRIPTION = + "Indicates validation error count of the tokens presented by the clients."; + public static final String INVALID_TOKENS_METER_BASE_UNIT = "errors"; + public static final String INVALID_TOKENS_METER_CAUSE_DIMENSION = "cause"; + + private final Counter tokenInvalidSignatureCounter; + private final Counter tokenExpiredCounter; + private final Counter tokenUnsupportedCounter; + private final Counter tokenMalformedCounter; + + public SecurityMetersService(MeterRegistry registry) { + this.tokenInvalidSignatureCounter = invalidTokensCounterForCauseBuilder("invalid-signature").register(registry); + this.tokenExpiredCounter = invalidTokensCounterForCauseBuilder("expired").register(registry); + this.tokenUnsupportedCounter = invalidTokensCounterForCauseBuilder("unsupported").register(registry); + this.tokenMalformedCounter = invalidTokensCounterForCauseBuilder("malformed").register(registry); + } + + private Counter.Builder invalidTokensCounterForCauseBuilder(String cause) { + return Counter.builder(INVALID_TOKENS_METER_NAME) + .baseUnit(INVALID_TOKENS_METER_BASE_UNIT) + .description(INVALID_TOKENS_METER_DESCRIPTION) + .tag(INVALID_TOKENS_METER_CAUSE_DIMENSION, cause); + } + + public void trackTokenInvalidSignature() { + this.tokenInvalidSignatureCounter.increment(); + } + + public void trackTokenExpired() { + this.tokenExpiredCounter.increment(); + } + + public void trackTokenUnsupported() { + this.tokenUnsupportedCounter.increment(); + } + + public void trackTokenMalformed() { + this.tokenMalformedCounter.increment(); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/model/IntegerRange.java b/src/main/java/org/mskcc/oncokb/curation/model/IntegerRange.java new file mode 100644 index 000000000..0710dd322 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/model/IntegerRange.java @@ -0,0 +1,25 @@ +package org.mskcc.oncokb.curation.model; + +import java.io.Serializable; + +public class IntegerRange implements Serializable { + + private Integer start = null; + private Integer end = null; + + public Integer getStart() { + return start; + } + + public void setStart(Integer start) { + this.start = start; + } + + public Integer getEnd() { + return end; + } + + public void setEnd(Integer end) { + this.end = end; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/AlleleStateRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/AlleleStateRepository.java new file mode 100644 index 000000000..4a55ffa6a --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/AlleleStateRepository.java @@ -0,0 +1,16 @@ +package org.mskcc.oncokb.curation.repository; + +import java.util.Optional; +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.mskcc.oncokb.curation.domain.AlleleState; +import org.springframework.data.jpa.repository.*; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the AlleleState entity. + */ +@JaversSpringDataAuditable +@Repository +public interface AlleleStateRepository extends JpaRepository { + Optional findByNameIgnoreCase(String name); +} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/AlterationRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/AlterationRepository.java new file mode 100644 index 000000000..fa14e6e0f --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/AlterationRepository.java @@ -0,0 +1,76 @@ +package org.mskcc.oncokb.curation.repository; + +import java.util.List; +import java.util.Optional; +import java.util.Set; +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.mskcc.oncokb.curation.domain.Alteration; +import org.mskcc.oncokb.curation.domain.Consequence; +import org.mskcc.oncokb.curation.domain.Gene; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.*; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the Alteration entity. + */ +@JaversSpringDataAuditable +@Repository +public interface AlterationRepository extends JpaRepository, JpaSpecificationExecutor { + @Query( + value = "select distinct alteration from Alteration alteration left join fetch alteration.flags left join fetch alteration.genes", + countQuery = "select count(distinct alteration) from Alteration alteration" + ) + Page findAllWithEagerRelationships(Pageable pageable); + + @Query("select distinct alteration from Alteration alteration left join fetch alteration.flags left join fetch alteration.genes") + List findAllWithEagerRelationships(); + + @Query( + "select alteration from Alteration alteration left join fetch alteration.flags left join fetch alteration.genes where alteration.id =:id" + ) + Optional findOneWithEagerRelationships(@Param("id") Long id); + + @Query( + "select distinct alteration from Alteration alteration" + + " left join fetch alteration.flags" + + " left join fetch alteration.genes" + + " where alteration.id in (:ids)" + ) + List findAllWithEagerRelationships(@Param("ids") List ids); + + List findByGenesId(@Param("id") Long id); + + @Query( + "select distinct alteration from Alteration alteration" + + " left join fetch alteration.flags" + + " left join fetch alteration.genes g" + + " where g.id in (:id) and" + + " (alteration.name =:query or alteration.alteration=:query )" + ) + List findByNameOrAlterationAndGenesId(@Param("query") String query, @Param("id") Long geneId); + + @Query( + "select distinct alteration from Alteration alteration" + + " left join fetch alteration.genes g" + + " left join fetch alteration.flags" + + " where g.id in :genes and " + + " alteration.consequence = :consequence and (alteration.start <= :end and alteration.end >= :start)" + ) + List findByGeneAndConsequenceThatOverlap( + @Param("genes") List genes, + @Param("consequence") Consequence consequence, + @Param("end") int end, + @Param("start") int start + ); + + @Query( + value = "select distinct a from Alteration a" + + " where lower(a.name) like lower(concat('%', ?1,'%')) or lower(a.alteration) like lower(concat('%', ?1,'%'))", + countQuery = "select count(distinct a) from Alteration a" + + " where lower(a.name) like lower(concat('%', ?1,'%')) or lower(a.alteration) like lower(concat('%', ?1,'%'))" + ) + Page searchAlteration(String query, Pageable pageable); +} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/ArticleRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/ArticleRepository.java new file mode 100644 index 000000000..5fe4f2f3b --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/ArticleRepository.java @@ -0,0 +1,37 @@ +package org.mskcc.oncokb.curation.repository; + +import java.util.List; +import java.util.Optional; +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.mskcc.oncokb.curation.domain.Article; +import org.mskcc.oncokb.curation.domain.enumeration.ArticleType; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.*; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the Article entity. + */ +@JaversSpringDataAuditable +@Repository +public interface ArticleRepository extends JpaRepository, JpaSpecificationExecutor
{ + @Query( + value = "select distinct article from Article article left join fetch article.flags left join fetch article.synonyms", + countQuery = "select count(distinct article) from Article article" + ) + Page
findAllWithEagerRelationships(Pageable pageable); + + @Query("select distinct article from Article article left join fetch article.flags left join fetch article.synonyms") + List
findAllWithEagerRelationships(); + + @Query("select article from Article article left join fetch article.flags left join fetch article.synonyms where article.id =:id") + Optional
findOneWithEagerRelationships(@Param("id") Long id); + + Optional
findByContent(@Param("content") String content); + + Optional
findByLink(@Param("link") String link); + + Optional
findByTypeAndUid(@Param("type") ArticleType type, @Param("uid") String uid); +} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/AssociationRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/AssociationRepository.java new file mode 100644 index 000000000..b59b00999 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/AssociationRepository.java @@ -0,0 +1,34 @@ +package org.mskcc.oncokb.curation.repository; + +import java.util.List; +import java.util.Optional; +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.mskcc.oncokb.curation.domain.Association; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.*; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the Association entity. + */ +@JaversSpringDataAuditable +@Repository +public interface AssociationRepository extends JpaRepository { + @Query( + value = "select distinct association from Association association left join fetch association.alterations left join fetch association.articles left join fetch association.cancerTypes left join fetch association.drugs", + countQuery = "select count(distinct association) from Association association" + ) + Page findAllWithEagerRelationships(Pageable pageable); + + @Query( + "select distinct association from Association association left join fetch association.alterations left join fetch association.articles left join fetch association.cancerTypes left join fetch association.drugs" + ) + List findAllWithEagerRelationships(); + + @Query( + "select association from Association association left join fetch association.alterations left join fetch association.articles left join fetch association.cancerTypes left join fetch association.drugs where association.id =:id" + ) + Optional findOneWithEagerRelationships(@Param("id") Long id); +} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/AuthorityRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/AuthorityRepository.java new file mode 100644 index 000000000..f2cb31bed --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/AuthorityRepository.java @@ -0,0 +1,11 @@ +package org.mskcc.oncokb.curation.repository; + +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.mskcc.oncokb.curation.domain.Authority; +import org.springframework.data.jpa.repository.JpaRepository; + +/** + * Spring Data JPA repository for the {@link Authority} entity. + */ +@JaversSpringDataAuditable +public interface AuthorityRepository extends JpaRepository {} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/CancerTypeRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/CancerTypeRepository.java new file mode 100644 index 000000000..9784f9da7 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/CancerTypeRepository.java @@ -0,0 +1,52 @@ +package org.mskcc.oncokb.curation.repository; + +import java.util.List; +import java.util.Optional; +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.mskcc.oncokb.curation.domain.CancerType; +import org.mskcc.oncokb.curation.domain.enumeration.TumorForm; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.*; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the CancerType entity. + */ +@JaversSpringDataAuditable +@Repository +public interface CancerTypeRepository extends JpaRepository, JpaSpecificationExecutor { + @Query( + value = "select distinct cancerType from CancerType cancerType left join fetch cancerType.synonyms", + countQuery = "select count(distinct cancerType) from CancerType cancerType" + ) + Page findAllWithEagerRelationships(Pageable pageable); + + @Query("select distinct cancerType from CancerType cancerType left join fetch cancerType.synonyms") + List findAllWithEagerRelationships(); + + @Query("select cancerType from CancerType cancerType left join fetch cancerType.synonyms where cancerType.id =:id") + Optional findOneWithEagerRelationships(@Param("id") Long id); + + @Query( + "SELECT cancerType from CancerType cancerType WHERE cancerType.mainType LIKE %:containing% OR cancerType.subtype LIKE %:containing% OR cancerType.code LIKE %:containing% ORDER BY CASE WHEN cancerType.subtype LIKE :startsWith% THEN 0 WHEN cancerType.subtype IS NULL AND cancerType.mainType LIKE :startsWith% THEN 0 ELSE 1 END" + ) + Page findAllByQueryPrioritizeStartsWith( + @Param("containing") String containing, + @Param("startsWith") String startsWith, + Pageable pageable + ); + + List findAllByMainTypeIs(@Param("maintype") String mainType); + + List findByTumorFormIn(List tumorForms); + + Optional findOneByCodeIgnoreCase(String code); + + Optional findOneBySubtypeIgnoreCase(String subtype); + + Optional findOneByMainTypeIgnoreCaseAndCodeIsNull(String mainType); + + Optional findByMainTypeAndSubtypeIsNull(String mainType); +} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/CategoricalAlterationRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/CategoricalAlterationRepository.java new file mode 100644 index 000000000..e8d69747e --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/CategoricalAlterationRepository.java @@ -0,0 +1,18 @@ +package org.mskcc.oncokb.curation.repository; + +import java.util.Optional; +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.mskcc.oncokb.curation.domain.CategoricalAlteration; +import org.mskcc.oncokb.curation.domain.enumeration.AlterationType; +import org.springframework.data.jpa.repository.*; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the CategoricalAlteration entity. + */ +@JaversSpringDataAuditable +@Repository +public interface CategoricalAlterationRepository extends JpaRepository { + Optional findByAlterationTypeAndName(AlterationType alterationType, String name); + Optional findByName(String name); +} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/ClinicalTrialArmRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/ClinicalTrialArmRepository.java new file mode 100644 index 000000000..c4bbe490d --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/ClinicalTrialArmRepository.java @@ -0,0 +1,32 @@ +package org.mskcc.oncokb.curation.repository; + +import java.util.List; +import java.util.Optional; +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.mskcc.oncokb.curation.domain.ClinicalTrialArm; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.*; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the ClinicalTrialArm entity. + */ +@JaversSpringDataAuditable +@Repository +public interface ClinicalTrialArmRepository extends JpaRepository, JpaSpecificationExecutor { + @Query( + value = "select distinct clinicalTrialArm from ClinicalTrialArm clinicalTrialArm left join fetch clinicalTrialArm.associations", + countQuery = "select count(distinct clinicalTrialArm) from ClinicalTrialArm clinicalTrialArm" + ) + Page findAllWithEagerRelationships(Pageable pageable); + + @Query("select distinct clinicalTrialArm from ClinicalTrialArm clinicalTrialArm left join fetch clinicalTrialArm.associations") + List findAllWithEagerRelationships(); + + @Query( + "select clinicalTrialArm from ClinicalTrialArm clinicalTrialArm left join fetch clinicalTrialArm.associations where clinicalTrialArm.id =:id" + ) + Optional findOneWithEagerRelationships(@Param("id") Long id); +} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/ClinicalTrialRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/ClinicalTrialRepository.java new file mode 100644 index 000000000..0e651c99a --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/ClinicalTrialRepository.java @@ -0,0 +1,30 @@ +package org.mskcc.oncokb.curation.repository; + +import java.util.List; +import java.util.Optional; +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.mskcc.oncokb.curation.domain.ClinicalTrial; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.*; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the ClinicalTrial entity. + */ +@JaversSpringDataAuditable +@Repository +public interface ClinicalTrialRepository extends JpaRepository, JpaSpecificationExecutor { + @Query( + value = "select distinct clinicalTrial from ClinicalTrial clinicalTrial left join fetch clinicalTrial.associations", + countQuery = "select count(distinct clinicalTrial) from ClinicalTrial clinicalTrial" + ) + Page findAllWithEagerRelationships(Pageable pageable); + + @Query("select distinct clinicalTrial from ClinicalTrial clinicalTrial left join fetch clinicalTrial.associations") + List findAllWithEagerRelationships(); + + @Query("select clinicalTrial from ClinicalTrial clinicalTrial left join fetch clinicalTrial.associations where clinicalTrial.id =:id") + Optional findOneWithEagerRelationships(@Param("id") Long id); +} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/CompanionDiagnosticDeviceRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/CompanionDiagnosticDeviceRepository.java new file mode 100644 index 000000000..75bb029dd --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/CompanionDiagnosticDeviceRepository.java @@ -0,0 +1,66 @@ +package org.mskcc.oncokb.curation.repository; + +import java.util.List; +import java.util.Optional; +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.mskcc.oncokb.curation.domain.CompanionDiagnosticDevice; +import org.springframework.data.jpa.repository.*; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the CompanionDiagnosticDevice entity. + */ +@JaversSpringDataAuditable +@Repository +public interface CompanionDiagnosticDeviceRepository + extends JpaRepository, JpaSpecificationExecutor { + @Query( + "select distinct companionDiagnosticDevice from CompanionDiagnosticDevice companionDiagnosticDevice" + + " left join fetch companionDiagnosticDevice.fdaSubmissions fa" + + " left join fetch companionDiagnosticDevice.specimenTypes st" + + " left join fetch fa.associations ba" + + " left join fetch ba.rules" + + " left join fetch ba.cancerTypes" + + " left join fetch ba.drugs" + + " left join fetch ba.alterations baa" + + " left join fetch baa.genes" + + " left join fetch ba.fdaSubmissions" + ) + List findAllWithEagerRelationships(); + + @Query( + "select companionDiagnosticDevice from CompanionDiagnosticDevice companionDiagnosticDevice" + + " left join fetch companionDiagnosticDevice.fdaSubmissions fa" + + " left join fetch companionDiagnosticDevice.specimenTypes st" + + " left join fetch fa.associations ba" + + " left join fetch ba.rules" + + " left join fetch ba.cancerTypes" + + " left join fetch ba.drugs" + + " left join fetch ba.alterations baa" + + " left join fetch baa.genes" + + " left join fetch ba.fdaSubmissions" + + " where companionDiagnosticDevice.id =:id" + ) + Optional findOneWithEagerRelationships(@Param("id") Long id); + + Optional findByName(String name); + + @Query( + "select companionDiagnosticDevice from CompanionDiagnosticDevice companionDiagnosticDevice" + + " left join fetch companionDiagnosticDevice.fdaSubmissions fa" + + " left join fetch companionDiagnosticDevice.specimenTypes st" + + " left join fetch fa.associations ba" + + " left join fetch ba.rules" + + " left join fetch ba.cancerTypes" + + " left join fetch ba.drugs" + + " left join fetch ba.alterations baa" + + " left join fetch baa.genes" + + " left join fetch ba.fdaSubmissions" + + " where companionDiagnosticDevice.name =:name and companionDiagnosticDevice.manufacturer=:manufacturer" + ) + List findByNameIgnoreCaseAndManufacturerIgnoreCase( + @Param("name") String name, + @Param("manufacturer") String manufacturer + ); +} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/ConsequenceRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/ConsequenceRepository.java new file mode 100644 index 000000000..2dce75465 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/ConsequenceRepository.java @@ -0,0 +1,16 @@ +package org.mskcc.oncokb.curation.repository; + +import java.util.Optional; +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.mskcc.oncokb.curation.domain.Consequence; +import org.springframework.data.jpa.repository.*; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the Consequence entity. + */ +@JaversSpringDataAuditable +@Repository +public interface ConsequenceRepository extends JpaRepository, JpaSpecificationExecutor { + Optional findByTerm(String term); +} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/DrugRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/DrugRepository.java new file mode 100644 index 000000000..63f780ffd --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/DrugRepository.java @@ -0,0 +1,81 @@ +package org.mskcc.oncokb.curation.repository; + +import java.util.List; +import java.util.Optional; +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.mskcc.oncokb.curation.domain.Drug; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.*; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the Drug entity. + */ +@JaversSpringDataAuditable +@Repository +public interface DrugRepository extends JpaRepository, JpaSpecificationExecutor { + @Query(value = "select distinct drug from Drug drug", countQuery = "select count(distinct drug) from Drug drug") + Page findAllWithEagerRelationships(Pageable pageable); + + @Query( + "select distinct drug from Drug drug" + + " left join fetch drug.flags" + + " left join fetch drug.fdaDrugs" + + " left join fetch drug.associations da" + + " left join fetch da.rules" + + " left join fetch da.cancerTypes" + + " left join fetch da.drugs" + + " left join fetch da.alterations daa" + + " left join fetch daa.genes" + ) + List findAllWithEagerRelationships(); + + @Query( + "select drug from Drug drug" + + " left join fetch drug.flags" + + " left join fetch drug.fdaDrugs" + + " left join fetch drug.associations da" + + " left join fetch da.rules" + + " left join fetch da.cancerTypes" + + " left join fetch da.drugs" + + " left join fetch da.alterations daa" + + " left join fetch daa.genes" + + " left join fetch drug.nciThesaurus ncit" + + " left join fetch ncit.synonyms" + + " where drug.id =:id" + ) + Optional findOneWithEagerRelationships(@Param("id") Long id); + + @Query( + "select distinct drug from Drug drug" + + " left join fetch drug.flags" + + " left join fetch drug.fdaDrugs" + + " left join fetch drug.nciThesaurus nci" + + " left join fetch nci.synonyms" + + " left join fetch drug.associations da" + + " left join fetch da.rules" + + " left join fetch da.cancerTypes" + + " left join fetch da.drugs" + + " left join fetch da.alterations daa" + + " left join fetch daa.genes" + + " where drug.id in (:ids)" + ) + List findAllWithEagerRelationships(@Param("ids") List ids); + + @Query( + "select distinct drug from Drug drug left join fetch drug.flags where drug.nciThesaurus is not null and drug.nciThesaurus.code=:code" + ) + Optional findOneByCodeWithEagerRelationships(@Param("code") String code); + + @Query("select distinct drug from Drug drug left join fetch drug.flags where drug.name=:name") + Optional findByNameIgnoreCaseWithEagerRelationships(@Param("name") String name); + + @Query( + "select distinct d from Drug d" + + " left join fetch d.flags " + + " where lower(cast(d.name as char ) ) like lower(concat('%', ?1,'%')) or lower(d.nciThesaurus.code) like lower(concat('%', ?1,'%'))" + ) + List searchDrug(String query); +} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/EligibilityCriteriaRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/EligibilityCriteriaRepository.java new file mode 100644 index 000000000..c45d15b33 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/EligibilityCriteriaRepository.java @@ -0,0 +1,35 @@ +package org.mskcc.oncokb.curation.repository; + +import java.util.List; +import java.util.Optional; +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.mskcc.oncokb.curation.domain.EligibilityCriteria; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.*; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the EligibilityCriteria entity. + */ +@JaversSpringDataAuditable +@Repository +public interface EligibilityCriteriaRepository + extends JpaRepository, JpaSpecificationExecutor { + @Query( + value = "select distinct eligibilityCriteria from EligibilityCriteria eligibilityCriteria left join fetch eligibilityCriteria.associations", + countQuery = "select count(distinct eligibilityCriteria) from EligibilityCriteria eligibilityCriteria" + ) + Page findAllWithEagerRelationships(Pageable pageable); + + @Query( + "select distinct eligibilityCriteria from EligibilityCriteria eligibilityCriteria left join fetch eligibilityCriteria.associations" + ) + List findAllWithEagerRelationships(); + + @Query( + "select eligibilityCriteria from EligibilityCriteria eligibilityCriteria left join fetch eligibilityCriteria.associations where eligibilityCriteria.id =:id" + ) + Optional findOneWithEagerRelationships(@Param("id") Long id); +} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/EnsemblGeneRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/EnsemblGeneRepository.java new file mode 100644 index 000000000..961defec2 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/EnsemblGeneRepository.java @@ -0,0 +1,24 @@ +package org.mskcc.oncokb.curation.repository; + +import java.util.List; +import java.util.Optional; +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.mskcc.oncokb.curation.domain.EnsemblGene; +import org.mskcc.oncokb.curation.domain.Gene; +import org.mskcc.oncokb.curation.domain.enumeration.ReferenceGenome; +import org.springframework.data.jpa.repository.*; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the EnsemblGene entity. + */ +@JaversSpringDataAuditable +@Repository +public interface EnsemblGeneRepository extends JpaRepository, JpaSpecificationExecutor { + @Query("select eg from EnsemblGene eg join eg.gene g where g.entrezGeneId=?1 and eg.canonical=true and eg.referenceGenome=?2") + Optional findCanonicalEnsemblGene(Integer entrezGeneId, ReferenceGenome referenceGenome); + + List findAllByGeneAndReferenceGenome(Gene gene, ReferenceGenome referenceGenome); + + List findAllByReferenceGenomeAndEnsemblGeneIdIn(ReferenceGenome referenceGenome, List ensemblGeneIds); +} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/EvidenceRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/EvidenceRepository.java new file mode 100644 index 000000000..5b98dd9a3 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/EvidenceRepository.java @@ -0,0 +1,30 @@ +package org.mskcc.oncokb.curation.repository; + +import java.util.List; +import java.util.Optional; +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.mskcc.oncokb.curation.domain.Evidence; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.*; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the Evidence entity. + */ +@JaversSpringDataAuditable +@Repository +public interface EvidenceRepository extends JpaRepository, JpaSpecificationExecutor { + @Query( + value = "select distinct evidence from Evidence evidence left join fetch evidence.levelOfEvidences", + countQuery = "select count(distinct evidence) from Evidence evidence" + ) + Page findAllWithEagerRelationships(Pageable pageable); + + @Query("select distinct evidence from Evidence evidence left join fetch evidence.levelOfEvidences") + List findAllWithEagerRelationships(); + + @Query("select evidence from Evidence evidence left join fetch evidence.levelOfEvidences where evidence.id =:id") + Optional findOneWithEagerRelationships(@Param("id") Long id); +} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/FdaDrugRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/FdaDrugRepository.java new file mode 100644 index 000000000..0e68a8f3e --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/FdaDrugRepository.java @@ -0,0 +1,16 @@ +package org.mskcc.oncokb.curation.repository; + +import java.util.Optional; +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.mskcc.oncokb.curation.domain.FdaDrug; +import org.springframework.data.jpa.repository.*; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the FdaDrug entity. + */ +@JaversSpringDataAuditable +@Repository +public interface FdaDrugRepository extends JpaRepository, JpaSpecificationExecutor { + public Optional findFirstByApplicationNumber(String applicationNumber); +} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/FdaSubmissionRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/FdaSubmissionRepository.java new file mode 100644 index 000000000..96d28f74e --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/FdaSubmissionRepository.java @@ -0,0 +1,51 @@ +package org.mskcc.oncokb.curation.repository; + +import java.util.List; +import java.util.Optional; +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.mskcc.oncokb.curation.domain.CompanionDiagnosticDevice; +import org.mskcc.oncokb.curation.domain.FdaSubmission; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.*; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the FdaSubmission entity. + */ +@JaversSpringDataAuditable +@Repository +public interface FdaSubmissionRepository extends JpaRepository, JpaSpecificationExecutor { + @Query( + value = "select distinct fdaSubmission from FdaSubmission fdaSubmission left join fetch fdaSubmission.articles left join fetch fdaSubmission.associations", + countQuery = "select count(distinct fdaSubmission) from FdaSubmission fdaSubmission" + ) + Page findAllWithEagerRelationships(Pageable pageable); + + @Query( + "select distinct fdaSubmission from FdaSubmission fdaSubmission left join fetch fdaSubmission.articles left join fetch fdaSubmission.associations" + ) + List findAllWithEagerRelationships(); + + @Query( + "select fdaSubmission from FdaSubmission fdaSubmission left join fetch fdaSubmission.articles left join fetch fdaSubmission.associations where fdaSubmission.id =:id" + ) + Optional findOneWithEagerRelationships(@Param("id") Long id); + + @Query( + "select fdaSubmission from FdaSubmission fdaSubmission left join fetch fdaSubmission.articles left join fetch fdaSubmission.associations where fdaSubmission.number =:number and fdaSubmission.supplementNumber =:supplementNumber" + ) + Optional findByNumberAndSupplementNumber( + @Param("number") String number, + @Param("supplementNumber") String supplementNumber + ); + + List findByNumberAndSupplementNumberAndCompanionDiagnosticDevice( + String number, + String supplementNumber, + CompanionDiagnosticDevice companionDiagnosticDevice + ); + + List findByCompanionDiagnosticDeviceId(Long id); +} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/FdaSubmissionTypeRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/FdaSubmissionTypeRepository.java new file mode 100644 index 000000000..5794706ad --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/FdaSubmissionTypeRepository.java @@ -0,0 +1,17 @@ +package org.mskcc.oncokb.curation.repository; + +import java.util.Optional; +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.mskcc.oncokb.curation.domain.FdaSubmissionType; +import org.mskcc.oncokb.curation.domain.enumeration.FdaSubmissionTypeKey; +import org.springframework.data.jpa.repository.*; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the FdaSubmissionType entity. + */ +@JaversSpringDataAuditable +@Repository +public interface FdaSubmissionTypeRepository extends JpaRepository { + Optional findByType(FdaSubmissionTypeKey type); +} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/FlagRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/FlagRepository.java new file mode 100644 index 000000000..2a743e270 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/FlagRepository.java @@ -0,0 +1,19 @@ +package org.mskcc.oncokb.curation.repository; + +import java.util.List; +import java.util.Optional; +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.mskcc.oncokb.curation.domain.Flag; +import org.springframework.data.jpa.repository.*; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the Flag entity. + */ +@JaversSpringDataAuditable +@Repository +public interface FlagRepository extends JpaRepository, JpaSpecificationExecutor { + Optional findByTypeAndFlag(String type, String flag); + + List findAllByFlagIn(List flags); +} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/GeneRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/GeneRepository.java new file mode 100644 index 000000000..44e5e9147 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/GeneRepository.java @@ -0,0 +1,84 @@ +package org.mskcc.oncokb.curation.repository; + +import java.util.List; +import java.util.Optional; +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.mskcc.oncokb.curation.domain.Gene; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.*; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the Gene entity. + */ +@JaversSpringDataAuditable +@Repository +public interface GeneRepository extends JpaRepository, JpaSpecificationExecutor { + @Query( + value = "select distinct gene from Gene gene left join fetch gene.flags left join fetch gene.synonyms", + countQuery = "select count(distinct gene) from Gene gene" + ) + Page findAllWithEagerRelationships(Pageable pageable); + + @Query("select distinct gene from Gene gene left join fetch gene.flags left join fetch gene.synonyms") + List findAllWithEagerRelationships(); + + @Query("select gene from Gene gene left join fetch gene.flags left join fetch gene.synonyms where gene.id =:id") + Optional findOneWithEagerRelationships(@Param("id") Long id); + + @Cacheable(cacheResolver = "geneCacheResolver") + @Query( + "select gene from Gene gene" + + " left join fetch gene.flags" + + " left join fetch gene.synonyms" + + " where gene.entrezGeneId =:entrezGeneId" + ) + Optional findByEntrezGeneId(@Param("entrezGeneId") Integer entrezGeneId); + + @Cacheable(cacheResolver = "geneCacheResolver") + @Query( + "select gene from Gene gene" + + " left join fetch gene.flags" + + " left join fetch gene.synonyms" + + " where gene.hugoSymbol =:hugoSymbol" + ) + Optional findByHugoSymbol(@Param("hugoSymbol") String hugoSymbol); + + @Query( + value = "select gene from Gene gene left join fetch gene.flags left join fetch gene.synonyms ga where UPPER(gene.hugoSymbol) = UPPER(:hugoSymbol) or UPPER(ga.name) = UPPER(:hugoSymbol) " + ) + List findGeneByHugoSymbolOrGeneAliasesIn(@Param("hugoSymbol") String hugoSymbol); + + @Query( + value = "select distinct gene from Gene gene left join fetch gene.flags left join fetch gene.synonyms ga left join fetch gene.ensemblGenes eg where gene.id in :ids" + ) + List findAllByIdInWithGeneAliasAndEnsemblGenes(@Param("ids") List ids); + + @Query( + "select distinct gene from Gene gene" + + " left join fetch gene.flags" + + " left join fetch gene.synonyms" + + " where gene.id in (:ids)" + ) + List findAllWithEagerRelationships(@Param("ids") List ids); + + @Query( + "select distinct gene from Gene gene" + + " left join fetch gene.flags" + + " left join fetch gene.synonyms" + + " where gene.hugoSymbol in (:symbols)" + ) + List findByHugoSymbolInIgnoreCase(@Param("symbols") List symbols); + + @Query( + value = "select * from (" + + "(select * from Gene gene where gene.hugo_symbol =:query)" + + " union (select * from Gene gene where lower(gene.hugo_symbol) like lower(concat('%', :query,'%'))" + + ") as t1", + nativeQuery = true + ) + Page blurSearchByHugoSymbol(@Param("query") String query, Pageable pageable); +} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/GenomeFragmentRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/GenomeFragmentRepository.java new file mode 100644 index 000000000..893282df5 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/GenomeFragmentRepository.java @@ -0,0 +1,16 @@ +package org.mskcc.oncokb.curation.repository; + +import java.util.List; +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.mskcc.oncokb.curation.domain.GenomeFragment; +import org.springframework.data.jpa.repository.*; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the GenomeFragment entity. + */ +@Repository +public interface GenomeFragmentRepository extends JpaRepository, JpaSpecificationExecutor { + @Query("select genomeFragment from GenomeFragment genomeFragment where genomeFragment.transcript.id = ?1") + List findAllByTranscriptId(Long id); +} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/GenomicIndicatorRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/GenomicIndicatorRepository.java new file mode 100644 index 000000000..b3ceed341 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/GenomicIndicatorRepository.java @@ -0,0 +1,45 @@ +package org.mskcc.oncokb.curation.repository; + +import java.util.List; +import java.util.Optional; +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.mskcc.oncokb.curation.domain.GenomicIndicator; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.*; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the GenomicIndicator entity. + */ +@JaversSpringDataAuditable +@Repository +public interface GenomicIndicatorRepository extends JpaRepository, JpaSpecificationExecutor { + @Query( + "select distinct genomicIndicator from GenomicIndicator genomicIndicator left join fetch genomicIndicator.alleleStates left join fetch genomicIndicator.associations acat " + + "left join fetch acat.alterations alts " + + "left join fetch alts.genes " + ) + List findAllWithEagerRelationships(); + + @Query( + "select genomicIndicator from GenomicIndicator genomicIndicator left join fetch genomicIndicator.alleleStates left join fetch genomicIndicator.associations acat " + + "left join fetch acat.alterations alts " + + "left join fetch alts.genes " + + "where genomicIndicator.id =:id" + ) + Optional findOneWithEagerRelationships(@Param("id") Long id); + + @Query( + "select genomicIndicator from GenomicIndicator genomicIndicator " + + "left join fetch genomicIndicator.alleleStates " + + "left join fetch genomicIndicator.associations acat " + + "left join fetch acat.alterations alts " + + "left join fetch alts.genes " + + "where genomicIndicator.id in(:ids)" + ) + List findByIdInWithEagerRelationships(@Param("ids") List ids); + + Optional findByTypeAndName(String type, String name); +} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/InfoRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/InfoRepository.java new file mode 100644 index 000000000..4d8ac6174 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/InfoRepository.java @@ -0,0 +1,17 @@ +package org.mskcc.oncokb.curation.repository; + +import java.util.Optional; +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.mskcc.oncokb.curation.domain.Info; +import org.mskcc.oncokb.curation.domain.enumeration.InfoType; +import org.springframework.data.jpa.repository.*; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the Info entity. + */ +@JaversSpringDataAuditable +@Repository +public interface InfoRepository extends JpaRepository { + Optional findOneByType(String type); +} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/LevelOfEvidenceRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/LevelOfEvidenceRepository.java new file mode 100644 index 000000000..30188401d --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/LevelOfEvidenceRepository.java @@ -0,0 +1,13 @@ +package org.mskcc.oncokb.curation.repository; + +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.mskcc.oncokb.curation.domain.LevelOfEvidence; +import org.springframework.data.jpa.repository.*; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the LevelOfEvidence entity. + */ +@JaversSpringDataAuditable +@Repository +public interface LevelOfEvidenceRepository extends JpaRepository {} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/NciThesaurusRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/NciThesaurusRepository.java new file mode 100644 index 000000000..e8d4d7b27 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/NciThesaurusRepository.java @@ -0,0 +1,43 @@ +package org.mskcc.oncokb.curation.repository; + +import java.util.List; +import java.util.Optional; +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.mskcc.oncokb.curation.domain.NciThesaurus; +import org.springframework.data.jpa.repository.*; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the NciThesaurus entity. + */ +@JaversSpringDataAuditable +@Repository +public interface NciThesaurusRepository extends JpaRepository, JpaSpecificationExecutor { + @Query("select nciThesaurus from NciThesaurus nciThesaurus left join fetch nciThesaurus.synonyms where nciThesaurus.id =:id") + Optional findOneWithEagerRelationships(@Param("id") Long id); + + Optional findByCode(String code); + + @Query( + "select distinct nciThesaurus from NciThesaurus nciThesaurus left join fetch nciThesaurus.synonyms synonyms where nciThesaurus.displayName = :name or nciThesaurus.preferredName=:name or synonyms.name=:name" + ) + List findByName(@Param("name") String name); + + @Query( + "select distinct nciThesaurus from NciThesaurus nciThesaurus left join fetch nciThesaurus.synonyms where nciThesaurus.id in :ids" + ) + List findAllWithEagerRelationships(@Param("ids") List ids); + + @Query("select distinct nciThesaurus from NciThesaurus nciThesaurus left join fetch nciThesaurus.synonyms") + List findAllWithEagerRelationships(); + + @Query( + "select distinct ncit from NciThesaurus ncit left join fetch ncit.synonyms" + + " where lower(ncit.code) like lower(concat('%', ?1,'%'))" + + " or lower(ncit.displayName) like lower(concat('%', ?1,'%'))" + + " or lower(ncit.preferredName) like lower(concat('%', ?1,'%'))" + + " or lower(ncit.version) like lower(concat('%', ?1,'%'))" + ) + List searchNciThesaurus(String query); +} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/RuleRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/RuleRepository.java new file mode 100644 index 000000000..668d61f11 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/RuleRepository.java @@ -0,0 +1,13 @@ +package org.mskcc.oncokb.curation.repository; + +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.mskcc.oncokb.curation.domain.Rule; +import org.springframework.data.jpa.repository.*; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the Rule entity. + */ +@JaversSpringDataAuditable +@Repository +public interface RuleRepository extends JpaRepository {} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/SeqRegionRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/SeqRegionRepository.java new file mode 100644 index 000000000..5b0354385 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/SeqRegionRepository.java @@ -0,0 +1,16 @@ +package org.mskcc.oncokb.curation.repository; + +import java.util.Optional; +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.mskcc.oncokb.curation.domain.SeqRegion; +import org.springframework.data.jpa.repository.*; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the SeqRegion entity. + */ +@JaversSpringDataAuditable +@Repository +public interface SeqRegionRepository extends JpaRepository { + Optional findByName(String name); +} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/SequenceRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/SequenceRepository.java new file mode 100644 index 000000000..79078d227 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/SequenceRepository.java @@ -0,0 +1,16 @@ +package org.mskcc.oncokb.curation.repository; + +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.Sequence; +import org.mskcc.oncokb.curation.domain.Transcript; +import org.mskcc.oncokb.curation.domain.enumeration.SequenceType; +import org.springframework.data.jpa.repository.*; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the Sequence entity. + */ +@Repository +public interface SequenceRepository extends JpaRepository, JpaSpecificationExecutor { + Optional findOneByTranscriptAndSequenceType(Transcript transcript, SequenceType sequenceType); +} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/SpecimenTypeRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/SpecimenTypeRepository.java new file mode 100644 index 000000000..a8a8b18fd --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/SpecimenTypeRepository.java @@ -0,0 +1,17 @@ +package org.mskcc.oncokb.curation.repository; + +import java.util.Optional; +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.mskcc.oncokb.curation.domain.SpecimenType; +import org.springframework.data.jpa.repository.*; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the SpecimenType entity. + */ +@JaversSpringDataAuditable +@Repository +public interface SpecimenTypeRepository extends JpaRepository { + Optional findOneByType(String type); + Optional findOneByName(String name); +} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/SynonymRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/SynonymRepository.java new file mode 100644 index 000000000..a5ce5d695 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/SynonymRepository.java @@ -0,0 +1,16 @@ +package org.mskcc.oncokb.curation.repository; + +import java.util.List; +import java.util.Optional; +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.mskcc.oncokb.curation.domain.Synonym; +import org.springframework.data.jpa.repository.*; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the Synonym entity. + */ +@Repository +public interface SynonymRepository extends JpaRepository, JpaSpecificationExecutor { + Optional findByTypeAndSourceAndName(String type, String source, String name); +} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/TranscriptRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/TranscriptRepository.java new file mode 100644 index 000000000..52475796e --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/TranscriptRepository.java @@ -0,0 +1,52 @@ +package org.mskcc.oncokb.curation.repository; + +import java.util.List; +import java.util.Optional; +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.mskcc.oncokb.curation.domain.EnsemblGene; +import org.mskcc.oncokb.curation.domain.Gene; +import org.mskcc.oncokb.curation.domain.Transcript; +import org.mskcc.oncokb.curation.domain.enumeration.ReferenceGenome; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.jpa.repository.*; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the Transcript entity. + */ +@JaversSpringDataAuditable +@Repository +public interface TranscriptRepository extends JpaRepository, JpaSpecificationExecutor { + @Query("select t from Transcript t join t.ensemblGene eg where eg.referenceGenome= ?1 and t.ensemblTranscriptId=?2") + Optional findByReferenceGenomeAndEnsemblTranscriptId(ReferenceGenome referenceGenome, String ensemblTranscriptId); + + @Cacheable(cacheResolver = "transcriptCacheResolver") + @Query("select distinct t from Transcript t join t.ensemblGene eg where eg.referenceGenome= ?1 and t.ensemblTranscriptId in ?2") + List findByReferenceGenomeAndEnsemblTranscriptIdIsIn(String referenceGenome, List ensemblTranscriptIds); + + List findByEnsemblGene(EnsemblGene ensemblGene); + + @Query( + "select distinct t from Transcript t left join fetch t.flags left join t.gene g where t.referenceGenome=?2 and g.entrezGeneId=?1" + ) + List findByEntrezGeneIdAndReferenceGenome(Integer entrezGeneId, ReferenceGenome referenceGenome); + + Optional findByEnsemblGeneAndEnsemblTranscriptId(EnsemblGene ensemblGene, String ensemblTranscriptId); + + @Cacheable(cacheResolver = "transcriptCacheResolver") + @Query( + "select distinct transcript from Transcript transcript left join fetch transcript.flags where transcript.ensemblGene=:ensemblGene and transcript.canonical is true" + ) + Optional findByEnsemblGeneAndCanonicalIsTrue(@Param("ensemblGene") EnsemblGene ensemblGene); + + Optional findByGeneAndReferenceGenomeAndCanonicalIsTrue(Gene gene, ReferenceGenome referenceGenome); + + List findAllByIdIn(List ids); + + @Query("select distinct transcript from Transcript transcript left join fetch transcript.flags where transcript.id =:id") + Optional findOneWithEagerRelationships(@Param("id") Long id); + + @Query("select distinct transcript from Transcript transcript left join fetch transcript.flags where transcript.id in :ids") + List findAllWithEagerRelationships(@Param("ids") List ids); +} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/UserRepository.java b/src/main/java/org/mskcc/oncokb/curation/repository/UserRepository.java new file mode 100644 index 000000000..784cfadcf --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/UserRepository.java @@ -0,0 +1,32 @@ +package org.mskcc.oncokb.curation.repository; + +import java.util.Optional; +import org.javers.spring.annotation.JaversSpringDataAuditable; +import org.mskcc.oncokb.curation.domain.User; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.EntityGraph; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the {@link User} entity. + */ +@JaversSpringDataAuditable +@Repository +public interface UserRepository extends JpaRepository { + Optional findOneByEmailIgnoreCase(String email); + + Optional findOneByLogin(String login); + + @EntityGraph(attributePaths = "authorities") + @Cacheable(cacheResolver = "userCacheResolver") + Optional findOneWithAuthoritiesByLogin(String login); + + @EntityGraph(attributePaths = "authorities") + @Cacheable(cacheResolver = "userCacheResolver") + Optional findOneWithAuthoritiesByEmailIgnoreCase(String email); + + Page findAllByIdNotNullAndActivatedIsTrue(Pageable pageable); +} diff --git a/src/main/java/org/mskcc/oncokb/curation/repository/package-info.java b/src/main/java/org/mskcc/oncokb/curation/repository/package-info.java new file mode 100644 index 000000000..38ce8676c --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/repository/package-info.java @@ -0,0 +1,4 @@ +/** + * Spring Data JPA repositories. + */ +package org.mskcc.oncokb.curation.repository; diff --git a/src/main/java/org/mskcc/oncokb/curation/security/AudienceValidator.java b/src/main/java/org/mskcc/oncokb/curation/security/AudienceValidator.java new file mode 100644 index 000000000..584f63c12 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/security/AudienceValidator.java @@ -0,0 +1,33 @@ +package org.mskcc.oncokb.curation.security; + +import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.oauth2.core.OAuth2Error; +import org.springframework.security.oauth2.core.OAuth2TokenValidator; +import org.springframework.security.oauth2.core.OAuth2TokenValidatorResult; +import org.springframework.security.oauth2.jwt.Jwt; +import org.springframework.util.Assert; + +public class AudienceValidator implements OAuth2TokenValidator { + + private final Logger log = LoggerFactory.getLogger(AudienceValidator.class); + private final OAuth2Error error = new OAuth2Error("invalid_token", "The required audience is missing", null); + + private final List allowedAudience; + + public AudienceValidator(List allowedAudience) { + Assert.notEmpty(allowedAudience, "Allowed audience should not be null or empty."); + this.allowedAudience = allowedAudience; + } + + public OAuth2TokenValidatorResult validate(Jwt jwt) { + List audience = jwt.getAudience(); + if (audience.stream().anyMatch(allowedAudience::contains)) { + return OAuth2TokenValidatorResult.success(); + } else { + log.warn("Invalid audience: {}", audience); + return OAuth2TokenValidatorResult.failure(error); + } + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/security/AuthoritiesConstants.java b/src/main/java/org/mskcc/oncokb/curation/security/AuthoritiesConstants.java new file mode 100644 index 000000000..27dbb1834 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/security/AuthoritiesConstants.java @@ -0,0 +1,19 @@ +package org.mskcc.oncokb.curation.security; + +/** + * Constants for Spring Security authorities. + */ +public final class AuthoritiesConstants { + + public static final String ADMIN = "ROLE_ADMIN"; + + public static final String DEV = "ROLE_DEV"; + + public static final String USER = "ROLE_USER"; + + public static final String CURATOR = "ROLE_CURATOR"; + + public static final String ANONYMOUS = "ROLE_ANONYMOUS"; + + private AuthoritiesConstants() {} +} diff --git a/src/main/java/org/mskcc/oncokb/curation/security/CustomOAuthSuccessHandler.java b/src/main/java/org/mskcc/oncokb/curation/security/CustomOAuthSuccessHandler.java new file mode 100644 index 000000000..9c50f058e --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/security/CustomOAuthSuccessHandler.java @@ -0,0 +1,127 @@ +package org.mskcc.oncokb.curation.security; + +import com.google.firebase.auth.FirebaseAuth; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.time.Instant; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ExecutionException; +import java.util.stream.Collectors; +import org.mskcc.oncokb.curation.config.Constants; +import org.mskcc.oncokb.curation.config.InstantTypeAdapter; +import org.mskcc.oncokb.curation.config.application.ApplicationProperties; +import org.mskcc.oncokb.curation.service.UserService; +import org.mskcc.oncokb.curation.service.dto.KeycloakUserDTO; +import org.mskcc.oncokb.curation.service.dto.UserDTO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; +import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser; +import org.springframework.security.oauth2.core.oidc.user.OidcUser; +import org.springframework.security.web.DefaultRedirectStrategy; +import org.springframework.security.web.RedirectStrategy; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; +import org.springframework.stereotype.Component; + +@Component +public class CustomOAuthSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { + + private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); + + @Autowired + private UserService userService; + + @Autowired + private ApplicationProperties applicationProperties; + + @Override + public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) + throws IOException, ServletException { + Map attributes = ((OAuth2AuthenticationToken) authentication).getPrincipal().getAttributes(); + Gson gson = new GsonBuilder().registerTypeAdapter(Instant.class, new InstantTypeAdapter()).create(); + String json = gson.toJson(attributes); + KeycloakUserDTO keycloakUser = gson.fromJson(json, KeycloakUserDTO.class); + + Optional optionalUser = userService.findOneByEmailIgnoreCase(keycloakUser.getEmail()); + // If user is in db, then let spring security handle authentication success. + // When we use the OncoKB public user table, then an activated user is not neccesarily + // allowed to access this service. We will need to add a ROLE_CURATOR role to public + // and check that the role exists here. + if ( + optionalUser.isPresent() && optionalUser.orElseThrow().isActivated() && !optionalUser.orElseThrow().getAuthorities().isEmpty() + ) { + UserDTO user = optionalUser.orElseThrow(); + if (keycloakUser.getImageUrl() != null) { + user.setImageUrl(keycloakUser.getImageUrl()); + userService.updateUser(user); + } + + // Keycloak oauth token uses `sub` to get principal name which is a unique id. + // We like to use the `name` field instead, so it can be used to store in the audit. + OAuth2AuthenticationToken authenticationWithAuthorities = getOAuth2AuthenticationToken( + (OAuth2AuthenticationToken) authentication, + user + ); + + if (applicationProperties.getFirebase().isEnabled()) { + addFirebaseTokenToAuthToken(authenticationWithAuthorities); + } + + SecurityContextHolder.getContext().setAuthentication(authenticationWithAuthorities); + super.onAuthenticationSuccess(request, response, authenticationWithAuthorities); + } else { + redirectStrategy.sendRedirect(request, response, "/logout?unauthorized=true"); + } + + clearAuthenticationAttributes(request); + } + + private static OAuth2AuthenticationToken getOAuth2AuthenticationToken(OAuth2AuthenticationToken authentication, UserDTO user) { + Collection authorities = user + .getAuthorities() + .stream() + .map(SimpleGrantedAuthority::new) + .collect(Collectors.toList()); + + OidcUser oAuth2User = (OidcUser) authentication.getPrincipal(); + + OAuth2AuthenticationToken authenticationWithAuthorities = new OAuth2AuthenticationToken( + new DefaultOidcUser(oAuth2User.getAuthorities(), oAuth2User.getIdToken(), "sub"), + authorities, + authentication.getAuthorizedClientRegistrationId() + ); + return authenticationWithAuthorities; + } + + private void addFirebaseTokenToAuthToken(OAuth2AuthenticationToken authenticationWithAuthorities) { + // Create a custom token for frontend Firebase authentication if user has ROLE_CURATOR role + if (SecurityUtils.hasAuthenticationAnyOfAuthorities(authenticationWithAuthorities, AuthoritiesConstants.CURATOR)) { + String email = authenticationWithAuthorities.getPrincipal().getAttribute("email"); + String firebaseCustomToken = null; + try { + Map additionalClaims = new HashMap<>(); + // This claim will be used in Firebase security rules for authorization. + additionalClaims.put(Constants.FIREBASE_AUTHORIZED_CLAIM, true); + firebaseCustomToken = FirebaseAuth.getInstance().createCustomTokenAsync(email, additionalClaims).get(); + } catch (InterruptedException | ExecutionException e) { + logger.error("Could not create Firebase custom token", e); + } + // Add additionalDetails containing firebase token to Authentication object + if (firebaseCustomToken != null) { + Map additionalDetails = new HashMap<>(); + additionalDetails.put(Constants.FIREBASE_CUSTOM_TOKEN, firebaseCustomToken); + authenticationWithAuthorities.setDetails(additionalDetails); + } + } + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/security/SecurityUtils.java b/src/main/java/org/mskcc/oncokb/curation/security/SecurityUtils.java new file mode 100644 index 000000000..7f544ee7e --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/security/SecurityUtils.java @@ -0,0 +1,137 @@ +package org.mskcc.oncokb.curation.security; + +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; +import org.springframework.security.oauth2.client.registration.ClientRegistration; +import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser; +import org.springframework.security.oauth2.core.oidc.user.OidcUser; +import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; + +/** + * Utility class for Spring Security. + */ +public final class SecurityUtils { + + private SecurityUtils() {} + + /** + * Get the login of the current user. + * + * @return the login of the current user. + */ + public static Optional getCurrentUserLogin() { + SecurityContext securityContext = SecurityContextHolder.getContext(); + return Optional.ofNullable(extractPrincipal(securityContext.getAuthentication())); + } + + private static String extractPrincipal(Authentication authentication) { + if (authentication == null) { + return null; + } else if (authentication.getPrincipal() instanceof UserDetails) { + UserDetails springSecurityUser = (UserDetails) authentication.getPrincipal(); + return springSecurityUser.getUsername(); + } else if (authentication instanceof JwtAuthenticationToken) { + return (String) ((JwtAuthenticationToken) authentication).getToken().getClaims().get("preferred_username"); + } else if (authentication.getPrincipal() instanceof DefaultOidcUser) { + Map attributes = ((DefaultOidcUser) authentication.getPrincipal()).getAttributes(); + if (attributes.containsKey("preferred_username")) { + return (String) attributes.get("preferred_username"); + } + } else if (authentication.getPrincipal() instanceof String) { + return (String) authentication.getPrincipal(); + } + return null; + } + + /** + * Check if a user is authenticated. + * + * @return true if the user is authenticated, false otherwise. + */ + public static boolean isAuthenticated() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + return authentication != null && getAuthorities(authentication).noneMatch(AuthoritiesConstants.ANONYMOUS::equals); + } + + /** + * Checks if the current user has any of the authorities. + * + * @param authorities the authorities to check. + * @return true if the current user has any of the authorities, false otherwise. + */ + public static boolean hasCurrentUserAnyOfAuthorities(String... authorities) { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + return hasAuthenticationAnyOfAuthorities(authentication, authorities); + } + + public static boolean hasAuthenticationAnyOfAuthorities(Authentication authentication, String... authorities) { + return ( + authentication != null && getAuthorities(authentication).anyMatch(authority -> Arrays.asList(authorities).contains(authority)) + ); + } + + /** + * Checks if the current user has none of the authorities. + * + * @param authorities the authorities to check. + * @return true if the current user has none of the authorities, false otherwise. + */ + public static boolean hasCurrentUserNoneOfAuthorities(String... authorities) { + return !hasCurrentUserAnyOfAuthorities(authorities); + } + + /** + * Checks if the current user has a specific authority. + * + * @param authority the authority to check. + * @return true if the current user has the authority, false otherwise. + */ + public static boolean hasCurrentUserThisAuthority(String authority) { + return hasCurrentUserAnyOfAuthorities(authority); + } + + private static Stream getAuthorities(Authentication authentication) { + Collection authorities = authentication instanceof JwtAuthenticationToken + ? extractAuthorityFromClaims(((JwtAuthenticationToken) authentication).getToken().getClaims()) + : authentication.getAuthorities(); + return authorities.stream().map(GrantedAuthority::getAuthority); + } + + public static List extractAuthorityFromClaims(Map claims) { + return mapRolesToGrantedAuthorities(getRolesFromClaims(claims)); + } + + @SuppressWarnings("unchecked") + private static Collection getRolesFromClaims(Map claims) { + return (Collection) claims.getOrDefault("roles", new ArrayList<>()); + } + + private static List mapRolesToGrantedAuthorities(Collection roles) { + return roles.stream().filter(role -> role.startsWith("ROLE_")).map(SimpleGrantedAuthority::new).collect(Collectors.toList()); + } + + public static String getKeycloakLogoutURL(ClientRegistration clientRegistration) { + StringBuilder logoutUrl = new StringBuilder(); + + // Get keycloak logout endpoint (host/auth/realms//protocol/openid-connect/logout) + logoutUrl.append(clientRegistration.getProviderDetails().getConfigurationMetadata().get("end_session_endpoint").toString()); + + // Get id token + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication instanceof OAuth2AuthenticationToken auth) { + OidcUser oAuth2User = (OidcUser) auth.getPrincipal(); + String idTokenHint = oAuth2User.getIdToken().getTokenValue(); + logoutUrl.append("?id_token_hint=").append(idTokenHint); + } + + return logoutUrl.toString(); + } +} diff --git a/src/main/java/org/mskcc/oncokb/transcript/security/SpringSecurityAuditorAware.java b/src/main/java/org/mskcc/oncokb/curation/security/SpringSecurityAuditorAware.java similarity index 82% rename from src/main/java/org/mskcc/oncokb/transcript/security/SpringSecurityAuditorAware.java rename to src/main/java/org/mskcc/oncokb/curation/security/SpringSecurityAuditorAware.java index 0e3d2d54f..708c1a747 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/security/SpringSecurityAuditorAware.java +++ b/src/main/java/org/mskcc/oncokb/curation/security/SpringSecurityAuditorAware.java @@ -1,7 +1,7 @@ -package org.mskcc.oncokb.transcript.security; +package org.mskcc.oncokb.curation.security; import java.util.Optional; -import org.mskcc.oncokb.transcript.config.Constants; +import org.mskcc.oncokb.curation.config.Constants; import org.springframework.data.domain.AuditorAware; import org.springframework.stereotype.Component; diff --git a/src/main/java/org/mskcc/oncokb/transcript/security/jwt/JWTConfigurer.java b/src/main/java/org/mskcc/oncokb/curation/security/jwt/JWTConfigurer.java similarity index 94% rename from src/main/java/org/mskcc/oncokb/transcript/security/jwt/JWTConfigurer.java rename to src/main/java/org/mskcc/oncokb/curation/security/jwt/JWTConfigurer.java index 55257be4e..c0db5b4b9 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/security/jwt/JWTConfigurer.java +++ b/src/main/java/org/mskcc/oncokb/curation/security/jwt/JWTConfigurer.java @@ -1,4 +1,4 @@ -package org.mskcc.oncokb.transcript.security.jwt; +package org.mskcc.oncokb.curation.security.jwt; import org.springframework.security.config.annotation.SecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.builders.HttpSecurity; diff --git a/src/main/java/org/mskcc/oncokb/transcript/security/jwt/JWTFilter.java b/src/main/java/org/mskcc/oncokb/curation/security/jwt/JWTFilter.java similarity index 86% rename from src/main/java/org/mskcc/oncokb/transcript/security/jwt/JWTFilter.java rename to src/main/java/org/mskcc/oncokb/curation/security/jwt/JWTFilter.java index 05167ebd3..a8649173a 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/security/jwt/JWTFilter.java +++ b/src/main/java/org/mskcc/oncokb/curation/security/jwt/JWTFilter.java @@ -1,11 +1,11 @@ -package org.mskcc.oncokb.transcript.security.jwt; +package org.mskcc.oncokb.curation.security.jwt; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; import java.io.IOException; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.util.StringUtils; diff --git a/src/main/java/org/mskcc/oncokb/transcript/security/jwt/TokenProvider.java b/src/main/java/org/mskcc/oncokb/curation/security/jwt/TokenProvider.java similarity index 88% rename from src/main/java/org/mskcc/oncokb/transcript/security/jwt/TokenProvider.java rename to src/main/java/org/mskcc/oncokb/curation/security/jwt/TokenProvider.java index 48fa68d8f..9d69027b4 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/security/jwt/TokenProvider.java +++ b/src/main/java/org/mskcc/oncokb/curation/security/jwt/TokenProvider.java @@ -1,11 +1,13 @@ -package org.mskcc.oncokb.transcript.security.jwt; +package org.mskcc.oncokb.curation.security.jwt; import io.jsonwebtoken.*; import io.jsonwebtoken.io.Decoders; import io.jsonwebtoken.security.Keys; import java.nio.charset.StandardCharsets; import java.security.Key; -import java.util.*; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -48,10 +50,10 @@ public TokenProvider(JHipsterProperties jHipsterProperties) { keyBytes = secret.getBytes(StandardCharsets.UTF_8); } key = Keys.hmacShaKeyFor(keyBytes); - jwtParser = Jwts.parserBuilder().setSigningKey(key).build(); + jwtParser = Jwts.parser().setSigningKey(key).build(); this.tokenValidityInMilliseconds = 1000 * jHipsterProperties.getSecurity().getAuthentication().getJwt().getTokenValidityInSeconds(); - this.tokenValidityInMillisecondsForRememberMe = - 1000 * jHipsterProperties.getSecurity().getAuthentication().getJwt().getTokenValidityInSecondsForRememberMe(); + this.tokenValidityInMillisecondsForRememberMe = 1000 * + jHipsterProperties.getSecurity().getAuthentication().getJwt().getTokenValidityInSecondsForRememberMe(); } public String createToken(Authentication authentication, boolean rememberMe) { @@ -65,8 +67,7 @@ public String createToken(Authentication authentication, boolean rememberMe) { validity = new Date(now + this.tokenValidityInMilliseconds); } - return Jwts - .builder() + return Jwts.builder() .setSubject(authentication.getName()) .claim(AUTHORITIES_KEY, authorities) .signWith(key, SignatureAlgorithm.HS512) @@ -77,8 +78,7 @@ public String createToken(Authentication authentication, boolean rememberMe) { public Authentication getAuthentication(String token) { Claims claims = jwtParser.parseClaimsJws(token).getBody(); - Collection authorities = Arrays - .stream(claims.get(AUTHORITIES_KEY).toString().split(",")) + Collection authorities = Arrays.stream(claims.get(AUTHORITIES_KEY).toString().split(",")) .filter(auth -> !auth.trim().isEmpty()) .map(SimpleGrantedAuthority::new) .collect(Collectors.toList()); diff --git a/src/main/java/org/mskcc/oncokb/curation/security/package-info.java b/src/main/java/org/mskcc/oncokb/curation/security/package-info.java new file mode 100644 index 000000000..8ea0ab8e6 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/security/package-info.java @@ -0,0 +1,4 @@ +/** + * Spring Security configuration. + */ +package org.mskcc.oncokb.curation.security; diff --git a/src/main/java/org/mskcc/oncokb/transcript/service/AlignmentService.java b/src/main/java/org/mskcc/oncokb/curation/service/AlignmentService.java similarity index 98% rename from src/main/java/org/mskcc/oncokb/transcript/service/AlignmentService.java rename to src/main/java/org/mskcc/oncokb/curation/service/AlignmentService.java index 03de17f11..aa922663f 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/service/AlignmentService.java +++ b/src/main/java/org/mskcc/oncokb/curation/service/AlignmentService.java @@ -1,10 +1,10 @@ -package org.mskcc.oncokb.transcript.service; +package org.mskcc.oncokb.curation.service; import java.util.Arrays; import java.util.HashSet; import java.util.Set; -import org.mskcc.oncokb.transcript.domain.Alignment; -import org.mskcc.oncokb.transcript.domain.AlignmentResult; +import org.mskcc.oncokb.curation.domain.Alignment; +import org.mskcc.oncokb.curation.domain.AlignmentResult; import org.springframework.stereotype.Service; /** diff --git a/src/main/java/org/mskcc/oncokb/curation/service/AlleleStateService.java b/src/main/java/org/mskcc/oncokb/curation/service/AlleleStateService.java new file mode 100644 index 000000000..6c66c5b39 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/AlleleStateService.java @@ -0,0 +1,101 @@ +package org.mskcc.oncokb.curation.service; + +import java.util.List; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.AlleleState; +import org.mskcc.oncokb.curation.repository.AlleleStateRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * Service Implementation for managing {@link AlleleState}. + */ +@Service +@Transactional +public class AlleleStateService { + + private final Logger log = LoggerFactory.getLogger(AlleleStateService.class); + + private final AlleleStateRepository alleleStateRepository; + + public AlleleStateService(AlleleStateRepository alleleStateRepository) { + this.alleleStateRepository = alleleStateRepository; + } + + /** + * Save a alleleState. + * + * @param alleleState the entity to save. + * @return the persisted entity. + */ + public AlleleState save(AlleleState alleleState) { + log.debug("Request to save AlleleState : {}", alleleState); + return alleleStateRepository.save(alleleState); + } + + /** + * Partially update a alleleState. + * + * @param alleleState the entity to update partially. + * @return the persisted entity. + */ + public Optional partialUpdate(AlleleState alleleState) { + log.debug("Request to partially update AlleleState : {}", alleleState); + + return alleleStateRepository + .findById(alleleState.getId()) + .map(existingAlleleState -> { + if (alleleState.getName() != null) { + existingAlleleState.setName(alleleState.getName()); + } + + return existingAlleleState; + }) + .map(alleleStateRepository::save); + } + + /** + * Get all the alleleStates. + * + * @return the list of entities. + */ + @Transactional(readOnly = true) + public List findAll() { + log.debug("Request to get all AlleleStates"); + return alleleStateRepository.findAll(); + } + + /** + * Get one alleleState by id. + * + * @param id the id of the entity. + * @return the entity. + */ + @Transactional(readOnly = true) + public Optional findOne(Long id) { + log.debug("Request to get AlleleState : {}", id); + return alleleStateRepository.findById(id); + } + + /** + * get one alleleState by name + * @param name the name of the entity + * @return the entity + */ + @Transactional(readOnly = true) + public Optional findByNameIgnoreCase(String name) { + return alleleStateRepository.findByNameIgnoreCase(name); + } + + /** + * Delete the alleleState by id. + * + * @param id the id of the entity. + */ + public void delete(Long id) { + log.debug("Request to delete AlleleState : {}", id); + alleleStateRepository.deleteById(id); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/AlterationQueryService.java b/src/main/java/org/mskcc/oncokb/curation/service/AlterationQueryService.java new file mode 100644 index 000000000..526934b78 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/AlterationQueryService.java @@ -0,0 +1,159 @@ +package org.mskcc.oncokb.curation.service; + +import jakarta.persistence.criteria.JoinType; +import java.util.List; +import org.mskcc.oncokb.curation.domain.*; // for static metamodels +import org.mskcc.oncokb.curation.domain.Alteration; +import org.mskcc.oncokb.curation.repository.AlterationRepository; +import org.mskcc.oncokb.curation.service.criteria.AlterationCriteria; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import tech.jhipster.service.QueryService; +import tech.jhipster.service.filter.StringFilter; + +/** + * Service for executing complex queries for {@link Alteration} entities in the database. + * The main input is a {@link AlterationCriteria} which gets converted to {@link Specification}, + * in a way that all the filters must apply. + * It returns a {@link List} of {@link Alteration} or a {@link Page} of {@link Alteration} which fulfills the criteria. + */ +@Service +@Transactional(readOnly = true) +public class AlterationQueryService extends QueryService { + + private final Logger log = LoggerFactory.getLogger(AlterationQueryService.class); + + private final AlterationRepository alterationRepository; + + public AlterationQueryService(AlterationRepository alterationRepository) { + this.alterationRepository = alterationRepository; + } + + @Transactional(readOnly = true) + public Page findBySearchQuery(String query, Pageable page) { + AlterationCriteria criteria = new AlterationCriteria(); + StringFilter stringFilter = new StringFilter(); + stringFilter.setContains(query); + criteria.setName(stringFilter); + return findByCriteria(criteria, page); + } + + /** + * Return a {@link List} of {@link Alteration} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public List findByCriteria(AlterationCriteria criteria) { + log.debug("find by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return alterationRepository.findAll(specification); + } + + /** + * Return a {@link Page} of {@link Alteration} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @param page The page, which should be returned. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public Page findByCriteria(AlterationCriteria criteria, Pageable page) { + log.debug("find by criteria : {}, page: {}", criteria, page); + final Specification specification = createSpecification(criteria); + return alterationRepository.findAll(specification, page); + } + + /** + * Return the number of matching entities in the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the number of matching entities. + */ + @Transactional(readOnly = true) + public long countByCriteria(AlterationCriteria criteria) { + log.debug("count by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return alterationRepository.count(specification); + } + + /** + * Function to convert {@link AlterationCriteria} to a {@link Specification} + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching {@link Specification} of the entity. + */ + protected Specification createSpecification(AlterationCriteria criteria) { + Specification specification = Specification.where(null); + if (criteria != null) { + // This has to be called first, because the distinct method returns null + if (criteria.getDistinct() != null) { + specification = specification.or(distinct(criteria.getDistinct())); + } + if (criteria.getId() != null) { + specification = specification.or(buildRangeSpecification(criteria.getId(), Alteration_.id)); + } + if (criteria.getType() != null) { + specification = specification.or(buildSpecification(criteria.getType(), Alteration_.type)); + } + if (criteria.getName() != null) { + specification = specification.or(buildStringSpecification(criteria.getName(), Alteration_.name)); + } + if (criteria.getAlteration() != null) { + specification = specification.or(buildStringSpecification(criteria.getAlteration(), Alteration_.alteration)); + } + if (criteria.getProteinChange() != null) { + specification = specification.or(buildStringSpecification(criteria.getProteinChange(), Alteration_.proteinChange)); + } + if (criteria.getStart() != null) { + specification = specification.or(buildRangeSpecification(criteria.getStart(), Alteration_.start)); + } + if (criteria.getEnd() != null) { + specification = specification.or(buildRangeSpecification(criteria.getEnd(), Alteration_.end)); + } + if (criteria.getRefResidues() != null) { + specification = specification.or(buildStringSpecification(criteria.getRefResidues(), Alteration_.refResidues)); + } + if (criteria.getVariantResidues() != null) { + specification = specification.or(buildStringSpecification(criteria.getVariantResidues(), Alteration_.variantResidues)); + } + if (criteria.getFlagId() != null) { + specification = specification.or( + buildSpecification(criteria.getFlagId(), root -> root.join(Alteration_.flags, JoinType.LEFT).get(Flag_.id)) + ); + } + if (criteria.getGeneId() != null) { + specification = specification.or( + buildSpecification(criteria.getGeneId(), root -> root.join(Alteration_.genes, JoinType.LEFT).get(Gene_.id)) + ); + } + if (criteria.getTranscriptId() != null) { + specification = specification.or( + buildSpecification( + criteria.getTranscriptId(), + root -> root.join(Alteration_.transcripts, JoinType.LEFT).get(Transcript_.id) + ) + ); + } + if (criteria.getConsequenceId() != null) { + specification = specification.or( + buildSpecification( + criteria.getConsequenceId(), + root -> root.join(Alteration_.consequence, JoinType.LEFT).get(Consequence_.id) + ) + ); + } + if (criteria.getAssociationId() != null) { + specification = specification.or( + buildSpecification( + criteria.getAssociationId(), + root -> root.join(Alteration_.associations, JoinType.LEFT).get(Association_.id) + ) + ); + } + } + return specification; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/AlterationService.java b/src/main/java/org/mskcc/oncokb/curation/service/AlterationService.java new file mode 100644 index 000000000..d739a5981 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/AlterationService.java @@ -0,0 +1,179 @@ +package org.mskcc.oncokb.curation.service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; +import org.mskcc.oncokb.curation.domain.Alteration; +import org.mskcc.oncokb.curation.domain.Consequence; +import org.mskcc.oncokb.curation.domain.Gene; +import org.mskcc.oncokb.curation.repository.AlterationRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * Service Implementation for managing {@link Alteration}. + */ +@Service +@Transactional +public class AlterationService { + + private final Logger log = LoggerFactory.getLogger(AlterationService.class); + + private final AlterationRepository alterationRepository; + + public AlterationService(AlterationRepository alterationRepository) { + this.alterationRepository = alterationRepository; + } + + /** + * Save a alteration. + * + * @param alteration the entity to save. + * @return the persisted entity. + */ + public Alteration save(Alteration alteration) { + log.debug("Request to save Alteration : {}", alteration); + return alterationRepository.save(alteration); + } + + /** + * Partially update a alteration. + * + * @param alteration the entity to update partially. + * @return the persisted entity. + */ + public Optional partialUpdate(Alteration alteration) { + log.debug("Request to partially update Alteration : {}", alteration); + + return alterationRepository + .findById(alteration.getId()) + .map(existingAlteration -> { + if (alteration.getType() != null) { + existingAlteration.setType(alteration.getType()); + } + if (alteration.getName() != null) { + existingAlteration.setName(alteration.getName()); + } + if (alteration.getAlteration() != null) { + existingAlteration.setAlteration(alteration.getAlteration()); + } + if (alteration.getProteinChange() != null) { + existingAlteration.setProteinChange(alteration.getProteinChange()); + } + if (alteration.getStart() != null) { + existingAlteration.setStart(alteration.getStart()); + } + if (alteration.getEnd() != null) { + existingAlteration.setEnd(alteration.getEnd()); + } + if (alteration.getRefResidues() != null) { + existingAlteration.setRefResidues(alteration.getRefResidues()); + } + if (alteration.getVariantResidues() != null) { + existingAlteration.setVariantResidues(alteration.getVariantResidues()); + } + + return existingAlteration; + }) + .map(alterationRepository::save); + } + + /** + * Get all the alterations. + * + * @param pageable the pagination information. + * @return the list of entities. + */ + @Transactional(readOnly = true) + public Page findAll(Pageable pageable) { + log.debug("Request to get all Alterations"); + return alterationRepository.findAll(pageable); + } + + /** + * Get all the alterations with eager load of many-to-many relationships. + * + * @return the list of entities. + */ + public Page findAllWithEagerRelationships(Pageable pageable) { + Page alterationPage = alterationRepository.findAll(pageable); + List enrichedAlterations = alterationRepository.findAllWithEagerRelationships( + alterationPage.getContent().stream().map(Alteration::getId).collect(Collectors.toList()) + ); + return new PageImpl<>(enrichedAlterations, pageable, alterationPage.getTotalElements()); + } + + /** + * Get one alteration by id. + * + * @param id the id of the entity. + * @return the entity. + */ + @Transactional(readOnly = true) + public Optional findOne(Long id) { + log.debug("Request to get Alteration : {}", id); + return alterationRepository.findOneWithEagerRelationships(id); + } + + /** + * Get alterations by their id. + * + * @param ids the list of id. + * @return list of entity. + */ + @Transactional(readOnly = true) + public List findAllWithEagerRelationshipsByIds(List ids) { + log.debug("Request to get Alteration : {}", ids); + return alterationRepository.findAllWithEagerRelationships(ids); + } + + @Transactional(readOnly = true) + public List findByGeneId(Long geneId) { + return alterationRepository.findByGenesId(geneId); + } + + public Page search(String query, Pageable pageable) { + Page alterationPage = alterationRepository.searchAlteration(query, pageable); + Page page = new PageImpl<>( + alterationRepository.findAllWithEagerRelationships( + alterationPage.getContent().stream().map(Alteration::getId).collect(Collectors.toList()) + ), + pageable, + alterationPage.getTotalElements() + ); + return page; + } + + public List findByNameOrAlterationAndGenesId(String query, Long geneId) { + return alterationRepository.findByNameOrAlterationAndGenesId(query, geneId); + } + + public List findByGeneAndConsequenceThatOverlap(List genes, Consequence consequence, Integer end, Integer start) { + if (start == null || end == null) { + return new ArrayList<>(); + } + return alterationRepository.findByGeneAndConsequenceThatOverlap( + genes.stream().map(Gene::getId).collect(Collectors.toList()), + consequence, + end, + start + ); + } + + /** + * Delete the alteration by id. + * + * @param id the id of the entity. + */ + public void delete(Long id) { + log.debug("Request to delete Alteration : {}", id); + alterationRepository.deleteById(id); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/AnnotationService.java b/src/main/java/org/mskcc/oncokb/curation/service/AnnotationService.java new file mode 100644 index 000000000..d68878c44 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/AnnotationService.java @@ -0,0 +1,63 @@ +package org.mskcc.oncokb.curation.service; + +import java.util.*; +import org.mskcc.oncokb.curation.domain.Alteration; +import org.mskcc.oncokb.curation.domain.enumeration.MutationConsequence; +import org.springframework.stereotype.Service; + +@Service +public class AnnotationService { + + private final AlterationService alterationService; + + public AnnotationService(AlterationService alterationService) { + this.alterationService = alterationService; + } + + public LinkedHashSet findRelevantAlterations(Alteration alteration) { + LinkedHashSet alterations = new LinkedHashSet<>(); + + if (alteration.getConsequence().getTerm().equals("synonymous_variant")) { + return alterations; + } + + // Find exact match + Alteration matchedAlt = null; + List matchedAlts = alterationService.findByNameOrAlterationAndGenesId( + alteration.getAlteration(), + alteration.getGenes().iterator().next().getId() + ); + if (!matchedAlts.isEmpty()) { + matchedAlt = matchedAlts.iterator().next(); + } + + if (matchedAlt != null) { + alterations.add(matchedAlt); + } + + if ( + alteration.getRefResidues() != null && + alteration.getStart() != null && + MutationConsequence.MISSENSE_VARIANT.name().equals(alteration.getConsequence().getTerm()) + ) { + // add positional variant + alterations.addAll( + alterationService.findByNameOrAlterationAndGenesId( + alteration.getRefResidues() + alteration.getStart(), + alteration.getGenes().iterator().next().getId() + ) + ); + } + + alterations.addAll( + alterationService.findByGeneAndConsequenceThatOverlap( + new ArrayList<>(alteration.getGenes()), + alteration.getConsequence(), + alteration.getEnd(), + alteration.getStart() + ) + ); + // add overlap variant with the same consequence + return alterations; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/ApiProxyService.java b/src/main/java/org/mskcc/oncokb/curation/service/ApiProxyService.java new file mode 100644 index 000000000..e0f3314f4 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/ApiProxyService.java @@ -0,0 +1,38 @@ +package org.mskcc.oncokb.curation.service; + +import jakarta.servlet.http.HttpServletRequest; +import java.net.URI; +import java.net.URISyntaxException; +import org.mskcc.oncokb.curation.config.application.ApplicationProperties; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.*; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +/** + * * Service for proxying oncokb core requests + * *

+ * * We use the {@link Async} annotation to send emails asynchronously. + * */ +@Service +public class ApiProxyService { + + @Autowired + private ApplicationProperties applicationProperties; + + public URI prepareURI(HttpServletRequest request) throws URISyntaxException { + String queryString = request.getQueryString(); + return new URI( + applicationProperties.getOncokbCore().getUrl() + request.getRequestURI() + (queryString == null ? "" : "?" + queryString) + ); + } + + public HttpHeaders prepareHttpHeaders(String contentType) { + HttpHeaders httpHeaders = new HttpHeaders(); + if (contentType != null) { + httpHeaders.setContentType(MediaType.valueOf(contentType)); + } + + return httpHeaders; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/ArticleQueryService.java b/src/main/java/org/mskcc/oncokb/curation/service/ArticleQueryService.java new file mode 100644 index 000000000..c46c101e1 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/ArticleQueryService.java @@ -0,0 +1,134 @@ +package org.mskcc.oncokb.curation.service; + +import jakarta.persistence.criteria.JoinType; +import java.util.List; +import org.mskcc.oncokb.curation.domain.*; // for static metamodels +import org.mskcc.oncokb.curation.domain.Article; +import org.mskcc.oncokb.curation.repository.ArticleRepository; +import org.mskcc.oncokb.curation.service.criteria.ArticleCriteria; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import tech.jhipster.service.QueryService; +import tech.jhipster.service.filter.StringFilter; + +/** + * Service for executing complex queries for {@link Article} entities in the database. + * The main input is a {@link ArticleCriteria} which gets converted to {@link Specification}, + * in a way that all the filters must apply. + * It returns a {@link List} of {@link Article} or a {@link Page} of {@link Article} which fulfills the criteria. + */ +@Service +@Transactional(readOnly = true) +public class ArticleQueryService extends QueryService

{ + + private final Logger log = LoggerFactory.getLogger(ArticleQueryService.class); + + private final ArticleRepository articleRepository; + + public ArticleQueryService(ArticleRepository articleRepository) { + this.articleRepository = articleRepository; + } + + @Transactional(readOnly = true) + public Page
findBySearchQuery(String query, Pageable page) { + ArticleCriteria criteria = new ArticleCriteria(); + StringFilter stringFilter = new StringFilter(); + stringFilter.setContains(query); + criteria.setUid(stringFilter); + return findByCriteria(criteria, page); + } + + /** + * Return a {@link List} of {@link Article} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public List
findByCriteria(ArticleCriteria criteria) { + log.debug("find by criteria : {}", criteria); + final Specification
specification = createSpecification(criteria); + return articleRepository.findAll(specification); + } + + /** + * Return a {@link Page} of {@link Article} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @param page The page, which should be returned. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public Page
findByCriteria(ArticleCriteria criteria, Pageable page) { + log.debug("find by criteria : {}, page: {}", criteria, page); + final Specification
specification = createSpecification(criteria); + return articleRepository.findAll(specification, page); + } + + /** + * Return the number of matching entities in the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the number of matching entities. + */ + @Transactional(readOnly = true) + public long countByCriteria(ArticleCriteria criteria) { + log.debug("count by criteria : {}", criteria); + final Specification
specification = createSpecification(criteria); + return articleRepository.count(specification); + } + + /** + * Function to convert {@link ArticleCriteria} to a {@link Specification} + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching {@link Specification} of the entity. + */ + protected Specification
createSpecification(ArticleCriteria criteria) { + Specification
specification = Specification.where(null); + if (criteria != null) { + // This has to be called first, because the distinct method returns null + if (criteria.getDistinct() != null) { + specification = specification.or(distinct(criteria.getDistinct())); + } + if (criteria.getId() != null) { + specification = specification.or(buildRangeSpecification(criteria.getId(), Article_.id)); + } + if (criteria.getType() != null) { + specification = specification.or(buildSpecification(criteria.getType(), Article_.type)); + } + if (criteria.getUid() != null) { + specification = specification.or(buildStringSpecification(criteria.getUid(), Article_.uid)); + } + if (criteria.getLink() != null) { + specification = specification.or(buildStringSpecification(criteria.getLink(), Article_.link)); + } + if (criteria.getAuthors() != null) { + specification = specification.or(buildStringSpecification(criteria.getAuthors(), Article_.authors)); + } + if (criteria.getDate() != null) { + specification = specification.or(buildRangeSpecification(criteria.getDate(), Article_.date)); + } + if (criteria.getFlagId() != null) { + specification = specification.or( + buildSpecification(criteria.getFlagId(), root -> root.join(Article_.flags, JoinType.LEFT).get(Flag_.id)) + ); + } + if (criteria.getSynonymId() != null) { + specification = specification.or( + buildSpecification(criteria.getSynonymId(), root -> root.join(Article_.synonyms, JoinType.LEFT).get(Synonym_.id)) + ); + } + if (criteria.getAssociationId() != null) { + specification = specification.or( + buildSpecification( + criteria.getAssociationId(), + root -> root.join(Article_.associations, JoinType.LEFT).get(Association_.id) + ) + ); + } + } + return specification; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/ArticleService.java b/src/main/java/org/mskcc/oncokb/curation/service/ArticleService.java new file mode 100644 index 000000000..16a00c7b1 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/ArticleService.java @@ -0,0 +1,165 @@ +package org.mskcc.oncokb.curation.service; + +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.Article; +import org.mskcc.oncokb.curation.domain.enumeration.ArticleType; +import org.mskcc.oncokb.curation.repository.ArticleRepository; +import org.mskcc.oncokb.curation.service.dto.pubmed.PubMedDTO; +import org.mskcc.oncokb.curation.service.mapper.PubMedMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * Service Implementation for managing {@link Article}. + */ +@Service +@Transactional +public class ArticleService { + + private final Logger log = LoggerFactory.getLogger(ArticleService.class); + + private final ArticleRepository articleRepository; + private final NihEutilsService nihEutilsService; + private final PubMedMapper pubMedMapper; + + public ArticleService(ArticleRepository articleRepository, NihEutilsService nihEutilsService, PubMedMapper pubMedMapper) { + this.articleRepository = articleRepository; + this.nihEutilsService = nihEutilsService; + this.pubMedMapper = pubMedMapper; + } + + /** + * Save a article. + * + * @param article the entity to save. + * @return the persisted entity. + */ + public Article save(Article article) { + log.debug("Request to save Article : {}", article); + return articleRepository.save(article); + } + + /** + * Partially update a article. + * + * @param article the entity to update partially. + * @return the persisted entity. + */ + public Optional
partialUpdate(Article article) { + log.debug("Request to partially update Article : {}", article); + + return articleRepository + .findById(article.getId()) + .map(existingArticle -> { + if (article.getType() != null) { + existingArticle.setType(article.getType()); + } + if (article.getUid() != null) { + existingArticle.setUid(article.getUid()); + } + if (article.getTitle() != null) { + existingArticle.setTitle(article.getTitle()); + } + if (article.getContent() != null) { + existingArticle.setContent(article.getContent()); + } + if (article.getLink() != null) { + existingArticle.setLink(article.getLink()); + } + if (article.getAuthors() != null) { + existingArticle.setAuthors(article.getAuthors()); + } + if (article.getDate() != null) { + existingArticle.setDate(article.getDate()); + } + + return existingArticle; + }) + .map(articleRepository::save); + } + + /** + * Get all the articles. + * + * @param pageable the pagination information. + * @return the list of entities. + */ + @Transactional(readOnly = true) + public Page
findAll(Pageable pageable) { + log.debug("Request to get all Articles"); + return articleRepository.findAll(pageable); + } + + @Transactional(readOnly = true) + public Optional
findByContent(String content) { + log.debug("Request to get Article : {}", content); + return articleRepository.findByContent(content); + } + + @Transactional(readOnly = true) + public Optional
findByLink(String link) { + log.debug("Request to get Article : {}", link); + return articleRepository.findByLink(link); + } + + @Transactional(readOnly = true) + public Optional
findByPmid(String pmid) { + log.debug("Request to get Article by PMID : {}", pmid); + return findByTypeAndUid(ArticleType.PUBMED, pmid); + } + + @Transactional(readOnly = true) + public Optional
findByTypeAndUid(ArticleType articleType, String uid) { + log.debug("Request to get Article : {} {}", articleType, uid); + return articleRepository.findByTypeAndUid(articleType, uid); + } + + /** + * Get all the articles with eager load of many-to-many relationships. + * + * @return the list of entities. + */ + public Page
findAllWithEagerRelationships(Pageable pageable) { + return articleRepository.findAllWithEagerRelationships(pageable); + } + + /** + * Get one article by id. + * + * @param id the id of the entity. + * @return the entity. + */ + @Transactional(readOnly = true) + public Optional
findOne(Long id) { + log.debug("Request to get Article : {}", id); + return articleRepository.findOneWithEagerRelationships(id); + } + + /** + * Delete the article by id. + * + * @param id the id of the entity. + */ + public void delete(Long id) { + log.debug("Request to delete Article : {}", id); + articleRepository.deleteById(id); + } + + public Article fetchAndSavePubMed(String pmid) { + PubMedDTO pubMedDTO = nihEutilsService.fetchPubmedArticle(pmid); + // We would like to retry if there is no data returned. Eutils sometime has glitch returning empty result but usually resolved in second try. + if (pubMedDTO == null) { + pubMedDTO = nihEutilsService.fetchPubmedArticle(pmid); + } + if (pubMedDTO == null) { + log.error("No PubMed info found for {}", pmid); + return null; + } else { + return this.save(pubMedMapper.pubMedDTOToArticle(pubMedDTO)); + } + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/AssociationService.java b/src/main/java/org/mskcc/oncokb/curation/service/AssociationService.java new file mode 100644 index 000000000..2723ee811 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/AssociationService.java @@ -0,0 +1,153 @@ +package org.mskcc.oncokb.curation.service; + +import java.util.Iterator; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; +import org.mskcc.oncokb.curation.domain.Association; +import org.mskcc.oncokb.curation.domain.FdaSubmission; +import org.mskcc.oncokb.curation.repository.AssociationRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * Service Implementation for managing {@link Association}. + */ +@Service +@Transactional +public class AssociationService { + + private final Logger log = LoggerFactory.getLogger(AssociationService.class); + + private final AssociationRepository associationRepository; + + private final FdaSubmissionService fdaSubmissionService; + + public AssociationService(AssociationRepository associationRepository, FdaSubmissionService fdaSubmissionService) { + this.associationRepository = associationRepository; + this.fdaSubmissionService = fdaSubmissionService; + } + + /** + * Save a association. + * + * @param association the entity to save. + * @return the persisted entity. + */ + public Association save(Association association) { + log.debug("Request to save Association : {}", association); + Association savedAssociation = associationRepository.save(association); + // FDA Submission needs to be updated individually, FDASubmission is the owner of the m2m relationship + if (!association.getFdaSubmissions().isEmpty()) { + association + .getFdaSubmissions() + .forEach(fdaSubmission -> { + if (fdaSubmission.getId() != null) { + Optional fdaSubmissionOptional = fdaSubmissionService.findOne(fdaSubmission.getId()); + fdaSubmissionOptional.ifPresent(submission -> submission.getAssociations().add(savedAssociation)); + } + }); + } + return this.findOne(savedAssociation.getId()).orElseThrow(); + } + + /** + * Partially update a association. + * + * @param association the entity to update partially. + * @return the persisted entity. + */ + public Optional partialUpdate(Association association) { + log.debug("Request to partially update Association : {}", association); + + return associationRepository + .findById(association.getId()) + .map(existingAssociation -> { + if (association.getName() != null) { + existingAssociation.setName(association.getName()); + } + + return existingAssociation; + }) + .map(associationRepository::save); + } + + /** + * Get all the associations. + * + * @return the list of entities. + */ + @Transactional(readOnly = true) + public List findAll() { + log.debug("Request to get all Associations"); + return associationRepository.findAllWithEagerRelationships(); + } + + /** + * Get all the associations with eager load of many-to-many relationships. + * + * @return the list of entities. + */ + public Page findAllWithEagerRelationships(Pageable pageable) { + return associationRepository.findAllWithEagerRelationships(pageable); + } + + /** + * Get all the associations where Evidence is {@code null}. + * @return the list of entities. + */ + @Transactional(readOnly = true) + public List findAllWhereEvidenceIsNull() { + log.debug("Request to get all associations where Evidence is null"); + return associationRepository + .findAll() + .stream() + .filter(association -> association.getEvidence() == null) + .collect(Collectors.toList()); + } + + /** + * Get one association by id. + * + * @param id the id of the entity. + * @return the entity. + */ + @Transactional(readOnly = true) + public Optional findOne(Long id) { + log.debug("Request to get Association : {}", id); + return associationRepository.findOneWithEagerRelationships(id); + } + + /** + * Delete the association by id. + * + * @param id the id of the entity. + */ + public void delete(Long id) throws Exception { + log.debug("Request to delete Association : {}", id); + Optional associationOptional = findOne(id); + if (associationOptional.isEmpty()) { + throw new Exception("Association id: " + id + " does not exist"); + } + if (associationOptional.orElseThrow().getFdaSubmissions() != null) { + associationOptional.orElseThrow().getFdaSubmissions().remove(this); + Iterator iterator = associationOptional.orElseThrow().getFdaSubmissions().iterator(); + while (iterator.hasNext()) { + FdaSubmission fdaSubmission = iterator.next(); + if (fdaSubmission.getId() != null) { + Optional fdaSubmissionOptional = fdaSubmissionService.findOne(fdaSubmission.getId()); + if (fdaSubmissionOptional.isPresent()) { + fdaSubmissionOptional.orElseThrow().getAssociations().remove(associationOptional.orElseThrow()); + fdaSubmissionService.save(fdaSubmissionOptional.orElseThrow()); + } + } + } + } + associationRepository.delete(associationOptional.orElseThrow()); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/CancerTypeQueryService.java b/src/main/java/org/mskcc/oncokb/curation/service/CancerTypeQueryService.java new file mode 100644 index 000000000..9c60e2802 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/CancerTypeQueryService.java @@ -0,0 +1,140 @@ +package org.mskcc.oncokb.curation.service; + +import jakarta.persistence.criteria.JoinType; +import java.util.List; +import org.mskcc.oncokb.curation.domain.*; // for static metamodels +import org.mskcc.oncokb.curation.domain.CancerType; +import org.mskcc.oncokb.curation.repository.CancerTypeRepository; +import org.mskcc.oncokb.curation.service.criteria.CancerTypeCriteria; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import tech.jhipster.service.QueryService; + +/** + * Service for executing complex queries for {@link CancerType} entities in the database. + * The main input is a {@link CancerTypeCriteria} which gets converted to {@link Specification}, + * in a way that all the filters must apply. + * It returns a {@link List} of {@link CancerType} or a {@link Page} of {@link CancerType} which fulfills the criteria. + */ +@Service +@Transactional(readOnly = true) +public class CancerTypeQueryService extends QueryService { + + private final Logger log = LoggerFactory.getLogger(CancerTypeQueryService.class); + + private final CancerTypeRepository cancerTypeRepository; + + public CancerTypeQueryService(CancerTypeRepository cancerTypeRepository) { + this.cancerTypeRepository = cancerTypeRepository; + } + + @Transactional(readOnly = true) + public Page findBySearchQuery(String query, Pageable page) { + return cancerTypeRepository.findAllByQueryPrioritizeStartsWith(query, query, page); + } + + /** + * Return a {@link List} of {@link CancerType} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public List findByCriteria(CancerTypeCriteria criteria) { + log.debug("find by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return cancerTypeRepository.findAll(specification); + } + + /** + * Return a {@link Page} of {@link CancerType} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @param page The page, which should be returned. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public Page findByCriteria(CancerTypeCriteria criteria, Pageable page) { + log.debug("find by criteria : {}, page: {}", criteria, page); + final Specification specification = createSpecification(criteria); + return cancerTypeRepository.findAll(specification, page); + } + + /** + * Return the number of matching entities in the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the number of matching entities. + */ + @Transactional(readOnly = true) + public long countByCriteria(CancerTypeCriteria criteria) { + log.debug("count by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return cancerTypeRepository.count(specification); + } + + /** + * Function to convert {@link CancerTypeCriteria} to a {@link Specification} + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching {@link Specification} of the entity. + */ + protected Specification createSpecification(CancerTypeCriteria criteria) { + Specification specification = Specification.where(null); + if (criteria != null) { + // This has to be called first, because the distinct method returns null + if (criteria.getDistinct() != null) { + specification = specification.or(distinct(criteria.getDistinct())); + } + if (criteria.getId() != null) { + specification = specification.or(buildRangeSpecification(criteria.getId(), CancerType_.id)); + } + if (criteria.getCode() != null) { + specification = specification.or(buildStringSpecification(criteria.getCode(), CancerType_.code)); + } + if (criteria.getColor() != null) { + specification = specification.or(buildStringSpecification(criteria.getColor(), CancerType_.color)); + } + if (criteria.getLevel() != null) { + specification = specification.or(buildRangeSpecification(criteria.getLevel(), CancerType_.level)); + } + if (criteria.getMainType() != null) { + specification = specification.or(buildStringSpecification(criteria.getMainType(), CancerType_.mainType)); + } + if (criteria.getSubtype() != null) { + specification = specification.or(buildStringSpecification(criteria.getSubtype(), CancerType_.subtype)); + } + if (criteria.getTissue() != null) { + specification = specification.or(buildStringSpecification(criteria.getTissue(), CancerType_.tissue)); + } + if (criteria.getTumorForm() != null) { + specification = specification.or(buildSpecification(criteria.getTumorForm(), CancerType_.tumorForm)); + } + if (criteria.getChildrenId() != null) { + specification = specification.or( + buildSpecification(criteria.getChildrenId(), root -> root.join(CancerType_.children, JoinType.LEFT).get(CancerType_.id)) + ); + } + if (criteria.getSynonymId() != null) { + specification = specification.or( + buildSpecification(criteria.getSynonymId(), root -> root.join(CancerType_.synonyms, JoinType.LEFT).get(Synonym_.id)) + ); + } + if (criteria.getParentId() != null) { + specification = specification.or( + buildSpecification(criteria.getParentId(), root -> root.join(CancerType_.parent, JoinType.LEFT).get(CancerType_.id)) + ); + } + if (criteria.getAssociationId() != null) { + specification = specification.or( + buildSpecification( + criteria.getAssociationId(), + root -> root.join(CancerType_.associations, JoinType.LEFT).get(Association_.id) + ) + ); + } + } + return specification; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/CancerTypeService.java b/src/main/java/org/mskcc/oncokb/curation/service/CancerTypeService.java new file mode 100644 index 000000000..d84e16f7d --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/CancerTypeService.java @@ -0,0 +1,351 @@ +package org.mskcc.oncokb.curation.service; + +import com.mysql.cj.util.StringUtils; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; +import org.mskcc.oncokb.curation.domain.CancerType; +import org.mskcc.oncokb.curation.domain.RelevantCancerTypeBody; +import org.mskcc.oncokb.curation.domain.RelevantCancerTypeQuery; +import org.mskcc.oncokb.curation.domain.enumeration.TumorForm; +import org.mskcc.oncokb.curation.repository.CancerTypeRepository; +import org.mskcc.oncokb.curation.util.CancerTypeUtils; +import org.mskcc.oncokb.curation.util.enumeration.RelevantCancerTypeDirection; +import org.mskcc.oncokb.curation.util.enumeration.SpecialCancerType; +import org.oncokb.client.Evidence.LevelOfEvidenceEnum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * Service Implementation for managing {@link CancerType}. + */ +@Service +@Transactional +public class CancerTypeService { + + private final Logger log = LoggerFactory.getLogger(CancerTypeService.class); + + private final CancerTypeRepository cancerTypeRepository; + + public CancerTypeService(CancerTypeRepository cancerTypeRepository) { + this.cancerTypeRepository = cancerTypeRepository; + } + + /** + * Save a cancerType. + * + * @param cancerType the entity to save. + * @return the persisted entity. + */ + public CancerType save(CancerType cancerType) { + log.debug("Request to save CancerType : {}", cancerType); + return cancerTypeRepository.save(cancerType); + } + + /** + * Partially update a cancerType. + * + * @param cancerType the entity to update partially. + * @return the persisted entity. + */ + public Optional partialUpdate(CancerType cancerType) { + log.debug("Request to partially update CancerType : {}", cancerType); + + return cancerTypeRepository + .findById(cancerType.getId()) + .map(existingCancerType -> { + if (cancerType.getCode() != null) { + existingCancerType.setCode(cancerType.getCode()); + } + if (cancerType.getColor() != null) { + existingCancerType.setColor(cancerType.getColor()); + } + if (cancerType.getLevel() != null) { + existingCancerType.setLevel(cancerType.getLevel()); + } + if (cancerType.getMainType() != null) { + existingCancerType.setMainType(cancerType.getMainType()); + } + if (cancerType.getSubtype() != null) { + existingCancerType.setSubtype(cancerType.getSubtype()); + } + if (cancerType.getTissue() != null) { + existingCancerType.setTissue(cancerType.getTissue()); + } + if (cancerType.getTumorForm() != null) { + existingCancerType.setTumorForm(cancerType.getTumorForm()); + } + + return existingCancerType; + }) + .map(cancerTypeRepository::save); + } + + /** + * Get all the cancerTypes. + * + * @param pageable the pagination information. + * @return the list of entities. + */ + @Transactional(readOnly = true) + public Page findAll(Pageable pageable) { + log.debug("Request to get all CancerTypes"); + return cancerTypeRepository.findAll(pageable); + } + + /** + * Get all the cancerTypes with eager load of many-to-many relationships. + * + * @return the list of entities. + */ + public Page findAllWithEagerRelationships(Pageable pageable) { + return cancerTypeRepository.findAllWithEagerRelationships(pageable); + } + + public List findAllByMainTypeIs(String maintype) { + return cancerTypeRepository.findAllByMainTypeIs(maintype); + } + + /** + * Get one cancerType by id. + * + * @param id the id of the entity. + * @return the entity. + */ + @Transactional(readOnly = true) + public Optional findOne(Long id) { + log.debug("Request to get CancerType : {}", id); + return cancerTypeRepository.findOneWithEagerRelationships(id); + } + + @Transactional(readOnly = true) + public Optional findOneByCode(String code) { + return cancerTypeRepository.findOneByCodeIgnoreCase(code); + } + + @Transactional(readOnly = true) + public Optional findOneBySubtypeIgnoreCase(String subtype) { + return cancerTypeRepository.findOneBySubtypeIgnoreCase(subtype); + } + + @Transactional(readOnly = true) + public Optional findByMainTypeAndSubtypeIsNull(String mainType) { + return cancerTypeRepository.findByMainTypeAndSubtypeIsNull(mainType); + } + + @Transactional(readOnly = true) + public List getRelevantCancerTypes(String levelOfEvidence, RelevantCancerTypeBody relevantCancerTypeBody) { + List cancerTypes = new ArrayList<>(); + List cancerTypeQueries = relevantCancerTypeBody.getRelevantCancerTypeQueries(); + if (cancerTypeQueries == null) { + return cancerTypes; + } else { + cancerTypes = getRelevantCancerTypes(levelOfEvidence, cancerTypeQueries); + } + + List excludedCancerTypes = new ArrayList<>(); + List excludedCancerTypeQueries = relevantCancerTypeBody.getExcludedRelevantCancerTypeQueries(); + if (excludedCancerTypeQueries != null) { + excludedCancerTypes = getRelevantCancerTypes(levelOfEvidence, excludedCancerTypeQueries); + } + + Set relevantCancerTypes = new HashSet<>(cancerTypes); + relevantCancerTypes.removeAll(excludedCancerTypes); + return new ArrayList<>(relevantCancerTypes); + } + + @Transactional(readOnly = true) + private List getRelevantCancerTypes(String levelOfEvidence, List cancerTypeQueries) { + boolean isLevelBased = levelOfEvidence != null; + RelevantCancerTypeDirection direction = isLevelBased && levelOfEvidence.equals(LevelOfEvidenceEnum.LEVEL_DX1.getValue()) + ? RelevantCancerTypeDirection.UPWARD + : RelevantCancerTypeDirection.DOWNWARD; + Set relevantCancerTypes = cancerTypeQueries + .stream() + .map(query -> { + if (StringUtils.isNullOrEmpty(query.getCode())) { + List relevant = findRelevantCancerTypes(query.getMainType(), true, direction); + if (isLevelBased) { + return relevant.stream().filter(type -> type.getLevel() >= 0).collect(Collectors.toSet()); + } else { + return relevant; + } + } else { + Set relevant = findRelevantCancerTypes(query.getCode(), false, direction) + .stream() + .filter(type -> type.getLevel() > 0) + .collect(Collectors.toSet()); + if (isLevelBased) { + return relevant.stream().filter(type -> type.getLevel() > 0).collect(Collectors.toSet()); + } else { + return relevant; + } + } + }) + .flatMap(Collection::stream) + .collect(Collectors.toSet()); + + return new ArrayList<>(relevantCancerTypes); + } + + public List findRelevantCancerTypes(String cancerType, Boolean isMainType, RelevantCancerTypeDirection direction) { + SpecialCancerType specialCancerType = SpecialCancerType.getByTumorType(cancerType); + if (specialCancerType != null) { + return findRelevantCancerTypesForSpecialCancerTypes(specialCancerType, direction); + } + + LinkedHashSet mappedCancerTypes = new LinkedHashSet<>(); + CancerType matchedCancerType = null; + + if (isMainType != Boolean.TRUE) { + Optional match = cancerTypeRepository.findOneByCodeIgnoreCase(cancerType); + if (match.isPresent()) { + matchedCancerType = match.orElseThrow(); + } else { + match = cancerTypeRepository.findOneBySubtypeIgnoreCase(cancerType); + if (match.isPresent()) { + matchedCancerType = match.orElseThrow(); + } + } + } + + String mainTypeName = cancerType; + if (matchedCancerType != null) { + mappedCancerTypes.add(matchedCancerType); + mainTypeName = matchedCancerType.getMainType(); + } + + Optional matchedMainType = cancerTypeRepository.findOneByMainTypeIgnoreCaseAndCodeIsNull(mainTypeName); + if (matchedMainType.isPresent() && direction.equals(RelevantCancerTypeDirection.UPWARD)) { + mappedCancerTypes.add(matchedMainType.orElseThrow()); + } + + if (direction.equals(RelevantCancerTypeDirection.UPWARD)) { + if (matchedCancerType != null) { + mappedCancerTypes.addAll(CancerTypeUtils.getParentTumorTypes(matchedCancerType, true)); + } + } else { + if (matchedCancerType != null) { + mappedCancerTypes.addAll(CancerTypeUtils.getChildTumorTypes(matchedCancerType, true)); + } else if (matchedMainType.isPresent()) { + mappedCancerTypes.addAll(cancerTypeRepository.findAllByMainTypeIs(matchedMainType.orElseThrow().getMainType())); + } + } + + if (CancerTypeUtils.hasSolidTumor(new HashSet<>(mappedCancerTypes))) { + Optional allSolidTumors = cancerTypeRepository.findOneByMainTypeIgnoreCaseAndCodeIsNull( + SpecialCancerType.ALL_SOLID_TUMORS.getTumorType() + ); + if (allSolidTumors.isPresent()) { + mappedCancerTypes.add(allSolidTumors.orElseThrow()); + } + } + + if (CancerTypeUtils.hasLiquidTumor(new HashSet<>(mappedCancerTypes))) { + Optional allLiquidTumors = cancerTypeRepository.findOneByMainTypeIgnoreCaseAndCodeIsNull( + SpecialCancerType.ALL_LIQUID_TUMORS.getTumorType() + ); + if (allLiquidTumors.isPresent()) { + mappedCancerTypes.add(allLiquidTumors.orElseThrow()); + } + } + + Optional allTumors = cancerTypeRepository.findOneByMainTypeIgnoreCaseAndCodeIsNull( + SpecialCancerType.ALL_TUMORS.getTumorType() + ); + if (allTumors.isPresent()) { + mappedCancerTypes.add(allTumors.orElseThrow()); + } + + List relevantCancerTypes = new ArrayList<>(new LinkedHashSet<>(mappedCancerTypes)); + CancerTypeUtils.sortByLevel(relevantCancerTypes); + return relevantCancerTypes; + } + + public List findRelevantCancerTypesForSpecialCancerTypes( + SpecialCancerType specialCancerType, + RelevantCancerTypeDirection direction + ) { + List relevantCancerTypes = new ArrayList<>(); + if (specialCancerType == null) { + return relevantCancerTypes; + } + + Optional special = cancerTypeRepository.findOneByCodeIgnoreCase(specialCancerType.name()); + if (special.isPresent()) { + relevantCancerTypes.add(special.orElseThrow()); + } + + if (direction.equals(RelevantCancerTypeDirection.UPWARD)) { + switch (specialCancerType) { + case ALL_SOLID_TUMORS: + case ALL_LIQUID_TUMORS: + Optional allTumors = cancerTypeRepository.findOneByCodeIgnoreCase(SpecialCancerType.ALL_TUMORS.name()); + if (allTumors.isPresent()) { + relevantCancerTypes.add(allTumors.orElseThrow()); + } + break; + default: + break; + } + } else if (direction.equals(RelevantCancerTypeDirection.DOWNWARD)) { + switch (specialCancerType) { + case ALL_SOLID_TUMORS: // add all non-special that are solid or mixed + relevantCancerTypes.addAll( + cancerTypeRepository + .findByTumorFormIn(Arrays.asList(TumorForm.SOLID, TumorForm.MIXED)) + .stream() + .filter(cancerType -> cancerType.getLevel() >= 0) + .collect(Collectors.toSet()) + ); + break; + case ALL_LIQUID_TUMORS: // add all non-special that are liquid or mixed + relevantCancerTypes.addAll( + cancerTypeRepository + .findByTumorFormIn(Arrays.asList(TumorForm.LIQUID, TumorForm.MIXED)) + .stream() + .filter(cancerType -> cancerType.getLevel() >= 0) + .collect(Collectors.toSet()) + ); + break; + case ALL_TUMORS: // add all non-special and all solid tumors and all liquid tumors + relevantCancerTypes.addAll( + cancerTypeRepository + .findAll() + .stream() + .filter( + cancerType -> + cancerType.getLevel() >= 0 || + cancerType.getMainType().equals(SpecialCancerType.ALL_SOLID_TUMORS.getTumorType()) || + cancerType.getMainType().equals(SpecialCancerType.ALL_LIQUID_TUMORS.getTumorType()) + ) + .collect(Collectors.toSet()) + ); + break; + default: + break; + } + } + return relevantCancerTypes; + } + + /** + * Delete the cancerType by id. + * + * @param id the id of the entity. + */ + public void delete(Long id) { + log.debug("Request to delete CancerType : {}", id); + cancerTypeRepository.deleteById(id); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/CategoricalAlterationService.java b/src/main/java/org/mskcc/oncokb/curation/service/CategoricalAlterationService.java new file mode 100644 index 000000000..2e168405b --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/CategoricalAlterationService.java @@ -0,0 +1,117 @@ +package org.mskcc.oncokb.curation.service; + +import static org.mskcc.oncokb.curation.util.AlterationUtils.removeExclusionCriteria; + +import java.util.List; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.Alteration; +import org.mskcc.oncokb.curation.domain.CategoricalAlteration; +import org.mskcc.oncokb.curation.domain.enumeration.AlterationType; +import org.mskcc.oncokb.curation.repository.CategoricalAlterationRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * Service Implementation for managing {@link CategoricalAlteration}. + */ +@Service +@Transactional +public class CategoricalAlterationService { + + private final Logger log = LoggerFactory.getLogger(CategoricalAlterationService.class); + + private final CategoricalAlterationRepository categoricalAlterationRepository; + + public CategoricalAlterationService(CategoricalAlterationRepository categoricalAlterationRepository) { + this.categoricalAlterationRepository = categoricalAlterationRepository; + } + + /** + * Save a categoricalAlteration. + * + * @param categoricalAlteration the entity to save. + * @return the persisted entity. + */ + public CategoricalAlteration save(CategoricalAlteration categoricalAlteration) { + log.debug("Request to save CategoricalAlteration : {}", categoricalAlteration); + return categoricalAlterationRepository.save(categoricalAlteration); + } + + /** + * Partially update a categoricalAlteration. + * + * @param categoricalAlteration the entity to update partially. + * @return the persisted entity. + */ + public Optional partialUpdate(CategoricalAlteration categoricalAlteration) { + log.debug("Request to partially update CategoricalAlteration : {}", categoricalAlteration); + + return categoricalAlterationRepository + .findById(categoricalAlteration.getId()) + .map(existingCategoricalAlteration -> { + if (categoricalAlteration.getAlterationType() != null) { + existingCategoricalAlteration.setAlterationType(categoricalAlteration.getAlterationType()); + } + if (categoricalAlteration.getType() != null) { + existingCategoricalAlteration.setType(categoricalAlteration.getType()); + } + if (categoricalAlteration.getName() != null) { + existingCategoricalAlteration.setName(categoricalAlteration.getName()); + } + + return existingCategoricalAlteration; + }) + .map(categoricalAlterationRepository::save); + } + + public Optional findByAlterationTypeAndName(AlterationType alterationType, String name) { + if (alterationType == null) { + return Optional.empty(); + } + return categoricalAlterationRepository.findByAlterationTypeAndName(alterationType, name); + } + + public Optional findByName(String name) { + return categoricalAlterationRepository.findByName(name); + } + + /** + * Get all the categoricalAlterations. + * + * @return the list of entities. + */ + @Transactional(readOnly = true) + public List findAll() { + log.debug("Request to get all CategoricalAlterations"); + return categoricalAlterationRepository.findAll(); + } + + /** + * Get one categoricalAlteration by id. + * + * @param id the id of the entity. + * @return the entity. + */ + @Transactional(readOnly = true) + public Optional findOne(Long id) { + log.debug("Request to get CategoricalAlteration : {}", id); + return categoricalAlterationRepository.findById(id); + } + + /** + * Delete the categoricalAlteration by id. + * + * @param id the id of the entity. + */ + public void delete(Long id) { + log.debug("Request to delete CategoricalAlteration : {}", id); + categoricalAlterationRepository.deleteById(id); + } + + public Optional findOneByAlteration(Alteration alteration) { + String trimmedAlteration = removeExclusionCriteria(alteration.getAlteration()); + return findByName(trimmedAlteration); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/ClinicalTrialArmQueryService.java b/src/main/java/org/mskcc/oncokb/curation/service/ClinicalTrialArmQueryService.java new file mode 100644 index 000000000..c9fe77e65 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/ClinicalTrialArmQueryService.java @@ -0,0 +1,110 @@ +package org.mskcc.oncokb.curation.service; + +import jakarta.persistence.criteria.JoinType; +import java.util.List; +import org.mskcc.oncokb.curation.domain.*; // for static metamodels +import org.mskcc.oncokb.curation.domain.ClinicalTrialArm; +import org.mskcc.oncokb.curation.repository.ClinicalTrialArmRepository; +import org.mskcc.oncokb.curation.service.criteria.ClinicalTrialArmCriteria; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import tech.jhipster.service.QueryService; + +/** + * Service for executing complex queries for {@link ClinicalTrialArm} entities in the database. + * The main input is a {@link ClinicalTrialArmCriteria} which gets converted to {@link Specification}, + * in a way that all the filters must apply. + * It returns a {@link List} of {@link ClinicalTrialArm} or a {@link Page} of {@link ClinicalTrialArm} which fulfills the criteria. + */ +@Service +@Transactional(readOnly = true) +public class ClinicalTrialArmQueryService extends QueryService { + + private final Logger log = LoggerFactory.getLogger(ClinicalTrialArmQueryService.class); + + private final ClinicalTrialArmRepository clinicalTrialArmRepository; + + public ClinicalTrialArmQueryService(ClinicalTrialArmRepository clinicalTrialArmRepository) { + this.clinicalTrialArmRepository = clinicalTrialArmRepository; + } + + /** + * Return a {@link List} of {@link ClinicalTrialArm} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public List findByCriteria(ClinicalTrialArmCriteria criteria) { + log.debug("find by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return clinicalTrialArmRepository.findAll(specification); + } + + /** + * Return a {@link Page} of {@link ClinicalTrialArm} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @param page The page, which should be returned. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public Page findByCriteria(ClinicalTrialArmCriteria criteria, Pageable page) { + log.debug("find by criteria : {}, page: {}", criteria, page); + final Specification specification = createSpecification(criteria); + return clinicalTrialArmRepository.findAll(specification, page); + } + + /** + * Return the number of matching entities in the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the number of matching entities. + */ + @Transactional(readOnly = true) + public long countByCriteria(ClinicalTrialArmCriteria criteria) { + log.debug("count by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return clinicalTrialArmRepository.count(specification); + } + + /** + * Function to convert {@link ClinicalTrialArmCriteria} to a {@link Specification} + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching {@link Specification} of the entity. + */ + protected Specification createSpecification(ClinicalTrialArmCriteria criteria) { + Specification specification = Specification.where(null); + if (criteria != null) { + // This has to be called first, because the distinct method returns null + if (criteria.getDistinct() != null) { + specification = specification.or(distinct(criteria.getDistinct())); + } + if (criteria.getId() != null) { + specification = specification.or(buildRangeSpecification(criteria.getId(), ClinicalTrialArm_.id)); + } + if (criteria.getName() != null) { + specification = specification.or(buildStringSpecification(criteria.getName(), ClinicalTrialArm_.name)); + } + if (criteria.getAssociationId() != null) { + specification = specification.or( + buildSpecification( + criteria.getAssociationId(), + root -> root.join(ClinicalTrialArm_.associations, JoinType.LEFT).get(Association_.id) + ) + ); + } + if (criteria.getClinicalTrialId() != null) { + specification = specification.or( + buildSpecification( + criteria.getClinicalTrialId(), + root -> root.join(ClinicalTrialArm_.clinicalTrial, JoinType.LEFT).get(ClinicalTrial_.id) + ) + ); + } + } + return specification; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/ClinicalTrialArmService.java b/src/main/java/org/mskcc/oncokb/curation/service/ClinicalTrialArmService.java new file mode 100644 index 000000000..b9432f8fa --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/ClinicalTrialArmService.java @@ -0,0 +1,102 @@ +package org.mskcc.oncokb.curation.service; + +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.ClinicalTrialArm; +import org.mskcc.oncokb.curation.repository.ClinicalTrialArmRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * Service Implementation for managing {@link ClinicalTrialArm}. + */ +@Service +@Transactional +public class ClinicalTrialArmService { + + private final Logger log = LoggerFactory.getLogger(ClinicalTrialArmService.class); + + private final ClinicalTrialArmRepository clinicalTrialArmRepository; + + public ClinicalTrialArmService(ClinicalTrialArmRepository clinicalTrialArmRepository) { + this.clinicalTrialArmRepository = clinicalTrialArmRepository; + } + + /** + * Save a clinicalTrialArm. + * + * @param clinicalTrialArm the entity to save. + * @return the persisted entity. + */ + public ClinicalTrialArm save(ClinicalTrialArm clinicalTrialArm) { + log.debug("Request to save ClinicalTrialArm : {}", clinicalTrialArm); + return clinicalTrialArmRepository.save(clinicalTrialArm); + } + + /** + * Partially update a clinicalTrialArm. + * + * @param clinicalTrialArm the entity to update partially. + * @return the persisted entity. + */ + public Optional partialUpdate(ClinicalTrialArm clinicalTrialArm) { + log.debug("Request to partially update ClinicalTrialArm : {}", clinicalTrialArm); + + return clinicalTrialArmRepository + .findById(clinicalTrialArm.getId()) + .map(existingClinicalTrialArm -> { + if (clinicalTrialArm.getName() != null) { + existingClinicalTrialArm.setName(clinicalTrialArm.getName()); + } + + return existingClinicalTrialArm; + }) + .map(clinicalTrialArmRepository::save); + } + + /** + * Get all the clinicalTrialArms. + * + * @param pageable the pagination information. + * @return the list of entities. + */ + @Transactional(readOnly = true) + public Page findAll(Pageable pageable) { + log.debug("Request to get all ClinicalTrialArms"); + return clinicalTrialArmRepository.findAll(pageable); + } + + /** + * Get all the clinicalTrialArms with eager load of many-to-many relationships. + * + * @return the list of entities. + */ + public Page findAllWithEagerRelationships(Pageable pageable) { + return clinicalTrialArmRepository.findAllWithEagerRelationships(pageable); + } + + /** + * Get one clinicalTrialArm by id. + * + * @param id the id of the entity. + * @return the entity. + */ + @Transactional(readOnly = true) + public Optional findOne(Long id) { + log.debug("Request to get ClinicalTrialArm : {}", id); + return clinicalTrialArmRepository.findOneWithEagerRelationships(id); + } + + /** + * Delete the clinicalTrialArm by id. + * + * @param id the id of the entity. + */ + public void delete(Long id) { + log.debug("Request to delete ClinicalTrialArm : {}", id); + clinicalTrialArmRepository.deleteById(id); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/ClinicalTrialQueryService.java b/src/main/java/org/mskcc/oncokb/curation/service/ClinicalTrialQueryService.java new file mode 100644 index 000000000..d126fb024 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/ClinicalTrialQueryService.java @@ -0,0 +1,127 @@ +package org.mskcc.oncokb.curation.service; + +import jakarta.persistence.criteria.JoinType; +import java.util.List; +import org.mskcc.oncokb.curation.domain.*; // for static metamodels +import org.mskcc.oncokb.curation.domain.ClinicalTrial; +import org.mskcc.oncokb.curation.repository.ClinicalTrialRepository; +import org.mskcc.oncokb.curation.service.criteria.ClinicalTrialCriteria; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import tech.jhipster.service.QueryService; + +/** + * Service for executing complex queries for {@link ClinicalTrial} entities in the database. + * The main input is a {@link ClinicalTrialCriteria} which gets converted to {@link Specification}, + * in a way that all the filters must apply. + * It returns a {@link List} of {@link ClinicalTrial} or a {@link Page} of {@link ClinicalTrial} which fulfills the criteria. + */ +@Service +@Transactional(readOnly = true) +public class ClinicalTrialQueryService extends QueryService { + + private final Logger log = LoggerFactory.getLogger(ClinicalTrialQueryService.class); + + private final ClinicalTrialRepository clinicalTrialRepository; + + public ClinicalTrialQueryService(ClinicalTrialRepository clinicalTrialRepository) { + this.clinicalTrialRepository = clinicalTrialRepository; + } + + /** + * Return a {@link List} of {@link ClinicalTrial} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public List findByCriteria(ClinicalTrialCriteria criteria) { + log.debug("find by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return clinicalTrialRepository.findAll(specification); + } + + /** + * Return a {@link Page} of {@link ClinicalTrial} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @param page The page, which should be returned. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public Page findByCriteria(ClinicalTrialCriteria criteria, Pageable page) { + log.debug("find by criteria : {}, page: {}", criteria, page); + final Specification specification = createSpecification(criteria); + return clinicalTrialRepository.findAll(specification, page); + } + + /** + * Return the number of matching entities in the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the number of matching entities. + */ + @Transactional(readOnly = true) + public long countByCriteria(ClinicalTrialCriteria criteria) { + log.debug("count by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return clinicalTrialRepository.count(specification); + } + + /** + * Function to convert {@link ClinicalTrialCriteria} to a {@link Specification} + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching {@link Specification} of the entity. + */ + protected Specification createSpecification(ClinicalTrialCriteria criteria) { + Specification specification = Specification.where(null); + if (criteria != null) { + // This has to be called first, because the distinct method returns null + if (criteria.getDistinct() != null) { + specification = specification.or(distinct(criteria.getDistinct())); + } + if (criteria.getId() != null) { + specification = specification.or(buildRangeSpecification(criteria.getId(), ClinicalTrial_.id)); + } + if (criteria.getNctId() != null) { + specification = specification.or(buildStringSpecification(criteria.getNctId(), ClinicalTrial_.nctId)); + } + if (criteria.getBriefTitle() != null) { + specification = specification.or(buildStringSpecification(criteria.getBriefTitle(), ClinicalTrial_.briefTitle)); + } + if (criteria.getPhase() != null) { + specification = specification.or(buildStringSpecification(criteria.getPhase(), ClinicalTrial_.phase)); + } + if (criteria.getStatus() != null) { + specification = specification.or(buildStringSpecification(criteria.getStatus(), ClinicalTrial_.status)); + } + if (criteria.getClinicalTrialArmId() != null) { + specification = specification.or( + buildSpecification( + criteria.getClinicalTrialArmId(), + root -> root.join(ClinicalTrial_.clinicalTrialArms, JoinType.LEFT).get(ClinicalTrialArm_.id) + ) + ); + } + if (criteria.getEligibilityCriteriaId() != null) { + specification = specification.or( + buildSpecification( + criteria.getEligibilityCriteriaId(), + root -> root.join(ClinicalTrial_.eligibilityCriteria, JoinType.LEFT).get(EligibilityCriteria_.id) + ) + ); + } + if (criteria.getAssociationId() != null) { + specification = specification.or( + buildSpecification( + criteria.getAssociationId(), + root -> root.join(ClinicalTrial_.associations, JoinType.LEFT).get(Association_.id) + ) + ); + } + } + return specification; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/ClinicalTrialService.java b/src/main/java/org/mskcc/oncokb/curation/service/ClinicalTrialService.java new file mode 100644 index 000000000..6357eaec0 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/ClinicalTrialService.java @@ -0,0 +1,111 @@ +package org.mskcc.oncokb.curation.service; + +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.ClinicalTrial; +import org.mskcc.oncokb.curation.repository.ClinicalTrialRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * Service Implementation for managing {@link ClinicalTrial}. + */ +@Service +@Transactional +public class ClinicalTrialService { + + private final Logger log = LoggerFactory.getLogger(ClinicalTrialService.class); + + private final ClinicalTrialRepository clinicalTrialRepository; + + public ClinicalTrialService(ClinicalTrialRepository clinicalTrialRepository) { + this.clinicalTrialRepository = clinicalTrialRepository; + } + + /** + * Save a clinicalTrial. + * + * @param clinicalTrial the entity to save. + * @return the persisted entity. + */ + public ClinicalTrial save(ClinicalTrial clinicalTrial) { + log.debug("Request to save ClinicalTrial : {}", clinicalTrial); + return clinicalTrialRepository.save(clinicalTrial); + } + + /** + * Partially update a clinicalTrial. + * + * @param clinicalTrial the entity to update partially. + * @return the persisted entity. + */ + public Optional partialUpdate(ClinicalTrial clinicalTrial) { + log.debug("Request to partially update ClinicalTrial : {}", clinicalTrial); + + return clinicalTrialRepository + .findById(clinicalTrial.getId()) + .map(existingClinicalTrial -> { + if (clinicalTrial.getNctId() != null) { + existingClinicalTrial.setNctId(clinicalTrial.getNctId()); + } + if (clinicalTrial.getBriefTitle() != null) { + existingClinicalTrial.setBriefTitle(clinicalTrial.getBriefTitle()); + } + if (clinicalTrial.getPhase() != null) { + existingClinicalTrial.setPhase(clinicalTrial.getPhase()); + } + if (clinicalTrial.getStatus() != null) { + existingClinicalTrial.setStatus(clinicalTrial.getStatus()); + } + + return existingClinicalTrial; + }) + .map(clinicalTrialRepository::save); + } + + /** + * Get all the clinicalTrials. + * + * @param pageable the pagination information. + * @return the list of entities. + */ + @Transactional(readOnly = true) + public Page findAll(Pageable pageable) { + log.debug("Request to get all ClinicalTrials"); + return clinicalTrialRepository.findAll(pageable); + } + + /** + * Get all the clinicalTrials with eager load of many-to-many relationships. + * + * @return the list of entities. + */ + public Page findAllWithEagerRelationships(Pageable pageable) { + return clinicalTrialRepository.findAllWithEagerRelationships(pageable); + } + + /** + * Get one clinicalTrial by id. + * + * @param id the id of the entity. + * @return the entity. + */ + @Transactional(readOnly = true) + public Optional findOne(Long id) { + log.debug("Request to get ClinicalTrial : {}", id); + return clinicalTrialRepository.findOneWithEagerRelationships(id); + } + + /** + * Delete the clinicalTrial by id. + * + * @param id the id of the entity. + */ + public void delete(Long id) { + log.debug("Request to delete ClinicalTrial : {}", id); + clinicalTrialRepository.deleteById(id); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/CompanionDiagnosticDeviceQueryService.java b/src/main/java/org/mskcc/oncokb/curation/service/CompanionDiagnosticDeviceQueryService.java new file mode 100644 index 000000000..86c61a55f --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/CompanionDiagnosticDeviceQueryService.java @@ -0,0 +1,146 @@ +package org.mskcc.oncokb.curation.service; + +import jakarta.persistence.criteria.JoinType; +import java.util.List; +import org.mskcc.oncokb.curation.domain.*; // for static metamodels +import org.mskcc.oncokb.curation.domain.CompanionDiagnosticDevice; +import org.mskcc.oncokb.curation.repository.CompanionDiagnosticDeviceRepository; +import org.mskcc.oncokb.curation.service.criteria.CompanionDiagnosticDeviceCriteria; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import tech.jhipster.service.QueryService; +import tech.jhipster.service.filter.StringFilter; + +/** + * Service for executing complex queries for {@link CompanionDiagnosticDevice} entities in the database. + * The main input is a {@link CompanionDiagnosticDeviceCriteria} which gets converted to {@link Specification}, + * in a way that all the filters must apply. + * It returns a {@link List} of {@link CompanionDiagnosticDevice} or a {@link Page} of {@link CompanionDiagnosticDevice} which fulfills the criteria. + */ +@Service +@Transactional(readOnly = true) +public class CompanionDiagnosticDeviceQueryService extends QueryService { + + private final Logger log = LoggerFactory.getLogger(CompanionDiagnosticDeviceQueryService.class); + + private final CompanionDiagnosticDeviceRepository companionDiagnosticDeviceRepository; + + public CompanionDiagnosticDeviceQueryService(CompanionDiagnosticDeviceRepository companionDiagnosticDeviceRepository) { + this.companionDiagnosticDeviceRepository = companionDiagnosticDeviceRepository; + } + + @Transactional(readOnly = true) + public List findBySearchQuery(String query) { + return findBySearchQuery(query, Pageable.unpaged()).getContent(); + } + + @Transactional(readOnly = true) + public Page findBySearchQuery(String query, Pageable page) { + CompanionDiagnosticDeviceCriteria criteria = new CompanionDiagnosticDeviceCriteria(); + StringFilter stringFilter = new StringFilter(); + stringFilter.setContains(query); + criteria.setName(stringFilter); + criteria.setManufacturer(stringFilter); + return findByCriteria(criteria, page); + } + + /** + * Return a {@link List} of {@link CompanionDiagnosticDevice} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public List findByCriteria(CompanionDiagnosticDeviceCriteria criteria) { + log.debug("find by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return companionDiagnosticDeviceRepository.findAllWithEagerRelationships(); + } + + /** + * Return a {@link Page} of {@link CompanionDiagnosticDevice} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @param page The page, which should be returned. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public Page findByCriteria(CompanionDiagnosticDeviceCriteria criteria, Pageable page) { + log.debug("find by criteria : {}, page: {}", criteria, page); + final Specification specification = createSpecification(criteria); + return companionDiagnosticDeviceRepository.findAll(specification, page); + } + + /** + * Return the number of matching entities in the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the number of matching entities. + */ + @Transactional(readOnly = true) + public long countByCriteria(CompanionDiagnosticDeviceCriteria criteria) { + log.debug("count by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return companionDiagnosticDeviceRepository.count(specification); + } + + /** + * Function to convert {@link CompanionDiagnosticDeviceCriteria} to a {@link Specification} + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching {@link Specification} of the entity. + */ + protected Specification createSpecification(CompanionDiagnosticDeviceCriteria criteria) { + Specification specification = Specification.where(null); + if (criteria != null) { + // This has to be called first, because the distinct method returns null + if (criteria.getDistinct() != null) { + specification = specification.or(distinct(criteria.getDistinct())); + } + if (criteria.getId() != null) { + specification = specification.or(buildRangeSpecification(criteria.getId(), CompanionDiagnosticDevice_.id)); + } + if (criteria.getName() != null) { + specification = specification.or(buildStringSpecification(criteria.getName(), CompanionDiagnosticDevice_.name)); + } + if (criteria.getManufacturer() != null) { + specification = specification.or( + buildStringSpecification(criteria.getManufacturer(), CompanionDiagnosticDevice_.manufacturer) + ); + } + if (criteria.getIndicationDetails() != null) { + specification = specification.or( + buildStringSpecification(criteria.getIndicationDetails(), CompanionDiagnosticDevice_.indicationDetails) + ); + } + if (criteria.getPlatformType() != null) { + specification = specification.or( + buildStringSpecification(criteria.getPlatformType(), CompanionDiagnosticDevice_.platformType) + ); + } + if (criteria.getLastUpdated() != null) { + specification = specification.or( + buildRangeSpecification(criteria.getLastUpdated(), CompanionDiagnosticDevice_.lastUpdated) + ); + } + if (criteria.getFdaSubmissionId() != null) { + specification = specification.or( + buildSpecification( + criteria.getFdaSubmissionId(), + root -> root.join(CompanionDiagnosticDevice_.fdaSubmissions, JoinType.LEFT).get(FdaSubmission_.id) + ) + ); + } + if (criteria.getSpecimenTypeId() != null) { + specification = specification.or( + buildSpecification( + criteria.getSpecimenTypeId(), + root -> root.join(CompanionDiagnosticDevice_.specimenTypes, JoinType.LEFT).get(SpecimenType_.id) + ) + ); + } + } + return specification; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/CompanionDiagnosticDeviceService.java b/src/main/java/org/mskcc/oncokb/curation/service/CompanionDiagnosticDeviceService.java new file mode 100644 index 000000000..9c2f7838f --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/CompanionDiagnosticDeviceService.java @@ -0,0 +1,117 @@ +package org.mskcc.oncokb.curation.service; + +import java.time.Instant; +import java.util.List; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.CompanionDiagnosticDevice; +import org.mskcc.oncokb.curation.repository.CompanionDiagnosticDeviceRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * Service Implementation for managing {@link CompanionDiagnosticDevice}. + */ +@Service +@Transactional +public class CompanionDiagnosticDeviceService { + + private final Logger log = LoggerFactory.getLogger(CompanionDiagnosticDeviceService.class); + + private final CompanionDiagnosticDeviceRepository companionDiagnosticDeviceRepository; + + public CompanionDiagnosticDeviceService(CompanionDiagnosticDeviceRepository companionDiagnosticDeviceRepository) { + this.companionDiagnosticDeviceRepository = companionDiagnosticDeviceRepository; + } + + /** + * Save a companionDiagnosticDevice. + * + * @param companionDiagnosticDevice the entity to save. + * @return the persisted entity. + */ + public CompanionDiagnosticDevice save(CompanionDiagnosticDevice companionDiagnosticDevice) { + log.debug("Request to save CompanionDiagnosticDevice : {}", companionDiagnosticDevice); + companionDiagnosticDevice.setLastUpdated(Instant.now()); + return companionDiagnosticDeviceRepository.save(companionDiagnosticDevice); + } + + /** + * Partially update a companionDiagnosticDevice. + * + * @param companionDiagnosticDevice the entity to update partially. + * @return the persisted entity. + */ + public Optional partialUpdate(CompanionDiagnosticDevice companionDiagnosticDevice) { + log.debug("Request to partially update CompanionDiagnosticDevice : {}", companionDiagnosticDevice); + + return companionDiagnosticDeviceRepository + .findById(companionDiagnosticDevice.getId()) + .map(existingCompanionDiagnosticDevice -> { + if (companionDiagnosticDevice.getName() != null) { + existingCompanionDiagnosticDevice.setName(companionDiagnosticDevice.getName()); + } + if (companionDiagnosticDevice.getManufacturer() != null) { + existingCompanionDiagnosticDevice.setManufacturer(companionDiagnosticDevice.getManufacturer()); + } + if (companionDiagnosticDevice.getIndicationDetails() != null) { + existingCompanionDiagnosticDevice.setIndicationDetails(companionDiagnosticDevice.getIndicationDetails()); + } + if (companionDiagnosticDevice.getPlatformType() != null) { + existingCompanionDiagnosticDevice.setPlatformType(companionDiagnosticDevice.getPlatformType()); + } + if (companionDiagnosticDevice.getLastUpdated() != null) { + existingCompanionDiagnosticDevice.setLastUpdated(companionDiagnosticDevice.getLastUpdated()); + } else { + existingCompanionDiagnosticDevice.setLastUpdated(Instant.now()); + } + + return existingCompanionDiagnosticDevice; + }) + .map(companionDiagnosticDeviceRepository::save); + } + + /** + * Get all the companionDiagnosticDevices. + * + * @return the list of entities. + */ + @Transactional(readOnly = true) + public List findAll() { + log.debug("Request to get all CompanionDiagnosticDevices"); + return companionDiagnosticDeviceRepository.findAllWithEagerRelationships(); + } + + /** + * Get one companionDiagnosticDevice by id. + * + * @param id the id of the entity. + * @return the entity. + */ + @Transactional(readOnly = true) + public Optional findOne(Long id) { + log.debug("Request to get CompanionDiagnosticDevice : {}", id); + return companionDiagnosticDeviceRepository.findOneWithEagerRelationships(id); + } + + @Transactional(readOnly = true) + public Optional findByName(String name) { + return companionDiagnosticDeviceRepository.findByName(name); + } + + @Transactional(readOnly = true) + public List findByNameAndManufacturer(String name, String manufacturer) { + return companionDiagnosticDeviceRepository.findByNameIgnoreCaseAndManufacturerIgnoreCase(name, manufacturer); + } + + /** + * Delete the companionDiagnosticDevice by id. + * + * @param id the id of the entity. + */ + public void delete(Long id) { + log.debug("Request to delete CompanionDiagnosticDevice : {}", id); + companionDiagnosticDeviceRepository.deleteById(id); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/ConsequenceQueryService.java b/src/main/java/org/mskcc/oncokb/curation/service/ConsequenceQueryService.java new file mode 100644 index 000000000..c4751f478 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/ConsequenceQueryService.java @@ -0,0 +1,121 @@ +package org.mskcc.oncokb.curation.service; + +import jakarta.persistence.criteria.JoinType; +import java.util.List; +import org.mskcc.oncokb.curation.domain.*; // for static metamodels +import org.mskcc.oncokb.curation.domain.Consequence; +import org.mskcc.oncokb.curation.repository.ConsequenceRepository; +import org.mskcc.oncokb.curation.service.criteria.ConsequenceCriteria; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import tech.jhipster.service.QueryService; + +/** + * Service for executing complex queries for {@link Consequence} entities in the database. + * The main input is a {@link ConsequenceCriteria} which gets converted to {@link Specification}, + * in a way that all the filters must apply. + * It returns a {@link List} of {@link Consequence} or a {@link Page} of {@link Consequence} which fulfills the criteria. + */ +@Service +@Transactional(readOnly = true) +public class ConsequenceQueryService extends QueryService { + + private final Logger log = LoggerFactory.getLogger(ConsequenceQueryService.class); + + private final ConsequenceRepository consequenceRepository; + + public ConsequenceQueryService(ConsequenceRepository consequenceRepository) { + this.consequenceRepository = consequenceRepository; + } + + /** + * Return a {@link List} of {@link Consequence} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public List findByCriteria(ConsequenceCriteria criteria) { + log.debug("find by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return consequenceRepository.findAll(specification); + } + + /** + * Return a {@link Page} of {@link Consequence} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @param page The page, which should be returned. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public Page findByCriteria(ConsequenceCriteria criteria, Pageable page) { + log.debug("find by criteria : {}, page: {}", criteria, page); + final Specification specification = createSpecification(criteria); + return consequenceRepository.findAll(specification, page); + } + + /** + * Return the number of matching entities in the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the number of matching entities. + */ + @Transactional(readOnly = true) + public long countByCriteria(ConsequenceCriteria criteria) { + log.debug("count by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return consequenceRepository.count(specification); + } + + /** + * Function to convert {@link ConsequenceCriteria} to a {@link Specification} + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching {@link Specification} of the entity. + */ + protected Specification createSpecification(ConsequenceCriteria criteria) { + Specification specification = Specification.where(null); + if (criteria != null) { + // This has to be called first, because the distinct method returns null + if (criteria.getDistinct() != null) { + specification = specification.or(distinct(criteria.getDistinct())); + } + if (criteria.getId() != null) { + specification = specification.or(buildRangeSpecification(criteria.getId(), Consequence_.id)); + } + if (criteria.getTerm() != null) { + specification = specification.or(buildStringSpecification(criteria.getTerm(), Consequence_.term)); + } + if (criteria.getName() != null) { + specification = specification.or(buildStringSpecification(criteria.getName(), Consequence_.name)); + } + if (criteria.getIsGenerallyTruncating() != null) { + specification = specification.or( + buildSpecification(criteria.getIsGenerallyTruncating(), Consequence_.isGenerallyTruncating) + ); + } + if (criteria.getDescription() != null) { + specification = specification.or(buildStringSpecification(criteria.getDescription(), Consequence_.description)); + } + if (criteria.getAlterationId() != null) { + specification = specification.or( + buildSpecification( + criteria.getAlterationId(), + root -> root.join(Consequence_.alterations, JoinType.LEFT).get(Alteration_.id) + ) + ); + } + if (criteria.getCategoricalAlterationId() != null) { + specification = specification.or( + buildSpecification( + criteria.getCategoricalAlterationId(), + root -> root.join(Consequence_.categoricalAlterations, JoinType.LEFT).get(CategoricalAlteration_.id) + ) + ); + } + } + return specification; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/ConsequenceService.java b/src/main/java/org/mskcc/oncokb/curation/service/ConsequenceService.java new file mode 100644 index 000000000..ab0a5d9c3 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/ConsequenceService.java @@ -0,0 +1,105 @@ +package org.mskcc.oncokb.curation.service; + +import java.util.List; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.Consequence; +import org.mskcc.oncokb.curation.repository.ConsequenceRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * Service Implementation for managing {@link Consequence}. + */ +@Service +@Transactional +public class ConsequenceService { + + private final Logger log = LoggerFactory.getLogger(ConsequenceService.class); + + private final ConsequenceRepository consequenceRepository; + + public ConsequenceService(ConsequenceRepository consequenceRepository) { + this.consequenceRepository = consequenceRepository; + } + + /** + * Save a consequence. + * + * @param consequence the entity to save. + * @return the persisted entity. + */ + public Consequence save(Consequence consequence) { + log.debug("Request to save Consequence : {}", consequence); + return consequenceRepository.save(consequence); + } + + /** + * Partially update a consequence. + * + * @param consequence the entity to update partially. + * @return the persisted entity. + */ + public Optional partialUpdate(Consequence consequence) { + log.debug("Request to partially update Consequence : {}", consequence); + + return consequenceRepository + .findById(consequence.getId()) + .map(existingConsequence -> { + if (consequence.getTerm() != null) { + existingConsequence.setTerm(consequence.getTerm()); + } + if (consequence.getName() != null) { + existingConsequence.setName(consequence.getName()); + } + if (consequence.getIsGenerallyTruncating() != null) { + existingConsequence.setIsGenerallyTruncating(consequence.getIsGenerallyTruncating()); + } + if (consequence.getDescription() != null) { + existingConsequence.setDescription(consequence.getDescription()); + } + + return existingConsequence; + }) + .map(consequenceRepository::save); + } + + /** + * Get all the consequences. + * + * @return the list of entities. + */ + @Transactional(readOnly = true) + public List findAll() { + log.debug("Request to get all Consequences"); + return consequenceRepository.findAll(); + } + + /** + * Get one consequence by id. + * + * @param id the id of the entity. + * @return the entity. + */ + @Transactional(readOnly = true) + public Optional findOne(Long id) { + log.debug("Request to get Consequence : {}", id); + return consequenceRepository.findById(id); + } + + public Optional findByTerm(String term) { + log.debug("Request to get Consequence by term : {}", term); + return consequenceRepository.findByTerm(term); + } + + /** + * Delete the consequence by id. + * + * @param id the id of the entity. + */ + public void delete(Long id) { + log.debug("Request to delete Consequence : {}", id); + consequenceRepository.deleteById(id); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/DrugQueryService.java b/src/main/java/org/mskcc/oncokb/curation/service/DrugQueryService.java new file mode 100644 index 000000000..8d09a2e3c --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/DrugQueryService.java @@ -0,0 +1,131 @@ +package org.mskcc.oncokb.curation.service; + +import jakarta.persistence.criteria.JoinType; +import java.util.Iterator; +import java.util.List; +import java.util.function.Function; +import org.mskcc.oncokb.curation.domain.*; // for static metamodels +import org.mskcc.oncokb.curation.domain.Drug; +import org.mskcc.oncokb.curation.repository.DrugRepository; +import org.mskcc.oncokb.curation.service.criteria.DrugCriteria; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import tech.jhipster.service.QueryService; +import tech.jhipster.service.filter.StringFilter; + +/** + * Service for executing complex queries for {@link Drug} entities in the database. + * The main input is a {@link DrugCriteria} which gets converted to {@link Specification}, + * in a way that all the filters must apply. + * It returns a {@link List} of {@link Drug} or a {@link Page} of {@link Drug} which fulfills the criteria. + */ +@Service +@Transactional(readOnly = true) +public class DrugQueryService extends QueryService { + + private final Logger log = LoggerFactory.getLogger(DrugQueryService.class); + + private final DrugRepository drugRepository; + + public DrugQueryService(DrugRepository drugRepository) { + this.drugRepository = drugRepository; + } + + @Transactional(readOnly = true) + public Page findBySearchQuery(String query, Pageable page) { + DrugCriteria criteria = new DrugCriteria(); + StringFilter stringFilter = new StringFilter(); + stringFilter.setContains(query); + criteria.setNcitCode(stringFilter); + criteria.setName(stringFilter); + return findByCriteria(criteria, page); + } + + /** + * Return a {@link List} of {@link Drug} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public List findByCriteria(DrugCriteria criteria) { + log.debug("find by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return drugRepository.findAll(specification); + } + + /** + * Return a {@link Page} of {@link Drug} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @param page The page, which should be returned. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public Page findByCriteria(DrugCriteria criteria, Pageable page) { + log.debug("find by criteria : {}, page: {}", criteria, page); + final Specification specification = createSpecification(criteria); + return drugRepository.findAll(specification, page); + } + + /** + * Return the number of matching entities in the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the number of matching entities. + */ + @Transactional(readOnly = true) + public long countByCriteria(DrugCriteria criteria) { + log.debug("count by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return drugRepository.count(specification); + } + + /** + * Function to convert {@link DrugCriteria} to a {@link Specification} + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching {@link Specification} of the entity. + */ + protected Specification createSpecification(DrugCriteria criteria) { + Specification specification = Specification.where(null); + if (criteria != null) { + // This has to be called first, because the distinct method returns null + if (criteria.getDistinct() != null) { + specification = specification.or(distinct(criteria.getDistinct())); + } + if (criteria.getId() != null) { + specification = specification.or(buildRangeSpecification(criteria.getId(), Drug_.id)); + } + if (criteria.getName() != null && criteria.getName().getContains() != null) { + specification = specification.or((root, _ignore, cb) -> { + return cb.like(root.get(Drug_.name), "%" + criteria.getName().getContains() + "%"); + }); + } + if (criteria.getUuid() != null) { + specification = specification.or(buildStringSpecification(criteria.getUuid(), Drug_.uuid)); + } + if (criteria.getNcitCode() != null) { + specification = specification.or( + buildSpecification(criteria.getNcitCode(), root -> root.join(Drug_.nciThesaurus, JoinType.LEFT).get(NciThesaurus_.code)) + ); + } + if (criteria.getFlagId() != null) { + specification = specification.or( + buildSpecification(criteria.getFlagId(), root -> root.join(Drug_.flags, JoinType.LEFT).get(Flag_.id)) + ); + } + if (criteria.getAssociationId() != null) { + specification = specification.or( + buildSpecification( + criteria.getAssociationId(), + root -> root.join(Drug_.associations, JoinType.LEFT).get(Association_.id) + ) + ); + } + } + return specification; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/DrugService.java b/src/main/java/org/mskcc/oncokb/curation/service/DrugService.java new file mode 100644 index 000000000..dbf204534 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/DrugService.java @@ -0,0 +1,191 @@ +package org.mskcc.oncokb.curation.service; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import org.mskcc.oncokb.curation.domain.Drug; +import org.mskcc.oncokb.curation.repository.DrugRepository; +import org.mskcc.oncokb.curation.service.criteria.DrugCriteria; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * Service Implementation for managing {@link Drug}. + */ +@Service +@Transactional +public class DrugService { + + private final Logger log = LoggerFactory.getLogger(DrugService.class); + + private final DrugRepository drugRepository; + private final DrugQueryService drugQueryService; + + public DrugService(DrugRepository drugRepository, DrugQueryService drugQueryService) { + this.drugRepository = drugRepository; + this.drugQueryService = drugQueryService; + } + + /** + * Save a drug. + * + * @param drug the entity to save. + * @return the persisted entity. + */ + public Drug save(Drug drug) { + log.debug("Request to save Drug : {}", drug); + return drugRepository.save(drug); + } + + /** + * Partially update a drug. + * + * @param drug the entity to update partially. + * @return the persisted entity. + */ + public Optional partialUpdate(Drug drug) { + log.debug("Request to partially update Drug : {}", drug); + + return drugRepository + .findById(drug.getId()) + .map(existingDrug -> { + if (drug.getUuid() != null) { + existingDrug.setUuid(drug.getUuid()); + } + if (drug.getName() != null) { + existingDrug.setName(drug.getName()); + } + if (drug.getNciThesaurus() != null) { + existingDrug.setNciThesaurus(drug.getNciThesaurus()); + } + + return existingDrug; + }) + .map(drugRepository::save); + } + + /** + * Get all the drugs. + * + * @return the list of entities. + */ + @Transactional(readOnly = true) + @Cacheable(cacheResolver = "drugCacheResolver") + public List findAll(DrugCriteria criteria) { + log.debug("Request to get all Drugs"); + Boolean isEmptyCriteria = (new DrugCriteria()).equals(criteria); + List drugs = new ArrayList<>(); + if (!isEmptyCriteria) { + drugs = drugQueryService.findByCriteria(criteria); + } + if (drugs.size() == 0) { + return drugRepository.findAllWithEagerRelationships(); + } else { + return drugRepository.findAllWithEagerRelationships(drugs.stream().map(Drug::getId).collect(Collectors.toList())); + } + } + + /** + * Get all the drugs where FdaDrug is {@code null}. + * @return the list of entities. + */ + @Transactional(readOnly = true) + public List findAllWhereFdaDrugIsNull() { + log.debug("Request to get all drugs where FdaDrug is null"); + return drugRepository + .findAll() + .stream() + .filter(drug -> drug.getFdaDrugs() == null || drug.getFdaDrugs().isEmpty()) + .collect(Collectors.toList()); + } + + /** + * Get one drug by id. + * + * @param id the id of the entity. + * @return the entity. + */ + @Transactional(readOnly = true) + public Optional findOne(Long id) { + log.debug("Request to get Drug : {}", id); + return drugRepository.findOneWithEagerRelationships(id); + } + + /** + * Get list of drugs by ids + * + * @param ids the id of the entities. + * @return list of entity. + */ + @Transactional(readOnly = true) + public List findAllByIds(List ids) { + log.debug("Request to get all : {}", ids); + return drugRepository.findAllWithEagerRelationships(ids); + } + + public Optional findByCode(String code) { + return drugRepository.findOneByCodeWithEagerRelationships(code); + } + + public Optional findByName(String name) { + return drugRepository.findByNameIgnoreCaseWithEagerRelationships(name); + } + + public List searchDrug(String query) { + List result = drugRepository.searchDrug(query); + result.sort(new DrugComp(query)); + return result; + } + + /** + * Delete the drug by id. + * + * @param id the id of the entity. + */ + public void delete(Long id) { + log.debug("Request to delete Drug : {}", id); + drugRepository.deleteById(id); + } +} + +class DrugComp implements Comparator { + + private final String keyword; + + public DrugComp(String keyword) { + this.keyword = keyword.toLowerCase(); + } + + @Override + public int compare(Drug e1, Drug e2) { + if (e1.getName().equalsIgnoreCase(keyword)) { + return -1; + } + if (e2.getName().equalsIgnoreCase(keyword)) { + return 1; + } + Integer index1 = e1.getName().indexOf(this.keyword); + Integer index2 = e2.getName().indexOf(this.keyword); + if (index1.equals(index2)) { + index1 = e1.getNciThesaurus() == null ? 0 : e1.getNciThesaurus().getCode().indexOf(this.keyword); + index2 = e2.getNciThesaurus() == null ? 0 : e2.getNciThesaurus().getCode().indexOf(this.keyword); + if (index1.equals(index2)) { + // At this moment, these are the matches from the synonyms. The order does not matter, so alphabetically sort base on drug name + return e1.getName().compareTo(e2.getName()); + } else { + if (index1.equals(-1)) return 1; + if (index2.equals(-1)) return -1; + return index1 - index2; + } + } else { + if (index1.equals(-1)) return 1; + if (index2.equals(-1)) return -1; + return index1 - index2; + } + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/EbiService.java b/src/main/java/org/mskcc/oncokb/curation/service/EbiService.java new file mode 100644 index 000000000..946473980 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/EbiService.java @@ -0,0 +1,115 @@ +package org.mskcc.oncokb.curation.service; + +import java.net.URI; +import java.net.URL; +import org.mskcc.oncokb.curation.security.SecurityUtils; +import org.mskcc.oncokb.curation.service.dto.ClustalOResp; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.*; +import org.springframework.stereotype.Service; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +@Service +public class EbiService { + + private final Logger log = LoggerFactory.getLogger(EbiService.class); + + public final String BASE_URL = "https://www.ebi.ac.uk/Tools/services/rest"; + public final String CLUSTAL_O_URL = "/clustalo"; + public final String MVIEW_URL = "/mview"; + + private HttpHeaders getCommonEbiHttpHeaders() { + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + return httpHeaders; + } + + private String runEbiJob(HttpEntity entity, String toolUrl) throws InterruptedException { + try { + RestTemplate restTemplate = new RestTemplate(); + // Post to run + String jobId = restTemplate.postForObject(getEbiApiUrl(toolUrl + "/run"), entity, String.class); + + // Check status + String status = ""; + while (!status.equals("FINISHED")) { + status = restTemplate.getForObject(URI.create(getEbiApiUrl(toolUrl + "/status/" + jobId)), String.class); + Thread.sleep(1000); + } + + return jobId; + } catch (Exception e) { + log.error("Failed "); + throw e; + } + } + + private String runClustaloJob(String sequence) throws InterruptedException { + // Prep the POST body before running the ClustalO alignment + HttpHeaders httpHeaders = getCommonEbiHttpHeaders(); + + MultiValueMap map = new LinkedMultiValueMap(); + map.add("stype", "protein"); + map.add("sequence", sequence); + map.add("email", SecurityUtils.getCurrentUserLogin().orElseThrow()); + HttpEntity> entity = new HttpEntity<>(map, httpHeaders); + + return runEbiJob(entity, CLUSTAL_O_URL); + } + + private String runMviewJob(String clustaloJobId) throws InterruptedException { + // Prep the POST body before sending to MView + HttpHeaders httpHeaders = getCommonEbiHttpHeaders(); + + MultiValueMap map = new LinkedMultiValueMap(); + map = new LinkedMultiValueMap(); + map.add("stype", "protein"); + map.add("informat", "automatic"); + map.add("outputformat", "mview"); + map.add("sequence", clustaloJobId); + map.add("htmlmarkup", "head"); + map.add("css", "true"); + map.add("toolId", "mview"); + map.add("pcid", "aligned"); + map.add("alignment", "true"); + map.add("ruler", "true"); + map.add("width", "100"); + map.add("coloring", "identity"); + map.add("colormap", "RED"); + map.add("email", SecurityUtils.getCurrentUserLogin().orElseThrow()); + HttpEntity> entity = new HttpEntity<>(map, httpHeaders); + return runEbiJob(entity, MVIEW_URL); + } + + public ClustalOResp alignUsingClustalO(String sequence) throws InterruptedException { + // Run ClustalO job + String clustaloJobId = runClustaloJob(sequence); + + // Run MView job + String mviewJobIds = runMviewJob(clustaloJobId); + + // Return result + ClustalOResp clustalOResp = new ClustalOResp(); + RestTemplate restTemplate = new RestTemplate(); + clustalOResp.setClustalo( + restTemplate.getForObject( + URI.create(getEbiApiUrl(CLUSTAL_O_URL + "/result/" + clustaloJobId + "/aln-clustal_num")), + String.class + ) + ); + clustalOResp.setFasta( + restTemplate.getForObject(URI.create(getEbiApiUrl(CLUSTAL_O_URL + "/result/" + clustaloJobId + "/fa")), String.class) + ); + clustalOResp.setMview( + restTemplate.getForObject(URI.create(getEbiApiUrl(MVIEW_URL + "/result/" + mviewJobIds + "/aln-html")), String.class) + ); + return clustalOResp; + } + + private String getEbiApiUrl(String tool) { + return BASE_URL + tool; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/EligibilityCriteriaQueryService.java b/src/main/java/org/mskcc/oncokb/curation/service/EligibilityCriteriaQueryService.java new file mode 100644 index 000000000..2b0c4da67 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/EligibilityCriteriaQueryService.java @@ -0,0 +1,113 @@ +package org.mskcc.oncokb.curation.service; + +import jakarta.persistence.criteria.JoinType; +import java.util.List; +import org.mskcc.oncokb.curation.domain.*; // for static metamodels +import org.mskcc.oncokb.curation.domain.EligibilityCriteria; +import org.mskcc.oncokb.curation.repository.EligibilityCriteriaRepository; +import org.mskcc.oncokb.curation.service.criteria.EligibilityCriteriaCriteria; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import tech.jhipster.service.QueryService; + +/** + * Service for executing complex queries for {@link EligibilityCriteria} entities in the database. + * The main input is a {@link EligibilityCriteriaCriteria} which gets converted to {@link Specification}, + * in a way that all the filters must apply. + * It returns a {@link List} of {@link EligibilityCriteria} or a {@link Page} of {@link EligibilityCriteria} which fulfills the criteria. + */ +@Service +@Transactional(readOnly = true) +public class EligibilityCriteriaQueryService extends QueryService { + + private final Logger log = LoggerFactory.getLogger(EligibilityCriteriaQueryService.class); + + private final EligibilityCriteriaRepository eligibilityCriteriaRepository; + + public EligibilityCriteriaQueryService(EligibilityCriteriaRepository eligibilityCriteriaRepository) { + this.eligibilityCriteriaRepository = eligibilityCriteriaRepository; + } + + /** + * Return a {@link List} of {@link EligibilityCriteria} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public List findByCriteria(EligibilityCriteriaCriteria criteria) { + log.debug("find by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return eligibilityCriteriaRepository.findAll(specification); + } + + /** + * Return a {@link Page} of {@link EligibilityCriteria} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @param page The page, which should be returned. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public Page findByCriteria(EligibilityCriteriaCriteria criteria, Pageable page) { + log.debug("find by criteria : {}, page: {}", criteria, page); + final Specification specification = createSpecification(criteria); + return eligibilityCriteriaRepository.findAll(specification, page); + } + + /** + * Return the number of matching entities in the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the number of matching entities. + */ + @Transactional(readOnly = true) + public long countByCriteria(EligibilityCriteriaCriteria criteria) { + log.debug("count by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return eligibilityCriteriaRepository.count(specification); + } + + /** + * Function to convert {@link EligibilityCriteriaCriteria} to a {@link Specification} + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching {@link Specification} of the entity. + */ + protected Specification createSpecification(EligibilityCriteriaCriteria criteria) { + Specification specification = Specification.where(null); + if (criteria != null) { + // This has to be called first, because the distinct method returns null + if (criteria.getDistinct() != null) { + specification = specification.or(distinct(criteria.getDistinct())); + } + if (criteria.getId() != null) { + specification = specification.or(buildRangeSpecification(criteria.getId(), EligibilityCriteria_.id)); + } + if (criteria.getType() != null) { + specification = specification.or(buildSpecification(criteria.getType(), EligibilityCriteria_.type)); + } + if (criteria.getPriority() != null) { + specification = specification.or(buildRangeSpecification(criteria.getPriority(), EligibilityCriteria_.priority)); + } + if (criteria.getAssociationId() != null) { + specification = specification.or( + buildSpecification( + criteria.getAssociationId(), + root -> root.join(EligibilityCriteria_.associations, JoinType.LEFT).get(Association_.id) + ) + ); + } + if (criteria.getClinicalTrialId() != null) { + specification = specification.or( + buildSpecification( + criteria.getClinicalTrialId(), + root -> root.join(EligibilityCriteria_.clinicalTrial, JoinType.LEFT).get(ClinicalTrial_.id) + ) + ); + } + } + return specification; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/EligibilityCriteriaService.java b/src/main/java/org/mskcc/oncokb/curation/service/EligibilityCriteriaService.java new file mode 100644 index 000000000..750366a13 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/EligibilityCriteriaService.java @@ -0,0 +1,108 @@ +package org.mskcc.oncokb.curation.service; + +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.EligibilityCriteria; +import org.mskcc.oncokb.curation.repository.EligibilityCriteriaRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * Service Implementation for managing {@link EligibilityCriteria}. + */ +@Service +@Transactional +public class EligibilityCriteriaService { + + private final Logger log = LoggerFactory.getLogger(EligibilityCriteriaService.class); + + private final EligibilityCriteriaRepository eligibilityCriteriaRepository; + + public EligibilityCriteriaService(EligibilityCriteriaRepository eligibilityCriteriaRepository) { + this.eligibilityCriteriaRepository = eligibilityCriteriaRepository; + } + + /** + * Save a eligibilityCriteria. + * + * @param eligibilityCriteria the entity to save. + * @return the persisted entity. + */ + public EligibilityCriteria save(EligibilityCriteria eligibilityCriteria) { + log.debug("Request to save EligibilityCriteria : {}", eligibilityCriteria); + return eligibilityCriteriaRepository.save(eligibilityCriteria); + } + + /** + * Partially update a eligibilityCriteria. + * + * @param eligibilityCriteria the entity to update partially. + * @return the persisted entity. + */ + public Optional partialUpdate(EligibilityCriteria eligibilityCriteria) { + log.debug("Request to partially update EligibilityCriteria : {}", eligibilityCriteria); + + return eligibilityCriteriaRepository + .findById(eligibilityCriteria.getId()) + .map(existingEligibilityCriteria -> { + if (eligibilityCriteria.getType() != null) { + existingEligibilityCriteria.setType(eligibilityCriteria.getType()); + } + if (eligibilityCriteria.getPriority() != null) { + existingEligibilityCriteria.setPriority(eligibilityCriteria.getPriority()); + } + if (eligibilityCriteria.getCriteria() != null) { + existingEligibilityCriteria.setCriteria(eligibilityCriteria.getCriteria()); + } + + return existingEligibilityCriteria; + }) + .map(eligibilityCriteriaRepository::save); + } + + /** + * Get all the eligibilityCriteria. + * + * @param pageable the pagination information. + * @return the list of entities. + */ + @Transactional(readOnly = true) + public Page findAll(Pageable pageable) { + log.debug("Request to get all EligibilityCriteria"); + return eligibilityCriteriaRepository.findAll(pageable); + } + + /** + * Get all the eligibilityCriteria with eager load of many-to-many relationships. + * + * @return the list of entities. + */ + public Page findAllWithEagerRelationships(Pageable pageable) { + return eligibilityCriteriaRepository.findAllWithEagerRelationships(pageable); + } + + /** + * Get one eligibilityCriteria by id. + * + * @param id the id of the entity. + * @return the entity. + */ + @Transactional(readOnly = true) + public Optional findOne(Long id) { + log.debug("Request to get EligibilityCriteria : {}", id); + return eligibilityCriteriaRepository.findOneWithEagerRelationships(id); + } + + /** + * Delete the eligibilityCriteria by id. + * + * @param id the id of the entity. + */ + public void delete(Long id) { + log.debug("Request to delete EligibilityCriteria : {}", id); + eligibilityCriteriaRepository.deleteById(id); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/EnsemblGeneQueryService.java b/src/main/java/org/mskcc/oncokb/curation/service/EnsemblGeneQueryService.java new file mode 100644 index 000000000..517d47150 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/EnsemblGeneQueryService.java @@ -0,0 +1,150 @@ +package org.mskcc.oncokb.curation.service; + +import jakarta.persistence.criteria.JoinType; +import java.util.List; +import org.apache.commons.lang3.StringUtils; +import org.mskcc.oncokb.curation.domain.*; // for static metamodels +import org.mskcc.oncokb.curation.domain.EnsemblGene; +import org.mskcc.oncokb.curation.repository.EnsemblGeneRepository; +import org.mskcc.oncokb.curation.service.criteria.EnsemblGeneCriteria; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import tech.jhipster.service.QueryService; +import tech.jhipster.service.filter.IntegerFilter; +import tech.jhipster.service.filter.StringFilter; + +/** + * Service for executing complex queries for {@link EnsemblGene} entities in the database. + * The main input is a {@link EnsemblGeneCriteria} which gets converted to {@link Specification}, + * in a way that all the filters must apply. + * It returns a {@link List} of {@link EnsemblGene} or a {@link Page} of {@link EnsemblGene} which fulfills the criteria. + */ +@Service +@Transactional(readOnly = true) +public class EnsemblGeneQueryService extends QueryService { + + private final Logger log = LoggerFactory.getLogger(EnsemblGeneQueryService.class); + + private final EnsemblGeneRepository ensemblGeneRepository; + + public EnsemblGeneQueryService(EnsemblGeneRepository ensemblGeneRepository) { + this.ensemblGeneRepository = ensemblGeneRepository; + } + + /** + * Return a {@link List} of {@link EnsemblGene} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public List findByCriteria(EnsemblGeneCriteria criteria) { + log.debug("find by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return ensemblGeneRepository.findAll(specification); + } + + /** + * Return a {@link Page} of {@link EnsemblGene} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @param page The page, which should be returned. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public Page findByCriteria(EnsemblGeneCriteria criteria, Pageable page) { + log.debug("find by criteria : {}, page: {}", criteria, page); + final Specification specification = createSpecification(criteria); + return ensemblGeneRepository.findAll(specification, page); + } + + @Transactional(readOnly = true) + public Page findBySearchQuery(String query, Pageable page) { + EnsemblGeneCriteria criteria = new EnsemblGeneCriteria(); + StringFilter stringFilter = new StringFilter(); + stringFilter.setContains(query); + boolean isNumericQuery = StringUtils.isNumeric(query); + if (isNumericQuery) { + int numberQuery = Integer.parseInt(query); + IntegerFilter integerFilter = new IntegerFilter(); + integerFilter.setEquals(numberQuery); + criteria.setStart(integerFilter); + criteria.setEnd(integerFilter); + } + criteria.setEnsemblGeneId(stringFilter); + return findByCriteria(criteria, page); + } + + /** + * Return the number of matching entities in the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the number of matching entities. + */ + @Transactional(readOnly = true) + public long countByCriteria(EnsemblGeneCriteria criteria) { + log.debug("count by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return ensemblGeneRepository.count(specification); + } + + /** + * Function to convert {@link EnsemblGeneCriteria} to a {@link Specification} + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching {@link Specification} of the entity. + */ + protected Specification createSpecification(EnsemblGeneCriteria criteria) { + Specification specification = Specification.where(null); + if (criteria != null) { + // This has to be called first, because the distinct method returns null + if (criteria.getDistinct() != null) { + specification = specification.or(distinct(criteria.getDistinct())); + } + if (criteria.getId() != null) { + specification = specification.or(buildRangeSpecification(criteria.getId(), EnsemblGene_.id)); + } + if (criteria.getReferenceGenome() != null) { + specification = specification.or(buildSpecification(criteria.getReferenceGenome(), EnsemblGene_.referenceGenome)); + } + if (criteria.getEnsemblGeneId() != null) { + specification = specification.or(buildStringSpecification(criteria.getEnsemblGeneId(), EnsemblGene_.ensemblGeneId)); + } + if (criteria.getCanonical() != null) { + specification = specification.or(buildSpecification(criteria.getCanonical(), EnsemblGene_.canonical)); + } + if (criteria.getStart() != null) { + specification = specification.or(buildRangeSpecification(criteria.getStart(), EnsemblGene_.start)); + } + if (criteria.getEnd() != null) { + specification = specification.or(buildRangeSpecification(criteria.getEnd(), EnsemblGene_.end)); + } + if (criteria.getStrand() != null) { + specification = specification.or(buildRangeSpecification(criteria.getStrand(), EnsemblGene_.strand)); + } + if (criteria.getTranscriptId() != null) { + specification = specification.or( + buildSpecification( + criteria.getTranscriptId(), + root -> root.join(EnsemblGene_.transcripts, JoinType.LEFT).get(Transcript_.id) + ) + ); + } + if (criteria.getGeneId() != null) { + specification = specification.or( + buildSpecification(criteria.getGeneId(), root -> root.join(EnsemblGene_.gene, JoinType.LEFT).get(Gene_.id)) + ); + } + if (criteria.getSeqRegionId() != null) { + specification = specification.or( + buildSpecification( + criteria.getSeqRegionId(), + root -> root.join(EnsemblGene_.seqRegion, JoinType.LEFT).get(SeqRegion_.id) + ) + ); + } + } + return specification; + } +} diff --git a/src/main/java/org/mskcc/oncokb/transcript/service/EnsemblGeneService.java b/src/main/java/org/mskcc/oncokb/curation/service/EnsemblGeneService.java similarity index 81% rename from src/main/java/org/mskcc/oncokb/transcript/service/EnsemblGeneService.java rename to src/main/java/org/mskcc/oncokb/curation/service/EnsemblGeneService.java index c10adda56..5a1542732 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/service/EnsemblGeneService.java +++ b/src/main/java/org/mskcc/oncokb/curation/service/EnsemblGeneService.java @@ -1,18 +1,22 @@ -package org.mskcc.oncokb.transcript.service; +package org.mskcc.oncokb.curation.service; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; import org.genome_nexus.ApiException; -import org.mskcc.oncokb.transcript.domain.EnsemblGene; -import org.mskcc.oncokb.transcript.domain.Gene; -import org.mskcc.oncokb.transcript.domain.enumeration.ReferenceGenome; -import org.mskcc.oncokb.transcript.repository.EnsemblGeneRepository; -import org.mskcc.oncokb.transcript.vm.ensembl.EnsemblTranscript; +import org.mskcc.oncokb.curation.domain.EnsemblGene; +import org.mskcc.oncokb.curation.domain.Gene; +import org.mskcc.oncokb.curation.domain.SeqRegion; +import org.mskcc.oncokb.curation.domain.enumeration.ReferenceGenome; +import org.mskcc.oncokb.curation.repository.EnsemblGeneRepository; +import org.mskcc.oncokb.curation.vm.ensembl.EnsemblTranscript; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -29,17 +33,20 @@ public class EnsemblGeneService { private final GenomeNexusService genomeNexusService; private final TranscriptService transcriptService; private final GeneService geneService; + private final SeqRegionService seqRegionService; public EnsemblGeneService( EnsemblGeneRepository ensemblGeneRepository, GenomeNexusService genomeNexusService, TranscriptService transcriptService, - GeneService geneService + GeneService geneService, + SeqRegionService seqRegionService ) { this.ensemblGeneRepository = ensemblGeneRepository; this.genomeNexusService = genomeNexusService; this.transcriptService = transcriptService; this.geneService = geneService; + this.seqRegionService = seqRegionService; } /** @@ -74,8 +81,8 @@ public Optional partialUpdate(EnsemblGene ensemblGene) { if (ensemblGene.getCanonical() != null) { existingEnsemblGene.setCanonical(ensemblGene.getCanonical()); } - if (ensemblGene.getChromosome() != null) { - existingEnsemblGene.setChromosome(ensemblGene.getChromosome()); + if (ensemblGene.getSeqRegion() != null) { + existingEnsemblGene.setSeqRegion(ensemblGene.getSeqRegion()); } if (ensemblGene.getStart() != null) { existingEnsemblGene.setStart(ensemblGene.getStart()); @@ -95,12 +102,13 @@ public Optional partialUpdate(EnsemblGene ensemblGene) { /** * Get all the ensemblGenes. * + * @param pageable the pagination information. * @return the list of entities. */ @Transactional(readOnly = true) - public List findAll() { + public Page findAll(Pageable pageable) { log.debug("Request to get all EnsemblGenes"); - return ensemblGeneRepository.findAll(); + return ensemblGeneRepository.findAll(pageable); } /** @@ -116,7 +124,7 @@ public Optional findOne(Long id) { } public Optional findCanonicalEnsemblGene(Integer entrezGeneId, ReferenceGenome referenceGenome) { - return ensemblGeneRepository.findCanonicalEnsemblGene(entrezGeneId, referenceGenome.name()); + return ensemblGeneRepository.findCanonicalEnsemblGene(entrezGeneId, referenceGenome); } /** @@ -127,15 +135,19 @@ public Optional findCanonicalEnsemblGene(Integer entrezGeneId, Refe * @return the entity. */ public Optional findByEnsemblGeneIdAndReferenceGenome(String ensemblGeneId, ReferenceGenome referenceGenome) { - return ensemblGeneRepository.findByEnsemblGeneIdAndReferenceGenome(ensemblGeneId, referenceGenome.name()); + List ensemblGenes = ensemblGeneRepository.findAllByReferenceGenomeAndEnsemblGeneIdIn( + referenceGenome, + Collections.singletonList(ensemblGeneId) + ); + return ensemblGenes.size() > 0 ? Optional.of(ensemblGenes.get(0)) : Optional.empty(); } public List findAllByGeneAndReferenceGenome(Gene gene, ReferenceGenome referenceGenome) { - return ensemblGeneRepository.findAllByGeneAndReferenceGenome(gene, referenceGenome.name()); + return ensemblGeneRepository.findAllByGeneAndReferenceGenome(gene, referenceGenome); } public List findAllByReferenceGenomeAndEnsemblGeneIdIn(ReferenceGenome referenceGenome, List ensemblGeneIds) { - return ensemblGeneRepository.findAllByReferenceGenomeAndEnsemblGeneIdIn(referenceGenome.name(), ensemblGeneIds); + return ensemblGeneRepository.findAllByReferenceGenomeAndEnsemblGeneIdIn(referenceGenome, ensemblGeneIds); } public List saveByReferenceGenomeAndEntrezGeneIds(ReferenceGenome rg, List entrezGeneIds) throws ApiException { @@ -160,12 +172,13 @@ public List saveByReferenceGenomeAndEntrezGeneIds(ReferenceGenome r log.info("Processing {} of ensembl genes.", i); } EnsemblTranscript et = ensemblTranscriptList.get(i); + Optional seqRegionOptional = seqRegionService.findByNameOrCreate(et.getSeqRegionName()); Optional ensemblGeneGNOptional = ensemblGeneFromGN .stream() .filter(ensemblGene -> ensemblGene.getGeneId().equals(et.getId())) .findFirst(); if (ensemblGeneGNOptional.isPresent()) { - String entrezGeneStr = ensemblGeneGNOptional.get().getEntrezGeneId(); + String entrezGeneStr = ensemblGeneGNOptional.orElseThrow().getEntrezGeneId(); if (StringUtils.isNumeric(entrezGeneStr)) { int entrezGeneId = Integer.parseInt(entrezGeneStr); if (entrezGeneId > 0) { @@ -175,17 +188,19 @@ public List saveByReferenceGenomeAndEntrezGeneIds(ReferenceGenome r if (ensemblGeneOptional.isEmpty()) { EnsemblGene ensemblGene = new EnsemblGene(); ensemblGene.setCanonical(true); - ensemblGene.setReferenceGenome(rg.name()); + ensemblGene.setReferenceGenome(rg); ensemblGene.setEnsemblGeneId(et.getId()); ensemblGene.setStrand(et.getStrand()); ensemblGene.setStart(et.getStart()); ensemblGene.setEnd(et.getEnd()); - ensemblGene.setChromosome(et.getSeqRegionName()); - ensemblGene.setGene(savedGeneOptional.get()); + if (seqRegionOptional.isPresent()) { + ensemblGene.setSeqRegion(seqRegionOptional.orElseThrow()); + } + ensemblGene.setGene(savedGeneOptional.orElseThrow()); EnsemblGene savedEnsemblGene = save(ensemblGene); savedEnsemblGenes.add(savedEnsemblGene); } else { - savedEnsemblGenes.add(ensemblGeneOptional.get()); + savedEnsemblGenes.add(ensemblGeneOptional.orElseThrow()); } } else { log.error("The entrez gene is not available in DB {}", entrezGeneId); diff --git a/src/main/java/org/mskcc/oncokb/curation/service/EnsemblService.java b/src/main/java/org/mskcc/oncokb/curation/service/EnsemblService.java new file mode 100644 index 000000000..fc4b174cb --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/EnsemblService.java @@ -0,0 +1,253 @@ +package org.mskcc.oncokb.curation.service; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import java.lang.reflect.Type; +import java.util.*; +import java.util.stream.Collectors; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.mskcc.oncokb.curation.domain.enumeration.ReferenceGenome; +import org.mskcc.oncokb.curation.util.GsonUtils; +import org.mskcc.oncokb.curation.vm.ensembl.EnsemblArchiveId; +import org.mskcc.oncokb.curation.vm.ensembl.EnsemblSequence; +import org.mskcc.oncokb.curation.vm.ensembl.EnsemblTranscript; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.*; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.RestTemplate; + +/** + * Created by Hongxin Zhang on 7/15/20. + */ +@Service +public class EnsemblService { + + private final Logger log = LoggerFactory.getLogger(EnsemblService.class); + + public final String ENSEMBL_37_API_URL = "https://grch37.rest.ensembl.org"; + public final String ENSEMBL_38_API_URL = "https://rest.ensembl.org"; + + private String getSequenceGETUrl(ReferenceGenome referenceGenome, String sequenceId) { + return getEnsemblAPIUrl(referenceGenome) + "/sequence/id/" + sequenceId; + } + + private String getSequencePOSTUrl(ReferenceGenome referenceGenome) { + return getEnsemblAPIUrl(referenceGenome) + "/sequence/id"; + } + + public Optional getProteinSequence(ReferenceGenome referenceGenome, String sequenceId) { + String mainSequenceId = sequenceId; + String subversion = null; + // ensembl does not accept id with subversion, trim it before fetching + if (sequenceId.contains(".")) { + int dotIndex = sequenceId.indexOf("."); + mainSequenceId = sequenceId.substring(0, dotIndex); + subversion = sequenceId.substring(dotIndex + 1); + } + + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setContentType(MediaType.APPLICATION_JSON); + HttpEntity entity = new HttpEntity<>(httpHeaders); + + RestTemplate restTemplate = new RestTemplate(); + try { + ResponseEntity response = restTemplate.exchange( + getSequenceGETUrl(referenceGenome, mainSequenceId), + HttpMethod.GET, + entity, + EnsemblSequence.class + ); + EnsemblSequence ensemblSequence = response.getBody(); + if ( + subversion != null && + (ensemblSequence.getVersion() == null || !ensemblSequence.getVersion().equals(Integer.parseInt(subversion))) + ) { + log.error("The sequence subversion is NOT the latest, aborting"); + return Optional.empty(); + } else { + return Optional.of(ensemblSequence); + } + } catch (RestClientException exception) { + log.error(exception.getMessage()); + return Optional.empty(); + } + } + + public List getProteinSequences(ReferenceGenome referenceGenome, List transcripts) { + if (transcripts.size() == 0) { + return new ArrayList<>(); + } + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setContentType(MediaType.APPLICATION_JSON); + JSONObject jsonObject = new JSONObject(); + JSONArray jsonArray = new JSONArray(); + transcripts.stream().forEach(transcript -> jsonArray.put(transcript)); + try { + jsonObject.put("ids", jsonArray); + } catch (JSONException e) { + e.printStackTrace(); + } + HttpEntity entity = new HttpEntity<>(jsonObject.toString(), httpHeaders); + + RestTemplate restTemplate = new RestTemplate(); + ResponseEntity response = restTemplate.postForEntity( + getSequencePOSTUrl(referenceGenome), + entity, + EnsemblSequence[].class + ); + return Arrays.asList(response.getBody()); + } + + public Optional getTranscript( + ReferenceGenome referenceGenome, + String transcriptId + ) { + log.info("Get info about {} {}", referenceGenome, transcriptId); + String mainTranscriptId = transcriptId; + String subversion = null; + // ensembl does not accept id with subversion, trim it before fetching + if (transcriptId.contains(".")) { + int dotIndex = transcriptId.indexOf("."); + mainTranscriptId = transcriptId.substring(0, dotIndex); + subversion = transcriptId.substring(dotIndex + 1); + } + List ensemblTranscriptList = getIds( + referenceGenome, + Collections.singletonList(mainTranscriptId), + true, + true + ); + EnsemblTranscript ensemblTranscript = ensemblTranscriptList.size() > 0 ? ensemblTranscriptList.get(0) : null; + if ( + ensemblTranscript != null && + subversion != null && + (ensemblTranscript.getVersion() == null || !ensemblTranscript.getVersion().equals(Integer.parseInt(subversion))) + ) { + log.error("The transcript subversion is NOT the latest transcript, aborting"); + return Optional.empty(); + } else if (ensemblTranscript != null) { + return Optional.of(ensemblTranscript); + } else { + log.error("No transcript found for {} {}", referenceGenome, mainTranscriptId); + return Optional.empty(); + } + } + + public Optional getArchiveId(ReferenceGenome referenceGenome, String id) { + List ensemblTranscriptList = getArchiveIds( + referenceGenome, + Collections.singletonList(id) + ); + return ensemblTranscriptList.size() > 0 ? Optional.of(ensemblTranscriptList.get(0)) : Optional.empty(); + } + + public List getArchiveIds(ReferenceGenome referenceGenome, List ids) { + if (ids.size() == 0) { + return new ArrayList<>(); + } + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setContentType(MediaType.APPLICATION_JSON); + JSONObject jsonObject = new JSONObject(); + JSONArray jsonArray = new JSONArray(); + ids.stream().forEach(id -> jsonArray.put(id)); + try { + jsonObject.put("ids", jsonArray); + } catch (JSONException e) { + e.printStackTrace(); + } + HttpEntity entity = new HttpEntity<>(jsonObject.toString(), httpHeaders); + + RestTemplate restTemplate = new RestTemplate(); + String response = restTemplate.postForObject(getArchiveIdPOSTUrl(referenceGenome), entity, String.class); + Gson gson = GsonUtils.create(); + Type type = new TypeToken>() {}.getType(); + Map archiveMap = gson.fromJson(response, type); + return archiveMap.values().stream().filter(val -> val != null).collect(Collectors.toList()); + } + + public Optional getId( + ReferenceGenome referenceGenome, + String id, + boolean includeUtr, + boolean expand + ) { + List ensemblTranscriptList = getIds( + referenceGenome, + Collections.singletonList(id), + includeUtr, + expand + ); + return ensemblTranscriptList.size() > 0 ? Optional.of(ensemblTranscriptList.get(0)) : Optional.empty(); + } + + public List getIds( + ReferenceGenome referenceGenome, + List ids, + boolean includeUtr, + boolean expand + ) { + if (ids.size() == 0) { + return new ArrayList<>(); + } + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setContentType(MediaType.APPLICATION_JSON); + JSONObject jsonObject = new JSONObject(); + JSONArray jsonArray = new JSONArray(); + ids.stream().forEach(id -> jsonArray.put(id)); + try { + jsonObject.put("ids", jsonArray); + } catch (JSONException e) { + e.printStackTrace(); + } + HttpEntity entity = new HttpEntity<>(jsonObject.toString(), httpHeaders); + + try { + RestTemplate restTemplate = new RestTemplate(); + String response = restTemplate.postForObject(getLookupPOSTUrl(referenceGenome, includeUtr, expand), entity, String.class); + Type type = new TypeToken>() {}.getType(); + Map transcriptMap = GsonUtils.create().fromJson(response, type); + return transcriptMap.values().stream().filter(val -> val != null).collect(Collectors.toList()); + } catch (Exception e) { + log.error(e.getMessage()); + return new ArrayList<>(); + } + } + + private String getArchiveIdPOSTUrl(ReferenceGenome referenceGenome) { + StringBuilder sb = new StringBuilder(); + sb.append("/archive/id"); + return getEnsemblAPIUrl(referenceGenome) + sb; + } + + private String getLookupPOSTUrl(ReferenceGenome referenceGenome, boolean includeUtr, boolean expand) { + StringBuilder sb = new StringBuilder(); + sb.append("/lookup/id"); + if (includeUtr || expand) { + List requestParams = new ArrayList<>(); + sb.append("?"); + if (includeUtr) { + requestParams.add("utr=1"); + } + if (expand) { + requestParams.add("expand=1"); + } + sb.append(String.join("&", requestParams)); + } + return getEnsemblAPIUrl(referenceGenome) + sb; + } + + private String getEnsemblAPIUrl(ReferenceGenome referenceGenome) { + switch (referenceGenome) { + case GRCh37: + return ENSEMBL_37_API_URL; + case GRCh38: + return ENSEMBL_38_API_URL; + default: + return ""; + } + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/EvidenceQueryService.java b/src/main/java/org/mskcc/oncokb/curation/service/EvidenceQueryService.java new file mode 100644 index 000000000..359bb7221 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/EvidenceQueryService.java @@ -0,0 +1,121 @@ +package org.mskcc.oncokb.curation.service; + +import jakarta.persistence.criteria.JoinType; +import java.util.List; +import org.mskcc.oncokb.curation.domain.*; // for static metamodels +import org.mskcc.oncokb.curation.domain.Evidence; +import org.mskcc.oncokb.curation.repository.EvidenceRepository; +import org.mskcc.oncokb.curation.service.criteria.EvidenceCriteria; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import tech.jhipster.service.QueryService; + +/** + * Service for executing complex queries for {@link Evidence} entities in the database. + * The main input is a {@link EvidenceCriteria} which gets converted to {@link Specification}, + * in a way that all the filters must apply. + * It returns a {@link List} of {@link Evidence} or a {@link Page} of {@link Evidence} which fulfills the criteria. + */ +@Service +@Transactional(readOnly = true) +public class EvidenceQueryService extends QueryService { + + private final Logger log = LoggerFactory.getLogger(EvidenceQueryService.class); + + private final EvidenceRepository evidenceRepository; + + public EvidenceQueryService(EvidenceRepository evidenceRepository) { + this.evidenceRepository = evidenceRepository; + } + + /** + * Return a {@link List} of {@link Evidence} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public List findByCriteria(EvidenceCriteria criteria) { + log.debug("find by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return evidenceRepository.findAll(specification); + } + + /** + * Return a {@link Page} of {@link Evidence} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @param page The page, which should be returned. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public Page findByCriteria(EvidenceCriteria criteria, Pageable page) { + log.debug("find by criteria : {}, page: {}", criteria, page); + final Specification specification = createSpecification(criteria); + return evidenceRepository.findAll(specification, page); + } + + /** + * Return the number of matching entities in the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the number of matching entities. + */ + @Transactional(readOnly = true) + public long countByCriteria(EvidenceCriteria criteria) { + log.debug("count by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return evidenceRepository.count(specification); + } + + /** + * Function to convert {@link EvidenceCriteria} to a {@link Specification} + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching {@link Specification} of the entity. + */ + protected Specification createSpecification(EvidenceCriteria criteria) { + Specification specification = Specification.where(null); + if (criteria != null) { + // This has to be called first, because the distinct method returns null + if (criteria.getDistinct() != null) { + specification = specification.or(distinct(criteria.getDistinct())); + } + if (criteria.getId() != null) { + specification = specification.or(buildRangeSpecification(criteria.getId(), Evidence_.id)); + } + if (criteria.getUuid() != null) { + specification = specification.or(buildStringSpecification(criteria.getUuid(), Evidence_.uuid)); + } + if (criteria.getEvidenceType() != null) { + specification = specification.or(buildStringSpecification(criteria.getEvidenceType(), Evidence_.evidenceType)); + } + if (criteria.getKnownEffect() != null) { + specification = specification.or(buildStringSpecification(criteria.getKnownEffect(), Evidence_.knownEffect)); + } + if (criteria.getAssociationId() != null) { + specification = specification.or( + buildSpecification( + criteria.getAssociationId(), + root -> root.join(Evidence_.association, JoinType.LEFT).get(Association_.id) + ) + ); + } + if (criteria.getLevelOfEvidenceId() != null) { + specification = specification.or( + buildSpecification( + criteria.getLevelOfEvidenceId(), + root -> root.join(Evidence_.levelOfEvidences, JoinType.LEFT).get(LevelOfEvidence_.id) + ) + ); + } + if (criteria.getGeneId() != null) { + specification = specification.or( + buildSpecification(criteria.getGeneId(), root -> root.join(Evidence_.gene, JoinType.LEFT).get(Gene_.id)) + ); + } + } + return specification; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/EvidenceService.java b/src/main/java/org/mskcc/oncokb/curation/service/EvidenceService.java new file mode 100644 index 000000000..7508b1a08 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/EvidenceService.java @@ -0,0 +1,114 @@ +package org.mskcc.oncokb.curation.service; + +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.Evidence; +import org.mskcc.oncokb.curation.repository.EvidenceRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * Service Implementation for managing {@link Evidence}. + */ +@Service +@Transactional +public class EvidenceService { + + private final Logger log = LoggerFactory.getLogger(EvidenceService.class); + + private final EvidenceRepository evidenceRepository; + + public EvidenceService(EvidenceRepository evidenceRepository) { + this.evidenceRepository = evidenceRepository; + } + + /** + * Save a evidence. + * + * @param evidence the entity to save. + * @return the persisted entity. + */ + public Evidence save(Evidence evidence) { + log.debug("Request to save Evidence : {}", evidence); + return evidenceRepository.save(evidence); + } + + /** + * Partially update a evidence. + * + * @param evidence the entity to update partially. + * @return the persisted entity. + */ + public Optional partialUpdate(Evidence evidence) { + log.debug("Request to partially update Evidence : {}", evidence); + + return evidenceRepository + .findById(evidence.getId()) + .map(existingEvidence -> { + if (evidence.getUuid() != null) { + existingEvidence.setUuid(evidence.getUuid()); + } + if (evidence.getEvidenceType() != null) { + existingEvidence.setEvidenceType(evidence.getEvidenceType()); + } + if (evidence.getKnownEffect() != null) { + existingEvidence.setKnownEffect(evidence.getKnownEffect()); + } + if (evidence.getDescription() != null) { + existingEvidence.setDescription(evidence.getDescription()); + } + if (evidence.getNote() != null) { + existingEvidence.setNote(evidence.getNote()); + } + + return existingEvidence; + }) + .map(evidenceRepository::save); + } + + /** + * Get all the evidences. + * + * @param pageable the pagination information. + * @return the list of entities. + */ + @Transactional(readOnly = true) + public Page findAll(Pageable pageable) { + log.debug("Request to get all Evidences"); + return evidenceRepository.findAll(pageable); + } + + /** + * Get all the evidences with eager load of many-to-many relationships. + * + * @return the list of entities. + */ + public Page findAllWithEagerRelationships(Pageable pageable) { + return evidenceRepository.findAllWithEagerRelationships(pageable); + } + + /** + * Get one evidence by id. + * + * @param id the id of the entity. + * @return the entity. + */ + @Transactional(readOnly = true) + public Optional findOne(Long id) { + log.debug("Request to get Evidence : {}", id); + return evidenceRepository.findOneWithEagerRelationships(id); + } + + /** + * Delete the evidence by id. + * + * @param id the id of the entity. + */ + public void delete(Long id) { + log.debug("Request to delete Evidence : {}", id); + evidenceRepository.deleteById(id); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/FdaDrugQueryService.java b/src/main/java/org/mskcc/oncokb/curation/service/FdaDrugQueryService.java new file mode 100644 index 000000000..16454ce60 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/FdaDrugQueryService.java @@ -0,0 +1,115 @@ +package org.mskcc.oncokb.curation.service; + +import jakarta.persistence.criteria.JoinType; +import java.util.List; +import org.mskcc.oncokb.curation.domain.*; // for static metamodels +import org.mskcc.oncokb.curation.domain.FdaDrug; +import org.mskcc.oncokb.curation.repository.FdaDrugRepository; +import org.mskcc.oncokb.curation.service.criteria.FdaDrugCriteria; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import tech.jhipster.service.QueryService; + +/** + * Service for executing complex queries for {@link FdaDrug} entities in the database. + * The main input is a {@link FdaDrugCriteria} which gets converted to {@link Specification}, + * in a way that all the filters must apply. + * It returns a {@link List} of {@link FdaDrug} or a {@link Page} of {@link FdaDrug} which fulfills the criteria. + */ +@Service +@Transactional(readOnly = true) +public class FdaDrugQueryService extends QueryService { + + private final Logger log = LoggerFactory.getLogger(FdaDrugQueryService.class); + + private final FdaDrugRepository fdaDrugRepository; + + public FdaDrugQueryService(FdaDrugRepository fdaDrugRepository) { + this.fdaDrugRepository = fdaDrugRepository; + } + + /** + * Return a {@link List} of {@link FdaDrug} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public List findByCriteria(FdaDrugCriteria criteria) { + log.debug("find by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return fdaDrugRepository.findAll(specification); + } + + /** + * Return a {@link Page} of {@link FdaDrug} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @param page The page, which should be returned. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public Page findByCriteria(FdaDrugCriteria criteria, Pageable page) { + log.debug("find by criteria : {}, page: {}", criteria, page); + final Specification specification = createSpecification(criteria); + return fdaDrugRepository.findAll(specification, page); + } + + /** + * Return the number of matching entities in the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the number of matching entities. + */ + @Transactional(readOnly = true) + public long countByCriteria(FdaDrugCriteria criteria) { + log.debug("count by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return fdaDrugRepository.count(specification); + } + + /** + * Function to convert {@link FdaDrugCriteria} to a {@link Specification} + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching {@link Specification} of the entity. + */ + protected Specification createSpecification(FdaDrugCriteria criteria) { + Specification specification = Specification.where(null); + if (criteria != null) { + // This has to be called first, because the distinct method returns null + if (criteria.getDistinct() != null) { + specification = specification.or(distinct(criteria.getDistinct())); + } + if (criteria.getId() != null) { + specification = specification.or(buildRangeSpecification(criteria.getId(), FdaDrug_.id)); + } + if (criteria.getApplicationNumber() != null) { + specification = specification.or(buildStringSpecification(criteria.getApplicationNumber(), FdaDrug_.applicationNumber)); + } + if (criteria.getSponsorName() != null) { + specification = specification.or(buildStringSpecification(criteria.getSponsorName(), FdaDrug_.sponsorName)); + } + if (criteria.getOverallMarketingStatus() != null) { + specification = specification.or( + buildStringSpecification(criteria.getOverallMarketingStatus(), FdaDrug_.overallMarketingStatus) + ); + } + if (criteria.getFdaSubmissionId() != null) { + specification = specification.or( + buildSpecification( + criteria.getFdaSubmissionId(), + root -> root.join(FdaDrug_.fdaSubmissions, JoinType.LEFT).get(FdaSubmission_.id) + ) + ); + } + if (criteria.getDrugId() != null) { + specification = specification.or( + buildSpecification(criteria.getDrugId(), root -> root.join(FdaDrug_.drug, JoinType.LEFT).get(Drug_.id)) + ); + } + } + return specification; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/FdaDrugService.java b/src/main/java/org/mskcc/oncokb/curation/service/FdaDrugService.java new file mode 100644 index 000000000..6ed733383 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/FdaDrugService.java @@ -0,0 +1,119 @@ +package org.mskcc.oncokb.curation.service; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; +import org.mskcc.oncokb.curation.domain.FdaDrug; +import org.mskcc.oncokb.curation.repository.FdaDrugRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * Service Implementation for managing {@link FdaDrug}. + */ +@Service +@Transactional +public class FdaDrugService { + + private final Logger log = LoggerFactory.getLogger(FdaDrugService.class); + + private final FdaDrugRepository fdaDrugRepository; + + public FdaDrugService(FdaDrugRepository fdaDrugRepository) { + this.fdaDrugRepository = fdaDrugRepository; + } + + /** + * Save a fdaDrug. + * + * @param fdaDrug the entity to save. + * @return the persisted entity. + */ + public FdaDrug save(FdaDrug fdaDrug) { + log.debug("Request to save FdaDrug : {}", fdaDrug); + return fdaDrugRepository.save(fdaDrug); + } + + /** + * Partially update a fdaDrug. + * + * @param fdaDrug the entity to update partially. + * @return the persisted entity. + */ + public Optional partialUpdate(FdaDrug fdaDrug) { + log.debug("Request to partially update FdaDrug : {}", fdaDrug); + + return fdaDrugRepository + .findById(fdaDrug.getId()) + .map(existingFdaDrug -> { + if (fdaDrug.getApplicationNumber() != null) { + existingFdaDrug.setApplicationNumber(fdaDrug.getApplicationNumber()); + } + if (fdaDrug.getSponsorName() != null) { + existingFdaDrug.setSponsorName(fdaDrug.getSponsorName()); + } + if (fdaDrug.getOverallMarketingStatus() != null) { + existingFdaDrug.setOverallMarketingStatus(fdaDrug.getOverallMarketingStatus()); + } + + return existingFdaDrug; + }) + .map(fdaDrugRepository::save); + } + + /** + * Get all the fdaDrugs. + * + * @param pageable the pagination information. + * @return the list of entities. + */ + @Transactional(readOnly = true) + public Page findAll(Pageable pageable) { + log.debug("Request to get all FdaDrugs"); + return fdaDrugRepository.findAll(pageable); + } + + /** + * Get all the fdaDrugs where Drug is {@code null}. + * @return the list of entities. + */ + @Transactional(readOnly = true) + public List findAllWhereDrugIsNull() { + log.debug("Request to get all fdaDrugs where Drug is null"); + return StreamSupport.stream(fdaDrugRepository.findAll().spliterator(), false) + .filter(fdaDrug -> fdaDrug.getDrug() == null) + .collect(Collectors.toList()); + } + + /** + * Get one fdaDrug by id. + * + * @param id the id of the entity. + * @return the entity. + */ + @Transactional(readOnly = true) + public Optional findOne(Long id) { + log.debug("Request to get FdaDrug : {}", id); + return fdaDrugRepository.findById(id); + } + + @Transactional(readOnly = true) + public Optional findOneByApplicationNumber(String applicationNumber) { + return fdaDrugRepository.findFirstByApplicationNumber(applicationNumber); + } + + /** + * Delete the fdaDrug by id. + * + * @param id the id of the entity. + */ + public void delete(Long id) { + log.debug("Request to delete FdaDrug : {}", id); + fdaDrugRepository.deleteById(id); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/FdaSubmissionQueryService.java b/src/main/java/org/mskcc/oncokb/curation/service/FdaSubmissionQueryService.java new file mode 100644 index 000000000..2812b7d66 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/FdaSubmissionQueryService.java @@ -0,0 +1,161 @@ +package org.mskcc.oncokb.curation.service; + +import jakarta.persistence.criteria.JoinType; +import java.util.List; +import org.mskcc.oncokb.curation.domain.*; // for static metamodels +import org.mskcc.oncokb.curation.domain.FdaSubmission; +import org.mskcc.oncokb.curation.repository.FdaSubmissionRepository; +import org.mskcc.oncokb.curation.service.criteria.FdaSubmissionCriteria; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import tech.jhipster.service.QueryService; +import tech.jhipster.service.filter.StringFilter; + +/** + * Service for executing complex queries for {@link FdaSubmission} entities in the database. + * The main input is a {@link FdaSubmissionCriteria} which gets converted to {@link Specification}, + * in a way that all the filters must apply. + * It returns a {@link List} of {@link FdaSubmission} or a {@link Page} of {@link FdaSubmission} which fulfills the criteria. + */ +@Service +@Transactional(readOnly = true) +public class FdaSubmissionQueryService extends QueryService { + + private final Logger log = LoggerFactory.getLogger(FdaSubmissionQueryService.class); + + private final FdaSubmissionRepository fdaSubmissionRepository; + + public FdaSubmissionQueryService(FdaSubmissionRepository fdaSubmissionRepository) { + this.fdaSubmissionRepository = fdaSubmissionRepository; + } + + @Transactional(readOnly = true) + public Page findBySearchQuery(String query, Pageable page) { + FdaSubmissionCriteria criteria = new FdaSubmissionCriteria(); + StringFilter stringFilter = new StringFilter(); + stringFilter.setContains(query); + criteria.setDeviceName(stringFilter); + criteria.setNumber(stringFilter); + criteria.setSupplementNumber(stringFilter); + return findByCriteria(criteria, page); + } + + /** + * Return a {@link List} of {@link FdaSubmission} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public List findByCriteria(FdaSubmissionCriteria criteria) { + log.debug("find by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return fdaSubmissionRepository.findAll(specification); + } + + /** + * Return a {@link Page} of {@link FdaSubmission} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @param page The page, which should be returned. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public Page findByCriteria(FdaSubmissionCriteria criteria, Pageable page) { + log.debug("find by criteria : {}, page: {}", criteria, page); + final Specification specification = createSpecification(criteria); + return fdaSubmissionRepository.findAll(specification, page); + } + + /** + * Return the number of matching entities in the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the number of matching entities. + */ + @Transactional(readOnly = true) + public long countByCriteria(FdaSubmissionCriteria criteria) { + log.debug("count by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return fdaSubmissionRepository.count(specification); + } + + /** + * Function to convert {@link FdaSubmissionCriteria} to a {@link Specification} + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching {@link Specification} of the entity. + */ + protected Specification createSpecification(FdaSubmissionCriteria criteria) { + Specification specification = Specification.where(null); + if (criteria != null) { + // This has to be called first, because the distinct method returns null + if (criteria.getDistinct() != null) { + specification = specification.or(distinct(criteria.getDistinct())); + } + if (criteria.getId() != null) { + specification = specification.or(buildRangeSpecification(criteria.getId(), FdaSubmission_.id)); + } + if (criteria.getNumber() != null) { + specification = specification.or(buildStringSpecification(criteria.getNumber(), FdaSubmission_.number)); + } + if (criteria.getSupplementNumber() != null) { + specification = specification.or(buildStringSpecification(criteria.getSupplementNumber(), FdaSubmission_.supplementNumber)); + } + if (criteria.getDeviceName() != null) { + specification = specification.or(buildStringSpecification(criteria.getDeviceName(), FdaSubmission_.deviceName)); + } + if (criteria.getGenericName() != null) { + specification = specification.or(buildStringSpecification(criteria.getGenericName(), FdaSubmission_.genericName)); + } + if (criteria.getDateReceived() != null) { + specification = specification.or(buildRangeSpecification(criteria.getDateReceived(), FdaSubmission_.dateReceived)); + } + if (criteria.getDecisionDate() != null) { + specification = specification.or(buildRangeSpecification(criteria.getDecisionDate(), FdaSubmission_.decisionDate)); + } + if (criteria.getCurated() != null) { + specification = specification.or(buildSpecification(criteria.getCurated(), FdaSubmission_.curated)); + } + if (criteria.getGenetic() != null) { + specification = specification.or(buildSpecification(criteria.getGenetic(), FdaSubmission_.genetic)); + } + if (criteria.getArticleId() != null) { + specification = specification.or( + buildSpecification(criteria.getArticleId(), root -> root.join(FdaSubmission_.articles, JoinType.LEFT).get(Article_.id)) + ); + } + if (criteria.getAssociationId() != null) { + specification = specification.or( + buildSpecification( + criteria.getAssociationId(), + root -> root.join(FdaSubmission_.associations, JoinType.LEFT).get(Association_.id) + ) + ); + } + if (criteria.getCompanionDiagnosticDeviceId() != null) { + specification = specification.or( + buildSpecification( + criteria.getCompanionDiagnosticDeviceId(), + root -> root.join(FdaSubmission_.companionDiagnosticDevice, JoinType.LEFT).get(CompanionDiagnosticDevice_.id) + ) + ); + } + if (criteria.getFdaDrugId() != null) { + specification = specification.or( + buildSpecification(criteria.getFdaDrugId(), root -> root.join(FdaSubmission_.fdaDrug, JoinType.LEFT).get(FdaDrug_.id)) + ); + } + if (criteria.getTypeId() != null) { + specification = specification.or( + buildSpecification( + criteria.getTypeId(), + root -> root.join(FdaSubmission_.type, JoinType.LEFT).get(FdaSubmissionType_.id) + ) + ); + } + } + return specification; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/FdaSubmissionService.java b/src/main/java/org/mskcc/oncokb/curation/service/FdaSubmissionService.java new file mode 100644 index 000000000..2f150d92f --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/FdaSubmissionService.java @@ -0,0 +1,198 @@ +package org.mskcc.oncokb.curation.service; + +import java.util.List; +import java.util.Optional; +import java.util.Set; +import org.apache.commons.lang3.StringUtils; +import org.mskcc.oncokb.curation.domain.FdaSubmission; +import org.mskcc.oncokb.curation.repository.FdaSubmissionRepository; +import org.mskcc.oncokb.curation.util.CdxUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * Service Implementation for managing {@link FdaSubmission}. + */ +@Service +@Transactional +public class FdaSubmissionService { + + private final Logger log = LoggerFactory.getLogger(FdaSubmissionService.class); + + private final FdaSubmissionRepository fdaSubmissionRepository; + + private final CdxUtils cdxUtils; + + public FdaSubmissionService(FdaSubmissionRepository fdaSubmissionRepository, CdxUtils cdxUtils) { + this.fdaSubmissionRepository = fdaSubmissionRepository; + this.cdxUtils = cdxUtils; + } + + /** + * Save a fdaSubmission. + * + * @param fdaSubmission the entity to save. + * @return the persisted entity. + */ + public FdaSubmission save(FdaSubmission fdaSubmission) { + log.debug("Request to save FdaSubmission : {}", fdaSubmission); + return fdaSubmissionRepository.save(fdaSubmission); + } + + /** + * Partially update a fdaSubmission. + * + * @param fdaSubmission the entity to update partially. + * @return the persisted entity. + */ + public Optional partialUpdate(FdaSubmission fdaSubmission) { + log.debug("Request to partially update FdaSubmission : {}", fdaSubmission); + + return fdaSubmissionRepository + .findById(fdaSubmission.getId()) + .map(existingFdaSubmission -> { + if (fdaSubmission.getNumber() != null) { + existingFdaSubmission.setNumber(fdaSubmission.getNumber()); + } + if (fdaSubmission.getSupplementNumber() != null) { + existingFdaSubmission.setSupplementNumber(fdaSubmission.getSupplementNumber()); + } + if (fdaSubmission.getDeviceName() != null) { + existingFdaSubmission.setDeviceName(fdaSubmission.getDeviceName()); + } + if (fdaSubmission.getGenericName() != null) { + existingFdaSubmission.setGenericName(fdaSubmission.getGenericName()); + } + if (fdaSubmission.getDateReceived() != null) { + existingFdaSubmission.setDateReceived(fdaSubmission.getDateReceived()); + } + if (fdaSubmission.getDecisionDate() != null) { + existingFdaSubmission.setDecisionDate(fdaSubmission.getDecisionDate()); + } + if (fdaSubmission.getDescription() != null) { + existingFdaSubmission.setDescription(fdaSubmission.getDescription()); + } + if (fdaSubmission.getCurated() != null) { + existingFdaSubmission.setCurated(fdaSubmission.getCurated()); + } + if (fdaSubmission.getGenetic() != null) { + existingFdaSubmission.setGenetic(fdaSubmission.getGenetic()); + } + if (fdaSubmission.getNote() != null) { + existingFdaSubmission.setNote(fdaSubmission.getNote()); + } + if (fdaSubmission.getAssociations() != null) { + existingFdaSubmission.setAssociations(fdaSubmission.getAssociations()); + } + + return existingFdaSubmission; + }) + .map(fdaSubmissionRepository::save); + } + + /** + * Get all the fdaSubmissions. + * + * @param pageable the pagination information. + * @return the list of entities. + */ + @Transactional(readOnly = true) + public Page findAll(Pageable pageable) { + log.debug("Request to get all FdaSubmissions"); + return fdaSubmissionRepository.findAll(pageable); + } + + /** + * Get all the fdaSubmissions with eager load of many-to-many relationships. + * + * @return the list of entities. + */ + public Page findAllWithEagerRelationships(Pageable pageable) { + return fdaSubmissionRepository.findAllWithEagerRelationships(pageable); + } + + /** + * Get one fdaSubmission by id. + * + * @param id the id of the entity. + * @return the entity. + */ + @Transactional(readOnly = true) + public Optional findOne(Long id) { + log.debug("Request to get FdaSubmission : {}", id); + return fdaSubmissionRepository.findOneWithEagerRelationships(id); + } + + /** + * Get one fdaSubmission by number and supplement number + * @param number the primary number of the fda submission + * @param supplementNumber the supplement number + * @return the entity + */ + public Optional findByNumberAndSupplementNumber(String number, String supplementNumber) { + return fdaSubmissionRepository.findByNumberAndSupplementNumber(number, supplementNumber).stream().findAny(); + } + + /** + * If the fda submission does not exist in db, then fetch and parse the information from fda website + * @param number the primary fda submission number + * @param supplementNumber the supplement number + * @return Optional with the parsed fda submission or the one already existing in db, otherwise empty optional + */ + public Optional findOrFetchFdaSubmissionByNumber(String number, String supplementNumber, Boolean getAllSupplements) { + Optional fdaSubmission = this.findByNumberAndSupplementNumber(number, supplementNumber); + if (fdaSubmission.isEmpty()) { // Fetch from FDA website if not present in database + if (StringUtils.isEmpty(number)) { + return Optional.empty(); + } + String submissionNumber = number; + if (!StringUtils.isEmpty(supplementNumber)) { + submissionNumber += "/" + supplementNumber; + } + Set newFdaSubmissions = cdxUtils.getFDASubmissionFromHTML( + Set.of(submissionNumber), + supplementNumber != null, + getAllSupplements + ); + return newFdaSubmissions + .stream() + .filter(sub -> { + return number.equals(sub.getNumber()) && StringUtils.equals(supplementNumber, sub.getSupplementNumber()); + }) + .findFirst(); + } + return fdaSubmission; + } + + public List findByCompanionDiagnosticDevice(Long id) { + return fdaSubmissionRepository.findByCompanionDiagnosticDeviceId(id); + } + + /** + * Checks whether another fda submission exists with the same number, supplement number and cdx association + * @param fdaSubmission the fda submision entity + */ + public Boolean isUnique(FdaSubmission fdaSubmission) { + return fdaSubmissionRepository + .findByNumberAndSupplementNumberAndCompanionDiagnosticDevice( + fdaSubmission.getNumber(), + fdaSubmission.getSupplementNumber(), + fdaSubmission.getCompanionDiagnosticDevice() + ) + .isEmpty(); + } + + /** + * Delete the fdaSubmission by id. + * + * @param id the id of the entity. + */ + public void delete(Long id) { + log.debug("Request to delete FdaSubmission : {}", id); + fdaSubmissionRepository.deleteById(id); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/FdaSubmissionTypeService.java b/src/main/java/org/mskcc/oncokb/curation/service/FdaSubmissionTypeService.java new file mode 100644 index 000000000..bf795b3f5 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/FdaSubmissionTypeService.java @@ -0,0 +1,124 @@ +package org.mskcc.oncokb.curation.service; + +import java.util.List; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.FdaSubmissionType; +import org.mskcc.oncokb.curation.domain.enumeration.FdaSubmissionTypeKey; +import org.mskcc.oncokb.curation.repository.FdaSubmissionTypeRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * Service Implementation for managing {@link FdaSubmissionType}. + */ +@Service +@Transactional +public class FdaSubmissionTypeService { + + private final Logger log = LoggerFactory.getLogger(FdaSubmissionTypeService.class); + + private final FdaSubmissionTypeRepository fdaSubmissionTypeRepository; + + public FdaSubmissionTypeService(FdaSubmissionTypeRepository fdaSubmissionTypeRepository) { + this.fdaSubmissionTypeRepository = fdaSubmissionTypeRepository; + } + + /** + * Save a fdaSubmissionType. + * + * @param fdaSubmissionType the entity to save. + * @return the persisted entity. + */ + public FdaSubmissionType save(FdaSubmissionType fdaSubmissionType) { + log.debug("Request to save FdaSubmissionType : {}", fdaSubmissionType); + return fdaSubmissionTypeRepository.save(fdaSubmissionType); + } + + /** + * Partially update a fdaSubmissionType. + * + * @param fdaSubmissionType the entity to update partially. + * @return the persisted entity. + */ + public Optional partialUpdate(FdaSubmissionType fdaSubmissionType) { + log.debug("Request to partially update FdaSubmissionType : {}", fdaSubmissionType); + + return fdaSubmissionTypeRepository + .findById(fdaSubmissionType.getId()) + .map(existingFdaSubmissionType -> { + if (fdaSubmissionType.getType() != null) { + existingFdaSubmissionType.setType(fdaSubmissionType.getType()); + } + if (fdaSubmissionType.getName() != null) { + existingFdaSubmissionType.setName(fdaSubmissionType.getName()); + } + if (fdaSubmissionType.getShortName() != null) { + existingFdaSubmissionType.setShortName(fdaSubmissionType.getShortName()); + } + if (fdaSubmissionType.getSubmissionPrefix() != null) { + existingFdaSubmissionType.setSubmissionPrefix(fdaSubmissionType.getSubmissionPrefix()); + } + if (fdaSubmissionType.getSubmissionLink() != null) { + existingFdaSubmissionType.setSubmissionLink(fdaSubmissionType.getSubmissionLink()); + } + if (fdaSubmissionType.getDescription() != null) { + existingFdaSubmissionType.setDescription(fdaSubmissionType.getDescription()); + } + + return existingFdaSubmissionType; + }) + .map(fdaSubmissionTypeRepository::save); + } + + /** + * Get all the fdaSubmissionTypes. + * + * @return the list of entities. + */ + @Transactional(readOnly = true) + public List findAll() { + log.debug("Request to get all FdaSubmissionTypes"); + return fdaSubmissionTypeRepository.findAll(); + } + + /** + * Get one fdaSubmissionType by id. + * + * @param id the id of the entity. + * @return the entity. + */ + @Transactional(readOnly = true) + public Optional findOne(Long id) { + log.debug("Request to get FdaSubmissionType : {}", id); + return fdaSubmissionTypeRepository.findById(id); + } + + @Transactional(readOnly = true) + public Optional findByType(FdaSubmissionTypeKey typeKey) { + log.debug("Request to get FdaSubmissionTypeKey : {}", typeKey); + return fdaSubmissionTypeRepository.findByType(typeKey); + } + + @Transactional(readOnly = true) + public Optional findOneBySubmissionNumber(String submissionNumber) { + log.debug("Request to get FdaSubmissionType : {}", submissionNumber); + String[] splitSubmission = submissionNumber.split("[0-9]"); + if (splitSubmission.length == 0) { + return Optional.empty(); + } + FdaSubmissionTypeKey type = FdaSubmissionTypeKey.getTypeByPrefix(splitSubmission[0]); + return fdaSubmissionTypeRepository.findByType(type); + } + + /** + * Delete the fdaSubmissionType by id. + * + * @param id the id of the entity. + */ + public void delete(Long id) { + log.debug("Request to delete FdaSubmissionType : {}", id); + fdaSubmissionTypeRepository.deleteById(id); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/FirebaseService.java b/src/main/java/org/mskcc/oncokb/curation/service/FirebaseService.java new file mode 100644 index 000000000..81df826c1 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/FirebaseService.java @@ -0,0 +1,152 @@ +package org.mskcc.oncokb.curation.service; + +import com.google.firebase.database.*; +import java.util.*; +import org.apache.commons.lang3.StringUtils; +import org.mskcc.oncokb.curation.domain.Alteration; +import org.mskcc.oncokb.curation.domain.Association; +import org.mskcc.oncokb.curation.domain.Evidence; +import org.mskcc.oncokb.curation.domain.NciThesaurus; +import org.mskcc.oncokb.curation.domain.enumeration.EvidenceType; +import org.mskcc.oncokb.curation.domain.firebase.Drug; +import org.mskcc.oncokb.curation.domain.firebase.Gene; +import org.mskcc.oncokb.curation.domain.firebase.Mutation; +import org.mskcc.oncokb.curation.domain.firebase.MutationEffect; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +@Service +public class FirebaseService { + + private final Logger log = LoggerFactory.getLogger(FirebaseService.class); + private final GeneService geneService; + private final AlterationService alterationService; + private final EvidenceService evidenceService; + private final AssociationService associationService; + private final DrugService drugService; + private final NciThesaurusService nciThesaurusService; + private FirebaseDatabase database; + + public FirebaseService( + GeneService geneService, + AlterationService alterationService, + EvidenceService evidenceService, + AssociationService associationService, + DrugService drugService, + NciThesaurusService nciThesaurusService + ) { + this.geneService = geneService; + this.alterationService = alterationService; + this.evidenceService = evidenceService; + this.associationService = associationService; + this.drugService = drugService; + this.nciThesaurusService = nciThesaurusService; + } + + public void readGene() { + String PATH = "Genes/BRAF"; + database = FirebaseDatabase.getInstance(); + DatabaseReference ref = database.getReference(PATH); + // Attach a listener to read the data + ref.addValueEventListener( + new ValueEventListener() { + @Override + public void onDataChange(DataSnapshot dataSnapshot) { + Gene gene = dataSnapshot.getValue(Gene.class); + log.info("Loaded {}", PATH); + importGeneData(gene); + } + + @Override + public void onCancelled(DatabaseError databaseError) { + log.error("The read failed: {}", databaseError.getCode()); + } + } + ); + } + + private void importGeneData(Gene gene) { + Optional geneOptional = geneService.findGeneByHugoSymbol(gene.getName()); + if (geneOptional.isEmpty()) { + log.error("Cannot find matched gene {}", gene.getName()); + } + + for (Mutation mutation : gene.getMutations()) { + List altList = alterationService.findByNameOrAlterationAndGenesId( + mutation.getName(), + geneOptional.orElseThrow().getId() + ); + if (altList.isEmpty()) { + Alteration alteration = new Alteration(); + alteration.setName(mutation.getName()); + alteration.setGenes(Collections.singleton(geneOptional.orElseThrow())); + altList.add(alterationService.save(alteration)); + } + if (mutation.getMutationEffect() != null) { + MutationEffect me = mutation.getMutationEffect(); + if (StringUtils.isNotEmpty(me.getOncogenic())) { + Evidence evidence = new Evidence(); + evidence.setEvidenceType(EvidenceType.ONCOGENIC.name()); + evidence.setKnownEffect(me.getOncogenic()); + Association association = new Association(); + association.setAlterations(new HashSet<>(altList)); + // association = associationService.save(association); + evidence.setAssociation(association); + evidenceService.save(evidence); + } + } + } + } + + public void importDrugs() { + database = FirebaseDatabase.getInstance(); + DatabaseReference ref = database.getReference("Drugs"); + // Attach a listener to read the data + ref.addValueEventListener( + new ValueEventListener() { + @Override + public void onDataChange(DataSnapshot dataSnapshot) { + GenericTypeIndicator> genericTypeIndicator = new GenericTypeIndicator>() {}; + Map drugMap = dataSnapshot.getValue(genericTypeIndicator); + log.info("Loaded Drugs"); + for (Map.Entry drugEntry : drugMap.entrySet()) { + Drug drug = drugEntry.getValue(); + Optional drugOptional = Optional.empty(); + if (StringUtils.isEmpty(drug.getNcitCode())) { + drugOptional = drugService.findByName(drug.getDrugName()); + } else { + drugOptional = drugService.findByCode(drug.getNcitCode()); + } + if (drugOptional.isEmpty()) { + Optional nciThesaurusOptional = Optional.empty(); + if (StringUtils.isEmpty(drug.getNcitCode())) { + nciThesaurusOptional = nciThesaurusService.findOneByNamePriority(drug.getDrugName()); + } else { + nciThesaurusOptional = nciThesaurusService.findByCode(drug.getNcitCode()); + } + if (nciThesaurusOptional.isEmpty()) { + log.error("Cannot find the NCIT code from drug {} {}", drug.getNcitCode(), drug.getDrugName()); + } else { + org.mskcc.oncokb.curation.domain.Drug newDrugEntity = new org.mskcc.oncokb.curation.domain.Drug(); + newDrugEntity.setNciThesaurus(nciThesaurusOptional.orElseThrow()); + newDrugEntity.setName(drug.getDrugName()); + newDrugEntity.setUuid(drug.getUuid()); + drugService.save(newDrugEntity); + log.info("Add new drug {} {}", drug.getDrugName(), drug.getNcitCode()); + } + } else { + drugOptional.orElseThrow().setUuid(drug.getUuid()); + drugService.partialUpdate(drugOptional.orElseThrow()); + } + } + } + + @Override + public void onCancelled(DatabaseError databaseError) { + log.error("The read failed: {}", databaseError.getCode()); + } + } + ); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/FlagQueryService.java b/src/main/java/org/mskcc/oncokb/curation/service/FlagQueryService.java new file mode 100644 index 000000000..46931c639 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/FlagQueryService.java @@ -0,0 +1,137 @@ +package org.mskcc.oncokb.curation.service; + +import jakarta.persistence.criteria.JoinType; +import java.util.List; +import org.mskcc.oncokb.curation.domain.*; // for static metamodels +import org.mskcc.oncokb.curation.domain.Flag; +import org.mskcc.oncokb.curation.repository.FlagRepository; +import org.mskcc.oncokb.curation.service.criteria.FlagCriteria; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import tech.jhipster.service.QueryService; +import tech.jhipster.service.filter.StringFilter; + +/** + * Service for executing complex queries for {@link Flag} entities in the database. + * The main input is a {@link FlagCriteria} which gets converted to {@link Specification}, + * in a way that all the filters must apply. + * It returns a {@link List} of {@link Flag} or a {@link Page} of {@link Flag} which fulfills the criteria. + */ +@Service +@Transactional(readOnly = true) +public class FlagQueryService extends QueryService { + + private final Logger log = LoggerFactory.getLogger(FlagQueryService.class); + + private final FlagRepository flagRepository; + + public FlagQueryService(FlagRepository flagRepository) { + this.flagRepository = flagRepository; + } + + /** + * Return a {@link List} of {@link Flag} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public List findByCriteria(FlagCriteria criteria) { + log.debug("find by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return flagRepository.findAll(specification); + } + + /** + * Return a {@link Page} of {@link Flag} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @param page The page, which should be returned. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public Page findByCriteria(FlagCriteria criteria, Pageable page) { + log.debug("find by criteria : {}, page: {}", criteria, page); + final Specification specification = createSpecification(criteria); + return flagRepository.findAll(specification, page); + } + + @Transactional(readOnly = true) + public Page findBySearchQuery(String query, Pageable page) { + FlagCriteria criteria = new FlagCriteria(); + StringFilter stringFilter = new StringFilter(); + stringFilter.setContains(query); + criteria.setType(stringFilter); + criteria.setFlag(stringFilter); + criteria.setName(stringFilter); + return findByCriteria(criteria, page); + } + + /** + * Return the number of matching entities in the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the number of matching entities. + */ + @Transactional(readOnly = true) + public long countByCriteria(FlagCriteria criteria) { + log.debug("count by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return flagRepository.count(specification); + } + + /** + * Function to convert {@link FlagCriteria} to a {@link Specification} + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching {@link Specification} of the entity. + */ + protected Specification createSpecification(FlagCriteria criteria) { + Specification specification = Specification.where(null); + if (criteria != null) { + // This has to be called first, because the distinct method returns null + if (criteria.getDistinct() != null) { + specification = specification.or(distinct(criteria.getDistinct())); + } + if (criteria.getId() != null) { + specification = specification.or(buildRangeSpecification(criteria.getId(), Flag_.id)); + } + if (criteria.getType() != null) { + specification = specification.or(buildStringSpecification(criteria.getType(), Flag_.type)); + } + if (criteria.getFlag() != null) { + specification = specification.or(buildStringSpecification(criteria.getFlag(), Flag_.flag)); + } + if (criteria.getName() != null) { + specification = specification.or(buildStringSpecification(criteria.getName(), Flag_.name)); + } + if (criteria.getAlterationId() != null) { + specification = specification.or( + buildSpecification(criteria.getAlterationId(), root -> root.join(Flag_.alterations, JoinType.LEFT).get(Alteration_.id)) + ); + } + if (criteria.getArticleId() != null) { + specification = specification.or( + buildSpecification(criteria.getArticleId(), root -> root.join(Flag_.articles, JoinType.LEFT).get(Article_.id)) + ); + } + if (criteria.getDrugId() != null) { + specification = specification.or( + buildSpecification(criteria.getDrugId(), root -> root.join(Flag_.drugs, JoinType.LEFT).get(Drug_.id)) + ); + } + if (criteria.getGeneId() != null) { + specification = specification.or( + buildSpecification(criteria.getGeneId(), root -> root.join(Flag_.genes, JoinType.LEFT).get(Gene_.id)) + ); + } + if (criteria.getTranscriptId() != null) { + specification = specification.or( + buildSpecification(criteria.getTranscriptId(), root -> root.join(Flag_.transcripts, JoinType.LEFT).get(Transcript_.id)) + ); + } + } + return specification; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/FlagService.java b/src/main/java/org/mskcc/oncokb/curation/service/FlagService.java new file mode 100644 index 000000000..546c8a17a --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/FlagService.java @@ -0,0 +1,116 @@ +package org.mskcc.oncokb.curation.service; + +import java.util.List; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.Flag; +import org.mskcc.oncokb.curation.domain.enumeration.FlagType; +import org.mskcc.oncokb.curation.repository.FlagRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * Service Implementation for managing {@link Flag}. + */ +@Service +@Transactional +public class FlagService { + + private final Logger log = LoggerFactory.getLogger(FlagService.class); + + private final FlagRepository flagRepository; + + public FlagService(FlagRepository flagRepository) { + this.flagRepository = flagRepository; + } + + /** + * Save a flag. + * + * @param flag the entity to save. + * @return the persisted entity. + */ + public Flag save(Flag flag) { + log.debug("Request to save Flag : {}", flag); + return flagRepository.save(flag); + } + + /** + * Partially update a flag. + * + * @param flag the entity to update partially. + * @return the persisted entity. + */ + public Optional partialUpdate(Flag flag) { + log.debug("Request to partially update Flag : {}", flag); + + return flagRepository + .findById(flag.getId()) + .map(existingFlag -> { + if (flag.getType() != null) { + existingFlag.setType(flag.getType()); + } + if (flag.getFlag() != null) { + existingFlag.setFlag(flag.getFlag()); + } + if (flag.getName() != null) { + existingFlag.setName(flag.getName()); + } + if (flag.getDescription() != null) { + existingFlag.setDescription(flag.getDescription()); + } + + return existingFlag; + }) + .map(flagRepository::save); + } + + /** + * Get all the flags. + * + * @param pageable the pagination information. + * @return the list of entities. + */ + @Transactional(readOnly = true) + public Page findAll(Pageable pageable) { + log.debug("Request to get all Flags"); + return flagRepository.findAll(pageable); + } + + @Transactional(readOnly = true) + public List findAllByFlagIn(List flags) { + log.debug("Request to get all Flags"); + return flagRepository.findAllByFlagIn(flags); + } + + @Transactional(readOnly = true) + public Optional findByTypeAndFlag(FlagType type, String flag) { + log.debug("Request to get all Flags"); + return flagRepository.findByTypeAndFlag(type.name(), flag); + } + + /** + * Get one flag by id. + * + * @param id the id of the entity. + * @return the entity. + */ + @Transactional(readOnly = true) + public Optional findOne(Long id) { + log.debug("Request to get Flag : {}", id); + return flagRepository.findById(id); + } + + /** + * Delete the flag by id. + * + * @param id the id of the entity. + */ + public void delete(Long id) { + log.debug("Request to delete Flag : {}", id); + flagRepository.deleteById(id); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/GeneQueryService.java b/src/main/java/org/mskcc/oncokb/curation/service/GeneQueryService.java new file mode 100644 index 000000000..377b1e083 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/GeneQueryService.java @@ -0,0 +1,149 @@ +package org.mskcc.oncokb.curation.service; + +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.JoinType; +import java.util.List; +import org.mskcc.oncokb.curation.domain.*; // for static metamodels +import org.mskcc.oncokb.curation.domain.Gene; +import org.mskcc.oncokb.curation.repository.GeneRepository; +import org.mskcc.oncokb.curation.service.criteria.GeneCriteria; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import tech.jhipster.service.QueryService; +import tech.jhipster.service.filter.StringFilter; + +/** + * Service for executing complex queries for {@link Gene} entities in the database. + * The main input is a {@link GeneCriteria} which gets converted to {@link Specification}, + * in a way that all the filters must apply. + * It returns a {@link List} of {@link Gene} or a {@link Page} of {@link Gene} which fulfills the criteria. + */ +@Service +@Transactional(readOnly = true) +public class GeneQueryService extends QueryService { + + private final Logger log = LoggerFactory.getLogger(GeneQueryService.class); + + private final GeneRepository geneRepository; + + public GeneQueryService(GeneRepository geneRepository) { + this.geneRepository = geneRepository; + } + + @Transactional(readOnly = true) + public Page findBySearchQuery(String query, Boolean exact, Pageable page) { + GeneCriteria criteria = new GeneCriteria(); + StringFilter stringFilter = new StringFilter(); + if (exact) { + stringFilter.setEquals(query); + } else { + stringFilter.setContains(query); + } + criteria.setHugoSymbol(stringFilter); + final Specification specification = createSpecification(criteria); + return geneRepository.findAll(specification, page); + } + + /** + * Return a {@link List} of {@link Gene} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public List findByCriteria(GeneCriteria criteria) { + log.debug("find by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return geneRepository.findAll(specification); + } + + /** + * Return a {@link Page} of {@link Gene} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @param page The page, which should be returned. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public Page findByCriteria(GeneCriteria criteria, Pageable page) { + log.debug("find by criteria : {}, page: {}", criteria, page); + final Specification specification = createSpecification(criteria); + return geneRepository.findAll(specification, page); + } + + /** + * Return the number of matching entities in the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the number of matching entities. + */ + @Transactional(readOnly = true) + public long countByCriteria(GeneCriteria criteria) { + log.debug("count by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return geneRepository.count(specification); + } + + /** + * Function to convert {@link GeneCriteria} to a {@link Specification} + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching {@link Specification} of the entity. + */ + protected Specification createSpecification(GeneCriteria criteria) { + Specification specification = Specification.where(null); + if (criteria != null) { + // This has to be called first, because the distinct method returns null + if (criteria.getDistinct() != null) { + specification = specification.or(distinct(criteria.getDistinct())); + } + if (criteria.getId() != null) { + specification = specification.or(buildRangeSpecification(criteria.getId(), Gene_.id)); + } + if (criteria.getEntrezGeneId() != null) { + specification = specification.or(buildRangeSpecification(criteria.getEntrezGeneId(), Gene_.entrezGeneId)); + } + if (criteria.getHugoSymbol() != null) { + specification = specification.or(buildStringSpecification(criteria.getHugoSymbol(), Gene_.hugoSymbol)); + } + if (criteria.getHgncId() != null) { + specification = specification.or(buildStringSpecification(criteria.getHgncId(), Gene_.hgncId)); + } + if (criteria.getEnsemblGeneId() != null) { + specification = specification.or( + buildSpecification( + criteria.getEnsemblGeneId(), + root -> root.join(Gene_.ensemblGenes, JoinType.LEFT).get(EnsemblGene_.id) + ) + ); + } + if (criteria.getEvidenceId() != null) { + specification = specification.or( + buildSpecification(criteria.getEvidenceId(), root -> root.join(Gene_.evidences, JoinType.LEFT).get(Evidence_.id)) + ); + } + if (criteria.getTranscriptId() != null) { + specification = specification.or( + buildSpecification(criteria.getTranscriptId(), root -> root.join(Gene_.transcripts, JoinType.LEFT).get(Transcript_.id)) + ); + } + if (criteria.getFlagId() != null) { + specification = specification.or( + buildSpecification(criteria.getFlagId(), root -> root.join(Gene_.flags, JoinType.LEFT).get(Flag_.id)) + ); + } + if (criteria.getSynonymId() != null) { + specification = specification.or( + buildSpecification(criteria.getSynonymId(), root -> root.join(Gene_.synonyms, JoinType.LEFT).get(Synonym_.id)) + ); + } + if (criteria.getAlterationId() != null) { + specification = specification.or( + buildSpecification(criteria.getAlterationId(), root -> root.join(Gene_.alterations, JoinType.LEFT).get(Alteration_.id)) + ); + } + } + return specification; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/GeneService.java b/src/main/java/org/mskcc/oncokb/curation/service/GeneService.java new file mode 100644 index 000000000..846d6d955 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/GeneService.java @@ -0,0 +1,214 @@ +package org.mskcc.oncokb.curation.service; + +import static org.mskcc.oncokb.curation.config.Constants.DEFAULT_GENE_SYNONMN_SOURCE; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; +import org.mskcc.oncokb.curation.config.cache.CacheCategory; +import org.mskcc.oncokb.curation.config.cache.CacheNameResolver; +import org.mskcc.oncokb.curation.domain.Gene; +import org.mskcc.oncokb.curation.domain.Synonym; +import org.mskcc.oncokb.curation.repository.GeneRepository; +import org.mskcc.oncokb.curation.repository.SynonymRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cache.CacheManager; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * Service Implementation for managing {@link Gene}. + */ +@Service +@Transactional +public class GeneService { + + private final Logger log = LoggerFactory.getLogger(GeneService.class); + + private final GeneRepository geneRepository; + private final SynonymRepository synonymRepository; + private final InfoService infoService; + private final CacheNameResolver cacheNameResolver; + private final Optional optionalCacheManager; + + public GeneService( + GeneRepository geneRepository, + SynonymRepository synonymRepository, + InfoService infoService, + CacheNameResolver cacheNameResolver, + Optional optionalCacheManager + ) { + this.geneRepository = geneRepository; + this.synonymRepository = synonymRepository; + this.infoService = infoService; + this.cacheNameResolver = cacheNameResolver; + this.optionalCacheManager = optionalCacheManager; + } + + /** + * Save a gene. + * + * @param gene the entity to save. + * @return the persisted entity. + */ + public Gene save(Gene gene) { + log.debug("Request to save Gene : {}", gene); + return geneRepository.save(gene); + } + + /** + * Partially update a gene. + * + * @param gene the entity to update partially. + * @return the persisted entity. + */ + public Optional partialUpdate(Gene gene) { + log.debug("Request to partially update Gene : {}", gene); + + return geneRepository + .findOneWithEagerRelationships(gene.getId()) + .map(existingGene -> { + if (gene.getEntrezGeneId() != null) { + existingGene.setEntrezGeneId(gene.getEntrezGeneId()); + } + if (gene.getHugoSymbol() != null) { + existingGene.setHugoSymbol(gene.getHugoSymbol()); + } + if (gene.getHgncId() != null) { + existingGene.setHgncId(gene.getHgncId()); + } + if (gene.getFlags() != null) { + existingGene.getFlags().clear(); + existingGene.getFlags().addAll(gene.getFlags()); + } + if (gene.getSynonyms() != null) { + existingGene.getSynonyms().clear(); + existingGene.getSynonyms().addAll(gene.getSynonyms()); + } + + return existingGene; + }) + .map(geneRepository::save); + } + + /** + * Get all the genes. + * + * @param pageable the pagination information. + * @return the list of entities. + */ + @Transactional(readOnly = true) + public Page findAll(Pageable pageable) { + log.debug("Request to get all Genes"); + Page genePage = geneRepository.findAll(pageable); + return new PageImpl<>( + geneRepository.findAllWithEagerRelationships(genePage.getContent().stream().map(Gene::getId).collect(Collectors.toList())), + pageable, + genePage.getSize() + ); + } + + /** + * Get all the gene ids + * + * @param pageable the pagination information. + * @return the list of ids. + */ + @Transactional(readOnly = true) + public Page findAllGeneIds(Pageable pageable) { + log.debug("Request to get all Genes"); + return Page.empty(); + } + + /** + * Get all the genes by ids + * + * @param geneIds a list of gene ids for query. + * @return the list of genes. + */ + @Transactional(readOnly = true) + public List findAllByIdInWithGeneAliasAndEnsemblGenes(List geneIds) { + log.debug("Request to get all Genes"); + return geneRepository.findAllByIdInWithGeneAliasAndEnsemblGenes(geneIds); + } + + /** + * Get one gene by id. + * + * @param id the id of the entity. + * @return the entity. + */ + @Transactional(readOnly = true) + public Optional findOne(Long id) { + log.debug("Request to get Gene : {}", id); + return geneRepository.findOneWithEagerRelationships(id); + } + + /** + * Delete the gene by id. + * + * @param id the id of the entity. + */ + public void delete(Long id) { + log.debug("Request to delete Gene : {}", id); + geneRepository.deleteById(id); + } + + @Transactional(readOnly = true) + public Optional findGeneByEntrezGeneId(Integer entrezGeneId) { + return geneRepository.findByEntrezGeneId(entrezGeneId); + } + + @Transactional(readOnly = true) + public Optional findGeneByHugoSymbol(String hugoSymbol) { + return geneRepository.findByHugoSymbol(hugoSymbol.toLowerCase()); + } + + @Transactional(readOnly = true) + public List findGeneByHugoSymbolOrGeneAliasesIn(String hugoSymbol) { + return geneRepository.findGeneByHugoSymbolOrGeneAliasesIn(hugoSymbol); + } + + @Transactional(readOnly = true) + public Optional findGeneBySynonym(String synonym) { + Optional synonymOptional = synonymRepository.findByTypeAndSourceAndName("GENE", DEFAULT_GENE_SYNONMN_SOURCE, synonym); + if (synonymOptional.isPresent()) { + return Optional.of(synonymOptional.orElseThrow().getGenes().iterator().next()); + } else { + return Optional.empty(); + } + } + + private void clearGeneCaches() { + if (this.optionalCacheManager.isPresent()) { + for (String cacheKey : this.optionalCacheManager.orElseThrow().getCacheNames()) { + String cacheKeyPrefix = this.cacheNameResolver.getCacheName(CacheCategory.GENE, ""); + if (cacheKey.startsWith(cacheKeyPrefix)) { + Objects.requireNonNull(this.optionalCacheManager.orElseThrow().getCache(cacheKey)).clear(); + } + } + } + } + + @Transactional(readOnly = true) + public List findByHugoSymbolIn(Set searchValues) { + log.debug("Request to search for a list of genes by list of search values"); + return geneRepository.findByHugoSymbolInIgnoreCase(searchValues.stream().collect(Collectors.toList())); + } + + public Page blurSearchByHugoSymbol(String query, Pageable pageable) { + Page genePage = geneRepository.blurSearchByHugoSymbol(query, pageable); + Page page = new PageImpl<>( + geneRepository.findAllWithEagerRelationships(genePage.getContent().stream().map(Gene::getId).collect(Collectors.toList())), + pageable, + genePage.getTotalElements() + ); + return page; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/GenomeFragmentQueryService.java b/src/main/java/org/mskcc/oncokb/curation/service/GenomeFragmentQueryService.java new file mode 100644 index 000000000..766d07679 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/GenomeFragmentQueryService.java @@ -0,0 +1,119 @@ +package org.mskcc.oncokb.curation.service; + +import jakarta.persistence.criteria.JoinType; +import java.util.List; +import org.mskcc.oncokb.curation.domain.*; // for static metamodels +import org.mskcc.oncokb.curation.domain.GenomeFragment; +import org.mskcc.oncokb.curation.repository.GenomeFragmentRepository; +import org.mskcc.oncokb.curation.service.criteria.GenomeFragmentCriteria; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import tech.jhipster.service.QueryService; + +/** + * Service for executing complex queries for {@link GenomeFragment} entities in the database. + * The main input is a {@link GenomeFragmentCriteria} which gets converted to {@link Specification}, + * in a way that all the filters must apply. + * It returns a {@link List} of {@link GenomeFragment} or a {@link Page} of {@link GenomeFragment} which fulfills the criteria. + */ +@Service +@Transactional(readOnly = true) +public class GenomeFragmentQueryService extends QueryService { + + private final Logger log = LoggerFactory.getLogger(GenomeFragmentQueryService.class); + + private final GenomeFragmentRepository genomeFragmentRepository; + + public GenomeFragmentQueryService(GenomeFragmentRepository genomeFragmentRepository) { + this.genomeFragmentRepository = genomeFragmentRepository; + } + + /** + * Return a {@link List} of {@link GenomeFragment} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public List findByCriteria(GenomeFragmentCriteria criteria) { + log.debug("find by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return genomeFragmentRepository.findAll(specification); + } + + /** + * Return a {@link Page} of {@link GenomeFragment} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @param page The page, which should be returned. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public Page findByCriteria(GenomeFragmentCriteria criteria, Pageable page) { + log.debug("find by criteria : {}, page: {}", criteria, page); + final Specification specification = createSpecification(criteria); + return genomeFragmentRepository.findAll(specification, page); + } + + /** + * Return the number of matching entities in the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the number of matching entities. + */ + @Transactional(readOnly = true) + public long countByCriteria(GenomeFragmentCriteria criteria) { + log.debug("count by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return genomeFragmentRepository.count(specification); + } + + /** + * Function to convert {@link GenomeFragmentCriteria} to a {@link Specification} + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching {@link Specification} of the entity. + */ + protected Specification createSpecification(GenomeFragmentCriteria criteria) { + Specification specification = Specification.where(null); + if (criteria != null) { + // This has to be called first, because the distinct method returns null + if (criteria.getDistinct() != null) { + specification = specification.or(distinct(criteria.getDistinct())); + } + if (criteria.getId() != null) { + specification = specification.or(buildRangeSpecification(criteria.getId(), GenomeFragment_.id)); + } + if (criteria.getStart() != null) { + specification = specification.or(buildRangeSpecification(criteria.getStart(), GenomeFragment_.start)); + } + if (criteria.getEnd() != null) { + specification = specification.or(buildRangeSpecification(criteria.getEnd(), GenomeFragment_.end)); + } + if (criteria.getStrand() != null) { + specification = specification.or(buildRangeSpecification(criteria.getStrand(), GenomeFragment_.strand)); + } + if (criteria.getType() != null) { + specification = specification.or(buildSpecification(criteria.getType(), GenomeFragment_.type)); + } + if (criteria.getSeqRegionId() != null) { + specification = specification.or( + buildSpecification( + criteria.getSeqRegionId(), + root -> root.join(GenomeFragment_.seqRegion, JoinType.LEFT).get(SeqRegion_.id) + ) + ); + } + if (criteria.getTranscriptId() != null) { + specification = specification.or( + buildSpecification( + criteria.getTranscriptId(), + root -> root.join(GenomeFragment_.transcript, JoinType.LEFT).get(Transcript_.id) + ) + ); + } + } + return specification; + } +} diff --git a/src/main/java/org/mskcc/oncokb/transcript/service/GenomeFragmentService.java b/src/main/java/org/mskcc/oncokb/curation/service/GenomeFragmentService.java similarity index 87% rename from src/main/java/org/mskcc/oncokb/transcript/service/GenomeFragmentService.java rename to src/main/java/org/mskcc/oncokb/curation/service/GenomeFragmentService.java index 303a85c09..e46734120 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/service/GenomeFragmentService.java +++ b/src/main/java/org/mskcc/oncokb/curation/service/GenomeFragmentService.java @@ -1,12 +1,14 @@ -package org.mskcc.oncokb.transcript.service; +package org.mskcc.oncokb.curation.service; import java.util.Collection; import java.util.List; import java.util.Optional; -import org.mskcc.oncokb.transcript.domain.GenomeFragment; -import org.mskcc.oncokb.transcript.repository.GenomeFragmentRepository; +import org.mskcc.oncokb.curation.domain.GenomeFragment; +import org.mskcc.oncokb.curation.repository.GenomeFragmentRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -53,8 +55,8 @@ public Optional partialUpdate(GenomeFragment genomeFragment) { return genomeFragmentRepository .findById(genomeFragment.getId()) .map(existingGenomeFragment -> { - if (genomeFragment.getChromosome() != null) { - existingGenomeFragment.setChromosome(genomeFragment.getChromosome()); + if (genomeFragment.getSeqRegion() != null) { + existingGenomeFragment.setSeqRegion(genomeFragment.getSeqRegion()); } if (genomeFragment.getStart() != null) { existingGenomeFragment.setStart(genomeFragment.getStart()); @@ -77,12 +79,13 @@ public Optional partialUpdate(GenomeFragment genomeFragment) { /** * Get all the genomeFragments. * + * @param pageable the pagination information. * @return the list of entities. */ @Transactional(readOnly = true) - public List findAll() { + public Page findAll(Pageable pageable) { log.debug("Request to get all GenomeFragments"); - return genomeFragmentRepository.findAll(); + return genomeFragmentRepository.findAll(pageable); } /** diff --git a/src/main/java/org/mskcc/oncokb/curation/service/GenomeNexusService.java b/src/main/java/org/mskcc/oncokb/curation/service/GenomeNexusService.java new file mode 100644 index 000000000..5152e7bb0 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/GenomeNexusService.java @@ -0,0 +1,109 @@ +package org.mskcc.oncokb.curation.service; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import org.genome_nexus.ApiClient; +import org.genome_nexus.ApiException; +import org.genome_nexus.client.*; +import org.mskcc.oncokb.curation.domain.enumeration.ReferenceGenome; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +/** + * Created by Hongxin Zhang on 7/15/20. + */ +@Service +public class GenomeNexusService { + + public final String GN_37_URL = "https://www.genomenexus.org"; + public final String GN_38_URL = "https://grch38.genomenexus.org"; + private final int GN_READ_TIMEOUT_OVERRIDE = 30000; + private final String MSK_ISOFORM_OVERRIDE_SOURCE = "mskcc"; + + private final EnsemblControllerApi ensemblControllerApi38; + private final EnsemblControllerApi ensemblControllerApi37; + + private final AnnotationControllerApi annotationControllerApi38; + private final AnnotationControllerApi annotationControllerApi37; + + private final Logger log = LoggerFactory.getLogger(GenomeNexusService.class); + + public GenomeNexusService() { + this.ensemblControllerApi37 = getGNEnsemblControllerApi(GN_37_URL); + this.ensemblControllerApi38 = getGNEnsemblControllerApi(GN_38_URL); + this.annotationControllerApi37 = getAnnotationControllerApi(GN_37_URL); + this.annotationControllerApi38 = getAnnotationControllerApi(GN_38_URL); + } + + private ApiClient getDefaultApiClient(String url) { + ApiClient client = new ApiClient(); + client.setReadTimeout(GN_READ_TIMEOUT_OVERRIDE); + client.setBasePath(url); + return client; + } + + private EnsemblControllerApi getGNEnsemblControllerApi(String url) { + return new EnsemblControllerApi(getDefaultApiClient(url)); + } + + public EnsemblControllerApi getEnsemblControllerApi(ReferenceGenome referenceGenome) { + switch (referenceGenome) { + case GRCh37: + return this.ensemblControllerApi37; + case GRCh38: + return this.ensemblControllerApi38; + default: + return new EnsemblControllerApi(); + } + } + + private AnnotationControllerApi getAnnotationControllerApi(String url) { + return new AnnotationControllerApi(getDefaultApiClient(url)); + } + + public AnnotationControllerApi getAnnotationControllerApi(ReferenceGenome referenceGenome) { + switch (referenceGenome) { + case GRCh37: + return this.annotationControllerApi37; + case GRCh38: + return this.annotationControllerApi38; + default: + return new AnnotationControllerApi(); + } + } + + public VariantAnnotation annotateGenomicChange(ReferenceGenome referenceGenome, String genomicChange) throws ApiException { + return this.getAnnotationControllerApi(referenceGenome).fetchVariantAnnotationGET( + genomicChange, + MSK_ISOFORM_OVERRIDE_SOURCE, + null, + Collections.singletonList("annotation_summary") + ); + } + + public EnsemblGene findCanonicalEnsemblGeneTranscript(ReferenceGenome referenceGenome, Integer entrezGeneId) throws ApiException { + return this.getEnsemblControllerApi(referenceGenome).fetchCanonicalEnsemblGeneIdByEntrezGeneIdGET(Integer.toString(entrezGeneId)); + } + + public List findCanonicalEnsemblGeneTranscript(ReferenceGenome referenceGenome, List entrezGeneIds) + throws ApiException { + List ensemblGenesList = new ArrayList<>(); + List idStrs = entrezGeneIds.stream().map(id -> Integer.toString(id)).collect(Collectors.toList()); + int postThreshold = 1000; + for (int i = 0; i < idStrs.size(); i += postThreshold) { + ensemblGenesList.addAll( + this.getEnsemblControllerApi(referenceGenome).fetchCanonicalEnsemblGeneIdByEntrezGeneIdsPOST( + idStrs.subList(i, Math.min(idStrs.toArray().length, i + postThreshold)) + ) + ); + } + return ensemblGenesList; + } + + public EnsemblTranscript findCanonicalEnsemblTranscript(ReferenceGenome referenceGenome, String hugoSymbol) throws ApiException { + return this.getEnsemblControllerApi(referenceGenome).fetchCanonicalEnsemblTranscriptByHugoSymbolGET(hugoSymbol, null); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/GenomicIndicatorQueryService.java b/src/main/java/org/mskcc/oncokb/curation/service/GenomicIndicatorQueryService.java new file mode 100644 index 000000000..f6fa55c2b --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/GenomicIndicatorQueryService.java @@ -0,0 +1,116 @@ +package org.mskcc.oncokb.curation.service; + +import jakarta.persistence.criteria.JoinType; +import java.util.List; +import org.mskcc.oncokb.curation.domain.*; // for static metamodels +import org.mskcc.oncokb.curation.domain.GenomicIndicator; +import org.mskcc.oncokb.curation.repository.GenomicIndicatorRepository; +import org.mskcc.oncokb.curation.service.criteria.GenomicIndicatorCriteria; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import tech.jhipster.service.QueryService; + +/** + * Service for executing complex queries for {@link GenomicIndicator} entities in the database. + * The main input is a {@link GenomicIndicatorCriteria} which gets converted to {@link Specification}, + * in a way that all the filters must apply. + * It returns a {@link List} of {@link GenomicIndicator} or a {@link Page} of {@link GenomicIndicator} which fulfills the criteria. + */ +@Service +@Transactional(readOnly = true) +public class GenomicIndicatorQueryService extends QueryService { + + private final Logger log = LoggerFactory.getLogger(GenomicIndicatorQueryService.class); + + private final GenomicIndicatorRepository genomicIndicatorRepository; + + public GenomicIndicatorQueryService(GenomicIndicatorRepository genomicIndicatorRepository) { + this.genomicIndicatorRepository = genomicIndicatorRepository; + } + + /** + * Return a {@link List} of {@link GenomicIndicator} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public List findByCriteria(GenomicIndicatorCriteria criteria) { + log.debug("find by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return genomicIndicatorRepository.findAll(specification); + } + + /** + * Return a {@link Page} of {@link GenomicIndicator} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @param page The page, which should be returned. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public Page findByCriteria(GenomicIndicatorCriteria criteria, Pageable page) { + log.debug("find by criteria : {}, page: {}", criteria, page); + final Specification specification = createSpecification(criteria); + return genomicIndicatorRepository.findAll(specification, page); + } + + /** + * Return the number of matching entities in the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the number of matching entities. + */ + @Transactional(readOnly = true) + public long countByCriteria(GenomicIndicatorCriteria criteria) { + log.debug("count by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return genomicIndicatorRepository.count(specification); + } + + /** + * Function to convert {@link GenomicIndicatorCriteria} to a {@link Specification} + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching {@link Specification} of the entity. + */ + protected Specification createSpecification(GenomicIndicatorCriteria criteria) { + Specification specification = Specification.where(null); + if (criteria != null) { + // This has to be called first, because the distinct method returns null + if (criteria.getDistinct() != null) { + specification = specification.or(distinct(criteria.getDistinct())); + } + if (criteria.getId() != null) { + specification = specification.or(buildRangeSpecification(criteria.getId(), GenomicIndicator_.id)); + } + if (criteria.getUuid() != null) { + specification = specification.or(buildStringSpecification(criteria.getUuid(), GenomicIndicator_.uuid)); + } + if (criteria.getType() != null) { + specification = specification.or(buildStringSpecification(criteria.getType(), GenomicIndicator_.type)); + } + if (criteria.getName() != null) { + specification = specification.or(buildStringSpecification(criteria.getName(), GenomicIndicator_.name)); + } + if (criteria.getAlleleStateId() != null) { + specification = specification.or( + buildSpecification( + criteria.getAlleleStateId(), + root -> root.join(GenomicIndicator_.alleleStates, JoinType.LEFT).get(AlleleState_.id) + ) + ); + } + if (criteria.getAssociationId() != null) { + specification = specification.or( + buildSpecification( + criteria.getAssociationId(), + root -> root.join(GenomicIndicator_.associations, JoinType.LEFT).get(Association_.id) + ) + ); + } + } + return specification; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/GenomicIndicatorService.java b/src/main/java/org/mskcc/oncokb/curation/service/GenomicIndicatorService.java new file mode 100644 index 000000000..8ce065ce9 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/GenomicIndicatorService.java @@ -0,0 +1,139 @@ +package org.mskcc.oncokb.curation.service; + +import java.util.List; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.GenomicIndicator; +import org.mskcc.oncokb.curation.domain.enumeration.GenomicIndicatorType; +import org.mskcc.oncokb.curation.repository.GenomicIndicatorRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * Service Implementation for managing {@link GenomicIndicator}. + */ +@Service +@Transactional +public class GenomicIndicatorService { + + private final Logger log = LoggerFactory.getLogger(GenomicIndicatorService.class); + + private final GenomicIndicatorRepository genomicIndicatorRepository; + + public GenomicIndicatorService(GenomicIndicatorRepository genomicIndicatorRepository) { + this.genomicIndicatorRepository = genomicIndicatorRepository; + } + + /** + * Save a genomicIndicator. + * + * @param genomicIndicator the entity to save. + * @return the persisted entity. + */ + public GenomicIndicator save(GenomicIndicator genomicIndicator) { + log.debug("Request to save GenomicIndicator : {}", genomicIndicator); + return genomicIndicatorRepository.save(genomicIndicator); + } + + /** + * Partially update a genomicIndicator. + * + * @param genomicIndicator the entity to update partially. + * @return the persisted entity. + */ + public Optional partialUpdate(GenomicIndicator genomicIndicator) { + log.debug("Request to partially update GenomicIndicator : {}", genomicIndicator); + + return genomicIndicatorRepository + .findById(genomicIndicator.getId()) + .map(existingGenomicIndicator -> { + if (genomicIndicator.getUuid() != null) { + existingGenomicIndicator.setUuid(genomicIndicator.getUuid()); + } + if (genomicIndicator.getType() != null) { + existingGenomicIndicator.setType(genomicIndicator.getType()); + } + if (genomicIndicator.getName() != null) { + existingGenomicIndicator.setName(genomicIndicator.getName()); + } + if (genomicIndicator.getDescription() != null) { + existingGenomicIndicator.setDescription(genomicIndicator.getDescription()); + } + if (genomicIndicator.getAlleleStates() != null) { + existingGenomicIndicator.getAlleleStates().clear(); + existingGenomicIndicator.getAlleleStates().addAll(genomicIndicator.getAlleleStates()); + } + if (genomicIndicator.getAssociations() != null) { + existingGenomicIndicator.getAssociations().clear(); + existingGenomicIndicator.getAssociations().addAll(genomicIndicator.getAssociations()); + } + + return existingGenomicIndicator; + }) + .map(genomicIndicatorRepository::save); + } + + /** + * Get all the genomicIndicators. + * + * @return the list of entities. + */ + @Transactional(readOnly = true) + public List findAll() { + log.debug("Request to get all GenomicIndicators"); + return genomicIndicatorRepository.findAllWithEagerRelationships(); + } + + /** + * Get one genomicIndicator by id. + * + * @param id the id of the entity. + * @return the entity. + */ + @Transactional(readOnly = true) + public Optional findOne(Long id) { + log.debug("Request to get GenomicIndicator : {}", id); + return genomicIndicatorRepository.findOneWithEagerRelationships(id); + } + + /** + * Get a list of genomicIndicators by ids + * + * @param ids the list of id for the entities + * @return list of entity + */ + @Transactional(readOnly = true) + public List findByIdIn(List ids) { + log.debug("Request to get GenomicIndicators : {}", ids); + return genomicIndicatorRepository.findByIdInWithEagerRelationships(ids); + } + + /** + * Get one genomicIndicator by type and name + * + * @param type genomic indicator type, GERMLINE + * @param name the name of the entity + * @return the entity + */ + public Optional findByTypeAndName(GenomicIndicatorType type, String name) { + if (type == null) { + return Optional.empty(); + } + Optional genomicIndicatorOptional = genomicIndicatorRepository.findByTypeAndName(type.name(), name); + if (genomicIndicatorOptional.isPresent()) { + return genomicIndicatorRepository.findOneWithEagerRelationships(genomicIndicatorOptional.orElseThrow().getId()); + } + return Optional.empty(); + } + + /** + * Delete the genomicIndicator by id. + * + * @param id the id of the entity. + */ + public void delete(Long id) { + log.debug("Request to delete GenomicIndicator : {}", id); + genomicIndicatorRepository.deleteById(id); + } +} diff --git a/src/main/java/org/mskcc/oncokb/transcript/service/InfoService.java b/src/main/java/org/mskcc/oncokb/curation/service/InfoService.java similarity index 76% rename from src/main/java/org/mskcc/oncokb/transcript/service/InfoService.java rename to src/main/java/org/mskcc/oncokb/curation/service/InfoService.java index 3fe376229..44dab2361 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/service/InfoService.java +++ b/src/main/java/org/mskcc/oncokb/curation/service/InfoService.java @@ -1,11 +1,13 @@ -package org.mskcc.oncokb.transcript.service; +package org.mskcc.oncokb.curation.service; import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; import java.util.List; import java.util.Optional; -import org.mskcc.oncokb.transcript.domain.Info; -import org.mskcc.oncokb.transcript.domain.enumeration.InfoType; -import org.mskcc.oncokb.transcript.repository.InfoRepository; +import org.mskcc.oncokb.curation.domain.Info; +import org.mskcc.oncokb.curation.domain.enumeration.InfoType; +import org.mskcc.oncokb.curation.repository.InfoRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; @@ -55,6 +57,9 @@ public Optional partialUpdate(Info info) { if (info.getValue() != null) { existingInfo.setValue(info.getValue()); } + if (info.getCreated() != null) { + existingInfo.setCreated(info.getCreated()); + } if (info.getLastUpdated() != null) { existingInfo.setLastUpdated(info.getLastUpdated()); } @@ -97,15 +102,19 @@ public void delete(Long id) { infoRepository.deleteById(id); } + public void updateInfo(InfoType infoType, String newValue, String lastUpdated) { + this.updateInfo(infoType, newValue, LocalDate.parse(lastUpdated).atStartOfDay(ZoneId.of("UTC")).toInstant()); + } + public void updateInfo(InfoType infoType, String newValue, Instant newLastUpdated) { - Optional infoRecord = this.infoRepository.findOneByType(infoType); + Optional infoRecord = this.infoRepository.findOneByType(infoType.name()); if (infoRecord.isPresent()) { - infoRecord.get().setValue(newValue); - infoRecord.get().setLastUpdated(newLastUpdated); - this.infoRepository.save(infoRecord.get()); + infoRecord.orElseThrow().setValue(newValue); + infoRecord.orElseThrow().setLastUpdated(newLastUpdated); + this.infoRepository.save(infoRecord.orElseThrow()); } else { Info info = new Info(); - info.setType(infoType); + info.setType(infoType.name()); info.setValue(newValue); info.setLastUpdated(newLastUpdated); this.infoRepository.save(info); diff --git a/src/main/java/org/mskcc/oncokb/curation/service/InvalidPasswordException.java b/src/main/java/org/mskcc/oncokb/curation/service/InvalidPasswordException.java new file mode 100644 index 000000000..0e0d9fd62 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/InvalidPasswordException.java @@ -0,0 +1,10 @@ +package org.mskcc.oncokb.curation.service; + +public class InvalidPasswordException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public InvalidPasswordException() { + super("Incorrect password"); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/LevelOfEvidenceService.java b/src/main/java/org/mskcc/oncokb/curation/service/LevelOfEvidenceService.java new file mode 100644 index 000000000..2020f2f48 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/LevelOfEvidenceService.java @@ -0,0 +1,103 @@ +package org.mskcc.oncokb.curation.service; + +import java.util.List; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.LevelOfEvidence; +import org.mskcc.oncokb.curation.repository.LevelOfEvidenceRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * Service Implementation for managing {@link LevelOfEvidence}. + */ +@Service +@Transactional +public class LevelOfEvidenceService { + + private final Logger log = LoggerFactory.getLogger(LevelOfEvidenceService.class); + + private final LevelOfEvidenceRepository levelOfEvidenceRepository; + + public LevelOfEvidenceService(LevelOfEvidenceRepository levelOfEvidenceRepository) { + this.levelOfEvidenceRepository = levelOfEvidenceRepository; + } + + /** + * Save a levelOfEvidence. + * + * @param levelOfEvidence the entity to save. + * @return the persisted entity. + */ + public LevelOfEvidence save(LevelOfEvidence levelOfEvidence) { + log.debug("Request to save LevelOfEvidence : {}", levelOfEvidence); + return levelOfEvidenceRepository.save(levelOfEvidence); + } + + /** + * Partially update a levelOfEvidence. + * + * @param levelOfEvidence the entity to update partially. + * @return the persisted entity. + */ + public Optional partialUpdate(LevelOfEvidence levelOfEvidence) { + log.debug("Request to partially update LevelOfEvidence : {}", levelOfEvidence); + + return levelOfEvidenceRepository + .findById(levelOfEvidence.getId()) + .map(existingLevelOfEvidence -> { + if (levelOfEvidence.getType() != null) { + existingLevelOfEvidence.setType(levelOfEvidence.getType()); + } + if (levelOfEvidence.getLevel() != null) { + existingLevelOfEvidence.setLevel(levelOfEvidence.getLevel()); + } + if (levelOfEvidence.getDescription() != null) { + existingLevelOfEvidence.setDescription(levelOfEvidence.getDescription()); + } + if (levelOfEvidence.getHtmlDescription() != null) { + existingLevelOfEvidence.setHtmlDescription(levelOfEvidence.getHtmlDescription()); + } + if (levelOfEvidence.getColor() != null) { + existingLevelOfEvidence.setColor(levelOfEvidence.getColor()); + } + + return existingLevelOfEvidence; + }) + .map(levelOfEvidenceRepository::save); + } + + /** + * Get all the levelOfEvidences. + * + * @return the list of entities. + */ + @Transactional(readOnly = true) + public List findAll() { + log.debug("Request to get all LevelOfEvidences"); + return levelOfEvidenceRepository.findAll(); + } + + /** + * Get one levelOfEvidence by id. + * + * @param id the id of the entity. + * @return the entity. + */ + @Transactional(readOnly = true) + public Optional findOne(Long id) { + log.debug("Request to get LevelOfEvidence : {}", id); + return levelOfEvidenceRepository.findById(id); + } + + /** + * Delete the levelOfEvidence by id. + * + * @param id the id of the entity. + */ + public void delete(Long id) { + log.debug("Request to delete LevelOfEvidence : {}", id); + levelOfEvidenceRepository.deleteById(id); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/MailService.java b/src/main/java/org/mskcc/oncokb/curation/service/MailService.java new file mode 100644 index 000000000..e2ccd0530 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/MailService.java @@ -0,0 +1,94 @@ +package org.mskcc.oncokb.curation.service; + +import jakarta.mail.MessagingException; +import jakarta.mail.internet.MimeMessage; +import java.nio.charset.StandardCharsets; +import java.util.Locale; +import org.mskcc.oncokb.curation.domain.User; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.MessageSource; +import org.springframework.mail.MailException; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.MimeMessageHelper; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; +import org.thymeleaf.context.Context; +import org.thymeleaf.spring6.SpringTemplateEngine; +import tech.jhipster.config.JHipsterProperties; + +/** + * Service for sending emails. + *

+ * We use the {@link Async} annotation to send emails asynchronously. + */ +@Service +public class MailService { + + private final Logger log = LoggerFactory.getLogger(MailService.class); + + private static final String USER = "user"; + + private static final String BASE_URL = "baseUrl"; + + private final JHipsterProperties jHipsterProperties; + + private final JavaMailSender javaMailSender; + + private final MessageSource messageSource; + + private final SpringTemplateEngine templateEngine; + + public MailService( + JHipsterProperties jHipsterProperties, + JavaMailSender javaMailSender, + MessageSource messageSource, + SpringTemplateEngine templateEngine + ) { + this.jHipsterProperties = jHipsterProperties; + this.javaMailSender = javaMailSender; + this.messageSource = messageSource; + this.templateEngine = templateEngine; + } + + @Async + public void sendEmail(String to, String subject, String content, boolean isMultipart, boolean isHtml) { + log.debug( + "Send email[multipart '{}' and html '{}'] to '{}' with subject '{}' and content={}", + isMultipart, + isHtml, + to, + subject, + content + ); + + // Prepare message using a Spring helper + MimeMessage mimeMessage = javaMailSender.createMimeMessage(); + try { + MimeMessageHelper message = new MimeMessageHelper(mimeMessage, isMultipart, StandardCharsets.UTF_8.name()); + message.setTo(to); + message.setFrom(jHipsterProperties.getMail().getFrom()); + message.setSubject(subject); + message.setText(content, isHtml); + javaMailSender.send(mimeMessage); + log.debug("Sent email to User '{}'", to); + } catch (MailException | MessagingException e) { + log.warn("Email could not be sent to user '{}'", to, e); + } + } + + @Async + public void sendEmailFromTemplate(User user, String templateName, String titleKey) { + if (user.getEmail() == null) { + log.debug("Email doesn't exist for user '{}'", user.getLogin()); + return; + } + Locale locale = Locale.forLanguageTag(user.getLangKey()); + Context context = new Context(locale); + context.setVariable(USER, user); + context.setVariable(BASE_URL, jHipsterProperties.getMail().getBaseUrl()); + String content = templateEngine.process(templateName, context); + String subject = messageSource.getMessage(titleKey, null, locale); + sendEmail(user.getEmail(), subject, content, false, true); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/MainService.java b/src/main/java/org/mskcc/oncokb/curation/service/MainService.java new file mode 100644 index 000000000..37c318a18 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/MainService.java @@ -0,0 +1,652 @@ +package org.mskcc.oncokb.curation.service; + +import static org.mskcc.oncokb.curation.domain.enumeration.AlterationType.*; + +import jakarta.validation.constraints.NotNull; +import java.util.*; +import java.util.stream.Collectors; +import org.apache.commons.lang3.StringUtils; +import org.genome_nexus.ApiException; +import org.genome_nexus.client.TranscriptConsequenceSummary; +import org.genome_nexus.client.VariantAnnotation; +import org.genome_nexus.client.VariantAnnotationSummary; +import org.mskcc.oncokb.curation.domain.*; +import org.mskcc.oncokb.curation.domain.dto.AnnotationDTO; +import org.mskcc.oncokb.curation.domain.dto.HotspotDTO; +import org.mskcc.oncokb.curation.domain.dto.HotspotInfoDTO; +import org.mskcc.oncokb.curation.domain.dto.ProteinExonDTO; +import org.mskcc.oncokb.curation.domain.enumeration.*; +import org.mskcc.oncokb.curation.model.IntegerRange; +import org.mskcc.oncokb.curation.service.dto.TranscriptDTO; +import org.mskcc.oncokb.curation.service.mapper.TranscriptMapper; +import org.mskcc.oncokb.curation.util.AlterationUtils; +import org.mskcc.oncokb.curation.vm.ensembl.EnsemblTranscript; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +public class MainService { + + private final Logger log = LoggerFactory.getLogger(MainService.class); + + private final TranscriptService transcriptService; + private final FlagService flagService; + private final EnsemblService ensemblService; + private final EnsemblGeneService ensemblGeneService; + private final GeneService geneService; + private final GenomeNexusService genomeNexusService; + private final SequenceService sequenceService; + private final TranscriptMapper transcriptMapper; + private final AlterationUtils alterationUtils; + private final ConsequenceService consequenceService; + private final SeqRegionService seqRegionService; + private final AnnotationService annotationService; + + private final CategoricalAlterationService categoricalAlterationService; + + public MainService( + TranscriptService transcriptService, + FlagService flagService, + EnsemblService ensemblService, + EnsemblGeneService ensemblGeneService, + GeneService geneService, + GenomeNexusService genomeNexusService, + SequenceService sequenceService, + TranscriptMapper transcriptMapper, + AlterationUtils alterationUtils, + ConsequenceService consequenceService, + SeqRegionService seqRegionService, + AnnotationService annotationService, + CategoricalAlterationService categoricalAlterationService + ) { + this.transcriptService = transcriptService; + this.flagService = flagService; + this.ensemblService = ensemblService; + this.ensemblGeneService = ensemblGeneService; + this.geneService = geneService; + this.genomeNexusService = genomeNexusService; + this.sequenceService = sequenceService; + this.transcriptMapper = transcriptMapper; + this.alterationUtils = alterationUtils; + this.consequenceService = consequenceService; + this.seqRegionService = seqRegionService; + this.annotationService = annotationService; + this.categoricalAlterationService = categoricalAlterationService; + } + + public Optional findSequenceByGene(ReferenceGenome referenceGenome, Integer entrezGeneId, SequenceType sequenceType) { + Optional ensemblGeneOptional = ensemblGeneService.findCanonicalEnsemblGene(entrezGeneId, referenceGenome); + if (ensemblGeneOptional.isPresent()) { + Optional transcriptDTOOptional = transcriptService.findByEnsemblGeneAndCanonicalIsTrue( + ensemblGeneOptional.orElseThrow() + ); + if (transcriptDTOOptional.isPresent()) { + Optional sequenceOptional = sequenceService.findOneByTranscriptAndSequenceType( + transcriptMapper.toEntity(transcriptDTOOptional.orElseThrow()), + sequenceType + ); + if (sequenceOptional.isPresent()) { + return sequenceOptional; + } + } + } + return Optional.empty(); + } + + public AlterationAnnotationStatus annotateAlteration(ReferenceGenome referenceGenome, Alteration alteration) { + AlterationAnnotationStatus alterationWithStatus = new AlterationAnnotationStatus(); + alterationWithStatus.setEntity(alteration); + + Optional categoricalAlterationOptional = categoricalAlterationService.findOneByAlteration(alteration); + if (categoricalAlterationOptional.isPresent()) { + CategoricalAlteration categoricalAlteration = categoricalAlterationOptional.orElseThrow(); + alteration.setAlteration(categoricalAlteration.getName()); + alteration.setName(categoricalAlteration.getName()); + alteration.setType(categoricalAlteration.getAlterationType()); + alteration.setConsequence(categoricalAlteration.getConsequence()); + + alterationWithStatus.setType(EntityStatusType.OK); + alterationWithStatus.setMessage(""); + return alterationWithStatus; + } + + EntityStatus alterationWithEntityStatus = alterationUtils.parseAlteration(alteration.getAlteration()); + if (alterationWithEntityStatus == null) { + alterationWithStatus.setMessage("No alteration provided"); + alterationWithStatus.setType(EntityStatusType.ERROR); + return alterationWithStatus; + } + + // get protein change for genomic change variant + if (GENOMIC_CHANGE.equals(alterationWithEntityStatus.getEntity().getType())) { + try { + VariantAnnotation variantAnnotation = genomeNexusService.annotateGenomicChange( + referenceGenome, + alterationWithEntityStatus.getEntity().getAlteration() + ); + + String hgvsg = variantAnnotation.getHgvsg(); + if (StringUtils.isEmpty(hgvsg)) { + throw new ApiException(variantAnnotation.getErrorMessage()); + } + alterationWithEntityStatus.getEntity().setAlteration(hgvsg); + } catch (ApiException e) { + String message = "Failed to be annotated by GenomeNexus"; + if (!e.getMessage().isEmpty()) { + message += ": " + e.getMessage(); + } + alterationWithStatus.setMessage(message); + + alterationWithStatus.setEntity(alterationWithEntityStatus.getEntity()); + alterationWithStatus.setType(EntityStatusType.WARNING); + return alterationWithStatus; + } + } + + // update alteration type + Alteration parsedAlteration = alterationWithEntityStatus.getEntity(); + if (parsedAlteration.getType() != null) { + alteration.setType(parsedAlteration.getType()); + } + + // update associated genes + Set genes = alteration.getGenes(); + if (STRUCTURAL_VARIANT.equals(parsedAlteration.getType()) && !parsedAlteration.getGenes().isEmpty()) { + genes = parsedAlteration.getGenes(); + } + Set annotatedGenes = genes + .stream() + .map(gene -> { + Optional geneOptional = Optional.empty(); + if (gene.getId() != null) { + geneOptional = geneService.findOne(gene.getId()); + } else if (gene.getEntrezGeneId() != null) { + geneOptional = geneService.findGeneByEntrezGeneId(gene.getEntrezGeneId()); + } else if (gene.getHugoSymbol() != null) { + geneOptional = geneService.findGeneByHugoSymbol(gene.getHugoSymbol()); + if (geneOptional.isEmpty()) { + geneOptional = geneService.findGeneBySynonym(gene.getHugoSymbol()); + } + } + if (geneOptional.isEmpty()) { + geneOptional = Optional.empty(); + log.error("No match found for gene {}", gene); + } + return geneOptional; + }) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(Collectors.toSet()); + alteration.setGenes(annotatedGenes); + alteration.setAlteration(parsedAlteration.getAlteration()); + alteration.setName(parsedAlteration.getName()); + + if (!alteration.getGenes().isEmpty() && alteration.getGenes().stream().anyMatch(gene -> gene.getEntrezGeneId() < 0)) { + alteration.setType(NA); + } + + if (alteration.getConsequence() == null) { + if (parsedAlteration.getConsequence() != null) { + Optional consequenceOptional = consequenceService.findByTerm(parsedAlteration.getConsequence().getTerm()); + if (consequenceOptional.isEmpty()) { + consequenceOptional = consequenceService.findByTerm("UNKNOWN"); + } + if (consequenceOptional.isPresent()) { + alteration.setConsequence(consequenceOptional.orElseThrow()); + } + } + } + + if (StringUtils.isEmpty(alteration.getProteinChange())) { + alteration.setProteinChange(parsedAlteration.getProteinChange()); + } + if (alteration.getStart() == null) { + alteration.setStart(parsedAlteration.getStart()); + } + if (alteration.getEnd() == null) { + alteration.setEnd(parsedAlteration.getEnd()); + } + if (alteration.getRefResidues() == null) { + alteration.setRefResidues(parsedAlteration.getRefResidues()); + } + if (alteration.getVariantResidues() == null) { + alteration.setVariantResidues(parsedAlteration.getVariantResidues()); + } + if (alteration.getName() == null) { + alteration.setName(alteration.getAlteration()); + } + + alterationWithStatus.setMessage(alterationWithEntityStatus.getMessage()); + alterationWithStatus.setType(alterationWithEntityStatus.getType()); + + // update reference genome + if (alteration.getGenes().size() > 0 && PROTEIN_CHANGE.equals(alteration.getType())) { + Gene gene = alteration.getGenes().iterator().next(); + if (alteration.getStart() != null) { + Optional canonicalSequenceOptional = findSequenceByGene( + referenceGenome, + gene.getEntrezGeneId(), + SequenceType.PROTEIN + ); + + if ( + canonicalSequenceOptional.isPresent() && + alteration.getStart() < canonicalSequenceOptional.orElseThrow().getSequence().length() + ) { + String refRe = String.valueOf(canonicalSequenceOptional.orElseThrow().getSequence().charAt(alteration.getStart() - 1)); + if (!StringUtils.isEmpty(refRe)) { + // only set the reference AA when the alteration happens on one position + if (StringUtils.isEmpty(alteration.getRefResidues()) && alteration.getStart().equals(alteration.getEnd())) { + alteration.setRefResidues(refRe); + } else { + // If The AA in alteration is differed from the canonical transcript, and it's not X, we give warning + // X indicates "any AA" + if (!refRe.equals(alteration.getRefResidues()) && !"X".equals(alteration.getRefResidues())) { + alterationWithStatus.setMessage( + "The reference allele does not match with the transcript. It's supposed to be " + refRe + ); + alterationWithStatus.setType(EntityStatusType.WARNING); + } + } + } + } + } + } + + // Provide annotation for the alteration + // 1. check whether alteration is hotspot + AnnotationDTO annotationDTO = new AnnotationDTO(); + Set relevantAlts = annotationService.findRelevantAlterations(alteration); + List hotspotFlags = Arrays.asList(HotspotFlagEnum.HOTSPOT_V1.name(), HotspotFlagEnum.THREE_D.name()); + List hotspots = relevantAlts + .stream() + .filter(alt -> !Collections.disjoint(hotspotFlags, alt.getFlags().stream().map(Flag::getFlag).collect(Collectors.toList()))) + .collect(Collectors.toList()); + HotspotInfoDTO hotspotInfoDTO = new HotspotInfoDTO(); + if (!hotspots.isEmpty()) { + hotspotInfoDTO.setHotspot(true); + List associatedHotspots = new ArrayList<>(); + hotspots.forEach(hotspot -> { + hotspot + .getFlags() + .forEach(flag -> { + if (hotspotFlags.contains(flag.getFlag())) { + HotspotDTO hotspotDTO = new HotspotDTO(); + hotspotDTO.setType(flag.getFlag()); + hotspotDTO.setAlteration(hotspot.getName()); + associatedHotspots.add(hotspotDTO); + } + }); + }); + hotspotInfoDTO.setAssociatedHotspots(associatedHotspots); + } + annotationDTO.setHotspot(hotspotInfoDTO); + + if ( + annotatedGenes.size() == 1 && + PROTEIN_CHANGE.equals(alteration.getType()) && + alteration.getStart() != null && + alteration.getEnd() != null + ) { + Optional transcriptOptional = transcriptService.findByGeneAndReferenceGenomeAndCanonicalIsTrue( + annotatedGenes.stream().iterator().next(), + referenceGenome + ); + if (transcriptOptional.isPresent()) { + List utrs = transcriptOptional.orElseThrow().getUtrs(); + List exons = transcriptOptional.orElseThrow().getExons(); + exons.sort((o1, o2) -> { + int diff = o1.getStart() - o2.getStart(); + if (diff == 0) { + diff = o1.getEnd() - o2.getEnd(); + } + if (diff == 0) { + diff = (int) (o1.getId() - o2.getId()); + } + return diff; + }); + + List codingExons = new ArrayList<>(); + exons.forEach(exon -> { + Integer start = exon.getStart(); + Integer end = exon.getEnd(); + for (GenomeFragment utr : utrs) { + if (utr.getStart().equals(exon.getStart())) { + start = utr.getEnd() + 1; + } + if (utr.getEnd().equals(exon.getEnd())) { + end = utr.getStart() - 1; + } + } + if (start < end) { + GenomeFragment genomeFragment = new GenomeFragment(); + genomeFragment.setType(GenomeFragmentType.EXON); + genomeFragment.setStart(start); + genomeFragment.setEnd(end); + codingExons.add(genomeFragment); + } else { + GenomeFragment genomeFragment = new GenomeFragment(); + genomeFragment.setType(GenomeFragmentType.EXON); + genomeFragment.setStart(0); + genomeFragment.setEnd(0); + codingExons.add(genomeFragment); + } + }); + + if (transcriptOptional.orElseThrow().getStrand() == -1) { + Collections.reverse(codingExons); + } + + List proteinExons = new ArrayList<>(); + int startAA = 1; + int previousExonCodonResidues = 0; + for (int i = 0; i < codingExons.size(); i++) { + GenomeFragment genomeFragment = codingExons.get(i); + if (genomeFragment.getStart() == 0) { + continue; + } + int proteinLength = (previousExonCodonResidues + (genomeFragment.getEnd() - genomeFragment.getStart() + 1)) / 3; + previousExonCodonResidues = (previousExonCodonResidues + (genomeFragment.getEnd() - genomeFragment.getStart() + 1)) % 3; + ProteinExonDTO proteinExonDTO = new ProteinExonDTO(); + proteinExonDTO.setExon(i + 1); + IntegerRange integerRange = new IntegerRange(); + integerRange.setStart(startAA); + integerRange.setEnd(startAA + proteinLength - 1 + (previousExonCodonResidues > 0 ? 1 : 0)); + proteinExonDTO.setRange(integerRange); + proteinExons.add(proteinExonDTO); + startAA += proteinLength; + } + List overlap = proteinExons + .stream() + .filter(exon -> alteration.getStart() <= exon.getRange().getEnd() && alteration.getEnd() >= exon.getRange().getStart()) + .collect(Collectors.toList()); + annotationDTO.setExons(overlap); + } + } + alterationWithStatus.setAnnotation(annotationDTO); + return alterationWithStatus; + } + + public void createCanonicalEnsemblGene(@NotNull ReferenceGenome referenceGenome, @NotNull Integer entrezGeneId) { + Optional savedCanonicalEnsemblGeneOptional = ensemblGeneService.findCanonicalEnsemblGene( + entrezGeneId, + referenceGenome + ); + if (savedCanonicalEnsemblGeneOptional.isEmpty()) { + List ensemblGeneFromGN = new ArrayList<>(); + try { + ensemblGeneFromGN = genomeNexusService.findCanonicalEnsemblGeneTranscript( + referenceGenome, + Collections.singletonList(entrezGeneId) + ); + if (!ensemblGeneFromGN.isEmpty()) { + org.genome_nexus.client.EnsemblGene ensemblGene = ensemblGeneFromGN.get(0); + if (StringUtils.isNotEmpty(ensemblGene.getGeneId())) { + Optional ensemblGeneOptional = createEnsemblGene( + referenceGenome, + ensemblGene.getGeneId(), + entrezGeneId, + true + ); + if (ensemblGeneOptional.isEmpty()) { + log.error("Failed to save the ensembl {} {} {}", referenceGenome, ensemblGene.getGeneId(), entrezGeneId); + } + } else { + log.warn("No ensembl gene id available {} {} {}", referenceGenome, entrezGeneId, ensemblGene); + } + } else { + log.error("No canonical ensembl gene for {} {}", referenceGenome, entrezGeneId); + } + } catch (ApiException e) { + log.error("Failed to fetch the canonical transcript from GN {} {}", referenceGenome, entrezGeneId); + log.error(e.getMessage()); + } + } + } + + public Optional createEnsemblGene( + @NotNull ReferenceGenome referenceGenome, + @NotNull String ensemblGeneId, + @NotNull Integer entrezGeneId, + Boolean isCanonical + ) { + Optional savedEnsemblGeneOptional = ensemblGeneService.findByEnsemblGeneIdAndReferenceGenome( + ensemblGeneId, + referenceGenome + ); + if (savedEnsemblGeneOptional.isEmpty()) { + Optional ensemblGeneOptional = ensemblService.getId( + referenceGenome, + ensemblGeneId, + true, + true + ); + Optional geneOptional = geneService.findGeneByEntrezGeneId(entrezGeneId); + if (ensemblGeneOptional.isPresent() && geneOptional.isPresent()) { + org.mskcc.oncokb.curation.vm.ensembl.EnsemblTranscript remoteEnsemblGene = ensemblGeneOptional.orElseThrow(); + Optional seqRegionOptional = seqRegionService.findByNameOrCreate(remoteEnsemblGene.getSeqRegionName()); + EnsemblGene ensemblGene = new EnsemblGene(); + ensemblGene.setReferenceGenome(referenceGenome); + ensemblGene.setEnsemblGeneId(remoteEnsemblGene.getId()); + if (seqRegionOptional.isPresent()) { + ensemblGene.setSeqRegion(seqRegionOptional.orElseThrow()); + } + ensemblGene.setStart(remoteEnsemblGene.getStart()); + ensemblGene.setEnd(remoteEnsemblGene.getEnd()); + ensemblGene.setStrand(remoteEnsemblGene.getStrand()); + ensemblGene.setGene(geneOptional.orElseThrow()); + if (isCanonical != null) { + ensemblGene.setCanonical(isCanonical); + } + savedEnsemblGeneOptional = Optional.of(ensemblGeneService.save(ensemblGene)); + + // when creating canonical ensembl gene, we should add the canonical transcript from Ensembl + if (isCanonical != null && isCanonical && StringUtils.isNotEmpty(remoteEnsemblGene.getCanonicalTranscript())) { + createTranscript( + referenceGenome, + remoteEnsemblGene.getCanonicalTranscript(), + geneOptional.orElseThrow().getEntrezGeneId(), + null, + null, + false, + Collections.singletonList(TranscriptFlagEnum.ENSEMBL_CANONICAL) + ); + } + } + } else if (isCanonical != null && savedEnsemblGeneOptional.orElseThrow().getCanonical() != isCanonical) { + savedEnsemblGeneOptional.orElseThrow().setCanonical(isCanonical); + savedEnsemblGeneOptional = ensemblGeneService.partialUpdate(savedEnsemblGeneOptional.orElseThrow()); + } + return savedEnsemblGeneOptional; + } + + /** + * Create/Update transcript using the info. The method will include genome fragments if the ensemblTranscript is specified + * + * @param referenceGenome + * @param ensemblTranscriptId + * @return an optional with the saved transcript + */ + public Optional createTranscript( + @NotNull ReferenceGenome referenceGenome, + @NotNull String ensemblTranscriptId, + @NotNull Integer entrezGeneId, + String ensemblProteinId, + String refSeqId, + Boolean isCanonical, + @NotNull List transcriptFlags + ) { + Optional ensemblTranscriptOptional = ensemblService.getTranscript(referenceGenome, ensemblTranscriptId); + if (ensemblTranscriptOptional.isPresent()) { + Optional savedEnsemblGeneOptional = createEnsemblGene( + referenceGenome, + ensemblTranscriptOptional.orElseThrow().getParent(), + entrezGeneId, + null + ); + if (savedEnsemblGeneOptional.isPresent()) { + return createTranscript( + savedEnsemblGeneOptional.orElseThrow(), + ensemblTranscriptOptional.orElseThrow(), + ensemblProteinId, + refSeqId, + isCanonical, + transcriptFlags + ); + } else { + log.error( + "Failed to create ensembl gene {} {} {} {}", + referenceGenome, + ensemblTranscriptOptional.orElseThrow().getParent(), + entrezGeneId, + isCanonical + ); + } + } else { + log.error("Failed to find ensembl transcript through Ensembl {} {} {}", referenceGenome, entrezGeneId, ensemblTranscriptId); + } + return Optional.empty(); + } + + private Optional createTranscript( + @NotNull EnsemblGene ensemblGene, + @NotNull EnsemblTranscript ensemblTranscript, + String ensemblProteinId, + String refSeqId, + Boolean isCanonical, + @NotNull List transcriptFlags + ) { + String transcriptId = ensemblTranscript.getId(); + if (ensemblTranscript.getVersion() != null) { + transcriptId += "." + ensemblTranscript.getVersion().toString(); + } + if (ensemblProteinId == null && ensemblTranscript.getTranscription() != null) { + Optional proteinTranscriptOptional = ensemblService.getId( + ensemblGene.getReferenceGenome(), + ensemblTranscript.getTranscription().getId(), + false, + false + ); + if (proteinTranscriptOptional.isPresent()) { + ensemblProteinId = proteinTranscriptOptional.orElseThrow().getId() + + "." + + proteinTranscriptOptional.orElseThrow().getVersion(); + } else { + log.error( + "Failed to find ensembl protein through Ensembl {} {}", + ensemblGene.getReferenceGenome(), + ensemblTranscript.getTranscription().getId() + ); + } + } + if (isCanonical != null && isCanonical) { + Optional canonicalTranscriptOptional = transcriptService.findByEnsemblGeneAndCanonicalIsTrue(ensemblGene); + if ( + canonicalTranscriptOptional.isPresent() && + !canonicalTranscriptOptional.orElseThrow().getEnsemblTranscriptId().equals(transcriptId) + ) { + canonicalTranscriptOptional.orElseThrow().setCanonical(false); + transcriptService.partialUpdate(canonicalTranscriptOptional.orElseThrow()); + } + } + + Optional transcriptDTOOptional = transcriptService.findByEnsemblGeneAndEnsemblTranscriptId( + ensemblGene, + transcriptId + ); + List flagList = flagService.findAllByFlagIn(transcriptFlags.stream().map(flag -> flag.name()).collect(Collectors.toList())); + if (transcriptDTOOptional.isPresent()) { + if (isCanonical != null && transcriptDTOOptional.orElseThrow().getCanonical() != isCanonical) { + transcriptDTOOptional.orElseThrow().setCanonical(isCanonical); + } + transcriptDTOOptional.orElseThrow().getFlags().addAll(flagList); + transcriptDTOOptional = transcriptService.partialUpdate(transcriptDTOOptional.orElseThrow()); + return transcriptDTOOptional; + } + + TranscriptDTO transcriptDTO = new TranscriptDTO(); + transcriptDTO.setGene(ensemblGene.getGene()); + transcriptDTO.setReferenceGenome(ensemblGene.getReferenceGenome()); + transcriptDTO.setEnsemblGene(ensemblGene); + transcriptDTO.setEnsemblTranscriptId(transcriptId); + transcriptDTO.setEnsemblProteinId(ensemblProteinId); + transcriptDTO.setReferenceSequenceId(refSeqId); + transcriptDTO.setCanonical(isCanonical == null ? false : isCanonical); + transcriptDTO.setFlags(flagList); + updateGenomeFragments(transcriptDTO, ensemblTranscript); + + Optional savedTranscriptDTO = Optional.of(transcriptService.save(transcriptDTO)); + return savedTranscriptDTO; + } + + private void updateGenomeFragments( + TranscriptDTO transcriptDTO, + org.mskcc.oncokb.curation.vm.ensembl.EnsemblTranscript ensemblTranscript + ) { + // save gene fragment + transcriptDTO.setChromosome(ensemblTranscript.getSeqRegionName()); + transcriptDTO.setStart(ensemblTranscript.getStart()); + transcriptDTO.setEnd(ensemblTranscript.getEnd()); + transcriptDTO.setStrand(ensemblTranscript.getStrand()); + + // save UTRs + transcriptDTO.setUtrs( + ensemblTranscript + .getUtrs() + .stream() + .map(utr -> { + GenomeFragment utrFragment = new GenomeFragment(); + GenomeFragmentType genomeFragmentType = null; + + Optional seqRegionOptional = seqRegionService.findByNameOrCreate(utr.getSeqRegionName()); + + switch (utr.getType()) { + case "five_prime_UTR": + genomeFragmentType = GenomeFragmentType.FIVE_PRIME_UTR; + break; + case "three_prime_UTR": + genomeFragmentType = GenomeFragmentType.THREE_PRIME_UTR; + break; + default: + break; + } + if (genomeFragmentType != null) { + utrFragment.setType(genomeFragmentType); + utrFragment.setStrand(utr.getStrand()); + utrFragment.setStart(utr.getStart()); + utrFragment.setEnd(utr.getEnd()); + if (seqRegionOptional.isPresent()) { + utrFragment.setSeqRegion(seqRegionOptional.orElseThrow()); + } + } + return utrFragment; + }) + .collect(Collectors.toList()) + ); + + // save exons + transcriptDTO.setExons( + ensemblTranscript + .getExons() + .stream() + .map(utr -> { + GenomeFragment exonFragment = new GenomeFragment(); + exonFragment.setType(GenomeFragmentType.EXON); + exonFragment.setStrand(utr.getStrand()); + exonFragment.setStart(utr.getStart()); + exonFragment.setEnd(utr.getEnd()); + + Optional seqRegionOptional = seqRegionService.findByNameOrCreate(utr.getSeqRegionName()); + + if (seqRegionOptional.isPresent()) { + exonFragment.setSeqRegion(seqRegionOptional.orElseThrow()); + } + return exonFragment; + }) + .collect(Collectors.toList()) + ); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/NciThesaurusQueryService.java b/src/main/java/org/mskcc/oncokb/curation/service/NciThesaurusQueryService.java new file mode 100644 index 000000000..7b900ae01 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/NciThesaurusQueryService.java @@ -0,0 +1,108 @@ +package org.mskcc.oncokb.curation.service; + +import jakarta.persistence.criteria.JoinType; +import java.util.List; +import org.mskcc.oncokb.curation.domain.*; // for static metamodels +import org.mskcc.oncokb.curation.domain.NciThesaurus; +import org.mskcc.oncokb.curation.repository.NciThesaurusRepository; +import org.mskcc.oncokb.curation.service.criteria.NciThesaurusCriteria; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import tech.jhipster.service.QueryService; + +/** + * Service for executing complex queries for {@link NciThesaurus} entities in the database. + * The main input is a {@link NciThesaurusCriteria} which gets converted to {@link Specification}, + * in a way that all the filters must apply. + * It returns a {@link List} of {@link NciThesaurus} or a {@link Page} of {@link NciThesaurus} which fulfills the criteria. + */ +@Service +@Transactional(readOnly = true) +public class NciThesaurusQueryService extends QueryService { + + private final Logger log = LoggerFactory.getLogger(NciThesaurusQueryService.class); + + private final NciThesaurusRepository nciThesaurusRepository; + + public NciThesaurusQueryService(NciThesaurusRepository nciThesaurusRepository) { + this.nciThesaurusRepository = nciThesaurusRepository; + } + + /** + * Return a {@link List} of {@link NciThesaurus} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public List findByCriteria(NciThesaurusCriteria criteria) { + log.debug("find by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return nciThesaurusRepository.findAll(specification); + } + + /** + * Return a {@link Page} of {@link NciThesaurus} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @param page The page, which should be returned. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public Page findByCriteria(NciThesaurusCriteria criteria, Pageable page) { + log.debug("find by criteria : {}, page: {}", criteria, page); + final Specification specification = createSpecification(criteria); + return nciThesaurusRepository.findAll(specification, page); + } + + /** + * Return the number of matching entities in the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the number of matching entities. + */ + @Transactional(readOnly = true) + public long countByCriteria(NciThesaurusCriteria criteria) { + log.debug("count by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return nciThesaurusRepository.count(specification); + } + + /** + * Function to convert {@link NciThesaurusCriteria} to a {@link Specification} + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching {@link Specification} of the entity. + */ + protected Specification createSpecification(NciThesaurusCriteria criteria) { + Specification specification = Specification.where(null); + if (criteria != null) { + // This has to be called first, because the distinct method returns null + if (criteria.getDistinct() != null) { + specification = specification.or(distinct(criteria.getDistinct())); + } + if (criteria.getId() != null) { + specification = specification.or(buildRangeSpecification(criteria.getId(), NciThesaurus_.id)); + } + if (criteria.getVersion() != null) { + specification = specification.or(buildStringSpecification(criteria.getVersion(), NciThesaurus_.version)); + } + if (criteria.getCode() != null) { + specification = specification.or(buildStringSpecification(criteria.getCode(), NciThesaurus_.code)); + } + if (criteria.getPreferredName() != null) { + specification = specification.or(buildStringSpecification(criteria.getPreferredName(), NciThesaurus_.preferredName)); + } + if (criteria.getDisplayName() != null) { + specification = specification.or(buildStringSpecification(criteria.getDisplayName(), NciThesaurus_.displayName)); + } + if (criteria.getSynonymId() != null) { + specification = specification.or( + buildSpecification(criteria.getSynonymId(), root -> root.join(NciThesaurus_.synonyms, JoinType.LEFT).get(Synonym_.id)) + ); + } + } + return specification; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/NciThesaurusService.java b/src/main/java/org/mskcc/oncokb/curation/service/NciThesaurusService.java new file mode 100644 index 000000000..b5c5db7bb --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/NciThesaurusService.java @@ -0,0 +1,174 @@ +package org.mskcc.oncokb.curation.service; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import org.apache.commons.lang3.StringUtils; +import org.mskcc.oncokb.curation.domain.NciThesaurus; +import org.mskcc.oncokb.curation.repository.NciThesaurusRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * Service Implementation for managing {@link NciThesaurus}. + */ +@Service +@Transactional +public class NciThesaurusService { + + private final Logger log = LoggerFactory.getLogger(NciThesaurusService.class); + + private final NciThesaurusRepository nciThesaurusRepository; + + public NciThesaurusService(NciThesaurusRepository nciThesaurusRepository) { + this.nciThesaurusRepository = nciThesaurusRepository; + } + + /** + * Save a nciThesaurus. + * + * @param nciThesaurus the entity to save. + * @return the persisted entity. + */ + public NciThesaurus save(NciThesaurus nciThesaurus) { + log.debug("Request to save NciThesaurus : {}", nciThesaurus); + // we need to trim the display name and preferred name if it's too long. + if (StringUtils.isNotEmpty(nciThesaurus.getDisplayName()) && nciThesaurus.getDisplayName().length() > 255) { + nciThesaurus.setDisplayName(nciThesaurus.getDisplayName().substring(0, 255)); + } + if (StringUtils.isNotEmpty(nciThesaurus.getPreferredName()) && nciThesaurus.getPreferredName().length() > 255) { + nciThesaurus.setPreferredName(nciThesaurus.getPreferredName().substring(0, 255)); + } + return nciThesaurusRepository.save(nciThesaurus); + } + + /** + * Partially update a nciThesaurus. + * + * @param nciThesaurus the entity to update partially. + * @return the persisted entity. + */ + public Optional partialUpdate(NciThesaurus nciThesaurus) { + log.debug("Request to partially update NciThesaurus : {}", nciThesaurus); + + return nciThesaurusRepository + .findById(nciThesaurus.getId()) + .map(existingNciThesaurus -> { + if (nciThesaurus.getVersion() != null) { + existingNciThesaurus.setVersion(nciThesaurus.getVersion()); + } + if (nciThesaurus.getCode() != null) { + existingNciThesaurus.setCode(nciThesaurus.getCode()); + } + if (nciThesaurus.getPreferredName() != null) { + existingNciThesaurus.setPreferredName(nciThesaurus.getPreferredName()); + } + if (nciThesaurus.getDisplayName() != null) { + existingNciThesaurus.setDisplayName(nciThesaurus.getDisplayName()); + } + + return existingNciThesaurus; + }) + .map(nciThesaurusRepository::save); + } + + /** + * Get all the nciThesauruses. + * + * @param pageable the pagination information. + * @return the list of entities. + */ + @Transactional(readOnly = true) + public Page findAll(Pageable pageable) { + log.debug("Request to get all NciThesauruses"); + return nciThesaurusRepository.findAll(pageable); + } + + /** + * Get all the nciThesauruses with eager load of many-to-many relationships. + * + * @return the list of entities. + */ + public Page findAllWithEagerRelationships(Pageable pageable) { + Page nciThesaurusPage = nciThesaurusRepository.findAll(pageable); + List enrichedNciThesaurus = nciThesaurusRepository.findAllWithEagerRelationships( + nciThesaurusPage.getContent().stream().map(NciThesaurus::getId).collect(Collectors.toList()) + ); + return new PageImpl<>(enrichedNciThesaurus, pageable, nciThesaurusPage.getTotalElements()); + } + + @Transactional(readOnly = true) + public List findAllWithEagerRelationships(List ids) { + log.debug("Request to get NciThesaurus : {}", ids); + return nciThesaurusRepository.findAllWithEagerRelationships(ids); + } + + /** + * Get one nciThesaurus by id. + * + * @param id the id of the entity. + * @return the entity. + */ + @Transactional(readOnly = true) + public Optional findOne(Long id) { + log.debug("Request to get NciThesaurus : {}", id); + return nciThesaurusRepository.findOneWithEagerRelationships(id); + } + + @Transactional(readOnly = true) + public Optional findByCode(String code) { + log.debug("Request to get NciThesaurus by code: {}", code); + return nciThesaurusRepository.findByCode(code); + } + + @Transactional(readOnly = true) + public List findByName(String name) { + log.debug("Request to get NciThesaurus by name: {}", name); + return nciThesaurusRepository.findByName(name); + } + + @Transactional(readOnly = true) + public Optional findOneByNamePriority(String name) { + log.debug("Request to get NciThesaurus by name: {}", name); + List matches = nciThesaurusRepository.findByName(name); + if (matches.size() > 0) { + matches.sort((o1, o2) -> { + if (o1.getDisplayName().equalsIgnoreCase(name)) { + return -1; + } + if (o2.getDisplayName().equalsIgnoreCase(name)) { + return 1; + } + if (o1.getPreferredName().equalsIgnoreCase(name)) { + return -1; + } + if (o2.getPreferredName().equalsIgnoreCase(name)) { + return 1; + } + return 0; + }); + return Optional.of(matches.get(0)); + } else { + return Optional.empty(); + } + } + + /** + * Delete the nciThesaurus by id. + * + * @param id the id of the entity. + */ + public void delete(Long id) { + log.debug("Request to delete NciThesaurus : {}", id); + nciThesaurusRepository.deleteById(id); + } + + public List searchNciThesaurus(String query) { + return nciThesaurusRepository.searchNciThesaurus(query); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/NcitService.java b/src/main/java/org/mskcc/oncokb/curation/service/NcitService.java new file mode 100644 index 000000000..71f327599 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/NcitService.java @@ -0,0 +1,58 @@ +package org.mskcc.oncokb.curation.service; + +import static org.mskcc.oncokb.curation.util.FileUtils.readTrimmedLinesStream; +import static org.mskcc.oncokb.curation.util.GzipUtils.deCompress; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.nio.charset.Charset; +import java.time.Instant; +import java.util.*; +import java.util.stream.Collectors; +import org.apache.commons.lang3.StringUtils; +import org.mskcc.oncokb.curation.domain.Drug; +import org.mskcc.oncokb.curation.domain.enumeration.InfoType; +import org.mskcc.oncokb.curation.repository.DrugRepository; +import org.mskcc.oncokb.curation.repository.SynonymRepository; +import org.mskcc.oncokb.curation.util.COMPRESSED_FILE_FORMAT; +import org.oncokb.ApiException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * Created by Hongxin Zhang on 4/21/21. + */ +@Service +public class NcitService { + + private final String NCIT_DOWNLOAD_URL = "https://evs.nci.nih.gov/ftp1/NCI_Thesaurus/"; + private final String NCIT_README = NCIT_DOWNLOAD_URL + "ReadMe.txt"; + private final String NCIT_DATA_FILE = NCIT_DOWNLOAD_URL + "Thesaurus.FLAT.zip"; + + @Autowired + private InfoService infoService; + + public String updateNcitDrugs() throws IOException, ApiException { + String ncitVersion = getNcitLatestVersion(); + if (ncitVersion == null) { + throw new ApiException("The NCIT README file has no content. Link to the README: " + NCIT_README); + } else { + // update the NCIT pipeline to use the NCI API + this.infoService.updateInfo(InfoType.NCIT_VERSION, ncitVersion, Instant.now()); + return ncitVersion; + } + } + + private String getNcitLatestVersion() throws IOException { + URL url = new URL(NCIT_README); + InputStream is = url.openStream(); + List readmeFileLines = readTrimmedLinesStream(is); + if (readmeFileLines.size() > 0) { + return readmeFileLines.get(0); + } else { + return null; + } + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/NihEutilsService.java b/src/main/java/org/mskcc/oncokb/curation/service/NihEutilsService.java new file mode 100644 index 000000000..151b7edc2 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/NihEutilsService.java @@ -0,0 +1,382 @@ +package org.mskcc.oncokb.curation.service; + +import java.io.StringReader; +import java.lang.Object; +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.stream.Collectors; +import javax.xml.bind.*; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParserFactory; +import javax.xml.transform.Source; +import javax.xml.transform.sax.SAXSource; +import org.apache.commons.lang3.StringUtils; +import org.mskcc.oncokb.curation.config.application.ApplicationProperties; +import org.mskcc.oncokb.curation.domain.Synonym; +import org.mskcc.oncokb.curation.domain.enumeration.SynonymType; +import org.mskcc.oncokb.curation.domain.nih.efetch.*; +import org.mskcc.oncokb.curation.service.dto.pubmed.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.SAXNotSupportedException; + +@Service +public class NihEutilsService { + + private static final String DEFAULT_BASE_URL = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/"; + private static final Logger logger = LoggerFactory.getLogger(NihEutilsService.class); + private static final String EFETCH = "efetch.fcgi"; + private static final String DEFAULT_UNLABELLED_ABSTRACT_TEXT = "UNLABELLED"; + private final String baseUrl; + private final String nihEutilsToken; + private final SynonymService synonymService; + + public NihEutilsService(ApplicationProperties applicationProperties, SynonymService synonymService) { + this.baseUrl = DEFAULT_BASE_URL; + this.nihEutilsToken = applicationProperties.getNihEutilsToken(); + this.synonymService = synonymService; + } + + private Instant parseDateByFormat(String year, String month, String day, String format) { + return LocalDate.parse(year + "/" + month + "/" + day, DateTimeFormatter.ofPattern(format, Locale.US)) + .atStartOfDay() + .toInstant(ZoneOffset.UTC); + } + + private String parseListElement(List items) { + List strings = new ArrayList<>(); + items.forEach(item -> { + if (item instanceof String) { + strings.add(((String) item)); + } else if (item instanceof org.w3c.dom.Element) { + strings.add((((org.w3c.dom.Element) item).getFirstChild().getTextContent())); + } + }); + return strings.stream().filter(StringUtils::isNotEmpty).collect(Collectors.joining("")); + } + + private Synonym parseArticleId(ArticleId articleId) { + Optional synonymOptional = synonymService.findByTypeAndSourceAndName( + SynonymType.ARTICLE, + articleId.getIdType(), + articleId.getvalue() + ); + if (synonymOptional.isEmpty()) { + Synonym synonym = new Synonym(); + synonym.setType(SynonymType.ARTICLE.name()); + synonym.setSource(articleId.getIdType()); + synonym.setName(articleId.getvalue()); + return synonymService.save(synonym); + } else { + return synonymOptional.orElseThrow(); + } + } + + private Instant parseDate(String year, String month, String day) { + Instant date = parseDateByFormat(year, month, day, "yyyy/M/d"); + if (date == null) { + date = parseDateByFormat(year, month, day, "yyyy/L/d"); + } + return date; + } + + private PubMedDTO parsePubmedArticle(PubmedArticle pubmedArticle) { + if (pubmedArticle != null) { + PubMedDTO pubMedDTO = new PubMedDTO(); + AdditionalInfoDTO additionalInfoDTO = new AdditionalInfoDTO(); + + Optional medlineCitationOptional = Optional.ofNullable(pubmedArticle.getMedlineCitation()); + Optional
articleOptional = Optional.ofNullable(pubmedArticle.getMedlineCitation().getArticle()); + if (medlineCitationOptional.isPresent()) { + MedlineCitation medlineCitation = medlineCitationOptional.orElseThrow(); + pubMedDTO.setPmid(medlineCitation.getPMID().getvalue()); + if (medlineCitation.getDateCompleted() != null) { + Instant dateCompleted = parseDate( + medlineCitation.getDateCompleted().getYear().getvalue(), + medlineCitation.getDateCompleted().getMonth().getvalue(), + medlineCitation.getDateCompleted().getDay().getvalue() + ); + additionalInfoDTO.setCompletedDate(dateCompleted); + pubMedDTO.setDate(dateCompleted); + } + if (medlineCitation.getDateRevised() != null) { + additionalInfoDTO.setRevisedDate( + parseDate( + medlineCitation.getDateRevised().getYear().getvalue(), + medlineCitation.getDateRevised().getMonth().getvalue(), + medlineCitation.getDateRevised().getDay().getvalue() + ) + ); + } + } + if (articleOptional.isPresent()) { + Article article = articleOptional.orElseThrow(); + if (article.getArticleTitle() != null && article.getArticleTitle().getValue() != null) { + pubMedDTO.setTitle(parseListElement(article.getArticleTitle().getValue())); + } + if (article.getAuthorList() != null && !article.getAuthorList().getAuthor().isEmpty()) { + List authorInfo = article + .getAuthorList() + .getAuthor() + .get(0) + .getLastNameOrForeNameOrInitialsOrSuffixOrCollectiveName(); + Optional lastNameOptional = authorInfo.stream().filter(item -> item instanceof LastName).findFirst(); + if (lastNameOptional.isPresent()) { + String authorString = ((LastName) lastNameOptional.orElseThrow()).getvalue(); + if (article.getAuthorList().getAuthor().size() > 1) { + authorString += " et al."; + } + pubMedDTO.setAuthors(authorString); + } + } + if (article.getJournal() != null) { + Journal journal = article.getJournal(); + JournalIssue journalIssue = journal.getJournalIssue(); + JournalDTO journalDTO = new JournalDTO(); + if (journal.getISSN() != null) { + journalDTO.setIssn(journal.getISSN().getvalue()); + } + journalDTO.setTitle(journal.getTitle()); + journalDTO.setIsoAbbreviation(journal.getISOAbbreviation()); + + journalDTO.setIssue(journalIssue.getIssue()); + journalDTO.setVolume(journalIssue.getVolume()); + + if (article.getPaginationOrELocationID() != null) { + article + .getPaginationOrELocationID() + .forEach(object -> { + if (object instanceof Pagination) { + Pagination pagination = (Pagination) object; + Optional medlinePgn = pagination + .getStartPageOrEndPageOrMedlinePgn() + .stream() + .filter(pageObject -> pageObject instanceof MedlinePgn) + .findFirst(); + medlinePgn.ifPresent(o -> journalDTO.setPages(((MedlinePgn) o).getvalue())); + } + }); + } + + additionalInfoDTO.setJournal(journalDTO); + } + if (article.getAbstract() != null) { + List abstractTexts = article.getAbstract().getAbstractText(); + if (abstractTexts != null && !abstractTexts.isEmpty()) { + List abstractTextDTOs = new ArrayList<>(); + if (abstractTexts.size() == 1) { + AbstractTextDTO abstractTextDTO = abstractTextMapper(abstractTexts.get(0)); + abstractTextDTOs.add(abstractTextDTO); + pubMedDTO.setContent(abstractTextDTO.getValue()); + } else { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < abstractTexts.size(); i++) { + AbstractTextDTO text = abstractTextMapper(abstractTexts.get(i)); + abstractTextDTOs.add(text); + if (StringUtils.isNotEmpty(text.getLabel()) && !DEFAULT_UNLABELLED_ABSTRACT_TEXT.equals(text.getLabel())) { + sb.append(StringUtils.capitalize(text.getLabel().toLowerCase())); + sb.append(": "); + } + sb.append(text.getValue()); + if (i < abstractTexts.size() - 1) { + sb.append("\n\n"); + } + } + pubMedDTO.setContent(sb.toString()); + } + additionalInfoDTO.setAbstractTexts(abstractTextDTOs); + } + } + if (article.getDataBankList() != null) { + DataBankList dataBankList = article.getDataBankList(); + dataBankList + .getDataBank() + .forEach(dataBank -> { + DataBankDTO dataBankDTO = new DataBankDTO(); + dataBankDTO.setName(dataBank.getDataBankName()); + dataBankDTO.setAccessionNumbers( + dataBank + .getAccessionNumberList() + .getAccessionNumber() + .stream() + .map(AccessionNumber::getvalue) + .collect(Collectors.toList()) + ); + additionalInfoDTO.addDataBank(dataBankDTO); + }); + } + } + + Optional pubmedDataOptional = Optional.ofNullable(pubmedArticle.getPubmedData()); + if (pubmedDataOptional.isPresent()) { + if ( + pubmedDataOptional.orElseThrow().getArticleIdList() != null && + pubmedDataOptional.orElseThrow().getArticleIdList().getArticleId() != null + ) { + pubMedDTO.setSynonyms( + pubmedDataOptional + .orElseThrow() + .getArticleIdList() + .getArticleId() + .stream() + .map(this::parseArticleId) + .collect(Collectors.toSet()) + ); + } + } + pubMedDTO.setAdditionalInfo(additionalInfoDTO); + return pubMedDTO; + } + return null; + } + + private AbstractTextDTO abstractTextMapper(AbstractText abstractText) { + AbstractTextDTO abstractTextDTO = new AbstractTextDTO(); + abstractTextDTO.setLabel(abstractText.getLabel()); + abstractTextDTO.setNlmCategory(abstractText.getNlmCategory()); + abstractTextDTO.setValue(parseListElement(abstractText.getValue())); + return abstractTextDTO; + } + + private PubMedDTO parsePubmedBookArticle(PubmedBookArticle pubmedBookArticle) { + if (pubmedBookArticle != null) { + PubMedDTO pubMedDTO = new PubMedDTO(); + AdditionalInfoDTO additionalInfoDTO = new AdditionalInfoDTO(); + + Optional bookDocumentOptional = Optional.ofNullable(pubmedBookArticle.getBookDocument()); + if (bookDocumentOptional.isPresent()) { + BookDocument bookDocument = bookDocumentOptional.orElseThrow(); + pubMedDTO.setPmid(bookDocument.getPMID().getvalue()); + + if (bookDocument.getArticleTitle() != null) { + pubMedDTO.setTitle(parseListElement(bookDocument.getArticleTitle().getValue())); + } + if (bookDocument.getAuthorList() != null && !bookDocument.getAuthorList().isEmpty()) { + List authorInfo = bookDocument + .getAuthorList() + .get(0) + .getAuthor() + .get(0) + .getLastNameOrForeNameOrInitialsOrSuffixOrCollectiveName(); + Optional lastNameOptional = authorInfo.stream().filter(item -> item instanceof LastName).findFirst(); + if (lastNameOptional.isPresent()) { + String authorString = ((LastName) lastNameOptional.orElseThrow()).getvalue(); + if (bookDocument.getAuthorList().get(0).getAuthor().size() > 1) { + authorString += " et al."; + } + pubMedDTO.setAuthors(authorString); + } + } + + if (bookDocument.getAbstract() != null) { + List abstractTexts = bookDocument.getAbstract().getAbstractText(); + if (abstractTexts != null && !abstractTexts.isEmpty()) { + List abstractTextDTOs = new ArrayList<>(); + if (abstractTexts.size() == 1) { + AbstractTextDTO abstractTextDTO = abstractTextMapper(abstractTexts.get(0)); + abstractTextDTOs.add(abstractTextDTO); + pubMedDTO.setContent(abstractTextDTO.getValue()); + } else { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < abstractTexts.size(); i++) { + AbstractTextDTO text = abstractTextMapper(abstractTexts.get(i)); + abstractTextDTOs.add(text); + if (StringUtils.isNotEmpty(text.getLabel()) && !DEFAULT_UNLABELLED_ABSTRACT_TEXT.equals(text.getLabel())) { + sb.append(StringUtils.capitalize(text.getLabel().toLowerCase())); + sb.append(": "); + } + sb.append(text.getValue()); + if (i < abstractTexts.size() - 1) { + sb.append("\n\n"); + } + } + pubMedDTO.setContent(sb.toString()); + } + additionalInfoDTO.setAbstractTexts(abstractTextDTOs); + } + } + + if (bookDocument.getArticleIdList() != null && bookDocument.getArticleIdList().getArticleId() != null) { + pubMedDTO.setSynonyms( + bookDocument.getArticleIdList().getArticleId().stream().map(this::parseArticleId).collect(Collectors.toSet()) + ); + } + } + pubMedDTO.setAdditionalInfo(additionalInfoDTO); + return pubMedDTO; + } + return null; + } + + public PubMedDTO fetchPubmedArticle(String pmid) { + if (StringUtils.isEmpty(pmid)) { + return null; + } + Map fetchParams = new HashMap<>(); + fetchParams.put("db", "pubmed"); + fetchParams.put("id", pmid); + fetchParams.put("retmode", "xml"); + + // We can NIH EUtils API call without the token, but it comes with limitation on the IP. + if (StringUtils.isNotEmpty(nihEutilsToken)) { + fetchParams.put("api_key", nihEutilsToken); + } + + PubmedArticleSet pubmedArticleSet = fetch(fetchParams); + if (pubmedArticleSet != null) { + List objects = pubmedArticleSet.getPubmedArticleOrPubmedBookArticle(); + if (objects.size() == 1) { + if (objects.get(0) instanceof PubmedArticle) { + PubmedArticle pubmedArticle = (PubmedArticle) objects.get(0); + return parsePubmedArticle(pubmedArticle); + } + if (objects.get(0) instanceof PubmedBookArticle) { + PubmedBookArticle pubmedBookArticle = (PubmedBookArticle) objects.get(0); + return parsePubmedBookArticle(pubmedBookArticle); + } + } + } + return null; + } + + private PubmedArticleSet fetch(Map queryParams) { + logger.debug("making efetch query with params {}", queryParams); + StringBuilder sb = new StringBuilder(); + sb.append(this.baseUrl); + sb.append(EFETCH); + sb.append("?"); + sb.append(queryParams.entrySet().stream().map(entry -> entry.getKey() + "=" + entry.getValue()).collect(Collectors.joining("&"))); + RestTemplate rest = new RestTemplate(); + + SAXParserFactory spf = SAXParserFactory.newInstance(); + try { + spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", false); + logger.info("Fetch {}", sb); + Source xmlSource = new SAXSource( + spf.newSAXParser().getXMLReader(), + new InputSource(new StringReader(rest.getForObject(sb.toString(), String.class))) + ); + JAXBContext jc = JAXBContext.newInstance(PubmedArticleSet.class); + Unmarshaller um = jc.createUnmarshaller(); + return (PubmedArticleSet) um.unmarshal(xmlSource); + } catch (ParserConfigurationException e) { + throw new RuntimeException(e); + } catch (SAXNotRecognizedException e) { + throw new RuntimeException(e); + } catch (SAXNotSupportedException e) { + throw new RuntimeException(e); + } catch (JAXBException e) { + throw new RuntimeException(e); + } catch (SAXException e) { + throw new RuntimeException(e); + } + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/OncoKbUrlService.java b/src/main/java/org/mskcc/oncokb/curation/service/OncoKbUrlService.java new file mode 100644 index 000000000..964aa3c67 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/OncoKbUrlService.java @@ -0,0 +1,56 @@ +package org.mskcc.oncokb.curation.service; + +import java.util.List; +import org.apache.commons.lang3.StringUtils; +import org.mskcc.oncokb.curation.config.application.ApplicationProperties; +import org.oncokb.ApiClient; +import org.oncokb.ApiException; +import org.oncokb.auth.HttpBearerAuth; +import org.oncokb.client.Gene; +import org.oncokb.client.GenesApi; +import org.oncokb.client.InfoApi; +import org.oncokb.client.OncoKBInfo; +import org.springframework.stereotype.Service; + +/** + * Created by Hongxin Zhang on 7/15/20. + */ +@Service +public class OncoKbUrlService { + + public final String ONCOKB_API_URL = "https://www.oncokb.org/api/v1"; + + private final int ONCOKB_READ_TIMEOUT_OVERRIDE = 30000; + + private final ApiClient apiClient; + + private ApplicationProperties applicationProperties; + + public OncoKbUrlService(ApplicationProperties applicationProperties) { + this.applicationProperties = applicationProperties; + + ApiClient client = new ApiClient(); + client.setReadTimeout(ONCOKB_READ_TIMEOUT_OVERRIDE); + if (applicationProperties.getOncokb() != null) { + client.setBasePath( + StringUtils.isEmpty(applicationProperties.getOncokb().getUrl()) + ? ONCOKB_API_URL + : applicationProperties.getOncokb().getUrl() + ); + HttpBearerAuth Authorization = (HttpBearerAuth) client.getAuthentication("Authorization"); + Authorization.setBearerToken(applicationProperties.getOncokb().getApiKey()); + } + + this.apiClient = client; + } + + public List getGenes() throws ApiException { + GenesApi genesApi = new GenesApi(this.apiClient); + return genesApi.genesGetUsingGET(null); + } + + public OncoKBInfo getInfo() throws ApiException { + InfoApi infoApi = new InfoApi(this.apiClient); + return infoApi.infoGetUsingGET(); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/RuleService.java b/src/main/java/org/mskcc/oncokb/curation/service/RuleService.java new file mode 100644 index 000000000..61f5ee297 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/RuleService.java @@ -0,0 +1,97 @@ +package org.mskcc.oncokb.curation.service; + +import java.util.List; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.Rule; +import org.mskcc.oncokb.curation.repository.RuleRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * Service Implementation for managing {@link Rule}. + */ +@Service +@Transactional +public class RuleService { + + private final Logger log = LoggerFactory.getLogger(RuleService.class); + + private final RuleRepository ruleRepository; + + public RuleService(RuleRepository ruleRepository) { + this.ruleRepository = ruleRepository; + } + + /** + * Save a rule. + * + * @param rule the entity to save. + * @return the persisted entity. + */ + public Rule save(Rule rule) { + log.debug("Request to save Rule : {}", rule); + return ruleRepository.save(rule); + } + + /** + * Partially update a rule. + * + * @param rule the entity to update partially. + * @return the persisted entity. + */ + public Optional partialUpdate(Rule rule) { + log.debug("Request to partially update Rule : {}", rule); + + return ruleRepository + .findById(rule.getId()) + .map(existingRule -> { + if (rule.getEntity() != null) { + existingRule.setEntity(rule.getEntity()); + } + if (rule.getRule() != null) { + existingRule.setRule(rule.getRule()); + } + if (rule.getName() != null) { + existingRule.setName(rule.getName()); + } + + return existingRule; + }) + .map(ruleRepository::save); + } + + /** + * Get all the rules. + * + * @return the list of entities. + */ + @Transactional(readOnly = true) + public List findAll() { + log.debug("Request to get all Rules"); + return ruleRepository.findAll(); + } + + /** + * Get one rule by id. + * + * @param id the id of the entity. + * @return the entity. + */ + @Transactional(readOnly = true) + public Optional findOne(Long id) { + log.debug("Request to get Rule : {}", id); + return ruleRepository.findById(id); + } + + /** + * Delete the rule by id. + * + * @param id the id of the entity. + */ + public void delete(Long id) { + log.debug("Request to delete Rule : {}", id); + ruleRepository.deleteById(id); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/SearchService.java b/src/main/java/org/mskcc/oncokb/curation/service/SearchService.java new file mode 100644 index 000000000..e90691a57 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/SearchService.java @@ -0,0 +1,105 @@ +package org.mskcc.oncokb.curation.service; + +import java.util.ArrayList; +import java.util.List; +import org.mskcc.oncokb.curation.domain.Alteration; +import org.mskcc.oncokb.curation.domain.Article; +import org.mskcc.oncokb.curation.domain.CompanionDiagnosticDevice; +import org.mskcc.oncokb.curation.domain.Drug; +import org.mskcc.oncokb.curation.domain.FdaSubmission; +import org.mskcc.oncokb.curation.domain.Gene; +import org.mskcc.oncokb.curation.service.criteria.AlterationCriteria; +import org.mskcc.oncokb.curation.service.criteria.ArticleCriteria; +import org.mskcc.oncokb.curation.service.criteria.CompanionDiagnosticDeviceCriteria; +import org.mskcc.oncokb.curation.service.criteria.DrugCriteria; +import org.mskcc.oncokb.curation.service.criteria.FdaSubmissionCriteria; +import org.mskcc.oncokb.curation.service.criteria.GeneCriteria; +import org.mskcc.oncokb.curation.service.dto.SearchResultDTO; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import tech.jhipster.service.filter.IntegerFilter; +import tech.jhipster.service.filter.StringFilter; + +@Service +@Transactional +public class SearchService { + + private final Logger log = LoggerFactory.getLogger(SearchService.class); + + private final AlterationQueryService alterationQueryService; + private final ArticleQueryService articleQueryService; + private final CompanionDiagnosticDeviceQueryService companionDiagnosticDeviceQueryService; + private final DrugQueryService drugQueryService; + private final FdaSubmissionQueryService fdaSubmissionQueryService; + private final GeneQueryService geneQueryService; + + public SearchService( + AlterationQueryService alterationQueryService, + ArticleQueryService articleQueryService, + CompanionDiagnosticDeviceQueryService companionDiagnosticDeviceQueryService, + DrugQueryService drugQueryService, + FdaSubmissionQueryService fdaSubmissionQueryService, + GeneQueryService geneQueryService + ) { + this.alterationQueryService = alterationQueryService; + this.articleQueryService = articleQueryService; + this.companionDiagnosticDeviceQueryService = companionDiagnosticDeviceQueryService; + this.drugQueryService = drugQueryService; + this.fdaSubmissionQueryService = fdaSubmissionQueryService; + this.geneQueryService = geneQueryService; + } + + public SearchResultDTO search(String query) { + log.debug("Request to search for query {}", query); + Pageable defaultPageable = Pageable.ofSize(5); + + List fdaSubmissions = new ArrayList<>(); + List cdxs = new ArrayList<>(); + List
articles = new ArrayList<>(); + List drugs = new ArrayList<>(); + List genes = new ArrayList<>(); + List alterations = new ArrayList<>(); + + StringFilter stringContainsFilter = new StringFilter(); + stringContainsFilter.setContains(query); + + FdaSubmissionCriteria fdaSubmissionCriteria = new FdaSubmissionCriteria(); + fdaSubmissionCriteria.setDeviceName(stringContainsFilter); + fdaSubmissionCriteria.setNumber(stringContainsFilter); + fdaSubmissionCriteria.setSupplementNumber(stringContainsFilter); + fdaSubmissions = this.fdaSubmissionQueryService.findByCriteria(fdaSubmissionCriteria, defaultPageable).getContent(); + + CompanionDiagnosticDeviceCriteria cdxCriteria = new CompanionDiagnosticDeviceCriteria(); + cdxCriteria.setName(stringContainsFilter); + cdxCriteria.setManufacturer(stringContainsFilter); + cdxs = this.companionDiagnosticDeviceQueryService.findByCriteria(cdxCriteria, defaultPageable).getContent(); + + ArticleCriteria articleCriteria = new ArticleCriteria(); + articleCriteria.setUid(stringContainsFilter); + articles = this.articleQueryService.findByCriteria(articleCriteria, defaultPageable).getContent(); + + DrugCriteria drugCriteria = new DrugCriteria(); + drugCriteria.setName(stringContainsFilter); + drugs = this.drugQueryService.findByCriteria(drugCriteria, defaultPageable).getContent(); + + IntegerFilter entrezGeneIdFilter = new IntegerFilter(); + try { + Integer entrezGeneId = Integer.parseInt(query); + entrezGeneIdFilter.setEquals(entrezGeneId); + } catch (NumberFormatException e) {} + GeneCriteria geneCriteria = new GeneCriteria(); + geneCriteria.setHugoSymbol(stringContainsFilter); + geneCriteria.setEntrezGeneId(entrezGeneIdFilter); + genes = this.geneQueryService.findByCriteria(geneCriteria, defaultPageable).getContent(); + + AlterationCriteria alterationCriteria = new AlterationCriteria(); + alterationCriteria.setName(stringContainsFilter); + alterations = this.alterationQueryService.findByCriteria(alterationCriteria, defaultPageable).getContent(); + + SearchResultDTO searchResultDTO = new SearchResultDTO(fdaSubmissions, cdxs, articles, drugs, genes, alterations); + return searchResultDTO; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/SeqRegionService.java b/src/main/java/org/mskcc/oncokb/curation/service/SeqRegionService.java new file mode 100644 index 000000000..a94a0ecd0 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/SeqRegionService.java @@ -0,0 +1,116 @@ +package org.mskcc.oncokb.curation.service; + +import java.util.List; +import java.util.Optional; +import org.apache.commons.lang3.StringUtils; +import org.mskcc.oncokb.curation.domain.SeqRegion; +import org.mskcc.oncokb.curation.repository.SeqRegionRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * Service Implementation for managing {@link SeqRegion}. + */ +@Service +@Transactional +public class SeqRegionService { + + private final Logger log = LoggerFactory.getLogger(SeqRegionService.class); + + private final SeqRegionRepository seqRegionRepository; + + public SeqRegionService(SeqRegionRepository seqRegionRepository) { + this.seqRegionRepository = seqRegionRepository; + } + + /** + * Save a seqRegion. + * + * @param seqRegion the entity to save. + * @return the persisted entity. + */ + public SeqRegion save(SeqRegion seqRegion) { + log.debug("Request to save SeqRegion : {}", seqRegion); + return seqRegionRepository.save(seqRegion); + } + + /** + * Partially update a seqRegion. + * + * @param seqRegion the entity to update partially. + * @return the persisted entity. + */ + public Optional partialUpdate(SeqRegion seqRegion) { + log.debug("Request to partially update SeqRegion : {}", seqRegion); + + return seqRegionRepository + .findById(seqRegion.getId()) + .map(existingSeqRegion -> { + if (seqRegion.getName() != null) { + existingSeqRegion.setName(seqRegion.getName()); + } + if (seqRegion.getChromosome() != null) { + existingSeqRegion.setChromosome(seqRegion.getChromosome()); + } + if (seqRegion.getDescription() != null) { + existingSeqRegion.setDescription(seqRegion.getDescription()); + } + + return existingSeqRegion; + }) + .map(seqRegionRepository::save); + } + + /** + * Get all the seqRegions. + * + * @return the list of entities. + */ + @Transactional(readOnly = true) + public List findAll() { + log.debug("Request to get all SeqRegions"); + return seqRegionRepository.findAll(); + } + + public Optional findByName(String name) { + return seqRegionRepository.findByName(name); + } + + public Optional findByNameOrCreate(String name) { + if (StringUtils.isEmpty(name)) { + return Optional.empty(); + } + Optional seqRegionOptional = seqRegionRepository.findByName(name); + if (seqRegionOptional.isEmpty()) { + SeqRegion seqRegion = new SeqRegion(); + seqRegion.setName(name); + return Optional.ofNullable(seqRegionRepository.save(seqRegion)); + } else { + return seqRegionOptional; + } + } + + /** + * Get one seqRegion by id. + * + * @param id the id of the entity. + * @return the entity. + */ + @Transactional(readOnly = true) + public Optional findOne(Long id) { + log.debug("Request to get SeqRegion : {}", id); + return seqRegionRepository.findById(id); + } + + /** + * Delete the seqRegion by id. + * + * @param id the id of the entity. + */ + public void delete(Long id) { + log.debug("Request to delete SeqRegion : {}", id); + seqRegionRepository.deleteById(id); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/SequenceQueryService.java b/src/main/java/org/mskcc/oncokb/curation/service/SequenceQueryService.java new file mode 100644 index 000000000..aa62f9ff6 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/SequenceQueryService.java @@ -0,0 +1,102 @@ +package org.mskcc.oncokb.curation.service; + +import jakarta.persistence.criteria.JoinType; +import java.util.List; +import org.mskcc.oncokb.curation.domain.*; // for static metamodels +import org.mskcc.oncokb.curation.domain.Sequence; +import org.mskcc.oncokb.curation.repository.SequenceRepository; +import org.mskcc.oncokb.curation.service.criteria.SequenceCriteria; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import tech.jhipster.service.QueryService; + +/** + * Service for executing complex queries for {@link Sequence} entities in the database. + * The main input is a {@link SequenceCriteria} which gets converted to {@link Specification}, + * in a way that all the filters must apply. + * It returns a {@link List} of {@link Sequence} or a {@link Page} of {@link Sequence} which fulfills the criteria. + */ +@Service +@Transactional(readOnly = true) +public class SequenceQueryService extends QueryService { + + private final Logger log = LoggerFactory.getLogger(SequenceQueryService.class); + + private final SequenceRepository sequenceRepository; + + public SequenceQueryService(SequenceRepository sequenceRepository) { + this.sequenceRepository = sequenceRepository; + } + + /** + * Return a {@link List} of {@link Sequence} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public List findByCriteria(SequenceCriteria criteria) { + log.debug("find by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return sequenceRepository.findAll(specification); + } + + /** + * Return a {@link Page} of {@link Sequence} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @param page The page, which should be returned. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public Page findByCriteria(SequenceCriteria criteria, Pageable page) { + log.debug("find by criteria : {}, page: {}", criteria, page); + final Specification specification = createSpecification(criteria); + return sequenceRepository.findAll(specification, page); + } + + /** + * Return the number of matching entities in the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the number of matching entities. + */ + @Transactional(readOnly = true) + public long countByCriteria(SequenceCriteria criteria) { + log.debug("count by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return sequenceRepository.count(specification); + } + + /** + * Function to convert {@link SequenceCriteria} to a {@link Specification} + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching {@link Specification} of the entity. + */ + protected Specification createSpecification(SequenceCriteria criteria) { + Specification specification = Specification.where(null); + if (criteria != null) { + // This has to be called first, because the distinct method returns null + if (criteria.getDistinct() != null) { + specification = specification.or(distinct(criteria.getDistinct())); + } + if (criteria.getId() != null) { + specification = specification.or(buildRangeSpecification(criteria.getId(), Sequence_.id)); + } + if (criteria.getSequenceType() != null) { + specification = specification.or(buildSpecification(criteria.getSequenceType(), Sequence_.sequenceType)); + } + if (criteria.getTranscriptId() != null) { + specification = specification.or( + buildSpecification( + criteria.getTranscriptId(), + root -> root.join(Sequence_.transcript, JoinType.LEFT).get(Transcript_.id) + ) + ); + } + } + return specification; + } +} diff --git a/src/main/java/org/mskcc/oncokb/transcript/service/SequenceService.java b/src/main/java/org/mskcc/oncokb/curation/service/SequenceService.java similarity index 81% rename from src/main/java/org/mskcc/oncokb/transcript/service/SequenceService.java rename to src/main/java/org/mskcc/oncokb/curation/service/SequenceService.java index 25d28bed1..1119e7e65 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/service/SequenceService.java +++ b/src/main/java/org/mskcc/oncokb/curation/service/SequenceService.java @@ -1,13 +1,15 @@ -package org.mskcc.oncokb.transcript.service; +package org.mskcc.oncokb.curation.service; -import java.util.List; import java.util.Optional; -import org.mskcc.oncokb.transcript.domain.Sequence; -import org.mskcc.oncokb.transcript.domain.Transcript; -import org.mskcc.oncokb.transcript.domain.enumeration.SequenceType; -import org.mskcc.oncokb.transcript.repository.SequenceRepository; +import org.mskcc.oncokb.curation.domain.Sequence; +import org.mskcc.oncokb.curation.domain.Transcript; +import org.mskcc.oncokb.curation.domain.enumeration.SequenceType; +import org.mskcc.oncokb.curation.repository.SequenceRepository; +import org.mskcc.oncokb.curation.service.mapper.TranscriptMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -64,12 +66,13 @@ public Optional partialUpdate(Sequence sequence) { /** * Get all the sequences. * + * @param pageable the pagination information. * @return the list of entities. */ @Transactional(readOnly = true) - public List findAll() { + public Page findAll(Pageable pageable) { log.debug("Request to get all Sequences"); - return sequenceRepository.findAll(); + return sequenceRepository.findAll(pageable); } /** diff --git a/src/main/java/org/mskcc/oncokb/curation/service/SpecimenTypeService.java b/src/main/java/org/mskcc/oncokb/curation/service/SpecimenTypeService.java new file mode 100644 index 000000000..710530eba --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/SpecimenTypeService.java @@ -0,0 +1,104 @@ +package org.mskcc.oncokb.curation.service; + +import java.util.List; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.SpecimenType; +import org.mskcc.oncokb.curation.repository.SpecimenTypeRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * Service Implementation for managing {@link SpecimenType}. + */ +@Service +@Transactional +public class SpecimenTypeService { + + private final Logger log = LoggerFactory.getLogger(SpecimenTypeService.class); + + private final SpecimenTypeRepository specimenTypeRepository; + + public SpecimenTypeService(SpecimenTypeRepository specimenTypeRepository) { + this.specimenTypeRepository = specimenTypeRepository; + } + + /** + * Save a specimenType. + * + * @param specimenType the entity to save. + * @return the persisted entity. + */ + public SpecimenType save(SpecimenType specimenType) { + log.debug("Request to save SpecimenType : {}", specimenType); + return specimenTypeRepository.save(specimenType); + } + + /** + * Partially update a specimenType. + * + * @param specimenType the entity to update partially. + * @return the persisted entity. + */ + public Optional partialUpdate(SpecimenType specimenType) { + log.debug("Request to partially update SpecimenType : {}", specimenType); + + return specimenTypeRepository + .findById(specimenType.getId()) + .map(existingSpecimenType -> { + if (specimenType.getType() != null) { + existingSpecimenType.setType(specimenType.getType()); + } + if (specimenType.getName() != null) { + existingSpecimenType.setName(specimenType.getName()); + } + + return existingSpecimenType; + }) + .map(specimenTypeRepository::save); + } + + /** + * Get all the specimenTypes. + * + * @return the list of entities. + */ + @Transactional(readOnly = true) + public List findAll() { + log.debug("Request to get all SpecimenTypes"); + return specimenTypeRepository.findAll(); + } + + /** + * Get one specimenType by id. + * + * @param id the id of the entity. + * @return the entity. + */ + @Transactional(readOnly = true) + public Optional findOne(Long id) { + log.debug("Request to get SpecimenType : {}", id); + return specimenTypeRepository.findById(id); + } + + @Transactional(readOnly = true) + public Optional findOneByType(String type) { + return specimenTypeRepository.findOneByType(type); + } + + @Transactional(readOnly = true) + public Optional findOneByName(String name) { + return specimenTypeRepository.findOneByName(name); + } + + /** + * Delete the specimenType by id. + * + * @param id the id of the entity. + */ + public void delete(Long id) { + log.debug("Request to delete SpecimenType : {}", id); + specimenTypeRepository.deleteById(id); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/SynonymQueryService.java b/src/main/java/org/mskcc/oncokb/curation/service/SynonymQueryService.java new file mode 100644 index 000000000..b915ace38 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/SynonymQueryService.java @@ -0,0 +1,129 @@ +package org.mskcc.oncokb.curation.service; + +import jakarta.persistence.criteria.JoinType; +import java.util.List; +import org.mskcc.oncokb.curation.domain.*; // for static metamodels +import org.mskcc.oncokb.curation.domain.Synonym; +import org.mskcc.oncokb.curation.repository.SynonymRepository; +import org.mskcc.oncokb.curation.service.criteria.SynonymCriteria; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import tech.jhipster.service.QueryService; + +/** + * Service for executing complex queries for {@link Synonym} entities in the database. + * The main input is a {@link SynonymCriteria} which gets converted to {@link Specification}, + * in a way that all the filters must apply. + * It returns a {@link List} of {@link Synonym} or a {@link Page} of {@link Synonym} which fulfills the criteria. + */ +@Service +@Transactional(readOnly = true) +public class SynonymQueryService extends QueryService { + + private final Logger log = LoggerFactory.getLogger(SynonymQueryService.class); + + private final SynonymRepository synonymRepository; + + public SynonymQueryService(SynonymRepository synonymRepository) { + this.synonymRepository = synonymRepository; + } + + /** + * Return a {@link List} of {@link Synonym} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public List findByCriteria(SynonymCriteria criteria) { + log.debug("find by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return synonymRepository.findAll(specification); + } + + /** + * Return a {@link Page} of {@link Synonym} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @param page The page, which should be returned. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public Page findByCriteria(SynonymCriteria criteria, Pageable page) { + log.debug("find by criteria : {}, page: {}", criteria, page); + final Specification specification = createSpecification(criteria); + return synonymRepository.findAll(specification, page); + } + + /** + * Return the number of matching entities in the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the number of matching entities. + */ + @Transactional(readOnly = true) + public long countByCriteria(SynonymCriteria criteria) { + log.debug("count by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return synonymRepository.count(specification); + } + + /** + * Function to convert {@link SynonymCriteria} to a {@link Specification} + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching {@link Specification} of the entity. + */ + protected Specification createSpecification(SynonymCriteria criteria) { + Specification specification = Specification.where(null); + if (criteria != null) { + // This has to be called first, because the distinct method returns null + if (criteria.getDistinct() != null) { + specification = specification.or(distinct(criteria.getDistinct())); + } + if (criteria.getId() != null) { + specification = specification.or(buildRangeSpecification(criteria.getId(), Synonym_.id)); + } + if (criteria.getType() != null) { + specification = specification.or(buildStringSpecification(criteria.getType(), Synonym_.type)); + } + if (criteria.getSource() != null) { + specification = specification.or(buildStringSpecification(criteria.getSource(), Synonym_.source)); + } + if (criteria.getCode() != null) { + specification = specification.or(buildStringSpecification(criteria.getCode(), Synonym_.code)); + } + if (criteria.getName() != null) { + specification = specification.or(buildStringSpecification(criteria.getName(), Synonym_.name)); + } + if (criteria.getArticleId() != null) { + specification = specification.or( + buildSpecification(criteria.getArticleId(), root -> root.join(Synonym_.articles, JoinType.LEFT).get(Article_.id)) + ); + } + if (criteria.getCancerTypeId() != null) { + specification = specification.or( + buildSpecification( + criteria.getCancerTypeId(), + root -> root.join(Synonym_.cancerTypes, JoinType.LEFT).get(CancerType_.id) + ) + ); + } + if (criteria.getGeneId() != null) { + specification = specification.or( + buildSpecification(criteria.getGeneId(), root -> root.join(Synonym_.genes, JoinType.LEFT).get(Gene_.id)) + ); + } + if (criteria.getNciThesaurusId() != null) { + specification = specification.or( + buildSpecification( + criteria.getNciThesaurusId(), + root -> root.join(Synonym_.nciThesauruses, JoinType.LEFT).get(NciThesaurus_.id) + ) + ); + } + } + return specification; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/SynonymService.java b/src/main/java/org/mskcc/oncokb/curation/service/SynonymService.java new file mode 100644 index 000000000..d213430f8 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/SynonymService.java @@ -0,0 +1,126 @@ +package org.mskcc.oncokb.curation.service; + +import java.util.Optional; +import org.apache.commons.lang3.StringUtils; +import org.mskcc.oncokb.curation.domain.Synonym; +import org.mskcc.oncokb.curation.domain.enumeration.SynonymType; +import org.mskcc.oncokb.curation.repository.SynonymRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * Service Implementation for managing {@link Synonym}. + */ +@Service +@Transactional +public class SynonymService { + + private final Logger log = LoggerFactory.getLogger(SynonymService.class); + + private final SynonymRepository synonymRepository; + + public SynonymService(SynonymRepository synonymRepository) { + this.synonymRepository = synonymRepository; + } + + /** + * Save a synonym. + * + * @param synonym the entity to save. + * @return the persisted entity. + */ + public Synonym save(Synonym synonym) { + log.debug("Request to save Synonym : {}", synonym); + // we need to trim the name if it's too long. + synonym.setName(trimName(synonym.getName())); + return synonymRepository.save(synonym); + } + + /** + * Partially update a synonym. + * + * @param synonym the entity to update partially. + * @return the persisted entity. + */ + public Optional partialUpdate(Synonym synonym) { + log.debug("Request to partially update Synonym : {}", synonym); + + return synonymRepository + .findById(synonym.getId()) + .map(existingSynonym -> { + if (synonym.getType() != null) { + existingSynonym.setType(synonym.getType()); + } + if (synonym.getSource() != null) { + existingSynonym.setSource(synonym.getSource()); + } + if (synonym.getCode() != null) { + existingSynonym.setCode(synonym.getCode()); + } + if (synonym.getName() != null) { + existingSynonym.setName(trimName(synonym.getName())); + } + if (synonym.getNote() != null) { + existingSynonym.setNote(synonym.getNote()); + } + + return existingSynonym; + }) + .map(synonymRepository::save); + } + + /** + * Get all the synonyms. + * + * @param pageable the pagination information. + * @return the list of entities. + */ + @Transactional(readOnly = true) + public Page findAll(Pageable pageable) { + log.debug("Request to get all Synonyms"); + return synonymRepository.findAll(pageable); + } + + /** + * Get one synonym by id. + * + * @param id the id of the entity. + * @return the entity. + */ + @Transactional(readOnly = true) + public Optional findOne(Long id) { + log.debug("Request to get Synonym : {}", id); + return synonymRepository.findById(id); + } + + public Optional findByTypeAndSourceAndName(SynonymType synonymType, String source, String name) { + return synonymRepository.findByTypeAndSourceAndName(synonymType.name(), source, trimName(name)); + } + + /** + * Delete the synonym by id. + * + * @param id the id of the entity. + */ + public void delete(Long id) { + log.debug("Request to delete Synonym : {}", id); + synonymRepository.deleteById(id); + } + + /** + * Limit the synonym name length. We only save no more than 255 characters. + * + * @param name Synonym name + * @return trimmed name + */ + private String trimName(String name) { + if (StringUtils.isNotEmpty(name) && name.length() > 255) { + name = name.substring(0, 255); + } + return name; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/TranscriptQueryService.java b/src/main/java/org/mskcc/oncokb/curation/service/TranscriptQueryService.java new file mode 100644 index 000000000..ff3a31e2a --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/TranscriptQueryService.java @@ -0,0 +1,171 @@ +package org.mskcc.oncokb.curation.service; + +import jakarta.persistence.criteria.JoinType; +import java.util.List; +import org.apache.commons.lang3.StringUtils; +import org.mskcc.oncokb.curation.domain.*; // for static metamodels +import org.mskcc.oncokb.curation.domain.Transcript; +import org.mskcc.oncokb.curation.repository.TranscriptRepository; +import org.mskcc.oncokb.curation.service.criteria.EnsemblGeneCriteria; +import org.mskcc.oncokb.curation.service.criteria.TranscriptCriteria; +import org.mskcc.oncokb.curation.service.dto.TranscriptDTO; +import org.mskcc.oncokb.curation.service.mapper.TranscriptMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import tech.jhipster.service.QueryService; +import tech.jhipster.service.filter.IntegerFilter; +import tech.jhipster.service.filter.StringFilter; + +/** + * Service for executing complex queries for {@link Transcript} entities in the database. + * The main input is a {@link TranscriptCriteria} which gets converted to {@link Specification}, + * in a way that all the filters must apply. + * It returns a {@link List} of {@link TranscriptDTO} or a {@link Page} of {@link TranscriptDTO} which fulfills the criteria. + */ +@Service +@Transactional(readOnly = true) +public class TranscriptQueryService extends QueryService { + + private final Logger log = LoggerFactory.getLogger(TranscriptQueryService.class); + + private final TranscriptRepository transcriptRepository; + + private final TranscriptMapper transcriptMapper; + + public TranscriptQueryService(TranscriptRepository transcriptRepository, TranscriptMapper transcriptMapper) { + this.transcriptRepository = transcriptRepository; + this.transcriptMapper = transcriptMapper; + } + + /** + * Return a {@link List} of {@link TranscriptDTO} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public List findByCriteria(TranscriptCriteria criteria) { + log.debug("find by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return transcriptMapper.toDto(transcriptRepository.findAll(specification)); + } + + /** + * Return a {@link Page} of {@link TranscriptDTO} which matches the criteria from the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @param page The page, which should be returned. + * @return the matching entities. + */ + @Transactional(readOnly = true) + public Page findByCriteria(TranscriptCriteria criteria, Pageable page) { + log.debug("find by criteria : {}, page: {}", criteria, page); + final Specification specification = createSpecification(criteria); + return transcriptRepository.findAll(specification, page).map(transcriptMapper::toDto); + } + + @Transactional(readOnly = true) + public Page findBySearchQuery(String query, Pageable page) { + TranscriptCriteria criteria = new TranscriptCriteria(); + StringFilter stringFilter = new StringFilter(); + stringFilter.setContains(query); + criteria.setEnsemblTranscriptId(stringFilter); + criteria.setEnsemblProteinId(stringFilter); + return findByCriteria(criteria, page); + } + + /** + * Return the number of matching entities in the database. + * @param criteria The object which holds all the filters, which the entities should match. + * @return the number of matching entities. + */ + @Transactional(readOnly = true) + public long countByCriteria(TranscriptCriteria criteria) { + log.debug("count by criteria : {}", criteria); + final Specification specification = createSpecification(criteria); + return transcriptRepository.count(specification); + } + + /** + * Function to convert {@link TranscriptCriteria} to a {@link Specification} + * @param criteria The object which holds all the filters, which the entities should match. + * @return the matching {@link Specification} of the entity. + */ + protected Specification createSpecification(TranscriptCriteria criteria) { + Specification specification = Specification.where(null); + if (criteria != null) { + // This has to be called first, because the distinct method returns null + if (criteria.getDistinct() != null) { + specification = specification.or(distinct(criteria.getDistinct())); + } + if (criteria.getId() != null) { + specification = specification.or(buildRangeSpecification(criteria.getId(), Transcript_.id)); + } + if (criteria.getReferenceGenome() != null) { + specification = specification.or(buildSpecification(criteria.getReferenceGenome(), Transcript_.referenceGenome)); + } + if (criteria.getEnsemblTranscriptId() != null) { + specification = specification.or( + buildStringSpecification(criteria.getEnsemblTranscriptId(), Transcript_.ensemblTranscriptId) + ); + } + if (criteria.getCanonical() != null) { + specification = specification.or(buildSpecification(criteria.getCanonical(), Transcript_.canonical)); + } + if (criteria.getEnsemblProteinId() != null) { + specification = specification.or(buildStringSpecification(criteria.getEnsemblProteinId(), Transcript_.ensemblProteinId)); + } + if (criteria.getReferenceSequenceId() != null) { + specification = specification.or( + buildStringSpecification(criteria.getReferenceSequenceId(), Transcript_.referenceSequenceId) + ); + } + if (criteria.getDescription() != null) { + specification = specification.or(buildStringSpecification(criteria.getDescription(), Transcript_.description)); + } + if (criteria.getSequenceId() != null) { + specification = specification.or( + buildSpecification(criteria.getSequenceId(), root -> root.join(Transcript_.sequences, JoinType.LEFT).get(Sequence_.id)) + ); + } + if (criteria.getFragmentsId() != null) { + specification = specification.or( + buildSpecification( + criteria.getFragmentsId(), + root -> root.join(Transcript_.fragments, JoinType.LEFT).get(GenomeFragment_.id) + ) + ); + } + if (criteria.getFlagId() != null) { + specification = specification.or( + buildSpecification(criteria.getFlagId(), root -> root.join(Transcript_.flags, JoinType.LEFT).get(Flag_.id)) + ); + } + if (criteria.getEnsemblGeneId() != null) { + specification = specification.or( + buildSpecification( + criteria.getEnsemblGeneId(), + root -> root.join(Transcript_.ensemblGene, JoinType.LEFT).get(EnsemblGene_.id) + ) + ); + } + if (criteria.getGeneId() != null) { + specification = specification.or( + buildSpecification(criteria.getGeneId(), root -> root.join(Transcript_.gene, JoinType.LEFT).get(Gene_.id)) + ); + } + if (criteria.getAlterationId() != null) { + specification = specification.or( + buildSpecification( + criteria.getAlterationId(), + root -> root.join(Transcript_.alterations, JoinType.LEFT).get(Alteration_.id) + ) + ); + } + } + return specification; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/TranscriptService.java b/src/main/java/org/mskcc/oncokb/curation/service/TranscriptService.java new file mode 100644 index 000000000..d1d1b9394 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/TranscriptService.java @@ -0,0 +1,632 @@ +package org.mskcc.oncokb.curation.service; + +import static org.mskcc.oncokb.curation.config.Constants.ENSEMBL_POST_THRESHOLD; + +import java.util.*; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import org.apache.commons.lang3.StringUtils; +import org.genome_nexus.ApiException; +import org.genome_nexus.client.EnsemblControllerApi; +import org.genome_nexus.client.EnsemblTranscript; +import org.mskcc.oncokb.curation.config.cache.CacheCategory; +import org.mskcc.oncokb.curation.config.cache.CacheNameResolver; +import org.mskcc.oncokb.curation.domain.*; +import org.mskcc.oncokb.curation.domain.enumeration.GenomeFragmentType; +import org.mskcc.oncokb.curation.domain.enumeration.ReferenceGenome; +import org.mskcc.oncokb.curation.domain.enumeration.SequenceType; +import org.mskcc.oncokb.curation.repository.TranscriptRepository; +import org.mskcc.oncokb.curation.service.dto.ClustalOResp; +import org.mskcc.oncokb.curation.service.dto.TranscriptDTO; +import org.mskcc.oncokb.curation.service.mapper.TranscriptMapper; +import org.mskcc.oncokb.curation.vm.MissMatchPairVM; +import org.mskcc.oncokb.curation.vm.TranscriptMatchResultVM; +import org.mskcc.oncokb.curation.vm.TranscriptPairVM; +import org.mskcc.oncokb.curation.vm.ensembl.EnsemblSequence; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cache.CacheManager; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * Service Implementation for managing {@link Transcript}. + */ +@Service +@Transactional +public class TranscriptService { + + private final GenomeNexusService genomeNexusService; + private final EnsemblService ensemblService; + private final AlignmentService alignmentService; + private final SequenceService sequenceService; + private final TranscriptMapper transcriptMapper; + private final CacheNameResolver cacheNameResolver; + private final Optional optionalCacheManager; + + private final Logger log = LoggerFactory.getLogger(TranscriptService.class); + + private final TranscriptRepository transcriptRepository; + private final GenomeFragmentService genomeFragmentService; + private final SeqRegionService seqRegionService; + private final EbiService ebiService; + + public TranscriptService( + GenomeNexusService genomeNexusService, + EnsemblService ensemblService, + AlignmentService alignmentService, + SequenceService sequenceService, + TranscriptRepository transcriptRepository, + TranscriptMapper transcriptMapper, + GenomeFragmentService genomeFragmentService, + CacheNameResolver cacheNameResolver, + Optional optionalCacheManager, + SeqRegionService seqRegionService, + EbiService ebiService + ) { + this.genomeNexusService = genomeNexusService; + this.ensemblService = ensemblService; + this.alignmentService = alignmentService; + this.sequenceService = sequenceService; + this.transcriptRepository = transcriptRepository; + this.transcriptMapper = transcriptMapper; + this.genomeFragmentService = genomeFragmentService; + this.cacheNameResolver = cacheNameResolver; + this.optionalCacheManager = optionalCacheManager; + this.seqRegionService = seqRegionService; + this.ebiService = ebiService; + } + + /** + * Save a transcript. + * + * @param transcriptDTO the entity to save. + * @return the persisted entity. + */ + public TranscriptDTO save(TranscriptDTO transcriptDTO) { + log.debug("Request to save Transcript : {}", transcriptDTO); + Transcript transcript = transcriptMapper.toEntity(transcriptDTO); + Transcript savedTranscript = transcriptRepository.save(transcript); + + List transcriptGenomeFragments = genomeFragmentService.findAllByTranscriptId(transcriptDTO.getId()); + genomeFragmentService.deleteAll(transcriptGenomeFragments); + + Optional seqRegionOptional = seqRegionService.findByNameOrCreate(transcriptDTO.getChromosome()); + + GenomeFragment genomeFragment = new GenomeFragment(); + genomeFragment.setTranscript(savedTranscript); + if (seqRegionOptional.isPresent()) { + genomeFragment.setSeqRegion(seqRegionOptional.orElseThrow()); + } + genomeFragment.setStart(transcriptDTO.getStart()); + genomeFragment.setEnd(transcriptDTO.getEnd()); + genomeFragment.setStrand(transcriptDTO.getStrand()); + genomeFragment.setType(GenomeFragmentType.GENE); + genomeFragmentService.save(genomeFragment); + + transcriptDTO.getExons().stream().forEach(exon -> exon.setTranscript(savedTranscript)); + genomeFragmentService.saveAll(transcriptDTO.getExons()); + transcriptDTO.getUtrs().stream().forEach(utr -> utr.setTranscript(savedTranscript)); + genomeFragmentService.saveAll(transcriptDTO.getUtrs()); + + // save sequence automatically when a new transcript saved + Optional sequenceOptional = sequenceService.findOneByTranscriptAndSequenceType(savedTranscript, SequenceType.PROTEIN); + if (sequenceOptional.isEmpty() && StringUtils.isNotEmpty(savedTranscript.getEnsemblProteinId())) { + Optional ensemblSequenceOptional = ensemblService.getProteinSequence( + savedTranscript.getEnsemblGene().getReferenceGenome(), + savedTranscript.getEnsemblProteinId() + ); + if (ensemblSequenceOptional.isPresent()) { + Sequence sequence = new Sequence(); + sequence.setTranscript(savedTranscript); + sequence.setSequenceType(SequenceType.PROTEIN); + sequence.setSequence(ensemblSequenceOptional.orElseThrow().getSeq()); + sequenceService.save(sequence); + } + } + clearTranscriptCaches(); + return transcriptMapper.toDto(savedTranscript); + } + + public Transcript save(Transcript transcript) { + log.debug("Request to save Transcript : {}", transcript); + return transcriptRepository.save(transcript); + } + + /** + * Partially update a transcript. + * + * @param transcriptDTO the entity to update partially. + * @return the persisted entity. + */ + public Optional partialUpdate(TranscriptDTO transcriptDTO) { + log.debug("Request to partially update Transcript : {}", transcriptDTO); + + return transcriptRepository + .findById(transcriptDTO.getId()) + .map(existingTranscript -> { + transcriptMapper.partialUpdate(existingTranscript, transcriptDTO); + + return existingTranscript; + }) + .map(transcriptRepository::save) + .map(transcriptMapper::toDto); + } + + /** + * Get all the transcripts. + * + * @param pageable the pagination information. + * @return the list of entities. + */ + @Transactional(readOnly = true) + public Page findAllWithEagerRelationships(Pageable pageable) { + log.debug("Request to get all Transcripts"); + Page transcriptPage = transcriptRepository.findAll(pageable); + List transcriptDTOS = transcriptRepository + .findAllWithEagerRelationships(transcriptPage.getContent().stream().map(Transcript::getId).collect(Collectors.toList())) + .stream() + .map(transcriptMapper::toDto) + .collect(Collectors.toList()); + return new PageImpl<>(transcriptDTOS, pageable, transcriptPage.getTotalElements()); + } + + @Transactional(readOnly = true) + public List findAllWithEagerRelationshipsByIdIn(List ids) { + return transcriptRepository + .findAllWithEagerRelationships(ids) + .stream() + .sorted(Comparator.comparingInt(o -> ids.indexOf(o.getId()))) + .map(transcriptMapper::toDto) + .collect(Collectors.toList()); + } + + /** + * Get one transcript by id. + * + * @param id the id of the entity. + * @return the entity. + */ + @Transactional(readOnly = true) + public Optional findOne(Long id) { + log.debug("Request to get Transcript : {}", id); + return transcriptRepository.findById(id).map(transcriptMapper::toDto); + } + + /** + * Delete the transcript by id. + * + * @param id the id of the entity. + */ + public void delete(Long id) { + log.debug("Request to delete Transcript : {}", id); + transcriptRepository.deleteById(id); + } + + public Optional findByEnsemblGeneAndEnsemblTranscriptId(EnsemblGene ensemblGene, String ensembleTranscriptId) { + log.debug( + "Request to get transcript by ensembl gene and transcript id : {} {} {}", + ensemblGene.getReferenceGenome(), + ensemblGene.getEnsemblGeneId(), + ensembleTranscriptId + ); + Optional transcriptOptional = transcriptRepository.findByEnsemblGeneAndEnsemblTranscriptId( + ensemblGene, + ensembleTranscriptId + ); + if (transcriptOptional.isPresent()) { + return Optional.of(transcriptMapper.toDto(transcriptOptional.orElseThrow())); + } else { + return Optional.empty(); + } + } + + public Optional findByEnsemblGeneAndCanonicalIsTrue(EnsemblGene ensemblGene) { + log.debug( + "Request to find canonical transcript for given ensembl gene : {} {}", + ensemblGene.getReferenceGenome(), + ensemblGene.getEnsemblGeneId() + ); + Optional transcriptOptional = transcriptRepository.findByEnsemblGeneAndCanonicalIsTrue(ensemblGene); + return transcriptOptional.map(transcriptMapper::toDto); + } + + public Optional findByGeneAndReferenceGenomeAndCanonicalIsTrue(Gene gene, ReferenceGenome referenceGenome) { + log.debug("Request to find canonical transcript for given gene : {} {}", gene.getHugoSymbol(), referenceGenome); + Optional transcriptOptional = transcriptRepository.findByGeneAndReferenceGenomeAndCanonicalIsTrue( + gene, + referenceGenome + ); + return transcriptOptional.map(transcriptMapper::toDto); + } + + /** + * Get trancript by reference genome and ensembleTranscriptId + * + * @param referenceGenome + * @param ensembleTranscriptId + * @return + */ + @Transactional(readOnly = true) + public Optional findByReferenceGenomeAndEnsemblTranscriptId( + ReferenceGenome referenceGenome, + String ensembleTranscriptId + ) { + log.debug("Request to get Sequence : {}", ensembleTranscriptId); + Optional transcriptOptional = transcriptRepository.findByReferenceGenomeAndEnsemblTranscriptId( + referenceGenome, + ensembleTranscriptId + ); + if (transcriptOptional.isPresent()) { + return Optional.of(transcriptMapper.toDto(transcriptOptional.orElseThrow())); + } else { + return Optional.empty(); + } + } + + @Transactional(readOnly = true) + public List findByReferenceGenomeAndEnsemblTranscriptIdIsIn( + ReferenceGenome referenceGenome, + List ensemblTranscriptIds + ) { + return transcriptRepository + .findByReferenceGenomeAndEnsemblTranscriptIdIsIn(referenceGenome.name(), ensemblTranscriptIds) + .stream() + .map(transcriptMapper::toDto) + .collect(Collectors.toList()); + } + + @Transactional(readOnly = true) + public List findByEnsemblGene(EnsemblGene ensemblGene) { + return transcriptMapper.toDto(transcriptRepository.findByEnsemblGene(ensemblGene)); + } + + @Transactional(readOnly = true) + public List findByEntrezGeneIdAndReferenceGenome(Integer entrezGeneId, ReferenceGenome referenceGenome) { + return transcriptRepository.findByEntrezGeneIdAndReferenceGenome(entrezGeneId, referenceGenome); + } + + public List getTranscriptsWithMatchedResidue( + ReferenceGenome referenceGenome, + List transcripts, + int proteinPosition, + String expectedAllele + ) { + return transcripts + .stream() + .filter(ensemblTranscript -> StringUtils.isNotEmpty(ensemblTranscript.getProteinId())) + .filter(ensemblTranscript -> { + Optional sequenceOptional = ensemblService.getProteinSequence( + referenceGenome, + ensemblTranscript.getProteinId() + ); + if (sequenceOptional.isPresent()) { + if (sequenceOptional.orElseThrow().getSeq().length() >= proteinPosition) { + return sequenceOptional + .orElseThrow() + .getSeq() + .substring(proteinPosition - 1, proteinPosition) + .equals(expectedAllele); + } else { + return false; + } + } else { + return false; + } + }) + .collect(Collectors.toList()); + } + + public ClustalOResp alignTranscripts(List transcriptToCompare) throws InterruptedException { + List transcripts = findAllWithEagerRelationshipsByIdIn(transcriptToCompare); + StringBuilder sb = new StringBuilder(); + for (TranscriptDTO transcript : transcripts) { + Optional sequenceOptional = sequenceService.findOneByTranscriptAndSequenceType( + transcriptMapper.toEntity(transcript), + SequenceType.PROTEIN + ); + if (sequenceOptional.isPresent()) { + sb.append(">"); + sb.append(transcript.getEnsemblGene().getReferenceGenome()); + sb.append("_"); + sb.append(transcript.getEnsemblTranscriptId()); + sb.append("\n"); + sb.append(sequenceOptional.orElseThrow().getSequence()); + sb.append("\n"); + } + } + return ebiService.alignUsingClustalO(sb.toString()); + } + + public TranscriptMatchResultVM matchTranscript(TranscriptPairVM transcript, ReferenceGenome referenceGenome, String hugoSymbol) { + // Find whether both transcript length are the same + Optional _ensemblTranscriptOptional = Optional.empty(); + try { + _ensemblTranscriptOptional = getEnsemblTranscript(hugoSymbol, transcript); + } catch (ApiException e) { + e.printStackTrace(); + } + TranscriptMatchResultVM transcriptMatchResultVM = new TranscriptMatchResultVM(); + + if (_ensemblTranscriptOptional.isPresent()) { + transcriptMatchResultVM.setOriginalEnsemblTranscript(_ensemblTranscriptOptional.orElseThrow()); + Optional _sequenceOptional = ensemblService.getProteinSequence( + transcript.getReferenceGenome(), + _ensemblTranscriptOptional.orElseThrow().getProteinId() + ); + if (_sequenceOptional.isPresent()) { + List targetEnsemblTranscripts = getEnsemblTranscriptList(hugoSymbol, referenceGenome); + if (targetEnsemblTranscripts.size() == 0) { + transcriptMatchResultVM.setNote("The target reference genome does not have any ensembl transcripts."); + } else { + try { + pickEnsemblTranscript( + transcriptMatchResultVM, + referenceGenome, + targetEnsemblTranscripts, + _sequenceOptional.orElseThrow() + ); + } catch (Exception exception) { + transcriptMatchResultVM.setNote(exception.getMessage()); + } + } + } else { + transcriptMatchResultVM.setNote("The transcript is invalid"); + } + } else { + transcriptMatchResultVM.setNote("The transcript is invalid"); + } + return transcriptMatchResultVM; + } + + public Optional getEnsemblTranscript(String transcriptId, ReferenceGenome referenceGenome) { + EnsemblControllerApi controllerApi = genomeNexusService.getEnsemblControllerApi(referenceGenome); + try { + EnsemblTranscript ensemblTranscript = controllerApi.fetchEnsemblTranscriptByTranscriptIdGET(transcriptId); + return ensemblTranscript == null ? Optional.empty() : Optional.of(ensemblTranscript); + } catch (Exception e) { + e.printStackTrace(); + return Optional.empty(); + } + } + + public List getEnsemblTranscriptList(String hugoSymbol, ReferenceGenome referenceGenome) { + EnsemblControllerApi controllerApi = genomeNexusService.getEnsemblControllerApi(referenceGenome); + Set transcripts = new LinkedHashSet<>(); + try { + transcripts.add(getCanonicalEnsemblTranscript(hugoSymbol, referenceGenome)); + } catch (ApiException e) { + e.printStackTrace(); + } + try { + transcripts.addAll(controllerApi.fetchEnsemblTranscriptsGET(null, null, hugoSymbol)); + } catch (ApiException e) { + e.printStackTrace(); + } + return new ArrayList<>(transcripts); + } + + public EnsemblTranscript getCanonicalEnsemblTranscript(String hugoSymbol, ReferenceGenome referenceGenome) throws ApiException { + EnsemblControllerApi controllerApi = genomeNexusService.getEnsemblControllerApi(referenceGenome); + return controllerApi.fetchCanonicalEnsemblTranscriptByHugoSymbolGET(hugoSymbol, "msk"); + } + + public Optional getEnsemblTranscript(String hugoSymbol, TranscriptPairVM transcriptPairVM) throws ApiException { + return getEnsemblTranscriptList(hugoSymbol, transcriptPairVM.getReferenceGenome()) + .stream() + .filter( + ensemblTranscript -> + !StringUtils.isEmpty(ensemblTranscript.getTranscriptId()) && + ensemblTranscript.getTranscriptId().equalsIgnoreCase(transcriptPairVM.getTranscript()) + ) + .findFirst(); + } + + /** + * Get a list of transcripts from ensembl.org + * + * @param referenceGenome Reference Genome + * @param ids a list of transcript/gene ids that need to be searched + * @return a lit of expanded ensembl transcripts with exon/utr info + */ + public List getEnsemblTranscriptIds( + ReferenceGenome referenceGenome, + List ids, + boolean includeUtr, + boolean expand + ) { + List ensemblTranscriptList = new ArrayList<>(); + log.info("Get {} ensembl transcript ids", ids.size()); + for (int i = 0; i < ids.size(); i += ENSEMBL_POST_THRESHOLD) { + log.info("\tIndex {}", i); + ensemblTranscriptList.addAll( + ensemblService.getIds( + referenceGenome, + ids.subList(i, Math.min(ids.toArray().length, i + ENSEMBL_POST_THRESHOLD)), + includeUtr, + expand + ) + ); + } + return ensemblTranscriptList; + } + + private TranscriptMatchResultVM pickEnsemblTranscript( + TranscriptMatchResultVM transcriptMatchResultVM, + ReferenceGenome referenceGenome, + List availableTranscripts, + EnsemblSequence sequence + ) { + List sameLengthList = availableTranscripts + .stream() + .filter( + ensemblTranscript -> + ensemblTranscript.getProteinLength() != null && ensemblTranscript.getProteinLength().equals(sequence.getSeq().length()) + ) + .collect(Collectors.toList()); + + List sequences = ensemblService + .getProteinSequences(referenceGenome, sameLengthList.stream().map(EnsemblTranscript::getProteinId).collect(Collectors.toList())) + .stream() + .filter(filteredSequence -> filteredSequence.getSeq().length() == sequence.getSeq().length()) + .collect(Collectors.toList()); + Optional sequenceSameOptional = sequences + .stream() + .filter(matchedSequence -> matchedSequence.getSeq().equals(sequence.getSeq())) + .findAny(); + + if (sequenceSameOptional.isPresent()) { + Optional ensemblTranscriptOptional = getEnsemblTranscriptBySequence( + sameLengthList, + sequenceSameOptional.orElseThrow() + ); + transcriptMatchResultVM.setTargetEnsemblTranscript(ensemblTranscriptOptional.orElseThrow()); + transcriptMatchResultVM.setNote("Same sequence"); + } else if (sequences.size() > 0) { + // We should make some comparison with the original sequence for the same length + sequences.sort(Comparator.comparingInt(s -> getNumOfMismatchSameLengthSequences(sequence.getSeq(), s.getSeq()).size())); + EnsemblSequence pickedSequence = sequences.iterator().next(); + + Optional ensemblTranscriptOptional = getEnsemblTranscriptBySequence(availableTranscripts, pickedSequence); + transcriptMatchResultVM.setTargetEnsemblTranscript(ensemblTranscriptOptional.orElseThrow()); + List missMatchPairVMS = getNumOfMismatchSameLengthSequences(sequence.getSeq(), pickedSequence.getSeq()); + transcriptMatchResultVM.setNote( + "Same length, but mismatch: " + + missMatchPairVMS.size() + + ". " + + missMatchPairVMS + .stream() + .map( + missMatchPairVM -> + missMatchPairVM.getPosition() + + "(" + + missMatchPairVM.getReferenceAllele() + + "," + + missMatchPairVM.getTargetAlelel() + + ")" + ) + .collect(Collectors.joining(", ")) + ); + } else { + // we want to see whether there is any transcript includes the original sequence + List longerOnes = availableTranscripts + .stream() + .filter( + ensemblTranscript -> + ensemblTranscript.getProteinLength() != null && ensemblTranscript.getProteinLength() > sequence.getSeq().length() + ) + .collect(Collectors.toList()); + + List longerSequences = ensemblService.getProteinSequences( + referenceGenome, + longerOnes.stream().map(EnsemblTranscript::getProteinId).collect(Collectors.toList()) + ); + List sequencesContains = longerSequences + .stream() + .filter(matchedSequence -> matchedSequence.getSeq().contains(sequence.getSeq())) + .collect(Collectors.toList()); + sequencesContains.sort((s1, s2) -> s2.getSeq().length() - s1.getSeq().length()); + + if (sequencesContains.size() > 0) { + EnsemblSequence pickedSequence = sequencesContains.iterator().next(); + Optional ensemblTranscriptOptional = getEnsemblTranscriptBySequence(longerOnes, pickedSequence); + transcriptMatchResultVM.setTargetEnsemblTranscript(ensemblTranscriptOptional.orElseThrow()); + transcriptMatchResultVM.setNote("Longer one found, length: " + ensemblTranscriptOptional.orElseThrow().getProteinLength()); + } else { + transcriptMatchResultVM.setNote("No matched sequence found"); + } + } + return transcriptMatchResultVM; + } + + public List getAlignmentResult( + ReferenceGenome refReferenceGenome, + EnsemblTranscript refEnsemblTranscript, + ReferenceGenome targetReferenceGenome, + List targetTranscripts + ) { + Optional refSequenceOptional = ensemblService.getProteinSequence( + refReferenceGenome, + refEnsemblTranscript.getProteinId() + ); + if (refSequenceOptional.isPresent()) { + return targetTranscripts + .stream() + .filter(ensemblTranscript -> StringUtils.isNotEmpty(ensemblTranscript.getProteinId())) + .map(ensemblTranscript -> { + Optional targetSequenceOptional = ensemblService.getProteinSequence( + targetReferenceGenome, + ensemblTranscript.getProteinId() + ); + if (targetSequenceOptional.isPresent()) { + AlignmentResult alignmentResult = + this.alignmentService.calcOptimalAlignment( + refSequenceOptional.orElseThrow().getSeq(), + targetSequenceOptional.orElseThrow().getSeq(), + true + ); + EnrichedAlignmentResult enrichedAlignmentResult = new EnrichedAlignmentResult(alignmentResult); + enrichedAlignmentResult.setRefEnsemblTranscript(refEnsemblTranscript); + enrichedAlignmentResult.setTargetEnsemblTranscript(ensemblTranscript); + return Optional.of(enrichedAlignmentResult); + } else { + Optional optional = Optional.empty(); + return optional; + } + }) + .filter(Optional::isPresent) + .map(Optional::get) + .sorted(Comparator.comparingInt(EnrichedAlignmentResult::getPenalty)) + .collect(Collectors.toList()); + } else { + return new ArrayList<>(); + } + } + + private Optional getEnsemblTranscriptBySequence( + List availableEnsemblTranscripts, + EnsemblSequence sequence + ) { + return availableEnsemblTranscripts + .stream() + .filter(ensemblTranscript -> { + if (ensemblTranscript.getProteinId() != null && ensemblTranscript.getProteinId().equals(sequence.getId())) { + return true; + } else { + return false; + } + }) + .findAny(); + } + + private List getNumOfMismatchSameLengthSequences(String reference, String newSequence) { + List mismatch = new ArrayList<>(); + for (int i = 0; i < reference.length(); i++) { + char r = reference.charAt(i); + char n = newSequence.charAt(i); + if (r != n) { + MissMatchPairVM missMatchPairVM = new MissMatchPairVM(); + missMatchPairVM.setPosition(i); + missMatchPairVM.setReferenceAllele(r); + missMatchPairVM.setTargetAlelel(n); + mismatch.add(missMatchPairVM); + } + } + return mismatch; + } + + private void clearTranscriptCaches() { + if (this.optionalCacheManager.isPresent()) { + for (String cacheKey : this.optionalCacheManager.orElseThrow().getCacheNames()) { + String cacheKeyPrefix = this.cacheNameResolver.getCacheName(CacheCategory.TRANSCRIPT, ""); + if (cacheKey.startsWith(cacheKeyPrefix)) { + Objects.requireNonNull(this.optionalCacheManager.orElseThrow().getCache(cacheKey)).clear(); + } + } + } + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/UserService.java b/src/main/java/org/mskcc/oncokb/curation/service/UserService.java new file mode 100644 index 000000000..d67bee1ce --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/UserService.java @@ -0,0 +1,220 @@ +package org.mskcc.oncokb.curation.service; + +import com.google.gson.Gson; +import java.util.*; +import java.util.stream.Collectors; +import org.mskcc.oncokb.curation.config.Constants; +import org.mskcc.oncokb.curation.config.cache.CacheCategory; +import org.mskcc.oncokb.curation.config.cache.CacheNameResolver; +import org.mskcc.oncokb.curation.domain.Authority; +import org.mskcc.oncokb.curation.domain.User; +import org.mskcc.oncokb.curation.repository.AuthorityRepository; +import org.mskcc.oncokb.curation.repository.UserRepository; +import org.mskcc.oncokb.curation.service.dto.KeycloakUserDTO; +import org.mskcc.oncokb.curation.service.dto.UserDTO; +import org.mskcc.oncokb.curation.service.mapper.UserMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cache.CacheManager; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; +import org.springframework.security.oauth2.core.oidc.user.OidcUser; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * Service class for managing users. + */ +@Service +@Transactional +public class UserService { + + private final Logger log = LoggerFactory.getLogger(UserService.class); + + private final UserRepository userRepository; + + private final AuthorityRepository authorityRepository; + + private final UserMapper userMapper; + + private final CacheNameResolver cacheNameResolver; + + private final Optional optionalCacheManager; + + public UserService( + UserRepository userRepository, + AuthorityRepository authorityRepository, + UserMapper userMapper, + CacheNameResolver cacheNameResolver, + Optional optionalCacheManager + ) { + this.userRepository = userRepository; + this.authorityRepository = authorityRepository; + this.userMapper = userMapper; + this.cacheNameResolver = cacheNameResolver; + this.optionalCacheManager = optionalCacheManager; + } + + public User createUser(UserDTO userDTO) { + User user = new User(); + user.setLogin(userDTO.getEmail().toLowerCase()); + user.setFirstName(userDTO.getFirstName()); + user.setLastName(userDTO.getLastName()); + if (userDTO.getEmail() != null) { + user.setEmail(userDTO.getEmail().toLowerCase()); + } + user.setImageUrl(userDTO.getImageUrl()); + if (userDTO.getLangKey() == null) { + user.setLangKey(Constants.DEFAULT_LANGUAGE); // default language + } else { + user.setLangKey(userDTO.getLangKey()); + } + user.setActivated(userDTO.isActivated()); + if (userDTO.getAuthorities() != null) { + Set authorities = userDTO + .getAuthorities() + .stream() + .map(authorityRepository::findById) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(Collectors.toSet()); + user.setAuthorities(authorities); + } + userRepository.save(user); + this.clearUserCaches(user); + log.debug("Created Information for User: {}", user); + return user; + } + + /** + * Update all information for a specific user, and return the modified user. + * + * @param userDTO user to update. + * @return updated user. + */ + public Optional updateUser(UserDTO userDTO) { + return Optional.of(userRepository.findById(userDTO.getId())) + .filter(Optional::isPresent) + .map(Optional::get) + .map(user -> { + this.clearUserCaches(user); + user.setLogin(userDTO.getLogin().toLowerCase()); + user.setFirstName(userDTO.getFirstName()); + user.setLastName(userDTO.getLastName()); + if (userDTO.getEmail() != null) { + user.setEmail(userDTO.getEmail().toLowerCase()); + } + user.setImageUrl(userDTO.getImageUrl()); + user.setActivated(userDTO.isActivated()); + user.setLangKey(userDTO.getLangKey()); + Set managedAuthorities = user.getAuthorities(); + managedAuthorities.clear(); + userDTO + .getAuthorities() + .stream() + .map(authorityRepository::findById) + .filter(Optional::isPresent) + .map(Optional::get) + .forEach(managedAuthorities::add); + this.clearUserCaches(user); + log.debug("Changed Information for User: {}", user); + return user; + }) + .map(UserDTO::new); + } + + @Transactional(readOnly = true) + public List getAllManagedUsers() { + return userMapper.usersToUserDTOs(userRepository.findAll()); + } + + @Transactional(readOnly = true) + public Optional getUserWithAuthoritiesByLogin(String login) { + return userRepository.findOneWithAuthoritiesByLogin(login); + } + + /** + * Gets a list of all the authorities. + * @return a list of all the authorities. + */ + @Transactional(readOnly = true) + public List getAuthorities() { + return authorityRepository.findAll().stream().map(Authority::getName).collect(Collectors.toList()); + } + + /** + * Returns the user from an OAuth 2.0 login or jwt token. + * + * @param authToken the authentication token. + * @return the user from the authentication. + */ + @Transactional + public Optional getUserFromAuthentication(AbstractAuthenticationToken authToken) { + if (authToken instanceof UsernamePasswordAuthenticationToken) { // Our custom JWT + Optional userOptional = userRepository.findOneByLogin(authToken.getName()); + if (userOptional.isPresent()) { + return Optional.of(userMapper.userToUserDTO(userOptional.orElseThrow())); + } + return Optional.empty(); + } + + Map attributes; + if (authToken instanceof OAuth2AuthenticationToken) { // Spring oauth2 + return findOneByEmailIgnoreCase(((OidcUser) authToken.getPrincipal()).getEmail()); + } else { + throw new IllegalArgumentException("AuthenticationToken is not OAuth2 or JWT!"); + } + } + + @Transactional(readOnly = true) + public Optional findOneByEmailIgnoreCase(String email) { + Optional optionalUser = userRepository.findOneByEmailIgnoreCase(email); + if (optionalUser.isPresent()) { + return Optional.of(userMapper.userToUserDTO(optionalUser.orElseThrow())); + } + return Optional.empty(); + } + + /** + * Extracts the authorities from the authentication token + * @param authToken the authentication token + * @return set of authorities + */ + private static Set getAuthoritiesFromAuthToken(AbstractAuthenticationToken authToken) { + return authToken + .getAuthorities() + .stream() + .map(GrantedAuthority::getAuthority) + .map(authority -> { + Authority auth = new Authority(); + auth.setName(authority); + return auth; + }) + .collect(Collectors.toSet()); + } + + public void deleteUser(String login) { + userRepository + .findOneByLogin(login) + .ifPresent(user -> { + userRepository.delete(user); + this.clearUserCaches(user); + log.debug("Deleted User: {}", user); + }); + } + + private void clearUserCaches(User user) { + if (this.optionalCacheManager.isPresent()) { + for (String cacheKey : this.optionalCacheManager.orElseThrow().getCacheNames()) { + String cacheKeyPrefix = this.cacheNameResolver.getCacheName(CacheCategory.USER, ""); + if (cacheKey.startsWith(cacheKeyPrefix)) { + Objects.requireNonNull(this.optionalCacheManager.orElseThrow().getCache(cacheKey)).clear(); + } + } + } + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/UsernameAlreadyUsedException.java b/src/main/java/org/mskcc/oncokb/curation/service/UsernameAlreadyUsedException.java new file mode 100644 index 000000000..b0c16bb73 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/UsernameAlreadyUsedException.java @@ -0,0 +1,10 @@ +package org.mskcc.oncokb.curation.service; + +public class UsernameAlreadyUsedException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public UsernameAlreadyUsedException() { + super("Login name already used!"); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/criteria/AlterationCriteria.java b/src/main/java/org/mskcc/oncokb/curation/service/criteria/AlterationCriteria.java new file mode 100644 index 000000000..85f1cd85a --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/criteria/AlterationCriteria.java @@ -0,0 +1,388 @@ +package org.mskcc.oncokb.curation.service.criteria; + +import java.io.Serializable; +import java.util.Objects; +import org.mskcc.oncokb.curation.domain.enumeration.AlterationType; +import tech.jhipster.service.Criteria; +import tech.jhipster.service.filter.BooleanFilter; +import tech.jhipster.service.filter.DoubleFilter; +import tech.jhipster.service.filter.Filter; +import tech.jhipster.service.filter.FloatFilter; +import tech.jhipster.service.filter.IntegerFilter; +import tech.jhipster.service.filter.LongFilter; +import tech.jhipster.service.filter.StringFilter; + +/** + * Criteria class for the {@link org.mskcc.oncokb.curation.domain.Alteration} entity. This class is used + * in {@link org.mskcc.oncokb.curation.web.rest.AlterationResource} to receive all the possible filtering options from + * the Http GET request parameters. + * For example the following could be a valid request: + * {@code /alterations?id.greaterThan=5&attr1.contains=something&attr2.specified=false} + * As Spring is unable to properly convert the types, unless specific {@link Filter} class are used, we need to use + * fix type specific filters. + */ +public class AlterationCriteria implements Serializable, Criteria { + + /** + * Class for filtering AlterationType + */ + public static class AlterationTypeFilter extends Filter { + + public AlterationTypeFilter() {} + + public AlterationTypeFilter(AlterationTypeFilter filter) { + super(filter); + } + + @Override + public AlterationTypeFilter copy() { + return new AlterationTypeFilter(this); + } + } + + private static final long serialVersionUID = 1L; + + private LongFilter id; + + private AlterationTypeFilter type; + + private StringFilter name; + + private StringFilter alteration; + + private StringFilter proteinChange; + + private IntegerFilter start; + + private IntegerFilter end; + + private StringFilter refResidues; + + private StringFilter variantResidues; + + private LongFilter flagId; + + private LongFilter geneId; + + private LongFilter transcriptId; + + private LongFilter consequenceId; + + private LongFilter associationId; + + private Boolean distinct; + + public AlterationCriteria() {} + + public AlterationCriteria(AlterationCriteria other) { + this.id = other.id == null ? null : other.id.copy(); + this.type = other.type == null ? null : other.type.copy(); + this.name = other.name == null ? null : other.name.copy(); + this.alteration = other.alteration == null ? null : other.alteration.copy(); + this.proteinChange = other.proteinChange == null ? null : other.proteinChange.copy(); + this.start = other.start == null ? null : other.start.copy(); + this.end = other.end == null ? null : other.end.copy(); + this.refResidues = other.refResidues == null ? null : other.refResidues.copy(); + this.variantResidues = other.variantResidues == null ? null : other.variantResidues.copy(); + this.flagId = other.flagId == null ? null : other.flagId.copy(); + this.geneId = other.geneId == null ? null : other.geneId.copy(); + this.transcriptId = other.transcriptId == null ? null : other.transcriptId.copy(); + this.consequenceId = other.consequenceId == null ? null : other.consequenceId.copy(); + this.associationId = other.associationId == null ? null : other.associationId.copy(); + this.distinct = other.distinct; + } + + @Override + public AlterationCriteria copy() { + return new AlterationCriteria(this); + } + + public LongFilter getId() { + return id; + } + + public LongFilter id() { + if (id == null) { + id = new LongFilter(); + } + return id; + } + + public void setId(LongFilter id) { + this.id = id; + } + + public AlterationTypeFilter getType() { + return type; + } + + public AlterationTypeFilter type() { + if (type == null) { + type = new AlterationTypeFilter(); + } + return type; + } + + public void setType(AlterationTypeFilter type) { + this.type = type; + } + + public StringFilter getName() { + return name; + } + + public StringFilter name() { + if (name == null) { + name = new StringFilter(); + } + return name; + } + + public void setName(StringFilter name) { + this.name = name; + } + + public StringFilter getAlteration() { + return alteration; + } + + public StringFilter alteration() { + if (alteration == null) { + alteration = new StringFilter(); + } + return alteration; + } + + public void setAlteration(StringFilter alteration) { + this.alteration = alteration; + } + + public StringFilter getProteinChange() { + return proteinChange; + } + + public StringFilter proteinChange() { + if (proteinChange == null) { + proteinChange = new StringFilter(); + } + return proteinChange; + } + + public void setProteinChange(StringFilter proteinChange) { + this.proteinChange = proteinChange; + } + + public IntegerFilter getStart() { + return start; + } + + public IntegerFilter start() { + if (start == null) { + start = new IntegerFilter(); + } + return start; + } + + public void setStart(IntegerFilter start) { + this.start = start; + } + + public IntegerFilter getEnd() { + return end; + } + + public IntegerFilter end() { + if (end == null) { + end = new IntegerFilter(); + } + return end; + } + + public void setEnd(IntegerFilter end) { + this.end = end; + } + + public StringFilter getRefResidues() { + return refResidues; + } + + public StringFilter refResidues() { + if (refResidues == null) { + refResidues = new StringFilter(); + } + return refResidues; + } + + public void setRefResidues(StringFilter refResidues) { + this.refResidues = refResidues; + } + + public StringFilter getVariantResidues() { + return variantResidues; + } + + public StringFilter variantResidues() { + if (variantResidues == null) { + variantResidues = new StringFilter(); + } + return variantResidues; + } + + public void setVariantResidues(StringFilter variantResidues) { + this.variantResidues = variantResidues; + } + + public LongFilter getFlagId() { + return flagId; + } + + public LongFilter flagId() { + if (flagId == null) { + flagId = new LongFilter(); + } + return flagId; + } + + public void setFlagId(LongFilter flagId) { + this.flagId = flagId; + } + + public LongFilter getGeneId() { + return geneId; + } + + public LongFilter geneId() { + if (geneId == null) { + geneId = new LongFilter(); + } + return geneId; + } + + public void setGeneId(LongFilter geneId) { + this.geneId = geneId; + } + + public LongFilter getTranscriptId() { + return transcriptId; + } + + public LongFilter transcriptId() { + if (transcriptId == null) { + transcriptId = new LongFilter(); + } + return transcriptId; + } + + public void setTranscriptId(LongFilter transcriptId) { + this.transcriptId = transcriptId; + } + + public LongFilter getConsequenceId() { + return consequenceId; + } + + public LongFilter consequenceId() { + if (consequenceId == null) { + consequenceId = new LongFilter(); + } + return consequenceId; + } + + public void setConsequenceId(LongFilter consequenceId) { + this.consequenceId = consequenceId; + } + + public LongFilter getAssociationId() { + return associationId; + } + + public LongFilter associationId() { + if (associationId == null) { + associationId = new LongFilter(); + } + return associationId; + } + + public void setAssociationId(LongFilter associationId) { + this.associationId = associationId; + } + + public Boolean getDistinct() { + return distinct; + } + + public void setDistinct(Boolean distinct) { + this.distinct = distinct; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final AlterationCriteria that = (AlterationCriteria) o; + return ( + Objects.equals(id, that.id) && + Objects.equals(type, that.type) && + Objects.equals(name, that.name) && + Objects.equals(alteration, that.alteration) && + Objects.equals(proteinChange, that.proteinChange) && + Objects.equals(start, that.start) && + Objects.equals(end, that.end) && + Objects.equals(refResidues, that.refResidues) && + Objects.equals(variantResidues, that.variantResidues) && + Objects.equals(flagId, that.flagId) && + Objects.equals(geneId, that.geneId) && + Objects.equals(transcriptId, that.transcriptId) && + Objects.equals(consequenceId, that.consequenceId) && + Objects.equals(associationId, that.associationId) && + Objects.equals(distinct, that.distinct) + ); + } + + @Override + public int hashCode() { + return Objects.hash( + id, + type, + name, + alteration, + proteinChange, + start, + end, + refResidues, + variantResidues, + flagId, + geneId, + transcriptId, + consequenceId, + associationId, + distinct + ); + } + + // prettier-ignore + @Override + public String toString() { + return "AlterationCriteria{" + + (id != null ? "id=" + id + ", " : "") + + (type != null ? "type=" + type + ", " : "") + + (name != null ? "name=" + name + ", " : "") + + (alteration != null ? "alteration=" + alteration + ", " : "") + + (proteinChange != null ? "proteinChange=" + proteinChange + ", " : "") + + (start != null ? "start=" + start + ", " : "") + + (end != null ? "end=" + end + ", " : "") + + (refResidues != null ? "refResidues=" + refResidues + ", " : "") + + (variantResidues != null ? "variantResidues=" + variantResidues + ", " : "") + + (flagId != null ? "flagId=" + flagId + ", " : "") + + (geneId != null ? "geneId=" + geneId + ", " : "") + + (transcriptId != null ? "transcriptId=" + transcriptId + ", " : "") + + (consequenceId != null ? "consequenceId=" + consequenceId + ", " : "") + + (associationId != null ? "associationId=" + associationId + ", " : "") + + (distinct != null ? "distinct=" + distinct + ", " : "") + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/criteria/ArticleCriteria.java b/src/main/java/org/mskcc/oncokb/curation/service/criteria/ArticleCriteria.java new file mode 100644 index 000000000..3b6978dfd --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/criteria/ArticleCriteria.java @@ -0,0 +1,273 @@ +package org.mskcc.oncokb.curation.service.criteria; + +import java.io.Serializable; +import java.util.Objects; +import org.mskcc.oncokb.curation.domain.enumeration.ArticleType; +import tech.jhipster.service.Criteria; +import tech.jhipster.service.filter.BooleanFilter; +import tech.jhipster.service.filter.DoubleFilter; +import tech.jhipster.service.filter.Filter; +import tech.jhipster.service.filter.FloatFilter; +import tech.jhipster.service.filter.InstantFilter; +import tech.jhipster.service.filter.IntegerFilter; +import tech.jhipster.service.filter.LongFilter; +import tech.jhipster.service.filter.StringFilter; + +/** + * Criteria class for the {@link org.mskcc.oncokb.curation.domain.Article} entity. This class is used + * in {@link org.mskcc.oncokb.curation.web.rest.ArticleResource} to receive all the possible filtering options from + * the Http GET request parameters. + * For example the following could be a valid request: + * {@code /articles?id.greaterThan=5&attr1.contains=something&attr2.specified=false} + * As Spring is unable to properly convert the types, unless specific {@link Filter} class are used, we need to use + * fix type specific filters. + */ +public class ArticleCriteria implements Serializable, Criteria { + + /** + * Class for filtering ArticleType + */ + public static class ArticleTypeFilter extends Filter { + + public ArticleTypeFilter() {} + + public ArticleTypeFilter(ArticleTypeFilter filter) { + super(filter); + } + + @Override + public ArticleTypeFilter copy() { + return new ArticleTypeFilter(this); + } + } + + private static final long serialVersionUID = 1L; + + private LongFilter id; + + private ArticleTypeFilter type; + + private StringFilter uid; + + private StringFilter link; + + private StringFilter authors; + + private InstantFilter date; + + private LongFilter flagId; + + private LongFilter synonymId; + + private LongFilter associationId; + + private Boolean distinct; + + public ArticleCriteria() {} + + public ArticleCriteria(ArticleCriteria other) { + this.id = other.id == null ? null : other.id.copy(); + this.type = other.type == null ? null : other.type.copy(); + this.uid = other.uid == null ? null : other.uid.copy(); + this.link = other.link == null ? null : other.link.copy(); + this.authors = other.authors == null ? null : other.authors.copy(); + this.date = other.date == null ? null : other.date.copy(); + this.flagId = other.flagId == null ? null : other.flagId.copy(); + this.synonymId = other.synonymId == null ? null : other.synonymId.copy(); + this.associationId = other.associationId == null ? null : other.associationId.copy(); + this.distinct = other.distinct; + } + + @Override + public ArticleCriteria copy() { + return new ArticleCriteria(this); + } + + public LongFilter getId() { + return id; + } + + public LongFilter id() { + if (id == null) { + id = new LongFilter(); + } + return id; + } + + public void setId(LongFilter id) { + this.id = id; + } + + public ArticleTypeFilter getType() { + return type; + } + + public ArticleTypeFilter type() { + if (type == null) { + type = new ArticleTypeFilter(); + } + return type; + } + + public void setType(ArticleTypeFilter type) { + this.type = type; + } + + public StringFilter getUid() { + return uid; + } + + public StringFilter uid() { + if (uid == null) { + uid = new StringFilter(); + } + return uid; + } + + public void setUid(StringFilter uid) { + this.uid = uid; + } + + public StringFilter getLink() { + return link; + } + + public StringFilter link() { + if (link == null) { + link = new StringFilter(); + } + return link; + } + + public void setLink(StringFilter link) { + this.link = link; + } + + public StringFilter getAuthors() { + return authors; + } + + public StringFilter authors() { + if (authors == null) { + authors = new StringFilter(); + } + return authors; + } + + public void setAuthors(StringFilter authors) { + this.authors = authors; + } + + public InstantFilter getDate() { + return date; + } + + public InstantFilter date() { + if (date == null) { + date = new InstantFilter(); + } + return date; + } + + public void setDate(InstantFilter date) { + this.date = date; + } + + public LongFilter getFlagId() { + return flagId; + } + + public LongFilter flagId() { + if (flagId == null) { + flagId = new LongFilter(); + } + return flagId; + } + + public void setFlagId(LongFilter flagId) { + this.flagId = flagId; + } + + public LongFilter getSynonymId() { + return synonymId; + } + + public LongFilter synonymId() { + if (synonymId == null) { + synonymId = new LongFilter(); + } + return synonymId; + } + + public void setSynonymId(LongFilter synonymId) { + this.synonymId = synonymId; + } + + public LongFilter getAssociationId() { + return associationId; + } + + public LongFilter associationId() { + if (associationId == null) { + associationId = new LongFilter(); + } + return associationId; + } + + public void setAssociationId(LongFilter associationId) { + this.associationId = associationId; + } + + public Boolean getDistinct() { + return distinct; + } + + public void setDistinct(Boolean distinct) { + this.distinct = distinct; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final ArticleCriteria that = (ArticleCriteria) o; + return ( + Objects.equals(id, that.id) && + Objects.equals(type, that.type) && + Objects.equals(uid, that.uid) && + Objects.equals(link, that.link) && + Objects.equals(authors, that.authors) && + Objects.equals(date, that.date) && + Objects.equals(flagId, that.flagId) && + Objects.equals(synonymId, that.synonymId) && + Objects.equals(associationId, that.associationId) && + Objects.equals(distinct, that.distinct) + ); + } + + @Override + public int hashCode() { + return Objects.hash(id, type, uid, link, authors, date, flagId, synonymId, associationId, distinct); + } + + // prettier-ignore + @Override + public String toString() { + return "ArticleCriteria{" + + (id != null ? "id=" + id + ", " : "") + + (type != null ? "type=" + type + ", " : "") + + (uid != null ? "uid=" + uid + ", " : "") + + (link != null ? "link=" + link + ", " : "") + + (authors != null ? "authors=" + authors + ", " : "") + + (date != null ? "date=" + date + ", " : "") + + (flagId != null ? "flagId=" + flagId + ", " : "") + + (synonymId != null ? "synonymId=" + synonymId + ", " : "") + + (associationId != null ? "associationId=" + associationId + ", " : "") + + (distinct != null ? "distinct=" + distinct + ", " : "") + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/criteria/CancerTypeCriteria.java b/src/main/java/org/mskcc/oncokb/curation/service/criteria/CancerTypeCriteria.java new file mode 100644 index 000000000..602fdf73a --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/criteria/CancerTypeCriteria.java @@ -0,0 +1,346 @@ +package org.mskcc.oncokb.curation.service.criteria; + +import java.io.Serializable; +import java.util.Objects; +import org.mskcc.oncokb.curation.domain.enumeration.TumorForm; +import tech.jhipster.service.Criteria; +import tech.jhipster.service.filter.BooleanFilter; +import tech.jhipster.service.filter.DoubleFilter; +import tech.jhipster.service.filter.Filter; +import tech.jhipster.service.filter.FloatFilter; +import tech.jhipster.service.filter.IntegerFilter; +import tech.jhipster.service.filter.LongFilter; +import tech.jhipster.service.filter.StringFilter; + +/** + * Criteria class for the {@link org.mskcc.oncokb.curation.domain.CancerType} entity. This class is used + * in {@link org.mskcc.oncokb.curation.web.rest.CancerTypeResource} to receive all the possible filtering options from + * the Http GET request parameters. + * For example the following could be a valid request: + * {@code /cancer-types?id.greaterThan=5&attr1.contains=something&attr2.specified=false} + * As Spring is unable to properly convert the types, unless specific {@link Filter} class are used, we need to use + * fix type specific filters. + */ +public class CancerTypeCriteria implements Serializable, Criteria { + + /** + * Class for filtering TumorForm + */ + public static class TumorFormFilter extends Filter { + + public TumorFormFilter() {} + + public TumorFormFilter(TumorFormFilter filter) { + super(filter); + } + + @Override + public TumorFormFilter copy() { + return new TumorFormFilter(this); + } + } + + private static final long serialVersionUID = 1L; + + private LongFilter id; + + private StringFilter code; + + private StringFilter color; + + private IntegerFilter level; + + private StringFilter mainType; + + private StringFilter subtype; + + private StringFilter tissue; + + private TumorFormFilter tumorForm; + + private LongFilter childrenId; + + private LongFilter synonymId; + + private LongFilter parentId; + + private LongFilter associationId; + + private Boolean distinct; + + public CancerTypeCriteria() {} + + public CancerTypeCriteria(CancerTypeCriteria other) { + this.id = other.id == null ? null : other.id.copy(); + this.code = other.code == null ? null : other.code.copy(); + this.color = other.color == null ? null : other.color.copy(); + this.level = other.level == null ? null : other.level.copy(); + this.mainType = other.mainType == null ? null : other.mainType.copy(); + this.subtype = other.subtype == null ? null : other.subtype.copy(); + this.tissue = other.tissue == null ? null : other.tissue.copy(); + this.tumorForm = other.tumorForm == null ? null : other.tumorForm.copy(); + this.childrenId = other.childrenId == null ? null : other.childrenId.copy(); + this.synonymId = other.synonymId == null ? null : other.synonymId.copy(); + this.parentId = other.parentId == null ? null : other.parentId.copy(); + this.associationId = other.associationId == null ? null : other.associationId.copy(); + this.distinct = other.distinct; + } + + @Override + public CancerTypeCriteria copy() { + return new CancerTypeCriteria(this); + } + + public LongFilter getId() { + return id; + } + + public LongFilter id() { + if (id == null) { + id = new LongFilter(); + } + return id; + } + + public void setId(LongFilter id) { + this.id = id; + } + + public StringFilter getCode() { + return code; + } + + public StringFilter code() { + if (code == null) { + code = new StringFilter(); + } + return code; + } + + public void setCode(StringFilter code) { + this.code = code; + } + + public StringFilter getColor() { + return color; + } + + public StringFilter color() { + if (color == null) { + color = new StringFilter(); + } + return color; + } + + public void setColor(StringFilter color) { + this.color = color; + } + + public IntegerFilter getLevel() { + return level; + } + + public IntegerFilter level() { + if (level == null) { + level = new IntegerFilter(); + } + return level; + } + + public void setLevel(IntegerFilter level) { + this.level = level; + } + + public StringFilter getMainType() { + return mainType; + } + + public StringFilter mainType() { + if (mainType == null) { + mainType = new StringFilter(); + } + return mainType; + } + + public void setMainType(StringFilter mainType) { + this.mainType = mainType; + } + + public StringFilter getSubtype() { + return subtype; + } + + public StringFilter subtype() { + if (subtype == null) { + subtype = new StringFilter(); + } + return subtype; + } + + public void setSubtype(StringFilter subtype) { + this.subtype = subtype; + } + + public StringFilter getTissue() { + return tissue; + } + + public StringFilter tissue() { + if (tissue == null) { + tissue = new StringFilter(); + } + return tissue; + } + + public void setTissue(StringFilter tissue) { + this.tissue = tissue; + } + + public TumorFormFilter getTumorForm() { + return tumorForm; + } + + public TumorFormFilter tumorForm() { + if (tumorForm == null) { + tumorForm = new TumorFormFilter(); + } + return tumorForm; + } + + public void setTumorForm(TumorFormFilter tumorForm) { + this.tumorForm = tumorForm; + } + + public LongFilter getChildrenId() { + return childrenId; + } + + public LongFilter childrenId() { + if (childrenId == null) { + childrenId = new LongFilter(); + } + return childrenId; + } + + public void setChildrenId(LongFilter childrenId) { + this.childrenId = childrenId; + } + + public LongFilter getSynonymId() { + return synonymId; + } + + public LongFilter synonymId() { + if (synonymId == null) { + synonymId = new LongFilter(); + } + return synonymId; + } + + public void setSynonymId(LongFilter synonymId) { + this.synonymId = synonymId; + } + + public LongFilter getParentId() { + return parentId; + } + + public LongFilter parentId() { + if (parentId == null) { + parentId = new LongFilter(); + } + return parentId; + } + + public void setParentId(LongFilter parentId) { + this.parentId = parentId; + } + + public LongFilter getAssociationId() { + return associationId; + } + + public LongFilter associationId() { + if (associationId == null) { + associationId = new LongFilter(); + } + return associationId; + } + + public void setAssociationId(LongFilter associationId) { + this.associationId = associationId; + } + + public Boolean getDistinct() { + return distinct; + } + + public void setDistinct(Boolean distinct) { + this.distinct = distinct; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final CancerTypeCriteria that = (CancerTypeCriteria) o; + return ( + Objects.equals(id, that.id) && + Objects.equals(code, that.code) && + Objects.equals(color, that.color) && + Objects.equals(level, that.level) && + Objects.equals(mainType, that.mainType) && + Objects.equals(subtype, that.subtype) && + Objects.equals(tissue, that.tissue) && + Objects.equals(tumorForm, that.tumorForm) && + Objects.equals(childrenId, that.childrenId) && + Objects.equals(synonymId, that.synonymId) && + Objects.equals(parentId, that.parentId) && + Objects.equals(associationId, that.associationId) && + Objects.equals(distinct, that.distinct) + ); + } + + @Override + public int hashCode() { + return Objects.hash( + id, + code, + color, + level, + mainType, + subtype, + tissue, + tumorForm, + childrenId, + synonymId, + parentId, + associationId, + distinct + ); + } + + // prettier-ignore + @Override + public String toString() { + return "CancerTypeCriteria{" + + (id != null ? "id=" + id + ", " : "") + + (code != null ? "code=" + code + ", " : "") + + (color != null ? "color=" + color + ", " : "") + + (level != null ? "level=" + level + ", " : "") + + (mainType != null ? "mainType=" + mainType + ", " : "") + + (subtype != null ? "subtype=" + subtype + ", " : "") + + (tissue != null ? "tissue=" + tissue + ", " : "") + + (tumorForm != null ? "tumorForm=" + tumorForm + ", " : "") + + (childrenId != null ? "childrenId=" + childrenId + ", " : "") + + (synonymId != null ? "synonymId=" + synonymId + ", " : "") + + (parentId != null ? "parentId=" + parentId + ", " : "") + + (associationId != null ? "associationId=" + associationId + ", " : "") + + (distinct != null ? "distinct=" + distinct + ", " : "") + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/criteria/ClinicalTrialArmCriteria.java b/src/main/java/org/mskcc/oncokb/curation/service/criteria/ClinicalTrialArmCriteria.java new file mode 100644 index 000000000..56707f2f7 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/criteria/ClinicalTrialArmCriteria.java @@ -0,0 +1,154 @@ +package org.mskcc.oncokb.curation.service.criteria; + +import java.io.Serializable; +import java.util.Objects; +import tech.jhipster.service.Criteria; +import tech.jhipster.service.filter.BooleanFilter; +import tech.jhipster.service.filter.DoubleFilter; +import tech.jhipster.service.filter.Filter; +import tech.jhipster.service.filter.FloatFilter; +import tech.jhipster.service.filter.IntegerFilter; +import tech.jhipster.service.filter.LongFilter; +import tech.jhipster.service.filter.StringFilter; + +/** + * Criteria class for the {@link org.mskcc.oncokb.curation.domain.ClinicalTrialArm} entity. This class is used + * in {@link org.mskcc.oncokb.curation.web.rest.ClinicalTrialArmResource} to receive all the possible filtering options from + * the Http GET request parameters. + * For example the following could be a valid request: + * {@code /clinical-trial-arms?id.greaterThan=5&attr1.contains=something&attr2.specified=false} + * As Spring is unable to properly convert the types, unless specific {@link Filter} class are used, we need to use + * fix type specific filters. + */ +public class ClinicalTrialArmCriteria implements Serializable, Criteria { + + private static final long serialVersionUID = 1L; + + private LongFilter id; + + private StringFilter name; + + private LongFilter associationId; + + private LongFilter clinicalTrialId; + + private Boolean distinct; + + public ClinicalTrialArmCriteria() {} + + public ClinicalTrialArmCriteria(ClinicalTrialArmCriteria other) { + this.id = other.id == null ? null : other.id.copy(); + this.name = other.name == null ? null : other.name.copy(); + this.associationId = other.associationId == null ? null : other.associationId.copy(); + this.clinicalTrialId = other.clinicalTrialId == null ? null : other.clinicalTrialId.copy(); + this.distinct = other.distinct; + } + + @Override + public ClinicalTrialArmCriteria copy() { + return new ClinicalTrialArmCriteria(this); + } + + public LongFilter getId() { + return id; + } + + public LongFilter id() { + if (id == null) { + id = new LongFilter(); + } + return id; + } + + public void setId(LongFilter id) { + this.id = id; + } + + public StringFilter getName() { + return name; + } + + public StringFilter name() { + if (name == null) { + name = new StringFilter(); + } + return name; + } + + public void setName(StringFilter name) { + this.name = name; + } + + public LongFilter getAssociationId() { + return associationId; + } + + public LongFilter associationId() { + if (associationId == null) { + associationId = new LongFilter(); + } + return associationId; + } + + public void setAssociationId(LongFilter associationId) { + this.associationId = associationId; + } + + public LongFilter getClinicalTrialId() { + return clinicalTrialId; + } + + public LongFilter clinicalTrialId() { + if (clinicalTrialId == null) { + clinicalTrialId = new LongFilter(); + } + return clinicalTrialId; + } + + public void setClinicalTrialId(LongFilter clinicalTrialId) { + this.clinicalTrialId = clinicalTrialId; + } + + public Boolean getDistinct() { + return distinct; + } + + public void setDistinct(Boolean distinct) { + this.distinct = distinct; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final ClinicalTrialArmCriteria that = (ClinicalTrialArmCriteria) o; + return ( + Objects.equals(id, that.id) && + Objects.equals(name, that.name) && + Objects.equals(associationId, that.associationId) && + Objects.equals(clinicalTrialId, that.clinicalTrialId) && + Objects.equals(distinct, that.distinct) + ); + } + + @Override + public int hashCode() { + return Objects.hash(id, name, associationId, clinicalTrialId, distinct); + } + + // prettier-ignore + @Override + public String toString() { + return "ClinicalTrialArmCriteria{" + + (id != null ? "id=" + id + ", " : "") + + (name != null ? "name=" + name + ", " : "") + + (associationId != null ? "associationId=" + associationId + ", " : "") + + (clinicalTrialId != null ? "clinicalTrialId=" + clinicalTrialId + ", " : "") + + (distinct != null ? "distinct=" + distinct + ", " : "") + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/criteria/ClinicalTrialCriteria.java b/src/main/java/org/mskcc/oncokb/curation/service/criteria/ClinicalTrialCriteria.java new file mode 100644 index 000000000..f4877efb4 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/criteria/ClinicalTrialCriteria.java @@ -0,0 +1,234 @@ +package org.mskcc.oncokb.curation.service.criteria; + +import java.io.Serializable; +import java.util.Objects; +import tech.jhipster.service.Criteria; +import tech.jhipster.service.filter.BooleanFilter; +import tech.jhipster.service.filter.DoubleFilter; +import tech.jhipster.service.filter.Filter; +import tech.jhipster.service.filter.FloatFilter; +import tech.jhipster.service.filter.IntegerFilter; +import tech.jhipster.service.filter.LongFilter; +import tech.jhipster.service.filter.StringFilter; + +/** + * Criteria class for the {@link org.mskcc.oncokb.curation.domain.ClinicalTrial} entity. This class is used + * in {@link org.mskcc.oncokb.curation.web.rest.ClinicalTrialResource} to receive all the possible filtering options from + * the Http GET request parameters. + * For example the following could be a valid request: + * {@code /clinical-trials?id.greaterThan=5&attr1.contains=something&attr2.specified=false} + * As Spring is unable to properly convert the types, unless specific {@link Filter} class are used, we need to use + * fix type specific filters. + */ +public class ClinicalTrialCriteria implements Serializable, Criteria { + + private static final long serialVersionUID = 1L; + + private LongFilter id; + + private StringFilter nctId; + + private StringFilter briefTitle; + + private StringFilter phase; + + private StringFilter status; + + private LongFilter clinicalTrialArmId; + + private LongFilter eligibilityCriteriaId; + + private LongFilter associationId; + + private Boolean distinct; + + public ClinicalTrialCriteria() {} + + public ClinicalTrialCriteria(ClinicalTrialCriteria other) { + this.id = other.id == null ? null : other.id.copy(); + this.nctId = other.nctId == null ? null : other.nctId.copy(); + this.briefTitle = other.briefTitle == null ? null : other.briefTitle.copy(); + this.phase = other.phase == null ? null : other.phase.copy(); + this.status = other.status == null ? null : other.status.copy(); + this.clinicalTrialArmId = other.clinicalTrialArmId == null ? null : other.clinicalTrialArmId.copy(); + this.eligibilityCriteriaId = other.eligibilityCriteriaId == null ? null : other.eligibilityCriteriaId.copy(); + this.associationId = other.associationId == null ? null : other.associationId.copy(); + this.distinct = other.distinct; + } + + @Override + public ClinicalTrialCriteria copy() { + return new ClinicalTrialCriteria(this); + } + + public LongFilter getId() { + return id; + } + + public LongFilter id() { + if (id == null) { + id = new LongFilter(); + } + return id; + } + + public void setId(LongFilter id) { + this.id = id; + } + + public StringFilter getNctId() { + return nctId; + } + + public StringFilter nctId() { + if (nctId == null) { + nctId = new StringFilter(); + } + return nctId; + } + + public void setNctId(StringFilter nctId) { + this.nctId = nctId; + } + + public StringFilter getBriefTitle() { + return briefTitle; + } + + public StringFilter briefTitle() { + if (briefTitle == null) { + briefTitle = new StringFilter(); + } + return briefTitle; + } + + public void setBriefTitle(StringFilter briefTitle) { + this.briefTitle = briefTitle; + } + + public StringFilter getPhase() { + return phase; + } + + public StringFilter phase() { + if (phase == null) { + phase = new StringFilter(); + } + return phase; + } + + public void setPhase(StringFilter phase) { + this.phase = phase; + } + + public StringFilter getStatus() { + return status; + } + + public StringFilter status() { + if (status == null) { + status = new StringFilter(); + } + return status; + } + + public void setStatus(StringFilter status) { + this.status = status; + } + + public LongFilter getClinicalTrialArmId() { + return clinicalTrialArmId; + } + + public LongFilter clinicalTrialArmId() { + if (clinicalTrialArmId == null) { + clinicalTrialArmId = new LongFilter(); + } + return clinicalTrialArmId; + } + + public void setClinicalTrialArmId(LongFilter clinicalTrialArmId) { + this.clinicalTrialArmId = clinicalTrialArmId; + } + + public LongFilter getEligibilityCriteriaId() { + return eligibilityCriteriaId; + } + + public LongFilter eligibilityCriteriaId() { + if (eligibilityCriteriaId == null) { + eligibilityCriteriaId = new LongFilter(); + } + return eligibilityCriteriaId; + } + + public void setEligibilityCriteriaId(LongFilter eligibilityCriteriaId) { + this.eligibilityCriteriaId = eligibilityCriteriaId; + } + + public LongFilter getAssociationId() { + return associationId; + } + + public LongFilter associationId() { + if (associationId == null) { + associationId = new LongFilter(); + } + return associationId; + } + + public void setAssociationId(LongFilter associationId) { + this.associationId = associationId; + } + + public Boolean getDistinct() { + return distinct; + } + + public void setDistinct(Boolean distinct) { + this.distinct = distinct; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final ClinicalTrialCriteria that = (ClinicalTrialCriteria) o; + return ( + Objects.equals(id, that.id) && + Objects.equals(nctId, that.nctId) && + Objects.equals(briefTitle, that.briefTitle) && + Objects.equals(phase, that.phase) && + Objects.equals(status, that.status) && + Objects.equals(clinicalTrialArmId, that.clinicalTrialArmId) && + Objects.equals(eligibilityCriteriaId, that.eligibilityCriteriaId) && + Objects.equals(associationId, that.associationId) && + Objects.equals(distinct, that.distinct) + ); + } + + @Override + public int hashCode() { + return Objects.hash(id, nctId, briefTitle, phase, status, clinicalTrialArmId, eligibilityCriteriaId, associationId, distinct); + } + + // prettier-ignore + @Override + public String toString() { + return "ClinicalTrialCriteria{" + + (id != null ? "id=" + id + ", " : "") + + (nctId != null ? "nctId=" + nctId + ", " : "") + + (briefTitle != null ? "briefTitle=" + briefTitle + ", " : "") + + (phase != null ? "phase=" + phase + ", " : "") + + (status != null ? "status=" + status + ", " : "") + + (clinicalTrialArmId != null ? "clinicalTrialArmId=" + clinicalTrialArmId + ", " : "") + + (eligibilityCriteriaId != null ? "eligibilityCriteriaId=" + eligibilityCriteriaId + ", " : "") + + (associationId != null ? "associationId=" + associationId + ", " : "") + + (distinct != null ? "distinct=" + distinct + ", " : "") + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/criteria/ClinicalTrialsGovConditionCriteria.java b/src/main/java/org/mskcc/oncokb/curation/service/criteria/ClinicalTrialsGovConditionCriteria.java new file mode 100644 index 000000000..1d052e50e --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/criteria/ClinicalTrialsGovConditionCriteria.java @@ -0,0 +1,134 @@ +package org.mskcc.oncokb.curation.service.criteria; + +import java.io.Serializable; +import java.util.Objects; +import tech.jhipster.service.Criteria; +import tech.jhipster.service.filter.BooleanFilter; +import tech.jhipster.service.filter.DoubleFilter; +import tech.jhipster.service.filter.Filter; +import tech.jhipster.service.filter.FloatFilter; +import tech.jhipster.service.filter.IntegerFilter; +import tech.jhipster.service.filter.LongFilter; +import tech.jhipster.service.filter.StringFilter; + +/** + * Criteria class for the {@link org.mskcc.oncokb.curation.domain.ClinicalTrialsGovCondition} entity. This class is used + * in {@link org.mskcc.oncokb.curation.web.rest.ClinicalTrialsGovConditionResource} to receive all the possible filtering options from + * the Http GET request parameters. + * For example the following could be a valid request: + * {@code /clinical-trials-gov-conditions?id.greaterThan=5&attr1.contains=something&attr2.specified=false} + * As Spring is unable to properly convert the types, unless specific {@link Filter} class are used, we need to use + * fix type specific filters. + */ +public class ClinicalTrialsGovConditionCriteria implements Serializable, Criteria { + + private static final long serialVersionUID = 1L; + + private LongFilter id; + + private StringFilter name; + + private LongFilter cancerTypeId; + + private Boolean distinct; + + public ClinicalTrialsGovConditionCriteria() {} + + public ClinicalTrialsGovConditionCriteria(ClinicalTrialsGovConditionCriteria other) { + this.id = other.id == null ? null : other.id.copy(); + this.name = other.name == null ? null : other.name.copy(); + this.cancerTypeId = other.cancerTypeId == null ? null : other.cancerTypeId.copy(); + this.distinct = other.distinct; + } + + @Override + public ClinicalTrialsGovConditionCriteria copy() { + return new ClinicalTrialsGovConditionCriteria(this); + } + + public LongFilter getId() { + return id; + } + + public LongFilter id() { + if (id == null) { + id = new LongFilter(); + } + return id; + } + + public void setId(LongFilter id) { + this.id = id; + } + + public StringFilter getName() { + return name; + } + + public StringFilter name() { + if (name == null) { + name = new StringFilter(); + } + return name; + } + + public void setName(StringFilter name) { + this.name = name; + } + + public LongFilter getCancerTypeId() { + return cancerTypeId; + } + + public LongFilter cancerTypeId() { + if (cancerTypeId == null) { + cancerTypeId = new LongFilter(); + } + return cancerTypeId; + } + + public void setCancerTypeId(LongFilter cancerTypeId) { + this.cancerTypeId = cancerTypeId; + } + + public Boolean getDistinct() { + return distinct; + } + + public void setDistinct(Boolean distinct) { + this.distinct = distinct; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final ClinicalTrialsGovConditionCriteria that = (ClinicalTrialsGovConditionCriteria) o; + return ( + Objects.equals(id, that.id) && + Objects.equals(name, that.name) && + Objects.equals(cancerTypeId, that.cancerTypeId) && + Objects.equals(distinct, that.distinct) + ); + } + + @Override + public int hashCode() { + return Objects.hash(id, name, cancerTypeId, distinct); + } + + // prettier-ignore + @Override + public String toString() { + return "ClinicalTrialsGovConditionCriteria{" + + (id != null ? "id=" + id + ", " : "") + + (name != null ? "name=" + name + ", " : "") + + (cancerTypeId != null ? "cancerTypeId=" + cancerTypeId + ", " : "") + + (distinct != null ? "distinct=" + distinct + ", " : "") + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/criteria/CompanionDiagnosticDeviceCriteria.java b/src/main/java/org/mskcc/oncokb/curation/service/criteria/CompanionDiagnosticDeviceCriteria.java new file mode 100644 index 000000000..801a25064 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/criteria/CompanionDiagnosticDeviceCriteria.java @@ -0,0 +1,245 @@ +package org.mskcc.oncokb.curation.service.criteria; + +import java.io.Serializable; +import java.util.Objects; +import tech.jhipster.service.Criteria; +import tech.jhipster.service.filter.BooleanFilter; +import tech.jhipster.service.filter.DoubleFilter; +import tech.jhipster.service.filter.Filter; +import tech.jhipster.service.filter.FloatFilter; +import tech.jhipster.service.filter.InstantFilter; +import tech.jhipster.service.filter.IntegerFilter; +import tech.jhipster.service.filter.LongFilter; +import tech.jhipster.service.filter.StringFilter; + +/** + * Criteria class for the {@link org.mskcc.oncokb.curation.domain.CompanionDiagnosticDevice} entity. This class is used + * in {@link org.mskcc.oncokb.curation.web.rest.CompanionDiagnosticDeviceResource} to receive all the possible filtering options from + * the Http GET request parameters. + * For example the following could be a valid request: + * {@code /companion-diagnostic-devices?id.greaterThan=5&attr1.contains=something&attr2.specified=false} + * As Spring is unable to properly convert the types, unless specific {@link Filter} class are used, we need to use + * fix type specific filters. + */ +public class CompanionDiagnosticDeviceCriteria implements Serializable, Criteria { + + private static final long serialVersionUID = 1L; + + private LongFilter id; + + private StringFilter name; + + private StringFilter manufacturer; + + private StringFilter indicationDetails; + + private StringFilter platformType; + + private InstantFilter lastUpdated; + + private LongFilter fdaSubmissionId; + + private LongFilter specimenTypeId; + + private Boolean distinct; + + public CompanionDiagnosticDeviceCriteria() {} + + public CompanionDiagnosticDeviceCriteria(CompanionDiagnosticDeviceCriteria other) { + this.id = other.id == null ? null : other.id.copy(); + this.name = other.name == null ? null : other.name.copy(); + this.manufacturer = other.manufacturer == null ? null : other.manufacturer.copy(); + this.indicationDetails = other.indicationDetails == null ? null : other.indicationDetails.copy(); + this.platformType = other.platformType == null ? null : other.platformType.copy(); + this.lastUpdated = other.lastUpdated == null ? null : other.lastUpdated.copy(); + this.fdaSubmissionId = other.fdaSubmissionId == null ? null : other.fdaSubmissionId.copy(); + this.specimenTypeId = other.specimenTypeId == null ? null : other.specimenTypeId.copy(); + this.distinct = other.distinct; + } + + @Override + public CompanionDiagnosticDeviceCriteria copy() { + return new CompanionDiagnosticDeviceCriteria(this); + } + + public LongFilter getId() { + return id; + } + + public LongFilter id() { + if (id == null) { + id = new LongFilter(); + } + return id; + } + + public void setId(LongFilter id) { + this.id = id; + } + + public StringFilter getName() { + return name; + } + + public StringFilter name() { + if (name == null) { + name = new StringFilter(); + } + return name; + } + + public void setName(StringFilter name) { + this.name = name; + } + + public StringFilter getManufacturer() { + return manufacturer; + } + + public StringFilter manufacturer() { + if (manufacturer == null) { + manufacturer = new StringFilter(); + } + return manufacturer; + } + + public void setManufacturer(StringFilter manufacturer) { + this.manufacturer = manufacturer; + } + + public StringFilter getIndicationDetails() { + return indicationDetails; + } + + public StringFilter indicationDetails() { + if (indicationDetails == null) { + indicationDetails = new StringFilter(); + } + return indicationDetails; + } + + public void setIndicationDetails(StringFilter indicationDetails) { + this.indicationDetails = indicationDetails; + } + + public StringFilter getPlatformType() { + return platformType; + } + + public StringFilter platformType() { + if (platformType == null) { + platformType = new StringFilter(); + } + return platformType; + } + + public void setPlatformType(StringFilter platformType) { + this.platformType = platformType; + } + + public InstantFilter getLastUpdated() { + return lastUpdated; + } + + public InstantFilter lastUpdated() { + if (lastUpdated == null) { + lastUpdated = new InstantFilter(); + } + return lastUpdated; + } + + public void setLastUpdated(InstantFilter lastUpdated) { + this.lastUpdated = lastUpdated; + } + + public LongFilter getFdaSubmissionId() { + return fdaSubmissionId; + } + + public LongFilter fdaSubmissionId() { + if (fdaSubmissionId == null) { + fdaSubmissionId = new LongFilter(); + } + return fdaSubmissionId; + } + + public void setFdaSubmissionId(LongFilter fdaSubmissionId) { + this.fdaSubmissionId = fdaSubmissionId; + } + + public LongFilter getSpecimenTypeId() { + return specimenTypeId; + } + + public LongFilter specimenTypeId() { + if (specimenTypeId == null) { + specimenTypeId = new LongFilter(); + } + return specimenTypeId; + } + + public void setSpecimenTypeId(LongFilter specimenTypeId) { + this.specimenTypeId = specimenTypeId; + } + + public Boolean getDistinct() { + return distinct; + } + + public void setDistinct(Boolean distinct) { + this.distinct = distinct; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final CompanionDiagnosticDeviceCriteria that = (CompanionDiagnosticDeviceCriteria) o; + return ( + Objects.equals(id, that.id) && + Objects.equals(name, that.name) && + Objects.equals(manufacturer, that.manufacturer) && + Objects.equals(indicationDetails, that.indicationDetails) && + Objects.equals(platformType, that.platformType) && + Objects.equals(lastUpdated, that.lastUpdated) && + Objects.equals(fdaSubmissionId, that.fdaSubmissionId) && + Objects.equals(specimenTypeId, that.specimenTypeId) && + Objects.equals(distinct, that.distinct) + ); + } + + @Override + public int hashCode() { + return Objects.hash( + id, + name, + manufacturer, + indicationDetails, + platformType, + lastUpdated, + fdaSubmissionId, + specimenTypeId, + distinct + ); + } + + // prettier-ignore + @Override + public String toString() { + return "CompanionDiagnosticDeviceCriteria{" + + (id != null ? "id=" + id + ", " : "") + + (name != null ? "name=" + name + ", " : "") + + (manufacturer != null ? "manufacturer=" + manufacturer + ", " : "") + + (indicationDetails != null ? "indicationDetails=" + indicationDetails + ", " : "") + + (platformType != null ? "platformType=" + platformType + ", " : "") + + (lastUpdated != null ? "lastUpdated=" + lastUpdated + ", " : "") + + (fdaSubmissionId != null ? "fdaSubmissionId=" + fdaSubmissionId + ", " : "") + + (specimenTypeId != null ? "specimenTypeId=" + specimenTypeId + ", " : "") + + (distinct != null ? "distinct=" + distinct + ", " : "") + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/criteria/ConsequenceCriteria.java b/src/main/java/org/mskcc/oncokb/curation/service/criteria/ConsequenceCriteria.java new file mode 100644 index 000000000..c64a3db5d --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/criteria/ConsequenceCriteria.java @@ -0,0 +1,214 @@ +package org.mskcc.oncokb.curation.service.criteria; + +import java.io.Serializable; +import java.util.Objects; +import tech.jhipster.service.Criteria; +import tech.jhipster.service.filter.BooleanFilter; +import tech.jhipster.service.filter.DoubleFilter; +import tech.jhipster.service.filter.Filter; +import tech.jhipster.service.filter.FloatFilter; +import tech.jhipster.service.filter.IntegerFilter; +import tech.jhipster.service.filter.LongFilter; +import tech.jhipster.service.filter.StringFilter; + +/** + * Criteria class for the {@link org.mskcc.oncokb.curation.domain.Consequence} entity. This class is used + * in {@link org.mskcc.oncokb.curation.web.rest.ConsequenceResource} to receive all the possible filtering options from + * the Http GET request parameters. + * For example the following could be a valid request: + * {@code /consequences?id.greaterThan=5&attr1.contains=something&attr2.specified=false} + * As Spring is unable to properly convert the types, unless specific {@link Filter} class are used, we need to use + * fix type specific filters. + */ +public class ConsequenceCriteria implements Serializable, Criteria { + + private static final long serialVersionUID = 1L; + + private LongFilter id; + + private StringFilter term; + + private StringFilter name; + + private BooleanFilter isGenerallyTruncating; + + private StringFilter description; + + private LongFilter alterationId; + + private LongFilter categoricalAlterationId; + + private Boolean distinct; + + public ConsequenceCriteria() {} + + public ConsequenceCriteria(ConsequenceCriteria other) { + this.id = other.id == null ? null : other.id.copy(); + this.term = other.term == null ? null : other.term.copy(); + this.name = other.name == null ? null : other.name.copy(); + this.isGenerallyTruncating = other.isGenerallyTruncating == null ? null : other.isGenerallyTruncating.copy(); + this.description = other.description == null ? null : other.description.copy(); + this.alterationId = other.alterationId == null ? null : other.alterationId.copy(); + this.categoricalAlterationId = other.categoricalAlterationId == null ? null : other.categoricalAlterationId.copy(); + this.distinct = other.distinct; + } + + @Override + public ConsequenceCriteria copy() { + return new ConsequenceCriteria(this); + } + + public LongFilter getId() { + return id; + } + + public LongFilter id() { + if (id == null) { + id = new LongFilter(); + } + return id; + } + + public void setId(LongFilter id) { + this.id = id; + } + + public StringFilter getTerm() { + return term; + } + + public StringFilter term() { + if (term == null) { + term = new StringFilter(); + } + return term; + } + + public void setTerm(StringFilter term) { + this.term = term; + } + + public StringFilter getName() { + return name; + } + + public StringFilter name() { + if (name == null) { + name = new StringFilter(); + } + return name; + } + + public void setName(StringFilter name) { + this.name = name; + } + + public BooleanFilter getIsGenerallyTruncating() { + return isGenerallyTruncating; + } + + public BooleanFilter isGenerallyTruncating() { + if (isGenerallyTruncating == null) { + isGenerallyTruncating = new BooleanFilter(); + } + return isGenerallyTruncating; + } + + public void setIsGenerallyTruncating(BooleanFilter isGenerallyTruncating) { + this.isGenerallyTruncating = isGenerallyTruncating; + } + + public StringFilter getDescription() { + return description; + } + + public StringFilter description() { + if (description == null) { + description = new StringFilter(); + } + return description; + } + + public void setDescription(StringFilter description) { + this.description = description; + } + + public LongFilter getAlterationId() { + return alterationId; + } + + public LongFilter alterationId() { + if (alterationId == null) { + alterationId = new LongFilter(); + } + return alterationId; + } + + public void setAlterationId(LongFilter alterationId) { + this.alterationId = alterationId; + } + + public LongFilter getCategoricalAlterationId() { + return categoricalAlterationId; + } + + public LongFilter categoricalAlterationId() { + if (categoricalAlterationId == null) { + categoricalAlterationId = new LongFilter(); + } + return categoricalAlterationId; + } + + public void setCategoricalAlterationId(LongFilter categoricalAlterationId) { + this.categoricalAlterationId = categoricalAlterationId; + } + + public Boolean getDistinct() { + return distinct; + } + + public void setDistinct(Boolean distinct) { + this.distinct = distinct; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final ConsequenceCriteria that = (ConsequenceCriteria) o; + return ( + Objects.equals(id, that.id) && + Objects.equals(term, that.term) && + Objects.equals(name, that.name) && + Objects.equals(isGenerallyTruncating, that.isGenerallyTruncating) && + Objects.equals(description, that.description) && + Objects.equals(alterationId, that.alterationId) && + Objects.equals(categoricalAlterationId, that.categoricalAlterationId) && + Objects.equals(distinct, that.distinct) + ); + } + + @Override + public int hashCode() { + return Objects.hash(id, term, name, isGenerallyTruncating, description, alterationId, categoricalAlterationId, distinct); + } + + // prettier-ignore + @Override + public String toString() { + return "ConsequenceCriteria{" + + (id != null ? "id=" + id + ", " : "") + + (term != null ? "term=" + term + ", " : "") + + (name != null ? "name=" + name + ", " : "") + + (isGenerallyTruncating != null ? "isGenerallyTruncating=" + isGenerallyTruncating + ", " : "") + + (description != null ? "description=" + description + ", " : "") + + (alterationId != null ? "alterationId=" + alterationId + ", " : "") + + (categoricalAlterationId != null ? "categoricalAlterationId=" + categoricalAlterationId + ", " : "") + + (distinct != null ? "distinct=" + distinct + ", " : "") + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/criteria/DrugCriteria.java b/src/main/java/org/mskcc/oncokb/curation/service/criteria/DrugCriteria.java new file mode 100644 index 000000000..303c04db0 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/criteria/DrugCriteria.java @@ -0,0 +1,194 @@ +package org.mskcc.oncokb.curation.service.criteria; + +import java.io.Serializable; +import java.util.Objects; +import tech.jhipster.service.Criteria; +import tech.jhipster.service.filter.BooleanFilter; +import tech.jhipster.service.filter.DoubleFilter; +import tech.jhipster.service.filter.Filter; +import tech.jhipster.service.filter.FloatFilter; +import tech.jhipster.service.filter.IntegerFilter; +import tech.jhipster.service.filter.LongFilter; +import tech.jhipster.service.filter.StringFilter; + +/** + * Criteria class for the {@link org.mskcc.oncokb.curation.domain.Drug} entity. This class is used + * in {@link org.mskcc.oncokb.curation.web.rest.DrugResource} to receive all the possible filtering options from + * the Http GET request parameters. + * For example the following could be a valid request: + * {@code /drugs?id.greaterThan=5&attr1.contains=something&attr2.specified=false} + * As Spring is unable to properly convert the types, unless specific {@link Filter} class are used, we need to use + * fix type specific filters. + */ +public class DrugCriteria implements Serializable, Criteria { + + private static final long serialVersionUID = 1L; + + private LongFilter id; + + private StringFilter uuid; + + private StringFilter name; + + private StringFilter ncitCode; + + private LongFilter flagId; + + private LongFilter associationId; + + private Boolean distinct; + + public DrugCriteria() {} + + public DrugCriteria(DrugCriteria other) { + this.id = other.id == null ? null : other.id.copy(); + this.uuid = other.uuid == null ? null : other.uuid.copy(); + this.name = other.name == null ? null : other.name.copy(); + this.ncitCode = other.ncitCode == null ? null : other.ncitCode.copy(); + this.flagId = other.flagId == null ? null : other.flagId.copy(); + this.associationId = other.associationId == null ? null : other.associationId.copy(); + this.distinct = other.distinct; + } + + @Override + public DrugCriteria copy() { + return new DrugCriteria(this); + } + + public LongFilter getId() { + return id; + } + + public LongFilter id() { + if (id == null) { + id = new LongFilter(); + } + return id; + } + + public void setId(LongFilter id) { + this.id = id; + } + + public StringFilter getUuid() { + return uuid; + } + + public StringFilter uuid() { + if (uuid == null) { + uuid = new StringFilter(); + } + return uuid; + } + + public void setUuid(StringFilter uuid) { + this.uuid = uuid; + } + + public StringFilter getName() { + return name; + } + + public StringFilter name() { + if (name == null) { + name = new StringFilter(); + } + return name; + } + + public void setName(StringFilter name) { + this.name = name; + } + + public StringFilter getNcitCode() { + return ncitCode; + } + + public StringFilter ncitCode() { + if (ncitCode == null) { + ncitCode = new StringFilter(); + } + return ncitCode; + } + + public void setNcitCode(StringFilter ncitCode) { + this.ncitCode = ncitCode; + } + + public LongFilter getFlagId() { + return flagId; + } + + public LongFilter flagId() { + if (flagId == null) { + flagId = new LongFilter(); + } + return flagId; + } + + public void setFlagId(LongFilter flagId) { + this.flagId = flagId; + } + + public LongFilter getAssociationId() { + return associationId; + } + + public LongFilter associationId() { + if (associationId == null) { + associationId = new LongFilter(); + } + return associationId; + } + + public void setAssociationId(LongFilter associationId) { + this.associationId = associationId; + } + + public Boolean getDistinct() { + return distinct; + } + + public void setDistinct(Boolean distinct) { + this.distinct = distinct; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final DrugCriteria that = (DrugCriteria) o; + return ( + Objects.equals(id, that.id) && + Objects.equals(uuid, that.uuid) && + Objects.equals(name, that.name) && + Objects.equals(ncitCode, that.ncitCode) && + Objects.equals(flagId, that.flagId) && + Objects.equals(associationId, that.associationId) && + Objects.equals(distinct, that.distinct) + ); + } + + @Override + public int hashCode() { + return Objects.hash(id, name, uuid, ncitCode, flagId, associationId, distinct); + } + + // prettier-ignore + @Override + public String toString() { + return "DrugCriteria{" + + (id != null ? "id=" + id + ", " : "") + + (uuid != null ? "uuid=" + uuid + ", " : "") + + (name != null ? "name=" + name + ", " : "") + + (ncitCode != null ? "ncitCode=" + ncitCode + ", " : "") + + (flagId != null ? "flagId=" + flagId + ", " : "") + + (associationId != null ? "associationId=" + associationId + ", " : "") + + (distinct != null ? "distinct=" + distinct + ", " : "") + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/criteria/EligibilityCriteriaCriteria.java b/src/main/java/org/mskcc/oncokb/curation/service/criteria/EligibilityCriteriaCriteria.java new file mode 100644 index 000000000..57e4c0ae2 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/criteria/EligibilityCriteriaCriteria.java @@ -0,0 +1,192 @@ +package org.mskcc.oncokb.curation.service.criteria; + +import java.io.Serializable; +import java.util.Objects; +import org.mskcc.oncokb.curation.domain.enumeration.EligibilityCriteriaType; +import tech.jhipster.service.Criteria; +import tech.jhipster.service.filter.BooleanFilter; +import tech.jhipster.service.filter.DoubleFilter; +import tech.jhipster.service.filter.Filter; +import tech.jhipster.service.filter.FloatFilter; +import tech.jhipster.service.filter.IntegerFilter; +import tech.jhipster.service.filter.LongFilter; +import tech.jhipster.service.filter.StringFilter; + +/** + * Criteria class for the {@link org.mskcc.oncokb.curation.domain.EligibilityCriteria} entity. This class is used + * in {@link org.mskcc.oncokb.curation.web.rest.EligibilityCriteriaResource} to receive all the possible filtering options from + * the Http GET request parameters. + * For example the following could be a valid request: + * {@code /eligibility-criteria?id.greaterThan=5&attr1.contains=something&attr2.specified=false} + * As Spring is unable to properly convert the types, unless specific {@link Filter} class are used, we need to use + * fix type specific filters. + */ +public class EligibilityCriteriaCriteria implements Serializable, Criteria { + + /** + * Class for filtering EligibilityCriteriaType + */ + public static class EligibilityCriteriaTypeFilter extends Filter { + + public EligibilityCriteriaTypeFilter() {} + + public EligibilityCriteriaTypeFilter(EligibilityCriteriaTypeFilter filter) { + super(filter); + } + + @Override + public EligibilityCriteriaTypeFilter copy() { + return new EligibilityCriteriaTypeFilter(this); + } + } + + private static final long serialVersionUID = 1L; + + private LongFilter id; + + private EligibilityCriteriaTypeFilter type; + + private IntegerFilter priority; + + private LongFilter associationId; + + private LongFilter clinicalTrialId; + + private Boolean distinct; + + public EligibilityCriteriaCriteria() {} + + public EligibilityCriteriaCriteria(EligibilityCriteriaCriteria other) { + this.id = other.id == null ? null : other.id.copy(); + this.type = other.type == null ? null : other.type.copy(); + this.priority = other.priority == null ? null : other.priority.copy(); + this.associationId = other.associationId == null ? null : other.associationId.copy(); + this.clinicalTrialId = other.clinicalTrialId == null ? null : other.clinicalTrialId.copy(); + this.distinct = other.distinct; + } + + @Override + public EligibilityCriteriaCriteria copy() { + return new EligibilityCriteriaCriteria(this); + } + + public LongFilter getId() { + return id; + } + + public LongFilter id() { + if (id == null) { + id = new LongFilter(); + } + return id; + } + + public void setId(LongFilter id) { + this.id = id; + } + + public EligibilityCriteriaTypeFilter getType() { + return type; + } + + public EligibilityCriteriaTypeFilter type() { + if (type == null) { + type = new EligibilityCriteriaTypeFilter(); + } + return type; + } + + public void setType(EligibilityCriteriaTypeFilter type) { + this.type = type; + } + + public IntegerFilter getPriority() { + return priority; + } + + public IntegerFilter priority() { + if (priority == null) { + priority = new IntegerFilter(); + } + return priority; + } + + public void setPriority(IntegerFilter priority) { + this.priority = priority; + } + + public LongFilter getAssociationId() { + return associationId; + } + + public LongFilter associationId() { + if (associationId == null) { + associationId = new LongFilter(); + } + return associationId; + } + + public void setAssociationId(LongFilter associationId) { + this.associationId = associationId; + } + + public LongFilter getClinicalTrialId() { + return clinicalTrialId; + } + + public LongFilter clinicalTrialId() { + if (clinicalTrialId == null) { + clinicalTrialId = new LongFilter(); + } + return clinicalTrialId; + } + + public void setClinicalTrialId(LongFilter clinicalTrialId) { + this.clinicalTrialId = clinicalTrialId; + } + + public Boolean getDistinct() { + return distinct; + } + + public void setDistinct(Boolean distinct) { + this.distinct = distinct; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final EligibilityCriteriaCriteria that = (EligibilityCriteriaCriteria) o; + return ( + Objects.equals(id, that.id) && + Objects.equals(type, that.type) && + Objects.equals(priority, that.priority) && + Objects.equals(associationId, that.associationId) && + Objects.equals(clinicalTrialId, that.clinicalTrialId) && + Objects.equals(distinct, that.distinct) + ); + } + + @Override + public int hashCode() { + return Objects.hash(id, type, priority, associationId, clinicalTrialId, distinct); + } + + // prettier-ignore + @Override + public String toString() { + return "EligibilityCriteriaCriteria{" + + (id != null ? "id=" + id + ", " : "") + + (type != null ? "type=" + type + ", " : "") + + (priority != null ? "priority=" + priority + ", " : "") + + (associationId != null ? "associationId=" + associationId + ", " : "") + + (clinicalTrialId != null ? "clinicalTrialId=" + clinicalTrialId + ", " : "") + + (distinct != null ? "distinct=" + distinct + ", " : "") + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/criteria/EnsemblGeneCriteria.java b/src/main/java/org/mskcc/oncokb/curation/service/criteria/EnsemblGeneCriteria.java new file mode 100644 index 000000000..ebbff63b2 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/criteria/EnsemblGeneCriteria.java @@ -0,0 +1,292 @@ +package org.mskcc.oncokb.curation.service.criteria; + +import java.io.Serializable; +import java.util.Objects; +import org.mskcc.oncokb.curation.domain.enumeration.ReferenceGenome; +import tech.jhipster.service.Criteria; +import tech.jhipster.service.filter.BooleanFilter; +import tech.jhipster.service.filter.DoubleFilter; +import tech.jhipster.service.filter.Filter; +import tech.jhipster.service.filter.FloatFilter; +import tech.jhipster.service.filter.IntegerFilter; +import tech.jhipster.service.filter.LongFilter; +import tech.jhipster.service.filter.StringFilter; + +/** + * Criteria class for the {@link org.mskcc.oncokb.curation.domain.EnsemblGene} entity. This class is used + * in {@link org.mskcc.oncokb.curation.web.rest.EnsemblGeneResource} to receive all the possible filtering options from + * the Http GET request parameters. + * For example the following could be a valid request: + * {@code /ensembl-genes?id.greaterThan=5&attr1.contains=something&attr2.specified=false} + * As Spring is unable to properly convert the types, unless specific {@link Filter} class are used, we need to use + * fix type specific filters. + */ +public class EnsemblGeneCriteria implements Serializable, Criteria { + + /** + * Class for filtering ReferenceGenome + */ + public static class ReferenceGenomeFilter extends Filter { + + public ReferenceGenomeFilter() {} + + public ReferenceGenomeFilter(ReferenceGenomeFilter filter) { + super(filter); + } + + @Override + public ReferenceGenomeFilter copy() { + return new ReferenceGenomeFilter(this); + } + } + + private static final long serialVersionUID = 1L; + + private LongFilter id; + + private ReferenceGenomeFilter referenceGenome; + + private StringFilter ensemblGeneId; + + private BooleanFilter canonical; + + private IntegerFilter start; + + private IntegerFilter end; + + private IntegerFilter strand; + + private LongFilter transcriptId; + + private LongFilter geneId; + + private LongFilter seqRegionId; + + private Boolean distinct; + + public EnsemblGeneCriteria() {} + + public EnsemblGeneCriteria(EnsemblGeneCriteria other) { + this.id = other.id == null ? null : other.id.copy(); + this.referenceGenome = other.referenceGenome == null ? null : other.referenceGenome.copy(); + this.ensemblGeneId = other.ensemblGeneId == null ? null : other.ensemblGeneId.copy(); + this.canonical = other.canonical == null ? null : other.canonical.copy(); + this.start = other.start == null ? null : other.start.copy(); + this.end = other.end == null ? null : other.end.copy(); + this.strand = other.strand == null ? null : other.strand.copy(); + this.transcriptId = other.transcriptId == null ? null : other.transcriptId.copy(); + this.geneId = other.geneId == null ? null : other.geneId.copy(); + this.seqRegionId = other.seqRegionId == null ? null : other.seqRegionId.copy(); + this.distinct = other.distinct; + } + + @Override + public EnsemblGeneCriteria copy() { + return new EnsemblGeneCriteria(this); + } + + public LongFilter getId() { + return id; + } + + public LongFilter id() { + if (id == null) { + id = new LongFilter(); + } + return id; + } + + public void setId(LongFilter id) { + this.id = id; + } + + public ReferenceGenomeFilter getReferenceGenome() { + return referenceGenome; + } + + public ReferenceGenomeFilter referenceGenome() { + if (referenceGenome == null) { + referenceGenome = new ReferenceGenomeFilter(); + } + return referenceGenome; + } + + public void setReferenceGenome(ReferenceGenomeFilter referenceGenome) { + this.referenceGenome = referenceGenome; + } + + public StringFilter getEnsemblGeneId() { + return ensemblGeneId; + } + + public StringFilter ensemblGeneId() { + if (ensemblGeneId == null) { + ensemblGeneId = new StringFilter(); + } + return ensemblGeneId; + } + + public void setEnsemblGeneId(StringFilter ensemblGeneId) { + this.ensemblGeneId = ensemblGeneId; + } + + public BooleanFilter getCanonical() { + return canonical; + } + + public BooleanFilter canonical() { + if (canonical == null) { + canonical = new BooleanFilter(); + } + return canonical; + } + + public void setCanonical(BooleanFilter canonical) { + this.canonical = canonical; + } + + public IntegerFilter getStart() { + return start; + } + + public IntegerFilter start() { + if (start == null) { + start = new IntegerFilter(); + } + return start; + } + + public void setStart(IntegerFilter start) { + this.start = start; + } + + public IntegerFilter getEnd() { + return end; + } + + public IntegerFilter end() { + if (end == null) { + end = new IntegerFilter(); + } + return end; + } + + public void setEnd(IntegerFilter end) { + this.end = end; + } + + public IntegerFilter getStrand() { + return strand; + } + + public IntegerFilter strand() { + if (strand == null) { + strand = new IntegerFilter(); + } + return strand; + } + + public void setStrand(IntegerFilter strand) { + this.strand = strand; + } + + public LongFilter getTranscriptId() { + return transcriptId; + } + + public LongFilter transcriptId() { + if (transcriptId == null) { + transcriptId = new LongFilter(); + } + return transcriptId; + } + + public void setTranscriptId(LongFilter transcriptId) { + this.transcriptId = transcriptId; + } + + public LongFilter getGeneId() { + return geneId; + } + + public LongFilter geneId() { + if (geneId == null) { + geneId = new LongFilter(); + } + return geneId; + } + + public void setGeneId(LongFilter geneId) { + this.geneId = geneId; + } + + public LongFilter getSeqRegionId() { + return seqRegionId; + } + + public LongFilter seqRegionId() { + if (seqRegionId == null) { + seqRegionId = new LongFilter(); + } + return seqRegionId; + } + + public void setSeqRegionId(LongFilter seqRegionId) { + this.seqRegionId = seqRegionId; + } + + public Boolean getDistinct() { + return distinct; + } + + public void setDistinct(Boolean distinct) { + this.distinct = distinct; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final EnsemblGeneCriteria that = (EnsemblGeneCriteria) o; + return ( + Objects.equals(id, that.id) && + Objects.equals(referenceGenome, that.referenceGenome) && + Objects.equals(ensemblGeneId, that.ensemblGeneId) && + Objects.equals(canonical, that.canonical) && + Objects.equals(start, that.start) && + Objects.equals(end, that.end) && + Objects.equals(strand, that.strand) && + Objects.equals(transcriptId, that.transcriptId) && + Objects.equals(geneId, that.geneId) && + Objects.equals(seqRegionId, that.seqRegionId) && + Objects.equals(distinct, that.distinct) + ); + } + + @Override + public int hashCode() { + return Objects.hash(id, referenceGenome, ensemblGeneId, canonical, start, end, strand, transcriptId, geneId, seqRegionId, distinct); + } + + // prettier-ignore + @Override + public String toString() { + return "EnsemblGeneCriteria{" + + (id != null ? "id=" + id + ", " : "") + + (referenceGenome != null ? "referenceGenome=" + referenceGenome + ", " : "") + + (ensemblGeneId != null ? "ensemblGeneId=" + ensemblGeneId + ", " : "") + + (canonical != null ? "canonical=" + canonical + ", " : "") + + (start != null ? "start=" + start + ", " : "") + + (end != null ? "end=" + end + ", " : "") + + (strand != null ? "strand=" + strand + ", " : "") + + (transcriptId != null ? "transcriptId=" + transcriptId + ", " : "") + + (geneId != null ? "geneId=" + geneId + ", " : "") + + (seqRegionId != null ? "seqRegionId=" + seqRegionId + ", " : "") + + (distinct != null ? "distinct=" + distinct + ", " : "") + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/criteria/EvidenceCriteria.java b/src/main/java/org/mskcc/oncokb/curation/service/criteria/EvidenceCriteria.java new file mode 100644 index 000000000..5dc8a17d6 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/criteria/EvidenceCriteria.java @@ -0,0 +1,214 @@ +package org.mskcc.oncokb.curation.service.criteria; + +import java.io.Serializable; +import java.util.Objects; +import tech.jhipster.service.Criteria; +import tech.jhipster.service.filter.BooleanFilter; +import tech.jhipster.service.filter.DoubleFilter; +import tech.jhipster.service.filter.Filter; +import tech.jhipster.service.filter.FloatFilter; +import tech.jhipster.service.filter.IntegerFilter; +import tech.jhipster.service.filter.LongFilter; +import tech.jhipster.service.filter.StringFilter; + +/** + * Criteria class for the {@link org.mskcc.oncokb.curation.domain.Evidence} entity. This class is used + * in {@link org.mskcc.oncokb.curation.web.rest.EvidenceResource} to receive all the possible filtering options from + * the Http GET request parameters. + * For example the following could be a valid request: + * {@code /evidences?id.greaterThan=5&attr1.contains=something&attr2.specified=false} + * As Spring is unable to properly convert the types, unless specific {@link Filter} class are used, we need to use + * fix type specific filters. + */ +public class EvidenceCriteria implements Serializable, Criteria { + + private static final long serialVersionUID = 1L; + + private LongFilter id; + + private StringFilter uuid; + + private StringFilter evidenceType; + + private StringFilter knownEffect; + + private LongFilter associationId; + + private LongFilter levelOfEvidenceId; + + private LongFilter geneId; + + private Boolean distinct; + + public EvidenceCriteria() {} + + public EvidenceCriteria(EvidenceCriteria other) { + this.id = other.id == null ? null : other.id.copy(); + this.uuid = other.uuid == null ? null : other.uuid.copy(); + this.evidenceType = other.evidenceType == null ? null : other.evidenceType.copy(); + this.knownEffect = other.knownEffect == null ? null : other.knownEffect.copy(); + this.associationId = other.associationId == null ? null : other.associationId.copy(); + this.levelOfEvidenceId = other.levelOfEvidenceId == null ? null : other.levelOfEvidenceId.copy(); + this.geneId = other.geneId == null ? null : other.geneId.copy(); + this.distinct = other.distinct; + } + + @Override + public EvidenceCriteria copy() { + return new EvidenceCriteria(this); + } + + public LongFilter getId() { + return id; + } + + public LongFilter id() { + if (id == null) { + id = new LongFilter(); + } + return id; + } + + public void setId(LongFilter id) { + this.id = id; + } + + public StringFilter getUuid() { + return uuid; + } + + public StringFilter uuid() { + if (uuid == null) { + uuid = new StringFilter(); + } + return uuid; + } + + public void setUuid(StringFilter uuid) { + this.uuid = uuid; + } + + public StringFilter getEvidenceType() { + return evidenceType; + } + + public StringFilter evidenceType() { + if (evidenceType == null) { + evidenceType = new StringFilter(); + } + return evidenceType; + } + + public void setEvidenceType(StringFilter evidenceType) { + this.evidenceType = evidenceType; + } + + public StringFilter getKnownEffect() { + return knownEffect; + } + + public StringFilter knownEffect() { + if (knownEffect == null) { + knownEffect = new StringFilter(); + } + return knownEffect; + } + + public void setKnownEffect(StringFilter knownEffect) { + this.knownEffect = knownEffect; + } + + public LongFilter getAssociationId() { + return associationId; + } + + public LongFilter associationId() { + if (associationId == null) { + associationId = new LongFilter(); + } + return associationId; + } + + public void setAssociationId(LongFilter associationId) { + this.associationId = associationId; + } + + public LongFilter getLevelOfEvidenceId() { + return levelOfEvidenceId; + } + + public LongFilter levelOfEvidenceId() { + if (levelOfEvidenceId == null) { + levelOfEvidenceId = new LongFilter(); + } + return levelOfEvidenceId; + } + + public void setLevelOfEvidenceId(LongFilter levelOfEvidenceId) { + this.levelOfEvidenceId = levelOfEvidenceId; + } + + public LongFilter getGeneId() { + return geneId; + } + + public LongFilter geneId() { + if (geneId == null) { + geneId = new LongFilter(); + } + return geneId; + } + + public void setGeneId(LongFilter geneId) { + this.geneId = geneId; + } + + public Boolean getDistinct() { + return distinct; + } + + public void setDistinct(Boolean distinct) { + this.distinct = distinct; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final EvidenceCriteria that = (EvidenceCriteria) o; + return ( + Objects.equals(id, that.id) && + Objects.equals(uuid, that.uuid) && + Objects.equals(evidenceType, that.evidenceType) && + Objects.equals(knownEffect, that.knownEffect) && + Objects.equals(associationId, that.associationId) && + Objects.equals(levelOfEvidenceId, that.levelOfEvidenceId) && + Objects.equals(geneId, that.geneId) && + Objects.equals(distinct, that.distinct) + ); + } + + @Override + public int hashCode() { + return Objects.hash(id, uuid, evidenceType, knownEffect, associationId, levelOfEvidenceId, geneId, distinct); + } + + // prettier-ignore + @Override + public String toString() { + return "EvidenceCriteria{" + + (id != null ? "id=" + id + ", " : "") + + (uuid != null ? "uuid=" + uuid + ", " : "") + + (evidenceType != null ? "evidenceType=" + evidenceType + ", " : "") + + (knownEffect != null ? "knownEffect=" + knownEffect + ", " : "") + + (associationId != null ? "associationId=" + associationId + ", " : "") + + (levelOfEvidenceId != null ? "levelOfEvidenceId=" + levelOfEvidenceId + ", " : "") + + (geneId != null ? "geneId=" + geneId + ", " : "") + + (distinct != null ? "distinct=" + distinct + ", " : "") + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/criteria/FdaDrugCriteria.java b/src/main/java/org/mskcc/oncokb/curation/service/criteria/FdaDrugCriteria.java new file mode 100644 index 000000000..e1cd5fdc9 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/criteria/FdaDrugCriteria.java @@ -0,0 +1,194 @@ +package org.mskcc.oncokb.curation.service.criteria; + +import java.io.Serializable; +import java.util.Objects; +import tech.jhipster.service.Criteria; +import tech.jhipster.service.filter.BooleanFilter; +import tech.jhipster.service.filter.DoubleFilter; +import tech.jhipster.service.filter.Filter; +import tech.jhipster.service.filter.FloatFilter; +import tech.jhipster.service.filter.IntegerFilter; +import tech.jhipster.service.filter.LongFilter; +import tech.jhipster.service.filter.StringFilter; + +/** + * Criteria class for the {@link org.mskcc.oncokb.curation.domain.FdaDrug} entity. This class is used + * in {@link org.mskcc.oncokb.curation.web.rest.FdaDrugResource} to receive all the possible filtering options from + * the Http GET request parameters. + * For example the following could be a valid request: + * {@code /fda-drugs?id.greaterThan=5&attr1.contains=something&attr2.specified=false} + * As Spring is unable to properly convert the types, unless specific {@link Filter} class are used, we need to use + * fix type specific filters. + */ +public class FdaDrugCriteria implements Serializable, Criteria { + + private static final long serialVersionUID = 1L; + + private LongFilter id; + + private StringFilter applicationNumber; + + private StringFilter sponsorName; + + private StringFilter overallMarketingStatus; + + private LongFilter fdaSubmissionId; + + private LongFilter drugId; + + private Boolean distinct; + + public FdaDrugCriteria() {} + + public FdaDrugCriteria(FdaDrugCriteria other) { + this.id = other.id == null ? null : other.id.copy(); + this.applicationNumber = other.applicationNumber == null ? null : other.applicationNumber.copy(); + this.sponsorName = other.sponsorName == null ? null : other.sponsorName.copy(); + this.overallMarketingStatus = other.overallMarketingStatus == null ? null : other.overallMarketingStatus.copy(); + this.fdaSubmissionId = other.fdaSubmissionId == null ? null : other.fdaSubmissionId.copy(); + this.drugId = other.drugId == null ? null : other.drugId.copy(); + this.distinct = other.distinct; + } + + @Override + public FdaDrugCriteria copy() { + return new FdaDrugCriteria(this); + } + + public LongFilter getId() { + return id; + } + + public LongFilter id() { + if (id == null) { + id = new LongFilter(); + } + return id; + } + + public void setId(LongFilter id) { + this.id = id; + } + + public StringFilter getApplicationNumber() { + return applicationNumber; + } + + public StringFilter applicationNumber() { + if (applicationNumber == null) { + applicationNumber = new StringFilter(); + } + return applicationNumber; + } + + public void setApplicationNumber(StringFilter applicationNumber) { + this.applicationNumber = applicationNumber; + } + + public StringFilter getSponsorName() { + return sponsorName; + } + + public StringFilter sponsorName() { + if (sponsorName == null) { + sponsorName = new StringFilter(); + } + return sponsorName; + } + + public void setSponsorName(StringFilter sponsorName) { + this.sponsorName = sponsorName; + } + + public StringFilter getOverallMarketingStatus() { + return overallMarketingStatus; + } + + public StringFilter overallMarketingStatus() { + if (overallMarketingStatus == null) { + overallMarketingStatus = new StringFilter(); + } + return overallMarketingStatus; + } + + public void setOverallMarketingStatus(StringFilter overallMarketingStatus) { + this.overallMarketingStatus = overallMarketingStatus; + } + + public LongFilter getFdaSubmissionId() { + return fdaSubmissionId; + } + + public LongFilter fdaSubmissionId() { + if (fdaSubmissionId == null) { + fdaSubmissionId = new LongFilter(); + } + return fdaSubmissionId; + } + + public void setFdaSubmissionId(LongFilter fdaSubmissionId) { + this.fdaSubmissionId = fdaSubmissionId; + } + + public LongFilter getDrugId() { + return drugId; + } + + public LongFilter drugId() { + if (drugId == null) { + drugId = new LongFilter(); + } + return drugId; + } + + public void setDrugId(LongFilter drugId) { + this.drugId = drugId; + } + + public Boolean getDistinct() { + return distinct; + } + + public void setDistinct(Boolean distinct) { + this.distinct = distinct; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final FdaDrugCriteria that = (FdaDrugCriteria) o; + return ( + Objects.equals(id, that.id) && + Objects.equals(applicationNumber, that.applicationNumber) && + Objects.equals(sponsorName, that.sponsorName) && + Objects.equals(overallMarketingStatus, that.overallMarketingStatus) && + Objects.equals(fdaSubmissionId, that.fdaSubmissionId) && + Objects.equals(drugId, that.drugId) && + Objects.equals(distinct, that.distinct) + ); + } + + @Override + public int hashCode() { + return Objects.hash(id, applicationNumber, sponsorName, overallMarketingStatus, fdaSubmissionId, drugId, distinct); + } + + // prettier-ignore + @Override + public String toString() { + return "FdaDrugCriteria{" + + (id != null ? "id=" + id + ", " : "") + + (applicationNumber != null ? "applicationNumber=" + applicationNumber + ", " : "") + + (sponsorName != null ? "sponsorName=" + sponsorName + ", " : "") + + (overallMarketingStatus != null ? "overallMarketingStatus=" + overallMarketingStatus + ", " : "") + + (fdaSubmissionId != null ? "fdaSubmissionId=" + fdaSubmissionId + ", " : "") + + (drugId != null ? "drugId=" + drugId + ", " : "") + + (distinct != null ? "distinct=" + distinct + ", " : "") + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/criteria/FdaSubmissionCriteria.java b/src/main/java/org/mskcc/oncokb/curation/service/criteria/FdaSubmissionCriteria.java new file mode 100644 index 000000000..1eeadaa12 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/criteria/FdaSubmissionCriteria.java @@ -0,0 +1,368 @@ +package org.mskcc.oncokb.curation.service.criteria; + +import java.io.Serializable; +import java.util.Objects; +import tech.jhipster.service.Criteria; +import tech.jhipster.service.filter.BooleanFilter; +import tech.jhipster.service.filter.Filter; +import tech.jhipster.service.filter.LocalDateFilter; +import tech.jhipster.service.filter.LongFilter; +import tech.jhipster.service.filter.StringFilter; + +/** + * Criteria class for the {@link org.mskcc.oncokb.curation.domain.FdaSubmission} entity. This class is used + * in {@link org.mskcc.oncokb.curation.web.rest.FdaSubmissionResource} to receive all the possible filtering options from + * the Http GET request parameters. + * For example the following could be a valid request: + * {@code /fda-submissions?id.greaterThan=5&attr1.contains=something&attr2.specified=false} + * As Spring is unable to properly convert the types, unless specific {@link Filter} class are used, we need to use + * fix type specific filters. + */ +public class FdaSubmissionCriteria implements Serializable, Criteria { + + private static final long serialVersionUID = 1L; + + private LongFilter id; + + private StringFilter number; + + private StringFilter supplementNumber; + + private StringFilter deviceName; + + private StringFilter genericName; + + private LocalDateFilter dateReceived; + + private LocalDateFilter decisionDate; + + private BooleanFilter curated; + + private BooleanFilter genetic; + + private LongFilter articleId; + + private LongFilter associationId; + + private LongFilter companionDiagnosticDeviceId; + + private LongFilter fdaDrugId; + + private LongFilter typeId; + + private Boolean distinct; + + public FdaSubmissionCriteria() {} + + public FdaSubmissionCriteria(FdaSubmissionCriteria other) { + this.id = other.id == null ? null : other.id.copy(); + this.number = other.number == null ? null : other.number.copy(); + this.supplementNumber = other.supplementNumber == null ? null : other.supplementNumber.copy(); + this.deviceName = other.deviceName == null ? null : other.deviceName.copy(); + this.genericName = other.genericName == null ? null : other.genericName.copy(); + this.dateReceived = other.dateReceived == null ? null : other.dateReceived.copy(); + this.decisionDate = other.decisionDate == null ? null : other.decisionDate.copy(); + this.curated = other.curated == null ? null : other.curated.copy(); + this.genetic = other.genetic == null ? null : other.genetic.copy(); + this.articleId = other.articleId == null ? null : other.articleId.copy(); + this.associationId = other.associationId == null ? null : other.associationId.copy(); + this.companionDiagnosticDeviceId = other.companionDiagnosticDeviceId == null ? null : other.companionDiagnosticDeviceId.copy(); + this.fdaDrugId = other.fdaDrugId == null ? null : other.fdaDrugId.copy(); + this.typeId = other.typeId == null ? null : other.typeId.copy(); + this.distinct = other.distinct; + } + + @Override + public FdaSubmissionCriteria copy() { + return new FdaSubmissionCriteria(this); + } + + public LongFilter getId() { + return id; + } + + public LongFilter id() { + if (id == null) { + id = new LongFilter(); + } + return id; + } + + public void setId(LongFilter id) { + this.id = id; + } + + public StringFilter getNumber() { + return number; + } + + public StringFilter number() { + if (number == null) { + number = new StringFilter(); + } + return number; + } + + public void setNumber(StringFilter number) { + this.number = number; + } + + public StringFilter getSupplementNumber() { + return supplementNumber; + } + + public StringFilter supplementNumber() { + if (supplementNumber == null) { + supplementNumber = new StringFilter(); + } + return supplementNumber; + } + + public void setSupplementNumber(StringFilter supplementNumber) { + this.supplementNumber = supplementNumber; + } + + public StringFilter getDeviceName() { + return deviceName; + } + + public StringFilter deviceName() { + if (deviceName == null) { + deviceName = new StringFilter(); + } + return deviceName; + } + + public void setDeviceName(StringFilter deviceName) { + this.deviceName = deviceName; + } + + public StringFilter getGenericName() { + return genericName; + } + + public StringFilter genericName() { + if (genericName == null) { + genericName = new StringFilter(); + } + return genericName; + } + + public void setGenericName(StringFilter genericName) { + this.genericName = genericName; + } + + public LocalDateFilter getDateReceived() { + return dateReceived; + } + + public LocalDateFilter dateReceived() { + if (dateReceived == null) { + dateReceived = new LocalDateFilter(); + } + return dateReceived; + } + + public void setDateReceived(LocalDateFilter dateReceived) { + this.dateReceived = dateReceived; + } + + public LocalDateFilter getDecisionDate() { + return decisionDate; + } + + public LocalDateFilter decisionDate() { + if (decisionDate == null) { + decisionDate = new LocalDateFilter(); + } + return decisionDate; + } + + public void setDecisionDate(LocalDateFilter decisionDate) { + this.decisionDate = decisionDate; + } + + public BooleanFilter getCurated() { + return curated; + } + + public BooleanFilter curated() { + if (curated == null) { + curated = new BooleanFilter(); + } + return curated; + } + + public void setCurated(BooleanFilter curated) { + this.curated = curated; + } + + public BooleanFilter getGenetic() { + return genetic; + } + + public BooleanFilter genetic() { + if (genetic == null) { + genetic = new BooleanFilter(); + } + return genetic; + } + + public void setGenetic(BooleanFilter genetic) { + this.genetic = genetic; + } + + public LongFilter getArticleId() { + return articleId; + } + + public LongFilter articleId() { + if (articleId == null) { + articleId = new LongFilter(); + } + return articleId; + } + + public void setArticleId(LongFilter articleId) { + this.articleId = articleId; + } + + public LongFilter getAssociationId() { + return associationId; + } + + public LongFilter associationId() { + if (associationId == null) { + associationId = new LongFilter(); + } + return associationId; + } + + public void setAssociationId(LongFilter associationId) { + this.associationId = associationId; + } + + public LongFilter getCompanionDiagnosticDeviceId() { + return companionDiagnosticDeviceId; + } + + public LongFilter companionDiagnosticDeviceId() { + if (companionDiagnosticDeviceId == null) { + companionDiagnosticDeviceId = new LongFilter(); + } + return companionDiagnosticDeviceId; + } + + public void setCompanionDiagnosticDeviceId(LongFilter companionDiagnosticDeviceId) { + this.companionDiagnosticDeviceId = companionDiagnosticDeviceId; + } + + public LongFilter getFdaDrugId() { + return fdaDrugId; + } + + public LongFilter fdaDrugId() { + if (fdaDrugId == null) { + fdaDrugId = new LongFilter(); + } + return fdaDrugId; + } + + public void setFdaDrugId(LongFilter fdaDrugId) { + this.fdaDrugId = fdaDrugId; + } + + public LongFilter getTypeId() { + return typeId; + } + + public LongFilter typeId() { + if (typeId == null) { + typeId = new LongFilter(); + } + return typeId; + } + + public void setTypeId(LongFilter typeId) { + this.typeId = typeId; + } + + public Boolean getDistinct() { + return distinct; + } + + public void setDistinct(Boolean distinct) { + this.distinct = distinct; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final FdaSubmissionCriteria that = (FdaSubmissionCriteria) o; + return ( + Objects.equals(id, that.id) && + Objects.equals(number, that.number) && + Objects.equals(supplementNumber, that.supplementNumber) && + Objects.equals(deviceName, that.deviceName) && + Objects.equals(genericName, that.genericName) && + Objects.equals(dateReceived, that.dateReceived) && + Objects.equals(decisionDate, that.decisionDate) && + Objects.equals(curated, that.curated) && + Objects.equals(genetic, that.genetic) && + Objects.equals(articleId, that.articleId) && + Objects.equals(associationId, that.associationId) && + Objects.equals(companionDiagnosticDeviceId, that.companionDiagnosticDeviceId) && + Objects.equals(fdaDrugId, that.fdaDrugId) && + Objects.equals(typeId, that.typeId) && + Objects.equals(distinct, that.distinct) + ); + } + + @Override + public int hashCode() { + return Objects.hash( + id, + number, + supplementNumber, + deviceName, + genericName, + dateReceived, + decisionDate, + curated, + genetic, + articleId, + associationId, + companionDiagnosticDeviceId, + fdaDrugId, + typeId, + distinct + ); + } + + // prettier-ignore + @Override + public String toString() { + return "FdaSubmissionCriteria{" + + (id != null ? "id=" + id + ", " : "") + + (number != null ? "number=" + number + ", " : "") + + (supplementNumber != null ? "supplementNumber=" + supplementNumber + ", " : "") + + (deviceName != null ? "deviceName=" + deviceName + ", " : "") + + (genericName != null ? "genericName=" + genericName + ", " : "") + + (dateReceived != null ? "dateReceived=" + dateReceived + ", " : "") + + (decisionDate != null ? "decisionDate=" + decisionDate + ", " : "") + + (curated != null ? "curated=" + curated + ", " : "") + + (genetic != null ? "genetic=" + genetic + ", " : "") + + (articleId != null ? "articleId=" + articleId + ", " : "") + + (associationId != null ? "associationId=" + associationId + ", " : "") + + (companionDiagnosticDeviceId != null ? "companionDiagnosticDeviceId=" + companionDiagnosticDeviceId + ", " : "") + + (fdaDrugId != null ? "fdaDrugId=" + fdaDrugId + ", " : "") + + (typeId != null ? "typeId=" + typeId + ", " : "") + + (distinct != null ? "distinct=" + distinct + ", " : "") + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/criteria/FlagCriteria.java b/src/main/java/org/mskcc/oncokb/curation/service/criteria/FlagCriteria.java new file mode 100644 index 000000000..3420a2bea --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/criteria/FlagCriteria.java @@ -0,0 +1,254 @@ +package org.mskcc.oncokb.curation.service.criteria; + +import java.io.Serializable; +import java.util.Objects; +import tech.jhipster.service.Criteria; +import tech.jhipster.service.filter.BooleanFilter; +import tech.jhipster.service.filter.DoubleFilter; +import tech.jhipster.service.filter.Filter; +import tech.jhipster.service.filter.FloatFilter; +import tech.jhipster.service.filter.IntegerFilter; +import tech.jhipster.service.filter.LongFilter; +import tech.jhipster.service.filter.StringFilter; + +/** + * Criteria class for the {@link org.mskcc.oncokb.curation.domain.Flag} entity. This class is used + * in {@link org.mskcc.oncokb.curation.web.rest.FlagResource} to receive all the possible filtering options from + * the Http GET request parameters. + * For example the following could be a valid request: + * {@code /flags?id.greaterThan=5&attr1.contains=something&attr2.specified=false} + * As Spring is unable to properly convert the types, unless specific {@link Filter} class are used, we need to use + * fix type specific filters. + */ +public class FlagCriteria implements Serializable, Criteria { + + private static final long serialVersionUID = 1L; + + private LongFilter id; + + private StringFilter type; + + private StringFilter flag; + + private StringFilter name; + + private LongFilter alterationId; + + private LongFilter articleId; + + private LongFilter drugId; + + private LongFilter geneId; + + private LongFilter transcriptId; + + private Boolean distinct; + + public FlagCriteria() {} + + public FlagCriteria(FlagCriteria other) { + this.id = other.id == null ? null : other.id.copy(); + this.type = other.type == null ? null : other.type.copy(); + this.flag = other.flag == null ? null : other.flag.copy(); + this.name = other.name == null ? null : other.name.copy(); + this.alterationId = other.alterationId == null ? null : other.alterationId.copy(); + this.articleId = other.articleId == null ? null : other.articleId.copy(); + this.drugId = other.drugId == null ? null : other.drugId.copy(); + this.geneId = other.geneId == null ? null : other.geneId.copy(); + this.transcriptId = other.transcriptId == null ? null : other.transcriptId.copy(); + this.distinct = other.distinct; + } + + @Override + public FlagCriteria copy() { + return new FlagCriteria(this); + } + + public LongFilter getId() { + return id; + } + + public LongFilter id() { + if (id == null) { + id = new LongFilter(); + } + return id; + } + + public void setId(LongFilter id) { + this.id = id; + } + + public StringFilter getType() { + return type; + } + + public StringFilter type() { + if (type == null) { + type = new StringFilter(); + } + return type; + } + + public void setType(StringFilter type) { + this.type = type; + } + + public StringFilter getFlag() { + return flag; + } + + public StringFilter flag() { + if (flag == null) { + flag = new StringFilter(); + } + return flag; + } + + public void setFlag(StringFilter flag) { + this.flag = flag; + } + + public StringFilter getName() { + return name; + } + + public StringFilter name() { + if (name == null) { + name = new StringFilter(); + } + return name; + } + + public void setName(StringFilter name) { + this.name = name; + } + + public LongFilter getAlterationId() { + return alterationId; + } + + public LongFilter alterationId() { + if (alterationId == null) { + alterationId = new LongFilter(); + } + return alterationId; + } + + public void setAlterationId(LongFilter alterationId) { + this.alterationId = alterationId; + } + + public LongFilter getArticleId() { + return articleId; + } + + public LongFilter articleId() { + if (articleId == null) { + articleId = new LongFilter(); + } + return articleId; + } + + public void setArticleId(LongFilter articleId) { + this.articleId = articleId; + } + + public LongFilter getDrugId() { + return drugId; + } + + public LongFilter drugId() { + if (drugId == null) { + drugId = new LongFilter(); + } + return drugId; + } + + public void setDrugId(LongFilter drugId) { + this.drugId = drugId; + } + + public LongFilter getGeneId() { + return geneId; + } + + public LongFilter geneId() { + if (geneId == null) { + geneId = new LongFilter(); + } + return geneId; + } + + public void setGeneId(LongFilter geneId) { + this.geneId = geneId; + } + + public LongFilter getTranscriptId() { + return transcriptId; + } + + public LongFilter transcriptId() { + if (transcriptId == null) { + transcriptId = new LongFilter(); + } + return transcriptId; + } + + public void setTranscriptId(LongFilter transcriptId) { + this.transcriptId = transcriptId; + } + + public Boolean getDistinct() { + return distinct; + } + + public void setDistinct(Boolean distinct) { + this.distinct = distinct; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final FlagCriteria that = (FlagCriteria) o; + return ( + Objects.equals(id, that.id) && + Objects.equals(type, that.type) && + Objects.equals(flag, that.flag) && + Objects.equals(name, that.name) && + Objects.equals(alterationId, that.alterationId) && + Objects.equals(articleId, that.articleId) && + Objects.equals(drugId, that.drugId) && + Objects.equals(geneId, that.geneId) && + Objects.equals(transcriptId, that.transcriptId) && + Objects.equals(distinct, that.distinct) + ); + } + + @Override + public int hashCode() { + return Objects.hash(id, type, flag, name, alterationId, articleId, drugId, geneId, transcriptId, distinct); + } + + // prettier-ignore + @Override + public String toString() { + return "FlagCriteria{" + + (id != null ? "id=" + id + ", " : "") + + (type != null ? "type=" + type + ", " : "") + + (flag != null ? "flag=" + flag + ", " : "") + + (name != null ? "name=" + name + ", " : "") + + (alterationId != null ? "alterationId=" + alterationId + ", " : "") + + (articleId != null ? "articleId=" + articleId + ", " : "") + + (drugId != null ? "drugId=" + drugId + ", " : "") + + (geneId != null ? "geneId=" + geneId + ", " : "") + + (transcriptId != null ? "transcriptId=" + transcriptId + ", " : "") + + (distinct != null ? "distinct=" + distinct + ", " : "") + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/criteria/GeneCriteria.java b/src/main/java/org/mskcc/oncokb/curation/service/criteria/GeneCriteria.java new file mode 100644 index 000000000..101c7c968 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/criteria/GeneCriteria.java @@ -0,0 +1,286 @@ +package org.mskcc.oncokb.curation.service.criteria; + +import java.io.Serializable; +import java.util.Objects; +import tech.jhipster.service.Criteria; +import tech.jhipster.service.filter.BooleanFilter; +import tech.jhipster.service.filter.DoubleFilter; +import tech.jhipster.service.filter.Filter; +import tech.jhipster.service.filter.FloatFilter; +import tech.jhipster.service.filter.IntegerFilter; +import tech.jhipster.service.filter.LongFilter; +import tech.jhipster.service.filter.StringFilter; + +/** + * Criteria class for the {@link org.mskcc.oncokb.curation.domain.Gene} entity. This class is used + * in {@link org.mskcc.oncokb.curation.web.rest.GeneResource} to receive all the possible filtering options from + * the Http GET request parameters. + * For example the following could be a valid request: + * {@code /genes?id.greaterThan=5&attr1.contains=something&attr2.specified=false} + * As Spring is unable to properly convert the types, unless specific {@link Filter} class are used, we need to use + * fix type specific filters. + */ +public class GeneCriteria implements Serializable, Criteria { + + private static final long serialVersionUID = 1L; + + private LongFilter id; + + private IntegerFilter entrezGeneId; + + private StringFilter hugoSymbol; + + private StringFilter hgncId; + + private LongFilter ensemblGeneId; + + private LongFilter evidenceId; + + private LongFilter transcriptId; + + private LongFilter flagId; + + private LongFilter synonymId; + + private LongFilter alterationId; + + private Boolean distinct; + + public GeneCriteria() {} + + public GeneCriteria(GeneCriteria other) { + this.id = other.id == null ? null : other.id.copy(); + this.entrezGeneId = other.entrezGeneId == null ? null : other.entrezGeneId.copy(); + this.hugoSymbol = other.hugoSymbol == null ? null : other.hugoSymbol.copy(); + this.hgncId = other.hgncId == null ? null : other.hgncId.copy(); + this.ensemblGeneId = other.ensemblGeneId == null ? null : other.ensemblGeneId.copy(); + this.evidenceId = other.evidenceId == null ? null : other.evidenceId.copy(); + this.transcriptId = other.transcriptId == null ? null : other.transcriptId.copy(); + this.flagId = other.flagId == null ? null : other.flagId.copy(); + this.synonymId = other.synonymId == null ? null : other.synonymId.copy(); + this.alterationId = other.alterationId == null ? null : other.alterationId.copy(); + this.distinct = other.distinct; + } + + @Override + public GeneCriteria copy() { + return new GeneCriteria(this); + } + + public LongFilter getId() { + return id; + } + + public LongFilter id() { + if (id == null) { + id = new LongFilter(); + } + return id; + } + + public void setId(LongFilter id) { + this.id = id; + } + + public IntegerFilter getEntrezGeneId() { + return entrezGeneId; + } + + public IntegerFilter entrezGeneId() { + if (entrezGeneId == null) { + entrezGeneId = new IntegerFilter(); + } + return entrezGeneId; + } + + public void setEntrezGeneId(IntegerFilter entrezGeneId) { + this.entrezGeneId = entrezGeneId; + } + + public StringFilter getHugoSymbol() { + return hugoSymbol; + } + + public StringFilter hugoSymbol() { + if (hugoSymbol == null) { + hugoSymbol = new StringFilter(); + } + return hugoSymbol; + } + + public void setHugoSymbol(StringFilter hugoSymbol) { + this.hugoSymbol = hugoSymbol; + } + + public StringFilter getHgncId() { + return hgncId; + } + + public StringFilter hgncId() { + if (hgncId == null) { + hgncId = new StringFilter(); + } + return hgncId; + } + + public void setHgncId(StringFilter hgncId) { + this.hgncId = hgncId; + } + + public LongFilter getEnsemblGeneId() { + return ensemblGeneId; + } + + public LongFilter ensemblGeneId() { + if (ensemblGeneId == null) { + ensemblGeneId = new LongFilter(); + } + return ensemblGeneId; + } + + public void setEnsemblGeneId(LongFilter ensemblGeneId) { + this.ensemblGeneId = ensemblGeneId; + } + + public LongFilter getEvidenceId() { + return evidenceId; + } + + public LongFilter evidenceId() { + if (evidenceId == null) { + evidenceId = new LongFilter(); + } + return evidenceId; + } + + public void setEvidenceId(LongFilter evidenceId) { + this.evidenceId = evidenceId; + } + + public LongFilter getTranscriptId() { + return transcriptId; + } + + public LongFilter transcriptId() { + if (transcriptId == null) { + transcriptId = new LongFilter(); + } + return transcriptId; + } + + public void setTranscriptId(LongFilter transcriptId) { + this.transcriptId = transcriptId; + } + + public LongFilter getFlagId() { + return flagId; + } + + public LongFilter flagId() { + if (flagId == null) { + flagId = new LongFilter(); + } + return flagId; + } + + public void setFlagId(LongFilter flagId) { + this.flagId = flagId; + } + + public LongFilter getSynonymId() { + return synonymId; + } + + public LongFilter synonymId() { + if (synonymId == null) { + synonymId = new LongFilter(); + } + return synonymId; + } + + public void setSynonymId(LongFilter synonymId) { + this.synonymId = synonymId; + } + + public LongFilter getAlterationId() { + return alterationId; + } + + public LongFilter alterationId() { + if (alterationId == null) { + alterationId = new LongFilter(); + } + return alterationId; + } + + public void setAlterationId(LongFilter alterationId) { + this.alterationId = alterationId; + } + + public Boolean getDistinct() { + return distinct; + } + + public void setDistinct(Boolean distinct) { + this.distinct = distinct; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final GeneCriteria that = (GeneCriteria) o; + return ( + Objects.equals(id, that.id) && + Objects.equals(entrezGeneId, that.entrezGeneId) && + Objects.equals(hugoSymbol, that.hugoSymbol) && + Objects.equals(hgncId, that.hgncId) && + Objects.equals(ensemblGeneId, that.ensemblGeneId) && + Objects.equals(evidenceId, that.evidenceId) && + Objects.equals(transcriptId, that.transcriptId) && + Objects.equals(flagId, that.flagId) && + Objects.equals(synonymId, that.synonymId) && + Objects.equals(alterationId, that.alterationId) && + Objects.equals(distinct, that.distinct) + ); + } + + @Override + public int hashCode() { + return Objects.hash( + id, + entrezGeneId, + hugoSymbol, + hgncId, + ensemblGeneId, + evidenceId, + transcriptId, + flagId, + synonymId, + alterationId, + distinct + ); + } + + // prettier-ignore + @Override + public String toString() { + return "GeneCriteria{" + + (id != null ? "id=" + id + ", " : "") + + (entrezGeneId != null ? "entrezGeneId=" + entrezGeneId + ", " : "") + + (hugoSymbol != null ? "hugoSymbol=" + hugoSymbol + ", " : "") + + (hgncId != null ? "hgncId=" + hgncId + ", " : "") + + (ensemblGeneId != null ? "ensemblGeneId=" + ensemblGeneId + ", " : "") + + (evidenceId != null ? "evidenceId=" + evidenceId + ", " : "") + + (transcriptId != null ? "transcriptId=" + transcriptId + ", " : "") + + (flagId != null ? "flagId=" + flagId + ", " : "") + + (synonymId != null ? "synonymId=" + synonymId + ", " : "") + + (alterationId != null ? "alterationId=" + alterationId + ", " : "") + + (distinct != null ? "distinct=" + distinct + ", " : "") + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/criteria/GenomeFragmentCriteria.java b/src/main/java/org/mskcc/oncokb/curation/service/criteria/GenomeFragmentCriteria.java new file mode 100644 index 000000000..e43a4a95c --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/criteria/GenomeFragmentCriteria.java @@ -0,0 +1,232 @@ +package org.mskcc.oncokb.curation.service.criteria; + +import java.io.Serializable; +import java.util.Objects; +import org.mskcc.oncokb.curation.domain.enumeration.GenomeFragmentType; +import tech.jhipster.service.Criteria; +import tech.jhipster.service.filter.BooleanFilter; +import tech.jhipster.service.filter.DoubleFilter; +import tech.jhipster.service.filter.Filter; +import tech.jhipster.service.filter.FloatFilter; +import tech.jhipster.service.filter.IntegerFilter; +import tech.jhipster.service.filter.LongFilter; +import tech.jhipster.service.filter.StringFilter; + +/** + * Criteria class for the {@link org.mskcc.oncokb.curation.domain.GenomeFragment} entity. This class is used + * in {@link org.mskcc.oncokb.curation.web.rest.GenomeFragmentResource} to receive all the possible filtering options from + * the Http GET request parameters. + * For example the following could be a valid request: + * {@code /genome-fragments?id.greaterThan=5&attr1.contains=something&attr2.specified=false} + * As Spring is unable to properly convert the types, unless specific {@link Filter} class are used, we need to use + * fix type specific filters. + */ +public class GenomeFragmentCriteria implements Serializable, Criteria { + + /** + * Class for filtering GenomeFragmentType + */ + public static class GenomeFragmentTypeFilter extends Filter { + + public GenomeFragmentTypeFilter() {} + + public GenomeFragmentTypeFilter(GenomeFragmentTypeFilter filter) { + super(filter); + } + + @Override + public GenomeFragmentTypeFilter copy() { + return new GenomeFragmentTypeFilter(this); + } + } + + private static final long serialVersionUID = 1L; + + private LongFilter id; + + private IntegerFilter start; + + private IntegerFilter end; + + private IntegerFilter strand; + + private GenomeFragmentTypeFilter type; + + private LongFilter seqRegionId; + + private LongFilter transcriptId; + + private Boolean distinct; + + public GenomeFragmentCriteria() {} + + public GenomeFragmentCriteria(GenomeFragmentCriteria other) { + this.id = other.id == null ? null : other.id.copy(); + this.start = other.start == null ? null : other.start.copy(); + this.end = other.end == null ? null : other.end.copy(); + this.strand = other.strand == null ? null : other.strand.copy(); + this.type = other.type == null ? null : other.type.copy(); + this.seqRegionId = other.seqRegionId == null ? null : other.seqRegionId.copy(); + this.transcriptId = other.transcriptId == null ? null : other.transcriptId.copy(); + this.distinct = other.distinct; + } + + @Override + public GenomeFragmentCriteria copy() { + return new GenomeFragmentCriteria(this); + } + + public LongFilter getId() { + return id; + } + + public LongFilter id() { + if (id == null) { + id = new LongFilter(); + } + return id; + } + + public void setId(LongFilter id) { + this.id = id; + } + + public IntegerFilter getStart() { + return start; + } + + public IntegerFilter start() { + if (start == null) { + start = new IntegerFilter(); + } + return start; + } + + public void setStart(IntegerFilter start) { + this.start = start; + } + + public IntegerFilter getEnd() { + return end; + } + + public IntegerFilter end() { + if (end == null) { + end = new IntegerFilter(); + } + return end; + } + + public void setEnd(IntegerFilter end) { + this.end = end; + } + + public IntegerFilter getStrand() { + return strand; + } + + public IntegerFilter strand() { + if (strand == null) { + strand = new IntegerFilter(); + } + return strand; + } + + public void setStrand(IntegerFilter strand) { + this.strand = strand; + } + + public GenomeFragmentTypeFilter getType() { + return type; + } + + public GenomeFragmentTypeFilter type() { + if (type == null) { + type = new GenomeFragmentTypeFilter(); + } + return type; + } + + public void setType(GenomeFragmentTypeFilter type) { + this.type = type; + } + + public LongFilter getSeqRegionId() { + return seqRegionId; + } + + public LongFilter seqRegionId() { + if (seqRegionId == null) { + seqRegionId = new LongFilter(); + } + return seqRegionId; + } + + public void setSeqRegionId(LongFilter seqRegionId) { + this.seqRegionId = seqRegionId; + } + + public LongFilter getTranscriptId() { + return transcriptId; + } + + public LongFilter transcriptId() { + if (transcriptId == null) { + transcriptId = new LongFilter(); + } + return transcriptId; + } + + public void setTranscriptId(LongFilter transcriptId) { + this.transcriptId = transcriptId; + } + + public Boolean getDistinct() { + return distinct; + } + + public void setDistinct(Boolean distinct) { + this.distinct = distinct; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final GenomeFragmentCriteria that = (GenomeFragmentCriteria) o; + return ( + Objects.equals(id, that.id) && + Objects.equals(start, that.start) && + Objects.equals(end, that.end) && + Objects.equals(strand, that.strand) && + Objects.equals(type, that.type) && + Objects.equals(seqRegionId, that.seqRegionId) && + Objects.equals(transcriptId, that.transcriptId) && + Objects.equals(distinct, that.distinct) + ); + } + + @Override + public int hashCode() { + return Objects.hash(id, start, end, strand, type, seqRegionId, transcriptId, distinct); + } + + // prettier-ignore + @Override + public String toString() { + return "GenomeFragmentCriteria{" + + (id != null ? "id=" + id + ", " : "") + + (start != null ? "start=" + start + ", " : "") + + (end != null ? "end=" + end + ", " : "") + + (strand != null ? "strand=" + strand + ", " : "") + + (type != null ? "type=" + type + ", " : "") + + (seqRegionId != null ? "seqRegionId=" + seqRegionId + ", " : "") + + (transcriptId != null ? "transcriptId=" + transcriptId + ", " : "") + + (distinct != null ? "distinct=" + distinct + ", " : "") + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/criteria/GenomicIndicatorCriteria.java b/src/main/java/org/mskcc/oncokb/curation/service/criteria/GenomicIndicatorCriteria.java new file mode 100644 index 000000000..01a1fb147 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/criteria/GenomicIndicatorCriteria.java @@ -0,0 +1,194 @@ +package org.mskcc.oncokb.curation.service.criteria; + +import java.io.Serializable; +import java.util.Objects; +import tech.jhipster.service.Criteria; +import tech.jhipster.service.filter.BooleanFilter; +import tech.jhipster.service.filter.DoubleFilter; +import tech.jhipster.service.filter.Filter; +import tech.jhipster.service.filter.FloatFilter; +import tech.jhipster.service.filter.IntegerFilter; +import tech.jhipster.service.filter.LongFilter; +import tech.jhipster.service.filter.StringFilter; + +/** + * Criteria class for the {@link org.mskcc.oncokb.curation.domain.GenomicIndicator} entity. This class is used + * in {@link org.mskcc.oncokb.curation.web.rest.GenomicIndicatorResource} to receive all the possible filtering options from + * the Http GET request parameters. + * For example the following could be a valid request: + * {@code /genomic-indicators?id.greaterThan=5&attr1.contains=something&attr2.specified=false} + * As Spring is unable to properly convert the types, unless specific {@link Filter} class are used, we need to use + * fix type specific filters. + */ +public class GenomicIndicatorCriteria implements Serializable, Criteria { + + private static final long serialVersionUID = 1L; + + private LongFilter id; + + private StringFilter uuid; + + private StringFilter type; + + private StringFilter name; + + private LongFilter alleleStateId; + + private LongFilter associationId; + + private Boolean distinct; + + public GenomicIndicatorCriteria() {} + + public GenomicIndicatorCriteria(GenomicIndicatorCriteria other) { + this.id = other.id == null ? null : other.id.copy(); + this.uuid = other.uuid == null ? null : other.uuid.copy(); + this.type = other.type == null ? null : other.type.copy(); + this.name = other.name == null ? null : other.name.copy(); + this.alleleStateId = other.alleleStateId == null ? null : other.alleleStateId.copy(); + this.associationId = other.associationId == null ? null : other.associationId.copy(); + this.distinct = other.distinct; + } + + @Override + public GenomicIndicatorCriteria copy() { + return new GenomicIndicatorCriteria(this); + } + + public LongFilter getId() { + return id; + } + + public LongFilter id() { + if (id == null) { + id = new LongFilter(); + } + return id; + } + + public void setId(LongFilter id) { + this.id = id; + } + + public StringFilter getUuid() { + return uuid; + } + + public StringFilter uuid() { + if (uuid == null) { + uuid = new StringFilter(); + } + return uuid; + } + + public void setUuid(StringFilter uuid) { + this.uuid = uuid; + } + + public StringFilter getType() { + return type; + } + + public StringFilter type() { + if (type == null) { + type = new StringFilter(); + } + return type; + } + + public void setType(StringFilter type) { + this.type = type; + } + + public StringFilter getName() { + return name; + } + + public StringFilter name() { + if (name == null) { + name = new StringFilter(); + } + return name; + } + + public void setName(StringFilter name) { + this.name = name; + } + + public LongFilter getAlleleStateId() { + return alleleStateId; + } + + public LongFilter alleleStateId() { + if (alleleStateId == null) { + alleleStateId = new LongFilter(); + } + return alleleStateId; + } + + public void setAlleleStateId(LongFilter alleleStateId) { + this.alleleStateId = alleleStateId; + } + + public LongFilter getAssociationId() { + return associationId; + } + + public LongFilter associationId() { + if (associationId == null) { + associationId = new LongFilter(); + } + return associationId; + } + + public void setAssociationId(LongFilter associationId) { + this.associationId = associationId; + } + + public Boolean getDistinct() { + return distinct; + } + + public void setDistinct(Boolean distinct) { + this.distinct = distinct; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final GenomicIndicatorCriteria that = (GenomicIndicatorCriteria) o; + return ( + Objects.equals(id, that.id) && + Objects.equals(uuid, that.uuid) && + Objects.equals(type, that.type) && + Objects.equals(name, that.name) && + Objects.equals(alleleStateId, that.alleleStateId) && + Objects.equals(associationId, that.associationId) && + Objects.equals(distinct, that.distinct) + ); + } + + @Override + public int hashCode() { + return Objects.hash(id, uuid, type, name, alleleStateId, associationId, distinct); + } + + // prettier-ignore + @Override + public String toString() { + return "GenomicIndicatorCriteria{" + + (id != null ? "id=" + id + ", " : "") + + (uuid != null ? "uuid=" + uuid + ", " : "") + + (type != null ? "type=" + type + ", " : "") + + (name != null ? "name=" + name + ", " : "") + + (alleleStateId != null ? "alleleStateId=" + alleleStateId + ", " : "") + + (associationId != null ? "associationId=" + associationId + ", " : "") + + (distinct != null ? "distinct=" + distinct + ", " : "") + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/criteria/HistoryCriteria.java b/src/main/java/org/mskcc/oncokb/curation/service/criteria/HistoryCriteria.java new file mode 100644 index 000000000..a57510028 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/criteria/HistoryCriteria.java @@ -0,0 +1,195 @@ +package org.mskcc.oncokb.curation.service.criteria; + +import java.io.Serializable; +import java.util.Objects; +import tech.jhipster.service.Criteria; +import tech.jhipster.service.filter.BooleanFilter; +import tech.jhipster.service.filter.DoubleFilter; +import tech.jhipster.service.filter.Filter; +import tech.jhipster.service.filter.FloatFilter; +import tech.jhipster.service.filter.InstantFilter; +import tech.jhipster.service.filter.IntegerFilter; +import tech.jhipster.service.filter.LongFilter; +import tech.jhipster.service.filter.StringFilter; + +/** + * Criteria class for the {@link org.mskcc.oncokb.curation.domain.History} entity. This class is used + * in {@link org.mskcc.oncokb.curation.web.rest.HistoryResource} to receive all the possible filtering options from + * the Http GET request parameters. + * For example the following could be a valid request: + * {@code /histories?id.greaterThan=5&attr1.contains=something&attr2.specified=false} + * As Spring is unable to properly convert the types, unless specific {@link Filter} class are used, we need to use + * fix type specific filters. + */ +public class HistoryCriteria implements Serializable, Criteria { + + private static final long serialVersionUID = 1L; + + private LongFilter id; + + private StringFilter type; + + private InstantFilter updatedTime; + + private StringFilter updatedBy; + + private StringFilter entityName; + + private IntegerFilter entityId; + + private Boolean distinct; + + public HistoryCriteria() {} + + public HistoryCriteria(HistoryCriteria other) { + this.id = other.id == null ? null : other.id.copy(); + this.type = other.type == null ? null : other.type.copy(); + this.updatedTime = other.updatedTime == null ? null : other.updatedTime.copy(); + this.updatedBy = other.updatedBy == null ? null : other.updatedBy.copy(); + this.entityName = other.entityName == null ? null : other.entityName.copy(); + this.entityId = other.entityId == null ? null : other.entityId.copy(); + this.distinct = other.distinct; + } + + @Override + public HistoryCriteria copy() { + return new HistoryCriteria(this); + } + + public LongFilter getId() { + return id; + } + + public LongFilter id() { + if (id == null) { + id = new LongFilter(); + } + return id; + } + + public void setId(LongFilter id) { + this.id = id; + } + + public StringFilter getType() { + return type; + } + + public StringFilter type() { + if (type == null) { + type = new StringFilter(); + } + return type; + } + + public void setType(StringFilter type) { + this.type = type; + } + + public InstantFilter getUpdatedTime() { + return updatedTime; + } + + public InstantFilter updatedTime() { + if (updatedTime == null) { + updatedTime = new InstantFilter(); + } + return updatedTime; + } + + public void setUpdatedTime(InstantFilter updatedTime) { + this.updatedTime = updatedTime; + } + + public StringFilter getUpdatedBy() { + return updatedBy; + } + + public StringFilter updatedBy() { + if (updatedBy == null) { + updatedBy = new StringFilter(); + } + return updatedBy; + } + + public void setUpdatedBy(StringFilter updatedBy) { + this.updatedBy = updatedBy; + } + + public StringFilter getEntityName() { + return entityName; + } + + public StringFilter entityName() { + if (entityName == null) { + entityName = new StringFilter(); + } + return entityName; + } + + public void setEntityName(StringFilter entityName) { + this.entityName = entityName; + } + + public IntegerFilter getEntityId() { + return entityId; + } + + public IntegerFilter entityId() { + if (entityId == null) { + entityId = new IntegerFilter(); + } + return entityId; + } + + public void setEntityId(IntegerFilter entityId) { + this.entityId = entityId; + } + + public Boolean getDistinct() { + return distinct; + } + + public void setDistinct(Boolean distinct) { + this.distinct = distinct; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final HistoryCriteria that = (HistoryCriteria) o; + return ( + Objects.equals(id, that.id) && + Objects.equals(type, that.type) && + Objects.equals(updatedTime, that.updatedTime) && + Objects.equals(updatedBy, that.updatedBy) && + Objects.equals(entityName, that.entityName) && + Objects.equals(entityId, that.entityId) && + Objects.equals(distinct, that.distinct) + ); + } + + @Override + public int hashCode() { + return Objects.hash(id, type, updatedTime, updatedBy, entityName, entityId, distinct); + } + + // prettier-ignore + @Override + public String toString() { + return "HistoryCriteria{" + + (id != null ? "id=" + id + ", " : "") + + (type != null ? "type=" + type + ", " : "") + + (updatedTime != null ? "updatedTime=" + updatedTime + ", " : "") + + (updatedBy != null ? "updatedBy=" + updatedBy + ", " : "") + + (entityName != null ? "entityName=" + entityName + ", " : "") + + (entityId != null ? "entityId=" + entityId + ", " : "") + + (distinct != null ? "distinct=" + distinct + ", " : "") + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/criteria/NciThesaurusCriteria.java b/src/main/java/org/mskcc/oncokb/curation/service/criteria/NciThesaurusCriteria.java new file mode 100644 index 000000000..dbe6b02ea --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/criteria/NciThesaurusCriteria.java @@ -0,0 +1,194 @@ +package org.mskcc.oncokb.curation.service.criteria; + +import java.io.Serializable; +import java.util.Objects; +import tech.jhipster.service.Criteria; +import tech.jhipster.service.filter.BooleanFilter; +import tech.jhipster.service.filter.DoubleFilter; +import tech.jhipster.service.filter.Filter; +import tech.jhipster.service.filter.FloatFilter; +import tech.jhipster.service.filter.IntegerFilter; +import tech.jhipster.service.filter.LongFilter; +import tech.jhipster.service.filter.StringFilter; + +/** + * Criteria class for the {@link org.mskcc.oncokb.curation.domain.NciThesaurus} entity. This class is used + * in {@link org.mskcc.oncokb.curation.web.rest.NciThesaurusResource} to receive all the possible filtering options from + * the Http GET request parameters. + * For example the following could be a valid request: + * {@code /nci-thesauruses?id.greaterThan=5&attr1.contains=something&attr2.specified=false} + * As Spring is unable to properly convert the types, unless specific {@link Filter} class are used, we need to use + * fix type specific filters. + */ +public class NciThesaurusCriteria implements Serializable, Criteria { + + private static final long serialVersionUID = 1L; + + private LongFilter id; + + private StringFilter version; + + private StringFilter code; + + private StringFilter preferredName; + + private StringFilter displayName; + + private LongFilter synonymId; + + private Boolean distinct; + + public NciThesaurusCriteria() {} + + public NciThesaurusCriteria(NciThesaurusCriteria other) { + this.id = other.id == null ? null : other.id.copy(); + this.version = other.version == null ? null : other.version.copy(); + this.code = other.code == null ? null : other.code.copy(); + this.preferredName = other.preferredName == null ? null : other.preferredName.copy(); + this.displayName = other.displayName == null ? null : other.displayName.copy(); + this.synonymId = other.synonymId == null ? null : other.synonymId.copy(); + this.distinct = other.distinct; + } + + @Override + public NciThesaurusCriteria copy() { + return new NciThesaurusCriteria(this); + } + + public LongFilter getId() { + return id; + } + + public LongFilter id() { + if (id == null) { + id = new LongFilter(); + } + return id; + } + + public void setId(LongFilter id) { + this.id = id; + } + + public StringFilter getVersion() { + return version; + } + + public StringFilter version() { + if (version == null) { + version = new StringFilter(); + } + return version; + } + + public void setVersion(StringFilter version) { + this.version = version; + } + + public StringFilter getCode() { + return code; + } + + public StringFilter code() { + if (code == null) { + code = new StringFilter(); + } + return code; + } + + public void setCode(StringFilter code) { + this.code = code; + } + + public StringFilter getPreferredName() { + return preferredName; + } + + public StringFilter preferredName() { + if (preferredName == null) { + preferredName = new StringFilter(); + } + return preferredName; + } + + public void setPreferredName(StringFilter preferredName) { + this.preferredName = preferredName; + } + + public StringFilter getDisplayName() { + return displayName; + } + + public StringFilter displayName() { + if (displayName == null) { + displayName = new StringFilter(); + } + return displayName; + } + + public void setDisplayName(StringFilter displayName) { + this.displayName = displayName; + } + + public LongFilter getSynonymId() { + return synonymId; + } + + public LongFilter synonymId() { + if (synonymId == null) { + synonymId = new LongFilter(); + } + return synonymId; + } + + public void setSynonymId(LongFilter synonymId) { + this.synonymId = synonymId; + } + + public Boolean getDistinct() { + return distinct; + } + + public void setDistinct(Boolean distinct) { + this.distinct = distinct; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final NciThesaurusCriteria that = (NciThesaurusCriteria) o; + return ( + Objects.equals(id, that.id) && + Objects.equals(version, that.version) && + Objects.equals(code, that.code) && + Objects.equals(preferredName, that.preferredName) && + Objects.equals(displayName, that.displayName) && + Objects.equals(synonymId, that.synonymId) && + Objects.equals(distinct, that.distinct) + ); + } + + @Override + public int hashCode() { + return Objects.hash(id, version, code, preferredName, displayName, synonymId, distinct); + } + + // prettier-ignore + @Override + public String toString() { + return "NciThesaurusCriteria{" + + (id != null ? "id=" + id + ", " : "") + + (version != null ? "version=" + version + ", " : "") + + (code != null ? "code=" + code + ", " : "") + + (preferredName != null ? "preferredName=" + preferredName + ", " : "") + + (displayName != null ? "displayName=" + displayName + ", " : "") + + (synonymId != null ? "synonymId=" + synonymId + ", " : "") + + (distinct != null ? "distinct=" + distinct + ", " : "") + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/criteria/SequenceCriteria.java b/src/main/java/org/mskcc/oncokb/curation/service/criteria/SequenceCriteria.java new file mode 100644 index 000000000..0b7906db4 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/criteria/SequenceCriteria.java @@ -0,0 +1,152 @@ +package org.mskcc.oncokb.curation.service.criteria; + +import java.io.Serializable; +import java.util.Objects; +import org.mskcc.oncokb.curation.domain.enumeration.SequenceType; +import tech.jhipster.service.Criteria; +import tech.jhipster.service.filter.BooleanFilter; +import tech.jhipster.service.filter.DoubleFilter; +import tech.jhipster.service.filter.Filter; +import tech.jhipster.service.filter.FloatFilter; +import tech.jhipster.service.filter.IntegerFilter; +import tech.jhipster.service.filter.LongFilter; +import tech.jhipster.service.filter.StringFilter; + +/** + * Criteria class for the {@link org.mskcc.oncokb.curation.domain.Sequence} entity. This class is used + * in {@link org.mskcc.oncokb.curation.web.rest.SequenceResource} to receive all the possible filtering options from + * the Http GET request parameters. + * For example the following could be a valid request: + * {@code /sequences?id.greaterThan=5&attr1.contains=something&attr2.specified=false} + * As Spring is unable to properly convert the types, unless specific {@link Filter} class are used, we need to use + * fix type specific filters. + */ +public class SequenceCriteria implements Serializable, Criteria { + + /** + * Class for filtering SequenceType + */ + public static class SequenceTypeFilter extends Filter { + + public SequenceTypeFilter() {} + + public SequenceTypeFilter(SequenceTypeFilter filter) { + super(filter); + } + + @Override + public SequenceTypeFilter copy() { + return new SequenceTypeFilter(this); + } + } + + private static final long serialVersionUID = 1L; + + private LongFilter id; + + private SequenceTypeFilter sequenceType; + + private LongFilter transcriptId; + + private Boolean distinct; + + public SequenceCriteria() {} + + public SequenceCriteria(SequenceCriteria other) { + this.id = other.id == null ? null : other.id.copy(); + this.sequenceType = other.sequenceType == null ? null : other.sequenceType.copy(); + this.transcriptId = other.transcriptId == null ? null : other.transcriptId.copy(); + this.distinct = other.distinct; + } + + @Override + public SequenceCriteria copy() { + return new SequenceCriteria(this); + } + + public LongFilter getId() { + return id; + } + + public LongFilter id() { + if (id == null) { + id = new LongFilter(); + } + return id; + } + + public void setId(LongFilter id) { + this.id = id; + } + + public SequenceTypeFilter getSequenceType() { + return sequenceType; + } + + public SequenceTypeFilter sequenceType() { + if (sequenceType == null) { + sequenceType = new SequenceTypeFilter(); + } + return sequenceType; + } + + public void setSequenceType(SequenceTypeFilter sequenceType) { + this.sequenceType = sequenceType; + } + + public LongFilter getTranscriptId() { + return transcriptId; + } + + public LongFilter transcriptId() { + if (transcriptId == null) { + transcriptId = new LongFilter(); + } + return transcriptId; + } + + public void setTranscriptId(LongFilter transcriptId) { + this.transcriptId = transcriptId; + } + + public Boolean getDistinct() { + return distinct; + } + + public void setDistinct(Boolean distinct) { + this.distinct = distinct; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final SequenceCriteria that = (SequenceCriteria) o; + return ( + Objects.equals(id, that.id) && + Objects.equals(sequenceType, that.sequenceType) && + Objects.equals(transcriptId, that.transcriptId) && + Objects.equals(distinct, that.distinct) + ); + } + + @Override + public int hashCode() { + return Objects.hash(id, sequenceType, transcriptId, distinct); + } + + // prettier-ignore + @Override + public String toString() { + return "SequenceCriteria{" + + (id != null ? "id=" + id + ", " : "") + + (sequenceType != null ? "sequenceType=" + sequenceType + ", " : "") + + (transcriptId != null ? "transcriptId=" + transcriptId + ", " : "") + + (distinct != null ? "distinct=" + distinct + ", " : "") + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/criteria/SynonymCriteria.java b/src/main/java/org/mskcc/oncokb/curation/service/criteria/SynonymCriteria.java new file mode 100644 index 000000000..9a723943b --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/criteria/SynonymCriteria.java @@ -0,0 +1,254 @@ +package org.mskcc.oncokb.curation.service.criteria; + +import java.io.Serializable; +import java.util.Objects; +import tech.jhipster.service.Criteria; +import tech.jhipster.service.filter.BooleanFilter; +import tech.jhipster.service.filter.DoubleFilter; +import tech.jhipster.service.filter.Filter; +import tech.jhipster.service.filter.FloatFilter; +import tech.jhipster.service.filter.IntegerFilter; +import tech.jhipster.service.filter.LongFilter; +import tech.jhipster.service.filter.StringFilter; + +/** + * Criteria class for the {@link org.mskcc.oncokb.curation.domain.Synonym} entity. This class is used + * in {@link org.mskcc.oncokb.curation.web.rest.SynonymResource} to receive all the possible filtering options from + * the Http GET request parameters. + * For example the following could be a valid request: + * {@code /synonyms?id.greaterThan=5&attr1.contains=something&attr2.specified=false} + * As Spring is unable to properly convert the types, unless specific {@link Filter} class are used, we need to use + * fix type specific filters. + */ +public class SynonymCriteria implements Serializable, Criteria { + + private static final long serialVersionUID = 1L; + + private LongFilter id; + + private StringFilter type; + + private StringFilter source; + + private StringFilter code; + + private StringFilter name; + + private LongFilter articleId; + + private LongFilter cancerTypeId; + + private LongFilter geneId; + + private LongFilter nciThesaurusId; + + private Boolean distinct; + + public SynonymCriteria() {} + + public SynonymCriteria(SynonymCriteria other) { + this.id = other.id == null ? null : other.id.copy(); + this.type = other.type == null ? null : other.type.copy(); + this.source = other.source == null ? null : other.source.copy(); + this.code = other.code == null ? null : other.code.copy(); + this.name = other.name == null ? null : other.name.copy(); + this.articleId = other.articleId == null ? null : other.articleId.copy(); + this.cancerTypeId = other.cancerTypeId == null ? null : other.cancerTypeId.copy(); + this.geneId = other.geneId == null ? null : other.geneId.copy(); + this.nciThesaurusId = other.nciThesaurusId == null ? null : other.nciThesaurusId.copy(); + this.distinct = other.distinct; + } + + @Override + public SynonymCriteria copy() { + return new SynonymCriteria(this); + } + + public LongFilter getId() { + return id; + } + + public LongFilter id() { + if (id == null) { + id = new LongFilter(); + } + return id; + } + + public void setId(LongFilter id) { + this.id = id; + } + + public StringFilter getType() { + return type; + } + + public StringFilter type() { + if (type == null) { + type = new StringFilter(); + } + return type; + } + + public void setType(StringFilter type) { + this.type = type; + } + + public StringFilter getSource() { + return source; + } + + public StringFilter source() { + if (source == null) { + source = new StringFilter(); + } + return source; + } + + public void setSource(StringFilter source) { + this.source = source; + } + + public StringFilter getCode() { + return code; + } + + public StringFilter code() { + if (code == null) { + code = new StringFilter(); + } + return code; + } + + public void setCode(StringFilter code) { + this.code = code; + } + + public StringFilter getName() { + return name; + } + + public StringFilter name() { + if (name == null) { + name = new StringFilter(); + } + return name; + } + + public void setName(StringFilter name) { + this.name = name; + } + + public LongFilter getArticleId() { + return articleId; + } + + public LongFilter articleId() { + if (articleId == null) { + articleId = new LongFilter(); + } + return articleId; + } + + public void setArticleId(LongFilter articleId) { + this.articleId = articleId; + } + + public LongFilter getCancerTypeId() { + return cancerTypeId; + } + + public LongFilter cancerTypeId() { + if (cancerTypeId == null) { + cancerTypeId = new LongFilter(); + } + return cancerTypeId; + } + + public void setCancerTypeId(LongFilter cancerTypeId) { + this.cancerTypeId = cancerTypeId; + } + + public LongFilter getGeneId() { + return geneId; + } + + public LongFilter geneId() { + if (geneId == null) { + geneId = new LongFilter(); + } + return geneId; + } + + public void setGeneId(LongFilter geneId) { + this.geneId = geneId; + } + + public LongFilter getNciThesaurusId() { + return nciThesaurusId; + } + + public LongFilter nciThesaurusId() { + if (nciThesaurusId == null) { + nciThesaurusId = new LongFilter(); + } + return nciThesaurusId; + } + + public void setNciThesaurusId(LongFilter nciThesaurusId) { + this.nciThesaurusId = nciThesaurusId; + } + + public Boolean getDistinct() { + return distinct; + } + + public void setDistinct(Boolean distinct) { + this.distinct = distinct; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final SynonymCriteria that = (SynonymCriteria) o; + return ( + Objects.equals(id, that.id) && + Objects.equals(type, that.type) && + Objects.equals(source, that.source) && + Objects.equals(code, that.code) && + Objects.equals(name, that.name) && + Objects.equals(articleId, that.articleId) && + Objects.equals(cancerTypeId, that.cancerTypeId) && + Objects.equals(geneId, that.geneId) && + Objects.equals(nciThesaurusId, that.nciThesaurusId) && + Objects.equals(distinct, that.distinct) + ); + } + + @Override + public int hashCode() { + return Objects.hash(id, type, source, code, name, articleId, cancerTypeId, geneId, nciThesaurusId, distinct); + } + + // prettier-ignore + @Override + public String toString() { + return "SynonymCriteria{" + + (id != null ? "id=" + id + ", " : "") + + (type != null ? "type=" + type + ", " : "") + + (source != null ? "source=" + source + ", " : "") + + (code != null ? "code=" + code + ", " : "") + + (name != null ? "name=" + name + ", " : "") + + (articleId != null ? "articleId=" + articleId + ", " : "") + + (cancerTypeId != null ? "cancerTypeId=" + cancerTypeId + ", " : "") + + (geneId != null ? "geneId=" + geneId + ", " : "") + + (nciThesaurusId != null ? "nciThesaurusId=" + nciThesaurusId + ", " : "") + + (distinct != null ? "distinct=" + distinct + ", " : "") + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/criteria/TranscriptCriteria.java b/src/main/java/org/mskcc/oncokb/curation/service/criteria/TranscriptCriteria.java new file mode 100644 index 000000000..4477d265c --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/criteria/TranscriptCriteria.java @@ -0,0 +1,367 @@ +package org.mskcc.oncokb.curation.service.criteria; + +import java.io.Serializable; +import java.util.Objects; +import org.mskcc.oncokb.curation.domain.enumeration.ReferenceGenome; +import tech.jhipster.service.Criteria; +import tech.jhipster.service.filter.BooleanFilter; +import tech.jhipster.service.filter.DoubleFilter; +import tech.jhipster.service.filter.Filter; +import tech.jhipster.service.filter.FloatFilter; +import tech.jhipster.service.filter.IntegerFilter; +import tech.jhipster.service.filter.LongFilter; +import tech.jhipster.service.filter.StringFilter; + +/** + * Criteria class for the {@link org.mskcc.oncokb.curation.domain.Transcript} entity. This class is used + * in {@link org.mskcc.oncokb.curation.web.rest.TranscriptResource} to receive all the possible filtering options from + * the Http GET request parameters. + * For example the following could be a valid request: + * {@code /transcripts?id.greaterThan=5&attr1.contains=something&attr2.specified=false} + * As Spring is unable to properly convert the types, unless specific {@link Filter} class are used, we need to use + * fix type specific filters. + */ +public class TranscriptCriteria implements Serializable, Criteria { + + /** + * Class for filtering ReferenceGenome + */ + public static class ReferenceGenomeFilter extends Filter { + + public ReferenceGenomeFilter() {} + + public ReferenceGenomeFilter(ReferenceGenomeFilter filter) { + super(filter); + } + + @Override + public ReferenceGenomeFilter copy() { + return new ReferenceGenomeFilter(this); + } + } + + private static final long serialVersionUID = 1L; + + private LongFilter id; + + private ReferenceGenomeFilter referenceGenome; + + private StringFilter ensemblTranscriptId; + + private BooleanFilter canonical; + + private StringFilter ensemblProteinId; + + private StringFilter referenceSequenceId; + + private StringFilter description; + + private LongFilter sequenceId; + + private LongFilter fragmentsId; + + private LongFilter flagId; + + private LongFilter ensemblGeneId; + + private LongFilter geneId; + + private LongFilter alterationId; + + private Boolean distinct; + + public TranscriptCriteria() {} + + public TranscriptCriteria(TranscriptCriteria other) { + this.id = other.id == null ? null : other.id.copy(); + this.referenceGenome = other.referenceGenome == null ? null : other.referenceGenome.copy(); + this.ensemblTranscriptId = other.ensemblTranscriptId == null ? null : other.ensemblTranscriptId.copy(); + this.canonical = other.canonical == null ? null : other.canonical.copy(); + this.ensemblProteinId = other.ensemblProteinId == null ? null : other.ensemblProteinId.copy(); + this.referenceSequenceId = other.referenceSequenceId == null ? null : other.referenceSequenceId.copy(); + this.description = other.description == null ? null : other.description.copy(); + this.sequenceId = other.sequenceId == null ? null : other.sequenceId.copy(); + this.fragmentsId = other.fragmentsId == null ? null : other.fragmentsId.copy(); + this.flagId = other.flagId == null ? null : other.flagId.copy(); + this.ensemblGeneId = other.ensemblGeneId == null ? null : other.ensemblGeneId.copy(); + this.geneId = other.geneId == null ? null : other.geneId.copy(); + this.alterationId = other.alterationId == null ? null : other.alterationId.copy(); + this.distinct = other.distinct; + } + + @Override + public TranscriptCriteria copy() { + return new TranscriptCriteria(this); + } + + public LongFilter getId() { + return id; + } + + public LongFilter id() { + if (id == null) { + id = new LongFilter(); + } + return id; + } + + public void setId(LongFilter id) { + this.id = id; + } + + public ReferenceGenomeFilter getReferenceGenome() { + return referenceGenome; + } + + public ReferenceGenomeFilter referenceGenome() { + if (referenceGenome == null) { + referenceGenome = new ReferenceGenomeFilter(); + } + return referenceGenome; + } + + public void setReferenceGenome(ReferenceGenomeFilter referenceGenome) { + this.referenceGenome = referenceGenome; + } + + public StringFilter getEnsemblTranscriptId() { + return ensemblTranscriptId; + } + + public StringFilter ensemblTranscriptId() { + if (ensemblTranscriptId == null) { + ensemblTranscriptId = new StringFilter(); + } + return ensemblTranscriptId; + } + + public void setEnsemblTranscriptId(StringFilter ensemblTranscriptId) { + this.ensemblTranscriptId = ensemblTranscriptId; + } + + public BooleanFilter getCanonical() { + return canonical; + } + + public BooleanFilter canonical() { + if (canonical == null) { + canonical = new BooleanFilter(); + } + return canonical; + } + + public void setCanonical(BooleanFilter canonical) { + this.canonical = canonical; + } + + public StringFilter getEnsemblProteinId() { + return ensemblProteinId; + } + + public StringFilter ensemblProteinId() { + if (ensemblProteinId == null) { + ensemblProteinId = new StringFilter(); + } + return ensemblProteinId; + } + + public void setEnsemblProteinId(StringFilter ensemblProteinId) { + this.ensemblProteinId = ensemblProteinId; + } + + public StringFilter getReferenceSequenceId() { + return referenceSequenceId; + } + + public StringFilter referenceSequenceId() { + if (referenceSequenceId == null) { + referenceSequenceId = new StringFilter(); + } + return referenceSequenceId; + } + + public void setReferenceSequenceId(StringFilter referenceSequenceId) { + this.referenceSequenceId = referenceSequenceId; + } + + public StringFilter getDescription() { + return description; + } + + public StringFilter description() { + if (description == null) { + description = new StringFilter(); + } + return description; + } + + public void setDescription(StringFilter description) { + this.description = description; + } + + public LongFilter getSequenceId() { + return sequenceId; + } + + public LongFilter sequenceId() { + if (sequenceId == null) { + sequenceId = new LongFilter(); + } + return sequenceId; + } + + public void setSequenceId(LongFilter sequenceId) { + this.sequenceId = sequenceId; + } + + public LongFilter getFragmentsId() { + return fragmentsId; + } + + public LongFilter fragmentsId() { + if (fragmentsId == null) { + fragmentsId = new LongFilter(); + } + return fragmentsId; + } + + public void setFragmentsId(LongFilter fragmentsId) { + this.fragmentsId = fragmentsId; + } + + public LongFilter getFlagId() { + return flagId; + } + + public LongFilter flagId() { + if (flagId == null) { + flagId = new LongFilter(); + } + return flagId; + } + + public void setFlagId(LongFilter flagId) { + this.flagId = flagId; + } + + public LongFilter getEnsemblGeneId() { + return ensemblGeneId; + } + + public LongFilter ensemblGeneId() { + if (ensemblGeneId == null) { + ensemblGeneId = new LongFilter(); + } + return ensemblGeneId; + } + + public void setEnsemblGeneId(LongFilter ensemblGeneId) { + this.ensemblGeneId = ensemblGeneId; + } + + public LongFilter getGeneId() { + return geneId; + } + + public LongFilter geneId() { + if (geneId == null) { + geneId = new LongFilter(); + } + return geneId; + } + + public void setGeneId(LongFilter geneId) { + this.geneId = geneId; + } + + public LongFilter getAlterationId() { + return alterationId; + } + + public LongFilter alterationId() { + if (alterationId == null) { + alterationId = new LongFilter(); + } + return alterationId; + } + + public void setAlterationId(LongFilter alterationId) { + this.alterationId = alterationId; + } + + public Boolean getDistinct() { + return distinct; + } + + public void setDistinct(Boolean distinct) { + this.distinct = distinct; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final TranscriptCriteria that = (TranscriptCriteria) o; + return ( + Objects.equals(id, that.id) && + Objects.equals(referenceGenome, that.referenceGenome) && + Objects.equals(ensemblTranscriptId, that.ensemblTranscriptId) && + Objects.equals(canonical, that.canonical) && + Objects.equals(ensemblProteinId, that.ensemblProteinId) && + Objects.equals(referenceSequenceId, that.referenceSequenceId) && + Objects.equals(description, that.description) && + Objects.equals(sequenceId, that.sequenceId) && + Objects.equals(fragmentsId, that.fragmentsId) && + Objects.equals(flagId, that.flagId) && + Objects.equals(ensemblGeneId, that.ensemblGeneId) && + Objects.equals(geneId, that.geneId) && + Objects.equals(alterationId, that.alterationId) && + Objects.equals(distinct, that.distinct) + ); + } + + @Override + public int hashCode() { + return Objects.hash( + id, + referenceGenome, + ensemblTranscriptId, + canonical, + ensemblProteinId, + referenceSequenceId, + description, + sequenceId, + fragmentsId, + flagId, + ensemblGeneId, + geneId, + alterationId, + distinct + ); + } + + // prettier-ignore + @Override + public String toString() { + return "TranscriptCriteria{" + + (id != null ? "id=" + id + ", " : "") + + (referenceGenome != null ? "referenceGenome=" + referenceGenome + ", " : "") + + (ensemblTranscriptId != null ? "ensemblTranscriptId=" + ensemblTranscriptId + ", " : "") + + (canonical != null ? "canonical=" + canonical + ", " : "") + + (ensemblProteinId != null ? "ensemblProteinId=" + ensemblProteinId + ", " : "") + + (referenceSequenceId != null ? "referenceSequenceId=" + referenceSequenceId + ", " : "") + + (description != null ? "description=" + description + ", " : "") + + (sequenceId != null ? "sequenceId=" + sequenceId + ", " : "") + + (fragmentsId != null ? "fragmentsId=" + fragmentsId + ", " : "") + + (flagId != null ? "flagId=" + flagId + ", " : "") + + (ensemblGeneId != null ? "ensemblGeneId=" + ensemblGeneId + ", " : "") + + (geneId != null ? "geneId=" + geneId + ", " : "") + + (alterationId != null ? "alterationId=" + alterationId + ", " : "") + + (distinct != null ? "distinct=" + distinct + ", " : "") + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/dto/BiomarkerAssociationDTO.java b/src/main/java/org/mskcc/oncokb/curation/service/dto/BiomarkerAssociationDTO.java new file mode 100644 index 000000000..874377098 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/dto/BiomarkerAssociationDTO.java @@ -0,0 +1,72 @@ +package org.mskcc.oncokb.curation.service.dto; + +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; +import org.mskcc.oncokb.curation.domain.Gene; + +/** + * A DTO for the {@link org.mskcc.oncokb.curation.domain.BiomarkerAssociation} entity. + */ +public class BiomarkerAssociationDTO implements Serializable { + + private Long id; + + private Set alterations = new HashSet<>(); + + private Set drugs = new HashSet<>(); + + private Set fdaSubmissions; + + private Long cancerType; + + private Long gene; + + public Long getId() { + return this.id; + } + + public void setId(Long id) { + this.id = id; + } + + public Set getAlterations() { + return this.alterations; + } + + public void setAlterations(Set alterations) { + this.alterations = alterations; + } + + public Set getDrugs() { + return this.drugs; + } + + public void setDrugs(Set drugs) { + this.drugs = drugs; + } + + public Set getFdaSubmissions() { + return this.fdaSubmissions; + } + + public void setFdaSubmissions(Set fdaSubmissions) { + this.fdaSubmissions = fdaSubmissions; + } + + public Long getCancerType() { + return this.cancerType; + } + + public void setCancerType(Long cancerType) { + this.cancerType = cancerType; + } + + public Long getGene() { + return this.gene; + } + + public void setGene(Long gene) { + this.gene = gene; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/dto/ClustalOResp.java b/src/main/java/org/mskcc/oncokb/curation/service/dto/ClustalOResp.java new file mode 100644 index 000000000..505ca9ed1 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/dto/ClustalOResp.java @@ -0,0 +1,33 @@ +package org.mskcc.oncokb.curation.service.dto; + +public class ClustalOResp { + + String fasta; + String clustalo; + + String mview; + + public String getFasta() { + return fasta; + } + + public void setFasta(String fasta) { + this.fasta = fasta; + } + + public String getClustalo() { + return clustalo; + } + + public void setClustalo(String clustalo) { + this.clustalo = clustalo; + } + + public String getMview() { + return mview; + } + + public void setMview(String mview) { + this.mview = mview; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/dto/EntityAuditAction.java b/src/main/java/org/mskcc/oncokb/curation/service/dto/EntityAuditAction.java new file mode 100644 index 000000000..8b4025019 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/dto/EntityAuditAction.java @@ -0,0 +1,25 @@ +package org.mskcc.oncokb.curation.service.dto; + +/** + * Enum for the different audit actions + */ +public enum EntityAuditAction { + CREATE("CREATE"), + UPDATE("UPDATE"), + DELETE("DELETE"); + + private String value; + + EntityAuditAction(final String value) { + this.value = value; + } + + public String value() { + return value; + } + + @Override + public String toString() { + return this.value(); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/dto/EntityAuditEvent.java b/src/main/java/org/mskcc/oncokb/curation/service/dto/EntityAuditEvent.java new file mode 100644 index 000000000..1719ac3c6 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/dto/EntityAuditEvent.java @@ -0,0 +1,187 @@ +package org.mskcc.oncokb.curation.service.dto; + +import java.io.Serializable; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.util.Objects; +import org.javers.core.metamodel.object.CdoSnapshot; + +public class EntityAuditEvent implements Serializable { + + private static final long serialVersionUID = 1L; + + private Long id; + + private String entityId; + + private String entityType; + + private String action; + + private String entityValue; + + private Integer commitVersion; + + private String modifiedBy; + + private Instant modifiedDate; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getEntityId() { + return entityId; + } + + public void setEntityId(String entityId) { + this.entityId = entityId; + } + + public String getEntityType() { + return entityType; + } + + public void setEntityType(String entityType) { + this.entityType = entityType; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public String getEntityValue() { + return entityValue; + } + + public void setEntityValue(String entityValue) { + this.entityValue = entityValue; + } + + public Integer getCommitVersion() { + return commitVersion; + } + + public void setCommitVersion(Integer commitVersion) { + this.commitVersion = commitVersion; + } + + public String getModifiedBy() { + return modifiedBy; + } + + public void setModifiedBy(String modifiedBy) { + this.modifiedBy = modifiedBy; + } + + public Instant getModifiedDate() { + return modifiedDate; + } + + public void setModifiedDate(Instant modifiedDate) { + this.modifiedDate = modifiedDate; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + EntityAuditEvent entityAuditEvent = (EntityAuditEvent) o; + return Objects.equals(id, entityAuditEvent.id); + } + + @Override + public int hashCode() { + return Objects.hashCode(id); + } + + @Override + public String toString() { + return ( + "EntityAuditEvent{" + + "id=" + + id + + ", entityId='" + + entityId + + "'" + + ", entityType='" + + entityType + + "'" + + ", action='" + + action + + "'" + + ", entityValue='" + + entityValue + + "'" + + ", commitVersion='" + + commitVersion + + "'" + + ", modifiedBy='" + + modifiedBy + + "'" + + ", modifiedDate='" + + modifiedDate + + "'" + + '}' + ); + } + + public static EntityAuditEvent fromJaversSnapshot(CdoSnapshot snapshot) { + EntityAuditEvent entityAuditEvent = new EntityAuditEvent(); + + switch (snapshot.getType()) { + case INITIAL: + entityAuditEvent.setAction("CREATE"); + break; + case UPDATE: + entityAuditEvent.setAction("UPDATE"); + break; + case TERMINAL: + entityAuditEvent.setAction("DELETE"); + break; + } + + entityAuditEvent.setId(snapshot.getCommitId().getMajorId()); + entityAuditEvent.setCommitVersion(Math.round(snapshot.getVersion())); + entityAuditEvent.setEntityType(snapshot.getManagedType().getName()); + entityAuditEvent.setEntityId(snapshot.getGlobalId().value().split("/")[1]); + entityAuditEvent.setModifiedBy(snapshot.getCommitMetadata().getAuthor()); + + if (snapshot.getState().getPropertyNames().size() > 0) { + int count = 0; + StringBuilder sb = new StringBuilder("{"); + + for (String s : snapshot.getState().getPropertyNames()) { + count++; + Object propertyValue = snapshot.getPropertyValue(s); + sb.append("\"" + s + "\": \"" + propertyValue + "\""); + if (count < snapshot.getState().getPropertyNames().size()) { + sb.append(","); + } + } + + sb.append("}"); + entityAuditEvent.setEntityValue(sb.toString()); + } + LocalDateTime localTime = snapshot.getCommitMetadata().getCommitDate(); + + Instant modifyDate = localTime.toInstant(ZoneOffset.UTC); + + entityAuditEvent.setModifiedDate(modifyDate); + + return entityAuditEvent; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/dto/KeycloakUserDTO.java b/src/main/java/org/mskcc/oncokb/curation/service/dto/KeycloakUserDTO.java new file mode 100644 index 000000000..ea11d436b --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/dto/KeycloakUserDTO.java @@ -0,0 +1,125 @@ +package org.mskcc.oncokb.curation.service.dto; + +import com.google.gson.annotations.SerializedName; +import java.io.Serializable; +import java.time.Instant; + +/* User returned from Keycloak */ + +public class KeycloakUserDTO implements Serializable { + + private String uid; + + private String sub; + + @SerializedName("preferred_username") + private String preferredUserName; + + @SerializedName("given_name") + private String givenName; + + @SerializedName("family_name") + private String familyName; + + private String name; + + private String email; + + private String langKey; + + private String locale; + + @SerializedName("picture") + private String imageUrl; + + @SerializedName("updated_at") + private Instant lastUpdate; + + public String getUid() { + return this.uid; + } + + public void setUid(String uid) { + this.uid = uid; + } + + public String getSub() { + return this.sub; + } + + public void setSub(String sub) { + this.sub = sub; + } + + public String getPreferredUserName() { + return this.preferredUserName; + } + + public void setPreferredUserName(String preferredUserName) { + this.preferredUserName = preferredUserName; + } + + public String getGivenName() { + return this.givenName; + } + + public void setGivenName(String givenName) { + this.givenName = givenName; + } + + public String getFamilyName() { + return this.familyName; + } + + public void setFamilyName(String familyName) { + this.familyName = familyName; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return this.email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getLangKey() { + return this.langKey; + } + + public void setLangKey(String langKey) { + this.langKey = langKey; + } + + public String getLocale() { + return this.locale; + } + + public void setLocale(String locale) { + this.locale = locale; + } + + public String getImageUrl() { + return this.imageUrl; + } + + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + } + + public Instant getLastUpdate() { + return this.lastUpdate; + } + + public void setLastUpdate(Instant lastUpdate) { + this.lastUpdate = lastUpdate; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/dto/SearchResultDTO.java b/src/main/java/org/mskcc/oncokb/curation/service/dto/SearchResultDTO.java new file mode 100644 index 000000000..7b1ae4282 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/dto/SearchResultDTO.java @@ -0,0 +1,59 @@ +package org.mskcc.oncokb.curation.service.dto; + +import java.util.List; +import org.mskcc.oncokb.curation.domain.Alteration; +import org.mskcc.oncokb.curation.domain.Article; +import org.mskcc.oncokb.curation.domain.CompanionDiagnosticDevice; +import org.mskcc.oncokb.curation.domain.Drug; +import org.mskcc.oncokb.curation.domain.FdaSubmission; +import org.mskcc.oncokb.curation.domain.Gene; + +public class SearchResultDTO { + + private final List fdaSubmissions; + private final List companionDiagnosticDevices; + private final List
articles; + private final List drugs; + private final List genes; + private final List alterations; + + public SearchResultDTO( + List fdaSubmissions, + List companionDiagnosticDevices, + List
articles, + List drugs, + List genes, + List alterations + ) { + this.fdaSubmissions = fdaSubmissions; + this.companionDiagnosticDevices = companionDiagnosticDevices; + this.articles = articles; + this.drugs = drugs; + this.genes = genes; + this.alterations = alterations; + } + + public List getFdaSubmissions() { + return this.fdaSubmissions; + } + + public List getCompanionDiagnosticDevices() { + return this.companionDiagnosticDevices; + } + + public List
getArticles() { + return this.articles; + } + + public List getDrugs() { + return this.drugs; + } + + public List getGenes() { + return this.genes; + } + + public List getAlterations() { + return this.alterations; + } +} diff --git a/src/main/java/org/mskcc/oncokb/transcript/service/dto/TranscriptDTO.java b/src/main/java/org/mskcc/oncokb/curation/service/dto/TranscriptDTO.java similarity index 76% rename from src/main/java/org/mskcc/oncokb/transcript/service/dto/TranscriptDTO.java rename to src/main/java/org/mskcc/oncokb/curation/service/dto/TranscriptDTO.java index ec337adf8..49bd65682 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/service/dto/TranscriptDTO.java +++ b/src/main/java/org/mskcc/oncokb/curation/service/dto/TranscriptDTO.java @@ -1,21 +1,25 @@ -package org.mskcc.oncokb.transcript.service.dto; +package org.mskcc.oncokb.curation.service.dto; +import jakarta.validation.constraints.*; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.Objects; -import javax.validation.constraints.*; -import org.mskcc.oncokb.transcript.domain.EnsemblGene; -import org.mskcc.oncokb.transcript.domain.GenomeFragment; -import org.mskcc.oncokb.transcript.domain.enumeration.ReferenceGenome; +import org.mskcc.oncokb.curation.domain.EnsemblGene; +import org.mskcc.oncokb.curation.domain.Flag; +import org.mskcc.oncokb.curation.domain.Gene; +import org.mskcc.oncokb.curation.domain.GenomeFragment; +import org.mskcc.oncokb.curation.domain.enumeration.ReferenceGenome; /** - * A DTO for the {@link org.mskcc.oncokb.transcript.domain.Transcript} entity. + * A DTO for the {@link org.mskcc.oncokb.curation.domain.Transcript} entity. */ public class TranscriptDTO implements Serializable { private Long id; + private ReferenceGenome referenceGenome; + private String ensemblTranscriptId; @NotNull @@ -27,6 +31,8 @@ public class TranscriptDTO implements Serializable { private String description; + private Gene gene; + private EnsemblGene ensemblGene; private Integer strand; @@ -41,6 +47,8 @@ public class TranscriptDTO implements Serializable { private List utrs = new ArrayList<>(); + private List flags = new ArrayList<>(); + public Long getId() { return id; } @@ -49,6 +57,14 @@ public void setId(Long id) { this.id = id; } + public ReferenceGenome getReferenceGenome() { + return referenceGenome; + } + + public void setReferenceGenome(ReferenceGenome referenceGenome) { + this.referenceGenome = referenceGenome; + } + public String getEnsemblTranscriptId() { return ensemblTranscriptId; } @@ -137,6 +153,14 @@ public void setUtrs(List utrs) { this.utrs = utrs; } + public Gene getGene() { + return gene; + } + + public void setGene(Gene gene) { + this.gene = gene; + } + public EnsemblGene getEnsemblGene() { return ensemblGene; } @@ -145,6 +169,14 @@ public void setEnsemblGene(EnsemblGene ensemblGene) { this.ensemblGene = ensemblGene; } + public List getFlags() { + return flags; + } + + public void setFlags(List flags) { + this.flags = flags; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -171,12 +203,15 @@ public int hashCode() { public String toString() { return "TranscriptDTO{" + "id=" + getId() + + ", referenceGenome='" + getReferenceGenome() + "'" + ", ensemblTranscriptId='" + getEnsemblTranscriptId() + "'" + ", canonical='" + getCanonical() + "'" + ", ensemblProteinId='" + getEnsemblProteinId() + "'" + ", referenceSequenceId='" + getReferenceSequenceId() + "'" + ", description='" + getDescription() + "'" + + ", flags=" + getFlags() + ", ensemblGene=" + getEnsemblGene() + + ", gene=" + getGene() + "}"; } } diff --git a/src/main/java/org/mskcc/oncokb/curation/service/dto/TreatmentDTO.java b/src/main/java/org/mskcc/oncokb/curation/service/dto/TreatmentDTO.java new file mode 100644 index 000000000..bb81ada16 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/dto/TreatmentDTO.java @@ -0,0 +1,24 @@ +package org.mskcc.oncokb.curation.service.dto; + +import java.util.ArrayList; +import java.util.List; +import org.mskcc.oncokb.curation.domain.Drug; + +public class TreatmentDTO { + + public TreatmentDTO() {} + + List drugs = new ArrayList<>(); + + public List getDrugs() { + return drugs; + } + + public void setDrugs(List drugs) { + this.drugs = drugs; + } + + public void addDrug(Drug drug) { + this.drugs.add(drug); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/dto/UserDTO.java b/src/main/java/org/mskcc/oncokb/curation/service/dto/UserDTO.java new file mode 100644 index 000000000..d339245bf --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/dto/UserDTO.java @@ -0,0 +1,196 @@ +package org.mskcc.oncokb.curation.service.dto; + +import jakarta.validation.constraints.*; +import java.time.Instant; +import java.util.Set; +import java.util.stream.Collectors; +import org.mskcc.oncokb.curation.config.Constants; +import org.mskcc.oncokb.curation.domain.Authority; +import org.mskcc.oncokb.curation.domain.User; + +/** + * A DTO representing a user, with their authorities. + */ +public class UserDTO { + + private Long id; + + @NotBlank + @Pattern(regexp = Constants.LOGIN_REGEX) + @Size(min = 1, max = 50) + private String login; + + @NotBlank + @Size(max = 50) + private String firstName; + + @NotBlank + @Size(max = 50) + private String lastName; + + @NotBlank + @Email + @Size(min = 5, max = 254) + private String email; + + @Size(max = 256) + private String imageUrl; + + private boolean activated = false; + + @Size(min = 2, max = 10) + private String langKey; + + private String createdBy; + + private Instant createdDate; + + private String lastModifiedBy; + + private Instant lastModifiedDate; + + private Set authorities; + + public UserDTO() { + // Empty constructor needed for Jackson. + } + + public UserDTO(User user) { + this.id = user.getId(); + this.login = user.getLogin(); + this.firstName = user.getFirstName(); + this.lastName = user.getLastName(); + this.email = user.getEmail(); + this.activated = user.isActivated(); + this.imageUrl = user.getImageUrl(); + this.langKey = user.getLangKey(); + this.createdBy = user.getCreatedBy(); + this.createdDate = user.getCreatedDate(); + this.lastModifiedBy = user.getLastModifiedBy(); + this.lastModifiedDate = user.getLastModifiedDate(); + this.authorities = user.getAuthorities().stream().map(Authority::getName).collect(Collectors.toSet()); + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getLogin() { + return login; + } + + public void setLogin(String login) { + this.login = login; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getImageUrl() { + return imageUrl; + } + + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + } + + public boolean isActivated() { + return activated; + } + + public void setActivated(boolean activated) { + this.activated = activated; + } + + public String getLangKey() { + return langKey; + } + + public void setLangKey(String langKey) { + this.langKey = langKey; + } + + public String getCreatedBy() { + return createdBy; + } + + public void setCreatedBy(String createdBy) { + this.createdBy = createdBy; + } + + public Instant getCreatedDate() { + return createdDate; + } + + public void setCreatedDate(Instant createdDate) { + this.createdDate = createdDate; + } + + public String getLastModifiedBy() { + return lastModifiedBy; + } + + public void setLastModifiedBy(String lastModifiedBy) { + this.lastModifiedBy = lastModifiedBy; + } + + public Instant getLastModifiedDate() { + return lastModifiedDate; + } + + public void setLastModifiedDate(Instant lastModifiedDate) { + this.lastModifiedDate = lastModifiedDate; + } + + public Set getAuthorities() { + return authorities; + } + + public void setAuthorities(Set authorities) { + this.authorities = authorities; + } + + // prettier-ignore + @Override + public String toString() { + return "UserDTO{" + + "login='" + login + '\'' + + ", firstName='" + firstName + '\'' + + ", lastName='" + lastName + '\'' + + ", email='" + email + '\'' + + ", imageUrl='" + imageUrl + '\'' + + ", activated=" + activated + + ", langKey='" + langKey + '\'' + + ", createdBy=" + createdBy + + ", createdDate=" + createdDate + + ", lastModifiedBy='" + lastModifiedBy + '\'' + + ", lastModifiedDate=" + lastModifiedDate + + ", authorities=" + authorities + + "}"; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/dto/package-info.java b/src/main/java/org/mskcc/oncokb/curation/service/dto/package-info.java new file mode 100644 index 000000000..52dbb5e59 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/dto/package-info.java @@ -0,0 +1,4 @@ +/** + * Data Transfer Objects. + */ +package org.mskcc.oncokb.curation.service.dto; diff --git a/src/main/java/org/mskcc/oncokb/curation/service/dto/pubmed/AbstractTextDTO.java b/src/main/java/org/mskcc/oncokb/curation/service/dto/pubmed/AbstractTextDTO.java new file mode 100644 index 000000000..8622ecd2c --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/dto/pubmed/AbstractTextDTO.java @@ -0,0 +1,36 @@ +package org.mskcc.oncokb.curation.service.dto.pubmed; + +import java.io.Serializable; + +public class AbstractTextDTO implements Serializable { + + String label; + String nlmCategory; + String value; + + public AbstractTextDTO() {} + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public String getNlmCategory() { + return nlmCategory; + } + + public void setNlmCategory(String nlmCategory) { + this.nlmCategory = nlmCategory; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/dto/pubmed/AdditionalInfoDTO.java b/src/main/java/org/mskcc/oncokb/curation/service/dto/pubmed/AdditionalInfoDTO.java new file mode 100644 index 000000000..925d00476 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/dto/pubmed/AdditionalInfoDTO.java @@ -0,0 +1,59 @@ +package org.mskcc.oncokb.curation.service.dto.pubmed; + +import java.io.Serializable; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; + +public class AdditionalInfoDTO implements Serializable { + + private List abstractTexts = new ArrayList<>(); + private JournalDTO journal; + private Instant completedDate; + private Instant revisedDate; + private List dataBanks = new ArrayList<>(); + + public List getAbstractTexts() { + return abstractTexts; + } + + public void setAbstractTexts(List abstractTexts) { + this.abstractTexts = abstractTexts; + } + + public JournalDTO getJournal() { + return journal; + } + + public void setJournal(JournalDTO journal) { + this.journal = journal; + } + + public Instant getCompletedDate() { + return completedDate; + } + + public void setCompletedDate(Instant completedDate) { + this.completedDate = completedDate; + } + + public Instant getRevisedDate() { + return revisedDate; + } + + public void setRevisedDate(Instant revisedDate) { + this.revisedDate = revisedDate; + } + + public List getDataBanks() { + return dataBanks; + } + + public void setDataBanks(List dataBanks) { + this.dataBanks = dataBanks; + } + + public void addDataBank(DataBankDTO dataBank) { + this.dataBanks.add(dataBank); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/dto/pubmed/DataBankDTO.java b/src/main/java/org/mskcc/oncokb/curation/service/dto/pubmed/DataBankDTO.java new file mode 100644 index 000000000..d8804b489 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/dto/pubmed/DataBankDTO.java @@ -0,0 +1,28 @@ +package org.mskcc.oncokb.curation.service.dto.pubmed; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +public class DataBankDTO implements Serializable { + + private String name; + + private List accessionNumbers = new ArrayList<>(); + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getAccessionNumbers() { + return accessionNumbers; + } + + public void setAccessionNumbers(List accessionNumbers) { + this.accessionNumbers = accessionNumbers; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/dto/pubmed/JournalDTO.java b/src/main/java/org/mskcc/oncokb/curation/service/dto/pubmed/JournalDTO.java new file mode 100644 index 000000000..868b4ac0c --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/dto/pubmed/JournalDTO.java @@ -0,0 +1,62 @@ +package org.mskcc.oncokb.curation.service.dto.pubmed; + +import java.io.Serializable; +import java.time.Instant; + +public class JournalDTO implements Serializable { + + String issn; + String volume; + String issue; + String pages; + String title; + String isoAbbreviation; + + public String getIssn() { + return issn; + } + + public void setIssn(String issn) { + this.issn = issn; + } + + public String getVolume() { + return volume; + } + + public void setVolume(String volume) { + this.volume = volume; + } + + public String getIssue() { + return issue; + } + + public void setIssue(String issue) { + this.issue = issue; + } + + public String getPages() { + return pages; + } + + public void setPages(String pages) { + this.pages = pages; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getIsoAbbreviation() { + return isoAbbreviation; + } + + public void setIsoAbbreviation(String isoAbbreviation) { + this.isoAbbreviation = isoAbbreviation; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/dto/pubmed/PubMedDTO.java b/src/main/java/org/mskcc/oncokb/curation/service/dto/pubmed/PubMedDTO.java new file mode 100644 index 000000000..c56ab4b58 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/dto/pubmed/PubMedDTO.java @@ -0,0 +1,143 @@ +package org.mskcc.oncokb.curation.service.dto.pubmed; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import java.io.Serializable; +import java.time.Instant; +import java.util.HashSet; +import java.util.Set; +import org.mskcc.oncokb.curation.domain.Article; +import org.mskcc.oncokb.curation.domain.Flag; +import org.mskcc.oncokb.curation.domain.Synonym; +import org.mskcc.oncokb.curation.domain.enumeration.ArticleType; +import org.mskcc.oncokb.curation.util.GsonUtils; + +public class PubMedDTO implements Serializable { + + private Long id; + + private ArticleType type = ArticleType.PUBMED; + + private String pmid; + + private String title; + + private String content; + + private String link; + + private String authors; + + private Instant date; + + private AdditionalInfoDTO additionalInfo; + + @JsonIgnoreProperties(value = { "alterations", "articles", "drugs", "genes", "transcripts" }, allowSetters = true) + private Set flags = new HashSet<>(); + + @JsonIgnoreProperties(value = { "articles", "cancerTypes", "genes", "nciThesauruses" }, allowSetters = true) + private Set synonyms = new HashSet<>(); + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public ArticleType getType() { + return type; + } + + public void setType(ArticleType type) { + this.type = type; + } + + public String getPmid() { + return pmid; + } + + public void setPmid(String pmid) { + this.pmid = pmid; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public String getLink() { + return link; + } + + public void setLink(String link) { + this.link = link; + } + + public String getAuthors() { + return authors; + } + + public void setAuthors(String authors) { + this.authors = authors; + } + + public Instant getDate() { + return date; + } + + public void setDate(Instant date) { + this.date = date; + } + + public AdditionalInfoDTO getAdditionalInfo() { + return additionalInfo; + } + + public void setAdditionalInfo(AdditionalInfoDTO additionalInfo) { + this.additionalInfo = additionalInfo; + } + + public Set getFlags() { + return flags; + } + + public void setFlags(Set flags) { + this.flags = flags; + } + + public Set getSynonyms() { + return synonyms; + } + + public void setSynonyms(Set synonyms) { + this.synonyms = synonyms; + } + + public PubMedDTO() {} + + public PubMedDTO(Article article) { + this.id = article.getId(); + this.type = article.getType(); + this.pmid = article.getUid(); + this.title = article.getTitle(); + this.content = article.getContent(); + this.link = article.getLink(); + this.authors = article.getAuthors(); + this.date = article.getDate(); + this.additionalInfo = GsonUtils.create().fromJson(article.getAdditionalInfo(), AdditionalInfoDTO.class); + this.flags = article.getFlags(); + this.synonyms = article.getSynonyms(); + } +} diff --git a/src/main/java/org/mskcc/oncokb/transcript/service/mapper/EntityMapper.java b/src/main/java/org/mskcc/oncokb/curation/service/mapper/EntityMapper.java similarity index 92% rename from src/main/java/org/mskcc/oncokb/transcript/service/mapper/EntityMapper.java rename to src/main/java/org/mskcc/oncokb/curation/service/mapper/EntityMapper.java index cc95056f9..2c9f6dbbe 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/service/mapper/EntityMapper.java +++ b/src/main/java/org/mskcc/oncokb/curation/service/mapper/EntityMapper.java @@ -1,4 +1,4 @@ -package org.mskcc.oncokb.transcript.service.mapper; +package org.mskcc.oncokb.curation.service.mapper; import java.util.List; import org.mapstruct.BeanMapping; diff --git a/src/main/java/org/mskcc/oncokb/curation/service/mapper/PubMedMapper.java b/src/main/java/org/mskcc/oncokb/curation/service/mapper/PubMedMapper.java new file mode 100644 index 000000000..5c1d7c538 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/mapper/PubMedMapper.java @@ -0,0 +1,51 @@ +package org.mskcc.oncokb.curation.service.mapper; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import org.mskcc.oncokb.curation.domain.Article; +import org.mskcc.oncokb.curation.service.dto.pubmed.PubMedDTO; +import org.mskcc.oncokb.curation.util.GsonUtils; +import org.springframework.stereotype.Service; + +/** + * Mapper to convert between {@link PubMedDTO} and {@link Article}. + *

+ * Normal mappers are generated using MapStruct, this one is hand-coded as MapStruct + * support is still in beta, and requires a manual step with an IDE. + */ +@Service +public class PubMedMapper { + + public List articlesToPubMedDTOs(List

articles) { + return articles.stream().filter(Objects::nonNull).map(this::articleToPubMedDTO).collect(Collectors.toList()); + } + + public PubMedDTO articleToPubMedDTO(Article article) { + return new PubMedDTO(article); + } + + public List
pubMedDTOsToArticle(List pubMedDTOs) { + return pubMedDTOs.stream().filter(Objects::nonNull).map(this::pubMedDTOToArticle).collect(Collectors.toList()); + } + + public Article pubMedDTOToArticle(PubMedDTO pubMedDTO) { + if (pubMedDTO == null) { + return null; + } else { + Article article = new Article(); + article.setId(pubMedDTO.getId()); + article.setType(pubMedDTO.getType()); + article.setUid(pubMedDTO.getPmid()); + article.setTitle(pubMedDTO.getTitle()); + article.setContent(pubMedDTO.getContent()); + article.setLink(pubMedDTO.getLink()); + article.setDate(pubMedDTO.getDate()); + article.setAuthors(pubMedDTO.getAuthors()); + article.setAdditionalInfo(GsonUtils.create().toJson(pubMedDTO.getAdditionalInfo())); + article.setFlags(pubMedDTO.getFlags()); + article.setSynonyms(pubMedDTO.getSynonyms()); + return article; + } + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/mapper/TranscriptMapper.java b/src/main/java/org/mskcc/oncokb/curation/service/mapper/TranscriptMapper.java new file mode 100644 index 000000000..3abbf1a4b --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/mapper/TranscriptMapper.java @@ -0,0 +1,61 @@ +package org.mskcc.oncokb.curation.service.mapper; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import org.mapstruct.*; +import org.mskcc.oncokb.curation.domain.GenomeFragment; +import org.mskcc.oncokb.curation.domain.Transcript; +import org.mskcc.oncokb.curation.domain.enumeration.GenomeFragmentType; +import org.mskcc.oncokb.curation.repository.GenomeFragmentRepository; +import org.mskcc.oncokb.curation.service.dto.TranscriptDTO; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * Mapper for the entity {@link Transcript} and its DTO {@link TranscriptDTO}. + */ +@Mapper(componentModel = "spring", uses = {}) +public abstract class TranscriptMapper implements EntityMapper { + + @Autowired + GenomeFragmentRepository genomeFragmentRepository; + + /** + * @param transcriptDTO + */ + @AfterMapping + protected void updateDTO(@MappingTarget TranscriptDTO transcriptDTO) { + List genomeFragmentList = genomeFragmentRepository.findAllByTranscriptId(transcriptDTO.getId()); + + Optional geneInfoOptional = genomeFragmentList + .stream() + .filter(genomeFragment -> genomeFragment.getType().equals(GenomeFragmentType.GENE)) + .findFirst(); + if (geneInfoOptional.isPresent()) { + GenomeFragment gf = geneInfoOptional.orElseThrow(); + transcriptDTO.setChromosome(gf.getSeqRegion().getChromosome()); + transcriptDTO.setStart(gf.getStart()); + transcriptDTO.setEnd(gf.getEnd()); + transcriptDTO.setStrand(gf.getStrand()); + } + + List exons = genomeFragmentList + .stream() + .filter(genomeFragment -> genomeFragment.getType().equals(GenomeFragmentType.EXON)) + .collect(Collectors.toList()); + transcriptDTO.setExons(exons); + + List utrs = genomeFragmentList + .stream() + .filter( + genomeFragment -> + genomeFragment.getType().equals(GenomeFragmentType.FIVE_PRIME_UTR) || + genomeFragment.getType().equals(GenomeFragmentType.THREE_PRIME_UTR) + ) + .collect(Collectors.toList()); + transcriptDTO.setUtrs(utrs); + } + + @AfterMapping + protected void update(@MappingTarget Transcript transcript) {} +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/mapper/UserMapper.java b/src/main/java/org/mskcc/oncokb/curation/service/mapper/UserMapper.java new file mode 100644 index 000000000..7fcc533b9 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/mapper/UserMapper.java @@ -0,0 +1,78 @@ +package org.mskcc.oncokb.curation.service.mapper; + +import java.util.*; +import java.util.stream.Collectors; +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapping; +import org.mapstruct.Named; +import org.mskcc.oncokb.curation.domain.Authority; +import org.mskcc.oncokb.curation.domain.User; +import org.mskcc.oncokb.curation.service.dto.UserDTO; +import org.springframework.stereotype.Service; + +/** + * Mapper for the entity {@link User} and its DTO called {@link UserDTO}. + * + * Normal mappers are generated using MapStruct, this one is hand-coded as MapStruct + * support is still in beta, and requires a manual step with an IDE. + */ +@Service +public class UserMapper { + + public List usersToUserDTOs(List users) { + return users.stream().filter(Objects::nonNull).map(this::userToUserDTO).collect(Collectors.toList()); + } + + public UserDTO userToUserDTO(User user) { + return new UserDTO(user); + } + + public List userDTOsToUsers(List userDTOs) { + return userDTOs.stream().filter(Objects::nonNull).map(this::userDTOToUser).collect(Collectors.toList()); + } + + public User userDTOToUser(UserDTO userDTO) { + if (userDTO == null) { + return null; + } else { + User user = new User(); + user.setId(userDTO.getId()); + user.setLogin(userDTO.getLogin()); + user.setFirstName(userDTO.getFirstName()); + user.setLastName(userDTO.getLastName()); + user.setEmail(userDTO.getEmail()); + user.setImageUrl(userDTO.getImageUrl()); + user.setActivated(userDTO.isActivated()); + user.setLangKey(userDTO.getLangKey()); + Set authorities = this.authoritiesFromStrings(userDTO.getAuthorities()); + user.setAuthorities(authorities); + return user; + } + } + + private Set authoritiesFromStrings(Set authoritiesAsString) { + Set authorities = new HashSet<>(); + + if (authoritiesAsString != null) { + authorities = authoritiesAsString + .stream() + .map(string -> { + Authority auth = new Authority(); + auth.setName(string); + return auth; + }) + .collect(Collectors.toSet()); + } + + return authorities; + } + + public User userFromId(Long id) { + if (id == null) { + return null; + } + User user = new User(); + user.setId(id); + return user; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/service/mapper/package-info.java b/src/main/java/org/mskcc/oncokb/curation/service/mapper/package-info.java new file mode 100644 index 000000000..e607d311a --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/mapper/package-info.java @@ -0,0 +1,4 @@ +/** + * MapStruct mappers for mapping domain objects and Data Transfer Objects. + */ +package org.mskcc.oncokb.curation.service.mapper; diff --git a/src/main/java/org/mskcc/oncokb/curation/service/package-info.java b/src/main/java/org/mskcc/oncokb/curation/service/package-info.java new file mode 100644 index 000000000..32208e86a --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/service/package-info.java @@ -0,0 +1,4 @@ +/** + * Service layer beans. + */ +package org.mskcc.oncokb.curation.service; diff --git a/src/main/java/org/mskcc/oncokb/curation/util/AlterationUtils.java b/src/main/java/org/mskcc/oncokb/curation/util/AlterationUtils.java new file mode 100644 index 000000000..336bb9e4f --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/util/AlterationUtils.java @@ -0,0 +1,339 @@ +package org.mskcc.oncokb.curation.util; + +import static java.util.regex.Pattern.CASE_INSENSITIVE; +import static org.mskcc.oncokb.curation.domain.enumeration.MutationConsequence.*; +import static org.mskcc.oncokb.curation.util.parser.ProteinChangeParser.*; + +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import org.apache.commons.lang3.StringUtils; +import org.mskcc.oncokb.curation.domain.*; +import org.mskcc.oncokb.curation.domain.enumeration.*; +import org.mskcc.oncokb.curation.util.parser.ParsingStatus; +import org.springframework.stereotype.Component; + +@Component +public class AlterationUtils { + + public static final String FUSION_SEPARATOR = "::"; + public static final String FUSION_ALTERNATIVE_SEPARATOR = "-"; + private static final String FUSION_REGEX = "\\s*(\\w*)" + FUSION_SEPARATOR + "(\\w*)\\s*(?i)(fusion)?\\s*"; + private static final String FUSION_ALT_REGEX = "\\s*(\\w*)" + FUSION_ALTERNATIVE_SEPARATOR + "(\\w*)\\s+(?i)fusion\\s*"; + + private Alteration parseFusion(String alteration) { + Alteration alt = new Alteration(); + + Consequence consequence = new Consequence(); + consequence.setTerm(SVConsequence.FUSION.name()); + alt.setType(AlterationType.STRUCTURAL_VARIANT); + alt.setConsequence(consequence); + + if (alteration.contains(FUSION_SEPARATOR) || alteration.contains(FUSION_ALTERNATIVE_SEPARATOR)) { + alt.setGenes( + getGenesStrs(alteration) + .stream() + .map(hugoSymbol -> { + Gene gene = new Gene(); + gene.setHugoSymbol(hugoSymbol); + return gene; + }) + .collect(Collectors.toSet()) + ); + alt.setAlteration(alt.getGenes().stream().map(Gene::getHugoSymbol).collect(Collectors.joining("-")) + " Fusion"); + } else { + alt.setAlteration(alteration.substring(0, 1).toUpperCase() + alteration.toLowerCase().substring(1)); + } + alt.setName(alt.getAlteration()); + return alt; + } + + private Alteration parseCopyNumberAlteration(String alteration) { + CNAConsequence cnaTerm = CNAConsequence.UNKNOWN; + + Optional cnaConsequenceOptional = getCNAConsequence(alteration); + if (cnaConsequenceOptional.isPresent()) { + cnaTerm = cnaConsequenceOptional.orElseThrow(); + } + + Alteration alt = new Alteration(); + Consequence consequence = new Consequence(); + consequence.setTerm(cnaTerm.name()); + alt.setType(AlterationType.COPY_NUMBER_ALTERATION); + alt.setConsequence(consequence); + + alt.setAlteration(cnaTerm.name().substring(0, 1) + cnaTerm.name().toLowerCase().substring(1)); + alt.setName(alt.getAlteration()); + + return alt; + } + + private Alteration parseCodingDnaChange(String codingDnaChange) { + Alteration alt = new Alteration(); + Consequence consequence = new Consequence(); + consequence.setTerm(UNKNOWN.name()); + alt.setType(AlterationType.CDNA_CHANGE); + alt.setConsequence(consequence); + alt.setAlteration(codingDnaChange); + alt.setName(codingDnaChange); + return alt; + } + + private Alteration parseGenomicChange(String genomicChange) { + Alteration alt = new Alteration(); + Consequence consequence = new Consequence(); + consequence.setTerm(UNKNOWN.name()); + alt.setType(AlterationType.GENOMIC_CHANGE); + alt.setConsequence(consequence); + alt.setAlteration(genomicChange); + alt.setName(genomicChange); + return alt; + } + + private static ParsingStatus parseCategoricalAlterations(String proteinChange) { + ParsingStatus parsedAlteration = new ParsingStatus<>(); + + // truncating + if (proteinChange.toLowerCase().matches("truncating mutations?")) { + Alteration alteration = new Alteration(); + Consequence consequence = new Consequence(); + consequence.setTerm(FEATURE_TRUNCATION.name()); + alteration.setConsequence(consequence); + alteration.setAlteration(proteinChange); + alteration.setName(proteinChange); + parsedAlteration.setEntity(alteration); + parsedAlteration.setStatus(EntityStatusType.OK); + } + return parsedAlteration; + } + + private static ParsingStatus parseProteinChangeWithStatus(String proteinChange, String excludedStr) { + ParsingStatus parsedAlteration = parseProteinChangeThroughAllTypes(proteinChange, excludedStr); + + if (parsedAlteration.getEntity() != null) { + Alteration alteration = parsedAlteration.getEntity(); + alteration.setType(AlterationType.PROTEIN_CHANGE); + if (StringUtils.isEmpty(alteration.getAlteration())) { + alteration.setAlteration(alteration.getProteinChange()); + } + if (StringUtils.isEmpty(alteration.getName())) { + alteration.setName(alteration.getProteinChange()); + } + // Change the positional name + if (isPositionedAlteration(alteration)) { + if (StringUtils.isEmpty(excludedStr)) { + alteration.setName(alteration.getAlteration() + " Missense Mutations"); + } else { + alteration.setName(proteinChange + " Missense Mutations, excluding " + excludedStr); + } + } + if (alteration.getConsequence() == null) { + Consequence consequence = new Consequence(); + consequence.setTerm(MutationConsequence.UNKNOWN.name()); + alteration.setConsequence(consequence); + } + } + return parsedAlteration; + } + + private static ParsingStatus parseProteinChangeThroughAllTypes(String proteinChange, String excludedStr) { + ParsingStatus parsedAlteration = new ParsingStatus<>(); + + parsedAlteration = parseInframe(proteinChange); + if (parsedAlteration.isParsed()) return parsedAlteration; + + parsedAlteration = parseSplice(proteinChange); + if (parsedAlteration.isParsed()) return parsedAlteration; + + parsedAlteration = parseFrameshift(proteinChange); + if (parsedAlteration.isParsed()) return parsedAlteration; + + parsedAlteration = parseExtension(proteinChange); + if (parsedAlteration.isParsed()) return parsedAlteration; + + parsedAlteration = parseRange(proteinChange); + if (parsedAlteration.isParsed()) return parsedAlteration; + + parsedAlteration = parseSynonymous(proteinChange); + if (parsedAlteration.isParsed()) return parsedAlteration; + + return parseGeneral(proteinChange); + } + + public static void parseProteinChange(EntityStatus alterationEntityStatus, String proteinChange) { + if (proteinChange == null) { + proteinChange = ""; + } + + if (proteinChange.startsWith("p.")) { + proteinChange = proteinChange.substring(2); + } + + if (proteinChange.indexOf("[") != -1) { + proteinChange = proteinChange.substring(0, proteinChange.indexOf("[")); + } + + // we need to deal with the exclusion format so the protein change can properly be interpreted. + String excludedStr = ""; + Matcher exclusionMatch = getExclusionCriteriaMatcher(proteinChange); + if (exclusionMatch.matches()) { + proteinChange = exclusionMatch.group(1); + excludedStr = exclusionMatch.group(3).trim(); + } + + proteinChange = proteinChange.trim(); + + ParsingStatus parsedAlteration; + + parsedAlteration = parseProteinChangeWithStatus(proteinChange, excludedStr); + if (!parsedAlteration.isParsed()) parsedAlteration = parseCategoricalAlterations(proteinChange); + + if (!parsedAlteration.isParsed()) { + Alteration alteration = new Alteration(); + alteration.setAlteration(proteinChange); + alteration.setName(proteinChange); + Consequence consequence = new Consequence(); + consequence.setTerm(UNKNOWN.name()); + alteration.setConsequence(consequence); + parsedAlteration.setEntity(alteration); + parsedAlteration.setStatus(EntityStatusType.OK); + } + alterationEntityStatus.setEntity(parsedAlteration.getEntity()); + alterationEntityStatus.setType(parsedAlteration.getStatus()); + alterationEntityStatus.setMessage(parsedAlteration.getMessage()); + } + + public EntityStatus parseAlteration(String alteration) { + EntityStatus entityWithStatus = new EntityStatus<>(); + String message = ""; + EntityStatusType status = EntityStatusType.OK; + + if (StringUtils.isEmpty(alteration)) { + return null; + } + if (isFusion(alteration)) { + Alteration alt = parseFusion(alteration); + entityWithStatus.setEntity(alt); + entityWithStatus.setType(status); + entityWithStatus.setMessage(message); + return entityWithStatus; + } + + if (isCopyNumberAlteration(alteration)) { + Alteration alt = parseCopyNumberAlteration(alteration); + entityWithStatus.setEntity(alt); + entityWithStatus.setType(status); + entityWithStatus.setMessage(message); + return entityWithStatus; + } + + if (alteration.startsWith("c.")) { + Alteration alt = parseCodingDnaChange(alteration); + entityWithStatus.setEntity(alt); + entityWithStatus.setType(status); + entityWithStatus.setMessage(message); + return entityWithStatus; + } + + if (isGenomicChange(alteration)) { + Alteration alt = parseGenomicChange(alteration); + entityWithStatus.setEntity(alt); + entityWithStatus.setType(status); + entityWithStatus.setMessage(message); + return entityWithStatus; + } + + parseProteinChange(entityWithStatus, alteration); + + return entityWithStatus; + } + + public List getGenesStrs(String alteration) { + if (StringUtils.isNotEmpty(alteration)) { + List genes = new ArrayList<>(); + Pattern p = Pattern.compile(FUSION_REGEX); + Matcher m = p.matcher(alteration); + if (m.matches()) { + genes.add(m.group(1)); + genes.add(m.group(2)); + } else { + p = Pattern.compile(FUSION_ALT_REGEX); + m = p.matcher(alteration); + if (m.matches()) { + genes.add(m.group(1)); + genes.add(m.group(2)); + } + } + return genes; + } + return new ArrayList<>(); + } + + public static boolean isPositionedAlteration(Alteration alteration) { + boolean isPositionVariant = false; + if ( + alteration != null && + alteration.getStart() != null && + alteration.getEnd() != null && + alteration.getStart().equals(alteration.getEnd()) && + alteration.getRefResidues() != null && + alteration.getRefResidues().length() == 1 && + alteration.getVariantResidues() == null && + alteration.getConsequence() != null && + (alteration.getConsequence().getTerm().equals(NA.name()) || + alteration.getConsequence().getTerm().equals(MISSENSE_VARIANT.name())) + ) isPositionVariant = true; + return isPositionVariant; + } + + private static Matcher getExclusionCriteriaMatcher(String proteinChange) { + Pattern exclusionPatter = Pattern.compile("(.*)\\{\\s*(exclude|excluding)(.*)\\}", CASE_INSENSITIVE); + Matcher exclusionMatch = exclusionPatter.matcher(proteinChange); + return exclusionMatch; + } + + public static boolean hasExclusionCriteria(String proteinChange) { + Matcher exclusionMatch = getExclusionCriteriaMatcher(proteinChange); + return exclusionMatch.matches(); + } + + public static Boolean isFusion(String variant) { + if (StringUtils.isEmpty(variant)) { + return false; + } + if (variant != null && (Pattern.matches(FUSION_REGEX, variant) || Pattern.matches(FUSION_ALT_REGEX, variant))) { + return true; + } + if (variant.equalsIgnoreCase("fusions")) { + return true; + } + if (variant.equalsIgnoreCase("fusion")) { + return true; + } + return false; + } + + public static Optional getCNAConsequence(String alteration) { + return Arrays.stream(CNAConsequence.values()).filter(cna -> cna.name().equals(alteration.toUpperCase())).findFirst(); + } + + public static Boolean isCopyNumberAlteration(String alteration) { + String cnaUpperCase = alteration.toUpperCase(); + return getCNAConsequence(cnaUpperCase).isPresent(); + } + + public static Boolean isGenomicChange(String alteration) { + Pattern p = Pattern.compile("(([0-9]{1,2}|X|Y|MT):)?g\\..*"); + Matcher m = p.matcher(alteration); + return m.matches(); + } + + public static String removeExclusionCriteria(String proteinChange) { + Matcher exclusionMatch = getExclusionCriteriaMatcher(proteinChange); + if (exclusionMatch.matches()) { + proteinChange = exclusionMatch.group(1).trim(); + } + return proteinChange; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/util/AminoAcidConverterUtils.java b/src/main/java/org/mskcc/oncokb/curation/util/AminoAcidConverterUtils.java new file mode 100644 index 000000000..a10dc456c --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/util/AminoAcidConverterUtils.java @@ -0,0 +1,52 @@ +package org.mskcc.oncokb.curation.util; + +public class AminoAcidConverterUtils { + + //code copied from https://github.com/genome-nexus/genome-nexus/blob/3b4d0eefa2ff4976b632180d770c4073cc957ecc/component/src/main/java/org/cbioportal/genome_nexus/component/annotation/ProteinChangeResolver.java#L95 + + // maps each letter to its corresponding three-letter code + private static final String AA3TO1[][] = { + { "Ala", "A" }, + { "Arg", "R" }, + { "Asn", "N" }, + { "Asp", "D" }, + { "Asx", "B" }, + { "Cys", "C" }, + { "Glu", "E" }, + { "Gln", "Q" }, + { "Glx", "Z" }, + { "Gly", "G" }, + { "His", "H" }, + { "Ile", "I" }, + { "Leu", "L" }, + { "Lys", "K" }, + { "Met", "M" }, + { "Phe", "F" }, + { "Pro", "P" }, + { "Ser", "S" }, + { "Thr", "T" }, + { "Trp", "W" }, + { "Tyr", "Y" }, + { "Val", "V" }, + { "Xxx", "X" }, + { "Ter", "*" }, + }; + + // converts a three-letter amino acid code to its one-letter amino acid code + public static String resolveHgvspShortFromHgvsp(String hgvsp) { + // check if there's a digit in order to not mistakenly convert a normal alteration name + if (hgvsp == null || !hgvsp.matches(".*\\d.*")) { + return hgvsp; + } + + String hgvspShort = hgvsp; + + for (int i = 0; i < 24; i++) { + if (hgvsp.contains(AA3TO1[i][0])) { + hgvspShort = hgvspShort.replaceAll(AA3TO1[i][0], AA3TO1[i][1]); + } + } + + return hgvspShort; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/util/COMPRESSED_FILE_FORMAT.java b/src/main/java/org/mskcc/oncokb/curation/util/COMPRESSED_FILE_FORMAT.java new file mode 100644 index 000000000..1019bf233 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/util/COMPRESSED_FILE_FORMAT.java @@ -0,0 +1,9 @@ +package org.mskcc.oncokb.curation.util; + +/** + * Created by Hongxin Zhang on 4/21/21. + */ +public enum COMPRESSED_FILE_FORMAT { + GZIP, + ZIP, +} diff --git a/src/main/java/org/mskcc/oncokb/curation/util/CancerTypeUtils.java b/src/main/java/org/mskcc/oncokb/curation/util/CancerTypeUtils.java new file mode 100644 index 000000000..596fbfe85 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/util/CancerTypeUtils.java @@ -0,0 +1,193 @@ +package org.mskcc.oncokb.curation.util; + +import static org.mskcc.oncokb.curation.util.enumeration.RelevantCancerTypeDirection.*; +import static org.mskcc.oncokb.curation.util.enumeration.SpecialCancerType.*; + +import com.google.common.collect.ImmutableList; +import java.util.*; +import java.util.stream.Collectors; +import org.apache.commons.lang3.StringUtils; +import org.mskcc.oncokb.curation.domain.CancerType; +import org.mskcc.oncokb.curation.domain.enumeration.TumorForm; +import org.mskcc.oncokb.curation.util.enumeration.RelevantCancerTypeDirection; +import org.mskcc.oncokb.curation.util.enumeration.SpecialCancerType; + +public class CancerTypeUtils { + + private static final List liquidTumorTissues = List.of("Lymph", "Blood", "Lymphoid", "Myeloid"); + + public static Boolean isSolidTumor(CancerType cancerType) { + return isDesiredTumorForm(cancerType, TumorForm.SOLID); + } + + public static Boolean isLiquidTumor(CancerType cancerType) { + return isDesiredTumorForm(cancerType, TumorForm.LIQUID); + } + + private static boolean isDesiredTumorForm(CancerType cancerType, TumorForm tumorForm) { + if (tumorForm == null || cancerType == null) { + return false; + } + + // This is mainly for the tissue + if (cancerType.getTumorForm() != null) { + return tumorForm.equals(cancerType.getTumorForm()); + } + + // when the code is null, we need to validate the main type + if (cancerType.getCode() == null) { + TumorForm mainTypeTumorForm = getTumorForm(cancerType.getMainType()); + if (cancerType.getMainType() != null && mainTypeTumorForm != null) { + return mainTypeTumorForm.equals(tumorForm); + } + } else { + return cancerType.getTumorForm() != null && cancerType.getTumorForm().equals(tumorForm); + } + return false; + } + + public static Boolean hasSolidTumor(Set cancerTypes) { + if (cancerTypes == null) return null; + for (CancerType cancerType : cancerTypes) { + if (isSolidTumor(cancerType)) { + return true; + } + } + return false; + } + + public static Boolean hasLiquidTumor(Set cancerTypes) { + if (cancerTypes == null) return null; + for (CancerType cancerType : cancerTypes) { + if (isLiquidTumor(cancerType)) { + return true; + } + } + return false; + } + + public static LinkedHashSet getParentTumorTypes(CancerType cancerType, boolean onlySameMainType) { + if (cancerType == null || cancerType.getParent() == null) return new LinkedHashSet<>(); + LinkedHashSet parentTumorTypes = new LinkedHashSet(); + // we do not want to include the tissue level which is 1 + if (cancerType.getParent() != null && cancerType.getLevel() > 2) { + if (!onlySameMainType || cancerType.getParent().getMainType().equals(cancerType.getMainType())) { + parentTumorTypes.add(cancerType.getParent()); + } + parentTumorTypes.addAll(getParentTumorTypes(cancerType.getParent(), onlySameMainType)); + } + return parentTumorTypes; + } + + public static LinkedHashSet getChildTumorTypes(CancerType cancerType, boolean onlySameMainType) { + if (cancerType == null || cancerType.getChildren().isEmpty()) return new LinkedHashSet<>(); + LinkedHashSet childTumorTypes = new LinkedHashSet(); + if (onlySameMainType) { + childTumorTypes.addAll( + cancerType + .getChildren() + .stream() + .filter(child -> child.getMainType().equals(cancerType.getMainType())) + .collect(Collectors.toList()) + ); + } else { + childTumorTypes.addAll(cancerType.getChildren()); + } + cancerType.getChildren().forEach(child -> childTumorTypes.addAll(getChildTumorTypes(child, onlySameMainType))); + return childTumorTypes; + } + + public static String getCancerTypeName(CancerType cancerType) { + if (cancerType == null) { + return ""; + } else { + if (!StringUtils.isEmpty(cancerType.getSubtype())) { + return cancerType.getSubtype(); + } else if (!StringUtils.isEmpty(cancerType.getMainType())) { + return cancerType.getMainType(); + } else { + return ""; + } + } + } + + public static String getCancerTypesName(Collection cancerTypes) { + return cancerTypes.stream().map(cancerType -> getCancerTypeName(cancerType)).collect(Collectors.joining(", ")); + } + + public static String getTumorTypesNameWithExclusion(Collection cancerTypes, Collection excludedTumorTypes) { + StringBuilder sb = new StringBuilder(getCancerTypesName(cancerTypes)); + if (excludedTumorTypes != null && excludedTumorTypes.size() > 0) { + sb.append(" (excluding "); + sb.append(getCancerTypesName(excludedTumorTypes)); + sb.append(")"); + } + return sb.toString(); + } + + private static TumorForm getTumorForm(CancerType cancerType) { + if (cancerType.getTumorForm() != null) { + return cancerType.getTumorForm(); + } + return null; + } + + public static TumorForm getTumorForm(Set cancerTypes) { + if (cancerTypes == null) return null; + Set uniqueTumorForms = cancerTypes + .stream() + .filter(cancerType -> { + TumorForm tumorForm = getTumorForm(cancerType); + return tumorForm != null; + }) + .map(cancerType -> getTumorForm(cancerType)) + .collect(Collectors.toSet()); + if (uniqueTumorForms.size() > 1) { + // There are ambiguous tumor forms + return TumorForm.MIXED; + } else if (uniqueTumorForms.size() == 0) { + return null; + } else { + return uniqueTumorForms.iterator().next(); + } + } + + public static TumorForm getTumorForm(SpecialCancerType specialTumorType) { + if (specialTumorType == null) return null; + + if (specialTumorType.equals(ALL_LIQUID_TUMORS) || specialTumorType.equals(SpecialCancerType.OTHER_LIQUID_TUMOR_TYPES)) { + return TumorForm.LIQUID; + } else if (specialTumorType.equals(ALL_SOLID_TUMORS) || specialTumorType.equals(SpecialCancerType.OTHER_SOLID_TUMOR_TYPES)) { + return TumorForm.SOLID; + } else { + return TumorForm.MIXED; + } + } + + public static TumorForm getTumorForm(String tissue) { + if (StringUtils.isNotEmpty(tissue)) { + if (liquidTumorTissues.contains(tissue)) return TumorForm.LIQUID; + else return TumorForm.SOLID; + } + return null; + } + + private static class SortByLevel implements Comparator { + + @Override + public int compare(CancerType ct1, CancerType ct2) { + int levelComparison = Integer.compare(ct1.getLevel(), ct2.getLevel()); + if (levelComparison != 0) { + return levelComparison; + } + String ct1Name = ct1.getSubtype() != null ? ct1.getSubtype() : ct1.getMainType(); + String ct2Name = ct2.getSubtype() != null ? ct2.getSubtype() : ct2.getMainType(); + return ct1Name.compareTo(ct2Name); + } + } + + public static void sortByLevel(List cancerTypes) { + SortByLevel comparator = new SortByLevel(); + cancerTypes.sort(comparator); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/util/CdxUtils.java b/src/main/java/org/mskcc/oncokb/curation/util/CdxUtils.java new file mode 100644 index 000000000..bdd723cae --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/util/CdxUtils.java @@ -0,0 +1,309 @@ +package org.mskcc.oncokb.curation.util; + +import java.io.IOException; +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Optional; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import org.apache.commons.lang3.StringUtils; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; +import org.mskcc.oncokb.curation.domain.CompanionDiagnosticDevice; +import org.mskcc.oncokb.curation.domain.FdaSubmission; +import org.mskcc.oncokb.curation.domain.FdaSubmissionType; +import org.mskcc.oncokb.curation.service.FdaSubmissionTypeService; +import org.mskcc.oncokb.curation.service.GeneService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class CdxUtils { + + private final Logger log = LoggerFactory.getLogger(CdxUtils.class); + + private final String CDX_URL = + "https://www.fda.gov/medical-devices/in-vitro-diagnostics/list-cleared-or-approved-companion-diagnostic-devices-in-vitro-and-imaging-tools"; + + private final Set cdxDeviceFieldNames = Set.of("Device Name", "Trade Name", "Device"); + + private final Set cdxNumberFieldNames = Set.of("PMA Number", "HDE Number", "510(K) Number", "De Novo Number"); + + @Autowired + private FdaSubmissionTypeService fdaSubmissionTypeService; + + @Autowired + private GeneService geneService; + + // Extract relevant information from the FDA CDx page + public List getCdxListFromHTML() throws IOException { + // Fetch the html from the fda cdx page + Document document = Jsoup.connect(CDX_URL).get(); + + Element table = document.select("table").first(); + + // Extract the table rows + List companionDiagnosticDevices = new ArrayList<>(); + Element tbody = table.select("tbody").first(); + Integer rowSpanCount = 0; + Integer rowCount = 0; + for (Element tr : tbody.getElementsByTag("tr")) { + rowCount++; + Elements td = tr.getElementsByTag("td"); + if (rowSpanCount > 0) { // Some cells may span across multiple rows + rowSpanCount--; + continue; + } + try { + rowSpanCount = Integer.parseInt(td.first().attributes().get("rowspan")) - 1; + } catch (NumberFormatException e) {} + ArrayList tableCells = td.stream().limit(3).map(e -> e.text()).collect(Collectors.toCollection(ArrayList::new)); + + // Create CompanionDiagnosticDevice entity + CompanionDiagnosticDevice cdx = new CompanionDiagnosticDevice(); + if (tableCells.size() < 3) { + log.warn("Row has less than 3 elements: {}", rowCount); + continue; + } + cdx.setName(tableCells.get(0)); + Set submissionCodes = Arrays.asList(tableCells.get(1).split("\\s")) + .stream() + .map(code -> code.trim().split("/")[0]) // Only get the primary pma + .filter(code -> code.length() > 0) + .collect(Collectors.toSet()); + cdx.setFdaSubmissions(getFDASubmissionFromHTML(submissionCodes, false, true)); + cdx.setManufacturer(tableCells.get(2)); + companionDiagnosticDevices.add(cdx); + } + return companionDiagnosticDevices; + } + + /** + * Extract the relevant information from the PMA / 510(k) / HDE pages + * @param fdaSubmissionCodes the submission codes to fetch from fda website + * @param exact if submission is a supplement, then return the supplement + * @param getAllSupplements parse all supplements when given a primary pma + */ + public Set getFDASubmissionFromHTML(Set fdaSubmissionCodes, Boolean exact, Boolean getAllSupplements) { + // Check if the fda submission codes are valid and purify input + Set purifiedSubmissionCodes = new HashSet<>(); + for (String code : fdaSubmissionCodes) { + Pattern regex = Pattern.compile("^([A-Z]+[0-9]+)(\\/((S[0-9]+)(-(S[0-9]+))?))?"); + Matcher matcher = regex.matcher(code.toUpperCase()); + if (matcher.find()) { + String primaryPma = matcher.group(1); + if (getAllSupplements) { + purifiedSubmissionCodes.clear(); + purifiedSubmissionCodes.add(primaryPma); + findAllSupplements(primaryPma).stream().forEach(supplement -> purifiedSubmissionCodes.add(primaryPma + supplement)); + } else { + if (!exact || matcher.group(2) == null) { + purifiedSubmissionCodes.add(primaryPma); + } + String supplement = matcher.group(3); + if (supplement != null) { + // Sometimes the PMAs are given as ranges (ie. P990081/S001-S028). + Integer start = Integer.valueOf(matcher.group(4).substring(1)); + Integer end = matcher.group(6) != null ? Integer.valueOf(matcher.group(6).substring(1)) : start; + IntStream.rangeClosed(start, end).forEach(num -> { + String pmaString = String.format("%sS%03d", primaryPma, num); + purifiedSubmissionCodes.add(pmaString); + }); + } + } + } + } + + // Fetch the PMA/510(k)/HDE information from webpage + Set fdaSubmissions = new HashSet<>(); + for (String code : purifiedSubmissionCodes) { + Document submissionInfoDocument = getJsoupDocument(code); + if (submissionInfoDocument == null) { + continue; + } + + Element targetTable = findFdaSubmissionTable(submissionInfoDocument); + if (targetTable == null) { + log.warn("No information found for fda submission : {}", code); + continue; + } + + Element tbody = targetTable.select("tbody").first(); + + FdaSubmission fdaSubmission = new FdaSubmission(); + + for (Element tr : tbody.getElementsByTag("tr")) { + Element th = tr.getElementsByTag("th").first(); + Element td = tr.getElementsByTag("td").first(); + + if (th != null) { + String header = th.text().trim(); + String content = td.text().trim(); + if (this.cdxDeviceFieldNames.stream().anyMatch(header::equalsIgnoreCase)) { + fdaSubmission.setDeviceName(content); + } else if (this.cdxNumberFieldNames.stream().anyMatch(header::equalsIgnoreCase)) { + fdaSubmission.setNumber(content); + } else if (header.equalsIgnoreCase("Generic Name")) { + fdaSubmission.setGenericName(content); + } else if (header.equalsIgnoreCase("Supplement Number")) { + fdaSubmission.setSupplementNumber(content); + } else if (header.equalsIgnoreCase("Date Received")) { + fdaSubmission.setDateReceived(convertDateToLocalDate(content)); + } else if (header.equalsIgnoreCase("Decision Date")) { + fdaSubmission.setDecisionDate(convertDateToLocalDate(content)); + } + } else { + // The Approval Order Statement column does not have the header stored in element + // Instead it is a inside element. + th = td.children().first(); + if (th != null) { + String header = th.text().trim(); + if (header.equalsIgnoreCase("Approval Order Statement")) { + String approvalOrderStatement = td.textNodes().get(td.textNodes().size() - 1).text(); + fdaSubmission.setDescription(approvalOrderStatement); + Boolean isGenetic = isGenetic(approvalOrderStatement); + fdaSubmission.setGenetic(isGenetic); + } + } + } + } + + // Add FDASubmissionType + if (fdaSubmission.getNumber() != null) { + Optional type = fdaSubmissionTypeService.findOneBySubmissionNumber(fdaSubmission.getNumber()); + if (type.isPresent()) { + fdaSubmission.setType(type.orElseThrow()); + } + } + fdaSubmissions.add(fdaSubmission); + } + return fdaSubmissions; + } + + private Document getJsoupDocument(String code) { + Document submissionInfoDocument = null; + String prefix = code.split("[0-9]").length > 0 ? code.split("[0-9]")[0] : null; + String url = FdaSubmissionUrl.getFullUrl(prefix, code); + if (url == null) { + log.warn("Fda submission code is not valid: {}", code); + } else { + try { + submissionInfoDocument = Jsoup.connect(url).get(); + } catch (IOException e) { + log.warn("Failed to fetch fda submission from fda: {}", code); + } + } + return submissionInfoDocument; + } + + private Element findFdaSubmissionTable(Document submissionInfoDocument) { + // The page contains many tables, so we need to find the table containing + // the relevant information. The PMA/510(K)/HDE tables all have a common 'Date Received' + // field that we can use to locate the desired table. + Elements tables = submissionInfoDocument.select("table"); + Element targetTable = null; + for (Element table : tables) { + Elements tableHeaders = table.select("> tbody > tr > th"); + if (tableHeaders.isEmpty()) { + continue; + } + Boolean isTargetTable = tableHeaders.stream().anyMatch(header -> header.text().trim().equals("Date Received")); + if (isTargetTable) { + targetTable = table; + break; + } + } + return targetTable; + } + + /** + * Find all supplement numbers for the primary fda submission number. + * @param primaryPma primary number + * @return list of supplement numbers + */ + private Set findAllSupplements(String primaryPma) { + Set supplements = new HashSet(); + Document primaryPmaDocument = getJsoupDocument(primaryPma); + if (primaryPmaDocument == null) { + return supplements; + } + + Element targetTable = findFdaSubmissionTable(primaryPmaDocument); + if (targetTable == null) { + log.warn("No information found for fda submission : {}", primaryPma); + return supplements; + } + + Element tbody = targetTable.select("tbody").first(); + for (Element tr : tbody.getElementsByTag("tr")) { + Element th = tr.getElementsByTag("th").first(); + Element td = tr.getElementsByTag("td").first(); + if (th != null) { + String header = th.text().trim(); + String content = td.text().trim(); + if (header.equalsIgnoreCase("Supplements:")) { + supplements.addAll(Arrays.asList(content.split("\\s"))); + } + } + } + return supplements; + } + + public LocalDate convertDateToLocalDate(String date) { + if (StringUtils.isEmpty(date)) { + return null; + } + return LocalDate.parse(date, DateTimeFormatter.ofPattern("MM/dd/yyyy", Locale.US)); + } + + /** + * Checks whether the description contains any genes + * @param description the fda submission description + * @return true if the description mentions a gene + */ + private Boolean isGenetic(String description) { + Set searchValues = Arrays.asList(description.replaceAll("[^\\w\\s-]", " ").split(" ")) + .stream() + .map(val -> val.trim().toUpperCase()) + .collect(Collectors.toSet()); + return !geneService.findByHugoSymbolIn(searchValues).isEmpty(); + } +} + +enum FdaSubmissionUrl { + PMA("P", "cfpma/pma.cfm"), + PMN("K", "cfpmn/pmn.cfm"), + HDE("H", "cfhde/hde.cfm"), + DEN("DEN", "cfpmn/denovo.cfm"); + + String prefix; + String urlSuffix; + + FdaSubmissionUrl(String prefix, String urlSuffix) { + this.prefix = prefix; + this.urlSuffix = urlSuffix; + } + + public static String getFullUrl(String prefix, String idParam) { + for (FdaSubmissionUrl fdaSubmissionUrl : FdaSubmissionUrl.values()) { + if (fdaSubmissionUrl.prefix.equalsIgnoreCase(prefix)) { + return "https://www.accessdata.fda.gov/scripts/cdrh/cfdocs/" + fdaSubmissionUrl.urlSuffix + "?id=" + idParam; + } + } + return null; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/util/FileUtils.java b/src/main/java/org/mskcc/oncokb/curation/util/FileUtils.java new file mode 100644 index 000000000..ca0b277bc --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/util/FileUtils.java @@ -0,0 +1,145 @@ +package org.mskcc.oncokb.curation.util; + +import java.io.*; +import java.net.URL; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class FileUtils { + + /** + * read local files and return content + * + * @param pathToFile + * @return + * @throws IOException + */ + public static String readLocal(String pathToFile) throws IOException { + return readStream(new FileInputStream(pathToFile)); + } + + /** + * return remote files and return content + * + * @param urlToFile + * @return + * @throws IOException + */ + public static String readRemote(String urlToFile) throws IOException { + URL url = new URL(urlToFile); + return readStream(url.openStream()); + } + + /** + * read a stream and return content + * + * @param is + * @return + * @throws IOException + */ + public static String readStream(InputStream is) throws IOException { + List lines = readTrimmedLinesStream(is); + return String.join("\n", lines); + } + + public static List readTrimmedLinesStream(InputStream is) throws IOException { + return readLinesStream(is, true); + } + + /** + * read a stream and return lines + * + * @param is + * @return + * @throws IOException + */ + public static List readLinesStream(InputStream is, boolean trim) throws IOException { + BufferedReader in = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8"))); + + List lines = new ArrayList(); + String line; + while ((line = in.readLine()) != null) { + if (trim) { + line = line.trim(); + } + if (!line.isEmpty()) lines.add(line); + } + in.close(); + + return lines; + } + + /** + * read a stream and splits each line by a delimiter + * + * @param is + * @param delimiter + * @param trim + * @return + * @throws IOException + */ + public static List> readDelimitedLinesStream(InputStream is, String delimiter, Boolean trim) throws IOException { + List> rows = new ArrayList<>(); + + BufferedReader in = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8"))); + + String line; + while ((line = in.readLine()) != null) { + List row = Arrays.asList(line.split(delimiter)); + if (trim) { + row.stream().map(String::trim); + } + rows.add(row); + } + + return rows; + } + + public static List> parseDelimitedFileWithoutHeader(String filePath, String delimiter, boolean trim, int numOfColumns) + throws IOException { + List readmeFileLines = readTrimmedLinesStream(new FileInputStream(filePath)); + // remove the first line which includes the column headers + return parseDelimitedFile(readmeFileLines, delimiter, trim, numOfColumns); + } + + public static List> parseDelimitedFile(String filePath, String delimiter, boolean trim) throws IOException { + List readmeFileLines = readTrimmedLinesStream(new FileInputStream(filePath)); + // remove the first line which includes the column headers + if (readmeFileLines.size() > 0) { + String header = readmeFileLines.remove(0); + final int numOfColumns = header.split(delimiter).length; + return parseDelimitedFile(readmeFileLines, delimiter, trim, numOfColumns); + } + return new ArrayList<>(); + } + + private static List> parseDelimitedFile(List fileLines, String delimiter, boolean trim, int numOfColumns) { + return fileLines + .stream() + .map(line -> { + List cellList = Arrays.stream(line.split(delimiter)).collect(Collectors.toList()); + if (cellList.size() < numOfColumns) { + for (int i = cellList.size() - 1; i < numOfColumns; i++) { + cellList.add(null); + } + } + if (trim) { + cellList = cellList + .stream() + .map(cell -> { + if (cell == null) { + return ""; + } else { + return cell.trim(); + } + }) + .collect(Collectors.toList()); + } + return cellList; + }) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/util/GsonUtils.java b/src/main/java/org/mskcc/oncokb/curation/util/GsonUtils.java new file mode 100644 index 000000000..9c8fb0a79 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/util/GsonUtils.java @@ -0,0 +1,14 @@ +package org.mskcc.oncokb.curation.util; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import java.time.Instant; +import org.mskcc.oncokb.curation.config.InstantTypeAdapter; + +public class GsonUtils { + + public static Gson create() { + // https://medium.com/@pratiktikarye/instant-to-gson-conversion-in-java-17-2673bb59fbea + return new GsonBuilder().registerTypeAdapter(Instant.class, new InstantTypeAdapter()).create(); + } +} diff --git a/src/main/java/org/mskcc/oncokb/transcript/util/GzipUtils.java b/src/main/java/org/mskcc/oncokb/curation/util/GzipUtils.java similarity index 99% rename from src/main/java/org/mskcc/oncokb/transcript/util/GzipUtils.java rename to src/main/java/org/mskcc/oncokb/curation/util/GzipUtils.java index 002f3f300..b33d96f52 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/util/GzipUtils.java +++ b/src/main/java/org/mskcc/oncokb/curation/util/GzipUtils.java @@ -1,4 +1,4 @@ -package org.mskcc.oncokb.transcript.util; +package org.mskcc.oncokb.curation.util; import java.io.*; import java.util.zip.GZIPInputStream; diff --git a/src/main/java/org/mskcc/oncokb/curation/util/HotspotUtils.java b/src/main/java/org/mskcc/oncokb/curation/util/HotspotUtils.java new file mode 100644 index 000000000..73f111bb1 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/util/HotspotUtils.java @@ -0,0 +1,51 @@ +package org.mskcc.oncokb.curation.util; + +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.mskcc.oncokb.curation.model.IntegerRange; + +public class HotspotUtils { + + public static IntegerRange extractProteinPos(String proteinChange) { + IntegerRange proteinPos = null; + Integer start = -1; + Integer end = -1; + + List positions = extractPositiveIntegers(proteinChange); + + // ideally positions.size() should always be 2 + if (positions.size() >= 2) { + start = positions.get(0); + end = positions.get(positions.size() - 1); + } + // in case no end point, use start as end + else if (!positions.isEmpty()) { + start = end = positions.get(0); + } + + if (!start.equals(-1)) { + proteinPos = new IntegerRange(); + proteinPos.setStart(start); + proteinPos.setEnd(end); + } + + return proteinPos; + } + + private static List extractPositiveIntegers(String input) { + if (input == null) { + return Collections.emptyList(); + } + + List list = new ArrayList<>(); + Pattern p = Pattern.compile("\\d+"); + Matcher m = p.matcher(input); + + while (m.find()) { + list.add(Integer.parseInt(m.group())); + } + + return list; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/util/TimeUtil.java b/src/main/java/org/mskcc/oncokb/curation/util/TimeUtil.java new file mode 100644 index 000000000..689aa45b2 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/util/TimeUtil.java @@ -0,0 +1,47 @@ +package org.mskcc.oncokb.curation.util; + +import static org.mskcc.oncokb.curation.config.Constants.NY_ZONE_ID; +import static org.mskcc.oncokb.curation.config.Constants.UTC_ZONE_ID; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; +import java.time.format.FormatStyle; +import java.time.temporal.ChronoField; +import java.util.Locale; + +public class TimeUtil { + + public static String toSystemDefaultZoneTime(Instant time) { + DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL) + .withLocale(Locale.US) + .withZone(ZoneId.systemDefault()); + return formatter.format(time); + } + + public static String toNYZoneTime(Instant time) { + DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL) + .withLocale(Locale.US) + .withZone(ZoneId.of(NY_ZONE_ID)); + return formatter.format(time); + } + + public static ZonedDateTime getCurrentNYTime() { + return ZonedDateTime.now(ZoneId.of(NY_ZONE_ID)); + } + + public static Instant parseDbStringInstant(String instantStr) { + // 2020-10-23 08:00:00.000000 + DateTimeFormatter dateTimeFormatter = new DateTimeFormatterBuilder() + .appendPattern("yyyy-MM-dd HH:mm:ss") + .appendFraction(ChronoField.NANO_OF_SECOND, 1, 9, true) + .toFormatter(); + LocalDateTime localDateTime = LocalDateTime.parse(instantStr, dateTimeFormatter); + ZoneId zoneId = ZoneId.of(UTC_ZONE_ID); + ZonedDateTime zonedDateTime = localDateTime.atZone(zoneId); + return zonedDateTime.toInstant(); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/util/enumeration/RelevantCancerTypeDirection.java b/src/main/java/org/mskcc/oncokb/curation/util/enumeration/RelevantCancerTypeDirection.java new file mode 100644 index 000000000..7f787dd32 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/util/enumeration/RelevantCancerTypeDirection.java @@ -0,0 +1,6 @@ +package org.mskcc.oncokb.curation.util.enumeration; + +public enum RelevantCancerTypeDirection { + UPWARD, + DOWNWARD, +} diff --git a/src/main/java/org/mskcc/oncokb/curation/util/enumeration/SpecialCancerType.java b/src/main/java/org/mskcc/oncokb/curation/util/enumeration/SpecialCancerType.java new file mode 100644 index 000000000..c60ccb2e9 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/util/enumeration/SpecialCancerType.java @@ -0,0 +1,38 @@ +package org.mskcc.oncokb.curation.util.enumeration; + +import java.util.HashMap; +import java.util.Map; + +public enum SpecialCancerType { + ALL_TUMORS("All Tumors"), + ALL_LIQUID_TUMORS("All Liquid Tumors"), + ALL_SOLID_TUMORS("All Solid Tumors"), + GERMLINE_DISPOSITION("Germline Disposition"), + OTHER_TUMOR_TYPES("Other Tumor Types"), + OTHER_SOLID_TUMOR_TYPES("Other Solid Tumor Types"), + OTHER_LIQUID_TUMOR_TYPES("Other Liquid Tumor Types"); + + private SpecialCancerType(String tumorType) { + this.tumorType = tumorType; + } + + private final String tumorType; + + public String getTumorType() { + return tumorType; + } + + private static final Map map = new HashMap<>(); + + static { + for (SpecialCancerType specialTumorType : SpecialCancerType.values()) { + map.put(specialTumorType.name().toLowerCase(), specialTumorType); + map.put(specialTumorType.getTumorType().toLowerCase(), specialTumorType); + } + } + + public static SpecialCancerType getByTumorType(String tumorType) { + if (tumorType == null) return null; + return map.get(tumorType.toLowerCase()); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/util/parser/ParsingStatus.java b/src/main/java/org/mskcc/oncokb/curation/util/parser/ParsingStatus.java new file mode 100644 index 000000000..f15e95ee2 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/util/parser/ParsingStatus.java @@ -0,0 +1,38 @@ +package org.mskcc.oncokb.curation.util.parser; + +import org.mskcc.oncokb.curation.domain.enumeration.EntityStatusType; + +public class ParsingStatus { + + EntityStatusType status; + String message; + T entity; + + public Boolean isParsed() { + return this.status != null; + } + + public EntityStatusType getStatus() { + return status; + } + + public void setStatus(EntityStatusType status) { + this.status = status; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public T getEntity() { + return entity; + } + + public void setEntity(T entity) { + this.entity = entity; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/util/parser/ProteinChangeParser.java b/src/main/java/org/mskcc/oncokb/curation/util/parser/ProteinChangeParser.java new file mode 100644 index 000000000..2f2627c69 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/util/parser/ProteinChangeParser.java @@ -0,0 +1,357 @@ +package org.mskcc.oncokb.curation.util.parser; + +import static java.util.regex.Pattern.CASE_INSENSITIVE; +import static org.mskcc.oncokb.curation.domain.enumeration.MutationConsequence.*; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.text.similarity.JaroWinklerSimilarity; +import org.mskcc.oncokb.curation.domain.Alteration; +import org.mskcc.oncokb.curation.domain.Consequence; +import org.mskcc.oncokb.curation.domain.enumeration.EntityStatusType; +import org.mskcc.oncokb.curation.domain.enumeration.MutationConsequence; + +public class ProteinChangeParser { + + /** + * support extension variant (https://varnomen.hgvs.org/recommendations/protein/variant/extension/) + * the following examples are supported + * *959Qext*14 + * *110Gext*17 + * *315TextALGT* + * *327Aext*? + */ + public static ParsingStatus parseExtension(String proteinChange) { + ParsingStatus parsingStatus = new ParsingStatus<>(); + Alteration alteration = new Alteration(); + + Pattern p = Pattern.compile("M?1ext(-[0-9]+)?", Pattern.CASE_INSENSITIVE); + Matcher m = p.matcher(proteinChange); + if (m.matches()) { + alteration.setStart(1); + alteration.setEnd(1); + Consequence consequence = new Consequence(); + consequence.setTerm(INFRAME_INSERTION.name()); + alteration.setConsequence(consequence); + parsingStatus.setStatus(EntityStatusType.OK); + } else { + p = Pattern.compile("(\\*)?([0-9]+)([A-Z])?ext([A-Z]+)?\\*(([0-9]+)?(\\?)?)", CASE_INSENSITIVE); + m = p.matcher(proteinChange); + if (m.matches()) { + String revisedProteinChange = ""; + + alteration.setRefResidues(Optional.ofNullable(m.group(1)).orElse("*")); + alteration.setStart(Integer.valueOf(m.group(2))); + alteration.setEnd(alteration.getStart()); + String var = Optional.ofNullable(m.group(3)).orElse("").toUpperCase(); + revisedProteinChange = alteration.getRefResidues() + alteration.getStart() + var + "ext"; + if (m.group(4) != null) { + revisedProteinChange += m.group(4).toUpperCase(); + } + revisedProteinChange += "*"; + if (m.group(5) != null) { + revisedProteinChange += m.group(5); + } + Consequence consequence = new Consequence(); + consequence.setTerm(STOP_LOST.name()); + alteration.setConsequence(consequence); + alteration.setProteinChange(StringUtils.isEmpty(revisedProteinChange) ? proteinChange : revisedProteinChange); + parsingStatus.setStatus(EntityStatusType.OK); + } + } + parsingStatus.setEntity(alteration); + return parsingStatus; + } + + public static ParsingStatus parseGeneral(String proteinChange) { + Pattern p = Pattern.compile("^([A-Z\\*]+)?([0-9]+)([A-Z\\*\\?]*)$", CASE_INSENSITIVE); + Matcher m = p.matcher(proteinChange); + ParsingStatus parsingStatus = new ParsingStatus<>(); + if (m.matches()) { + Alteration alteration = new Alteration(); + String revisedProteinChange = ""; + MutationConsequence term = null; + + String ref = Optional.ofNullable(m.group(1)).orElse("").toUpperCase(); + String var = m.group(3).toUpperCase(); + alteration.setRefResidues(ref); + alteration.setVariantResidues(var); + Integer start = Integer.valueOf(m.group(2)); + alteration.setStart(start); + Integer end = start; + revisedProteinChange = ref + start + var; + + Integer refL = ref.length(); + Integer varL = var.length(); + + if (ref.equals("*")) { + term = STOP_LOST; + } else if (var.equals("*")) { + term = STOP_GAINED; + } else if (ref.equals(var)) { + term = SYNONYMOUS_VARIANT; + } else if (start == 1) { + term = START_LOST; + } else if (var.equals("?")) { + term = ANY; + } else { + end = start + refL - 1; + if (refL > 1 || varL > 1) { + // Handle in-frame insertion/deletion event. Exp: IK744K + if (refL > varL) { + term = INFRAME_DELETION; + } else if (refL < varL) { + term = INFRAME_INSERTION; + } else { + term = MISSENSE_VARIANT; + } + } else if (refL == 1 && varL == 1) { + term = MISSENSE_VARIANT; + } else { + parsingStatus.setStatus(EntityStatusType.WARNING); + parsingStatus.setMessage("Unable to determine consequence"); + term = NA; + } + } + alteration.setEnd(end); + if (term != null) { + Consequence consequence = new Consequence(); + consequence.setTerm(term.name()); + alteration.setConsequence(consequence); + } + alteration.setProteinChange(StringUtils.isEmpty(revisedProteinChange) ? proteinChange : revisedProteinChange); + parsingStatus.setEntity(alteration); + parsingStatus.setStatus(EntityStatusType.OK); + } + return parsingStatus; + } + + public static ParsingStatus parseInframe(String proteinChange) { + Pattern p = Pattern.compile("([A-Z]?)([0-9]+)(_[A-Z]?([0-9]+))?(delins|ins|del|dup)(.*)?", CASE_INSENSITIVE); + Matcher m = p.matcher(proteinChange); + ParsingStatus parsingStatus = new ParsingStatus<>(); + if (m.matches()) { + Alteration alteration = new Alteration(); + String revisedProteinChange = ""; + MutationConsequence term = UNKNOWN; + if (m.group(1) != null && m.group(3) == null) { + // we only want to specify reference when it's one position ins/del + alteration.setRefResidues(m.group(1).toUpperCase()); + } + revisedProteinChange += m.group(1).toUpperCase(); + alteration.setStart(Integer.valueOf(m.group(2))); + revisedProteinChange += alteration.getStart(); + if (m.group(3) != null) { + revisedProteinChange += m.group(3).toUpperCase(); + } + alteration.setEnd(m.group(4) != null ? Integer.valueOf(m.group(4)) : alteration.getStart()); + String type = m.group(5); + String var = Optional.ofNullable(m.group(6)).orElse("").toUpperCase(); + revisedProteinChange += type + var; + if (StringUtils.isNotEmpty(var) && !var.matches("[A-Z]+")) { + var = ""; + } + if (type.equals("ins")) { + if (StringUtils.isNotEmpty(var)) { + term = INFRAME_INSERTION; + } + } else if (type.equals("dup")) { + term = INFRAME_INSERTION; + } else if (type.equals("del")) { + term = INFRAME_DELETION; + } else if (StringUtils.isNotEmpty(var)) { + Integer deletion = alteration.getEnd() - alteration.getStart() + 1; + Integer insertion = m.group(6).length(); + + if (insertion - deletion > 0) { + term = INFRAME_INSERTION; + } else if (insertion - deletion == 0) { + term = MISSENSE_VARIANT; + } else { + term = INFRAME_DELETION; + } + } + + if (term != null) { + Consequence consequence = new Consequence(); + consequence.setTerm(term.name()); + alteration.setConsequence(consequence); + } + alteration.setProteinChange(StringUtils.isEmpty(revisedProteinChange) ? proteinChange : revisedProteinChange); + parsingStatus.setEntity(alteration); + parsingStatus.setStatus(EntityStatusType.OK); + } + return parsingStatus; + } + + public static ParsingStatus parseFrameshift(String proteinChange) { + Pattern p = Pattern.compile("([A-Z])?([0-9]+)([A-Z])?(_[A-Z]?([0-9]+)[A-Z]?)?fs(.*)", CASE_INSENSITIVE); + Matcher m = p.matcher(proteinChange); + + ParsingStatus parsingStatus = new ParsingStatus<>(); + if (m.matches()) { + Alteration alteration = new Alteration(); + String ref = Optional.ofNullable(m.group(1)).orElse("").toUpperCase(); + alteration.setStart(Integer.valueOf(m.group(2))); + if (m.group(5) != null) { + alteration.setEnd(Integer.valueOf(m.group(5))); + } else { + alteration.setRefResidues(ref); + alteration.setEnd(alteration.getStart()); + } + + String revisedProteinChange = ref + alteration.getStart(); + if (m.group(3) != null) { + revisedProteinChange += m.group(3).toUpperCase(); + } + if (m.group(4) != null) { + revisedProteinChange += m.group(4).toUpperCase(); + } + revisedProteinChange += "fs"; + if (m.group(6) != null) { + revisedProteinChange += m.group(6); + } + + Consequence consequence = new Consequence(); + consequence.setTerm(FRAMESHIFT_VARIANT.name()); + alteration.setConsequence(consequence); + + alteration.setProteinChange(StringUtils.isEmpty(revisedProteinChange) ? proteinChange : revisedProteinChange); + parsingStatus.setEntity(alteration); + parsingStatus.setStatus(EntityStatusType.OK); + } + return parsingStatus; + } + + public static ParsingStatus parseRange(String proteinChange) { + Pattern p = Pattern.compile("([A-Z]?)([0-9]+)_([A-Z]?)([0-9]+)(.+)", CASE_INSENSITIVE); + Matcher m = p.matcher(proteinChange); + ParsingStatus parsingStatus = new ParsingStatus<>(); + if (m.matches()) { + Alteration alteration = new Alteration(); + String revisedProteinChange = ""; + + alteration.setStart(Integer.valueOf(m.group(2))); + alteration.setEnd(Integer.valueOf(m.group(4))); + String variant = m.group(5); + + HashMap termsToCheck = new HashMap<>(); + termsToCheck.put("mis", MISSENSE_VARIANT); + termsToCheck.put("ins", INFRAME_INSERTION); + termsToCheck.put("del", INFRAME_DELETION); + termsToCheck.put("fs", FEATURE_TRUNCATION); + termsToCheck.put("trunc", FEATURE_TRUNCATION); + termsToCheck.put("dup", INFRAME_INSERTION); + termsToCheck.put("mut", ANY); + + MutationConsequence mutationConsequence = termsToCheck.get(variant); + if (mutationConsequence != null) { + revisedProteinChange += m.group(1).toUpperCase(); + revisedProteinChange += m.group(2) + "_"; + revisedProteinChange += m.group(3).toUpperCase(); + revisedProteinChange += m.group(4) + variant; + + if (mutationConsequence != null) { + Consequence consequence = new Consequence(); + consequence.setTerm(mutationConsequence.name()); + alteration.setConsequence(consequence); + } + alteration.setProteinChange(StringUtils.isEmpty(revisedProteinChange) ? proteinChange : revisedProteinChange); + parsingStatus.setEntity(alteration); + parsingStatus.setStatus(EntityStatusType.OK); + } else { + Double greatestSimilarity = -1.0; + String termWithGreatestSimilarity = ""; + JaroWinklerSimilarity jw = new JaroWinklerSimilarity(); + for (Map.Entry entry : termsToCheck.entrySet()) { + double similarity = jw.apply(variant, entry.getKey()); + if (similarity > greatestSimilarity) { + greatestSimilarity = similarity; + termWithGreatestSimilarity = entry.getKey(); + } + } + parsingStatus.setStatus(EntityStatusType.ERROR); + parsingStatus.setMessage( + "The alteration name is invalid, do you mean " + + m.group(1) + + m.group(2) + + "_" + + m.group(3) + + m.group(4) + + termWithGreatestSimilarity + + "?" + ); + } + } + return parsingStatus; + } + + public static ParsingStatus parseSplice(String proteinChange) { + Pattern p = Pattern.compile("([A-Z]?)([0-9]+)(_[A-Z]?([0-9]+))?(_)?splice", CASE_INSENSITIVE); + Matcher m = p.matcher(proteinChange); + ParsingStatus parsingStatus = new ParsingStatus<>(); + if (m.matches()) { + String revisedProteinChange = ""; + Alteration alteration = new Alteration(); + if (m.group(1) != null && m.group(3) == null) { + // we only want to specify reference when it's one position splice + String var = m.group(1).toUpperCase(); + alteration.setRefResidues("X".equals(var) ? "" : var); + revisedProteinChange += alteration.getRefResidues().toUpperCase(); + } + alteration.setStart(Integer.valueOf(m.group(2))); + revisedProteinChange += alteration.getStart(); + if (m.group(3) != null) { + revisedProteinChange += m.group(3).toUpperCase() + "splice"; + } else { + revisedProteinChange += "_splice"; + } + alteration.setEnd(m.group(4) != null ? Integer.valueOf(m.group(4)) : alteration.getStart()); + + Consequence consequence = new Consequence(); + consequence.setTerm(SPLICE_REGION_VARIANT.name()); + alteration.setConsequence(consequence); + alteration.setProteinChange(StringUtils.isEmpty(revisedProteinChange) ? proteinChange : revisedProteinChange); + parsingStatus.setEntity(alteration); + parsingStatus.setStatus(EntityStatusType.OK); + } + return parsingStatus; + } + + public static ParsingStatus parseSynonymous(String proteinChange) { + Pattern p = Pattern.compile("([A-Z\\*])?([0-9]+)=", CASE_INSENSITIVE); + Matcher m = p.matcher(proteinChange); + ParsingStatus parsingStatus = new ParsingStatus<>(); + if (m.matches()) { + String revisedProteinChange = ""; + Alteration alteration = new Alteration(); + MutationConsequence term; + + if (m.group(1) != null) { + alteration.setRefResidues(m.group(1).toUpperCase()); + alteration.setVariantResidues(alteration.getRefResidues()); + revisedProteinChange += alteration.getRefResidues(); + } + alteration.setStart(Integer.valueOf(m.group(2))); + alteration.setEnd(alteration.getStart()); + revisedProteinChange += alteration.getStart() + "="; + if ("*".equals(alteration.getRefResidues())) { + term = STOP_RETAINED_VARIANT; + } else { + term = SYNONYMOUS_VARIANT; + } + + Consequence consequence = new Consequence(); + consequence.setTerm(term.name()); + alteration.setConsequence(consequence); + alteration.setProteinChange(StringUtils.isEmpty(revisedProteinChange) ? proteinChange : revisedProteinChange); + parsingStatus.setEntity(alteration); + parsingStatus.setStatus(EntityStatusType.OK); + } + return parsingStatus; + } +} diff --git a/src/main/java/org/mskcc/oncokb/transcript/vm/AllReferenceTranscriptSuggestionVM.java b/src/main/java/org/mskcc/oncokb/curation/vm/AllReferenceTranscriptSuggestionVM.java similarity index 93% rename from src/main/java/org/mskcc/oncokb/transcript/vm/AllReferenceTranscriptSuggestionVM.java rename to src/main/java/org/mskcc/oncokb/curation/vm/AllReferenceTranscriptSuggestionVM.java index 1856fd10a..983037d32 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/vm/AllReferenceTranscriptSuggestionVM.java +++ b/src/main/java/org/mskcc/oncokb/curation/vm/AllReferenceTranscriptSuggestionVM.java @@ -1,4 +1,4 @@ -package org.mskcc.oncokb.transcript.vm; +package org.mskcc.oncokb.curation.vm; /** * Created by Hongxin Zhang on 7/15/20. diff --git a/src/main/java/org/mskcc/oncokb/transcript/vm/MatchTranscriptVM.java b/src/main/java/org/mskcc/oncokb/curation/vm/MatchTranscriptVM.java similarity index 84% rename from src/main/java/org/mskcc/oncokb/transcript/vm/MatchTranscriptVM.java rename to src/main/java/org/mskcc/oncokb/curation/vm/MatchTranscriptVM.java index 721edb69c..e4ee78928 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/vm/MatchTranscriptVM.java +++ b/src/main/java/org/mskcc/oncokb/curation/vm/MatchTranscriptVM.java @@ -1,6 +1,6 @@ -package org.mskcc.oncokb.transcript.vm; +package org.mskcc.oncokb.curation.vm; -import org.mskcc.oncokb.transcript.domain.enumeration.ReferenceGenome; +import org.mskcc.oncokb.curation.domain.enumeration.ReferenceGenome; /** * Created by Hongxin Zhang on 7/15/20. diff --git a/src/main/java/org/mskcc/oncokb/transcript/vm/MissMatchPairVM.java b/src/main/java/org/mskcc/oncokb/curation/vm/MissMatchPairVM.java similarity index 94% rename from src/main/java/org/mskcc/oncokb/transcript/vm/MissMatchPairVM.java rename to src/main/java/org/mskcc/oncokb/curation/vm/MissMatchPairVM.java index ef685aa28..3e1280a15 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/vm/MissMatchPairVM.java +++ b/src/main/java/org/mskcc/oncokb/curation/vm/MissMatchPairVM.java @@ -1,4 +1,4 @@ -package org.mskcc.oncokb.transcript.vm; +package org.mskcc.oncokb.curation.vm; /** * Created by Hongxin Zhang on 10/22/20. diff --git a/src/main/java/org/mskcc/oncokb/transcript/vm/TranscriptComparisonResultVM.java b/src/main/java/org/mskcc/oncokb/curation/vm/TranscriptComparisonResultVM.java similarity index 93% rename from src/main/java/org/mskcc/oncokb/transcript/vm/TranscriptComparisonResultVM.java rename to src/main/java/org/mskcc/oncokb/curation/vm/TranscriptComparisonResultVM.java index 461013cdb..a67a2dd03 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/vm/TranscriptComparisonResultVM.java +++ b/src/main/java/org/mskcc/oncokb/curation/vm/TranscriptComparisonResultVM.java @@ -1,4 +1,4 @@ -package org.mskcc.oncokb.transcript.vm; +package org.mskcc.oncokb.curation.vm; /** * Created by Hongxin Zhang on 7/15/20. diff --git a/src/main/java/org/mskcc/oncokb/transcript/vm/TranscriptComparisonVM.java b/src/main/java/org/mskcc/oncokb/curation/vm/TranscriptComparisonVM.java similarity index 94% rename from src/main/java/org/mskcc/oncokb/transcript/vm/TranscriptComparisonVM.java rename to src/main/java/org/mskcc/oncokb/curation/vm/TranscriptComparisonVM.java index bfd6327a5..8448fe0c7 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/vm/TranscriptComparisonVM.java +++ b/src/main/java/org/mskcc/oncokb/curation/vm/TranscriptComparisonVM.java @@ -1,4 +1,4 @@ -package org.mskcc.oncokb.transcript.vm; +package org.mskcc.oncokb.curation.vm; /** * Created by Hongxin Zhang on 7/15/20. diff --git a/src/main/java/org/mskcc/oncokb/transcript/vm/TranscriptMatchResultVM.java b/src/main/java/org/mskcc/oncokb/curation/vm/TranscriptMatchResultVM.java similarity index 95% rename from src/main/java/org/mskcc/oncokb/transcript/vm/TranscriptMatchResultVM.java rename to src/main/java/org/mskcc/oncokb/curation/vm/TranscriptMatchResultVM.java index cfb8d9578..f2285baef 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/vm/TranscriptMatchResultVM.java +++ b/src/main/java/org/mskcc/oncokb/curation/vm/TranscriptMatchResultVM.java @@ -1,4 +1,4 @@ -package org.mskcc.oncokb.transcript.vm; +package org.mskcc.oncokb.curation.vm; import org.genome_nexus.client.EnsemblTranscript; diff --git a/src/main/java/org/mskcc/oncokb/transcript/vm/TranscriptPairVM.java b/src/main/java/org/mskcc/oncokb/curation/vm/TranscriptPairVM.java similarity index 82% rename from src/main/java/org/mskcc/oncokb/transcript/vm/TranscriptPairVM.java rename to src/main/java/org/mskcc/oncokb/curation/vm/TranscriptPairVM.java index cd900296d..075817f88 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/vm/TranscriptPairVM.java +++ b/src/main/java/org/mskcc/oncokb/curation/vm/TranscriptPairVM.java @@ -1,6 +1,6 @@ -package org.mskcc.oncokb.transcript.vm; +package org.mskcc.oncokb.curation.vm; -import org.mskcc.oncokb.transcript.domain.enumeration.ReferenceGenome; +import org.mskcc.oncokb.curation.domain.enumeration.ReferenceGenome; /** * Created by Hongxin Zhang on 7/15/20. diff --git a/src/main/java/org/mskcc/oncokb/transcript/vm/TranscriptResultVM.java b/src/main/java/org/mskcc/oncokb/curation/vm/TranscriptResultVM.java similarity index 95% rename from src/main/java/org/mskcc/oncokb/transcript/vm/TranscriptResultVM.java rename to src/main/java/org/mskcc/oncokb/curation/vm/TranscriptResultVM.java index d1b2558f8..9e881289f 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/vm/TranscriptResultVM.java +++ b/src/main/java/org/mskcc/oncokb/curation/vm/TranscriptResultVM.java @@ -1,4 +1,4 @@ -package org.mskcc.oncokb.transcript.vm; +package org.mskcc.oncokb.curation.vm; import org.genome_nexus.client.EnsemblTranscript; diff --git a/src/main/java/org/mskcc/oncokb/transcript/vm/TranscriptSuggestionVM.java b/src/main/java/org/mskcc/oncokb/curation/vm/TranscriptSuggestionVM.java similarity index 87% rename from src/main/java/org/mskcc/oncokb/transcript/vm/TranscriptSuggestionVM.java rename to src/main/java/org/mskcc/oncokb/curation/vm/TranscriptSuggestionVM.java index 428d11910..6a8bd5122 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/vm/TranscriptSuggestionVM.java +++ b/src/main/java/org/mskcc/oncokb/curation/vm/TranscriptSuggestionVM.java @@ -1,8 +1,8 @@ -package org.mskcc.oncokb.transcript.vm; +package org.mskcc.oncokb.curation.vm; import java.util.ArrayList; import java.util.List; -import org.mskcc.oncokb.transcript.domain.enumeration.ReferenceGenome; +import org.mskcc.oncokb.curation.domain.enumeration.ReferenceGenome; /** * Created by Hongxin Zhang on 7/15/20. diff --git a/src/main/java/org/mskcc/oncokb/transcript/vm/VariantSuggestionVM.java b/src/main/java/org/mskcc/oncokb/curation/vm/VariantSuggestionVM.java similarity index 95% rename from src/main/java/org/mskcc/oncokb/transcript/vm/VariantSuggestionVM.java rename to src/main/java/org/mskcc/oncokb/curation/vm/VariantSuggestionVM.java index 63f2cd702..f331ae8c1 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/vm/VariantSuggestionVM.java +++ b/src/main/java/org/mskcc/oncokb/curation/vm/VariantSuggestionVM.java @@ -1,4 +1,4 @@ -package org.mskcc.oncokb.transcript.vm; +package org.mskcc.oncokb.curation.vm; import org.genome_nexus.client.EnsemblTranscript; diff --git a/src/main/java/org/mskcc/oncokb/curation/vm/ensembl/EnsemblArchiveId.java b/src/main/java/org/mskcc/oncokb/curation/vm/ensembl/EnsemblArchiveId.java new file mode 100644 index 000000000..7bbe57412 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/vm/ensembl/EnsemblArchiveId.java @@ -0,0 +1,68 @@ +package org.mskcc.oncokb.curation.vm.ensembl; + +public class EnsemblArchiveId { + + String id; + String assembly; + String is_current; + String type; + String release; + String latest; + Integer version; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getAssembly() { + return assembly; + } + + public void setAssembly(String assembly) { + this.assembly = assembly; + } + + public String getIs_current() { + return is_current; + } + + public void setIs_current(String is_current) { + this.is_current = is_current; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getRelease() { + return release; + } + + public void setRelease(String release) { + this.release = release; + } + + public String getLatest() { + return latest; + } + + public void setLatest(String latest) { + this.latest = latest; + } + + public Integer getVersion() { + return version; + } + + public void setVersion(Integer version) { + this.version = version; + } +} diff --git a/src/main/java/org/mskcc/oncokb/transcript/vm/ensembl/EnsemblSequence.java b/src/main/java/org/mskcc/oncokb/curation/vm/ensembl/EnsemblSequence.java similarity index 95% rename from src/main/java/org/mskcc/oncokb/transcript/vm/ensembl/EnsemblSequence.java rename to src/main/java/org/mskcc/oncokb/curation/vm/ensembl/EnsemblSequence.java index 3c6d8eb35..32e352439 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/vm/ensembl/EnsemblSequence.java +++ b/src/main/java/org/mskcc/oncokb/curation/vm/ensembl/EnsemblSequence.java @@ -1,4 +1,4 @@ -package org.mskcc.oncokb.transcript.vm.ensembl; +package org.mskcc.oncokb.curation.vm.ensembl; /** * Created by Hongxin Zhang on 7/15/20. diff --git a/src/main/java/org/mskcc/oncokb/curation/vm/ensembl/EnsemblTranscript.java b/src/main/java/org/mskcc/oncokb/curation/vm/ensembl/EnsemblTranscript.java new file mode 100644 index 000000000..677c50069 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/vm/ensembl/EnsemblTranscript.java @@ -0,0 +1,85 @@ +package org.mskcc.oncokb.curation.vm.ensembl; + +import com.google.gson.annotations.SerializedName; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +public class EnsemblTranscript extends EnsemblTranscriptFragment implements Serializable { + + @SerializedName("Parent") + String parent; + + Integer version; + + @SerializedName("Translation") + EnsemblTranscript transcription; + + @SerializedName("canonical_transcript") + String canonicalTranscript; + + @SerializedName("Transcript") + List transcripts = new ArrayList<>(); + + @SerializedName("Exon") + List exons = new ArrayList<>(); + + @SerializedName("UTR") + List utrs = new ArrayList<>(); + + public String getParent() { + return parent; + } + + public void setParent(String parent) { + this.parent = parent; + } + + public Integer getVersion() { + return version; + } + + public void setVersion(Integer version) { + this.version = version; + } + + public EnsemblTranscript getTranscription() { + return transcription; + } + + public void setTranscription(EnsemblTranscript transcription) { + this.transcription = transcription; + } + + public String getCanonicalTranscript() { + return canonicalTranscript; + } + + public void setCanonicalTranscript(String canonicalTranscript) { + this.canonicalTranscript = canonicalTranscript; + } + + public List getTranscripts() { + return transcripts; + } + + public void setTranscripts(List transcripts) { + this.transcripts = transcripts; + } + + public List getExons() { + return exons; + } + + public void setExons(List exons) { + this.exons = exons; + } + + public List getUtrs() { + return utrs; + } + + public void setUtrs(List utrs) { + this.utrs = utrs; + } +} diff --git a/src/main/java/org/mskcc/oncokb/transcript/vm/ensembl/EnsemblTranscriptFragment.java b/src/main/java/org/mskcc/oncokb/curation/vm/ensembl/EnsemblTranscriptFragment.java similarity index 96% rename from src/main/java/org/mskcc/oncokb/transcript/vm/ensembl/EnsemblTranscriptFragment.java rename to src/main/java/org/mskcc/oncokb/curation/vm/ensembl/EnsemblTranscriptFragment.java index 4a071a288..9fb99cc0d 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/vm/ensembl/EnsemblTranscriptFragment.java +++ b/src/main/java/org/mskcc/oncokb/curation/vm/ensembl/EnsemblTranscriptFragment.java @@ -1,4 +1,4 @@ -package org.mskcc.oncokb.transcript.vm.ensembl; +package org.mskcc.oncokb.curation.vm.ensembl; import com.google.gson.annotations.SerializedName; import java.io.Serializable; diff --git a/src/main/java/org/mskcc/oncokb/curation/vm/package-info.java b/src/main/java/org/mskcc/oncokb/curation/vm/package-info.java new file mode 100644 index 000000000..34ff4ea74 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/vm/package-info.java @@ -0,0 +1,4 @@ +/** + * View Models. + */ +package org.mskcc.oncokb.curation.vm; diff --git a/src/main/java/org/mskcc/oncokb/curation/web/filter/OAuth2RefreshTokensWebFilter.java b/src/main/java/org/mskcc/oncokb/curation/web/filter/OAuth2RefreshTokensWebFilter.java new file mode 100644 index 000000000..82575d11c --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/filter/OAuth2RefreshTokensWebFilter.java @@ -0,0 +1,83 @@ +package org.mskcc.oncokb.curation.web.filter; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest; +import org.springframework.security.oauth2.client.OAuth2AuthorizedClient; +import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager; +import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; +import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; +import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizationRequestResolver; +import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter; +import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestResolver; +import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository; +import org.springframework.security.oauth2.core.OAuth2RefreshToken; +import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; +import org.springframework.security.web.DefaultRedirectStrategy; +import org.springframework.security.web.RedirectStrategy; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +/** + * Refresh oauth2 tokens. + */ +@Component +public class OAuth2RefreshTokensWebFilter extends OncePerRequestFilter { + + private final OAuth2AuthorizedClientManager clientManager; + private final OAuth2AuthorizedClientRepository authorizedClientRepository; + private final OAuth2AuthorizationRequestResolver authorizationRequestResolver; + private final RedirectStrategy authorizationRedirectStrategy = new DefaultRedirectStrategy(); + + public OAuth2RefreshTokensWebFilter( + OAuth2AuthorizedClientManager clientManager, + OAuth2AuthorizedClientRepository authorizedClientRepository, + ClientRegistrationRepository clientRegistrationRepository + ) { + this.clientManager = clientManager; + this.authorizedClientRepository = authorizedClientRepository; + this.authorizationRequestResolver = new DefaultOAuth2AuthorizationRequestResolver( + clientRegistrationRepository, + OAuth2AuthorizationRequestRedirectFilter.DEFAULT_AUTHORIZATION_REQUEST_BASE_URI + ); + } + + @Override + public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) + throws IOException, ServletException { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if ((authentication instanceof OAuth2AuthenticationToken)) { + try { + OAuth2AuthorizedClient authorizedClient = authorizedClient((OAuth2AuthenticationToken) authentication); + this.authorizedClientRepository.saveAuthorizedClient(authorizedClient, authentication, request, response); + } catch (Exception e) { + OAuth2AuthorizationRequest authorizationRequest = this.authorizationRequestResolver.resolve(request); + if (authorizationRequest != null) { + this.authorizationRedirectStrategy.sendRedirect(request, response, authorizationRequest.getAuthorizationRequestUri()); + return; + } + } + } + + filterChain.doFilter(request, response); + } + + private OAuth2AuthorizedClient authorizedClient(OAuth2AuthenticationToken oauth2Authentication) { + String clientRegistrationId = oauth2Authentication.getAuthorizedClientRegistrationId(); + OAuth2AuthorizeRequest request = OAuth2AuthorizeRequest.withClientRegistrationId(clientRegistrationId) + .principal(oauth2Authentication) + .build(); + if (clientManager == null) { + throw new IllegalStateException( + "No OAuth2AuthorizedClientManager bean was found. Did you include the " + + "org.springframework.boot:spring-boot-starter-oauth2-client dependency?" + ); + } + return clientManager.authorize(request); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/filter/RequestResponseLoggingFilter.java b/src/main/java/org/mskcc/oncokb/curation/web/filter/RequestResponseLoggingFilter.java new file mode 100644 index 000000000..7ceb5e1ad --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/filter/RequestResponseLoggingFilter.java @@ -0,0 +1,47 @@ +package org.mskcc.oncokb.curation.web.filter; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.UUID; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +@Order(1) +@Component +public class RequestResponseLoggingFilter extends OncePerRequestFilter { + + private static final Logger LOGGER = LoggerFactory.getLogger(RequestResponseLoggingFilter.class); + private static final String REQUEST_ID_HEADER = "X-Request-ID"; + private static final String MDC_REQUEST_ID_KEY = "requestId"; + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) + throws jakarta.servlet.ServletException, IOException { + String requestId = request.getHeader(REQUEST_ID_HEADER); + if (requestId == null || requestId.isEmpty()) { + requestId = UUID.randomUUID().toString(); + } + + MDC.put(MDC_REQUEST_ID_KEY, requestId); + + try { + String url = request.getRequestURI(); + String method = request.getMethod(); + LOGGER.info("Incoming Request: {} {}", method, url); + filterChain.doFilter(request, response); + int status = response.getStatus(); + LOGGER.info("Response status: {}", status); + } catch (Exception e) { + LOGGER.error("Unhandled exception", e); + throw e; + } finally { + MDC.remove(MDC_REQUEST_ID_KEY); + } + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/filter/SpaWebFilter.java b/src/main/java/org/mskcc/oncokb/curation/web/filter/SpaWebFilter.java new file mode 100644 index 000000000..7defad293 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/filter/SpaWebFilter.java @@ -0,0 +1,37 @@ +package org.mskcc.oncokb.curation.web.filter; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; +import org.springframework.web.filter.OncePerRequestFilter; + +public class SpaWebFilter extends OncePerRequestFilter { + + /** + * Forwards any unmapped paths (except those containing a period) to the client {@code index.html}. + */ + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) + throws ServletException, IOException { + // Request URI includes the contextPath if any, removed it. + String path = request.getRequestURI().substring(request.getContextPath().length()); + if ( + !path.startsWith("/api") && + !path.startsWith("/management") && + !path.startsWith("/v3/api-docs") && + !path.startsWith("/login") && + !path.startsWith("/oauth2") && + !path.startsWith("/legacy-api") && + !path.startsWith("/websocket") && + !path.contains(".") && + path.matches("/(.*)") + ) { + request.getRequestDispatcher("/index.html").forward(request, response); + return; + } + + filterChain.doFilter(request, response); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/AccountResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/AccountResource.java new file mode 100644 index 000000000..58f9938de --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/AccountResource.java @@ -0,0 +1,84 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.servlet.http.HttpServletRequest; +import java.security.Principal; +import java.util.Map; +import java.util.Optional; +import org.mskcc.oncokb.curation.config.Constants; +import org.mskcc.oncokb.curation.service.UserService; +import org.mskcc.oncokb.curation.service.dto.UserDTO; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * REST controller for managing the current user's account. + */ +@RestController +@RequestMapping("/api") +public class AccountResource { + + private static class AccountResourceException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + private AccountResourceException(String message) { + super(message); + } + } + + private final Logger log = LoggerFactory.getLogger(AccountResource.class); + + private final UserService userService; + + public AccountResource(UserService userService) { + this.userService = userService; + } + + /** + * {@code GET /account} : get the current user. + * + * @param principal the current user; resolves to {@code null} if not authenticated. + * @return the current user. + * @throws AccountResourceException {@code 500 (Internal Server Error)} if the user couldn't be returned. + */ + @GetMapping("/account") + @SuppressWarnings("unchecked") + public UserDTO getAccount(Principal principal) { + if (principal instanceof AbstractAuthenticationToken) { + Optional userOptional = userService.getUserFromAuthentication((AbstractAuthenticationToken) principal); + if (userOptional.isPresent()) { + return userOptional.orElseThrow(); + } + } + throw new AccountResourceException("User could not be found"); + } + + @GetMapping("/account/firebase-token") + public String getFirebaseToken(Principal principal) { + OAuth2AuthenticationToken oauth2Token = (OAuth2AuthenticationToken) principal; + try { + Map details = (Map) oauth2Token.getDetails(); + String firebaseCustomToken = (String) details.get(Constants.FIREBASE_CUSTOM_TOKEN); + return firebaseCustomToken; + } catch (Exception e) { + throw new AccountResourceException("Firebase token could not be found"); + } + } + + /** + * {@code GET /authenticate} : check if the user is authenticated, and return its login. + * + * @param request the HTTP request. + * @return the login if the user is authenticated. + */ + @GetMapping("/authenticate") + public String isAuthenticated(HttpServletRequest request) { + log.debug("REST request to check if the current user is authenticated"); + return request.getRemoteUser(); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/AlleleStateResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/AlleleStateResource.java new file mode 100644 index 000000000..e2e95b680 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/AlleleStateResource.java @@ -0,0 +1,171 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.AlleleState; +import org.mskcc.oncokb.curation.repository.AlleleStateRepository; +import org.mskcc.oncokb.curation.service.AlleleStateService; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing {@link org.mskcc.oncokb.curation.domain.AlleleState}. + */ +@RestController +@RequestMapping("/api") +public class AlleleStateResource { + + private final Logger log = LoggerFactory.getLogger(AlleleStateResource.class); + + private static final String ENTITY_NAME = "alleleState"; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final AlleleStateService alleleStateService; + + private final AlleleStateRepository alleleStateRepository; + + public AlleleStateResource(AlleleStateService alleleStateService, AlleleStateRepository alleleStateRepository) { + this.alleleStateService = alleleStateService; + this.alleleStateRepository = alleleStateRepository; + } + + /** + * {@code POST /allele-states} : Create a new alleleState. + * + * @param alleleState the alleleState to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new alleleState, or with status {@code 400 (Bad Request)} if the alleleState has already an ID. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PostMapping("/allele-states") + public ResponseEntity createAlleleState(@Valid @RequestBody AlleleState alleleState) throws URISyntaxException { + log.debug("REST request to save AlleleState : {}", alleleState); + if (alleleState.getId() != null) { + throw new BadRequestAlertException("A new alleleState cannot already have an ID", ENTITY_NAME, "idexists"); + } + AlleleState result = alleleStateService.save(alleleState); + return ResponseEntity.created(new URI("/api/allele-states/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) + .body(result); + } + + /** + * {@code PUT /allele-states/:id} : Updates an existing alleleState. + * + * @param id the id of the alleleState to save. + * @param alleleState the alleleState to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated alleleState, + * or with status {@code 400 (Bad Request)} if the alleleState is not valid, + * or with status {@code 500 (Internal Server Error)} if the alleleState couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PutMapping("/allele-states/{id}") + public ResponseEntity updateAlleleState( + @PathVariable(value = "id", required = false) final Long id, + @Valid @RequestBody AlleleState alleleState + ) throws URISyntaxException { + log.debug("REST request to update AlleleState : {}, {}", id, alleleState); + if (alleleState.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, alleleState.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!alleleStateRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + AlleleState result = alleleStateService.save(alleleState); + return ResponseEntity.ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, alleleState.getId().toString())) + .body(result); + } + + /** + * {@code PATCH /allele-states/:id} : Partial updates given fields of an existing alleleState, field will ignore if it is null + * + * @param id the id of the alleleState to save. + * @param alleleState the alleleState to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated alleleState, + * or with status {@code 400 (Bad Request)} if the alleleState is not valid, + * or with status {@code 404 (Not Found)} if the alleleState is not found, + * or with status {@code 500 (Internal Server Error)} if the alleleState couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/allele-states/{id}", consumes = { "application/json", "application/merge-patch+json" }) + public ResponseEntity partialUpdateAlleleState( + @PathVariable(value = "id", required = false) final Long id, + @NotNull @RequestBody AlleleState alleleState + ) throws URISyntaxException { + log.debug("REST request to partial update AlleleState partially : {}, {}", id, alleleState); + if (alleleState.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, alleleState.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!alleleStateRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Optional result = alleleStateService.partialUpdate(alleleState); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, alleleState.getId().toString()) + ); + } + + /** + * {@code GET /allele-states} : get all the alleleStates. + * + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of alleleStates in body. + */ + @GetMapping("/allele-states") + public List getAllAlleleStates() { + log.debug("REST request to get all AlleleStates"); + return alleleStateService.findAll(); + } + + /** + * {@code GET /allele-states/:id} : get the "id" alleleState. + * + * @param id the id of the alleleState to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the alleleState, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/allele-states/{id}") + public ResponseEntity getAlleleState(@PathVariable Long id) { + log.debug("REST request to get AlleleState : {}", id); + Optional alleleState = alleleStateService.findOne(id); + return ResponseUtil.wrapOrNotFound(alleleState); + } + + /** + * {@code DELETE /allele-states/:id} : delete the "id" alleleState. + * + * @param id the id of the alleleState to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/allele-states/{id}") + public ResponseEntity deleteAlleleState(@PathVariable Long id) { + log.debug("REST request to delete AlleleState : {}", id); + alleleStateService.delete(id); + return ResponseEntity.noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/AlterationController.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/AlterationController.java new file mode 100644 index 000000000..588a88c74 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/AlterationController.java @@ -0,0 +1,48 @@ +package org.mskcc.oncokb.curation.web.rest; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import org.mskcc.oncokb.curation.domain.Alteration; +import org.mskcc.oncokb.curation.domain.AlterationAnnotationStatus; +import org.mskcc.oncokb.curation.domain.EntityStatus; +import org.mskcc.oncokb.curation.service.MainService; +import org.mskcc.oncokb.curation.web.rest.model.AnnotateAlterationBody; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/api") +public class AlterationController { + + private final Logger log = LoggerFactory.getLogger(AlterationController.class); + + private final MainService mainService; + + public AlterationController(MainService mainService) { + this.mainService = mainService; + } + + @PostMapping("/annotate-alterations") + public ResponseEntity> annotateAlterations( + @RequestBody List alterationBodyList + ) { + log.debug("REST request to annotate alterations"); + + List status = new ArrayList<>(); + alterationBodyList.forEach(alterationBody -> { + AlterationAnnotationStatus annotationStatus = mainService.annotateAlteration( + alterationBody.getReferenceGenome(), + alterationBody.getAlteration() + ); + annotationStatus.setQueryId(alterationBody.getQueryId()); + status.add(annotationStatus); + }); + + return new ResponseEntity<>(status, HttpStatus.OK); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/AlterationResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/AlterationResource.java new file mode 100644 index 000000000..caaa42ede --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/AlterationResource.java @@ -0,0 +1,229 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; +import org.mskcc.oncokb.curation.domain.Alteration; +import org.mskcc.oncokb.curation.repository.AlterationRepository; +import org.mskcc.oncokb.curation.service.AlterationQueryService; +import org.mskcc.oncokb.curation.service.AlterationService; +import org.mskcc.oncokb.curation.service.criteria.AlterationCriteria; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.PaginationUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing {@link org.mskcc.oncokb.curation.domain.Alteration}. + */ +@RestController +@RequestMapping("/api") +public class AlterationResource { + + private final Logger log = LoggerFactory.getLogger(AlterationResource.class); + + private static final String ENTITY_NAME = "alteration"; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final AlterationService alterationService; + + private final AlterationRepository alterationRepository; + + private final AlterationQueryService alterationQueryService; + + public AlterationResource( + AlterationService alterationService, + AlterationRepository alterationRepository, + AlterationQueryService alterationQueryService + ) { + this.alterationService = alterationService; + this.alterationRepository = alterationRepository; + this.alterationQueryService = alterationQueryService; + } + + /** + * {@code POST /alterations} : Create a new alteration. + * + * @param alteration the alteration to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new alteration, or with status {@code 400 (Bad Request)} if the alteration has already an ID. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PostMapping("/alterations") + public ResponseEntity createAlteration(@Valid @RequestBody Alteration alteration) throws URISyntaxException { + log.debug("REST request to save Alteration : {}", alteration); + if (alteration.getId() != null) { + throw new BadRequestAlertException("A new alteration cannot already have an ID", ENTITY_NAME, "idexists"); + } + Alteration result = alterationService.save(alteration); + return ResponseEntity.created(new URI("/api/alterations/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) + .body(result); + } + + /** + * {@code PUT /alterations/:id} : Updates an existing alteration. + * + * @param id the id of the alteration to save. + * @param alteration the alteration to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated alteration, + * or with status {@code 400 (Bad Request)} if the alteration is not valid, + * or with status {@code 500 (Internal Server Error)} if the alteration couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PutMapping("/alterations/{id}") + public ResponseEntity updateAlteration( + @PathVariable(value = "id", required = false) final Long id, + @Valid @RequestBody Alteration alteration + ) throws URISyntaxException { + log.debug("REST request to update Alteration : {}, {}", id, alteration); + if (alteration.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, alteration.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!alterationRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Alteration result = alterationService.save(alteration); + return ResponseEntity.ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, alteration.getId().toString())) + .body(result); + } + + /** + * {@code PATCH /alterations/:id} : Partial updates given fields of an existing alteration, field will ignore if it is null + * + * @param id the id of the alteration to save. + * @param alteration the alteration to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated alteration, + * or with status {@code 400 (Bad Request)} if the alteration is not valid, + * or with status {@code 404 (Not Found)} if the alteration is not found, + * or with status {@code 500 (Internal Server Error)} if the alteration couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/alterations/{id}", consumes = { "application/json", "application/merge-patch+json" }) + public ResponseEntity partialUpdateAlteration( + @PathVariable(value = "id", required = false) final Long id, + @NotNull @RequestBody Alteration alteration + ) throws URISyntaxException { + log.debug("REST request to partial update Alteration partially : {}, {}", id, alteration); + if (alteration.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, alteration.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!alterationRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Optional result = alterationService.partialUpdate(alteration); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, alteration.getId().toString()) + ); + } + + /** + * {@code GET /alterations} : get all the alterations. + * + * @param pageable the pagination information. + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of alterations in body. + */ + @GetMapping("/alterations") + public ResponseEntity> getAllAlterations(AlterationCriteria criteria, Pageable pageable) { + log.debug("REST request to get Alterations by criteria: {}", criteria); + Page page = alterationQueryService.findByCriteria(criteria, pageable); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok() + .headers(headers) + .body( + alterationService.findAllWithEagerRelationshipsByIds( + page.getContent().stream().map(Alteration::getId).collect(Collectors.toList()) + ) + ); + } + + /** + * {@code GET /alterations/count} : count all the alterations. + * + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the count in body. + */ + @GetMapping("/alterations/count") + public ResponseEntity countAlterations(AlterationCriteria criteria) { + log.debug("REST request to count Alterations by criteria: {}", criteria); + return ResponseEntity.ok().body(alterationQueryService.countByCriteria(criteria)); + } + + /** + * {@code GET /alterations/:id} : get the "id" alteration. + * + * @param id the id of the alteration to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the alteration, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/alterations/{id}") + public ResponseEntity getAlteration(@PathVariable Long id) { + log.debug("REST request to get Alteration : {}", id); + Optional alteration = alterationService.findOne(id); + return ResponseUtil.wrapOrNotFound(alteration); + } + + /** + * {@code DELETE /alterations/:id} : delete the "id" alteration. + * + * @param id the id of the alteration to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/alterations/{id}") + public ResponseEntity deleteAlteration(@PathVariable Long id) { + log.debug("REST request to delete Alteration : {}", id); + alterationService.delete(id); + return ResponseEntity.noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); + } + + /** + * {@code SEARCH /alterations/search?query=:query} : search for the alteration corresponding + * to the query. + * + * @param query the query of the alteration search. + * @return the result of the search. + */ + @GetMapping("/alterations/search") + public ResponseEntity> searchAlterations(@RequestParam String query, Pageable pageable) { + log.debug("REST request to search for a page of Alterations for query {}", query); + Page page = alterationService.search(query, pageable); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(page.getContent()); + } + + @GetMapping("/alterations/gene/{id}") + public List findByGeneId(@PathVariable Long id) { + return alterationService.findByGeneId(id); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/ApiProxy.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/ApiProxy.java new file mode 100644 index 000000000..f5eb271f2 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/ApiProxy.java @@ -0,0 +1,79 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.servlet.http.HttpServletRequest; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.charset.StandardCharsets; +import org.mskcc.oncokb.curation.service.ApiProxyService; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.springframework.http.*; +import org.springframework.http.converter.FormHttpMessageConverter; +import org.springframework.http.converter.StringHttpMessageConverter; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.server.ResponseStatusException; + +@RestController +@RequestMapping({ "/legacy-api", "/api/v1/evidences" }) +public class ApiProxy { + + private final ApiProxyService apiProxyService; + + public ApiProxy(ApiProxyService apiProxyService) { + this.apiProxyService = apiProxyService; + } + + @RequestMapping(value = "/**", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) + public ResponseEntity formDataProxy( + @RequestParam MultiValueMap formParams, + HttpMethod method, + HttpServletRequest request + ) throws URISyntaxException { + URI uri = apiProxyService.prepareURI(request); + + HttpHeaders httpHeaders = apiProxyService.prepareHttpHeaders(request.getContentType()); + RestTemplate restTemplate = new RestTemplate(); + restTemplate.getMessageConverters().add(0, new FormHttpMessageConverter()); + + HttpEntity> requestEntity = new HttpEntity<>(formParams, httpHeaders); + try { + return restTemplate.exchange(uri, method, requestEntity, String.class); + } catch (HttpClientErrorException httpClientErrorException) { + if ( + httpClientErrorException.getStatusCode() != null && httpClientErrorException.getStatusCode().equals(HttpStatus.BAD_REQUEST) + ) { + throw new BadRequestAlertException(httpClientErrorException.getMessage(), "", ""); + } else { + throw new ResponseStatusException(httpClientErrorException.getStatusCode(), httpClientErrorException.getMessage()); + } + } + } + + @RequestMapping(value = "/**", consumes = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity jsonProxy(@RequestBody(required = false) String body, HttpMethod method, HttpServletRequest request) + throws URISyntaxException { + URI uri = apiProxyService.prepareURI(request); + + HttpHeaders httpHeaders = apiProxyService.prepareHttpHeaders(request.getContentType()); + RestTemplate restTemplate = new RestTemplate(); + restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(StandardCharsets.UTF_8)); + + try { + return restTemplate.exchange(uri, method, new HttpEntity<>(body, httpHeaders), String.class); + } catch (HttpClientErrorException httpClientErrorException) { + if ( + httpClientErrorException.getStatusCode() != null && httpClientErrorException.getStatusCode().equals(HttpStatus.BAD_REQUEST) + ) { + throw new BadRequestAlertException(httpClientErrorException.getMessage(), "", ""); + } else { + throw new ResponseStatusException(httpClientErrorException.getStatusCode(), httpClientErrorException.getMessage()); + } + } + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/ArticleResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/ArticleResource.java new file mode 100644 index 000000000..194dbf53c --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/ArticleResource.java @@ -0,0 +1,252 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.Article; +import org.mskcc.oncokb.curation.domain.nih.efetch.ArticleId; +import org.mskcc.oncokb.curation.repository.ArticleRepository; +import org.mskcc.oncokb.curation.service.ArticleQueryService; +import org.mskcc.oncokb.curation.service.ArticleService; +import org.mskcc.oncokb.curation.service.NihEutilsService; +import org.mskcc.oncokb.curation.service.criteria.ArticleCriteria; +import org.mskcc.oncokb.curation.service.dto.pubmed.PubMedDTO; +import org.mskcc.oncokb.curation.service.mapper.PubMedMapper; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import tech.jhipster.service.filter.StringFilter; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.PaginationUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing {@link org.mskcc.oncokb.curation.domain.Article}. + */ +@RestController +@RequestMapping("/api") +public class ArticleResource { + + private final Logger log = LoggerFactory.getLogger(ArticleResource.class); + + private static final String ENTITY_NAME = "article"; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final ArticleService articleService; + private final NihEutilsService nihEutilsService; + private final PubMedMapper pubMedMapper; + + private final ArticleRepository articleRepository; + + private final ArticleQueryService articleQueryService; + + public ArticleResource( + ArticleService articleService, + NihEutilsService nihEutilsService, + PubMedMapper pubMedMapper, + ArticleRepository articleRepository, + ArticleQueryService articleQueryService + ) { + this.articleService = articleService; + this.nihEutilsService = nihEutilsService; + this.pubMedMapper = pubMedMapper; + this.articleRepository = articleRepository; + this.articleQueryService = articleQueryService; + } + + /** + * {@code POST /articles} : Create a new article. + * + * @param article the article to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new article, or with status {@code 400 (Bad Request)} if the article has already an ID. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PostMapping("/articles") + public ResponseEntity
createArticle(@Valid @RequestBody Article article) throws URISyntaxException { + log.debug("REST request to save Article : {}", article); + if (article.getId() != null) { + throw new BadRequestAlertException("A new article cannot already have an ID", ENTITY_NAME, "idexists"); + } + Article result = articleService.save(article); + return ResponseEntity.created(new URI("/api/articles/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) + .body(result); + } + + /** + * {@code PUT /articles/:id} : Updates an existing article. + * + * @param id the id of the article to save. + * @param article the article to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated article, + * or with status {@code 400 (Bad Request)} if the article is not valid, + * or with status {@code 500 (Internal Server Error)} if the article couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PutMapping("/articles/{id}") + public ResponseEntity
updateArticle( + @PathVariable(value = "id", required = false) final Long id, + @Valid @RequestBody Article article + ) throws URISyntaxException { + log.debug("REST request to update Article : {}, {}", id, article); + if (article.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, article.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!articleRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Article result = articleService.save(article); + return ResponseEntity.ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, article.getId().toString())) + .body(result); + } + + /** + * {@code PATCH /articles/:id} : Partial updates given fields of an existing article, field will ignore if it is null + * + * @param id the id of the article to save. + * @param article the article to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated article, + * or with status {@code 400 (Bad Request)} if the article is not valid, + * or with status {@code 404 (Not Found)} if the article is not found, + * or with status {@code 500 (Internal Server Error)} if the article couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/articles/{id}", consumes = { "application/json", "application/merge-patch+json" }) + public ResponseEntity
partialUpdateArticle( + @PathVariable(value = "id", required = false) final Long id, + @NotNull @RequestBody Article article + ) throws URISyntaxException { + log.debug("REST request to partial update Article partially : {}, {}", id, article); + if (article.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, article.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!articleRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Optional
result = articleService.partialUpdate(article); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, article.getId().toString()) + ); + } + + /** + * {@code GET /articles} : get all the articles. + * + * @param pageable the pagination information. + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of articles in body. + */ + @GetMapping("/articles") + public ResponseEntity> getAllArticles(ArticleCriteria criteria, Pageable pageable) { + log.debug("REST request to get Articles by criteria: {}", criteria); + Page
page = articleQueryService.findByCriteria(criteria, pageable); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(page.getContent()); + } + + /** + * {@code GET /articles/count} : count all the articles. + * + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the count in body. + */ + @GetMapping("/articles/count") + public ResponseEntity countArticles(ArticleCriteria criteria) { + log.debug("REST request to count Articles by criteria: {}", criteria); + return ResponseEntity.ok().body(articleQueryService.countByCriteria(criteria)); + } + + /** + * {@code GET /articles/:id} : get the "id" article. + * + * @param id the id of the article to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the article, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/articles/{id}") + public ResponseEntity
getArticle(@PathVariable Long id) { + log.debug("REST request to get Article : {}", id); + Optional
article = articleService.findOne(id); + return ResponseUtil.wrapOrNotFound(article); + } + + /** + * {@code DELETE /articles/:id} : delete the "id" article. + * + * @param id the id of the article to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/articles/{id}") + public ResponseEntity deleteArticle(@PathVariable Long id) { + log.debug("REST request to delete Article : {}", id); + articleService.delete(id); + return ResponseEntity.noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); + } + + /** + * {@code SEARCH /articles/search?query=:query} : search for the article corresponding + * to the query. + * + * @param query the query of the article search. + * @param pageable the pagination information. + * @return the result of the search. + */ + @GetMapping("/articles/search") + public ResponseEntity> searchArticles(@RequestParam String query, Pageable pageable) { + log.debug("REST request to search for a page of Articles for query {}", query); + Page
page = articleQueryService.findBySearchQuery(query, pageable); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(page.getContent()); + } + + /** + * {@code GET /articles/pubmed/{pmid}} : get the PubMed article by PMID. + * + * @param pmid PubMed ID to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the PubMed article, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/articles/pubmed/{pmid}") + public ResponseEntity getPubMedArticle(@PathVariable Long pmid) { + log.debug("REST request to get PubMed Article : {}", pmid); + ArticleCriteria articleCriteria = new ArticleCriteria(); + PubMedDTO pubMedDTO; + StringFilter stringFilter = new StringFilter(); + stringFilter.setEquals(String.valueOf(pmid)); + articleCriteria.setUid(stringFilter); + List
matchedArticles = articleQueryService.findByCriteria(articleCriteria); + if (matchedArticles.isEmpty()) { + pubMedDTO = pubMedMapper.articleToPubMedDTO(articleService.fetchAndSavePubMed(String.valueOf(pmid))); + } else { + pubMedDTO = pubMedMapper.articleToPubMedDTO(articleService.findOne(matchedArticles.iterator().next().getId()).orElseThrow()); + } + return ResponseUtil.wrapOrNotFound(Optional.ofNullable(pubMedDTO)); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/AssociationResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/AssociationResource.java new file mode 100644 index 000000000..7b1fd2747 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/AssociationResource.java @@ -0,0 +1,132 @@ +package org.mskcc.oncokb.curation.web.rest; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.Association; +import org.mskcc.oncokb.curation.repository.AssociationRepository; +import org.mskcc.oncokb.curation.service.AssociationService; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.PaginationUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing {@link org.mskcc.oncokb.curation.domain.Association}. + */ +@RestController +@RequestMapping("/api") +public class AssociationResource { + + private final Logger log = LoggerFactory.getLogger(AssociationResource.class); + + private static final String ENTITY_NAME = "association"; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final AssociationService associationService; + + private final AssociationRepository associationRepository; + + public AssociationResource(AssociationService associationService, AssociationRepository associationRepository) { + this.associationService = associationService; + this.associationRepository = associationRepository; + } + + /** + * {@code POST /associations} : Create a new association. + * + * @param association the association to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new association, or with status {@code 400 (Bad Request)} if the association has already an ID. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PostMapping("/associations") + public ResponseEntity createAssociation(@RequestBody Association association) throws URISyntaxException { + log.debug("REST request to save Association : {}", association); + if (association.getId() != null) { + throw new BadRequestAlertException("A new association cannot already have an ID", ENTITY_NAME, "idexists"); + } + Association result = associationService.save(association); + return ResponseEntity.created(new URI("/api/associations/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) + .body(result); + } + + /** + * {@code GET /associations} : get all the associations. + * + * @param eagerload flag to eager load entities from relationships (This is applicable for many-to-many). + * @param filter the filter of the request. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of associations in body. + */ + @GetMapping("/associations") + public List getAllAssociations( + @RequestParam(required = false) String filter, + @RequestParam(required = false, defaultValue = "false") boolean eagerload + ) { + if ("evidence-is-null".equals(filter)) { + log.debug("REST request to get all Associations where evidence is null"); + return associationService.findAllWhereEvidenceIsNull(); + } + log.debug("REST request to get all Associations"); + return associationService.findAll(); + } + + /** + * {@code GET /associations/:id} : get the "id" association. + * + * @param id the id of the association to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the association, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/associations/{id}") + public ResponseEntity getAssociation(@PathVariable Long id) { + log.debug("REST request to get Association : {}", id); + Optional association = associationService.findOne(id); + return ResponseUtil.wrapOrNotFound(association); + } + + /** + * {@code DELETE /associations/:id} : delete the "id" association. + * + * @param id the id of the association to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/associations/{id}") + public ResponseEntity deleteAssociation(@PathVariable Long id) throws Exception { + log.debug("REST request to delete Association : {}", id); + associationService.delete(id); + return ResponseEntity.noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); + } + + /** + * {@code SEARCH /associations/search?query=:query} : search for the Association corresponding + * to the query. + * + * @param query the query of the Association search. + * @param pageable the pagination information. + * @return the result of the search. + */ + @GetMapping("/associations/search") + public ResponseEntity> searchAssociations(@RequestParam String query, Pageable pageable) { + log.debug("REST request to search for a page of Associations for query {}", query); + // TODO: implement the search + Page page = new PageImpl<>(new ArrayList<>()); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(page.getContent()); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/AuditResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/AuditResource.java new file mode 100644 index 000000000..c9668a0bf --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/AuditResource.java @@ -0,0 +1,184 @@ +package org.mskcc.oncokb.curation.web.rest; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import org.apache.commons.lang3.StringUtils; +import org.javers.core.Javers; +import org.javers.core.metamodel.object.CdoSnapshot; +import org.javers.core.metamodel.object.InstanceId; +import org.javers.repository.jql.QueryBuilder; +import org.mskcc.oncokb.curation.domain.Flag; +import org.mskcc.oncokb.curation.domain.enumeration.AuditEntity; +import org.mskcc.oncokb.curation.domain.enumeration.FlagType; +import org.mskcc.oncokb.curation.service.FlagService; +import org.mskcc.oncokb.curation.service.OncoKbUrlService; +import org.mskcc.oncokb.curation.service.dto.EntityAuditEvent; +import org.oncokb.ApiException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.util.MultiValueMap; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.util.UriComponentsBuilder; +import tech.jhipster.web.util.PaginationUtil; + +/** + * REST controller for getting the audit events for entity + */ +@RestController +@RequestMapping("/api") +public class AuditResource { + + private final Logger log = LoggerFactory.getLogger(AuditResource.class); + private static final String ENTITY_PACKAGE_PATH = "org.mskcc.oncokb.curation.domain."; + + @Autowired + private OncoKbUrlService oncoKbUrlService; + + @Autowired + private FlagService flagService; + + private final Javers javers; + + public AuditResource(Javers javers) { + this.javers = javers; + } + + /** + * Fetches all the audited entity types + * + * @return a full of the entity types + */ + @RequestMapping(value = "/audits/entity/all", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) + public List getAuditedEntities() { + return Arrays.stream(AuditEntity.values()).map(AuditEntity::getClassName).collect(Collectors.toList()); + } + + /** + * Fetches the last 100 change list for an entity class, if limit is passed fetches that many changes + * + * @param entityType One of the AuditEntity types + * @param limit number of records to return + * @param queryParams pagination parameters + * @return a list of entity audit events + */ + @RequestMapping(value = "/audits/entity/changes", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity> getChanges( + @RequestParam(value = "entityType") String entityType, + @RequestParam(value = "limit") int limit, + @RequestParam MultiValueMap queryParams, + UriComponentsBuilder uriBuilder + ) throws ClassNotFoundException { + log.debug("REST request to get a page of EntityAuditEvents"); + + Class entityTypeToFetch = Class.forName(ENTITY_PACKAGE_PATH + entityType); + QueryBuilder jqlQuery = QueryBuilder.byClass(entityTypeToFetch).limit(limit); + + List snapshots = javers.findSnapshots(jqlQuery.build()); + + List auditEvents = new ArrayList<>(); + + snapshots.forEach(snapshot -> { + EntityAuditEvent event = EntityAuditEvent.fromJaversSnapshot(snapshot); + event.setEntityType(entityType); + auditEvents.add(event); + }); + + Page page = new PageImpl<>(auditEvents); + + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(uriBuilder.queryParams(queryParams), page); + + return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK); + } + + /** + * Fetches a previous version for an entity class, id and commit id + * + * @param entityType One of the AuditEntity types + * @param entityId unique id in the selected entity table + * @param commitId the commit id that audit table uses + * @return previous audit event. Return empty if nothing found. + */ + @RequestMapping( + value = "/audits/entity/changes/version/previous", + method = RequestMethod.GET, + produces = MediaType.APPLICATION_JSON_VALUE + ) + public ResponseEntity getPrevVersion( + @RequestParam(value = "entityType") String entityType, + @RequestParam(value = "entityId") Integer entityId, + @RequestParam(value = "commitId") Long commitId + ) throws ClassNotFoundException { + Class entityTypeToFetch = Class.forName(ENTITY_PACKAGE_PATH + entityType); + + // Find the commit + QueryBuilder jqlQuery = QueryBuilder.byInstanceId(entityId, entityTypeToFetch).withCommitId(BigDecimal.valueOf(commitId)).limit(1); + + // Since we use random commit id, we need to find the list of commits that prior to the commitId + List snapshots = javers.findSnapshots(jqlQuery.build()); + if (snapshots.isEmpty()) { + return new ResponseEntity<>(HttpStatus.BAD_REQUEST); + } + + // Return the previous one of commitId + CdoSnapshot cdoSnapshot = snapshots.iterator().next(); + jqlQuery = QueryBuilder.byInstanceId(entityId, entityTypeToFetch).to(cdoSnapshot.getCommitMetadata().getCommitDate()).limit(2); + snapshots = javers.findSnapshots(jqlQuery.build()); + if (snapshots.size() == 2) { + return new ResponseEntity<>(EntityAuditEvent.fromJaversSnapshot(snapshots.get(1)), HttpStatus.OK); + } else { + return new ResponseEntity<>(HttpStatus.OK); + } + } + + /** + * Fetches all newly released somatic genes (germline TBD) + */ + @RequestMapping(value = "/audits/entity/genes/newly-released", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity> getNewlyReleasedGenes() throws ClassNotFoundException, ApiException { + Class geneEntityClass = Class.forName(ENTITY_PACKAGE_PATH + AuditEntity.GENE.getClassName()); + + // Get the latest OncoKB date of release + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy"); + LocalDate localDate = LocalDate.parse(oncoKbUrlService.getInfo().getDataVersion().getDate(), formatter); + + // Get the flag id of the somatic flag (germline TBD) + Optional optionalFlag = flagService.findByTypeAndFlag(FlagType.GENE_PANEL, "ONCOKB_SOMATIC"); + Long flagId = optionalFlag.orElseThrow().getId(); + + QueryBuilder jqlQuery = QueryBuilder.byClass(geneEntityClass).withChangedProperty("flags").from(localDate); + + List snapshots = javers.findSnapshots(jqlQuery.build()); + + // Extract hugoSymbols where flag changes include the target release flag id + List hugoSymbols = snapshots + .stream() + .map(snapshot -> snapshot.getState()) + .filter(snapshotState -> { + Collection flags = (Collection) snapshotState.getPropertyValue("flags"); + return flags != null && flags.stream().anyMatch(flag -> flagId.equals(flag.getCdoId())); + }) + .map(snapshotState -> (String) snapshotState.getPropertyValue("hugoSymbol")) + .filter(hugoSymbol -> StringUtils.isNotEmpty(hugoSymbol)) + .distinct() + .collect(Collectors.toList()); + + return new ResponseEntity<>(hugoSymbols, HttpStatus.OK); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/AuthInfoResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/AuthInfoResource.java new file mode 100644 index 000000000..ccbfb28a5 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/AuthInfoResource.java @@ -0,0 +1,52 @@ +package org.mskcc.oncokb.curation.web.rest; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * Resource to return information about OIDC properties + */ +@RestController +@RequestMapping("/api") +public class AuthInfoResource { + + @Value("${spring.security.oauth2.client.provider.oidc.issuer-uri:}") + private String issuer; + + @Value("${spring.security.oauth2.client.registration.oidc.client-id:}") + private String clientId; + + @GetMapping("/auth-info") + public AuthInfoVM getAuthInfo() { + return new AuthInfoVM(issuer, clientId); + } + + class AuthInfoVM { + + private String issuer; + private String clientId; + + AuthInfoVM(String issuer, String clientId) { + this.issuer = issuer; + this.clientId = clientId; + } + + public String getIssuer() { + return this.issuer; + } + + public void setIssuer(String issuer) { + this.issuer = issuer; + } + + public String getClientId() { + return clientId; + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/CancerTypeResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/CancerTypeResource.java new file mode 100644 index 000000000..710a42cbf --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/CancerTypeResource.java @@ -0,0 +1,234 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.CancerType; +import org.mskcc.oncokb.curation.domain.RelevantCancerTypeBody; +import org.mskcc.oncokb.curation.repository.CancerTypeRepository; +import org.mskcc.oncokb.curation.service.CancerTypeQueryService; +import org.mskcc.oncokb.curation.service.CancerTypeService; +import org.mskcc.oncokb.curation.service.criteria.CancerTypeCriteria; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.PaginationUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing {@link org.mskcc.oncokb.curation.domain.CancerType}. + */ +@RestController +@RequestMapping("/api") +public class CancerTypeResource { + + private final Logger log = LoggerFactory.getLogger(CancerTypeResource.class); + + private static final String ENTITY_NAME = "cancerType"; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final CancerTypeService cancerTypeService; + + private final CancerTypeRepository cancerTypeRepository; + + private final CancerTypeQueryService cancerTypeQueryService; + + public CancerTypeResource( + CancerTypeService cancerTypeService, + CancerTypeRepository cancerTypeRepository, + CancerTypeQueryService cancerTypeQueryService + ) { + this.cancerTypeService = cancerTypeService; + this.cancerTypeRepository = cancerTypeRepository; + this.cancerTypeQueryService = cancerTypeQueryService; + } + + /** + * {@code POST /cancer-types} : Create a new cancerType. + * + * @param cancerType the cancerType to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new cancerType, or with status {@code 400 (Bad Request)} if the cancerType has already an ID. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PostMapping("/cancer-types") + public ResponseEntity createCancerType(@Valid @RequestBody CancerType cancerType) throws URISyntaxException { + log.debug("REST request to save CancerType : {}", cancerType); + if (cancerType.getId() != null) { + throw new BadRequestAlertException("A new cancerType cannot already have an ID", ENTITY_NAME, "idexists"); + } + CancerType result = cancerTypeService.save(cancerType); + return ResponseEntity.created(new URI("/api/cancer-types/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) + .body(result); + } + + /** + * {@code PUT /cancer-types/:id} : Updates an existing cancerType. + * + * @param id the id of the cancerType to save. + * @param cancerType the cancerType to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated cancerType, + * or with status {@code 400 (Bad Request)} if the cancerType is not valid, + * or with status {@code 500 (Internal Server Error)} if the cancerType couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PutMapping("/cancer-types/{id}") + public ResponseEntity updateCancerType( + @PathVariable(value = "id", required = false) final Long id, + @Valid @RequestBody CancerType cancerType + ) throws URISyntaxException { + log.debug("REST request to update CancerType : {}, {}", id, cancerType); + if (cancerType.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, cancerType.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!cancerTypeRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + CancerType result = cancerTypeService.save(cancerType); + return ResponseEntity.ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, cancerType.getId().toString())) + .body(result); + } + + /** + * {@code PATCH /cancer-types/:id} : Partial updates given fields of an existing cancerType, field will ignore if it is null + * + * @param id the id of the cancerType to save. + * @param cancerType the cancerType to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated cancerType, + * or with status {@code 400 (Bad Request)} if the cancerType is not valid, + * or with status {@code 404 (Not Found)} if the cancerType is not found, + * or with status {@code 500 (Internal Server Error)} if the cancerType couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/cancer-types/{id}", consumes = { "application/json", "application/merge-patch+json" }) + public ResponseEntity partialUpdateCancerType( + @PathVariable(value = "id", required = false) final Long id, + @NotNull @RequestBody CancerType cancerType + ) throws URISyntaxException { + log.debug("REST request to partial update CancerType partially : {}, {}", id, cancerType); + if (cancerType.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, cancerType.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!cancerTypeRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Optional result = cancerTypeService.partialUpdate(cancerType); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, cancerType.getId().toString()) + ); + } + + /** + * {@code GET /cancer-types} : get all the cancerTypes. + * + * @param pageable the pagination information. + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of cancerTypes in body. + */ + @GetMapping("/cancer-types") + public ResponseEntity> getAllCancerTypes(CancerTypeCriteria criteria, Pageable pageable) { + log.debug("REST request to get CancerTypes by criteria: {}", criteria); + Page page = cancerTypeQueryService.findByCriteria(criteria, pageable); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(page.getContent()); + } + + /** + * {@code GET /cancer-types/count} : count all the cancerTypes. + * + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the count in body. + */ + @GetMapping("/cancer-types/count") + public ResponseEntity countCancerTypes(CancerTypeCriteria criteria) { + log.debug("REST request to count CancerTypes by criteria: {}", criteria); + return ResponseEntity.ok().body(cancerTypeQueryService.countByCriteria(criteria)); + } + + /** + * {@code GET /cancer-types/:id} : get the "id" cancerType. + * + * @param id the id of the cancerType to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the cancerType, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/cancer-types/{id}") + public ResponseEntity getCancerType(@PathVariable Long id) { + log.debug("REST request to get CancerType : {}", id); + Optional cancerType = cancerTypeService.findOne(id); + return ResponseUtil.wrapOrNotFound(cancerType); + } + + /** + * {@code DELETE /cancer-types/:id} : delete the "id" cancerType. + * + * @param id the id of the cancerType to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/cancer-types/{id}") + public ResponseEntity deleteCancerType(@PathVariable Long id) { + log.debug("REST request to delete CancerType : {}", id); + cancerTypeService.delete(id); + return ResponseEntity.noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); + } + + /** + * {@code SEARCH /cancer-types/search?query=:query} : search for the cancerType corresponding + * to the query. + * + * @param query the query of the cancerType search. + * @param pageable the pagination information. + * @return the result of the search. + */ + @GetMapping("/cancer-types/search") + public ResponseEntity> searchCancerTypes(@RequestParam String query, Pageable pageable) { + log.debug("REST request to search for a page of CancerTypes for query {}", query); + Page page = cancerTypeQueryService.findBySearchQuery(query, pageable); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(page.getContent()); + } + + /** + * {@code POST /cancer-types/relevant} : get the relevant cancer types corresponding + * to the cancer type queries. + * + * @param levelOfEvidence the level of evidence of the diagnostic implication (Dx), prognostic implication (Px), or treatment (Tx) + * @param cancerTypeQueries an object containing relevant cancer type queries consisting of main type and code, allowing for excluded queries as well + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the relevant cancer types in the body. + */ + @PostMapping("cancer-types/relevant") + public ResponseEntity> getRelevantCancerTypes( + @RequestParam(required = false) String levelOfEvidence, + @Valid @RequestBody RelevantCancerTypeBody cancerTypeQueries + ) { + return ResponseEntity.ok().body(cancerTypeService.getRelevantCancerTypes(levelOfEvidence, cancerTypeQueries)); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/CategoricalAlterationResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/CategoricalAlterationResource.java new file mode 100644 index 000000000..51a49eb5a --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/CategoricalAlterationResource.java @@ -0,0 +1,176 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.CategoricalAlteration; +import org.mskcc.oncokb.curation.repository.CategoricalAlterationRepository; +import org.mskcc.oncokb.curation.service.CategoricalAlterationService; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing {@link org.mskcc.oncokb.curation.domain.CategoricalAlteration}. + */ +@RestController +@RequestMapping("/api") +public class CategoricalAlterationResource { + + private final Logger log = LoggerFactory.getLogger(CategoricalAlterationResource.class); + + private static final String ENTITY_NAME = "categoricalAlteration"; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final CategoricalAlterationService categoricalAlterationService; + + private final CategoricalAlterationRepository categoricalAlterationRepository; + + public CategoricalAlterationResource( + CategoricalAlterationService categoricalAlterationService, + CategoricalAlterationRepository categoricalAlterationRepository + ) { + this.categoricalAlterationService = categoricalAlterationService; + this.categoricalAlterationRepository = categoricalAlterationRepository; + } + + /** + * {@code POST /categorical-alterations} : Create a new categoricalAlteration. + * + * @param categoricalAlteration the categoricalAlteration to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new categoricalAlteration, or with status {@code 400 (Bad Request)} if the categoricalAlteration has already an ID. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PostMapping("/categorical-alterations") + public ResponseEntity createCategoricalAlteration( + @Valid @RequestBody CategoricalAlteration categoricalAlteration + ) throws URISyntaxException { + log.debug("REST request to save CategoricalAlteration : {}", categoricalAlteration); + if (categoricalAlteration.getId() != null) { + throw new BadRequestAlertException("A new categoricalAlteration cannot already have an ID", ENTITY_NAME, "idexists"); + } + CategoricalAlteration result = categoricalAlterationService.save(categoricalAlteration); + return ResponseEntity.created(new URI("/api/categorical-alterations/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) + .body(result); + } + + /** + * {@code PUT /categorical-alterations/:id} : Updates an existing categoricalAlteration. + * + * @param id the id of the categoricalAlteration to save. + * @param categoricalAlteration the categoricalAlteration to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated categoricalAlteration, + * or with status {@code 400 (Bad Request)} if the categoricalAlteration is not valid, + * or with status {@code 500 (Internal Server Error)} if the categoricalAlteration couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PutMapping("/categorical-alterations/{id}") + public ResponseEntity updateCategoricalAlteration( + @PathVariable(value = "id", required = false) final Long id, + @Valid @RequestBody CategoricalAlteration categoricalAlteration + ) throws URISyntaxException { + log.debug("REST request to update CategoricalAlteration : {}, {}", id, categoricalAlteration); + if (categoricalAlteration.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, categoricalAlteration.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!categoricalAlterationRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + CategoricalAlteration result = categoricalAlterationService.save(categoricalAlteration); + return ResponseEntity.ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, categoricalAlteration.getId().toString())) + .body(result); + } + + /** + * {@code PATCH /categorical-alterations/:id} : Partial updates given fields of an existing categoricalAlteration, field will ignore if it is null + * + * @param id the id of the categoricalAlteration to save. + * @param categoricalAlteration the categoricalAlteration to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated categoricalAlteration, + * or with status {@code 400 (Bad Request)} if the categoricalAlteration is not valid, + * or with status {@code 404 (Not Found)} if the categoricalAlteration is not found, + * or with status {@code 500 (Internal Server Error)} if the categoricalAlteration couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/categorical-alterations/{id}", consumes = { "application/json", "application/merge-patch+json" }) + public ResponseEntity partialUpdateCategoricalAlteration( + @PathVariable(value = "id", required = false) final Long id, + @NotNull @RequestBody CategoricalAlteration categoricalAlteration + ) throws URISyntaxException { + log.debug("REST request to partial update CategoricalAlteration partially : {}, {}", id, categoricalAlteration); + if (categoricalAlteration.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, categoricalAlteration.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!categoricalAlterationRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Optional result = categoricalAlterationService.partialUpdate(categoricalAlteration); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, categoricalAlteration.getId().toString()) + ); + } + + /** + * {@code GET /categorical-alterations} : get all the categoricalAlterations. + * + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of categoricalAlterations in body. + */ + @GetMapping("/categorical-alterations") + public List getAllCategoricalAlterations() { + log.debug("REST request to get all CategoricalAlterations"); + return categoricalAlterationService.findAll(); + } + + /** + * {@code GET /categorical-alterations/:id} : get the "id" categoricalAlteration. + * + * @param id the id of the categoricalAlteration to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the categoricalAlteration, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/categorical-alterations/{id}") + public ResponseEntity getCategoricalAlteration(@PathVariable Long id) { + log.debug("REST request to get CategoricalAlteration : {}", id); + Optional categoricalAlteration = categoricalAlterationService.findOne(id); + return ResponseUtil.wrapOrNotFound(categoricalAlteration); + } + + /** + * {@code DELETE /categorical-alterations/:id} : delete the "id" categoricalAlteration. + * + * @param id the id of the categoricalAlteration to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/categorical-alterations/{id}") + public ResponseEntity deleteCategoricalAlteration(@PathVariable Long id) { + log.debug("REST request to delete CategoricalAlteration : {}", id); + categoricalAlterationService.delete(id); + return ResponseEntity.noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/ClientForwardController.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/ClientForwardController.java new file mode 100644 index 000000000..ef1dab748 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/ClientForwardController.java @@ -0,0 +1,43 @@ +package org.mskcc.oncokb.curation.web.rest; + +import org.mskcc.oncokb.curation.config.application.ApplicationProperties; +import org.mskcc.oncokb.curation.security.SecurityUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.thymeleaf.context.Context; +import org.thymeleaf.spring6.SpringTemplateEngine; + +@Controller +public class ClientForwardController { + + @Autowired + ApplicationProperties applicationProperties; + + @Autowired + SpringTemplateEngine templateEngine; + + /** + * Forwards any unmapped paths (except those containing a period) to the client {@code index.html}. + * + * @return forward to client {@code index.html}. + */ + @GetMapping(value = "/index.html") + public ResponseEntity index() { + Context context = new Context(); + + // Only to add frontend config after authentication + if (SecurityUtils.isAuthenticated()) { + context.setVariable("frontendConfig", applicationProperties.getFrontend()); + } + + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setContentType(MediaType.TEXT_HTML); + + ResponseEntity responseEntity = ResponseEntity.ok().headers(httpHeaders).body(templateEngine.process("index", context)); + return responseEntity; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/ClinicalTrialArmResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/ClinicalTrialArmResource.java new file mode 100644 index 000000000..aa099e8c8 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/ClinicalTrialArmResource.java @@ -0,0 +1,221 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.ClinicalTrialArm; +import org.mskcc.oncokb.curation.repository.ClinicalTrialArmRepository; +import org.mskcc.oncokb.curation.service.ClinicalTrialArmQueryService; +import org.mskcc.oncokb.curation.service.ClinicalTrialArmService; +import org.mskcc.oncokb.curation.service.criteria.ClinicalTrialArmCriteria; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.PaginationUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing {@link org.mskcc.oncokb.curation.domain.ClinicalTrialArm}. + */ +@RestController +@RequestMapping("/api") +public class ClinicalTrialArmResource { + + private final Logger log = LoggerFactory.getLogger(ClinicalTrialArmResource.class); + + private static final String ENTITY_NAME = "clinicalTrialArm"; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final ClinicalTrialArmService clinicalTrialArmService; + + private final ClinicalTrialArmRepository clinicalTrialArmRepository; + + private final ClinicalTrialArmQueryService clinicalTrialArmQueryService; + + public ClinicalTrialArmResource( + ClinicalTrialArmService clinicalTrialArmService, + ClinicalTrialArmRepository clinicalTrialArmRepository, + ClinicalTrialArmQueryService clinicalTrialArmQueryService + ) { + this.clinicalTrialArmService = clinicalTrialArmService; + this.clinicalTrialArmRepository = clinicalTrialArmRepository; + this.clinicalTrialArmQueryService = clinicalTrialArmQueryService; + } + + /** + * {@code POST /clinical-trial-arms} : Create a new clinicalTrialArm. + * + * @param clinicalTrialArm the clinicalTrialArm to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new clinicalTrialArm, or with status {@code 400 (Bad Request)} if the clinicalTrialArm has already an ID. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PostMapping("/clinical-trial-arms") + public ResponseEntity createClinicalTrialArm(@Valid @RequestBody ClinicalTrialArm clinicalTrialArm) + throws URISyntaxException { + log.debug("REST request to save ClinicalTrialArm : {}", clinicalTrialArm); + if (clinicalTrialArm.getId() != null) { + throw new BadRequestAlertException("A new clinicalTrialArm cannot already have an ID", ENTITY_NAME, "idexists"); + } + ClinicalTrialArm result = clinicalTrialArmService.save(clinicalTrialArm); + return ResponseEntity.created(new URI("/api/clinical-trial-arms/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) + .body(result); + } + + /** + * {@code PUT /clinical-trial-arms/:id} : Updates an existing clinicalTrialArm. + * + * @param id the id of the clinicalTrialArm to save. + * @param clinicalTrialArm the clinicalTrialArm to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated clinicalTrialArm, + * or with status {@code 400 (Bad Request)} if the clinicalTrialArm is not valid, + * or with status {@code 500 (Internal Server Error)} if the clinicalTrialArm couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PutMapping("/clinical-trial-arms/{id}") + public ResponseEntity updateClinicalTrialArm( + @PathVariable(value = "id", required = false) final Long id, + @Valid @RequestBody ClinicalTrialArm clinicalTrialArm + ) throws URISyntaxException { + log.debug("REST request to update ClinicalTrialArm : {}, {}", id, clinicalTrialArm); + if (clinicalTrialArm.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, clinicalTrialArm.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!clinicalTrialArmRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + ClinicalTrialArm result = clinicalTrialArmService.save(clinicalTrialArm); + return ResponseEntity.ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, clinicalTrialArm.getId().toString())) + .body(result); + } + + /** + * {@code PATCH /clinical-trial-arms/:id} : Partial updates given fields of an existing clinicalTrialArm, field will ignore if it is null + * + * @param id the id of the clinicalTrialArm to save. + * @param clinicalTrialArm the clinicalTrialArm to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated clinicalTrialArm, + * or with status {@code 400 (Bad Request)} if the clinicalTrialArm is not valid, + * or with status {@code 404 (Not Found)} if the clinicalTrialArm is not found, + * or with status {@code 500 (Internal Server Error)} if the clinicalTrialArm couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/clinical-trial-arms/{id}", consumes = { "application/json", "application/merge-patch+json" }) + public ResponseEntity partialUpdateClinicalTrialArm( + @PathVariable(value = "id", required = false) final Long id, + @NotNull @RequestBody ClinicalTrialArm clinicalTrialArm + ) throws URISyntaxException { + log.debug("REST request to partial update ClinicalTrialArm partially : {}, {}", id, clinicalTrialArm); + if (clinicalTrialArm.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, clinicalTrialArm.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!clinicalTrialArmRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Optional result = clinicalTrialArmService.partialUpdate(clinicalTrialArm); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, clinicalTrialArm.getId().toString()) + ); + } + + /** + * {@code GET /clinical-trial-arms} : get all the clinicalTrialArms. + * + * @param pageable the pagination information. + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of clinicalTrialArms in body. + */ + @GetMapping("/clinical-trial-arms") + public ResponseEntity> getAllClinicalTrialArms(ClinicalTrialArmCriteria criteria, Pageable pageable) { + log.debug("REST request to get ClinicalTrialArms by criteria: {}", criteria); + Page page = clinicalTrialArmQueryService.findByCriteria(criteria, pageable); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(page.getContent()); + } + + /** + * {@code GET /clinical-trial-arms/count} : count all the clinicalTrialArms. + * + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the count in body. + */ + @GetMapping("/clinical-trial-arms/count") + public ResponseEntity countClinicalTrialArms(ClinicalTrialArmCriteria criteria) { + log.debug("REST request to count ClinicalTrialArms by criteria: {}", criteria); + return ResponseEntity.ok().body(clinicalTrialArmQueryService.countByCriteria(criteria)); + } + + /** + * {@code GET /clinical-trial-arms/:id} : get the "id" clinicalTrialArm. + * + * @param id the id of the clinicalTrialArm to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the clinicalTrialArm, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/clinical-trial-arms/{id}") + public ResponseEntity getClinicalTrialArm(@PathVariable Long id) { + log.debug("REST request to get ClinicalTrialArm : {}", id); + Optional clinicalTrialArm = clinicalTrialArmService.findOne(id); + return ResponseUtil.wrapOrNotFound(clinicalTrialArm); + } + + /** + * {@code DELETE /clinical-trial-arms/:id} : delete the "id" clinicalTrialArm. + * + * @param id the id of the clinicalTrialArm to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/clinical-trial-arms/{id}") + public ResponseEntity deleteClinicalTrialArm(@PathVariable Long id) { + log.debug("REST request to delete ClinicalTrialArm : {}", id); + clinicalTrialArmService.delete(id); + return ResponseEntity.noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); + } + + /** + * {@code SEARCH /clinical-trial-arms/search?query=:query} : search for the ClinicalTrialArm corresponding + * to the query. + * + * @param query the query of the ClinicalTrialArm search. + * @param pageable the pagination information. + * @return the result of the search. + */ + @GetMapping("/clinical-trial-arms/search") + public ResponseEntity> searchClinicalTrialArms(@RequestParam String query, Pageable pageable) { + log.debug("REST request to search for a page of ClinicalTrialArms for query {}", query); + // TODO: implement the search + Page page = new PageImpl<>(new ArrayList<>()); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(page.getContent()); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/ClinicalTrialResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/ClinicalTrialResource.java new file mode 100644 index 000000000..d56724016 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/ClinicalTrialResource.java @@ -0,0 +1,220 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.ClinicalTrial; +import org.mskcc.oncokb.curation.repository.ClinicalTrialRepository; +import org.mskcc.oncokb.curation.service.ClinicalTrialQueryService; +import org.mskcc.oncokb.curation.service.ClinicalTrialService; +import org.mskcc.oncokb.curation.service.criteria.ClinicalTrialCriteria; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.PaginationUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing {@link org.mskcc.oncokb.curation.domain.ClinicalTrial}. + */ +@RestController +@RequestMapping("/api") +public class ClinicalTrialResource { + + private final Logger log = LoggerFactory.getLogger(ClinicalTrialResource.class); + + private static final String ENTITY_NAME = "clinicalTrial"; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final ClinicalTrialService clinicalTrialService; + + private final ClinicalTrialRepository clinicalTrialRepository; + + private final ClinicalTrialQueryService clinicalTrialQueryService; + + public ClinicalTrialResource( + ClinicalTrialService clinicalTrialService, + ClinicalTrialRepository clinicalTrialRepository, + ClinicalTrialQueryService clinicalTrialQueryService + ) { + this.clinicalTrialService = clinicalTrialService; + this.clinicalTrialRepository = clinicalTrialRepository; + this.clinicalTrialQueryService = clinicalTrialQueryService; + } + + /** + * {@code POST /clinical-trials} : Create a new clinicalTrial. + * + * @param clinicalTrial the clinicalTrial to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new clinicalTrial, or with status {@code 400 (Bad Request)} if the clinicalTrial has already an ID. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PostMapping("/clinical-trials") + public ResponseEntity createClinicalTrial(@Valid @RequestBody ClinicalTrial clinicalTrial) throws URISyntaxException { + log.debug("REST request to save ClinicalTrial : {}", clinicalTrial); + if (clinicalTrial.getId() != null) { + throw new BadRequestAlertException("A new clinicalTrial cannot already have an ID", ENTITY_NAME, "idexists"); + } + ClinicalTrial result = clinicalTrialService.save(clinicalTrial); + return ResponseEntity.created(new URI("/api/clinical-trials/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) + .body(result); + } + + /** + * {@code PUT /clinical-trials/:id} : Updates an existing clinicalTrial. + * + * @param id the id of the clinicalTrial to save. + * @param clinicalTrial the clinicalTrial to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated clinicalTrial, + * or with status {@code 400 (Bad Request)} if the clinicalTrial is not valid, + * or with status {@code 500 (Internal Server Error)} if the clinicalTrial couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PutMapping("/clinical-trials/{id}") + public ResponseEntity updateClinicalTrial( + @PathVariable(value = "id", required = false) final Long id, + @Valid @RequestBody ClinicalTrial clinicalTrial + ) throws URISyntaxException { + log.debug("REST request to update ClinicalTrial : {}, {}", id, clinicalTrial); + if (clinicalTrial.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, clinicalTrial.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!clinicalTrialRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + ClinicalTrial result = clinicalTrialService.save(clinicalTrial); + return ResponseEntity.ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, clinicalTrial.getId().toString())) + .body(result); + } + + /** + * {@code PATCH /clinical-trials/:id} : Partial updates given fields of an existing clinicalTrial, field will ignore if it is null + * + * @param id the id of the clinicalTrial to save. + * @param clinicalTrial the clinicalTrial to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated clinicalTrial, + * or with status {@code 400 (Bad Request)} if the clinicalTrial is not valid, + * or with status {@code 404 (Not Found)} if the clinicalTrial is not found, + * or with status {@code 500 (Internal Server Error)} if the clinicalTrial couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/clinical-trials/{id}", consumes = { "application/json", "application/merge-patch+json" }) + public ResponseEntity partialUpdateClinicalTrial( + @PathVariable(value = "id", required = false) final Long id, + @NotNull @RequestBody ClinicalTrial clinicalTrial + ) throws URISyntaxException { + log.debug("REST request to partial update ClinicalTrial partially : {}, {}", id, clinicalTrial); + if (clinicalTrial.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, clinicalTrial.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!clinicalTrialRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Optional result = clinicalTrialService.partialUpdate(clinicalTrial); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, clinicalTrial.getId().toString()) + ); + } + + /** + * {@code GET /clinical-trials} : get all the clinicalTrials. + * + * @param pageable the pagination information. + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of clinicalTrials in body. + */ + @GetMapping("/clinical-trials") + public ResponseEntity> getAllClinicalTrials(ClinicalTrialCriteria criteria, Pageable pageable) { + log.debug("REST request to get ClinicalTrials by criteria: {}", criteria); + Page page = clinicalTrialQueryService.findByCriteria(criteria, pageable); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(page.getContent()); + } + + /** + * {@code GET /clinical-trials/count} : count all the clinicalTrials. + * + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the count in body. + */ + @GetMapping("/clinical-trials/count") + public ResponseEntity countClinicalTrials(ClinicalTrialCriteria criteria) { + log.debug("REST request to count ClinicalTrials by criteria: {}", criteria); + return ResponseEntity.ok().body(clinicalTrialQueryService.countByCriteria(criteria)); + } + + /** + * {@code GET /clinical-trials/:id} : get the "id" clinicalTrial. + * + * @param id the id of the clinicalTrial to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the clinicalTrial, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/clinical-trials/{id}") + public ResponseEntity getClinicalTrial(@PathVariable Long id) { + log.debug("REST request to get ClinicalTrial : {}", id); + Optional clinicalTrial = clinicalTrialService.findOne(id); + return ResponseUtil.wrapOrNotFound(clinicalTrial); + } + + /** + * {@code DELETE /clinical-trials/:id} : delete the "id" clinicalTrial. + * + * @param id the id of the clinicalTrial to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/clinical-trials/{id}") + public ResponseEntity deleteClinicalTrial(@PathVariable Long id) { + log.debug("REST request to delete ClinicalTrial : {}", id); + clinicalTrialService.delete(id); + return ResponseEntity.noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); + } + + /** + * {@code SEARCH /clinical-trials/search?query=:query} : search for the ClinicalTrial corresponding + * to the query. + * + * @param query the query of the ClinicalTrial search. + * @param pageable the pagination information. + * @return the result of the search. + */ + @GetMapping("/clinical-trials/search") + public ResponseEntity> searchClinicalTrials(@RequestParam String query, Pageable pageable) { + log.debug("REST request to search for a page of ClinicalTrials for query {}", query); + // TODO: implement the search + Page page = new PageImpl<>(new ArrayList<>()); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(page.getContent()); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/CompanionDiagnosticDeviceResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/CompanionDiagnosticDeviceResource.java new file mode 100644 index 000000000..d2523e492 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/CompanionDiagnosticDeviceResource.java @@ -0,0 +1,218 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.CompanionDiagnosticDevice; +import org.mskcc.oncokb.curation.repository.CompanionDiagnosticDeviceRepository; +import org.mskcc.oncokb.curation.service.CompanionDiagnosticDeviceQueryService; +import org.mskcc.oncokb.curation.service.CompanionDiagnosticDeviceService; +import org.mskcc.oncokb.curation.service.criteria.CompanionDiagnosticDeviceCriteria; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing {@link org.mskcc.oncokb.curation.domain.CompanionDiagnosticDevice}. + */ +@RestController +@RequestMapping("/api") +public class CompanionDiagnosticDeviceResource { + + private final Logger log = LoggerFactory.getLogger(CompanionDiagnosticDeviceResource.class); + + private static final String ENTITY_NAME = "companionDiagnosticDevice"; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final CompanionDiagnosticDeviceService companionDiagnosticDeviceService; + + private final CompanionDiagnosticDeviceRepository companionDiagnosticDeviceRepository; + + private final CompanionDiagnosticDeviceQueryService companionDiagnosticDeviceQueryService; + + public CompanionDiagnosticDeviceResource( + CompanionDiagnosticDeviceService companionDiagnosticDeviceService, + CompanionDiagnosticDeviceRepository companionDiagnosticDeviceRepository, + CompanionDiagnosticDeviceQueryService companionDiagnosticDeviceQueryService + ) { + this.companionDiagnosticDeviceService = companionDiagnosticDeviceService; + this.companionDiagnosticDeviceRepository = companionDiagnosticDeviceRepository; + this.companionDiagnosticDeviceQueryService = companionDiagnosticDeviceQueryService; + } + + /** + * {@code POST /companion-diagnostic-devices} : Create a new companionDiagnosticDevice. + * + * @param companionDiagnosticDevice the companionDiagnosticDevice to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new companionDiagnosticDevice, or with status {@code 400 (Bad Request)} if the companionDiagnosticDevice has already an ID. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PostMapping("/companion-diagnostic-devices") + public ResponseEntity createCompanionDiagnosticDevice( + @Valid @RequestBody CompanionDiagnosticDevice companionDiagnosticDevice + ) throws URISyntaxException { + log.debug("REST request to save CompanionDiagnosticDevice : {}", companionDiagnosticDevice); + if (companionDiagnosticDevice.getId() != null) { + throw new BadRequestAlertException("A new companionDiagnosticDevice cannot already have an ID", ENTITY_NAME, "idexists"); + } + CompanionDiagnosticDevice result = companionDiagnosticDeviceService.save(companionDiagnosticDevice); + return ResponseEntity.created(new URI("/api/companion-diagnostic-devices/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) + .body(result); + } + + /** + * {@code PUT /companion-diagnostic-devices/:id} : Updates an existing companionDiagnosticDevice. + * + * @param id the id of the companionDiagnosticDevice to save. + * @param companionDiagnosticDevice the companionDiagnosticDevice to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated companionDiagnosticDevice, + * or with status {@code 400 (Bad Request)} if the companionDiagnosticDevice is not valid, + * or with status {@code 500 (Internal Server Error)} if the companionDiagnosticDevice couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PutMapping("/companion-diagnostic-devices/{id}") + public ResponseEntity updateCompanionDiagnosticDevice( + @PathVariable(value = "id", required = false) final Long id, + @Valid @RequestBody CompanionDiagnosticDevice companionDiagnosticDevice + ) throws URISyntaxException { + log.debug("REST request to update CompanionDiagnosticDevice : {}, {}", id, companionDiagnosticDevice); + if (companionDiagnosticDevice.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, companionDiagnosticDevice.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!companionDiagnosticDeviceRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + CompanionDiagnosticDevice result = companionDiagnosticDeviceService.save(companionDiagnosticDevice); + return ResponseEntity.ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, companionDiagnosticDevice.getId().toString())) + .body(result); + } + + /** + * {@code PATCH /companion-diagnostic-devices/:id} : Partial updates given fields of an existing companionDiagnosticDevice, field will ignore if it is null + * + * @param id the id of the companionDiagnosticDevice to save. + * @param companionDiagnosticDevice the companionDiagnosticDevice to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated companionDiagnosticDevice, + * or with status {@code 400 (Bad Request)} if the companionDiagnosticDevice is not valid, + * or with status {@code 404 (Not Found)} if the companionDiagnosticDevice is not found, + * or with status {@code 500 (Internal Server Error)} if the companionDiagnosticDevice couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/companion-diagnostic-devices/{id}", consumes = { "application/json", "application/merge-patch+json" }) + public ResponseEntity partialUpdateCompanionDiagnosticDevice( + @PathVariable(value = "id", required = false) final Long id, + @NotNull @RequestBody CompanionDiagnosticDevice companionDiagnosticDevice + ) throws URISyntaxException { + log.debug("REST request to partial update CompanionDiagnosticDevice partially : {}, {}", id, companionDiagnosticDevice); + if (companionDiagnosticDevice.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, companionDiagnosticDevice.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!companionDiagnosticDeviceRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Optional result = companionDiagnosticDeviceService.partialUpdate(companionDiagnosticDevice); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, companionDiagnosticDevice.getId().toString()) + ); + } + + /** + * {@code GET /companion-diagnostic-devices} : get all the companionDiagnosticDevices. + * + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of companionDiagnosticDevices in body. + */ + @GetMapping("/companion-diagnostic-devices") + public ResponseEntity> getAllCompanionDiagnosticDevices(CompanionDiagnosticDeviceCriteria criteria) { + log.debug("REST request to get CompanionDiagnosticDevices by criteria: {}", criteria); + List entityList = companionDiagnosticDeviceQueryService.findByCriteria(criteria); + return ResponseEntity.ok().body(entityList); + } + + /** + * {@code GET /companion-diagnostic-devices/count} : count all the companionDiagnosticDevices. + * + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the count in body. + */ + @GetMapping("/companion-diagnostic-devices/count") + public ResponseEntity countCompanionDiagnosticDevices(CompanionDiagnosticDeviceCriteria criteria) { + log.debug("REST request to count CompanionDiagnosticDevices by criteria: {}", criteria); + return ResponseEntity.ok().body(companionDiagnosticDeviceQueryService.countByCriteria(criteria)); + } + + /** + * {@code GET /companion-diagnostic-devices/:id} : get the "id" companionDiagnosticDevice. + * + * @param id the id of the companionDiagnosticDevice to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the companionDiagnosticDevice, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/companion-diagnostic-devices/{id}") + public ResponseEntity getCompanionDiagnosticDevice(@PathVariable Long id) { + log.debug("REST request to get CompanionDiagnosticDevice : {}", id); + Optional companionDiagnosticDevice = companionDiagnosticDeviceService.findOne(id); + return ResponseUtil.wrapOrNotFound(companionDiagnosticDevice); + } + + /** + * {@code DELETE /companion-diagnostic-devices/:id} : delete the "id" companionDiagnosticDevice. + * + * @param id the id of the companionDiagnosticDevice to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/companion-diagnostic-devices/{id}") + public ResponseEntity deleteCompanionDiagnosticDevice(@PathVariable Long id) { + log.debug("REST request to delete CompanionDiagnosticDevice : {}", id); + companionDiagnosticDeviceService.delete(id); + return ResponseEntity.noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); + } + + /** + * {@code SEARCH /companion-diagnostic-devices/search?query=:query} : search for the companionDiagnosticDevice corresponding + * to the query. + * + * @param query the query of the companionDiagnosticDevice search. + * @return the result of the search. + */ + @GetMapping("/companion-diagnostic-devices/search") + public List searchCompanionDiagnosticDevices(@RequestParam String query) { + log.debug("REST request to search CompanionDiagnosticDevices for query {}", query); + return companionDiagnosticDeviceQueryService.findBySearchQuery(query); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/ConsequenceResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/ConsequenceResource.java new file mode 100644 index 000000000..1f03a0d1c --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/ConsequenceResource.java @@ -0,0 +1,194 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.Consequence; +import org.mskcc.oncokb.curation.repository.ConsequenceRepository; +import org.mskcc.oncokb.curation.service.ConsequenceQueryService; +import org.mskcc.oncokb.curation.service.ConsequenceService; +import org.mskcc.oncokb.curation.service.criteria.ConsequenceCriteria; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing {@link org.mskcc.oncokb.curation.domain.Consequence}. + */ +@RestController +@RequestMapping("/api") +public class ConsequenceResource { + + private final Logger log = LoggerFactory.getLogger(ConsequenceResource.class); + + private static final String ENTITY_NAME = "consequence"; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final ConsequenceService consequenceService; + + private final ConsequenceRepository consequenceRepository; + + private final ConsequenceQueryService consequenceQueryService; + + public ConsequenceResource( + ConsequenceService consequenceService, + ConsequenceRepository consequenceRepository, + ConsequenceQueryService consequenceQueryService + ) { + this.consequenceService = consequenceService; + this.consequenceRepository = consequenceRepository; + this.consequenceQueryService = consequenceQueryService; + } + + /** + * {@code POST /consequences} : Create a new consequence. + * + * @param consequence the consequence to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new consequence, or with status {@code 400 (Bad Request)} if the consequence has already an ID. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PostMapping("/consequences") + public ResponseEntity createConsequence(@Valid @RequestBody Consequence consequence) throws URISyntaxException { + log.debug("REST request to save Consequence : {}", consequence); + if (consequence.getId() != null) { + throw new BadRequestAlertException("A new consequence cannot already have an ID", ENTITY_NAME, "idexists"); + } + Consequence result = consequenceService.save(consequence); + return ResponseEntity.created(new URI("/api/consequences/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) + .body(result); + } + + /** + * {@code PUT /consequences/:id} : Updates an existing consequence. + * + * @param id the id of the consequence to save. + * @param consequence the consequence to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated consequence, + * or with status {@code 400 (Bad Request)} if the consequence is not valid, + * or with status {@code 500 (Internal Server Error)} if the consequence couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PutMapping("/consequences/{id}") + public ResponseEntity updateConsequence( + @PathVariable(value = "id", required = false) final Long id, + @Valid @RequestBody Consequence consequence + ) throws URISyntaxException { + log.debug("REST request to update Consequence : {}, {}", id, consequence); + if (consequence.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, consequence.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!consequenceRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Consequence result = consequenceService.save(consequence); + return ResponseEntity.ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, consequence.getId().toString())) + .body(result); + } + + /** + * {@code PATCH /consequences/:id} : Partial updates given fields of an existing consequence, field will ignore if it is null + * + * @param id the id of the consequence to save. + * @param consequence the consequence to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated consequence, + * or with status {@code 400 (Bad Request)} if the consequence is not valid, + * or with status {@code 404 (Not Found)} if the consequence is not found, + * or with status {@code 500 (Internal Server Error)} if the consequence couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/consequences/{id}", consumes = { "application/json", "application/merge-patch+json" }) + public ResponseEntity partialUpdateConsequence( + @PathVariable(value = "id", required = false) final Long id, + @NotNull @RequestBody Consequence consequence + ) throws URISyntaxException { + log.debug("REST request to partial update Consequence partially : {}, {}", id, consequence); + if (consequence.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, consequence.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!consequenceRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Optional result = consequenceService.partialUpdate(consequence); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, consequence.getId().toString()) + ); + } + + /** + * {@code GET /consequences} : get all the consequences. + * + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of consequences in body. + */ + @GetMapping("/consequences") + public ResponseEntity> getAllConsequences(ConsequenceCriteria criteria) { + log.debug("REST request to get Consequences by criteria: {}", criteria); + List entityList = consequenceQueryService.findByCriteria(criteria); + return ResponseEntity.ok().body(entityList); + } + + /** + * {@code GET /consequences/count} : count all the consequences. + * + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the count in body. + */ + @GetMapping("/consequences/count") + public ResponseEntity countConsequences(ConsequenceCriteria criteria) { + log.debug("REST request to count Consequences by criteria: {}", criteria); + return ResponseEntity.ok().body(consequenceQueryService.countByCriteria(criteria)); + } + + /** + * {@code GET /consequences/:id} : get the "id" consequence. + * + * @param id the id of the consequence to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the consequence, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/consequences/{id}") + public ResponseEntity getConsequence(@PathVariable Long id) { + log.debug("REST request to get Consequence : {}", id); + Optional consequence = consequenceService.findOne(id); + return ResponseUtil.wrapOrNotFound(consequence); + } + + /** + * {@code DELETE /consequences/:id} : delete the "id" consequence. + * + * @param id the id of the consequence to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/consequences/{id}") + public ResponseEntity deleteConsequence(@PathVariable Long id) { + log.debug("REST request to delete Consequence : {}", id); + consequenceService.delete(id); + return ResponseEntity.noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/DrugResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/DrugResource.java new file mode 100644 index 000000000..63972e385 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/DrugResource.java @@ -0,0 +1,202 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; +import org.mskcc.oncokb.curation.domain.Drug; +import org.mskcc.oncokb.curation.repository.DrugRepository; +import org.mskcc.oncokb.curation.service.DrugQueryService; +import org.mskcc.oncokb.curation.service.DrugService; +import org.mskcc.oncokb.curation.service.criteria.DrugCriteria; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing {@link org.mskcc.oncokb.curation.domain.Drug}. + */ +@RestController +@RequestMapping("/api") +public class DrugResource { + + private final Logger log = LoggerFactory.getLogger(DrugResource.class); + + private static final String ENTITY_NAME = "drug"; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final DrugService drugService; + + private final DrugRepository drugRepository; + + private final DrugQueryService drugQueryService; + + public DrugResource(DrugService drugService, DrugRepository drugRepository, DrugQueryService drugQueryService) { + this.drugService = drugService; + this.drugRepository = drugRepository; + this.drugQueryService = drugQueryService; + } + + /** + * {@code POST /drugs} : Create a new drug. + * + * @param drug the drug to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new drug, or with status {@code 400 (Bad Request)} if the drug has already an ID. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PostMapping("/drugs") + public ResponseEntity createDrug(@Valid @RequestBody Drug drug) throws URISyntaxException { + log.debug("REST request to save Drug : {}", drug); + if (drug.getId() != null) { + throw new BadRequestAlertException("A new drug cannot already have an ID", ENTITY_NAME, "idexists"); + } + Drug result = drugService.save(drug); + return ResponseEntity.created(new URI("/api/drugs/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) + .body(result); + } + + /** + * {@code PUT /drugs/:id} : Updates an existing drug. + * + * @param id the id of the drug to save. + * @param drug the drug to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated drug, + * or with status {@code 400 (Bad Request)} if the drug is not valid, + * or with status {@code 500 (Internal Server Error)} if the drug couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PutMapping("/drugs/{id}") + public ResponseEntity updateDrug(@PathVariable(value = "id", required = false) final Long id, @Valid @RequestBody Drug drug) + throws URISyntaxException { + log.debug("REST request to update Drug : {}, {}", id, drug); + if (drug.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, drug.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!drugRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Drug result = drugService.save(drug); + return ResponseEntity.ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, drug.getId().toString())) + .body(result); + } + + /** + * {@code PATCH /drugs/:id} : Partial updates given fields of an existing drug, field will ignore if it is null + * + * @param id the id of the drug to save. + * @param drug the drug to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated drug, + * or with status {@code 400 (Bad Request)} if the drug is not valid, + * or with status {@code 404 (Not Found)} if the drug is not found, + * or with status {@code 500 (Internal Server Error)} if the drug couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/drugs/{id}", consumes = { "application/json", "application/merge-patch+json" }) + public ResponseEntity partialUpdateDrug( + @PathVariable(value = "id", required = false) final Long id, + @NotNull @RequestBody Drug drug + ) throws URISyntaxException { + log.debug("REST request to partial update Drug partially : {}, {}", id, drug); + if (drug.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, drug.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!drugRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Optional result = drugService.partialUpdate(drug); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, drug.getId().toString()) + ); + } + + /** + * {@code GET /drugs} : get all the drugs. + * + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of drugs in body. + */ + @GetMapping("/drugs") + public ResponseEntity> getAllDrugs(DrugCriteria criteria) { + log.debug("REST request to get Drugs by criteria: {}", criteria); + return ResponseEntity.ok().body(drugService.findAll(criteria)); + } + + /** + * {@code GET /drugs/count} : count all the drugs. + * + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the count in body. + */ + @GetMapping("/drugs/count") + public ResponseEntity countDrugs(DrugCriteria criteria) { + log.debug("REST request to count Drugs by criteria: {}", criteria); + return ResponseEntity.ok().body(drugQueryService.countByCriteria(criteria)); + } + + /** + * {@code GET /drugs/:id} : get the "id" drug. + * + * @param id the id of the drug to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the drug, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/drugs/{id}") + public ResponseEntity getDrug(@PathVariable Long id) { + log.debug("REST request to get Drug : {}", id); + Optional drug = drugService.findOne(id); + return ResponseUtil.wrapOrNotFound(drug); + } + + /** + * {@code DELETE /drugs/:id} : delete the "id" drug. + * + * @param id the id of the drug to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/drugs/{id}") + public ResponseEntity deleteDrug(@PathVariable Long id) { + log.debug("REST request to delete Drug : {}", id); + drugService.delete(id); + return ResponseEntity.noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); + } + + /** + * {@code SEARCH /drugs/search?query=:query} : search for the drug corresponding + * to the query. + * + * @param query the query of the drug search. + * @return the result of the search. + */ + @GetMapping("/drugs/search") + public ResponseEntity> searchDrugs(@RequestParam String query) { + log.debug("REST request to search for a page of Drugs for query {}", query); + List drugs = drugService.searchDrug(query); + return ResponseEntity.ok().body(drugs); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/EligibilityCriteriaResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/EligibilityCriteriaResource.java new file mode 100644 index 000000000..d44b73f42 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/EligibilityCriteriaResource.java @@ -0,0 +1,221 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.EligibilityCriteria; +import org.mskcc.oncokb.curation.repository.EligibilityCriteriaRepository; +import org.mskcc.oncokb.curation.service.EligibilityCriteriaQueryService; +import org.mskcc.oncokb.curation.service.EligibilityCriteriaService; +import org.mskcc.oncokb.curation.service.criteria.EligibilityCriteriaCriteria; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.PaginationUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing {@link org.mskcc.oncokb.curation.domain.EligibilityCriteria}. + */ +@RestController +@RequestMapping("/api") +public class EligibilityCriteriaResource { + + private final Logger log = LoggerFactory.getLogger(EligibilityCriteriaResource.class); + + private static final String ENTITY_NAME = "eligibilityCriteria"; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final EligibilityCriteriaService eligibilityCriteriaService; + + private final EligibilityCriteriaRepository eligibilityCriteriaRepository; + + private final EligibilityCriteriaQueryService eligibilityCriteriaQueryService; + + public EligibilityCriteriaResource( + EligibilityCriteriaService eligibilityCriteriaService, + EligibilityCriteriaRepository eligibilityCriteriaRepository, + EligibilityCriteriaQueryService eligibilityCriteriaQueryService + ) { + this.eligibilityCriteriaService = eligibilityCriteriaService; + this.eligibilityCriteriaRepository = eligibilityCriteriaRepository; + this.eligibilityCriteriaQueryService = eligibilityCriteriaQueryService; + } + + /** + * {@code POST /eligibility-criteria} : Create a new eligibilityCriteria. + * + * @param eligibilityCriteria the eligibilityCriteria to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new eligibilityCriteria, or with status {@code 400 (Bad Request)} if the eligibilityCriteria has already an ID. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PostMapping("/eligibility-criteria") + public ResponseEntity createEligibilityCriteria(@Valid @RequestBody EligibilityCriteria eligibilityCriteria) + throws URISyntaxException { + log.debug("REST request to save EligibilityCriteria : {}", eligibilityCriteria); + if (eligibilityCriteria.getId() != null) { + throw new BadRequestAlertException("A new eligibilityCriteria cannot already have an ID", ENTITY_NAME, "idexists"); + } + EligibilityCriteria result = eligibilityCriteriaService.save(eligibilityCriteria); + return ResponseEntity.created(new URI("/api/eligibility-criteria/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) + .body(result); + } + + /** + * {@code PUT /eligibility-criteria/:id} : Updates an existing eligibilityCriteria. + * + * @param id the id of the eligibilityCriteria to save. + * @param eligibilityCriteria the eligibilityCriteria to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated eligibilityCriteria, + * or with status {@code 400 (Bad Request)} if the eligibilityCriteria is not valid, + * or with status {@code 500 (Internal Server Error)} if the eligibilityCriteria couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PutMapping("/eligibility-criteria/{id}") + public ResponseEntity updateEligibilityCriteria( + @PathVariable(value = "id", required = false) final Long id, + @Valid @RequestBody EligibilityCriteria eligibilityCriteria + ) throws URISyntaxException { + log.debug("REST request to update EligibilityCriteria : {}, {}", id, eligibilityCriteria); + if (eligibilityCriteria.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, eligibilityCriteria.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!eligibilityCriteriaRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + EligibilityCriteria result = eligibilityCriteriaService.save(eligibilityCriteria); + return ResponseEntity.ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, eligibilityCriteria.getId().toString())) + .body(result); + } + + /** + * {@code PATCH /eligibility-criteria/:id} : Partial updates given fields of an existing eligibilityCriteria, field will ignore if it is null + * + * @param id the id of the eligibilityCriteria to save. + * @param eligibilityCriteria the eligibilityCriteria to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated eligibilityCriteria, + * or with status {@code 400 (Bad Request)} if the eligibilityCriteria is not valid, + * or with status {@code 404 (Not Found)} if the eligibilityCriteria is not found, + * or with status {@code 500 (Internal Server Error)} if the eligibilityCriteria couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/eligibility-criteria/{id}", consumes = { "application/json", "application/merge-patch+json" }) + public ResponseEntity partialUpdateEligibilityCriteria( + @PathVariable(value = "id", required = false) final Long id, + @NotNull @RequestBody EligibilityCriteria eligibilityCriteria + ) throws URISyntaxException { + log.debug("REST request to partial update EligibilityCriteria partially : {}, {}", id, eligibilityCriteria); + if (eligibilityCriteria.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, eligibilityCriteria.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!eligibilityCriteriaRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Optional result = eligibilityCriteriaService.partialUpdate(eligibilityCriteria); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, eligibilityCriteria.getId().toString()) + ); + } + + /** + * {@code GET /eligibility-criteria} : get all the eligibilityCriteria. + * + * @param pageable the pagination information. + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of eligibilityCriteria in body. + */ + @GetMapping("/eligibility-criteria") + public ResponseEntity> getAllEligibilityCriteria(EligibilityCriteriaCriteria criteria, Pageable pageable) { + log.debug("REST request to get EligibilityCriteria by criteria: {}", criteria); + Page page = eligibilityCriteriaQueryService.findByCriteria(criteria, pageable); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(page.getContent()); + } + + /** + * {@code GET /eligibility-criteria/count} : count all the eligibilityCriteria. + * + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the count in body. + */ + @GetMapping("/eligibility-criteria/count") + public ResponseEntity countEligibilityCriteria(EligibilityCriteriaCriteria criteria) { + log.debug("REST request to count EligibilityCriteria by criteria: {}", criteria); + return ResponseEntity.ok().body(eligibilityCriteriaQueryService.countByCriteria(criteria)); + } + + /** + * {@code GET /eligibility-criteria/:id} : get the "id" eligibilityCriteria. + * + * @param id the id of the eligibilityCriteria to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the eligibilityCriteria, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/eligibility-criteria/{id}") + public ResponseEntity getEligibilityCriteria(@PathVariable Long id) { + log.debug("REST request to get EligibilityCriteria : {}", id); + Optional eligibilityCriteria = eligibilityCriteriaService.findOne(id); + return ResponseUtil.wrapOrNotFound(eligibilityCriteria); + } + + /** + * {@code DELETE /eligibility-criteria/:id} : delete the "id" eligibilityCriteria. + * + * @param id the id of the eligibilityCriteria to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/eligibility-criteria/{id}") + public ResponseEntity deleteEligibilityCriteria(@PathVariable Long id) { + log.debug("REST request to delete EligibilityCriteria : {}", id); + eligibilityCriteriaService.delete(id); + return ResponseEntity.noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); + } + + /** + * {@code SEARCH /eligibility-criteria/search?query=:query} : search for the EligibilityCriteria corresponding + * to the query. + * + * @param query the query of the EligibilityCriteria search. + * @param pageable the pagination information. + * @return the result of the search. + */ + @GetMapping("/eligibility-criteria/search") + public ResponseEntity> searchEligibilityCriteria(@RequestParam String query, Pageable pageable) { + log.debug("REST request to search for a page of EligibilityCriteria for query {}", query); + // TODO: implement the search + Page page = new PageImpl<>(new ArrayList<>()); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(page.getContent()); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/EnsemblGeneController.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/EnsemblGeneController.java new file mode 100644 index 000000000..5c0a1d79d --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/EnsemblGeneController.java @@ -0,0 +1,37 @@ +package org.mskcc.oncokb.curation.web.rest; + +import java.util.Optional; +import org.genome_nexus.ApiException; +import org.mskcc.oncokb.curation.domain.EnsemblGene; +import org.mskcc.oncokb.curation.domain.enumeration.ReferenceGenome; +import org.mskcc.oncokb.curation.service.*; +import org.mskcc.oncokb.curation.web.rest.model.AddEnsemblGeneBody; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/api") +public class EnsemblGeneController { + + private final Logger log = LoggerFactory.getLogger(EnsemblGeneController.class); + + private final MainService mainService; + + public EnsemblGeneController(MainService mainService) { + this.mainService = mainService; + } + + @PostMapping("/add-ensembl-gene") + public ResponseEntity addEnsemblGene(@RequestBody AddEnsemblGeneBody body) throws ApiException { + Optional savedEnsemblGeneOptional = mainService.createEnsemblGene( + ReferenceGenome.valueOf(body.getReferenceGenome()), + body.getEnsemblGeneId(), + body.getEntrezGeneId(), + body.getCanonical() + ); + return new ResponseEntity<>(savedEnsemblGeneOptional.orElseThrow(), HttpStatus.OK); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/EnsemblGeneResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/EnsemblGeneResource.java new file mode 100644 index 000000000..f4a737a74 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/EnsemblGeneResource.java @@ -0,0 +1,219 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.EnsemblGene; +import org.mskcc.oncokb.curation.domain.FdaSubmission; +import org.mskcc.oncokb.curation.repository.EnsemblGeneRepository; +import org.mskcc.oncokb.curation.service.EnsemblGeneQueryService; +import org.mskcc.oncokb.curation.service.EnsemblGeneService; +import org.mskcc.oncokb.curation.service.criteria.EnsemblGeneCriteria; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.PaginationUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing {@link org.mskcc.oncokb.curation.domain.EnsemblGene}. + */ +@RestController +@RequestMapping("/api") +public class EnsemblGeneResource { + + private final Logger log = LoggerFactory.getLogger(EnsemblGeneResource.class); + + private static final String ENTITY_NAME = "ensemblGene"; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final EnsemblGeneService ensemblGeneService; + + private final EnsemblGeneRepository ensemblGeneRepository; + + private final EnsemblGeneQueryService ensemblGeneQueryService; + + public EnsemblGeneResource( + EnsemblGeneService ensemblGeneService, + EnsemblGeneRepository ensemblGeneRepository, + EnsemblGeneQueryService ensemblGeneQueryService + ) { + this.ensemblGeneService = ensemblGeneService; + this.ensemblGeneRepository = ensemblGeneRepository; + this.ensemblGeneQueryService = ensemblGeneQueryService; + } + + /** + * {@code POST /ensembl-genes} : Create a new ensemblGene. + * + * @param ensemblGene the ensemblGene to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new ensemblGene, or with status {@code 400 (Bad Request)} if the ensemblGene has already an ID. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PostMapping("/ensembl-genes") + public ResponseEntity createEnsemblGene(@Valid @RequestBody EnsemblGene ensemblGene) throws URISyntaxException { + log.debug("REST request to save EnsemblGene : {}", ensemblGene); + if (ensemblGene.getId() != null) { + throw new BadRequestAlertException("A new ensemblGene cannot already have an ID", ENTITY_NAME, "idexists"); + } + EnsemblGene result = ensemblGeneService.save(ensemblGene); + return ResponseEntity.created(new URI("/api/ensembl-genes/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) + .body(result); + } + + /** + * {@code PUT /ensembl-genes/:id} : Updates an existing ensemblGene. + * + * @param id the id of the ensemblGene to save. + * @param ensemblGene the ensemblGene to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated ensemblGene, + * or with status {@code 400 (Bad Request)} if the ensemblGene is not valid, + * or with status {@code 500 (Internal Server Error)} if the ensemblGene couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PutMapping("/ensembl-genes/{id}") + public ResponseEntity updateEnsemblGene( + @PathVariable(value = "id", required = false) final Long id, + @Valid @RequestBody EnsemblGene ensemblGene + ) throws URISyntaxException { + log.debug("REST request to update EnsemblGene : {}, {}", id, ensemblGene); + if (ensemblGene.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, ensemblGene.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!ensemblGeneRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + EnsemblGene result = ensemblGeneService.save(ensemblGene); + return ResponseEntity.ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, ensemblGene.getId().toString())) + .body(result); + } + + /** + * {@code PATCH /ensembl-genes/:id} : Partial updates given fields of an existing ensemblGene, field will ignore if it is null + * + * @param id the id of the ensemblGene to save. + * @param ensemblGene the ensemblGene to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated ensemblGene, + * or with status {@code 400 (Bad Request)} if the ensemblGene is not valid, + * or with status {@code 404 (Not Found)} if the ensemblGene is not found, + * or with status {@code 500 (Internal Server Error)} if the ensemblGene couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/ensembl-genes/{id}", consumes = { "application/json", "application/merge-patch+json" }) + public ResponseEntity partialUpdateEnsemblGene( + @PathVariable(value = "id", required = false) final Long id, + @NotNull @RequestBody EnsemblGene ensemblGene + ) throws URISyntaxException { + log.debug("REST request to partial update EnsemblGene partially : {}, {}", id, ensemblGene); + if (ensemblGene.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, ensemblGene.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!ensemblGeneRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Optional result = ensemblGeneService.partialUpdate(ensemblGene); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, ensemblGene.getId().toString()) + ); + } + + /** + * {@code GET /ensembl-genes} : get all the ensemblGenes. + * + * @param pageable the pagination information. + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of ensemblGenes in body. + */ + @GetMapping("/ensembl-genes") + public ResponseEntity> getAllEnsemblGenes(EnsemblGeneCriteria criteria, Pageable pageable) { + log.debug("REST request to get EnsemblGenes by criteria: {}", criteria); + Page page = ensemblGeneQueryService.findByCriteria(criteria, pageable); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(page.getContent()); + } + + /** + * {@code GET /ensembl-genes/count} : count all the ensemblGenes. + * + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the count in body. + */ + @GetMapping("/ensembl-genes/count") + public ResponseEntity countEnsemblGenes(EnsemblGeneCriteria criteria) { + log.debug("REST request to count EnsemblGenes by criteria: {}", criteria); + return ResponseEntity.ok().body(ensemblGeneQueryService.countByCriteria(criteria)); + } + + /** + * {@code GET /ensembl-genes/:id} : get the "id" ensemblGene. + * + * @param id the id of the ensemblGene to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the ensemblGene, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/ensembl-genes/{id}") + public ResponseEntity getEnsemblGene(@PathVariable Long id) { + log.debug("REST request to get EnsemblGene : {}", id); + Optional ensemblGene = ensemblGeneService.findOne(id); + return ResponseUtil.wrapOrNotFound(ensemblGene); + } + + /** + * {@code DELETE /ensembl-genes/:id} : delete the "id" ensemblGene. + * + * @param id the id of the ensemblGene to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/ensembl-genes/{id}") + public ResponseEntity deleteEnsemblGene(@PathVariable Long id) { + log.debug("REST request to delete EnsemblGene : {}", id); + ensemblGeneService.delete(id); + return ResponseEntity.noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); + } + + /** + * {@code SEARCH /ensembl-genes/search?query=:query} : search for the EnsemblGene corresponding + * to the query. + * + * @param query the query of the EnsemblGene search. + * @param pageable the pagination information. + * @return the result of the search. + */ + @GetMapping("/ensembl-genes/search") + public ResponseEntity> searchEnsemblGenes(@RequestParam String query, Pageable pageable) { + log.debug("REST request to search for a page of FdaSubmissions for query {}", query); + Page page = ensemblGeneQueryService.findBySearchQuery(query, pageable); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(page.getContent()); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/EvidenceResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/EvidenceResource.java new file mode 100644 index 000000000..1109d24db --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/EvidenceResource.java @@ -0,0 +1,221 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.Evidence; +import org.mskcc.oncokb.curation.repository.EvidenceRepository; +import org.mskcc.oncokb.curation.service.EvidenceQueryService; +import org.mskcc.oncokb.curation.service.EvidenceService; +import org.mskcc.oncokb.curation.service.criteria.EvidenceCriteria; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.PaginationUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing {@link org.mskcc.oncokb.curation.domain.Evidence}. + */ +@RestController +@RequestMapping("/api") +public class EvidenceResource { + + private final Logger log = LoggerFactory.getLogger(EvidenceResource.class); + + private static final String ENTITY_NAME = "evidence"; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final EvidenceService evidenceService; + + private final EvidenceRepository evidenceRepository; + + private final EvidenceQueryService evidenceQueryService; + + public EvidenceResource( + EvidenceService evidenceService, + EvidenceRepository evidenceRepository, + EvidenceQueryService evidenceQueryService + ) { + this.evidenceService = evidenceService; + this.evidenceRepository = evidenceRepository; + this.evidenceQueryService = evidenceQueryService; + } + + /** + * {@code POST /evidences} : Create a new evidence. + * + * @param evidence the evidence to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new evidence, or with status {@code 400 (Bad Request)} if the evidence has already an ID. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PostMapping("/evidences") + public ResponseEntity createEvidence(@Valid @RequestBody Evidence evidence) throws URISyntaxException { + log.debug("REST request to save Evidence : {}", evidence); + if (evidence.getId() != null) { + throw new BadRequestAlertException("A new evidence cannot already have an ID", ENTITY_NAME, "idexists"); + } + Evidence result = evidenceService.save(evidence); + return ResponseEntity.created(new URI("/api/evidences/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) + .body(result); + } + + /** + * {@code PUT /evidences/:id} : Updates an existing evidence. + * + * @param id the id of the evidence to save. + * @param evidence the evidence to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated evidence, + * or with status {@code 400 (Bad Request)} if the evidence is not valid, + * or with status {@code 500 (Internal Server Error)} if the evidence couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PutMapping("/evidences/{id}") + public ResponseEntity updateEvidence( + @PathVariable(value = "id", required = false) final Long id, + @Valid @RequestBody Evidence evidence + ) throws URISyntaxException { + log.debug("REST request to update Evidence : {}, {}", id, evidence); + if (evidence.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, evidence.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!evidenceRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Evidence result = evidenceService.save(evidence); + return ResponseEntity.ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, evidence.getId().toString())) + .body(result); + } + + /** + * {@code PATCH /evidences/:id} : Partial updates given fields of an existing evidence, field will ignore if it is null + * + * @param id the id of the evidence to save. + * @param evidence the evidence to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated evidence, + * or with status {@code 400 (Bad Request)} if the evidence is not valid, + * or with status {@code 404 (Not Found)} if the evidence is not found, + * or with status {@code 500 (Internal Server Error)} if the evidence couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/evidences/{id}", consumes = { "application/json", "application/merge-patch+json" }) + public ResponseEntity partialUpdateEvidence( + @PathVariable(value = "id", required = false) final Long id, + @NotNull @RequestBody Evidence evidence + ) throws URISyntaxException { + log.debug("REST request to partial update Evidence partially : {}, {}", id, evidence); + if (evidence.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, evidence.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!evidenceRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Optional result = evidenceService.partialUpdate(evidence); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, evidence.getId().toString()) + ); + } + + /** + * {@code GET /evidences} : get all the evidences. + * + * @param pageable the pagination information. + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of evidences in body. + */ + @GetMapping("/evidences") + public ResponseEntity> getAllEvidences(EvidenceCriteria criteria, Pageable pageable) { + log.debug("REST request to get Evidences by criteria: {}", criteria); + Page page = evidenceQueryService.findByCriteria(criteria, pageable); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(page.getContent()); + } + + /** + * {@code GET /evidences/count} : count all the evidences. + * + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the count in body. + */ + @GetMapping("/evidences/count") + public ResponseEntity countEvidences(EvidenceCriteria criteria) { + log.debug("REST request to count Evidences by criteria: {}", criteria); + return ResponseEntity.ok().body(evidenceQueryService.countByCriteria(criteria)); + } + + /** + * {@code GET /evidences/:id} : get the "id" evidence. + * + * @param id the id of the evidence to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the evidence, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/evidences/{id}") + public ResponseEntity getEvidence(@PathVariable Long id) { + log.debug("REST request to get Evidence : {}", id); + Optional evidence = evidenceService.findOne(id); + return ResponseUtil.wrapOrNotFound(evidence); + } + + /** + * {@code DELETE /evidences/:id} : delete the "id" evidence. + * + * @param id the id of the evidence to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/evidences/{id}") + public ResponseEntity deleteEvidence(@PathVariable Long id) { + log.debug("REST request to delete Evidence : {}", id); + evidenceService.delete(id); + return ResponseEntity.noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); + } + + /** + * {@code SEARCH /evidences/search?query=:query} : search for the Evidence corresponding + * to the query. + * + * @param query the query of the Evidence search. + * @param pageable the pagination information. + * @return the result of the search. + */ + @GetMapping("/evidences/search") + public ResponseEntity> searchEvidences(@RequestParam String query, Pageable pageable) { + log.debug("REST request to search for a page of Evidences for query {}", query); + // TODO: implement the search + Page page = new PageImpl<>(new ArrayList<>()); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(page.getContent()); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/FdaDrugResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/FdaDrugResource.java new file mode 100644 index 000000000..404a75078 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/FdaDrugResource.java @@ -0,0 +1,216 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.FdaDrug; +import org.mskcc.oncokb.curation.repository.FdaDrugRepository; +import org.mskcc.oncokb.curation.service.FdaDrugQueryService; +import org.mskcc.oncokb.curation.service.FdaDrugService; +import org.mskcc.oncokb.curation.service.criteria.FdaDrugCriteria; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.PaginationUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing {@link org.mskcc.oncokb.curation.domain.FdaDrug}. + */ +@RestController +@RequestMapping("/api") +public class FdaDrugResource { + + private final Logger log = LoggerFactory.getLogger(FdaDrugResource.class); + + private static final String ENTITY_NAME = "fdaDrug"; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final FdaDrugService fdaDrugService; + + private final FdaDrugRepository fdaDrugRepository; + + private final FdaDrugQueryService fdaDrugQueryService; + + public FdaDrugResource(FdaDrugService fdaDrugService, FdaDrugRepository fdaDrugRepository, FdaDrugQueryService fdaDrugQueryService) { + this.fdaDrugService = fdaDrugService; + this.fdaDrugRepository = fdaDrugRepository; + this.fdaDrugQueryService = fdaDrugQueryService; + } + + /** + * {@code POST /fda-drugs} : Create a new fdaDrug. + * + * @param fdaDrug the fdaDrug to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new fdaDrug, or with status {@code 400 (Bad Request)} if the fdaDrug has already an ID. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PostMapping("/fda-drugs") + public ResponseEntity createFdaDrug(@Valid @RequestBody FdaDrug fdaDrug) throws URISyntaxException { + log.debug("REST request to save FdaDrug : {}", fdaDrug); + if (fdaDrug.getId() != null) { + throw new BadRequestAlertException("A new fdaDrug cannot already have an ID", ENTITY_NAME, "idexists"); + } + FdaDrug result = fdaDrugService.save(fdaDrug); + return ResponseEntity.created(new URI("/api/fda-drugs/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) + .body(result); + } + + /** + * {@code PUT /fda-drugs/:id} : Updates an existing fdaDrug. + * + * @param id the id of the fdaDrug to save. + * @param fdaDrug the fdaDrug to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated fdaDrug, + * or with status {@code 400 (Bad Request)} if the fdaDrug is not valid, + * or with status {@code 500 (Internal Server Error)} if the fdaDrug couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PutMapping("/fda-drugs/{id}") + public ResponseEntity updateFdaDrug( + @PathVariable(value = "id", required = false) final Long id, + @Valid @RequestBody FdaDrug fdaDrug + ) throws URISyntaxException { + log.debug("REST request to update FdaDrug : {}, {}", id, fdaDrug); + if (fdaDrug.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, fdaDrug.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!fdaDrugRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + FdaDrug result = fdaDrugService.save(fdaDrug); + return ResponseEntity.ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, fdaDrug.getId().toString())) + .body(result); + } + + /** + * {@code PATCH /fda-drugs/:id} : Partial updates given fields of an existing fdaDrug, field will ignore if it is null + * + * @param id the id of the fdaDrug to save. + * @param fdaDrug the fdaDrug to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated fdaDrug, + * or with status {@code 400 (Bad Request)} if the fdaDrug is not valid, + * or with status {@code 404 (Not Found)} if the fdaDrug is not found, + * or with status {@code 500 (Internal Server Error)} if the fdaDrug couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/fda-drugs/{id}", consumes = { "application/json", "application/merge-patch+json" }) + public ResponseEntity partialUpdateFdaDrug( + @PathVariable(value = "id", required = false) final Long id, + @NotNull @RequestBody FdaDrug fdaDrug + ) throws URISyntaxException { + log.debug("REST request to partial update FdaDrug partially : {}, {}", id, fdaDrug); + if (fdaDrug.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, fdaDrug.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!fdaDrugRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Optional result = fdaDrugService.partialUpdate(fdaDrug); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, fdaDrug.getId().toString()) + ); + } + + /** + * {@code GET /fda-drugs} : get all the fdaDrugs. + * + * @param pageable the pagination information. + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of fdaDrugs in body. + */ + @GetMapping("/fda-drugs") + public ResponseEntity> getAllFdaDrugs(FdaDrugCriteria criteria, Pageable pageable) { + log.debug("REST request to get FdaDrugs by criteria: {}", criteria); + Page page = fdaDrugQueryService.findByCriteria(criteria, pageable); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(page.getContent()); + } + + /** + * {@code GET /fda-drugs/count} : count all the fdaDrugs. + * + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the count in body. + */ + @GetMapping("/fda-drugs/count") + public ResponseEntity countFdaDrugs(FdaDrugCriteria criteria) { + log.debug("REST request to count FdaDrugs by criteria: {}", criteria); + return ResponseEntity.ok().body(fdaDrugQueryService.countByCriteria(criteria)); + } + + /** + * {@code GET /fda-drugs/:id} : get the "id" fdaDrug. + * + * @param id the id of the fdaDrug to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the fdaDrug, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/fda-drugs/{id}") + public ResponseEntity getFdaDrug(@PathVariable Long id) { + log.debug("REST request to get FdaDrug : {}", id); + Optional fdaDrug = fdaDrugService.findOne(id); + return ResponseUtil.wrapOrNotFound(fdaDrug); + } + + /** + * {@code DELETE /fda-drugs/:id} : delete the "id" fdaDrug. + * + * @param id the id of the fdaDrug to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/fda-drugs/{id}") + public ResponseEntity deleteFdaDrug(@PathVariable Long id) { + log.debug("REST request to delete FdaDrug : {}", id); + fdaDrugService.delete(id); + return ResponseEntity.noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); + } + + /** + * {@code SEARCH /fda-drugs/search?query=:query} : search for the FdaDrug corresponding + * to the query. + * + * @param query the query of the FdaDrug search. + * @param pageable the pagination information. + * @return the result of the search. + */ + @GetMapping("/fda-drugs/search") + public ResponseEntity> searchFdaDrugs(@RequestParam String query, Pageable pageable) { + log.debug("REST request to search for a page of FdaDrugs for query {}", query); + // TODO: implement the search + Page page = new PageImpl<>(new ArrayList<>()); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(page.getContent()); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/FdaSubmissionResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/FdaSubmissionResource.java new file mode 100644 index 000000000..658e5b57b --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/FdaSubmissionResource.java @@ -0,0 +1,238 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import org.apache.commons.lang3.StringUtils; +import org.mskcc.oncokb.curation.domain.FdaSubmission; +import org.mskcc.oncokb.curation.repository.FdaSubmissionRepository; +import org.mskcc.oncokb.curation.service.FdaSubmissionQueryService; +import org.mskcc.oncokb.curation.service.FdaSubmissionService; +import org.mskcc.oncokb.curation.service.criteria.FdaSubmissionCriteria; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.PaginationUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing {@link org.mskcc.oncokb.curation.domain.FdaSubmission}. + */ +@RestController +@RequestMapping("/api") +public class FdaSubmissionResource { + + private final Logger log = LoggerFactory.getLogger(FdaSubmissionResource.class); + + private static final String ENTITY_NAME = "fdaSubmission"; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final FdaSubmissionService fdaSubmissionService; + + private final FdaSubmissionRepository fdaSubmissionRepository; + + private final FdaSubmissionQueryService fdaSubmissionQueryService; + + public FdaSubmissionResource( + FdaSubmissionService fdaSubmissionService, + FdaSubmissionRepository fdaSubmissionRepository, + FdaSubmissionQueryService fdaSubmissionQueryService + ) { + this.fdaSubmissionService = fdaSubmissionService; + this.fdaSubmissionRepository = fdaSubmissionRepository; + this.fdaSubmissionQueryService = fdaSubmissionQueryService; + } + + /** + * {@code POST /fda-submissions} : Create a new fdaSubmission. + * + * @param fdaSubmission the fdaSubmission to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new fdaSubmission, or with status {@code 400 (Bad Request)} if the fdaSubmission has already an ID. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PostMapping("/fda-submissions") + public ResponseEntity createFdaSubmission(@Valid @RequestBody FdaSubmission fdaSubmission) throws URISyntaxException { + log.debug("REST request to save FdaSubmission : {}", fdaSubmission); + if (fdaSubmission.getId() != null) { + throw new BadRequestAlertException("A new fdaSubmission cannot already have an ID", ENTITY_NAME, "idexists"); + } else if (!fdaSubmissionService.isUnique(fdaSubmission)) { + throw new BadRequestAlertException("Duplicate fdaSubmission", ENTITY_NAME, "duplicate"); + } + + FdaSubmission result = fdaSubmissionService.save(fdaSubmission); + return ResponseEntity.created(new URI("/api/fda-submissions/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) + .body(result); + } + + /** + * {@code PUT /fda-submissions/:id} : Updates an existing fdaSubmission. + * + * @param id the id of the fdaSubmission to save. + * @param fdaSubmission the fdaSubmission to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated fdaSubmission, + * or with status {@code 400 (Bad Request)} if the fdaSubmission is not valid, + * or with status {@code 500 (Internal Server Error)} if the fdaSubmission couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PutMapping("/fda-submissions/{id}") + public ResponseEntity updateFdaSubmission( + @PathVariable(value = "id", required = false) final Long id, + @Valid @RequestBody FdaSubmission fdaSubmission + ) throws URISyntaxException { + log.debug("REST request to update FdaSubmission : {}, {}", id, fdaSubmission); + if (fdaSubmission.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, fdaSubmission.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!fdaSubmissionRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + FdaSubmission result = fdaSubmissionService.save(fdaSubmission); + return ResponseEntity.ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, fdaSubmission.getId().toString())) + .body(result); + } + + /** + * {@code PATCH /fda-submissions/:id} : Partial updates given fields of an existing fdaSubmission, field will ignore if it is null + * + * @param id the id of the fdaSubmission to save. + * @param fdaSubmission the fdaSubmission to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated fdaSubmission, + * or with status {@code 400 (Bad Request)} if the fdaSubmission is not valid, + * or with status {@code 404 (Not Found)} if the fdaSubmission is not found, + * or with status {@code 500 (Internal Server Error)} if the fdaSubmission couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/fda-submissions/{id}", consumes = { "application/json", "application/merge-patch+json" }) + public ResponseEntity partialUpdateFdaSubmission( + @PathVariable(value = "id", required = false) final Long id, + @NotNull @RequestBody FdaSubmission fdaSubmission + ) throws URISyntaxException { + log.debug("REST request to partial update FdaSubmission partially : {}, {}", id, fdaSubmission); + if (fdaSubmission.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, fdaSubmission.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!fdaSubmissionRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Optional result = fdaSubmissionService.partialUpdate(fdaSubmission); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, fdaSubmission.getId().toString()) + ); + } + + /** + * {@code GET /fda-submissions} : get all the fdaSubmissions. + * + * @param pageable the pagination information. + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of fdaSubmissions in body. + */ + @GetMapping("/fda-submissions") + public ResponseEntity> getAllFdaSubmissions(FdaSubmissionCriteria criteria, Pageable pageable) { + log.debug("REST request to get FdaSubmissions by criteria: {}", criteria); + Page page = fdaSubmissionQueryService.findByCriteria(criteria, pageable); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(page.getContent()); + } + + /** + * {@code GET /fda-submissions/count} : count all the fdaSubmissions. + * + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the count in body. + */ + @GetMapping("/fda-submissions/count") + public ResponseEntity countFdaSubmissions(FdaSubmissionCriteria criteria) { + log.debug("REST request to count FdaSubmissions by criteria: {}", criteria); + return ResponseEntity.ok().body(fdaSubmissionQueryService.countByCriteria(criteria)); + } + + /** + * {@code GET /fda-submissions/:id} : get the "id" fdaSubmission. + * + * @param id the id of the fdaSubmission to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the fdaSubmission, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/fda-submissions/{id}") + public ResponseEntity getFdaSubmission(@PathVariable Long id) { + log.debug("REST request to get FdaSubmission : {}", id); + Optional fdaSubmission = fdaSubmissionService.findOne(id); + return ResponseUtil.wrapOrNotFound(fdaSubmission); + } + + @GetMapping("/fda-submissions/lookup") + public ResponseEntity getFdaSubmissionByNumber( + @RequestParam(value = "number", required = true) String number, + @RequestParam(value = "supplementNumber", required = false) String supplementNumber + ) { + if (StringUtils.isEmpty(supplementNumber)) { + supplementNumber = ""; + } + return ResponseUtil.wrapOrNotFound(fdaSubmissionService.findOrFetchFdaSubmissionByNumber(number, supplementNumber, false)); + } + + @GetMapping("/fda-submissions/companion-diagnostic-device/{id}") + public ResponseEntity> findFdaSubmissionsByCompanionDiagnosticDevice(@PathVariable Long id) { + List fdaSubmissions = fdaSubmissionService.findByCompanionDiagnosticDevice(id); + return ResponseEntity.ok().body(fdaSubmissions); + } + + /** + * {@code DELETE /fda-submissions/:id} : delete the "id" fdaSubmission. + * + * @param id the id of the fdaSubmission to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/fda-submissions/{id}") + public ResponseEntity deleteFdaSubmission(@PathVariable Long id) { + log.debug("REST request to delete FdaSubmission : {}", id); + fdaSubmissionService.delete(id); + return ResponseEntity.noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); + } + + /** + * {@code SEARCH /fda-submissions/search?query=:query} : search for the fdaSubmission corresponding + * to the query. + * + * @param query the query of the fdaSubmission search. + * @param pageable the pagination information. + * @return the result of the search. + */ + @GetMapping("/fda-submissions/search") + public ResponseEntity> searchFdaSubmissions(@RequestParam String query, Pageable pageable) { + log.debug("REST request to search for a page of FdaSubmissions for query {}", query); + Page page = fdaSubmissionQueryService.findBySearchQuery(query, pageable); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(page.getContent()); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/FdaSubmissionTypeResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/FdaSubmissionTypeResource.java new file mode 100644 index 000000000..998003fff --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/FdaSubmissionTypeResource.java @@ -0,0 +1,175 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.FdaSubmissionType; +import org.mskcc.oncokb.curation.repository.FdaSubmissionTypeRepository; +import org.mskcc.oncokb.curation.service.FdaSubmissionTypeService; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing {@link org.mskcc.oncokb.curation.domain.FdaSubmissionType}. + */ +@RestController +@RequestMapping("/api") +public class FdaSubmissionTypeResource { + + private final Logger log = LoggerFactory.getLogger(FdaSubmissionTypeResource.class); + + private static final String ENTITY_NAME = "fdaSubmissionType"; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final FdaSubmissionTypeService fdaSubmissionTypeService; + + private final FdaSubmissionTypeRepository fdaSubmissionTypeRepository; + + public FdaSubmissionTypeResource( + FdaSubmissionTypeService fdaSubmissionTypeService, + FdaSubmissionTypeRepository fdaSubmissionTypeRepository + ) { + this.fdaSubmissionTypeService = fdaSubmissionTypeService; + this.fdaSubmissionTypeRepository = fdaSubmissionTypeRepository; + } + + /** + * {@code POST /fda-submission-types} : Create a new fdaSubmissionType. + * + * @param fdaSubmissionType the fdaSubmissionType to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new fdaSubmissionType, or with status {@code 400 (Bad Request)} if the fdaSubmissionType has already an ID. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PostMapping("/fda-submission-types") + public ResponseEntity createFdaSubmissionType(@Valid @RequestBody FdaSubmissionType fdaSubmissionType) + throws URISyntaxException { + log.debug("REST request to save FdaSubmissionType : {}", fdaSubmissionType); + if (fdaSubmissionType.getId() != null) { + throw new BadRequestAlertException("A new fdaSubmissionType cannot already have an ID", ENTITY_NAME, "idexists"); + } + FdaSubmissionType result = fdaSubmissionTypeService.save(fdaSubmissionType); + return ResponseEntity.created(new URI("/api/fda-submission-types/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) + .body(result); + } + + /** + * {@code PUT /fda-submission-types/:id} : Updates an existing fdaSubmissionType. + * + * @param id the id of the fdaSubmissionType to save. + * @param fdaSubmissionType the fdaSubmissionType to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated fdaSubmissionType, + * or with status {@code 400 (Bad Request)} if the fdaSubmissionType is not valid, + * or with status {@code 500 (Internal Server Error)} if the fdaSubmissionType couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PutMapping("/fda-submission-types/{id}") + public ResponseEntity updateFdaSubmissionType( + @PathVariable(value = "id", required = false) final Long id, + @Valid @RequestBody FdaSubmissionType fdaSubmissionType + ) throws URISyntaxException { + log.debug("REST request to update FdaSubmissionType : {}, {}", id, fdaSubmissionType); + if (fdaSubmissionType.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, fdaSubmissionType.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!fdaSubmissionTypeRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + FdaSubmissionType result = fdaSubmissionTypeService.save(fdaSubmissionType); + return ResponseEntity.ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, fdaSubmissionType.getId().toString())) + .body(result); + } + + /** + * {@code PATCH /fda-submission-types/:id} : Partial updates given fields of an existing fdaSubmissionType, field will ignore if it is null + * + * @param id the id of the fdaSubmissionType to save. + * @param fdaSubmissionType the fdaSubmissionType to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated fdaSubmissionType, + * or with status {@code 400 (Bad Request)} if the fdaSubmissionType is not valid, + * or with status {@code 404 (Not Found)} if the fdaSubmissionType is not found, + * or with status {@code 500 (Internal Server Error)} if the fdaSubmissionType couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/fda-submission-types/{id}", consumes = { "application/json", "application/merge-patch+json" }) + public ResponseEntity partialUpdateFdaSubmissionType( + @PathVariable(value = "id", required = false) final Long id, + @NotNull @RequestBody FdaSubmissionType fdaSubmissionType + ) throws URISyntaxException { + log.debug("REST request to partial update FdaSubmissionType partially : {}, {}", id, fdaSubmissionType); + if (fdaSubmissionType.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, fdaSubmissionType.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!fdaSubmissionTypeRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Optional result = fdaSubmissionTypeService.partialUpdate(fdaSubmissionType); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, fdaSubmissionType.getId().toString()) + ); + } + + /** + * {@code GET /fda-submission-types} : get all the fdaSubmissionTypes. + * + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of fdaSubmissionTypes in body. + */ + @GetMapping("/fda-submission-types") + public List getAllFdaSubmissionTypes() { + log.debug("REST request to get all FdaSubmissionTypes"); + return fdaSubmissionTypeService.findAll(); + } + + /** + * {@code GET /fda-submission-types/:id} : get the "id" fdaSubmissionType. + * + * @param id the id of the fdaSubmissionType to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the fdaSubmissionType, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/fda-submission-types/{id}") + public ResponseEntity getFdaSubmissionType(@PathVariable Long id) { + log.debug("REST request to get FdaSubmissionType : {}", id); + Optional fdaSubmissionType = fdaSubmissionTypeService.findOne(id); + return ResponseUtil.wrapOrNotFound(fdaSubmissionType); + } + + /** + * {@code DELETE /fda-submission-types/:id} : delete the "id" fdaSubmissionType. + * + * @param id the id of the fdaSubmissionType to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/fda-submission-types/{id}") + public ResponseEntity deleteFdaSubmissionType(@PathVariable Long id) { + log.debug("REST request to delete FdaSubmissionType : {}", id); + fdaSubmissionTypeService.delete(id); + return ResponseEntity.noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/FlagResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/FlagResource.java new file mode 100644 index 000000000..f6b289912 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/FlagResource.java @@ -0,0 +1,213 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.Article; +import org.mskcc.oncokb.curation.domain.Flag; +import org.mskcc.oncokb.curation.repository.FlagRepository; +import org.mskcc.oncokb.curation.service.FlagQueryService; +import org.mskcc.oncokb.curation.service.FlagService; +import org.mskcc.oncokb.curation.service.criteria.FlagCriteria; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.PaginationUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing {@link org.mskcc.oncokb.curation.domain.Flag}. + */ +@RestController +@RequestMapping("/api") +public class FlagResource { + + private final Logger log = LoggerFactory.getLogger(FlagResource.class); + + private static final String ENTITY_NAME = "flag"; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final FlagService flagService; + + private final FlagRepository flagRepository; + + private final FlagQueryService flagQueryService; + + public FlagResource(FlagService flagService, FlagRepository flagRepository, FlagQueryService flagQueryService) { + this.flagService = flagService; + this.flagRepository = flagRepository; + this.flagQueryService = flagQueryService; + } + + /** + * {@code POST /flags} : Create a new flag. + * + * @param flag the flag to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new flag, or with status {@code 400 (Bad Request)} if the flag has already an ID. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PostMapping("/flags") + public ResponseEntity createFlag(@Valid @RequestBody Flag flag) throws URISyntaxException { + log.debug("REST request to save Flag : {}", flag); + if (flag.getId() != null) { + throw new BadRequestAlertException("A new flag cannot already have an ID", ENTITY_NAME, "idexists"); + } + Flag result = flagService.save(flag); + return ResponseEntity.created(new URI("/api/flags/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) + .body(result); + } + + /** + * {@code PUT /flags/:id} : Updates an existing flag. + * + * @param id the id of the flag to save. + * @param flag the flag to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated flag, + * or with status {@code 400 (Bad Request)} if the flag is not valid, + * or with status {@code 500 (Internal Server Error)} if the flag couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PutMapping("/flags/{id}") + public ResponseEntity updateFlag(@PathVariable(value = "id", required = false) final Long id, @Valid @RequestBody Flag flag) + throws URISyntaxException { + log.debug("REST request to update Flag : {}, {}", id, flag); + if (flag.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, flag.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!flagRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Flag result = flagService.save(flag); + return ResponseEntity.ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, flag.getId().toString())) + .body(result); + } + + /** + * {@code PATCH /flags/:id} : Partial updates given fields of an existing flag, field will ignore if it is null + * + * @param id the id of the flag to save. + * @param flag the flag to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated flag, + * or with status {@code 400 (Bad Request)} if the flag is not valid, + * or with status {@code 404 (Not Found)} if the flag is not found, + * or with status {@code 500 (Internal Server Error)} if the flag couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/flags/{id}", consumes = { "application/json", "application/merge-patch+json" }) + public ResponseEntity partialUpdateFlag( + @PathVariable(value = "id", required = false) final Long id, + @NotNull @RequestBody Flag flag + ) throws URISyntaxException { + log.debug("REST request to partial update Flag partially : {}, {}", id, flag); + if (flag.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, flag.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!flagRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Optional result = flagService.partialUpdate(flag); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, flag.getId().toString()) + ); + } + + /** + * {@code GET /flags} : get all the flags. + * + * @param pageable the pagination information. + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of flags in body. + */ + @GetMapping("/flags") + public ResponseEntity> getAllFlags(FlagCriteria criteria, Pageable pageable) { + log.debug("REST request to get Flags by criteria: {}", criteria); + Page page = flagQueryService.findByCriteria(criteria, pageable); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(page.getContent()); + } + + /** + * {@code GET /flags/count} : count all the flags. + * + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the count in body. + */ + @GetMapping("/flags/count") + public ResponseEntity countFlags(FlagCriteria criteria) { + log.debug("REST request to count Flags by criteria: {}", criteria); + return ResponseEntity.ok().body(flagQueryService.countByCriteria(criteria)); + } + + /** + * {@code GET /flags/:id} : get the "id" flag. + * + * @param id the id of the flag to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the flag, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/flags/{id}") + public ResponseEntity getFlag(@PathVariable Long id) { + log.debug("REST request to get Flag : {}", id); + Optional flag = flagService.findOne(id); + return ResponseUtil.wrapOrNotFound(flag); + } + + /** + * {@code DELETE /flags/:id} : delete the "id" flag. + * + * @param id the id of the flag to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/flags/{id}") + public ResponseEntity deleteFlag(@PathVariable Long id) { + log.debug("REST request to delete Flag : {}", id); + flagService.delete(id); + return ResponseEntity.noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); + } + + /** + * {@code SEARCH /flags/search?query=:query} : search for the flag corresponding + * to the query. + * + * @param query the query of the flag search. + * @param pageable the pagination information. + * @return the result of the search. + */ + @GetMapping("/flags/search") + public ResponseEntity> searchFlags(@RequestParam String query, Pageable pageable) { + log.debug("REST request to search for a page of Flags for query {}", query); + Page page = flagQueryService.findBySearchQuery(query, pageable); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(page.getContent()); + } +} diff --git a/src/main/java/org/mskcc/oncokb/transcript/web/rest/GeneController.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/GeneController.java similarity index 86% rename from src/main/java/org/mskcc/oncokb/transcript/web/rest/GeneController.java rename to src/main/java/org/mskcc/oncokb/curation/web/rest/GeneController.java index 56df54918..9086e8c42 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/web/rest/GeneController.java +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/GeneController.java @@ -1,10 +1,10 @@ -package org.mskcc.oncokb.transcript.web.rest; +package org.mskcc.oncokb.curation.web.rest; import java.util.*; import org.apache.commons.lang3.StringUtils; -import org.mskcc.oncokb.transcript.domain.Gene; -import org.mskcc.oncokb.transcript.repository.GeneRepository; -import org.mskcc.oncokb.transcript.service.GeneService; +import org.mskcc.oncokb.curation.domain.Gene; +import org.mskcc.oncokb.curation.repository.GeneRepository; +import org.mskcc.oncokb.curation.service.GeneService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; @@ -47,7 +47,7 @@ public ResponseEntity> findGenesBySymbols(@RequestBody List bo .forEach(symbol -> { Optional geneOptional = getGeneBySymbol(symbol); if (geneOptional.isPresent()) { - genes.add(geneOptional.get()); + genes.add(geneOptional.orElseThrow()); } }); } @@ -61,7 +61,7 @@ private Optional getGeneBySymbol(String symbol) { } else { gene = geneService.findGeneByHugoSymbol(symbol); if (gene.isEmpty()) { - gene = geneService.findGeneByAlias(symbol); + gene = geneService.findGeneBySynonym(symbol); } } return gene; diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/GeneResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/GeneResource.java new file mode 100644 index 000000000..cb3f3a1f3 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/GeneResource.java @@ -0,0 +1,230 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; +import org.mskcc.oncokb.curation.domain.Gene; +import org.mskcc.oncokb.curation.repository.GeneRepository; +import org.mskcc.oncokb.curation.service.GeneQueryService; +import org.mskcc.oncokb.curation.service.GeneService; +import org.mskcc.oncokb.curation.service.criteria.GeneCriteria; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.PaginationUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing {@link org.mskcc.oncokb.curation.domain.Gene}. + */ +@RestController +@RequestMapping("/api") +public class GeneResource { + + private final Logger log = LoggerFactory.getLogger(GeneResource.class); + + private static final String ENTITY_NAME = "gene"; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final GeneService geneService; + + private final GeneRepository geneRepository; + + private final GeneQueryService geneQueryService; + + public GeneResource(GeneService geneService, GeneRepository geneRepository, GeneQueryService geneQueryService) { + this.geneService = geneService; + this.geneRepository = geneRepository; + this.geneQueryService = geneQueryService; + } + + /** + * {@code POST /genes} : Create a new gene. + * + * @param gene the gene to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new gene, or with status {@code 400 (Bad Request)} if the gene has already an ID. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PostMapping("/genes") + public ResponseEntity createGene(@Valid @RequestBody Gene gene) throws URISyntaxException { + log.debug("REST request to save Gene : {}", gene); + if (gene.getId() != null) { + throw new BadRequestAlertException("A new gene cannot already have an ID", ENTITY_NAME, "idexists"); + } + Gene result = geneService.save(gene); + return ResponseEntity.created(new URI("/api/genes/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) + .body(result); + } + + /** + * {@code PUT /genes/:id} : Updates an existing gene. + * + * @param id the id of the gene to save. + * @param gene the gene to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated gene, + * or with status {@code 400 (Bad Request)} if the gene is not valid, + * or with status {@code 500 (Internal Server Error)} if the gene couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PutMapping("/genes/{id}") + public ResponseEntity updateGene(@PathVariable(value = "id", required = false) final Long id, @Valid @RequestBody Gene gene) + throws URISyntaxException { + log.debug("REST request to update Gene : {}, {}", id, gene); + if (gene.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, gene.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!geneRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Gene result = geneService.save(gene); + return ResponseEntity.ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, gene.getId().toString())) + .body(result); + } + + /** + * {@code PATCH /genes/:id} : Partial updates given fields of an existing gene, field will ignore if it is null + * + * @param id the id of the gene to save. + * @param gene the gene to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated gene, + * or with status {@code 400 (Bad Request)} if the gene is not valid, + * or with status {@code 404 (Not Found)} if the gene is not found, + * or with status {@code 500 (Internal Server Error)} if the gene couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/genes/{id}", consumes = { "application/json", "application/merge-patch+json" }) + public ResponseEntity partialUpdateGene( + @PathVariable(value = "id", required = false) final Long id, + @NotNull @RequestBody Gene gene + ) throws URISyntaxException { + log.debug("REST request to partial update Gene partially : {}, {}", id, gene); + if (gene.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, gene.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!geneRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Optional result = geneService.partialUpdate(gene); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, gene.getId().toString()) + ); + } + + /** + * {@code GET /genes} : get all the genes. + * + * @param pageable the pagination information. + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of genes in body. + */ + @GetMapping("/genes") + public ResponseEntity> getAllGenes(GeneCriteria criteria, Pageable pageable) { + log.debug("REST request to get Genes by criteria: {}", criteria); + Page page = geneQueryService.findByCriteria(criteria, pageable); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok() + .headers(headers) + .body( + geneService.findAllByIdInWithGeneAliasAndEnsemblGenes( + page.getContent().stream().map(Gene::getId).collect(Collectors.toList()) + ) + ); + } + + /** + * {@code GET /genes/count} : count all the genes. + * + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the count in body. + */ + @GetMapping("/genes/count") + public ResponseEntity countGenes(GeneCriteria criteria) { + log.debug("REST request to count Genes by criteria: {}", criteria); + return ResponseEntity.ok().body(geneQueryService.countByCriteria(criteria)); + } + + /** + * {@code GET /genes/:id} : get the "id" gene. + * + * @param id the id of the gene to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the gene, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/genes/{id}") + public ResponseEntity getGene(@PathVariable Long id) { + log.debug("REST request to get Gene : {}", id); + Optional gene = geneService.findOne(id); + return ResponseUtil.wrapOrNotFound(gene); + } + + /** + * {@code DELETE /genes/:id} : delete the "id" gene. + * + * @param id the id of the gene to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/genes/{id}") + public ResponseEntity deleteGene(@PathVariable Long id) { + log.debug("REST request to delete Gene : {}", id); + geneService.delete(id); + return ResponseEntity.noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); + } + + /** + * {@code SEARCH /genes/search?query=:query} : search for the gene corresponding + * to the query. + * + * @param query the query of the gene search. + * @return the result of the search. + */ + @GetMapping("/genes/search") + public ResponseEntity> searchGenes( + @RequestParam String query, + @RequestParam(required = false) Boolean exact, + Pageable pageable + ) { + log.debug("REST request to search for a page of Genes for query {}", query); + if (exact == null) { + exact = false; + } + Page page = geneQueryService.findBySearchQuery(query, exact, pageable); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok() + .headers(headers) + .body( + geneService.findAllByIdInWithGeneAliasAndEnsemblGenes( + page.getContent().stream().map(Gene::getId).collect(Collectors.toList()) + ) + ); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/GenomeFragmentResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/GenomeFragmentResource.java new file mode 100644 index 000000000..c55326f4a --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/GenomeFragmentResource.java @@ -0,0 +1,221 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.GenomeFragment; +import org.mskcc.oncokb.curation.repository.GenomeFragmentRepository; +import org.mskcc.oncokb.curation.service.GenomeFragmentQueryService; +import org.mskcc.oncokb.curation.service.GenomeFragmentService; +import org.mskcc.oncokb.curation.service.criteria.GenomeFragmentCriteria; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.PaginationUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing {@link org.mskcc.oncokb.curation.domain.GenomeFragment}. + */ +@RestController +@RequestMapping("/api") +public class GenomeFragmentResource { + + private final Logger log = LoggerFactory.getLogger(GenomeFragmentResource.class); + + private static final String ENTITY_NAME = "genomeFragment"; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final GenomeFragmentService genomeFragmentService; + + private final GenomeFragmentRepository genomeFragmentRepository; + + private final GenomeFragmentQueryService genomeFragmentQueryService; + + public GenomeFragmentResource( + GenomeFragmentService genomeFragmentService, + GenomeFragmentRepository genomeFragmentRepository, + GenomeFragmentQueryService genomeFragmentQueryService + ) { + this.genomeFragmentService = genomeFragmentService; + this.genomeFragmentRepository = genomeFragmentRepository; + this.genomeFragmentQueryService = genomeFragmentQueryService; + } + + /** + * {@code POST /genome-fragments} : Create a new genomeFragment. + * + * @param genomeFragment the genomeFragment to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new genomeFragment, or with status {@code 400 (Bad Request)} if the genomeFragment has already an ID. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PostMapping("/genome-fragments") + public ResponseEntity createGenomeFragment(@Valid @RequestBody GenomeFragment genomeFragment) + throws URISyntaxException { + log.debug("REST request to save GenomeFragment : {}", genomeFragment); + if (genomeFragment.getId() != null) { + throw new BadRequestAlertException("A new genomeFragment cannot already have an ID", ENTITY_NAME, "idexists"); + } + GenomeFragment result = genomeFragmentService.save(genomeFragment); + return ResponseEntity.created(new URI("/api/genome-fragments/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) + .body(result); + } + + /** + * {@code PUT /genome-fragments/:id} : Updates an existing genomeFragment. + * + * @param id the id of the genomeFragment to save. + * @param genomeFragment the genomeFragment to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated genomeFragment, + * or with status {@code 400 (Bad Request)} if the genomeFragment is not valid, + * or with status {@code 500 (Internal Server Error)} if the genomeFragment couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PutMapping("/genome-fragments/{id}") + public ResponseEntity updateGenomeFragment( + @PathVariable(value = "id", required = false) final Long id, + @Valid @RequestBody GenomeFragment genomeFragment + ) throws URISyntaxException { + log.debug("REST request to update GenomeFragment : {}, {}", id, genomeFragment); + if (genomeFragment.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, genomeFragment.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!genomeFragmentRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + GenomeFragment result = genomeFragmentService.save(genomeFragment); + return ResponseEntity.ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, genomeFragment.getId().toString())) + .body(result); + } + + /** + * {@code PATCH /genome-fragments/:id} : Partial updates given fields of an existing genomeFragment, field will ignore if it is null + * + * @param id the id of the genomeFragment to save. + * @param genomeFragment the genomeFragment to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated genomeFragment, + * or with status {@code 400 (Bad Request)} if the genomeFragment is not valid, + * or with status {@code 404 (Not Found)} if the genomeFragment is not found, + * or with status {@code 500 (Internal Server Error)} if the genomeFragment couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/genome-fragments/{id}", consumes = { "application/json", "application/merge-patch+json" }) + public ResponseEntity partialUpdateGenomeFragment( + @PathVariable(value = "id", required = false) final Long id, + @NotNull @RequestBody GenomeFragment genomeFragment + ) throws URISyntaxException { + log.debug("REST request to partial update GenomeFragment partially : {}, {}", id, genomeFragment); + if (genomeFragment.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, genomeFragment.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!genomeFragmentRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Optional result = genomeFragmentService.partialUpdate(genomeFragment); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, genomeFragment.getId().toString()) + ); + } + + /** + * {@code GET /genome-fragments} : get all the genomeFragments. + * + * @param pageable the pagination information. + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of genomeFragments in body. + */ + @GetMapping("/genome-fragments") + public ResponseEntity> getAllGenomeFragments(GenomeFragmentCriteria criteria, Pageable pageable) { + log.debug("REST request to get GenomeFragments by criteria: {}", criteria); + Page page = genomeFragmentQueryService.findByCriteria(criteria, pageable); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(page.getContent()); + } + + /** + * {@code GET /genome-fragments/count} : count all the genomeFragments. + * + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the count in body. + */ + @GetMapping("/genome-fragments/count") + public ResponseEntity countGenomeFragments(GenomeFragmentCriteria criteria) { + log.debug("REST request to count GenomeFragments by criteria: {}", criteria); + return ResponseEntity.ok().body(genomeFragmentQueryService.countByCriteria(criteria)); + } + + /** + * {@code GET /genome-fragments/:id} : get the "id" genomeFragment. + * + * @param id the id of the genomeFragment to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the genomeFragment, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/genome-fragments/{id}") + public ResponseEntity getGenomeFragment(@PathVariable Long id) { + log.debug("REST request to get GenomeFragment : {}", id); + Optional genomeFragment = genomeFragmentService.findOne(id); + return ResponseUtil.wrapOrNotFound(genomeFragment); + } + + /** + * {@code DELETE /genome-fragments/:id} : delete the "id" genomeFragment. + * + * @param id the id of the genomeFragment to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/genome-fragments/{id}") + public ResponseEntity deleteGenomeFragment(@PathVariable Long id) { + log.debug("REST request to delete GenomeFragment : {}", id); + genomeFragmentService.delete(id); + return ResponseEntity.noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); + } + + /** + * {@code SEARCH /genome-fragments/search?query=:query} : search for the GenomeFragment corresponding + * to the query. + * + * @param query the query of the GenomeFragment search. + * @param pageable the pagination information. + * @return the result of the search. + */ + @GetMapping("/genome-fragments/search") + public ResponseEntity> searchGenomeFragments(@RequestParam String query, Pageable pageable) { + log.debug("REST request to search for a page of GenomeFragments for query {}", query); + // TODO: implement the search + Page page = new PageImpl<>(new ArrayList<>()); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(page.getContent()); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/GenomicIndicatorResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/GenomicIndicatorResource.java new file mode 100644 index 000000000..6468a1b6e --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/GenomicIndicatorResource.java @@ -0,0 +1,221 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; +import org.mskcc.oncokb.curation.domain.GenomicIndicator; +import org.mskcc.oncokb.curation.repository.GenomicIndicatorRepository; +import org.mskcc.oncokb.curation.service.GenomicIndicatorQueryService; +import org.mskcc.oncokb.curation.service.GenomicIndicatorService; +import org.mskcc.oncokb.curation.service.criteria.GenomicIndicatorCriteria; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.PaginationUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing {@link org.mskcc.oncokb.curation.domain.GenomicIndicator}. + */ +@RestController +@RequestMapping("/api") +public class GenomicIndicatorResource { + + private final Logger log = LoggerFactory.getLogger(GenomicIndicatorResource.class); + + private static final String ENTITY_NAME = "genomicIndicator"; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final GenomicIndicatorService genomicIndicatorService; + + private final GenomicIndicatorRepository genomicIndicatorRepository; + + private final GenomicIndicatorQueryService genomicIndicatorQueryService; + + public GenomicIndicatorResource( + GenomicIndicatorService genomicIndicatorService, + GenomicIndicatorRepository genomicIndicatorRepository, + GenomicIndicatorQueryService genomicIndicatorQueryService + ) { + this.genomicIndicatorService = genomicIndicatorService; + this.genomicIndicatorRepository = genomicIndicatorRepository; + this.genomicIndicatorQueryService = genomicIndicatorQueryService; + } + + /** + * {@code POST /genomic-indicators} : Create a new genomicIndicator. + * + * @param genomicIndicator the genomicIndicator to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new genomicIndicator, or with status {@code 400 (Bad Request)} if the genomicIndicator has already an ID. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PostMapping("/genomic-indicators") + public ResponseEntity createGenomicIndicator(@Valid @RequestBody GenomicIndicator genomicIndicator) + throws URISyntaxException { + log.debug("REST request to save GenomicIndicator : {}", genomicIndicator); + if (genomicIndicator.getId() != null) { + throw new BadRequestAlertException("A new genomicIndicator cannot already have an ID", ENTITY_NAME, "idexists"); + } + GenomicIndicator result = genomicIndicatorService.save(genomicIndicator); + return ResponseEntity.created(new URI("/api/genomic-indicators/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) + .body(result); + } + + /** + * {@code PUT /genomic-indicators/:id} : Updates an existing genomicIndicator. + * + * @param id the id of the genomicIndicator to save. + * @param genomicIndicator the genomicIndicator to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated genomicIndicator, + * or with status {@code 400 (Bad Request)} if the genomicIndicator is not valid, + * or with status {@code 500 (Internal Server Error)} if the genomicIndicator couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PutMapping("/genomic-indicators/{id}") + public ResponseEntity updateGenomicIndicator( + @PathVariable(value = "id", required = false) final Long id, + @Valid @RequestBody GenomicIndicator genomicIndicator + ) throws URISyntaxException { + log.debug("REST request to update GenomicIndicator : {}, {}", id, genomicIndicator); + if (genomicIndicator.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, genomicIndicator.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!genomicIndicatorRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + GenomicIndicator result = genomicIndicatorService.save(genomicIndicator); + return ResponseEntity.ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, genomicIndicator.getId().toString())) + .body(result); + } + + /** + * {@code PATCH /genomic-indicators/:id} : Partial updates given fields of an existing genomicIndicator, field will ignore if it is null + * + * @param id the id of the genomicIndicator to save. + * @param genomicIndicator the genomicIndicator to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated genomicIndicator, + * or with status {@code 400 (Bad Request)} if the genomicIndicator is not valid, + * or with status {@code 404 (Not Found)} if the genomicIndicator is not found, + * or with status {@code 500 (Internal Server Error)} if the genomicIndicator couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/genomic-indicators/{id}", consumes = { "application/json", "application/merge-patch+json" }) + public ResponseEntity partialUpdateGenomicIndicator( + @PathVariable(value = "id", required = false) final Long id, + @NotNull @RequestBody GenomicIndicator genomicIndicator + ) throws URISyntaxException { + log.debug("REST request to partial update GenomicIndicator partially : {}, {}", id, genomicIndicator); + if (genomicIndicator.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, genomicIndicator.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!genomicIndicatorRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Optional result = genomicIndicatorService.partialUpdate(genomicIndicator); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, genomicIndicator.getId().toString()) + ); + } + + /** + * {@code GET /genomic-indicators} : get all the genomicIndicators. + * + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of genomicIndicators in body. + */ + @GetMapping("/genomic-indicators") + public ResponseEntity> getAllGenomicIndicators(GenomicIndicatorCriteria criteria) { + log.debug("REST request to get GenomicIndicators by criteria: {}", criteria); + List entityList = genomicIndicatorQueryService.findByCriteria(criteria); + return ResponseEntity.ok() + .body(genomicIndicatorService.findByIdIn(entityList.stream().map(GenomicIndicator::getId).collect(Collectors.toList()))); + } + + /** + * {@code GET /genomic-indicators/count} : count all the genomicIndicators. + * + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the count in body. + */ + @GetMapping("/genomic-indicators/count") + public ResponseEntity countGenomicIndicators(GenomicIndicatorCriteria criteria) { + log.debug("REST request to count GenomicIndicators by criteria: {}", criteria); + return ResponseEntity.ok().body(genomicIndicatorQueryService.countByCriteria(criteria)); + } + + /** + * {@code GET /genomic-indicators/:id} : get the "id" genomicIndicator. + * + * @param id the id of the genomicIndicator to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the genomicIndicator, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/genomic-indicators/{id}") + public ResponseEntity getGenomicIndicator(@PathVariable Long id) { + log.debug("REST request to get GenomicIndicator : {}", id); + Optional genomicIndicator = genomicIndicatorService.findOne(id); + return ResponseUtil.wrapOrNotFound(genomicIndicator); + } + + /** + * {@code DELETE /genomic-indicators/:id} : delete the "id" genomicIndicator. + * + * @param id the id of the genomicIndicator to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/genomic-indicators/{id}") + public ResponseEntity deleteGenomicIndicator(@PathVariable Long id) { + log.debug("REST request to delete GenomicIndicator : {}", id); + genomicIndicatorService.delete(id); + return ResponseEntity.noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); + } + + /** + * {@code SEARCH /genomic-indicators/search?query=:query} : search for the GenomicIndicator corresponding + * to the query. + * + * @param query the query of the GenomicIndicator search. + * @param pageable the pagination information. + * @return the result of the search. + */ + @GetMapping("/genomic-indicators/search") + public ResponseEntity> searchGenomicIndicators(@RequestParam String query, Pageable pageable) { + log.debug("REST request to search for a page of GenomicIndicators for query {}", query); + // TODO: implement the search + Page page = new PageImpl<>(new ArrayList<>()); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(page.getContent()); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/InfoResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/InfoResource.java new file mode 100644 index 000000000..93f3ecd22 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/InfoResource.java @@ -0,0 +1,169 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.Info; +import org.mskcc.oncokb.curation.repository.InfoRepository; +import org.mskcc.oncokb.curation.service.InfoService; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing {@link org.mskcc.oncokb.curation.domain.Info}. + */ +@RestController +@RequestMapping("/api") +public class InfoResource { + + private final Logger log = LoggerFactory.getLogger(InfoResource.class); + + private static final String ENTITY_NAME = "info"; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final InfoService infoService; + + private final InfoRepository infoRepository; + + public InfoResource(InfoService infoService, InfoRepository infoRepository) { + this.infoService = infoService; + this.infoRepository = infoRepository; + } + + /** + * {@code POST /infos} : Create a new info. + * + * @param info the info to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new info, or with status {@code 400 (Bad Request)} if the info has already an ID. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PostMapping("/infos") + public ResponseEntity createInfo(@Valid @RequestBody Info info) throws URISyntaxException { + log.debug("REST request to save Info : {}", info); + if (info.getId() != null) { + throw new BadRequestAlertException("A new info cannot already have an ID", ENTITY_NAME, "idexists"); + } + Info result = infoService.save(info); + return ResponseEntity.created(new URI("/api/infos/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) + .body(result); + } + + /** + * {@code PUT /infos/:id} : Updates an existing info. + * + * @param id the id of the info to save. + * @param info the info to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated info, + * or with status {@code 400 (Bad Request)} if the info is not valid, + * or with status {@code 500 (Internal Server Error)} if the info couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PutMapping("/infos/{id}") + public ResponseEntity updateInfo(@PathVariable(value = "id", required = false) final Long id, @Valid @RequestBody Info info) + throws URISyntaxException { + log.debug("REST request to update Info : {}, {}", id, info); + if (info.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, info.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!infoRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Info result = infoService.save(info); + return ResponseEntity.ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, info.getId().toString())) + .body(result); + } + + /** + * {@code PATCH /infos/:id} : Partial updates given fields of an existing info, field will ignore if it is null + * + * @param id the id of the info to save. + * @param info the info to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated info, + * or with status {@code 400 (Bad Request)} if the info is not valid, + * or with status {@code 404 (Not Found)} if the info is not found, + * or with status {@code 500 (Internal Server Error)} if the info couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/infos/{id}", consumes = { "application/json", "application/merge-patch+json" }) + public ResponseEntity partialUpdateInfo( + @PathVariable(value = "id", required = false) final Long id, + @NotNull @RequestBody Info info + ) throws URISyntaxException { + log.debug("REST request to partial update Info partially : {}, {}", id, info); + if (info.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, info.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!infoRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Optional result = infoService.partialUpdate(info); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, info.getId().toString()) + ); + } + + /** + * {@code GET /infos} : get all the infos. + * + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of infos in body. + */ + @GetMapping("/infos") + public List getAllInfos() { + log.debug("REST request to get all Infos"); + return infoService.findAll(); + } + + /** + * {@code GET /infos/:id} : get the "id" info. + * + * @param id the id of the info to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the info, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/infos/{id}") + public ResponseEntity getInfo(@PathVariable Long id) { + log.debug("REST request to get Info : {}", id); + Optional info = infoService.findOne(id); + return ResponseUtil.wrapOrNotFound(info); + } + + /** + * {@code DELETE /infos/:id} : delete the "id" info. + * + * @param id the id of the info to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/infos/{id}") + public ResponseEntity deleteInfo(@PathVariable Long id) { + log.debug("REST request to delete Info : {}", id); + infoService.delete(id); + return ResponseEntity.noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/LevelOfEvidenceResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/LevelOfEvidenceResource.java new file mode 100644 index 000000000..71e309a45 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/LevelOfEvidenceResource.java @@ -0,0 +1,172 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.LevelOfEvidence; +import org.mskcc.oncokb.curation.repository.LevelOfEvidenceRepository; +import org.mskcc.oncokb.curation.service.LevelOfEvidenceService; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing {@link org.mskcc.oncokb.curation.domain.LevelOfEvidence}. + */ +@RestController +@RequestMapping("/api") +public class LevelOfEvidenceResource { + + private final Logger log = LoggerFactory.getLogger(LevelOfEvidenceResource.class); + + private static final String ENTITY_NAME = "levelOfEvidence"; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final LevelOfEvidenceService levelOfEvidenceService; + + private final LevelOfEvidenceRepository levelOfEvidenceRepository; + + public LevelOfEvidenceResource(LevelOfEvidenceService levelOfEvidenceService, LevelOfEvidenceRepository levelOfEvidenceRepository) { + this.levelOfEvidenceService = levelOfEvidenceService; + this.levelOfEvidenceRepository = levelOfEvidenceRepository; + } + + /** + * {@code POST /level-of-evidences} : Create a new levelOfEvidence. + * + * @param levelOfEvidence the levelOfEvidence to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new levelOfEvidence, or with status {@code 400 (Bad Request)} if the levelOfEvidence has already an ID. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PostMapping("/level-of-evidences") + public ResponseEntity createLevelOfEvidence(@Valid @RequestBody LevelOfEvidence levelOfEvidence) + throws URISyntaxException { + log.debug("REST request to save LevelOfEvidence : {}", levelOfEvidence); + if (levelOfEvidence.getId() != null) { + throw new BadRequestAlertException("A new levelOfEvidence cannot already have an ID", ENTITY_NAME, "idexists"); + } + LevelOfEvidence result = levelOfEvidenceService.save(levelOfEvidence); + return ResponseEntity.created(new URI("/api/level-of-evidences/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) + .body(result); + } + + /** + * {@code PUT /level-of-evidences/:id} : Updates an existing levelOfEvidence. + * + * @param id the id of the levelOfEvidence to save. + * @param levelOfEvidence the levelOfEvidence to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated levelOfEvidence, + * or with status {@code 400 (Bad Request)} if the levelOfEvidence is not valid, + * or with status {@code 500 (Internal Server Error)} if the levelOfEvidence couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PutMapping("/level-of-evidences/{id}") + public ResponseEntity updateLevelOfEvidence( + @PathVariable(value = "id", required = false) final Long id, + @Valid @RequestBody LevelOfEvidence levelOfEvidence + ) throws URISyntaxException { + log.debug("REST request to update LevelOfEvidence : {}, {}", id, levelOfEvidence); + if (levelOfEvidence.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, levelOfEvidence.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!levelOfEvidenceRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + LevelOfEvidence result = levelOfEvidenceService.save(levelOfEvidence); + return ResponseEntity.ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, levelOfEvidence.getId().toString())) + .body(result); + } + + /** + * {@code PATCH /level-of-evidences/:id} : Partial updates given fields of an existing levelOfEvidence, field will ignore if it is null + * + * @param id the id of the levelOfEvidence to save. + * @param levelOfEvidence the levelOfEvidence to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated levelOfEvidence, + * or with status {@code 400 (Bad Request)} if the levelOfEvidence is not valid, + * or with status {@code 404 (Not Found)} if the levelOfEvidence is not found, + * or with status {@code 500 (Internal Server Error)} if the levelOfEvidence couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/level-of-evidences/{id}", consumes = { "application/json", "application/merge-patch+json" }) + public ResponseEntity partialUpdateLevelOfEvidence( + @PathVariable(value = "id", required = false) final Long id, + @NotNull @RequestBody LevelOfEvidence levelOfEvidence + ) throws URISyntaxException { + log.debug("REST request to partial update LevelOfEvidence partially : {}, {}", id, levelOfEvidence); + if (levelOfEvidence.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, levelOfEvidence.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!levelOfEvidenceRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Optional result = levelOfEvidenceService.partialUpdate(levelOfEvidence); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, levelOfEvidence.getId().toString()) + ); + } + + /** + * {@code GET /level-of-evidences} : get all the levelOfEvidences. + * + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of levelOfEvidences in body. + */ + @GetMapping("/level-of-evidences") + public List getAllLevelOfEvidences() { + log.debug("REST request to get all LevelOfEvidences"); + return levelOfEvidenceService.findAll(); + } + + /** + * {@code GET /level-of-evidences/:id} : get the "id" levelOfEvidence. + * + * @param id the id of the levelOfEvidence to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the levelOfEvidence, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/level-of-evidences/{id}") + public ResponseEntity getLevelOfEvidence(@PathVariable Long id) { + log.debug("REST request to get LevelOfEvidence : {}", id); + Optional levelOfEvidence = levelOfEvidenceService.findOne(id); + return ResponseUtil.wrapOrNotFound(levelOfEvidence); + } + + /** + * {@code DELETE /level-of-evidences/:id} : delete the "id" levelOfEvidence. + * + * @param id the id of the levelOfEvidence to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/level-of-evidences/{id}") + public ResponseEntity deleteLevelOfEvidence(@PathVariable Long id) { + log.debug("REST request to delete LevelOfEvidence : {}", id); + levelOfEvidenceService.delete(id); + return ResponseEntity.noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/LogoutResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/LogoutResource.java new file mode 100644 index 000000000..624b42468 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/LogoutResource.java @@ -0,0 +1,38 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.servlet.http.HttpServletRequest; +import java.util.Map; +import org.mskcc.oncokb.curation.security.SecurityUtils; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.oauth2.client.registration.ClientRegistration; +import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * REST controller for managing global OIDC logout. + */ +@RestController +public class LogoutResource { + + private final ClientRegistration registration; + + public LogoutResource(ClientRegistrationRepository registrations) { + this.registration = registrations.findByRegistrationId("oidc"); + } + + /** + * {@code POST /api/logout} : logout the current user. + * + * @param request the {@link HttpServletRequest}. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and a body with a global logout URL. + */ + @PostMapping("/api/logout") + public ResponseEntity logout(HttpServletRequest request) { + String logoutUrl = SecurityUtils.getKeycloakLogoutURL(this.registration); + request.getSession().invalidate(); + SecurityContextHolder.clearContext(); + return ResponseEntity.ok().body(Map.of("logoutUrl", logoutUrl)); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/NciThesaurusResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/NciThesaurusResource.java new file mode 100644 index 000000000..0b533b7a0 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/NciThesaurusResource.java @@ -0,0 +1,223 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; +import org.mskcc.oncokb.curation.domain.NciThesaurus; +import org.mskcc.oncokb.curation.repository.NciThesaurusRepository; +import org.mskcc.oncokb.curation.service.NciThesaurusQueryService; +import org.mskcc.oncokb.curation.service.NciThesaurusService; +import org.mskcc.oncokb.curation.service.criteria.NciThesaurusCriteria; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.PaginationUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing {@link org.mskcc.oncokb.curation.domain.NciThesaurus}. + */ +@RestController +@RequestMapping("/api") +public class NciThesaurusResource { + + private final Logger log = LoggerFactory.getLogger(NciThesaurusResource.class); + + private static final String ENTITY_NAME = "nciThesaurus"; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final NciThesaurusService nciThesaurusService; + + private final NciThesaurusRepository nciThesaurusRepository; + + private final NciThesaurusQueryService nciThesaurusQueryService; + + public NciThesaurusResource( + NciThesaurusService nciThesaurusService, + NciThesaurusRepository nciThesaurusRepository, + NciThesaurusQueryService nciThesaurusQueryService + ) { + this.nciThesaurusService = nciThesaurusService; + this.nciThesaurusRepository = nciThesaurusRepository; + this.nciThesaurusQueryService = nciThesaurusQueryService; + } + + /** + * {@code POST /nci-thesauruses} : Create a new nciThesaurus. + * + * @param nciThesaurus the nciThesaurus to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new nciThesaurus, or with status {@code 400 (Bad Request)} if the nciThesaurus has already an ID. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PostMapping("/nci-thesauruses") + public ResponseEntity createNciThesaurus(@Valid @RequestBody NciThesaurus nciThesaurus) throws URISyntaxException { + log.debug("REST request to save NciThesaurus : {}", nciThesaurus); + if (nciThesaurus.getId() != null) { + throw new BadRequestAlertException("A new nciThesaurus cannot already have an ID", ENTITY_NAME, "idexists"); + } + NciThesaurus result = nciThesaurusService.save(nciThesaurus); + return ResponseEntity.created(new URI("/api/nci-thesauruses/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) + .body(result); + } + + /** + * {@code PUT /nci-thesauruses/:id} : Updates an existing nciThesaurus. + * + * @param id the id of the nciThesaurus to save. + * @param nciThesaurus the nciThesaurus to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated nciThesaurus, + * or with status {@code 400 (Bad Request)} if the nciThesaurus is not valid, + * or with status {@code 500 (Internal Server Error)} if the nciThesaurus couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PutMapping("/nci-thesauruses/{id}") + public ResponseEntity updateNciThesaurus( + @PathVariable(value = "id", required = false) final Long id, + @Valid @RequestBody NciThesaurus nciThesaurus + ) throws URISyntaxException { + log.debug("REST request to update NciThesaurus : {}, {}", id, nciThesaurus); + if (nciThesaurus.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, nciThesaurus.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!nciThesaurusRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + NciThesaurus result = nciThesaurusService.save(nciThesaurus); + return ResponseEntity.ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, nciThesaurus.getId().toString())) + .body(result); + } + + /** + * {@code PATCH /nci-thesauruses/:id} : Partial updates given fields of an existing nciThesaurus, field will ignore if it is null + * + * @param id the id of the nciThesaurus to save. + * @param nciThesaurus the nciThesaurus to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated nciThesaurus, + * or with status {@code 400 (Bad Request)} if the nciThesaurus is not valid, + * or with status {@code 404 (Not Found)} if the nciThesaurus is not found, + * or with status {@code 500 (Internal Server Error)} if the nciThesaurus couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/nci-thesauruses/{id}", consumes = { "application/json", "application/merge-patch+json" }) + public ResponseEntity partialUpdateNciThesaurus( + @PathVariable(value = "id", required = false) final Long id, + @NotNull @RequestBody NciThesaurus nciThesaurus + ) throws URISyntaxException { + log.debug("REST request to partial update NciThesaurus partially : {}, {}", id, nciThesaurus); + if (nciThesaurus.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, nciThesaurus.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!nciThesaurusRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Optional result = nciThesaurusService.partialUpdate(nciThesaurus); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, nciThesaurus.getId().toString()) + ); + } + + /** + * {@code GET /nci-thesauruses} : get all the nciThesauruses. + * + * @param pageable the pagination information. + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of nciThesauruses in body. + */ + @GetMapping("/nci-thesauruses") + public ResponseEntity> getAllNciThesauruses(NciThesaurusCriteria criteria, Pageable pageable) { + log.debug("REST request to get NciThesauruses by criteria: {}", criteria); + Page page = nciThesaurusQueryService.findByCriteria(criteria, pageable); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok() + .headers(headers) + .body( + nciThesaurusService.findAllWithEagerRelationships( + page.getContent().stream().map(NciThesaurus::getId).collect(Collectors.toList()) + ) + ); + } + + /** + * {@code GET /nci-thesauruses/count} : count all the nciThesauruses. + * + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the count in body. + */ + @GetMapping("/nci-thesauruses/count") + public ResponseEntity countNciThesauruses(NciThesaurusCriteria criteria) { + log.debug("REST request to count NciThesauruses by criteria: {}", criteria); + return ResponseEntity.ok().body(nciThesaurusQueryService.countByCriteria(criteria)); + } + + /** + * {@code GET /nci-thesauruses/:id} : get the "id" nciThesaurus. + * + * @param id the id of the nciThesaurus to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the nciThesaurus, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/nci-thesauruses/{id}") + public ResponseEntity getNciThesaurus(@PathVariable Long id) { + log.debug("REST request to get NciThesaurus : {}", id); + Optional nciThesaurus = nciThesaurusService.findOne(id); + return ResponseUtil.wrapOrNotFound(nciThesaurus); + } + + /** + * {@code DELETE /nci-thesauruses/:id} : delete the "id" nciThesaurus. + * + * @param id the id of the nciThesaurus to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/nci-thesauruses/{id}") + public ResponseEntity deleteNciThesaurus(@PathVariable Long id) { + log.debug("REST request to delete NciThesaurus : {}", id); + nciThesaurusService.delete(id); + return ResponseEntity.noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); + } + + /** + * {@code SEARCH /nci-thesauruses/search?query=:query} : search for the NCI Thesaurus corresponding + * to the query. + * + * @param query the query of the NCI Thesaurus search. + * @return the result of the search. + */ + @GetMapping("/nci-thesauruses/search") + public ResponseEntity> searchNciThesaurus(@RequestParam String query) { + log.debug("REST request to search for a page of Drugs for query {}", query); + List drugs = nciThesaurusService.searchNciThesaurus(query); + return ResponseEntity.ok().body(drugs); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/PipelineController.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/PipelineController.java new file mode 100644 index 000000000..6d16a8044 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/PipelineController.java @@ -0,0 +1,33 @@ +package org.mskcc.oncokb.curation.web.rest; + +import org.mskcc.oncokb.curation.service.GeneService; +import org.mskcc.oncokb.curation.service.NcitService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +/** + * Controller to drugs. + */ +@RestController +@RequestMapping("/api/pipeline/") +public class PipelineController { + + NcitService ncitService; + GeneService geneService; + + private final Logger log = LoggerFactory.getLogger(PipelineController.class); + + public PipelineController(NcitService ncitService, GeneService geneService) { + this.ncitService = ncitService; + this.geneService = geneService; + } + + @PostMapping("/update-ncit") + public ResponseEntity updateNcit() throws Exception { + ncitService.updateNcitDrugs(); + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/RuleResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/RuleResource.java new file mode 100644 index 000000000..ed482c266 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/RuleResource.java @@ -0,0 +1,169 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.Rule; +import org.mskcc.oncokb.curation.repository.RuleRepository; +import org.mskcc.oncokb.curation.service.RuleService; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing {@link org.mskcc.oncokb.curation.domain.Rule}. + */ +@RestController +@RequestMapping("/api") +public class RuleResource { + + private final Logger log = LoggerFactory.getLogger(RuleResource.class); + + private static final String ENTITY_NAME = "rule"; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final RuleService ruleService; + + private final RuleRepository ruleRepository; + + public RuleResource(RuleService ruleService, RuleRepository ruleRepository) { + this.ruleService = ruleService; + this.ruleRepository = ruleRepository; + } + + /** + * {@code POST /rules} : Create a new rule. + * + * @param rule the rule to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new rule, or with status {@code 400 (Bad Request)} if the rule has already an ID. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PostMapping("/rules") + public ResponseEntity createRule(@Valid @RequestBody Rule rule) throws URISyntaxException { + log.debug("REST request to save Rule : {}", rule); + if (rule.getId() != null) { + throw new BadRequestAlertException("A new rule cannot already have an ID", ENTITY_NAME, "idexists"); + } + Rule result = ruleService.save(rule); + return ResponseEntity.created(new URI("/api/rules/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) + .body(result); + } + + /** + * {@code PUT /rules/:id} : Updates an existing rule. + * + * @param id the id of the rule to save. + * @param rule the rule to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated rule, + * or with status {@code 400 (Bad Request)} if the rule is not valid, + * or with status {@code 500 (Internal Server Error)} if the rule couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PutMapping("/rules/{id}") + public ResponseEntity updateRule(@PathVariable(value = "id", required = false) final Long id, @Valid @RequestBody Rule rule) + throws URISyntaxException { + log.debug("REST request to update Rule : {}, {}", id, rule); + if (rule.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, rule.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!ruleRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Rule result = ruleService.save(rule); + return ResponseEntity.ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, rule.getId().toString())) + .body(result); + } + + /** + * {@code PATCH /rules/:id} : Partial updates given fields of an existing rule, field will ignore if it is null + * + * @param id the id of the rule to save. + * @param rule the rule to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated rule, + * or with status {@code 400 (Bad Request)} if the rule is not valid, + * or with status {@code 404 (Not Found)} if the rule is not found, + * or with status {@code 500 (Internal Server Error)} if the rule couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/rules/{id}", consumes = { "application/json", "application/merge-patch+json" }) + public ResponseEntity partialUpdateRule( + @PathVariable(value = "id", required = false) final Long id, + @NotNull @RequestBody Rule rule + ) throws URISyntaxException { + log.debug("REST request to partial update Rule partially : {}, {}", id, rule); + if (rule.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, rule.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!ruleRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Optional result = ruleService.partialUpdate(rule); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, rule.getId().toString()) + ); + } + + /** + * {@code GET /rules} : get all the rules. + * + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of rules in body. + */ + @GetMapping("/rules") + public List getAllRules() { + log.debug("REST request to get all Rules"); + return ruleService.findAll(); + } + + /** + * {@code GET /rules/:id} : get the "id" rule. + * + * @param id the id of the rule to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the rule, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/rules/{id}") + public ResponseEntity getRule(@PathVariable Long id) { + log.debug("REST request to get Rule : {}", id); + Optional rule = ruleService.findOne(id); + return ResponseUtil.wrapOrNotFound(rule); + } + + /** + * {@code DELETE /rules/:id} : delete the "id" rule. + * + * @param id the id of the rule to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/rules/{id}") + public ResponseEntity deleteRule(@PathVariable Long id) { + log.debug("REST request to delete Rule : {}", id); + ruleService.delete(id); + return ResponseEntity.noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/SearchController.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/SearchController.java new file mode 100644 index 000000000..1771cea24 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/SearchController.java @@ -0,0 +1,30 @@ +package org.mskcc.oncokb.curation.web.rest; + +import org.mskcc.oncokb.curation.service.SearchService; +import org.mskcc.oncokb.curation.service.dto.SearchResultDTO; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +/** + * Controller for general search + */ +@RestController +@RequestMapping("/api") +public class SearchController { + + private final Logger log = LoggerFactory.getLogger(SearchController.class); + + private final SearchService searchService; + + public SearchController(SearchService searchService) { + this.searchService = searchService; + } + + @GetMapping("/search") + public ResponseEntity search(@RequestParam String query) { + return new ResponseEntity(searchService.search(query), HttpStatus.OK); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/SeqRegionResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/SeqRegionResource.java new file mode 100644 index 000000000..0876a5952 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/SeqRegionResource.java @@ -0,0 +1,195 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.SeqRegion; +import org.mskcc.oncokb.curation.repository.SeqRegionRepository; +import org.mskcc.oncokb.curation.service.SeqRegionService; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.PaginationUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing {@link org.mskcc.oncokb.curation.domain.SeqRegion}. + */ +@RestController +@RequestMapping("/api") +public class SeqRegionResource { + + private final Logger log = LoggerFactory.getLogger(SeqRegionResource.class); + + private static final String ENTITY_NAME = "seqRegion"; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final SeqRegionService seqRegionService; + + private final SeqRegionRepository seqRegionRepository; + + public SeqRegionResource(SeqRegionService seqRegionService, SeqRegionRepository seqRegionRepository) { + this.seqRegionService = seqRegionService; + this.seqRegionRepository = seqRegionRepository; + } + + /** + * {@code POST /seq-regions} : Create a new seqRegion. + * + * @param seqRegion the seqRegion to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new seqRegion, or with status {@code 400 (Bad Request)} if the seqRegion has already an ID. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PostMapping("/seq-regions") + public ResponseEntity createSeqRegion(@Valid @RequestBody SeqRegion seqRegion) throws URISyntaxException { + log.debug("REST request to save SeqRegion : {}", seqRegion); + if (seqRegion.getId() != null) { + throw new BadRequestAlertException("A new seqRegion cannot already have an ID", ENTITY_NAME, "idexists"); + } + SeqRegion result = seqRegionService.save(seqRegion); + return ResponseEntity.created(new URI("/api/seq-regions/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) + .body(result); + } + + /** + * {@code PUT /seq-regions/:id} : Updates an existing seqRegion. + * + * @param id the id of the seqRegion to save. + * @param seqRegion the seqRegion to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated seqRegion, + * or with status {@code 400 (Bad Request)} if the seqRegion is not valid, + * or with status {@code 500 (Internal Server Error)} if the seqRegion couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PutMapping("/seq-regions/{id}") + public ResponseEntity updateSeqRegion( + @PathVariable(value = "id", required = false) final Long id, + @Valid @RequestBody SeqRegion seqRegion + ) throws URISyntaxException { + log.debug("REST request to update SeqRegion : {}, {}", id, seqRegion); + if (seqRegion.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, seqRegion.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!seqRegionRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + SeqRegion result = seqRegionService.save(seqRegion); + return ResponseEntity.ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, seqRegion.getId().toString())) + .body(result); + } + + /** + * {@code PATCH /seq-regions/:id} : Partial updates given fields of an existing seqRegion, field will ignore if it is null + * + * @param id the id of the seqRegion to save. + * @param seqRegion the seqRegion to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated seqRegion, + * or with status {@code 400 (Bad Request)} if the seqRegion is not valid, + * or with status {@code 404 (Not Found)} if the seqRegion is not found, + * or with status {@code 500 (Internal Server Error)} if the seqRegion couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/seq-regions/{id}", consumes = { "application/json", "application/merge-patch+json" }) + public ResponseEntity partialUpdateSeqRegion( + @PathVariable(value = "id", required = false) final Long id, + @NotNull @RequestBody SeqRegion seqRegion + ) throws URISyntaxException { + log.debug("REST request to partial update SeqRegion partially : {}, {}", id, seqRegion); + if (seqRegion.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, seqRegion.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!seqRegionRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Optional result = seqRegionService.partialUpdate(seqRegion); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, seqRegion.getId().toString()) + ); + } + + /** + * {@code GET /seq-regions} : get all the seqRegions. + * + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of seqRegions in body. + */ + @GetMapping("/seq-regions") + public List getAllSeqRegions() { + log.debug("REST request to get all SeqRegions"); + return seqRegionService.findAll(); + } + + /** + * {@code GET /seq-regions/:id} : get the "id" seqRegion. + * + * @param id the id of the seqRegion to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the seqRegion, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/seq-regions/{id}") + public ResponseEntity getSeqRegion(@PathVariable Long id) { + log.debug("REST request to get SeqRegion : {}", id); + Optional seqRegion = seqRegionService.findOne(id); + return ResponseUtil.wrapOrNotFound(seqRegion); + } + + /** + * {@code DELETE /seq-regions/:id} : delete the "id" seqRegion. + * + * @param id the id of the seqRegion to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/seq-regions/{id}") + public ResponseEntity deleteSeqRegion(@PathVariable Long id) { + log.debug("REST request to delete SeqRegion : {}", id); + seqRegionService.delete(id); + return ResponseEntity.noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); + } + + /** + * {@code SEARCH /seq-regions/search?query=:query} : search for the SeqRegion corresponding + * to the query. + * + * @param query the query of the SeqRegion search. + * @param pageable the pagination information. + * @return the result of the search. + */ + @GetMapping("/seq-regions/search") + public ResponseEntity> searchSeqRegions(@RequestParam String query, Pageable pageable) { + log.debug("REST request to search for a page of SeqRegions for query {}", query); + // TODO: implement the search + Page page = new PageImpl<>(new ArrayList<>()); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(page.getContent()); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/SequenceController.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/SequenceController.java new file mode 100644 index 000000000..11c6c8a8a --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/SequenceController.java @@ -0,0 +1,58 @@ +package org.mskcc.oncokb.curation.web.rest; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import org.mskcc.oncokb.curation.domain.Sequence; +import org.mskcc.oncokb.curation.domain.enumeration.ReferenceGenome; +import org.mskcc.oncokb.curation.domain.enumeration.SequenceType; +import org.mskcc.oncokb.curation.service.MainService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.*; + +/** + * REST controller for managing {@link org.mskcc.oncokb.curation.domain.Sequence}. + */ +@RestController +@RequestMapping("/api") +public class SequenceController { + + private final Logger log = LoggerFactory.getLogger(SequenceController.class); + + private final MainService mainService; + + public SequenceController(MainService mainService) { + this.mainService = mainService; + } + + @GetMapping("/find-canonical-sequences") + public Sequence findCanonicalSequence( + @RequestParam ReferenceGenome referenceGenome, + @RequestParam Integer entrezGeneId, + @RequestParam(defaultValue = "PROTEIN") SequenceType sequenceType + ) { + log.debug("GET request to get canonical protein sequence by Gene: {} {}", referenceGenome, entrezGeneId); + return mainService.findSequenceByGene(referenceGenome, entrezGeneId, sequenceType).orElse(null); + } + + @PostMapping("/find-canonical-sequences") + public List findCanonicalSequences( + @RequestParam ReferenceGenome referenceGenome, + @RequestParam(defaultValue = "PROTEIN") SequenceType sequenceType, + @RequestBody List entrezGeneIds + ) { + log.debug("POST request to get canonical protein sequences"); + if (entrezGeneIds == null || entrezGeneIds.isEmpty()) { + return new ArrayList<>(); + } else { + return entrezGeneIds + .stream() + .map(entrezGeneId -> mainService.findSequenceByGene(referenceGenome, entrezGeneId, sequenceType)) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(Collectors.toList()); + } + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/SequenceResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/SequenceResource.java new file mode 100644 index 000000000..22eb02a1f --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/SequenceResource.java @@ -0,0 +1,221 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.Sequence; +import org.mskcc.oncokb.curation.repository.SequenceRepository; +import org.mskcc.oncokb.curation.service.SequenceQueryService; +import org.mskcc.oncokb.curation.service.SequenceService; +import org.mskcc.oncokb.curation.service.criteria.SequenceCriteria; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.PaginationUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing {@link org.mskcc.oncokb.curation.domain.Sequence}. + */ +@RestController +@RequestMapping("/api") +public class SequenceResource { + + private final Logger log = LoggerFactory.getLogger(SequenceResource.class); + + private static final String ENTITY_NAME = "sequence"; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final SequenceService sequenceService; + + private final SequenceRepository sequenceRepository; + + private final SequenceQueryService sequenceQueryService; + + public SequenceResource( + SequenceService sequenceService, + SequenceRepository sequenceRepository, + SequenceQueryService sequenceQueryService + ) { + this.sequenceService = sequenceService; + this.sequenceRepository = sequenceRepository; + this.sequenceQueryService = sequenceQueryService; + } + + /** + * {@code POST /sequences} : Create a new sequence. + * + * @param sequence the sequence to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new sequence, or with status {@code 400 (Bad Request)} if the sequence has already an ID. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PostMapping("/sequences") + public ResponseEntity createSequence(@Valid @RequestBody Sequence sequence) throws URISyntaxException { + log.debug("REST request to save Sequence : {}", sequence); + if (sequence.getId() != null) { + throw new BadRequestAlertException("A new sequence cannot already have an ID", ENTITY_NAME, "idexists"); + } + Sequence result = sequenceService.save(sequence); + return ResponseEntity.created(new URI("/api/sequences/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) + .body(result); + } + + /** + * {@code PUT /sequences/:id} : Updates an existing sequence. + * + * @param id the id of the sequence to save. + * @param sequence the sequence to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated sequence, + * or with status {@code 400 (Bad Request)} if the sequence is not valid, + * or with status {@code 500 (Internal Server Error)} if the sequence couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PutMapping("/sequences/{id}") + public ResponseEntity updateSequence( + @PathVariable(value = "id", required = false) final Long id, + @Valid @RequestBody Sequence sequence + ) throws URISyntaxException { + log.debug("REST request to update Sequence : {}, {}", id, sequence); + if (sequence.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, sequence.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!sequenceRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Sequence result = sequenceService.save(sequence); + return ResponseEntity.ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, sequence.getId().toString())) + .body(result); + } + + /** + * {@code PATCH /sequences/:id} : Partial updates given fields of an existing sequence, field will ignore if it is null + * + * @param id the id of the sequence to save. + * @param sequence the sequence to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated sequence, + * or with status {@code 400 (Bad Request)} if the sequence is not valid, + * or with status {@code 404 (Not Found)} if the sequence is not found, + * or with status {@code 500 (Internal Server Error)} if the sequence couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/sequences/{id}", consumes = { "application/json", "application/merge-patch+json" }) + public ResponseEntity partialUpdateSequence( + @PathVariable(value = "id", required = false) final Long id, + @NotNull @RequestBody Sequence sequence + ) throws URISyntaxException { + log.debug("REST request to partial update Sequence partially : {}, {}", id, sequence); + if (sequence.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, sequence.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!sequenceRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Optional result = sequenceService.partialUpdate(sequence); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, sequence.getId().toString()) + ); + } + + /** + * {@code GET /sequences} : get all the sequences. + * + * @param pageable the pagination information. + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of sequences in body. + */ + @GetMapping("/sequences") + public ResponseEntity> getAllSequences(SequenceCriteria criteria, Pageable pageable) { + log.debug("REST request to get Sequences by criteria: {}", criteria); + Page page = sequenceQueryService.findByCriteria(criteria, pageable); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(page.getContent()); + } + + /** + * {@code GET /sequences/count} : count all the sequences. + * + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the count in body. + */ + @GetMapping("/sequences/count") + public ResponseEntity countSequences(SequenceCriteria criteria) { + log.debug("REST request to count Sequences by criteria: {}", criteria); + return ResponseEntity.ok().body(sequenceQueryService.countByCriteria(criteria)); + } + + /** + * {@code GET /sequences/:id} : get the "id" sequence. + * + * @param id the id of the sequence to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the sequence, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/sequences/{id}") + public ResponseEntity getSequence(@PathVariable Long id) { + log.debug("REST request to get Sequence : {}", id); + Optional sequence = sequenceService.findOne(id); + return ResponseUtil.wrapOrNotFound(sequence); + } + + /** + * {@code DELETE /sequences/:id} : delete the "id" sequence. + * + * @param id the id of the sequence to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/sequences/{id}") + public ResponseEntity deleteSequence(@PathVariable Long id) { + log.debug("REST request to delete Sequence : {}", id); + sequenceService.delete(id); + return ResponseEntity.noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); + } + + /** + * {@code SEARCH /sequences/search?query=:query} : search for the Sequence corresponding + * to the query. + * + * @param query the query of the Sequence search. + * @param pageable the pagination information. + * @return the result of the search. + */ + @GetMapping("/sequences/search") + public ResponseEntity> searchSequences(@RequestParam String query, Pageable pageable) { + log.debug("REST request to search for a page of Sequences for query {}", query); + // TODO: implement the search + Page page = new PageImpl<>(new ArrayList<>()); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(page.getContent()); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/SpecimenTypeResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/SpecimenTypeResource.java new file mode 100644 index 000000000..667e71b6c --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/SpecimenTypeResource.java @@ -0,0 +1,171 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.SpecimenType; +import org.mskcc.oncokb.curation.repository.SpecimenTypeRepository; +import org.mskcc.oncokb.curation.service.SpecimenTypeService; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing {@link org.mskcc.oncokb.curation.domain.SpecimenType}. + */ +@RestController +@RequestMapping("/api") +public class SpecimenTypeResource { + + private final Logger log = LoggerFactory.getLogger(SpecimenTypeResource.class); + + private static final String ENTITY_NAME = "specimenType"; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final SpecimenTypeService specimenTypeService; + + private final SpecimenTypeRepository specimenTypeRepository; + + public SpecimenTypeResource(SpecimenTypeService specimenTypeService, SpecimenTypeRepository specimenTypeRepository) { + this.specimenTypeService = specimenTypeService; + this.specimenTypeRepository = specimenTypeRepository; + } + + /** + * {@code POST /specimen-types} : Create a new specimenType. + * + * @param specimenType the specimenType to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new specimenType, or with status {@code 400 (Bad Request)} if the specimenType has already an ID. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PostMapping("/specimen-types") + public ResponseEntity createSpecimenType(@Valid @RequestBody SpecimenType specimenType) throws URISyntaxException { + log.debug("REST request to save SpecimenType : {}", specimenType); + if (specimenType.getId() != null) { + throw new BadRequestAlertException("A new specimenType cannot already have an ID", ENTITY_NAME, "idexists"); + } + SpecimenType result = specimenTypeService.save(specimenType); + return ResponseEntity.created(new URI("/api/specimen-types/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) + .body(result); + } + + /** + * {@code PUT /specimen-types/:id} : Updates an existing specimenType. + * + * @param id the id of the specimenType to save. + * @param specimenType the specimenType to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated specimenType, + * or with status {@code 400 (Bad Request)} if the specimenType is not valid, + * or with status {@code 500 (Internal Server Error)} if the specimenType couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PutMapping("/specimen-types/{id}") + public ResponseEntity updateSpecimenType( + @PathVariable(value = "id", required = false) final Long id, + @Valid @RequestBody SpecimenType specimenType + ) throws URISyntaxException { + log.debug("REST request to update SpecimenType : {}, {}", id, specimenType); + if (specimenType.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, specimenType.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!specimenTypeRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + SpecimenType result = specimenTypeService.save(specimenType); + return ResponseEntity.ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, specimenType.getId().toString())) + .body(result); + } + + /** + * {@code PATCH /specimen-types/:id} : Partial updates given fields of an existing specimenType, field will ignore if it is null + * + * @param id the id of the specimenType to save. + * @param specimenType the specimenType to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated specimenType, + * or with status {@code 400 (Bad Request)} if the specimenType is not valid, + * or with status {@code 404 (Not Found)} if the specimenType is not found, + * or with status {@code 500 (Internal Server Error)} if the specimenType couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/specimen-types/{id}", consumes = { "application/json", "application/merge-patch+json" }) + public ResponseEntity partialUpdateSpecimenType( + @PathVariable(value = "id", required = false) final Long id, + @NotNull @RequestBody SpecimenType specimenType + ) throws URISyntaxException { + log.debug("REST request to partial update SpecimenType partially : {}, {}", id, specimenType); + if (specimenType.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, specimenType.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!specimenTypeRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Optional result = specimenTypeService.partialUpdate(specimenType); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, specimenType.getId().toString()) + ); + } + + /** + * {@code GET /specimen-types} : get all the specimenTypes. + * + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of specimenTypes in body. + */ + @GetMapping("/specimen-types") + public List getAllSpecimenTypes() { + log.debug("REST request to get all SpecimenTypes"); + return specimenTypeService.findAll(); + } + + /** + * {@code GET /specimen-types/:id} : get the "id" specimenType. + * + * @param id the id of the specimenType to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the specimenType, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/specimen-types/{id}") + public ResponseEntity getSpecimenType(@PathVariable Long id) { + log.debug("REST request to get SpecimenType : {}", id); + Optional specimenType = specimenTypeService.findOne(id); + return ResponseUtil.wrapOrNotFound(specimenType); + } + + /** + * {@code DELETE /specimen-types/:id} : delete the "id" specimenType. + * + * @param id the id of the specimenType to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/specimen-types/{id}") + public ResponseEntity deleteSpecimenType(@PathVariable Long id) { + log.debug("REST request to delete SpecimenType : {}", id); + specimenTypeService.delete(id); + return ResponseEntity.noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/SynonymResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/SynonymResource.java new file mode 100644 index 000000000..439809b9c --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/SynonymResource.java @@ -0,0 +1,216 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import org.mskcc.oncokb.curation.domain.Synonym; +import org.mskcc.oncokb.curation.repository.SynonymRepository; +import org.mskcc.oncokb.curation.service.SynonymQueryService; +import org.mskcc.oncokb.curation.service.SynonymService; +import org.mskcc.oncokb.curation.service.criteria.SynonymCriteria; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.PaginationUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing {@link org.mskcc.oncokb.curation.domain.Synonym}. + */ +@RestController +@RequestMapping("/api") +public class SynonymResource { + + private final Logger log = LoggerFactory.getLogger(SynonymResource.class); + + private static final String ENTITY_NAME = "synonym"; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final SynonymService synonymService; + + private final SynonymRepository synonymRepository; + + private final SynonymQueryService synonymQueryService; + + public SynonymResource(SynonymService synonymService, SynonymRepository synonymRepository, SynonymQueryService synonymQueryService) { + this.synonymService = synonymService; + this.synonymRepository = synonymRepository; + this.synonymQueryService = synonymQueryService; + } + + /** + * {@code POST /synonyms} : Create a new synonym. + * + * @param synonym the synonym to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new synonym, or with status {@code 400 (Bad Request)} if the synonym has already an ID. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PostMapping("/synonyms") + public ResponseEntity createSynonym(@Valid @RequestBody Synonym synonym) throws URISyntaxException { + log.debug("REST request to save Synonym : {}", synonym); + if (synonym.getId() != null) { + throw new BadRequestAlertException("A new synonym cannot already have an ID", ENTITY_NAME, "idexists"); + } + Synonym result = synonymService.save(synonym); + return ResponseEntity.created(new URI("/api/synonyms/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) + .body(result); + } + + /** + * {@code PUT /synonyms/:id} : Updates an existing synonym. + * + * @param id the id of the synonym to save. + * @param synonym the synonym to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated synonym, + * or with status {@code 400 (Bad Request)} if the synonym is not valid, + * or with status {@code 500 (Internal Server Error)} if the synonym couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PutMapping("/synonyms/{id}") + public ResponseEntity updateSynonym( + @PathVariable(value = "id", required = false) final Long id, + @Valid @RequestBody Synonym synonym + ) throws URISyntaxException { + log.debug("REST request to update Synonym : {}, {}", id, synonym); + if (synonym.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, synonym.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!synonymRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Synonym result = synonymService.save(synonym); + return ResponseEntity.ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, synonym.getId().toString())) + .body(result); + } + + /** + * {@code PATCH /synonyms/:id} : Partial updates given fields of an existing synonym, field will ignore if it is null + * + * @param id the id of the synonym to save. + * @param synonym the synonym to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated synonym, + * or with status {@code 400 (Bad Request)} if the synonym is not valid, + * or with status {@code 404 (Not Found)} if the synonym is not found, + * or with status {@code 500 (Internal Server Error)} if the synonym couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/synonyms/{id}", consumes = { "application/json", "application/merge-patch+json" }) + public ResponseEntity partialUpdateSynonym( + @PathVariable(value = "id", required = false) final Long id, + @NotNull @RequestBody Synonym synonym + ) throws URISyntaxException { + log.debug("REST request to partial update Synonym partially : {}, {}", id, synonym); + if (synonym.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, synonym.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!synonymRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Optional result = synonymService.partialUpdate(synonym); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, synonym.getId().toString()) + ); + } + + /** + * {@code GET /synonyms} : get all the synonyms. + * + * @param pageable the pagination information. + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of synonyms in body. + */ + @GetMapping("/synonyms") + public ResponseEntity> getAllSynonyms(SynonymCriteria criteria, Pageable pageable) { + log.debug("REST request to get Synonyms by criteria: {}", criteria); + Page page = synonymQueryService.findByCriteria(criteria, pageable); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(page.getContent()); + } + + /** + * {@code GET /synonyms/count} : count all the synonyms. + * + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the count in body. + */ + @GetMapping("/synonyms/count") + public ResponseEntity countSynonyms(SynonymCriteria criteria) { + log.debug("REST request to count Synonyms by criteria: {}", criteria); + return ResponseEntity.ok().body(synonymQueryService.countByCriteria(criteria)); + } + + /** + * {@code GET /synonyms/:id} : get the "id" synonym. + * + * @param id the id of the synonym to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the synonym, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/synonyms/{id}") + public ResponseEntity getSynonym(@PathVariable Long id) { + log.debug("REST request to get Synonym : {}", id); + Optional synonym = synonymService.findOne(id); + return ResponseUtil.wrapOrNotFound(synonym); + } + + /** + * {@code DELETE /synonyms/:id} : delete the "id" synonym. + * + * @param id the id of the synonym to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/synonyms/{id}") + public ResponseEntity deleteSynonym(@PathVariable Long id) { + log.debug("REST request to delete Synonym : {}", id); + synonymService.delete(id); + return ResponseEntity.noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); + } + + /** + * {@code SEARCH /synonyms/search?query=:query} : search for the Synonym corresponding + * to the query. + * + * @param query the query of the Synonym search. + * @param pageable the pagination information. + * @return the result of the search. + */ + @GetMapping("/synonyms/search") + public ResponseEntity> searchSynonymss(@RequestParam String query, Pageable pageable) { + log.debug("REST request to search for a page of Synonyms for query {}", query); + // TODO: implement the search + Page page = new PageImpl<>(new ArrayList<>()); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(page.getContent()); + } +} diff --git a/src/main/java/org/mskcc/oncokb/transcript/web/rest/TranscriptController.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/TranscriptController.java similarity index 78% rename from src/main/java/org/mskcc/oncokb/transcript/web/rest/TranscriptController.java rename to src/main/java/org/mskcc/oncokb/curation/web/rest/TranscriptController.java index 46c5c971c..a9253ce54 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/web/rest/TranscriptController.java +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/TranscriptController.java @@ -1,17 +1,17 @@ -package org.mskcc.oncokb.transcript.web.rest; +package org.mskcc.oncokb.curation.web.rest; import java.util.*; import java.util.stream.Collectors; import org.genome_nexus.ApiException; import org.genome_nexus.client.EnsemblTranscript; -import org.mskcc.oncokb.transcript.domain.AlignmentResult; -import org.mskcc.oncokb.transcript.domain.EnrichedAlignmentResult; -import org.mskcc.oncokb.transcript.domain.enumeration.ReferenceGenome; -import org.mskcc.oncokb.transcript.service.*; -import org.mskcc.oncokb.transcript.service.dto.TranscriptDTO; -import org.mskcc.oncokb.transcript.vm.*; -import org.mskcc.oncokb.transcript.vm.ensembl.EnsemblSequence; -import org.mskcc.oncokb.transcript.web.rest.model.AddTranscriptBody; +import org.mskcc.oncokb.curation.domain.AlignmentResult; +import org.mskcc.oncokb.curation.domain.EnrichedAlignmentResult; +import org.mskcc.oncokb.curation.domain.enumeration.ReferenceGenome; +import org.mskcc.oncokb.curation.service.*; +import org.mskcc.oncokb.curation.service.dto.TranscriptDTO; +import org.mskcc.oncokb.curation.vm.*; +import org.mskcc.oncokb.curation.vm.ensembl.EnsemblSequence; +import org.mskcc.oncokb.curation.web.rest.model.AddTranscriptBody; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.*; @@ -48,49 +48,57 @@ public ResponseEntity compareTranscript( TranscriptComparisonResultVM result = new TranscriptComparisonResultVM(); // Find whether both transcript length are the same - Optional ensemblA = transcriptService.getEnsemblTranscript(hugoSymbol, transcriptComparisonVM.getTranscriptA()); - Optional ensemblB = transcriptService.getEnsemblTranscript(hugoSymbol, transcriptComparisonVM.getTranscriptB()); + Optional ensemblAOptional = transcriptService.getEnsemblTranscript( + hugoSymbol, + transcriptComparisonVM.getTranscriptA() + ); + Optional ensemblBOptional = transcriptService.getEnsemblTranscript( + hugoSymbol, + transcriptComparisonVM.getTranscriptB() + ); - if (ensemblA.isEmpty()) { + if (ensemblAOptional.isEmpty()) { return new ResponseEntity("TranscriptA does not exist.", HttpStatus.BAD_REQUEST); } - if (ensemblB.isEmpty()) { + if (ensemblBOptional.isEmpty()) { return new ResponseEntity("TranscriptB does not exist.", HttpStatus.BAD_REQUEST); } - Optional sequenceA = Optional.of(new EnsemblSequence()); - if (ensemblA.isPresent()) { - sequenceA = - ensemblService.getProteinSequence( - transcriptComparisonVM.getTranscriptA().getReferenceGenome(), - ensemblA.get().getProteinId() - ); + Optional sequenceAOptional = Optional.of(new EnsemblSequence()); + if (ensemblAOptional.isPresent()) { + sequenceAOptional = ensemblService.getProteinSequence( + transcriptComparisonVM.getTranscriptA().getReferenceGenome(), + ensemblAOptional.orElseThrow().getProteinId() + ); } - Optional sequenceB = Optional.of(new EnsemblSequence()); - if (ensemblB.isPresent()) { - sequenceB = - ensemblService.getProteinSequence( - transcriptComparisonVM.getTranscriptB().getReferenceGenome(), - ensemblB.get().getProteinId() - ); + Optional sequenceBOptional = Optional.of(new EnsemblSequence()); + if (ensemblBOptional.isPresent()) { + sequenceBOptional = ensemblService.getProteinSequence( + transcriptComparisonVM.getTranscriptB().getReferenceGenome(), + ensemblBOptional.orElseThrow().getProteinId() + ); } if (transcriptComparisonVM.getAlign()) { AlignmentResult alignmentResult = alignmentService.calcOptimalAlignment( - sequenceA.get().getSeq(), - sequenceB.get().getSeq(), + sequenceAOptional.orElseThrow().getSeq(), + sequenceBOptional.orElseThrow().getSeq(), false ); result.setSequenceA(alignmentResult.getRefSeq()); result.setSequenceB(alignmentResult.getTargetSeq()); } else { - result.setSequenceA(sequenceA.get().getSeq()); - result.setSequenceB(sequenceB.get().getSeq()); + result.setSequenceA(sequenceAOptional.orElseThrow().getSeq()); + result.setSequenceB(sequenceBOptional.orElseThrow().getSeq()); } - if (ensemblA.isPresent() && ensemblB.isPresent() && ensemblA.get().getProteinLength().equals(ensemblB.get().getProteinLength())) { + if ( + ensemblAOptional.isPresent() && + ensemblBOptional.isPresent() && + ensemblAOptional.orElseThrow().getProteinLength().equals(ensemblBOptional.orElseThrow().getProteinLength()) + ) { // do a quick check whether the protein is the same - if (sequenceA.isPresent() && sequenceB.isPresent()) { - if (sequenceA.get().getSeq().equals(sequenceB.get().getSeq())) { + if (sequenceAOptional.isPresent() && sequenceBOptional.isPresent()) { + if (sequenceAOptional.orElseThrow().getSeq().equals(sequenceBOptional.orElseThrow().getSeq())) { result.setMatch(true); } } @@ -184,8 +192,9 @@ public ResponseEntity suggestVariant( if ( ensembl37Transcripts .stream() - .filter(ensemblTranscript -> - ensemblTranscript.getTranscriptId().equals(ensemblTranscriptOptional.get().getTranscriptId()) + .filter( + ensemblTranscript -> + ensemblTranscript.getTranscriptId().equals(ensemblTranscriptOptional.orElseThrow().getTranscriptId()) ) .findAny() .isPresent() @@ -194,7 +203,7 @@ public ResponseEntity suggestVariant( } else { List alignmentResults = transcriptService.getAlignmentResult( ReferenceGenome.GRCh37, - ensemblTranscriptOptional.get(), + ensemblTranscriptOptional.orElseThrow(), ReferenceGenome.GRCh37, ensembl37Transcripts ); @@ -240,8 +249,9 @@ public ResponseEntity suggestVariant( if ( ensembl38Transcripts .stream() - .filter(ensemblTranscript -> - ensemblTranscript.getTranscriptId().equals(ensemblTranscriptOptional.get().getTranscriptId()) + .filter( + ensemblTranscript -> + ensemblTranscript.getTranscriptId().equals(ensemblTranscriptOptional.orElseThrow().getTranscriptId()) ) .findAny() .isPresent() @@ -250,7 +260,7 @@ public ResponseEntity suggestVariant( } else { List alignmentResults = transcriptService.getAlignmentResult( ReferenceGenome.GRCh38, - ensemblTranscriptOptional.get(), + ensemblTranscriptOptional.orElseThrow(), ReferenceGenome.GRCh38, ensembl38Transcripts ); @@ -295,10 +305,13 @@ public ResponseEntity addTranscript(@RequestBody AddTranscriptBod ReferenceGenome.valueOf(body.getReferenceGenome()), body.getEnsemblTranscriptId(), body.getEntrezGeneId(), - body.getCanonical() + null, + null, + body.getCanonical(), + body.getFlags() ); return new ResponseEntity<>( - transcriptDTOOptional.get(), + transcriptDTOOptional.orElseThrow(), transcriptDTOOptional.isPresent() ? HttpStatus.OK : HttpStatus.BAD_REQUEST ); } diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/TranscriptResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/TranscriptResource.java new file mode 100644 index 000000000..1f11dff78 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/TranscriptResource.java @@ -0,0 +1,227 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; +import org.mskcc.oncokb.curation.repository.TranscriptRepository; +import org.mskcc.oncokb.curation.service.TranscriptQueryService; +import org.mskcc.oncokb.curation.service.TranscriptService; +import org.mskcc.oncokb.curation.service.criteria.TranscriptCriteria; +import org.mskcc.oncokb.curation.service.dto.ClustalOResp; +import org.mskcc.oncokb.curation.service.dto.TranscriptDTO; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.PaginationUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing {@link org.mskcc.oncokb.curation.domain.Transcript}. + */ +@RestController +@RequestMapping("/api") +public class TranscriptResource { + + private final Logger log = LoggerFactory.getLogger(TranscriptResource.class); + + private static final String ENTITY_NAME = "transcript"; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final TranscriptService transcriptService; + + private final TranscriptRepository transcriptRepository; + + private final TranscriptQueryService transcriptQueryService; + + public TranscriptResource( + TranscriptService transcriptService, + TranscriptRepository transcriptRepository, + TranscriptQueryService transcriptQueryService + ) { + this.transcriptService = transcriptService; + this.transcriptRepository = transcriptRepository; + this.transcriptQueryService = transcriptQueryService; + } + + /** + * {@code POST /transcripts} : Create a new transcript. + * + * @param transcriptDTO the transcriptDTO to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new transcriptDTO, or with status {@code 400 (Bad Request)} if the transcript has already an ID. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PostMapping("/transcripts") + public ResponseEntity createTranscript(@Valid @RequestBody TranscriptDTO transcriptDTO) throws URISyntaxException { + log.debug("REST request to save Transcript : {}", transcriptDTO); + if (transcriptDTO.getId() != null) { + throw new BadRequestAlertException("A new transcript cannot already have an ID", ENTITY_NAME, "idexists"); + } + TranscriptDTO result = transcriptService.save(transcriptDTO); + return ResponseEntity.created(new URI("/api/transcripts/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) + .body(result); + } + + /** + * {@code PUT /transcripts/:id} : Updates an existing transcript. + * + * @param id the id of the transcriptDTO to save. + * @param transcriptDTO the transcriptDTO to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated transcriptDTO, + * or with status {@code 400 (Bad Request)} if the transcriptDTO is not valid, + * or with status {@code 500 (Internal Server Error)} if the transcriptDTO couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PutMapping("/transcripts/{id}") + public ResponseEntity updateTranscript( + @PathVariable(value = "id", required = false) final Long id, + @Valid @RequestBody TranscriptDTO transcriptDTO + ) throws URISyntaxException { + log.debug("REST request to update Transcript : {}, {}", id, transcriptDTO); + if (transcriptDTO.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, transcriptDTO.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!transcriptRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + TranscriptDTO result = transcriptService.save(transcriptDTO); + return ResponseEntity.ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, transcriptDTO.getId().toString())) + .body(result); + } + + /** + * {@code PATCH /transcripts/:id} : Partial updates given fields of an existing transcript, field will ignore if it is null + * + * @param id the id of the transcriptDTO to save. + * @param transcriptDTO the transcriptDTO to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated transcriptDTO, + * or with status {@code 400 (Bad Request)} if the transcriptDTO is not valid, + * or with status {@code 404 (Not Found)} if the transcriptDTO is not found, + * or with status {@code 500 (Internal Server Error)} if the transcriptDTO couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/transcripts/{id}", consumes = { "application/json", "application/merge-patch+json" }) + public ResponseEntity partialUpdateTranscript( + @PathVariable(value = "id", required = false) final Long id, + @NotNull @RequestBody TranscriptDTO transcriptDTO + ) throws URISyntaxException { + log.debug("REST request to partial update Transcript partially : {}, {}", id, transcriptDTO); + if (transcriptDTO.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, transcriptDTO.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!transcriptRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Optional result = transcriptService.partialUpdate(transcriptDTO); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, transcriptDTO.getId().toString()) + ); + } + + /** + * {@code GET /transcripts} : get all the transcripts. + * + * @param pageable the pagination information. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of transcripts in body. + */ + @GetMapping("/transcripts") + public ResponseEntity> getAllTranscripts(TranscriptCriteria criteria, Pageable pageable) { + log.debug("REST request to get Transcripts by criteria: {}", criteria); + Page page = transcriptQueryService.findByCriteria(criteria, pageable); + List transcriptDTOS = transcriptService.findAllWithEagerRelationshipsByIdIn( + page.getContent().stream().map(TranscriptDTO::getId).collect(Collectors.toList()) + ); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(transcriptDTOS); + } + + /** + * {@code GET /transcripts/count} : count all the transcripts. + * + * @param criteria the criteria which the requested entities should match. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the count in body. + */ + @GetMapping("/transcripts/count") + public ResponseEntity countTranscripts(TranscriptCriteria criteria) { + log.debug("REST request to count Transcripts by criteria: {}", criteria); + return ResponseEntity.ok().body(transcriptQueryService.countByCriteria(criteria)); + } + + /** + * {@code GET /transcripts/:id} : get the "id" transcript. + * + * @param id the id of the transcriptDTO to retrieve. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the transcriptDTO, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/transcripts/{id}") + public ResponseEntity getTranscript(@PathVariable Long id) { + log.debug("REST request to get Transcript : {}", id); + Optional transcriptDTO = transcriptService.findOne(id); + return ResponseUtil.wrapOrNotFound(transcriptDTO); + } + + /** + * {@code DELETE /transcripts/:id} : delete the "id" transcript. + * + * @param id the id of the transcriptDTO to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/transcripts/{id}") + public ResponseEntity deleteTranscript(@PathVariable Long id) { + log.debug("REST request to delete Transcript : {}", id); + transcriptService.delete(id); + return ResponseEntity.noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); + } + + /** + * {@code SEARCH /transcripts/search?query=:query} : search for the Transcript corresponding + * to the query. + * + * @param query the query of the Transcript search. + * @param pageable the pagination information. + * @return the result of the search. + */ + @GetMapping("/transcripts/search") + public ResponseEntity> searchTranscripts(@RequestParam String query, Pageable pageable) { + log.debug("REST request to search for a page of FdaSubmissions for query {}", query); + Page page = transcriptQueryService.findBySearchQuery(query, pageable); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return ResponseEntity.ok().headers(headers).body(page.getContent()); + } + + @PostMapping("/transcripts/align") + public ResponseEntity alignTranscripts(@RequestBody List body) throws InterruptedException { + log.debug("REST request to align existing transcripts"); + return ResponseEntity.ok().body(transcriptService.alignTranscripts(body)); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/UserResource.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/UserResource.java new file mode 100644 index 000000000..a35c4dda9 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/UserResource.java @@ -0,0 +1,165 @@ +package org.mskcc.oncokb.curation.web.rest; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.Pattern; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.*; +import org.mskcc.oncokb.curation.config.Constants; +import org.mskcc.oncokb.curation.domain.User; +import org.mskcc.oncokb.curation.repository.UserRepository; +import org.mskcc.oncokb.curation.security.AuthoritiesConstants; +import org.mskcc.oncokb.curation.service.UserService; +import org.mskcc.oncokb.curation.service.dto.UserDTO; +import org.mskcc.oncokb.curation.web.rest.errors.BadRequestAlertException; +import org.mskcc.oncokb.curation.web.rest.errors.EmailAlreadyUsedException; +import org.mskcc.oncokb.curation.web.rest.errors.LoginAlreadyUsedException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import tech.jhipster.web.util.PaginationUtil; +import tech.jhipster.web.util.ResponseUtil; + +/** + * REST controller for managing users. + *

+ * This class accesses the {@link org.mskcc.oncokb.curation.domain.User} entity, and needs to fetch its collection of authorities. + *

+ * For a normal use-case, it would be better to have an eager relationship between User and Authority, + * and send everything to the client side: there would be no View Model and DTO, a lot less code, and an outer-join + * which would be good for performance. + *

+ * We use a View Model and a DTO for 3 reasons: + *

    + *
  • We want to keep a lazy association between the user and the authorities, because people will + * quite often do relationships with the user, and we don't want them to get the authorities all + * the time for nothing (for performance reasons). This is the #1 goal: we should not impact our users' + * application because of this use-case.
  • + *
  • Not having an outer join causes n+1 requests to the database. This is not a real issue as + * we have by default a second-level cache. This means on the first HTTP call we do the n+1 requests, + * but then all authorities come from the cache, so in fact it's much better than doing an outer join + * (which will get lots of data from the database, for each HTTP call).
  • + *
  • As this manages users, for security reasons, we'd rather have a DTO layer.
  • + *
+ *

+ * Another option would be to have a specific JPA entity graph to handle this case. + */ +@RestController +@RequestMapping("/api/admin") +public class UserResource { + + private final Logger log = LoggerFactory.getLogger(UserResource.class); + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final UserService userService; + + private final UserRepository userRepository; + + public UserResource(UserService userService, UserRepository userRepository) { + this.userService = userService; + this.userRepository = userRepository; + } + + /** + * {@code POST /admin/users} : Creates a new user. + *

+ * Creates a new user if the login and email are not already used, and sends an + * mail with an activation link. + * The user needs to be activated on creation. + * + * @param userDTO the user to create. + * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new user, or with status {@code 400 (Bad Request)} if the login or email is already in use. + * @throws URISyntaxException if the Location URI syntax is incorrect. + * @throws BadRequestAlertException {@code 400 (Bad Request)} if the login or email is already in use. + */ + @PostMapping("/users") + public ResponseEntity createUser(@Valid @RequestBody UserDTO userDTO) throws URISyntaxException { + log.debug("REST request to save User : {}", userDTO); + + if (userDTO.getId() != null) { + throw new BadRequestAlertException("A new user cannot already have an ID", "userManagement", "idexists"); + // Lowercase the user login before comparing with database + } else if (userRepository.findOneByLogin(userDTO.getLogin().toLowerCase()).isPresent()) { + throw new LoginAlreadyUsedException(); + } else if (userRepository.findOneByEmailIgnoreCase(userDTO.getEmail()).isPresent()) { + throw new EmailAlreadyUsedException(); + } else { + User newUser = userService.createUser(userDTO); + return ResponseEntity.created(new URI("/api/admin/users/" + newUser.getLogin())).body(newUser); + } + } + + /** + * {@code PUT /admin/users} : Updates an existing User. + * + * @param userDTO the user to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated user. + * @throws EmailAlreadyUsedException {@code 400 (Bad Request)} if the email is already in use. + * @throws LoginAlreadyUsedException {@code 400 (Bad Request)} if the login is already in use. + */ + @PutMapping("/users/{id}") + public ResponseEntity updateUser( + @PathVariable(value = "id", required = false) final Long id, + @Valid @RequestBody UserDTO userDTO + ) { + log.debug("REST request to update User : {}", userDTO); + Optional existingUserOptional = userRepository.findOneByEmailIgnoreCase(userDTO.getEmail()); + if (existingUserOptional.isPresent() && (!existingUserOptional.orElseThrow().getId().equals(userDTO.getId()))) { + throw new EmailAlreadyUsedException(); + } + existingUserOptional = userRepository.findOneByLogin(userDTO.getLogin().toLowerCase()); + if (existingUserOptional.isPresent() && (!existingUserOptional.orElseThrow().getId().equals(userDTO.getId()))) { + throw new LoginAlreadyUsedException(); + } + Optional updatedUser = userService.updateUser(userDTO); + + return ResponseUtil.wrapOrNotFound(updatedUser); + } + + /** + * {@code GET /admin/users} : get all users with all the details - calling this are only allowed for the administrators. + * + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body all users. + */ + @GetMapping("/users") + public ResponseEntity> getAllUsers() { + log.debug("REST request to get all User for an admin"); + + return new ResponseEntity<>(userService.getAllManagedUsers(), HttpStatus.OK); + } + + /** + * {@code GET /admin/users/:login} : get the "login" user. + * + * @param login the login of the user to find. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the "login" user, or with status {@code 404 (Not Found)}. + */ + @GetMapping("/users/{login}") + public ResponseEntity getUser(@PathVariable @Pattern(regexp = Constants.LOGIN_REGEX) String login) { + log.debug("REST request to get User : {}", login); + return ResponseUtil.wrapOrNotFound(userService.getUserWithAuthoritiesByLogin(login).map(UserDTO::new)); + } + + /** + * {@code DELETE /admin/users/:login} : delete the "login" User. + * + * @param login the login of the user to delete. + * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}. + */ + @DeleteMapping("/users/{login}") + public ResponseEntity deleteUser(@PathVariable @Pattern(regexp = Constants.LOGIN_REGEX) String login) { + log.debug("REST request to delete User: {}", login); + userService.deleteUser(login); + return ResponseEntity.noContent().build(); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/errors/BadRequestAlertException.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/errors/BadRequestAlertException.java new file mode 100644 index 000000000..67c4b5589 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/errors/BadRequestAlertException.java @@ -0,0 +1,49 @@ +package org.mskcc.oncokb.curation.web.rest.errors; + +import java.net.URI; +import org.springframework.http.HttpStatus; +import org.springframework.web.ErrorResponseException; +import tech.jhipster.web.rest.errors.ProblemDetailWithCause; +import tech.jhipster.web.rest.errors.ProblemDetailWithCause.ProblemDetailWithCauseBuilder; + +@SuppressWarnings("java:S110") // Inheritance tree of classes should not be too deep +public class BadRequestAlertException extends ErrorResponseException { + + private static final long serialVersionUID = 1L; + + private final String entityName; + + private final String errorKey; + + public BadRequestAlertException(String defaultMessage, String entityName, String errorKey) { + this(ErrorConstants.DEFAULT_TYPE, defaultMessage, entityName, errorKey); + } + + public BadRequestAlertException(URI type, String defaultMessage, String entityName, String errorKey) { + super( + HttpStatus.BAD_REQUEST, + ProblemDetailWithCauseBuilder.instance() + .withStatus(HttpStatus.BAD_REQUEST.value()) + .withType(type) + .withTitle(defaultMessage) + .withProperty("message", "error." + errorKey) + .withProperty("params", entityName) + .build(), + null + ); + this.entityName = entityName; + this.errorKey = errorKey; + } + + public String getEntityName() { + return entityName; + } + + public String getErrorKey() { + return errorKey; + } + + public ProblemDetailWithCause getProblemDetailWithCause() { + return (ProblemDetailWithCause) this.getBody(); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/errors/EmailAlreadyUsedException.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/errors/EmailAlreadyUsedException.java new file mode 100644 index 000000000..2a833b7bb --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/errors/EmailAlreadyUsedException.java @@ -0,0 +1,10 @@ +package org.mskcc.oncokb.curation.web.rest.errors; + +public class EmailAlreadyUsedException extends BadRequestAlertException { + + private static final long serialVersionUID = 1L; + + public EmailAlreadyUsedException() { + super(ErrorConstants.EMAIL_ALREADY_USED_TYPE, "Email is already in use!", "userManagement", "emailexists"); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/errors/ErrorConstants.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/errors/ErrorConstants.java new file mode 100644 index 000000000..d365a3b43 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/errors/ErrorConstants.java @@ -0,0 +1,17 @@ +package org.mskcc.oncokb.curation.web.rest.errors; + +import java.net.URI; + +public final class ErrorConstants { + + public static final String ERR_CONCURRENCY_FAILURE = "error.concurrencyFailure"; + public static final String ERR_VALIDATION = "error.validation"; + public static final String PROBLEM_BASE_URL = "https://www.oncokb.org/problem"; + public static final URI DEFAULT_TYPE = URI.create(PROBLEM_BASE_URL + "/problem-with-message"); + public static final URI CONSTRAINT_VIOLATION_TYPE = URI.create(PROBLEM_BASE_URL + "/constraint-violation"); + public static final URI USER_NOT_APPROVED = URI.create(PROBLEM_BASE_URL + "user-not-approved"); + public static final URI EMAIL_ALREADY_USED_TYPE = URI.create(PROBLEM_BASE_URL + "/email-already-used"); + public static final URI LOGIN_ALREADY_USED_TYPE = URI.create(PROBLEM_BASE_URL + "/login-already-used"); + + public ErrorConstants() {} +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/errors/ExceptionTranslator.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/errors/ExceptionTranslator.java new file mode 100644 index 000000000..edec0f452 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/errors/ExceptionTranslator.java @@ -0,0 +1,254 @@ +package org.mskcc.oncokb.curation.web.rest.errors; + +import static org.springframework.core.annotation.AnnotatedElementUtils.findMergedAnnotation; + +import jakarta.servlet.http.HttpServletRequest; +import java.net.URI; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.env.Environment; +import org.springframework.dao.ConcurrencyFailureException; +import org.springframework.dao.DataAccessException; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; +import org.springframework.http.ResponseEntity; +import org.springframework.http.converter.HttpMessageConversionException; +import org.springframework.lang.Nullable; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.web.ErrorResponse; +import org.springframework.web.ErrorResponseException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.context.request.WebRequest; +import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; +import tech.jhipster.config.JHipsterConstants; +import tech.jhipster.web.rest.errors.ProblemDetailWithCause; +import tech.jhipster.web.rest.errors.ProblemDetailWithCause.ProblemDetailWithCauseBuilder; +import tech.jhipster.web.util.HeaderUtil; + +/** + * Controller advice to translate the server side exceptions to client-friendly json structures. + * The error response follows RFC7807 - Problem Details for HTTP APIs (https://tools.ietf.org/html/rfc7807). + */ +@ControllerAdvice +public class ExceptionTranslator extends ResponseEntityExceptionHandler { + + private static final String FIELD_ERRORS_KEY = "fieldErrors"; + private static final String MESSAGE_KEY = "message"; + private static final String PATH_KEY = "path"; + private static final boolean CASUAL_CHAIN_ENABLED = false; + + @Value("${jhipster.clientApp.name}") + private String applicationName; + + private final Environment env; + + public ExceptionTranslator(Environment env) { + this.env = env; + } + + @ExceptionHandler + public ResponseEntity handleAnyException(Throwable ex, NativeWebRequest request) { + ProblemDetailWithCause pdCause = wrapAndCustomizeProblem(ex, request); + return handleExceptionInternal((Exception) ex, pdCause, buildHeaders(ex), HttpStatusCode.valueOf(pdCause.getStatus()), request); + } + + @Nullable + @Override + protected ResponseEntity handleExceptionInternal( + Exception ex, + @Nullable Object body, + HttpHeaders headers, + HttpStatusCode statusCode, + WebRequest request + ) { + body = body == null ? wrapAndCustomizeProblem((Throwable) ex, (NativeWebRequest) request) : body; + return super.handleExceptionInternal(ex, body, headers, statusCode, request); + } + + protected ProblemDetailWithCause wrapAndCustomizeProblem(Throwable ex, NativeWebRequest request) { + return customizeProblem(getProblemDetailWithCause(ex), ex, request); + } + + private ProblemDetailWithCause getProblemDetailWithCause(Throwable ex) { + if ( + ex instanceof ErrorResponseException exp && exp.getBody() instanceof ProblemDetailWithCause problemDetailWithCause + ) return problemDetailWithCause; + return ProblemDetailWithCauseBuilder.instance().withStatus(toStatus(ex).value()).build(); + } + + protected ProblemDetailWithCause customizeProblem(ProblemDetailWithCause problem, Throwable err, NativeWebRequest request) { + if (problem.getStatus() <= 0) problem.setStatus(toStatus(err)); + + if (problem.getType() == null || problem.getType().equals(URI.create("about:blank"))) problem.setType(getMappedType(err)); + + // higher precedence to Custom/ResponseStatus types + String title = extractTitle(err, problem.getStatus()); + String problemTitle = problem.getTitle(); + if (problemTitle == null || !problemTitle.equals(title)) { + problem.setTitle(title); + } + + if (problem.getDetail() == null) { + // higher precedence to cause + problem.setDetail(getCustomizedErrorDetails(err)); + } + + Map problemProperties = problem.getProperties(); + if (problemProperties == null || !problemProperties.containsKey(MESSAGE_KEY)) problem.setProperty( + MESSAGE_KEY, + getMappedMessageKey(err) != null ? getMappedMessageKey(err) : "error.http." + problem.getStatus() + ); + + if (problemProperties == null || !problemProperties.containsKey(PATH_KEY)) problem.setProperty(PATH_KEY, getPathValue(request)); + + if ( + (err instanceof MethodArgumentNotValidException fieldException) && + (problemProperties == null || !problemProperties.containsKey(FIELD_ERRORS_KEY)) + ) problem.setProperty(FIELD_ERRORS_KEY, getFieldErrors(fieldException)); + + problem.setCause(buildCause(err.getCause(), request).orElse(null)); + + return problem; + } + + private String extractTitle(Throwable err, int statusCode) { + return getCustomizedTitle(err) != null ? getCustomizedTitle(err) : extractTitleForResponseStatus(err, statusCode); + } + + private List getFieldErrors(MethodArgumentNotValidException ex) { + return ex + .getBindingResult() + .getFieldErrors() + .stream() + .map( + f -> + new FieldErrorVM( + f.getObjectName().replaceFirst("DTO$", ""), + f.getField(), + StringUtils.isNotBlank(f.getDefaultMessage()) ? f.getDefaultMessage() : f.getCode() + ) + ) + .toList(); + } + + private String extractTitleForResponseStatus(Throwable err, int statusCode) { + ResponseStatus specialStatus = extractResponseStatus(err); + return specialStatus == null ? HttpStatus.valueOf(statusCode).getReasonPhrase() : specialStatus.reason(); + } + + private String extractURI(NativeWebRequest request) { + HttpServletRequest nativeRequest = request.getNativeRequest(HttpServletRequest.class); + return nativeRequest != null ? nativeRequest.getRequestURI() : StringUtils.EMPTY; + } + + private HttpStatus toStatus(final Throwable throwable) { + // Let the ErrorResponse take this responsibility + if (throwable instanceof ErrorResponse err) return HttpStatus.valueOf(err.getBody().getStatus()); + + return Optional.ofNullable(getMappedStatus(throwable)).orElse( + Optional.ofNullable(resolveResponseStatus(throwable)).map(ResponseStatus::value).orElse(HttpStatus.INTERNAL_SERVER_ERROR) + ); + } + + private ResponseStatus extractResponseStatus(final Throwable throwable) { + return Optional.ofNullable(resolveResponseStatus(throwable)).orElse(null); + } + + private ResponseStatus resolveResponseStatus(final Throwable type) { + final ResponseStatus candidate = findMergedAnnotation(type.getClass(), ResponseStatus.class); + return candidate == null && type.getCause() != null ? resolveResponseStatus(type.getCause()) : candidate; + } + + private URI getMappedType(Throwable err) { + if (err instanceof MethodArgumentNotValidException) return ErrorConstants.CONSTRAINT_VIOLATION_TYPE; + return ErrorConstants.DEFAULT_TYPE; + } + + private String getMappedMessageKey(Throwable err) { + if (err instanceof MethodArgumentNotValidException) { + return ErrorConstants.ERR_VALIDATION; + } else if (err instanceof ConcurrencyFailureException || err.getCause() instanceof ConcurrencyFailureException) { + return ErrorConstants.ERR_CONCURRENCY_FAILURE; + } + return null; + } + + private String getCustomizedTitle(Throwable err) { + if (err instanceof MethodArgumentNotValidException) return "Method argument not valid"; + return null; + } + + private String getCustomizedErrorDetails(Throwable err) { + Collection activeProfiles = Arrays.asList(env.getActiveProfiles()); + if (activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_PRODUCTION)) { + if (err instanceof HttpMessageConversionException) return "Unable to convert http message"; + if (err instanceof DataAccessException) return "Failure during data access"; + if (containsPackageName(err.getMessage())) return "Unexpected runtime exception"; + } + return err.getCause() != null ? err.getCause().getMessage() : err.getMessage(); + } + + private HttpStatus getMappedStatus(Throwable err) { + // Where we disagree with Spring defaults + if (err instanceof AccessDeniedException) return HttpStatus.FORBIDDEN; + if (err instanceof ConcurrencyFailureException) return HttpStatus.CONFLICT; + if (err instanceof BadCredentialsException) return HttpStatus.UNAUTHORIZED; + return null; + } + + private URI getPathValue(NativeWebRequest request) { + if (request == null) return URI.create("about:blank"); + return URI.create(extractURI(request)); + } + + private HttpHeaders buildHeaders(Throwable err) { + return err instanceof BadRequestAlertException badRequestAlertException + ? HeaderUtil.createFailureAlert( + applicationName, + true, + badRequestAlertException.getEntityName(), + badRequestAlertException.getErrorKey(), + badRequestAlertException.getMessage() + ) + : null; + } + + public Optional buildCause(final Throwable throwable, NativeWebRequest request) { + if (throwable != null && isCasualChainEnabled()) { + return Optional.of(customizeProblem(getProblemDetailWithCause(throwable), throwable, request)); + } + return Optional.ofNullable(null); + } + + private boolean isCasualChainEnabled() { + // Customize as per the needs + return CASUAL_CHAIN_ENABLED; + } + + private boolean containsPackageName(String message) { + // This list is for sure not complete + return StringUtils.containsAny( + message, + "org.", + "java.", + "net.", + "jakarta.", + "javax.", + "com.", + "io.", + "de.", + "org.mskcc.oncokb.curation" + ); + } +} diff --git a/src/main/java/org/mskcc/oncokb/transcript/web/rest/errors/FieldErrorVM.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/errors/FieldErrorVM.java similarity index 91% rename from src/main/java/org/mskcc/oncokb/transcript/web/rest/errors/FieldErrorVM.java rename to src/main/java/org/mskcc/oncokb/curation/web/rest/errors/FieldErrorVM.java index 31bca961a..9e1ca75d5 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/web/rest/errors/FieldErrorVM.java +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/errors/FieldErrorVM.java @@ -1,4 +1,4 @@ -package org.mskcc.oncokb.transcript.web.rest.errors; +package org.mskcc.oncokb.curation.web.rest.errors; import java.io.Serializable; diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/errors/LoginAlreadyUsedException.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/errors/LoginAlreadyUsedException.java new file mode 100644 index 000000000..d345895d9 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/errors/LoginAlreadyUsedException.java @@ -0,0 +1,10 @@ +package org.mskcc.oncokb.curation.web.rest.errors; + +public class LoginAlreadyUsedException extends BadRequestAlertException { + + private static final long serialVersionUID = 1L; + + public LoginAlreadyUsedException() { + super(ErrorConstants.LOGIN_ALREADY_USED_TYPE, "Login name already used!", "userManagement", "userexists"); + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/errors/package-info.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/errors/package-info.java new file mode 100644 index 000000000..9dc5ed6b6 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/errors/package-info.java @@ -0,0 +1,6 @@ +/** + * Specific errors used with Zalando's "problem-spring-web" library. + * + * More information on https://github.com/zalando/problem-spring-web + */ +package org.mskcc.oncokb.curation.web.rest.errors; diff --git a/src/main/java/org/mskcc/oncokb/transcript/web/rest/model/AddEnsemblGeneBody.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/model/AddEnsemblGeneBody.java similarity index 90% rename from src/main/java/org/mskcc/oncokb/transcript/web/rest/model/AddEnsemblGeneBody.java rename to src/main/java/org/mskcc/oncokb/curation/web/rest/model/AddEnsemblGeneBody.java index daf4ea429..cd208a207 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/web/rest/model/AddEnsemblGeneBody.java +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/model/AddEnsemblGeneBody.java @@ -1,6 +1,6 @@ -package org.mskcc.oncokb.transcript.web.rest.model; +package org.mskcc.oncokb.curation.web.rest.model; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; public class AddEnsemblGeneBody { diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/model/AddTranscriptBody.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/model/AddTranscriptBody.java new file mode 100644 index 000000000..ba5dbdc0d --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/model/AddTranscriptBody.java @@ -0,0 +1,63 @@ +package org.mskcc.oncokb.curation.web.rest.model; + +import jakarta.validation.constraints.NotNull; +import java.util.List; +import org.mskcc.oncokb.curation.domain.enumeration.TranscriptFlagEnum; + +public class AddTranscriptBody { + + @NotNull + Integer entrezGeneId; + + @NotNull + String referenceGenome; + + @NotNull + String ensemblTranscriptId; + + @NotNull + Boolean isCanonical = false; + + @NotNull + List flags; + + public Integer getEntrezGeneId() { + return entrezGeneId; + } + + public void setEntrezGeneId(Integer entrezGeneId) { + this.entrezGeneId = entrezGeneId; + } + + public String getReferenceGenome() { + return referenceGenome; + } + + public void setReferenceGenome(String referenceGenome) { + this.referenceGenome = referenceGenome; + } + + public String getEnsemblTranscriptId() { + return ensemblTranscriptId; + } + + public void setEnsemblTranscriptId(String ensemblTranscriptId) { + this.ensemblTranscriptId = ensemblTranscriptId; + } + + public Boolean getCanonical() { + return isCanonical; + } + + public void setCanonical(Boolean canonical) { + isCanonical = canonical; + } + + public List getFlags() { + return flags; + } + + public void setFlags(List flags) { + this.flags = flags; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/model/AnnotateAlterationBody.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/model/AnnotateAlterationBody.java new file mode 100644 index 000000000..8bc584703 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/model/AnnotateAlterationBody.java @@ -0,0 +1,37 @@ +package org.mskcc.oncokb.curation.web.rest.model; + +import java.io.Serializable; +import org.mskcc.oncokb.curation.domain.Alteration; +import org.mskcc.oncokb.curation.domain.enumeration.ReferenceGenome; + +public class AnnotateAlterationBody implements Serializable { + + String queryId; + + ReferenceGenome referenceGenome; + Alteration alteration; + + public String getQueryId() { + return queryId; + } + + public void setQueryId(String queryId) { + this.queryId = queryId; + } + + public ReferenceGenome getReferenceGenome() { + return referenceGenome; + } + + public void setReferenceGenome(ReferenceGenome referenceGenome) { + this.referenceGenome = referenceGenome; + } + + public Alteration getAlteration() { + return alteration; + } + + public void setAlteration(Alteration alteration) { + this.alteration = alteration; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/package-info.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/package-info.java new file mode 100644 index 000000000..f02672485 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/package-info.java @@ -0,0 +1,4 @@ +/** + * Spring MVC REST controllers. + */ +package org.mskcc.oncokb.curation.web.rest; diff --git a/src/main/java/org/mskcc/oncokb/transcript/vm/LoginVM.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/vm/LoginVM.java similarity index 87% rename from src/main/java/org/mskcc/oncokb/transcript/vm/LoginVM.java rename to src/main/java/org/mskcc/oncokb/curation/web/rest/vm/LoginVM.java index 7a62b5e86..6384920cb 100644 --- a/src/main/java/org/mskcc/oncokb/transcript/vm/LoginVM.java +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/vm/LoginVM.java @@ -1,7 +1,7 @@ -package org.mskcc.oncokb.transcript.vm; +package org.mskcc.oncokb.curation.web.rest.vm; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; /** * View Model object for storing a user's credentials. diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/vm/ManagedUserVM.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/vm/ManagedUserVM.java new file mode 100644 index 000000000..46480a046 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/vm/ManagedUserVM.java @@ -0,0 +1,19 @@ +package org.mskcc.oncokb.curation.web.rest.vm; + +import org.mskcc.oncokb.curation.service.dto.UserDTO; + +/** + * View Model extending the UserDTO, which is meant to be used in the user management UI. + */ +public class ManagedUserVM extends UserDTO { + + public ManagedUserVM() { + // Empty constructor needed for Jackson. + } + + // prettier-ignore + @Override + public String toString() { + return "ManagedUserVM{" + super.toString() + "} "; + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/rest/vm/package-info.java b/src/main/java/org/mskcc/oncokb/curation/web/rest/vm/package-info.java new file mode 100644 index 000000000..f7dde0df4 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/rest/vm/package-info.java @@ -0,0 +1,4 @@ +/** + * View Models used by Spring MVC REST controllers. + */ +package org.mskcc.oncokb.curation.web.rest.vm; diff --git a/src/main/java/org/mskcc/oncokb/curation/web/websocket/OncoCoreWebSocketHandler.java b/src/main/java/org/mskcc/oncokb/curation/web/websocket/OncoCoreWebSocketHandler.java new file mode 100644 index 000000000..8ec244721 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/websocket/OncoCoreWebSocketHandler.java @@ -0,0 +1,63 @@ +package org.mskcc.oncokb.curation.web.websocket; + +import java.io.IOException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.socket.CloseStatus; +import org.springframework.web.socket.TextMessage; +import org.springframework.web.socket.WebSocketSession; +import org.springframework.web.socket.handler.TextWebSocketHandler; + +// https://docs.spring.io/spring-framework/docs/4.3.x/spring-framework-reference/html/websocket.html +// https://www.javainuse.com/spring/boot-websocket + +public class OncoCoreWebSocketHandler extends TextWebSocketHandler { + + private final Logger log = LoggerFactory.getLogger(ProxyWebSocketHandler.class); + private final WebSocketSession uiSession; + private WebSocketSession coreSession; + + public OncoCoreWebSocketHandler(WebSocketSession uiSession) { + super(); + this.uiSession = uiSession; + } + + @Override + public void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException { + try { + this.log.debug("Received message: " + message); + this.sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void sendText(TextMessage message) { + try { + this.uiSession.sendMessage(message); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void afterConnectionEstablished(WebSocketSession session) throws Exception { + this.coreSession = session; + } + + public void closeCoreSession() throws Exception { + if (this.coreSession != null) { + this.coreSession.close(); + } + } + + @Override + public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { + try { + super.afterConnectionClosed(session, status); + this.uiSession.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/org/mskcc/oncokb/curation/web/websocket/ProxyWebSocketHandler.java b/src/main/java/org/mskcc/oncokb/curation/web/websocket/ProxyWebSocketHandler.java new file mode 100644 index 000000000..67aa7aee8 --- /dev/null +++ b/src/main/java/org/mskcc/oncokb/curation/web/websocket/ProxyWebSocketHandler.java @@ -0,0 +1,56 @@ +package org.mskcc.oncokb.curation.web.websocket; + +import org.mskcc.oncokb.curation.config.application.ApplicationProperties; +import org.springframework.web.socket.CloseStatus; +import org.springframework.web.socket.WebSocketHandler; +import org.springframework.web.socket.WebSocketMessage; +import org.springframework.web.socket.WebSocketSession; +import org.springframework.web.socket.client.standard.StandardWebSocketClient; + +// https://docs.spring.io/spring-framework/docs/4.3.x/spring-framework-reference/html/websocket.html +// https://www.javainuse.com/spring/boot-websocket + +public class ProxyWebSocketHandler implements WebSocketHandler { + + private OncoCoreWebSocketHandler oncoHandler; + private String baseUrl; + + public ProxyWebSocketHandler(ApplicationProperties applicationProperties) { + String url = applicationProperties.getOncokbCore().getUrl(); + url = url.replace("https://", "wss://"); + url = url.replace("http://", "ws://"); + this.baseUrl = url; + } + + @Override + public void afterConnectionEstablished(WebSocketSession session) throws Exception { + try { + String incomingUri = session.getUri().getPath(); + StandardWebSocketClient client = new StandardWebSocketClient(); + OncoCoreWebSocketHandler handler = new OncoCoreWebSocketHandler(session); + client.doHandshake(handler, this.baseUrl + "/api" + incomingUri); + this.oncoHandler = handler; + } catch (Exception e) { + e.printStackTrace(); + session.close(CloseStatus.SERVER_ERROR.withReason("Failed to connect to core")); + } + } + + @Override + public void handleMessage(WebSocketSession session, WebSocketMessage message) throws Exception { + session.close(CloseStatus.NOT_ACCEPTABLE.withReason("All messages are not supported")); + } + + @Override + public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {} + + @Override + public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception { + this.oncoHandler.closeCoreSession(); + } + + @Override + public boolean supportsPartialMessages() { + return false; + } +} diff --git a/src/main/java/org/mskcc/oncokb/transcript/GeneratedByJHipster.java b/src/main/java/org/mskcc/oncokb/transcript/GeneratedByJHipster.java deleted file mode 100644 index 1fdaad7a0..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/GeneratedByJHipster.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.mskcc.oncokb.transcript; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import javax.annotation.Generated; - -@Generated(value = "JHipster", comments = "Generated by JHipster 7.3.1") -@Retention(RetentionPolicy.SOURCE) -@Target({ ElementType.TYPE }) -public @interface GeneratedByJHipster { -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/OncokbTranscriptApp.java b/src/main/java/org/mskcc/oncokb/transcript/OncokbTranscriptApp.java deleted file mode 100644 index 1008e9064..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/OncokbTranscriptApp.java +++ /dev/null @@ -1,119 +0,0 @@ -package org.mskcc.oncokb.transcript; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Arrays; -import java.util.Collection; -import java.util.Optional; -import javax.annotation.PostConstruct; -import org.apache.commons.lang3.StringUtils; -import org.mskcc.oncokb.transcript.config.ApplicationProperties; -import org.mskcc.oncokb.transcript.importer.Importer; -import org.oncokb.ApiException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.core.env.Environment; -import tech.jhipster.config.DefaultProfileUtil; -import tech.jhipster.config.JHipsterConstants; - -@SpringBootApplication -@EnableConfigurationProperties({ LiquibaseProperties.class, ApplicationProperties.class }) -public class OncokbTranscriptApp { - - @Autowired - private Importer importer; - - private static final Logger log = LoggerFactory.getLogger(OncokbTranscriptApp.class); - - private final Environment env; - - public OncokbTranscriptApp(Environment env) { - this.env = env; - } - - /** - * Initializes oncokb-transcript. - *

- * Spring profiles can be configured with a program argument --spring.profiles.active=your-active-profile - *

- * You can find more information on how profiles work with JHipster on https://www.jhipster.tech/profiles/. - */ - @PostConstruct - public void initApplication() { - Collection activeProfiles = Arrays.asList(env.getActiveProfiles()); - if ( - activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) && - activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_PRODUCTION) - ) { - log.error( - "You have misconfigured your application! It should not run " + "with both the 'dev' and 'prod' profiles at the same time." - ); - } - if ( - activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) && - activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_CLOUD) - ) { - log.error( - "You have misconfigured your application! It should not " + "run with both the 'dev' and 'cloud' profiles at the same time." - ); - } - } - - @PostConstruct - public void importOncoKbSequence() throws ApiException { - Collection activeProfiles = Arrays.asList( - env.getActiveProfiles().length == 0 ? env.getDefaultProfiles() : env.getActiveProfiles() - ); - if (activeProfiles.contains("importer")) { - importer.generalImport(); - } - } - - /** - * Main method, used to run the application. - * - * @param args the command line arguments. - */ - public static void main(String[] args) { - SpringApplication app = new SpringApplication(OncokbTranscriptApp.class); - DefaultProfileUtil.addDefaultProfile(app); - Environment env = app.run(args).getEnvironment(); - logApplicationStartup(env); - } - - private static void logApplicationStartup(Environment env) { - String protocol = Optional.ofNullable(env.getProperty("server.ssl.key-store")).map(key -> "https").orElse("http"); - String serverPort = env.getProperty("server.port"); - String contextPath = Optional - .ofNullable(env.getProperty("server.servlet.context-path")) - .filter(StringUtils::isNotBlank) - .orElse("/"); - String hostAddress = "localhost"; - try { - hostAddress = InetAddress.getLocalHost().getHostAddress(); - } catch (UnknownHostException e) { - log.warn("The host name could not be determined, using `localhost` as fallback"); - } - log.info( - "\n----------------------------------------------------------\n\t" + - "Application '{}' is running! Access URLs:\n\t" + - "Local: \t\t{}://localhost:{}{}\n\t" + - "External: \t{}://{}:{}{}\n\t" + - "Profile(s): \t{}\n----------------------------------------------------------", - env.getProperty("spring.application.name"), - protocol, - serverPort, - contextPath, - protocol, - hostAddress, - serverPort, - contextPath, - env.getActiveProfiles().length == 0 ? env.getDefaultProfiles() : env.getActiveProfiles() - ); - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/config/ApplicationProperties.java b/src/main/java/org/mskcc/oncokb/transcript/config/ApplicationProperties.java deleted file mode 100644 index 56bcdbf52..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/config/ApplicationProperties.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.mskcc.oncokb.transcript.config; - -import org.mskcc.oncokb.transcript.config.model.OncoKbConfig; -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * Properties specific to OncoKB Transcript. - *

- * Properties are configured in the {@code application.yml} file. - * See {@link tech.jhipster.config.JHipsterProperties} for a good example. - */ -@ConfigurationProperties(prefix = "application", ignoreUnknownFields = false) -public class ApplicationProperties extends org.mskcc.oncokb.meta.model.application.ApplicationProperties { - - private OncoKbConfig oncokb; - - public OncoKbConfig getOncokb() { - return oncokb; - } - - public void setOncokb(OncoKbConfig oncokb) { - this.oncokb = oncokb; - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/config/Constants.java b/src/main/java/org/mskcc/oncokb/transcript/config/Constants.java deleted file mode 100644 index 0db023bf6..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/config/Constants.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.mskcc.oncokb.transcript.config; - -/** - * Application constants. - */ -public final class Constants { - - public static final String SYSTEM = "system"; - public static final Integer ENSEMBL_POST_THRESHOLD = 100; - - private Constants() {} -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/config/DatabaseConfiguration.java b/src/main/java/org/mskcc/oncokb/transcript/config/DatabaseConfiguration.java deleted file mode 100644 index 9fb9e7428..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/config/DatabaseConfiguration.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.mskcc.oncokb.transcript.config; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.jpa.repository.config.EnableJpaAuditing; -import org.springframework.data.jpa.repository.config.EnableJpaRepositories; -import org.springframework.transaction.annotation.EnableTransactionManagement; -import tech.jhipster.config.JHipsterConstants; - -@Configuration -@EnableJpaRepositories({ "org.mskcc.oncokb.transcript.repository" }) -@EnableJpaAuditing(auditorAwareRef = "springSecurityAuditorAware") -@EnableTransactionManagement -public class DatabaseConfiguration {} diff --git a/src/main/java/org/mskcc/oncokb/transcript/config/JacksonConfiguration.java b/src/main/java/org/mskcc/oncokb/transcript/config/JacksonConfiguration.java deleted file mode 100644 index d95fb3f5a..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/config/JacksonConfiguration.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.mskcc.oncokb.transcript.config; - -import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module; -import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.zalando.problem.jackson.ProblemModule; -import org.zalando.problem.violations.ConstraintViolationProblemModule; - -@Configuration -public class JacksonConfiguration { - - /** - * Support for Java date and time API. - * @return the corresponding Jackson module. - */ - @Bean - public JavaTimeModule javaTimeModule() { - return new JavaTimeModule(); - } - - @Bean - public Jdk8Module jdk8TimeModule() { - return new Jdk8Module(); - } - - /* - * Support for Hibernate types in Jackson. - */ - @Bean - public Hibernate5Module hibernate5Module() { - return new Hibernate5Module(); - } - - /* - * Module for serialization/deserialization of RFC7807 Problem. - */ - @Bean - public ProblemModule problemModule() { - return new ProblemModule(); - } - - /* - * Module for serialization/deserialization of ConstraintViolationProblem. - */ - @Bean - public ConstraintViolationProblemModule constraintViolationProblemModule() { - return new ConstraintViolationProblemModule(); - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/config/LiquibaseConfiguration.java b/src/main/java/org/mskcc/oncokb/transcript/config/LiquibaseConfiguration.java deleted file mode 100644 index 40ba50dba..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/config/LiquibaseConfiguration.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.mskcc.oncokb.transcript.config; - -import java.util.concurrent.Executor; -import javax.sql.DataSource; -import liquibase.integration.spring.SpringLiquibase; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseDataSource; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.Environment; -import org.springframework.core.env.Profiles; -import tech.jhipster.config.JHipsterConstants; -import tech.jhipster.config.liquibase.SpringLiquibaseUtil; - -@Configuration -public class LiquibaseConfiguration { - - private final Logger log = LoggerFactory.getLogger(LiquibaseConfiguration.class); - - private final Environment env; - - public LiquibaseConfiguration(Environment env) { - this.env = env; - } - - @Bean - public SpringLiquibase liquibase( - @Qualifier("taskExecutor") Executor executor, - @LiquibaseDataSource ObjectProvider liquibaseDataSource, - LiquibaseProperties liquibaseProperties, - ObjectProvider dataSource, - DataSourceProperties dataSourceProperties - ) { - // If you don't want Liquibase to start asynchronously, substitute by this: - // SpringLiquibase liquibase = SpringLiquibaseUtil.createSpringLiquibase(liquibaseDataSource.getIfAvailable(), liquibaseProperties, dataSource.getIfUnique(), dataSourceProperties); - SpringLiquibase liquibase = SpringLiquibaseUtil.createAsyncSpringLiquibase( - this.env, - executor, - liquibaseDataSource.getIfAvailable(), - liquibaseProperties, - dataSource.getIfUnique(), - dataSourceProperties - ); - liquibase.setChangeLog("classpath:config/liquibase/master.xml"); - liquibase.setContexts(liquibaseProperties.getContexts()); - liquibase.setDefaultSchema(liquibaseProperties.getDefaultSchema()); - liquibase.setLiquibaseSchema(liquibaseProperties.getLiquibaseSchema()); - liquibase.setLiquibaseTablespace(liquibaseProperties.getLiquibaseTablespace()); - liquibase.setDatabaseChangeLogLockTable(liquibaseProperties.getDatabaseChangeLogLockTable()); - liquibase.setDatabaseChangeLogTable(liquibaseProperties.getDatabaseChangeLogTable()); - liquibase.setDropFirst(liquibaseProperties.isDropFirst()); - liquibase.setLabels(liquibaseProperties.getLabels()); - liquibase.setChangeLogParameters(liquibaseProperties.getParameters()); - liquibase.setRollbackFile(liquibaseProperties.getRollbackFile()); - liquibase.setTestRollbackOnUpdate(liquibaseProperties.isTestRollbackOnUpdate()); - if (env.acceptsProfiles(Profiles.of(JHipsterConstants.SPRING_PROFILE_NO_LIQUIBASE))) { - liquibase.setShouldRun(false); - } else { - liquibase.setShouldRun(liquibaseProperties.isEnabled()); - log.debug("Configuring Liquibase"); - } - return liquibase; - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/config/LocaleConfiguration.java b/src/main/java/org/mskcc/oncokb/transcript/config/LocaleConfiguration.java deleted file mode 100644 index 708408b4b..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/config/LocaleConfiguration.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.mskcc.oncokb.transcript.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.LocaleResolver; -import org.springframework.web.servlet.config.annotation.*; -import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; -import tech.jhipster.config.locale.AngularCookieLocaleResolver; - -@Configuration -public class LocaleConfiguration implements WebMvcConfigurer { - - @Bean - public LocaleResolver localeResolver() { - AngularCookieLocaleResolver cookieLocaleResolver = new AngularCookieLocaleResolver(); - cookieLocaleResolver.setCookieName("NG_TRANSLATE_LANG_KEY"); - return cookieLocaleResolver; - } - - @Override - public void addInterceptors(InterceptorRegistry registry) { - LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor(); - localeChangeInterceptor.setParamName("language"); - registry.addInterceptor(localeChangeInterceptor); - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/config/SecurityConfiguration.java b/src/main/java/org/mskcc/oncokb/transcript/config/SecurityConfiguration.java deleted file mode 100644 index 519684928..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/config/SecurityConfiguration.java +++ /dev/null @@ -1,92 +0,0 @@ -package org.mskcc.oncokb.transcript.config; - -import org.mskcc.oncokb.transcript.security.*; -import org.mskcc.oncokb.transcript.security.jwt.*; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpMethod; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.builders.WebSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.config.http.SessionCreationPolicy; -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; -import org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter; -import org.springframework.web.filter.CorsFilter; -import org.zalando.problem.spring.web.advice.security.SecurityProblemSupport; -import tech.jhipster.config.JHipsterProperties; - -@EnableWebSecurity -@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) -@Import(SecurityProblemSupport.class) -public class SecurityConfiguration extends WebSecurityConfigurerAdapter { - - private final JHipsterProperties jHipsterProperties; - - private final TokenProvider tokenProvider; - - private final CorsFilter corsFilter; - private final SecurityProblemSupport problemSupport; - - public SecurityConfiguration( - TokenProvider tokenProvider, - CorsFilter corsFilter, - JHipsterProperties jHipsterProperties, - SecurityProblemSupport problemSupport - ) { - this.tokenProvider = tokenProvider; - this.corsFilter = corsFilter; - this.problemSupport = problemSupport; - this.jHipsterProperties = jHipsterProperties; - } - - @Override - public void configure(WebSecurity web) { - web - .ignoring() - .antMatchers(HttpMethod.OPTIONS, "/**") - .antMatchers("/app/**/*.{js,html}") - .antMatchers("/i18n/**") - .antMatchers("/content/**") - .antMatchers("/swagger-ui/**") - .antMatchers("/test/**"); - } - - @Override - public void configure(HttpSecurity http) throws Exception { - // @formatter:off - http - .csrf() - .disable() - .addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class) - .exceptionHandling() - .authenticationEntryPoint(problemSupport) - .accessDeniedHandler(problemSupport) - .and() - .headers() - .contentSecurityPolicy(jHipsterProperties.getSecurity().getContentSecurityPolicy()) - .and() - .referrerPolicy(ReferrerPolicyHeaderWriter.ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN) - .and() - .featurePolicy("geolocation 'none'; midi 'none'; sync-xhr 'none'; microphone 'none'; camera 'none'; magnetometer 'none'; gyroscope 'none'; fullscreen 'self'; payment 'none'") - .and() - .frameOptions() - .deny() - .and() - .sessionManagement() - .sessionCreationPolicy(SessionCreationPolicy.STATELESS) - .and() - .authorizeRequests() - .antMatchers("/api/**").authenticated() - .and() - .httpBasic() - .and() - .apply(securityConfigurerAdapter()); - // @formatter:on - } - - private JWTConfigurer securityConfigurerAdapter() { - return new JWTConfigurer(tokenProvider); - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/config/cache/CacheCategory.java b/src/main/java/org/mskcc/oncokb/transcript/config/cache/CacheCategory.java deleted file mode 100644 index 79eb53d7e..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/config/cache/CacheCategory.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.mskcc.oncokb.transcript.config.cache; - -public enum CacheCategory { - GENE, - TRANSCRIPT, -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/config/cache/CacheKeys.java b/src/main/java/org/mskcc/oncokb/transcript/config/cache/CacheKeys.java deleted file mode 100644 index b656ad36d..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/config/cache/CacheKeys.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.mskcc.oncokb.transcript.config.cache; - -public final class CacheKeys { - - public static final String GENES_BY_ENTREZ_GENE_ID = "genesByEntrezGeneId"; - public static final String GENES_BY_HUGO_SYMBOL = "genesByHugoSymbol"; - public static final String GENE_ALIASES_BY_NAME = "geneAliasesByName"; - - public static final String TRANSCRIPTS_BY_ENSEMBL_TRANSCRIPT_IDS = "findByReferenceGenomeAndEnsemblTranscriptIdIsIn"; -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/config/cache/CacheNameResolver.java b/src/main/java/org/mskcc/oncokb/transcript/config/cache/CacheNameResolver.java deleted file mode 100644 index 2c7f73266..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/config/cache/CacheNameResolver.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.mskcc.oncokb.transcript.config.cache; - -import org.mskcc.oncokb.transcript.config.ApplicationProperties; -import org.springframework.stereotype.Component; - -@Component -public class CacheNameResolver { - - ApplicationProperties applicationProperties; - - public CacheNameResolver(ApplicationProperties applicationProperties) { - this.applicationProperties = applicationProperties; - } - - public String getCacheName(CacheCategory cacheCategory, String cacheKey) { - return applicationProperties.getName() + "-" + cacheCategory + "-" + cacheKey; - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/config/package-info.java b/src/main/java/org/mskcc/oncokb/transcript/config/package-info.java deleted file mode 100644 index 26c9bee16..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/config/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Spring Framework configuration files. - */ -package org.mskcc.oncokb.transcript.config; diff --git a/src/main/java/org/mskcc/oncokb/transcript/config/swagger/ApplicationSpringfoxCustomizer.java b/src/main/java/org/mskcc/oncokb/transcript/config/swagger/ApplicationSpringfoxCustomizer.java deleted file mode 100644 index eae993ad7..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/config/swagger/ApplicationSpringfoxCustomizer.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.mskcc.oncokb.transcript.config.swagger; - -import java.util.Collections; -import java.util.List; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import springfox.documentation.service.AuthorizationScope; -import springfox.documentation.service.HttpAuthenticationScheme; -import springfox.documentation.service.SecurityReference; -import springfox.documentation.spi.service.contexts.SecurityContext; -import springfox.documentation.spring.web.plugins.Docket; -import tech.jhipster.config.apidoc.customizer.SpringfoxCustomizer; - -/** - * Created by Hongxin Zhang on 2/17/21. - */ -public class ApplicationSpringfoxCustomizer implements SpringfoxCustomizer { - - private final Logger log = LoggerFactory.getLogger(ApplicationSpringfoxCustomizer.class); - - public ApplicationSpringfoxCustomizer() {} - - private SecurityContext securityContext() { - return SecurityContext.builder().securityReferences(defaultAuth()).build(); - } - - private List defaultAuth() { - final AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); - final AuthorizationScope[] authorizationScopes = new AuthorizationScope[] { authorizationScope }; - return Collections.singletonList(new SecurityReference("Authorization", authorizationScopes)); - } - - @Override - public void customize(Docket docket) { - log.debug("Customizing springfox docket..."); - HttpAuthenticationScheme authenticationScheme = HttpAuthenticationScheme.JWT_BEARER_BUILDER.name("Authorization").build(); - - docket - .securitySchemes(Collections.singletonList(authenticationScheme)) - .securityContexts(Collections.singletonList(securityContext())); - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/config/swagger/CustomSwaggerConfig.java b/src/main/java/org/mskcc/oncokb/transcript/config/swagger/CustomSwaggerConfig.java deleted file mode 100644 index 25d2213fd..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/config/swagger/CustomSwaggerConfig.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.mskcc.oncokb.transcript.config.swagger; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Created by Hongxin Zhang on 2/17/21. - */ -@Configuration -public class CustomSwaggerConfig { - - public CustomSwaggerConfig() {} - - @Bean - public ApplicationSpringfoxCustomizer applicationSwaggerCustomizer() { - return new ApplicationSpringfoxCustomizer(); - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/domain/Drug.java b/src/main/java/org/mskcc/oncokb/transcript/domain/Drug.java deleted file mode 100644 index a2bb0d578..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/domain/Drug.java +++ /dev/null @@ -1,152 +0,0 @@ -package org.mskcc.oncokb.transcript.domain; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import java.io.Serializable; -import java.util.HashSet; -import java.util.Set; -import javax.persistence.*; - -/** - * A Drug. - */ -@Entity -@Table(name = "drug") -public class Drug implements Serializable { - - private static final long serialVersionUID = 1L; - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "id") - private Long id; - - @Lob - @Column(name = "name") - private String name; - - @Column(name = "code") - private String code; - - @Lob - @Column(name = "semantic_type") - private String semanticType; - - @OneToMany(mappedBy = "drug", cascade = CascadeType.REMOVE, fetch = FetchType.EAGER) - @JsonIgnoreProperties(value = { "drug" }, allowSetters = true) - private Set synonyms = new HashSet<>(); - - // jhipster-needle-entity-add-field - JHipster will add fields here - - public Long getId() { - return this.id; - } - - public Drug id(Long id) { - this.setId(id); - return this; - } - - public void setId(Long id) { - this.id = id; - } - - public String getName() { - return this.name; - } - - public Drug name(String name) { - this.setName(name); - return this; - } - - public void setName(String name) { - this.name = name; - } - - public String getCode() { - return this.code; - } - - public Drug code(String code) { - this.setCode(code); - return this; - } - - public void setCode(String code) { - this.code = code; - } - - public String getSemanticType() { - return this.semanticType; - } - - public Drug semanticType(String semanticType) { - this.setSemanticType(semanticType); - return this; - } - - public void setSemanticType(String semanticType) { - this.semanticType = semanticType; - } - - public Set getSynonyms() { - return this.synonyms; - } - - public void setSynonyms(Set drugSynonyms) { - if (this.synonyms != null) { - this.synonyms.forEach(i -> i.setDrug(null)); - } - if (drugSynonyms != null) { - drugSynonyms.forEach(i -> i.setDrug(this)); - } - this.synonyms = drugSynonyms; - } - - public Drug synonyms(Set drugSynonyms) { - this.setSynonyms(drugSynonyms); - return this; - } - - public Drug addSynonyms(DrugSynonym drugSynonym) { - this.synonyms.add(drugSynonym); - drugSynonym.setDrug(this); - return this; - } - - public Drug removeSynonyms(DrugSynonym drugSynonym) { - this.synonyms.remove(drugSynonym); - drugSynonym.setDrug(null); - return this; - } - - // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof Drug)) { - return false; - } - return id != null && id.equals(((Drug) o).id); - } - - @Override - public int hashCode() { - // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ - return getClass().hashCode(); - } - - // prettier-ignore - @Override - public String toString() { - return "Drug{" + - "id=" + getId() + - ", name='" + getName() + "'" + - ", code='" + getCode() + "'" + - ", semanticType='" + getSemanticType() + "'" + - "}"; - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/domain/DrugSynonym.java b/src/main/java/org/mskcc/oncokb/transcript/domain/DrugSynonym.java deleted file mode 100644 index 91c3cddb6..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/domain/DrugSynonym.java +++ /dev/null @@ -1,97 +0,0 @@ -package org.mskcc.oncokb.transcript.domain; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import java.io.Serializable; -import javax.persistence.*; - -/** - * A DrugSynonym. - */ -@Entity -@Table(name = "drug_synonym") -public class DrugSynonym implements Serializable { - - private static final long serialVersionUID = 1L; - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "id") - private Long id; - - @Lob - @Column(name = "name") - private String name; - - @ManyToOne - @JsonIgnoreProperties(value = { "synonyms" }, allowSetters = true) - private Drug drug; - - // jhipster-needle-entity-add-field - JHipster will add fields here - - public Long getId() { - return this.id; - } - - public DrugSynonym id(Long id) { - this.setId(id); - return this; - } - - public void setId(Long id) { - this.id = id; - } - - public String getName() { - return this.name; - } - - public DrugSynonym name(String name) { - this.setName(name); - return this; - } - - public void setName(String name) { - this.name = name; - } - - public Drug getDrug() { - return this.drug; - } - - public void setDrug(Drug drug) { - this.drug = drug; - } - - public DrugSynonym drug(Drug drug) { - this.setDrug(drug); - return this; - } - - // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof DrugSynonym)) { - return false; - } - return id != null && id.equals(((DrugSynonym) o).id); - } - - @Override - public int hashCode() { - // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ - return getClass().hashCode(); - } - - // prettier-ignore - @Override - public String toString() { - return "DrugSynonym{" + - "id=" + getId() + - ", name='" + getName() + "'" + - "}"; - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/domain/Gene.java b/src/main/java/org/mskcc/oncokb/transcript/domain/Gene.java deleted file mode 100644 index 7d594a4e6..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/domain/Gene.java +++ /dev/null @@ -1,168 +0,0 @@ -package org.mskcc.oncokb.transcript.domain; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import java.io.Serializable; -import java.util.HashSet; -import java.util.Set; -import javax.persistence.*; - -/** - * A Gene. - */ -@Entity -@Table(name = "gene") -public class Gene implements Serializable { - - private static final long serialVersionUID = 1L; - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "id") - private Long id; - - @Column(name = "entrez_gene_id") - private Integer entrezGeneId; - - @Column(name = "hugo_symbol") - private String hugoSymbol; - - @OneToMany(mappedBy = "gene", cascade = CascadeType.ALL, fetch = FetchType.EAGER) - @JsonIgnoreProperties(value = { "gene" }, allowSetters = true) - private Set geneAliases = new HashSet<>(); - - @OneToMany(mappedBy = "gene", cascade = CascadeType.ALL, fetch = FetchType.EAGER) - @JsonIgnoreProperties(value = { "transcripts", "gene" }, allowSetters = true) - private Set ensemblGenes = new HashSet<>(); - - // jhipster-needle-entity-add-field - JHipster will add fields here - - public Long getId() { - return this.id; - } - - public Gene id(Long id) { - this.setId(id); - return this; - } - - public void setId(Long id) { - this.id = id; - } - - public Integer getEntrezGeneId() { - return this.entrezGeneId; - } - - public Gene entrezGeneId(Integer entrezGeneId) { - this.setEntrezGeneId(entrezGeneId); - return this; - } - - public void setEntrezGeneId(Integer entrezGeneId) { - this.entrezGeneId = entrezGeneId; - } - - public String getHugoSymbol() { - return this.hugoSymbol; - } - - public Gene hugoSymbol(String hugoSymbol) { - this.setHugoSymbol(hugoSymbol); - return this; - } - - public void setHugoSymbol(String hugoSymbol) { - this.hugoSymbol = hugoSymbol; - } - - public Set getGeneAliases() { - return this.geneAliases; - } - - public void setGeneAliases(Set geneAliases) { - if (this.geneAliases != null) { - this.geneAliases.forEach(i -> i.setGene(null)); - } - if (geneAliases != null) { - geneAliases.forEach(i -> i.setGene(this)); - } - this.geneAliases = geneAliases; - } - - public Gene geneAliases(Set geneAliases) { - this.setGeneAliases(geneAliases); - return this; - } - - public Gene addGeneAlias(GeneAlias geneAlias) { - this.geneAliases.add(geneAlias); - geneAlias.setGene(this); - return this; - } - - public Gene removeGeneAlias(GeneAlias geneAlias) { - this.geneAliases.remove(geneAlias); - geneAlias.setGene(null); - return this; - } - - public Set getEnsemblGenes() { - return this.ensemblGenes; - } - - public void setEnsemblGenes(Set ensemblGenes) { - if (this.ensemblGenes != null) { - this.ensemblGenes.forEach(i -> i.setGene(null)); - } - if (ensemblGenes != null) { - ensemblGenes.forEach(i -> i.setGene(this)); - } - this.ensemblGenes = ensemblGenes; - } - - public Gene ensemblGenes(Set ensemblGenes) { - this.setEnsemblGenes(ensemblGenes); - return this; - } - - public Gene addEnsemblGene(EnsemblGene ensemblGene) { - this.ensemblGenes.add(ensemblGene); - ensemblGene.setGene(this); - return this; - } - - public Gene removeEnsemblGene(EnsemblGene ensemblGene) { - this.ensemblGenes.remove(ensemblGene); - ensemblGene.setGene(null); - return this; - } - - // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof Gene)) { - return false; - } - return id != null && id.equals(((Gene) o).id); - } - - @Override - public int hashCode() { - // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ - return getClass().hashCode(); - } - - // prettier-ignore - @Override - public String toString() { - return "Gene{" + - "id=" + getId() + - ", entrezGeneId=" + getEntrezGeneId() + - ", hugoSymbol='" + getHugoSymbol() + "'" + - "}"; - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/domain/GeneAlias.java b/src/main/java/org/mskcc/oncokb/transcript/domain/GeneAlias.java deleted file mode 100644 index 4ca80a73b..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/domain/GeneAlias.java +++ /dev/null @@ -1,96 +0,0 @@ -package org.mskcc.oncokb.transcript.domain; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import java.io.Serializable; -import javax.persistence.*; - -/** - * A GeneAlias. - */ -@Entity -@Table(name = "gene_alias") -public class GeneAlias implements Serializable { - - private static final long serialVersionUID = 1L; - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "id") - private Long id; - - @Column(name = "name") - private String name; - - @ManyToOne - @JsonIgnoreProperties(value = { "geneAliases", "ensemblGenes" }, allowSetters = true) - private Gene gene; - - // jhipster-needle-entity-add-field - JHipster will add fields here - - public Long getId() { - return this.id; - } - - public GeneAlias id(Long id) { - this.setId(id); - return this; - } - - public void setId(Long id) { - this.id = id; - } - - public String getName() { - return this.name; - } - - public GeneAlias name(String name) { - this.setName(name); - return this; - } - - public void setName(String name) { - this.name = name; - } - - public Gene getGene() { - return this.gene; - } - - public void setGene(Gene gene) { - this.gene = gene; - } - - public GeneAlias gene(Gene gene) { - this.setGene(gene); - return this; - } - - // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof GeneAlias)) { - return false; - } - return id != null && id.equals(((GeneAlias) o).id); - } - - @Override - public int hashCode() { - // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ - return getClass().hashCode(); - } - - // prettier-ignore - @Override - public String toString() { - return "GeneAlias{" + - "id=" + getId() + - ", name='" + getName() + "'" + - "}"; - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/domain/GenomeFragment.java b/src/main/java/org/mskcc/oncokb/transcript/domain/GenomeFragment.java deleted file mode 100644 index 18dfcd483..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/domain/GenomeFragment.java +++ /dev/null @@ -1,166 +0,0 @@ -package org.mskcc.oncokb.transcript.domain; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import java.io.Serializable; -import javax.persistence.*; -import org.mskcc.oncokb.transcript.domain.enumeration.GenomeFragmentType; - -/** - * A GenomeFragment. - */ -@Entity -@Table(name = "genome_fragment") -public class GenomeFragment implements Serializable { - - private static final long serialVersionUID = 1L; - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "id") - private Long id; - - @Column(name = "chromosome") - private String chromosome; - - @Column(name = "start") - private Integer start; - - @Column(name = "end") - private Integer end; - - @Column(name = "strand") - private Integer strand; - - @Enumerated(EnumType.STRING) - @Column(name = "type") - private GenomeFragmentType type; - - @ManyToOne - @JsonIgnoreProperties(value = { "fragments", "sequences", "ensemblGene" }, allowSetters = true) - private Transcript transcript; - - // jhipster-needle-entity-add-field - JHipster will add fields here - - public Long getId() { - return this.id; - } - - public GenomeFragment id(Long id) { - this.setId(id); - return this; - } - - public void setId(Long id) { - this.id = id; - } - - public String getChromosome() { - return this.chromosome; - } - - public GenomeFragment chromosome(String chromosome) { - this.setChromosome(chromosome); - return this; - } - - public void setChromosome(String chromosome) { - this.chromosome = chromosome; - } - - public Integer getStart() { - return this.start; - } - - public GenomeFragment start(Integer start) { - this.setStart(start); - return this; - } - - public void setStart(Integer start) { - this.start = start; - } - - public Integer getEnd() { - return this.end; - } - - public GenomeFragment end(Integer end) { - this.setEnd(end); - return this; - } - - public void setEnd(Integer end) { - this.end = end; - } - - public Integer getStrand() { - return this.strand; - } - - public GenomeFragment strand(Integer strand) { - this.setStrand(strand); - return this; - } - - public void setStrand(Integer strand) { - this.strand = strand; - } - - public GenomeFragmentType getType() { - return this.type; - } - - public GenomeFragment type(GenomeFragmentType type) { - this.setType(type); - return this; - } - - public void setType(GenomeFragmentType type) { - this.type = type; - } - - public Transcript getTranscript() { - return this.transcript; - } - - public void setTranscript(Transcript transcript) { - this.transcript = transcript; - } - - public GenomeFragment transcript(Transcript transcript) { - this.setTranscript(transcript); - return this; - } - - // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof GenomeFragment)) { - return false; - } - return id != null && id.equals(((GenomeFragment) o).id); - } - - @Override - public int hashCode() { - // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ - return getClass().hashCode(); - } - - // prettier-ignore - @Override - public String toString() { - return "GenomeFragment{" + - "id=" + getId() + - ", chromosome='" + getChromosome() + "'" + - ", start=" + getStart() + - ", end=" + getEnd() + - ", strand=" + getStrand() + - ", type='" + getType() + "'" + - "}"; - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/domain/Transcript.java b/src/main/java/org/mskcc/oncokb/transcript/domain/Transcript.java deleted file mode 100644 index 768108919..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/domain/Transcript.java +++ /dev/null @@ -1,238 +0,0 @@ -package org.mskcc.oncokb.transcript.domain; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import java.io.Serializable; -import java.util.HashSet; -import java.util.Set; -import javax.persistence.*; -import javax.validation.constraints.*; - -/** - * A Transcript. - */ -@Entity -@Table(name = "transcript") -public class Transcript implements Serializable { - - private static final long serialVersionUID = 1L; - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "id") - private Long id; - - @Column(name = "ensembl_transcript_id") - private String ensemblTranscriptId; - - @NotNull - @Column(name = "canonical", nullable = false) - private Boolean canonical; - - @Column(name = "ensembl_protein_id") - private String ensemblProteinId; - - @Column(name = "reference_sequence_id") - private String referenceSequenceId; - - @Column(name = "description") - private String description; - - @OneToMany(mappedBy = "transcript") - @JsonIgnoreProperties(value = { "transcript" }, allowSetters = true) - private Set fragments = new HashSet<>(); - - @OneToMany(mappedBy = "transcript") - @JsonIgnoreProperties(value = { "transcript" }, allowSetters = true) - private Set sequences = new HashSet<>(); - - @ManyToOne - @JsonIgnoreProperties(value = { "transcripts", "gene" }, allowSetters = true) - private EnsemblGene ensemblGene; - - // jhipster-needle-entity-add-field - JHipster will add fields here - - public Long getId() { - return this.id; - } - - public Transcript id(Long id) { - this.setId(id); - return this; - } - - public void setId(Long id) { - this.id = id; - } - - public String getEnsemblTranscriptId() { - return this.ensemblTranscriptId; - } - - public Transcript ensemblTranscriptId(String ensemblTranscriptId) { - this.setEnsemblTranscriptId(ensemblTranscriptId); - return this; - } - - public void setEnsemblTranscriptId(String ensemblTranscriptId) { - this.ensemblTranscriptId = ensemblTranscriptId; - } - - public Boolean getCanonical() { - return this.canonical; - } - - public Transcript canonical(Boolean canonical) { - this.setCanonical(canonical); - return this; - } - - public void setCanonical(Boolean canonical) { - this.canonical = canonical; - } - - public String getEnsemblProteinId() { - return this.ensemblProteinId; - } - - public Transcript ensemblProteinId(String ensemblProteinId) { - this.setEnsemblProteinId(ensemblProteinId); - return this; - } - - public void setEnsemblProteinId(String ensemblProteinId) { - this.ensemblProteinId = ensemblProteinId; - } - - public String getReferenceSequenceId() { - return this.referenceSequenceId; - } - - public Transcript referenceSequenceId(String referenceSequenceId) { - this.setReferenceSequenceId(referenceSequenceId); - return this; - } - - public void setReferenceSequenceId(String referenceSequenceId) { - this.referenceSequenceId = referenceSequenceId; - } - - public String getDescription() { - return this.description; - } - - public Transcript description(String description) { - this.setDescription(description); - return this; - } - - public void setDescription(String description) { - this.description = description; - } - - public Set getFragments() { - return this.fragments; - } - - public void setFragments(Set genomeFragments) { - if (this.fragments != null) { - this.fragments.forEach(i -> i.setTranscript(null)); - } - if (genomeFragments != null) { - genomeFragments.forEach(i -> i.setTranscript(this)); - } - this.fragments = genomeFragments; - } - - public Transcript fragments(Set genomeFragments) { - this.setFragments(genomeFragments); - return this; - } - - public Transcript addFragments(GenomeFragment genomeFragment) { - this.fragments.add(genomeFragment); - genomeFragment.setTranscript(this); - return this; - } - - public Transcript removeFragments(GenomeFragment genomeFragment) { - this.fragments.remove(genomeFragment); - genomeFragment.setTranscript(null); - return this; - } - - public Set getSequences() { - return this.sequences; - } - - public void setSequences(Set sequences) { - if (this.sequences != null) { - this.sequences.forEach(i -> i.setTranscript(null)); - } - if (sequences != null) { - sequences.forEach(i -> i.setTranscript(this)); - } - this.sequences = sequences; - } - - public Transcript sequences(Set sequences) { - this.setSequences(sequences); - return this; - } - - public Transcript addSequence(Sequence sequence) { - this.sequences.add(sequence); - sequence.setTranscript(this); - return this; - } - - public Transcript removeSequence(Sequence sequence) { - this.sequences.remove(sequence); - sequence.setTranscript(null); - return this; - } - - public EnsemblGene getEnsemblGene() { - return this.ensemblGene; - } - - public void setEnsemblGene(EnsemblGene ensemblGene) { - this.ensemblGene = ensemblGene; - } - - public Transcript ensemblGene(EnsemblGene ensemblGene) { - this.setEnsemblGene(ensemblGene); - return this; - } - - // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof Transcript)) { - return false; - } - return id != null && id.equals(((Transcript) o).id); - } - - @Override - public int hashCode() { - // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ - return getClass().hashCode(); - } - - // prettier-ignore - @Override - public String toString() { - return "Transcript{" + - "id=" + getId() + - ", ensemblTranscriptId='" + getEnsemblTranscriptId() + "'" + - ", canonical='" + getCanonical() + "'" + - ", ensemblProteinId='" + getEnsemblProteinId() + "'" + - ", referenceSequenceId='" + getReferenceSequenceId() + "'" + - ", description='" + getDescription() + "'" + - "}"; - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/domain/enumeration/GenomeFragmentType.java b/src/main/java/org/mskcc/oncokb/transcript/domain/enumeration/GenomeFragmentType.java deleted file mode 100644 index 8e3295b9f..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/domain/enumeration/GenomeFragmentType.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.mskcc.oncokb.transcript.domain.enumeration; - -/** - * The GenomeFragmentType enumeration. - */ -public enum GenomeFragmentType { - GENE, - EXON, - FIVE_PRIME_UTR, - THREE_PRIME_UTR, -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/domain/enumeration/InfoType.java b/src/main/java/org/mskcc/oncokb/transcript/domain/enumeration/InfoType.java deleted file mode 100644 index a875b48dd..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/domain/enumeration/InfoType.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.mskcc.oncokb.transcript.domain.enumeration; - -/** - * The InfoType enumeration. - */ -public enum InfoType { - NCIT_VERSION, - GENE_LAST_UPDATED, -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/domain/enumeration/ReferenceGenome.java b/src/main/java/org/mskcc/oncokb/transcript/domain/enumeration/ReferenceGenome.java deleted file mode 100644 index b8a6f7c92..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/domain/enumeration/ReferenceGenome.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.mskcc.oncokb.transcript.domain.enumeration; - -/** - * The ReferenceGenome enumeration. - */ -public enum ReferenceGenome { - GRCh37, - GRCh38, -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/domain/enumeration/SequenceType.java b/src/main/java/org/mskcc/oncokb/transcript/domain/enumeration/SequenceType.java deleted file mode 100644 index fd552739e..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/domain/enumeration/SequenceType.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.mskcc.oncokb.transcript.domain.enumeration; - -/** - * The SequenceType enumeration. - */ -public enum SequenceType { - PROTEIN, - CDNA, -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/domain/package-info.java b/src/main/java/org/mskcc/oncokb/transcript/domain/package-info.java deleted file mode 100644 index 57be68e06..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/domain/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * JPA domain objects. - */ -package org.mskcc.oncokb.transcript.domain; diff --git a/src/main/java/org/mskcc/oncokb/transcript/importer/Importer.java b/src/main/java/org/mskcc/oncokb/transcript/importer/Importer.java deleted file mode 100644 index b2c0205a9..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/importer/Importer.java +++ /dev/null @@ -1,206 +0,0 @@ -package org.mskcc.oncokb.transcript.importer; - -import java.util.List; -import java.util.Optional; -import org.mskcc.oncokb.transcript.domain.EnsemblGene; -import org.mskcc.oncokb.transcript.domain.Sequence; -import org.mskcc.oncokb.transcript.domain.enumeration.ReferenceGenome; -import org.mskcc.oncokb.transcript.domain.enumeration.SequenceType; -import org.mskcc.oncokb.transcript.service.*; -import org.mskcc.oncokb.transcript.service.dto.TranscriptDTO; -import org.mskcc.oncokb.transcript.service.mapper.TranscriptMapper; -import org.oncokb.ApiException; -import org.oncokb.client.Gene; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -/** - * Created by Hongxin Zhang on 1/27/21. - */ -@Component -public class Importer { - - @Autowired - private OncoKbUrlService oncoKbUrlService; - - @Autowired - private GeneService geneService; - - @Autowired - private MainService mainService; - - @Autowired - private TranscriptService transcriptService; - - @Autowired - private TranscriptMapper transcriptMapper; - - @Autowired - private GenomeNexusService genomeNexusService; - - @Autowired - private EnsemblService ensemblService; - - @Autowired - private EnsemblGeneService ensemblGeneService; - - @Autowired - private SequenceService sequenceService; - - @Autowired - private AlignmentService alignmentService; - - private final Logger log = LoggerFactory.getLogger(Importer.class); - - public void generalImport() throws ApiException { - // try { - // geneService.updatePortalGenes(); - // } catch (IOException e) { - // e.printStackTrace(); - // } - // this.importOncoKbSequences(); - // importCanonicalEnsemblGenes(); - // importCanonicalEnsemblTranscripts(); - // checkOncoKbEnsemblGenes(); - checkOncoKbTranscriptSequenceAcrossRG(); - // importGeneFragments(); - } - - private void importCanonicalEnsemblGenes() { - List genes = geneService.findAll(); - for (ReferenceGenome rg : ReferenceGenome.values()) { - for (org.mskcc.oncokb.transcript.domain.Gene gene : genes) { - mainService.createCanonicalEnsemblGene(rg, gene.getEntrezGeneId()); - } - } - } - - private void importCanonicalEnsemblTranscripts() throws ApiException { - List genes = oncoKbUrlService.getGenes(); - for (int i = 0; i < genes.size(); i++) { - Gene gene = genes.get(i); - if (i % 100 == 0) { - log.info("Processing index {}", i); - } - // import canonical GRCh37 transcript - mainService.createTranscript(ReferenceGenome.GRCh37, gene.getGrch37Isoform(), gene.getEntrezGeneId(), true); - // import canonical GRCh38 transcript - mainService.createTranscript(ReferenceGenome.GRCh38, gene.getGrch38Isoform(), gene.getEntrezGeneId(), true); - } - } - - private void checkOncoKbEnsemblGenes() throws ApiException { - for (Gene gene : oncoKbUrlService.getGenes()) { - // check grch37 - Optional geneOptional = geneService.findGeneByEntrezGeneId(gene.getEntrezGeneId()); - if (geneOptional.isEmpty()) { - log.error("The OncoKB gene does not exist in transcript {}:{}", gene.getEntrezGeneId(), gene.getHugoSymbol()); - } else { - // grch37 - List ensembl37Genes = ensemblGeneService.findAllByGeneAndReferenceGenome( - geneOptional.get(), - ReferenceGenome.GRCh37 - ); - if (ensembl37Genes.size() > 0) { - ensembl37Genes.forEach(ensemblGene -> - log.info("Gene {}:{}, {}", gene.getEntrezGeneId(), gene.getHugoSymbol(), ensemblGene) - ); - } else { - log.error( - "No ensembl gene found for gene {} {}:{}", - ReferenceGenome.GRCh37, - gene.getEntrezGeneId(), - gene.getHugoSymbol() - ); - } - // grch38 - List ensembl38Genes = ensemblGeneService.findAllByGeneAndReferenceGenome( - geneOptional.get(), - ReferenceGenome.GRCh38 - ); - if (ensembl38Genes.size() > 0) { - ensembl38Genes.forEach(ensemblGene -> - log.info("Gene {}:{}, {}", gene.getEntrezGeneId(), gene.getHugoSymbol(), ensemblGene) - ); - } else { - log.error( - "No ensembl gene found for gene {} {}:{}", - ReferenceGenome.GRCh38, - gene.getEntrezGeneId(), - gene.getHugoSymbol() - ); - } - } - } - } - - private void checkOncoKbTranscriptSequenceAcrossRG() throws ApiException { - for (Gene gene : oncoKbUrlService.getGenes()) { - if (gene.getEntrezGeneId() <= 0) { - continue; - } - // check grch37 - Optional geneOptional = geneService.findGeneByEntrezGeneId(gene.getEntrezGeneId()); - if (geneOptional.isEmpty()) { - log.error("The OncoKB gene does not exist in transcript {}:{}", gene.getEntrezGeneId(), gene.getHugoSymbol()); - } else { - log.info("Checking gene {}:{}", gene.getEntrezGeneId(), gene.getHugoSymbol()); - Optional grch37TranscriptDtoOptional = transcriptService.findByReferenceGenomeAndEnsemblTranscriptId( - ReferenceGenome.GRCh37, - gene.getGrch37Isoform() - ); - Optional grch38TranscriptDtoOptional = transcriptService.findByReferenceGenomeAndEnsemblTranscriptId( - ReferenceGenome.GRCh38, - gene.getGrch38Isoform() - ); - - Optional sequenceGrch37Optional = Optional.empty(); - Optional sequenceGrch38Optional = Optional.empty(); - if (grch37TranscriptDtoOptional.isEmpty()) { - log.warn("\tNo GRCh37 transcript available"); - } else { - sequenceGrch37Optional = - sequenceService.findOneByTranscriptAndSequenceType( - transcriptMapper.toEntity(grch37TranscriptDtoOptional.get()), - SequenceType.PROTEIN - ); - if (sequenceGrch37Optional.isEmpty()) { - log.warn("\t\tNo GRCh37 transcript sequence"); - } - } - if (grch38TranscriptDtoOptional.isEmpty()) { - log.warn("\tNo GRCh38 transcript available"); - } else { - sequenceGrch38Optional = - sequenceService.findOneByTranscriptAndSequenceType( - transcriptMapper.toEntity(grch38TranscriptDtoOptional.get()), - SequenceType.PROTEIN - ); - if (sequenceGrch38Optional.isEmpty()) { - log.warn("\t\tNo GRCh38 transcript sequence"); - } - } - - if (sequenceGrch37Optional.isPresent() && sequenceGrch38Optional.isPresent()) { - if (sequenceGrch37Optional.get().getSequence().equals(sequenceGrch38Optional.get().getSequence())) { - log.info("\t\t Sequences match"); - } else { - log.warn("\t\t Sequences do not match"); - log.info( - "\t\t\t Alignment penalty {}", - alignmentService - .calcOptimalAlignment( - sequenceGrch37Optional.get().getSequence(), - sequenceGrch38Optional.get().getSequence(), - false - ) - .getPenalty() - ); - } - } - } - } - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/repository/DrugRepository.java b/src/main/java/org/mskcc/oncokb/transcript/repository/DrugRepository.java deleted file mode 100644 index 1fb861819..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/repository/DrugRepository.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.mskcc.oncokb.transcript.repository; - -import java.util.List; -import java.util.Optional; -import org.mskcc.oncokb.transcript.domain.Drug; -import org.springframework.data.jpa.repository.*; -import org.springframework.stereotype.Repository; - -/** - * Spring Data SQL repository for the Drug entity. - */ -@SuppressWarnings("unused") -@Repository -public interface DrugRepository extends JpaRepository { - Optional findOneByCode(String code); - - Optional findOneByName(String name); - - @Query( - "select distinct d from Drug d join d.synonyms ds where lower(d.name) like lower(concat('%', ?1,'%')) or lower(d.code) like lower(concat('%', ?1,'%')) or lower(ds.name) like lower(concat('%', ?1,'%'))" - ) - List searchDrug(String query); -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/repository/DrugSynonymRepository.java b/src/main/java/org/mskcc/oncokb/transcript/repository/DrugSynonymRepository.java deleted file mode 100644 index c62a42a53..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/repository/DrugSynonymRepository.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.mskcc.oncokb.transcript.repository; - -import org.mskcc.oncokb.transcript.domain.DrugSynonym; -import org.springframework.data.jpa.repository.*; -import org.springframework.stereotype.Repository; - -/** - * Spring Data SQL repository for the DrugSynonym entity. - */ -@SuppressWarnings("unused") -@Repository -public interface DrugSynonymRepository extends JpaRepository {} diff --git a/src/main/java/org/mskcc/oncokb/transcript/repository/EnsemblGeneRepository.java b/src/main/java/org/mskcc/oncokb/transcript/repository/EnsemblGeneRepository.java deleted file mode 100644 index 0fddbe1ba..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/repository/EnsemblGeneRepository.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.mskcc.oncokb.transcript.repository; - -import java.util.List; -import java.util.Optional; -import org.mskcc.oncokb.transcript.domain.EnsemblGene; -import org.mskcc.oncokb.transcript.domain.Gene; -import org.mskcc.oncokb.transcript.domain.enumeration.ReferenceGenome; -import org.springframework.data.jpa.repository.*; -import org.springframework.stereotype.Repository; - -/** - * Spring Data SQL repository for the EnsemblGene entity. - */ -@SuppressWarnings("unused") -@Repository -public interface EnsemblGeneRepository extends JpaRepository { - @Query("select eg from EnsemblGene eg join eg.gene g where g.entrezGeneId=?1 and eg.canonical=true and eg.referenceGenome=?2") - Optional findCanonicalEnsemblGene(Integer entrezGeneId, String referenceGenome); - - Optional findByEnsemblGeneIdAndReferenceGenome(String ensemblGeneId, String referenceGenome); - - List findAllByGeneAndReferenceGenome(Gene gene, String referenceGenome); - - List findAllByReferenceGenomeAndEnsemblGeneIdIn(String referenceGenome, List ensemblGeneIds); -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/repository/GeneAliasRepository.java b/src/main/java/org/mskcc/oncokb/transcript/repository/GeneAliasRepository.java deleted file mode 100644 index 1ec9caff7..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/repository/GeneAliasRepository.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.mskcc.oncokb.transcript.repository; - -import java.util.Optional; -import org.mskcc.oncokb.transcript.domain.GeneAlias; -import org.springframework.cache.annotation.Cacheable; -import org.springframework.data.jpa.repository.*; -import org.springframework.stereotype.Repository; - -/** - * Spring Data SQL repository for the GeneAlias entity. - */ -@SuppressWarnings("unused") -@Repository -public interface GeneAliasRepository extends JpaRepository { - @Cacheable(cacheResolver = "geneCacheResolver") - Optional findByName(String name); -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/repository/GeneRepository.java b/src/main/java/org/mskcc/oncokb/transcript/repository/GeneRepository.java deleted file mode 100644 index 3cdca2ec8..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/repository/GeneRepository.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.mskcc.oncokb.transcript.repository; - -import java.util.List; -import java.util.Optional; -import org.mskcc.oncokb.transcript.domain.Gene; -import org.springframework.cache.annotation.Cacheable; -import org.springframework.data.jpa.repository.*; -import org.springframework.stereotype.Repository; - -/** - * Spring Data SQL repository for the Gene entity. - */ -@SuppressWarnings("unused") -@Repository -public interface GeneRepository extends JpaRepository { - @Cacheable(cacheResolver = "geneCacheResolver") - Optional findByEntrezGeneId(Integer entrezGeneId); - - @Cacheable(cacheResolver = "geneCacheResolver") - Optional findByHugoSymbol(String hugoSymbol); - - @Query("select distinct g from Gene g left join fetch g.geneAliases ga left join fetch g.ensemblGenes eg") - List findAllWithGeneAliasAndEnsemblGenes(); -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/repository/GenomeFragmentRepository.java b/src/main/java/org/mskcc/oncokb/transcript/repository/GenomeFragmentRepository.java deleted file mode 100644 index 32fb55acc..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/repository/GenomeFragmentRepository.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.mskcc.oncokb.transcript.repository; - -import java.util.List; -import org.mskcc.oncokb.transcript.domain.GenomeFragment; -import org.springframework.data.jpa.repository.*; -import org.springframework.stereotype.Repository; - -/** - * Spring Data SQL repository for the GenomeFragment entity. - */ -@SuppressWarnings("unused") -@Repository -public interface GenomeFragmentRepository extends JpaRepository { - @Query("select genomeFragment from GenomeFragment genomeFragment where genomeFragment.transcript.id = ?1") - List findAllByTranscriptId(Long id); -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/repository/InfoRepository.java b/src/main/java/org/mskcc/oncokb/transcript/repository/InfoRepository.java deleted file mode 100644 index 37a9e6313..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/repository/InfoRepository.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.mskcc.oncokb.transcript.repository; - -import java.util.Optional; -import org.mskcc.oncokb.transcript.domain.Info; -import org.mskcc.oncokb.transcript.domain.enumeration.InfoType; -import org.springframework.data.jpa.repository.*; -import org.springframework.stereotype.Repository; - -/** - * Spring Data SQL repository for the Info entity. - */ -@SuppressWarnings("unused") -@Repository -public interface InfoRepository extends JpaRepository { - Optional findOneByType(InfoType type); -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/repository/SequenceRepository.java b/src/main/java/org/mskcc/oncokb/transcript/repository/SequenceRepository.java deleted file mode 100644 index 8102ebe02..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/repository/SequenceRepository.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.mskcc.oncokb.transcript.repository; - -import java.util.Optional; -import org.mskcc.oncokb.transcript.domain.Sequence; -import org.mskcc.oncokb.transcript.domain.Transcript; -import org.mskcc.oncokb.transcript.domain.enumeration.SequenceType; -import org.springframework.data.jpa.repository.*; -import org.springframework.stereotype.Repository; - -/** - * Spring Data SQL repository for the Sequence entity. - */ -@SuppressWarnings("unused") -@Repository -public interface SequenceRepository extends JpaRepository { - Optional findOneByTranscriptAndSequenceType(Transcript transcript, SequenceType sequenceType); -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/repository/TranscriptRepository.java b/src/main/java/org/mskcc/oncokb/transcript/repository/TranscriptRepository.java deleted file mode 100644 index 3827ab2bd..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/repository/TranscriptRepository.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.mskcc.oncokb.transcript.repository; - -import java.util.List; -import java.util.Optional; -import liquibase.pro.packaged.T; -import org.mskcc.oncokb.transcript.domain.EnsemblGene; -import org.mskcc.oncokb.transcript.domain.Transcript; -import org.springframework.cache.annotation.Cacheable; -import org.springframework.data.jpa.repository.*; -import org.springframework.stereotype.Repository; - -/** - * Spring Data SQL repository for the Transcript entity. - */ -@SuppressWarnings("unused") -@Repository -public interface TranscriptRepository extends JpaRepository { - @Query("select t from Transcript t join t.ensemblGene eg where eg.referenceGenome= ?1 and t.ensemblTranscriptId=?2") - Optional findByReferenceGenomeAndEnsemblTranscriptId(String referenceGenome, String ensemblTranscriptId); - - @Cacheable(cacheResolver = "transcriptCacheResolver") - @Query("select t from Transcript t join t.ensemblGene eg where eg.referenceGenome= ?1 and t.ensemblTranscriptId in ?2") - List findByReferenceGenomeAndEnsemblTranscriptIdIsIn(String referenceGenome, List ensemblTranscriptIds); - - List findByEnsemblGene(EnsemblGene ensemblGene); - - @Query("select t from Transcript t join t.ensemblGene eg where eg.referenceGenome= ?1 and t.ensemblTranscriptId in ?2") - List findByEnsemblGeneId(Integer entrezGeneId); - - Optional findByEnsemblGeneAndEnsemblTranscriptId(EnsemblGene ensemblGene, String ensemblTranscriptId); - - Optional findByEnsemblGeneAndCanonicalIsTrue(EnsemblGene ensemblGene); -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/repository/package-info.java b/src/main/java/org/mskcc/oncokb/transcript/repository/package-info.java deleted file mode 100644 index 5838440f3..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/repository/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Spring Data JPA repositories. - */ -package org.mskcc.oncokb.transcript.repository; diff --git a/src/main/java/org/mskcc/oncokb/transcript/security/AuthoritiesConstants.java b/src/main/java/org/mskcc/oncokb/transcript/security/AuthoritiesConstants.java deleted file mode 100644 index 476f1c982..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/security/AuthoritiesConstants.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.mskcc.oncokb.transcript.security; - -/** - * Constants for Spring Security authorities. - */ -public final class AuthoritiesConstants { - - public static final String ADMIN = "ROLE_ADMIN"; - - public static final String USER = "ROLE_USER"; - - public static final String ANONYMOUS = "ROLE_ANONYMOUS"; - - private AuthoritiesConstants() {} -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/security/SecurityUtils.java b/src/main/java/org/mskcc/oncokb/transcript/security/SecurityUtils.java deleted file mode 100644 index f59e10acb..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/security/SecurityUtils.java +++ /dev/null @@ -1,100 +0,0 @@ -package org.mskcc.oncokb.transcript.security; - -import java.util.Arrays; -import java.util.Optional; -import java.util.stream.Stream; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.userdetails.UserDetails; - -/** - * Utility class for Spring Security. - */ -public final class SecurityUtils { - - private SecurityUtils() {} - - /** - * Get the login of the current user. - * - * @return the login of the current user. - */ - public static Optional getCurrentUserLogin() { - SecurityContext securityContext = SecurityContextHolder.getContext(); - return Optional.ofNullable(extractPrincipal(securityContext.getAuthentication())); - } - - private static String extractPrincipal(Authentication authentication) { - if (authentication == null) { - return null; - } else if (authentication.getPrincipal() instanceof UserDetails) { - UserDetails springSecurityUser = (UserDetails) authentication.getPrincipal(); - return springSecurityUser.getUsername(); - } else if (authentication.getPrincipal() instanceof String) { - return (String) authentication.getPrincipal(); - } - return null; - } - - /** - * Get the JWT of the current user. - * - * @return the JWT of the current user. - */ - public static Optional getCurrentUserJWT() { - SecurityContext securityContext = SecurityContextHolder.getContext(); - return Optional - .ofNullable(securityContext.getAuthentication()) - .filter(authentication -> authentication.getCredentials() instanceof String) - .map(authentication -> (String) authentication.getCredentials()); - } - - /** - * Check if a user is authenticated. - * - * @return true if the user is authenticated, false otherwise. - */ - public static boolean isAuthenticated() { - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - return authentication != null && getAuthorities(authentication).noneMatch(AuthoritiesConstants.ANONYMOUS::equals); - } - - /** - * Checks if the current user has any of the authorities. - * - * @param authorities the authorities to check. - * @return true if the current user has any of the authorities, false otherwise. - */ - public static boolean hasCurrentUserAnyOfAuthorities(String... authorities) { - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - return ( - authentication != null && getAuthorities(authentication).anyMatch(authority -> Arrays.asList(authorities).contains(authority)) - ); - } - - /** - * Checks if the current user has none of the authorities. - * - * @param authorities the authorities to check. - * @return true if the current user has none of the authorities, false otherwise. - */ - public static boolean hasCurrentUserNoneOfAuthorities(String... authorities) { - return !hasCurrentUserAnyOfAuthorities(authorities); - } - - /** - * Checks if the current user has a specific authority. - * - * @param authority the authority to check. - * @return true if the current user has the authority, false otherwise. - */ - public static boolean hasCurrentUserThisAuthority(String authority) { - return hasCurrentUserAnyOfAuthorities(authority); - } - - private static Stream getAuthorities(Authentication authentication) { - return authentication.getAuthorities().stream().map(GrantedAuthority::getAuthority); - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/security/package-info.java b/src/main/java/org/mskcc/oncokb/transcript/security/package-info.java deleted file mode 100644 index cdde3089f..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/security/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Spring Security configuration. - */ -package org.mskcc.oncokb.transcript.security; diff --git a/src/main/java/org/mskcc/oncokb/transcript/service/DrugService.java b/src/main/java/org/mskcc/oncokb/transcript/service/DrugService.java deleted file mode 100644 index 45603bf9b..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/service/DrugService.java +++ /dev/null @@ -1,151 +0,0 @@ -package org.mskcc.oncokb.transcript.service; - -import java.util.Comparator; -import java.util.List; -import java.util.Optional; -import org.mskcc.oncokb.transcript.domain.Drug; -import org.mskcc.oncokb.transcript.repository.DrugRepository; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -/** - * Service Implementation for managing {@link Drug}. - */ -@Service -@Transactional -public class DrugService { - - private final Logger log = LoggerFactory.getLogger(DrugService.class); - - private final DrugRepository drugRepository; - - public DrugService(DrugRepository drugRepository) { - this.drugRepository = drugRepository; - } - - /** - * Save a drug. - * - * @param drug the entity to save. - * @return the persisted entity. - */ - public Drug save(Drug drug) { - log.debug("Request to save Drug : {}", drug); - return drugRepository.save(drug); - } - - /** - * Partially update a drug. - * - * @param drug the entity to update partially. - * @return the persisted entity. - */ - public Optional partialUpdate(Drug drug) { - log.debug("Request to partially update Drug : {}", drug); - - return drugRepository - .findById(drug.getId()) - .map(existingDrug -> { - if (drug.getName() != null) { - existingDrug.setName(drug.getName()); - } - if (drug.getCode() != null) { - existingDrug.setCode(drug.getCode()); - } - if (drug.getSemanticType() != null) { - existingDrug.setSemanticType(drug.getSemanticType()); - } - - return existingDrug; - }) - .map(drugRepository::save); - } - - /** - * Get all the drugs. - * - * @return the list of entities. - */ - @Transactional(readOnly = true) - public List findAll() { - log.debug("Request to get all Drugs"); - return drugRepository.findAll(); - } - - /** - * Get one drug by id. - * - * @param id the id of the entity. - * @return the entity. - */ - @Transactional(readOnly = true) - public Optional findOne(Long id) { - log.debug("Request to get Drug : {}", id); - return drugRepository.findById(id); - } - - public Optional findByCode(String code) { - return drugRepository.findOneByCode(code); - } - - public List searchDrug(String query) { - List result = drugRepository.searchDrug(query); - result.sort(new DrugComp(query)); - return result; - } - - /** - * Delete the drug by id. - * - * @param id the id of the entity. - */ - public void delete(Long id) { - log.debug("Request to delete Drug : {}", id); - drugRepository.deleteById(id); - } -} - -class DrugComp implements Comparator { - - private String keyword; - - public DrugComp(String keyword) { - this.keyword = keyword.toLowerCase(); - } - - @Override - public int compare(Drug e1, Drug e2) { - if (e1.getName().equalsIgnoreCase(keyword)) { - return -1; - } - if (e2.getName().equalsIgnoreCase(keyword)) { - return 1; - } - if (e1.getName().equalsIgnoreCase(keyword)) { - return -1; - } - if (e2.getName().equalsIgnoreCase(keyword)) { - return 1; - } - Integer index1 = e1.getName().indexOf(this.keyword); - Integer index2 = e2.getName().indexOf(this.keyword); - if (index1.equals(index2)) { - index1 = e1.getCode().indexOf(this.keyword); - index2 = e2.getCode().indexOf(this.keyword); - if (index1.equals(index2)) { - // In this moment, these are the matches from the synonyms. The order does not matter, so alphabetically sort base on drug name - return e1.getName().compareTo(e2.getName()); - } else { - if (index1.equals(-1)) return 1; - if (index2.equals(-1)) return -1; - return index1 - index2; - } - } else { - if (index1.equals(-1)) return 1; - if (index2.equals(-1)) return -1; - return index1 - index2; - } - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/service/DrugSynonymService.java b/src/main/java/org/mskcc/oncokb/transcript/service/DrugSynonymService.java deleted file mode 100644 index 5c2ba4324..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/service/DrugSynonymService.java +++ /dev/null @@ -1,91 +0,0 @@ -package org.mskcc.oncokb.transcript.service; - -import java.util.List; -import java.util.Optional; -import org.mskcc.oncokb.transcript.domain.DrugSynonym; -import org.mskcc.oncokb.transcript.repository.DrugSynonymRepository; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -/** - * Service Implementation for managing {@link DrugSynonym}. - */ -@Service -@Transactional -public class DrugSynonymService { - - private final Logger log = LoggerFactory.getLogger(DrugSynonymService.class); - - private final DrugSynonymRepository drugSynonymRepository; - - public DrugSynonymService(DrugSynonymRepository drugSynonymRepository) { - this.drugSynonymRepository = drugSynonymRepository; - } - - /** - * Save a drugSynonym. - * - * @param drugSynonym the entity to save. - * @return the persisted entity. - */ - public DrugSynonym save(DrugSynonym drugSynonym) { - log.debug("Request to save DrugSynonym : {}", drugSynonym); - return drugSynonymRepository.save(drugSynonym); - } - - /** - * Partially update a drugSynonym. - * - * @param drugSynonym the entity to update partially. - * @return the persisted entity. - */ - public Optional partialUpdate(DrugSynonym drugSynonym) { - log.debug("Request to partially update DrugSynonym : {}", drugSynonym); - - return drugSynonymRepository - .findById(drugSynonym.getId()) - .map(existingDrugSynonym -> { - if (drugSynonym.getName() != null) { - existingDrugSynonym.setName(drugSynonym.getName()); - } - - return existingDrugSynonym; - }) - .map(drugSynonymRepository::save); - } - - /** - * Get all the drugSynonyms. - * - * @return the list of entities. - */ - @Transactional(readOnly = true) - public List findAll() { - log.debug("Request to get all DrugSynonyms"); - return drugSynonymRepository.findAll(); - } - - /** - * Get one drugSynonym by id. - * - * @param id the id of the entity. - * @return the entity. - */ - @Transactional(readOnly = true) - public Optional findOne(Long id) { - log.debug("Request to get DrugSynonym : {}", id); - return drugSynonymRepository.findById(id); - } - - /** - * Delete the drugSynonym by id. - * - * @param id the id of the entity. - */ - public void delete(Long id) { - log.debug("Request to delete DrugSynonym : {}", id); - drugSynonymRepository.deleteById(id); - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/service/EnsemblService.java b/src/main/java/org/mskcc/oncokb/transcript/service/EnsemblService.java deleted file mode 100644 index b65a4d1a2..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/service/EnsemblService.java +++ /dev/null @@ -1,169 +0,0 @@ -package org.mskcc.oncokb.transcript.service; - -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; -import java.lang.reflect.Type; -import java.util.*; -import java.util.stream.Collectors; -import org.apache.commons.lang3.StringUtils; -import org.genome_nexus.ApiClient; -import org.genome_nexus.client.EnsemblControllerApi; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.mskcc.oncokb.transcript.domain.enumeration.ReferenceGenome; -import org.mskcc.oncokb.transcript.vm.ensembl.EnsemblSequence; -import org.mskcc.oncokb.transcript.vm.ensembl.EnsemblTranscript; -import org.springframework.http.*; -import org.springframework.stereotype.Service; -import org.springframework.util.CollectionUtils; -import org.springframework.web.client.RestClientException; -import org.springframework.web.client.RestTemplate; - -/** - * Created by Hongxin Zhang on 7/15/20. - */ -@Service -public class EnsemblService { - - public final String ENSEMBL_37_API_URL = "https://grch37.rest.ensembl.org"; - public final String ENSEMBL_38_API_URL = "https://rest.ensembl.org"; - - private String getSequenceGETUrl(ReferenceGenome referenceGenome, String transcript) { - return getEnsemblAPIUrl(referenceGenome) + "/sequence/id/" + transcript; - } - - private String getSequencePOSTUrl(ReferenceGenome referenceGenome) { - return getEnsemblAPIUrl(referenceGenome) + "/sequence/id"; - } - - public Optional getProteinSequence(ReferenceGenome referenceGenome, String transcript) { - HttpHeaders httpHeaders = new HttpHeaders(); - httpHeaders.setContentType(MediaType.APPLICATION_JSON); - HttpEntity entity = new HttpEntity<>(httpHeaders); - - RestTemplate restTemplate = new RestTemplate(); - try { - ResponseEntity response = restTemplate.exchange( - getSequenceGETUrl(referenceGenome, transcript), - HttpMethod.GET, - entity, - EnsemblSequence.class - ); - return Optional.of(response.getBody()); - } catch (RestClientException exception) { - exception.printStackTrace(); - return Optional.empty(); - } - } - - public List getProteinSequences(ReferenceGenome referenceGenome, List transcripts) { - if (transcripts.size() == 0) { - return new ArrayList<>(); - } - HttpHeaders httpHeaders = new HttpHeaders(); - httpHeaders.setContentType(MediaType.APPLICATION_JSON); - JSONObject jsonObject = new JSONObject(); - JSONArray jsonArray = new JSONArray(); - transcripts.stream().forEach(transcript -> jsonArray.put(transcript)); - try { - jsonObject.put("ids", jsonArray); - } catch (JSONException e) { - e.printStackTrace(); - } - HttpEntity entity = new HttpEntity<>(jsonObject.toString(), httpHeaders); - - RestTemplate restTemplate = new RestTemplate(); - ResponseEntity response = restTemplate.postForEntity( - getSequencePOSTUrl(referenceGenome), - entity, - EnsemblSequence[].class - ); - return Arrays.asList(response.getBody()); - } - - public Optional getTranscript( - ReferenceGenome referenceGenome, - String transcriptId - ) { - List ensemblTranscriptList = getIds( - referenceGenome, - Collections.singletonList(transcriptId), - true, - true - ); - return ensemblTranscriptList.size() > 0 ? Optional.of(ensemblTranscriptList.get(0)) : Optional.empty(); - } - - public Optional getId( - ReferenceGenome referenceGenome, - String id, - boolean includeUtr, - boolean expand - ) { - List ensemblTranscriptList = getIds( - referenceGenome, - Collections.singletonList(id), - includeUtr, - expand - ); - return ensemblTranscriptList.size() > 0 ? Optional.of(ensemblTranscriptList.get(0)) : Optional.empty(); - } - - public List getIds( - ReferenceGenome referenceGenome, - List ids, - boolean includeUtr, - boolean expand - ) { - if (ids.size() == 0) { - return new ArrayList<>(); - } - HttpHeaders httpHeaders = new HttpHeaders(); - httpHeaders.setContentType(MediaType.APPLICATION_JSON); - JSONObject jsonObject = new JSONObject(); - JSONArray jsonArray = new JSONArray(); - ids.stream().forEach(id -> jsonArray.put(id)); - try { - jsonObject.put("ids", jsonArray); - } catch (JSONException e) { - e.printStackTrace(); - } - HttpEntity entity = new HttpEntity<>(jsonObject.toString(), httpHeaders); - - RestTemplate restTemplate = new RestTemplate(); - String response = restTemplate.postForObject(getLookupPOSTUrl(referenceGenome, includeUtr, expand), entity, String.class); - Gson gson = new Gson(); - Type type = new TypeToken>() {}.getType(); - Map transcriptMap = gson.fromJson(response, type); - return transcriptMap.values().stream().filter(val -> val != null).collect(Collectors.toList()); - } - - private String getLookupPOSTUrl(ReferenceGenome referenceGenome, boolean includeUtr, boolean expand) { - StringBuilder sb = new StringBuilder(); - sb.append("/lookup/id"); - if (includeUtr || expand) { - List requestParams = new ArrayList<>(); - sb.append("?"); - if (includeUtr) { - requestParams.add("utr=1"); - } - if (expand) { - requestParams.add("expand=1"); - } - sb.append(StringUtils.join(requestParams, "&")); - } - return getEnsemblAPIUrl(referenceGenome) + sb; - } - - private String getEnsemblAPIUrl(ReferenceGenome referenceGenome) { - switch (referenceGenome) { - case GRCh37: - return ENSEMBL_37_API_URL; - case GRCh38: - return ENSEMBL_38_API_URL; - default: - return ""; - } - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/service/GeneAliasService.java b/src/main/java/org/mskcc/oncokb/transcript/service/GeneAliasService.java deleted file mode 100644 index c6e10e98b..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/service/GeneAliasService.java +++ /dev/null @@ -1,91 +0,0 @@ -package org.mskcc.oncokb.transcript.service; - -import java.util.List; -import java.util.Optional; -import org.mskcc.oncokb.transcript.domain.GeneAlias; -import org.mskcc.oncokb.transcript.repository.GeneAliasRepository; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -/** - * Service Implementation for managing {@link GeneAlias}. - */ -@Service -@Transactional -public class GeneAliasService { - - private final Logger log = LoggerFactory.getLogger(GeneAliasService.class); - - private final GeneAliasRepository geneAliasRepository; - - public GeneAliasService(GeneAliasRepository geneAliasRepository) { - this.geneAliasRepository = geneAliasRepository; - } - - /** - * Save a geneAlias. - * - * @param geneAlias the entity to save. - * @return the persisted entity. - */ - public GeneAlias save(GeneAlias geneAlias) { - log.debug("Request to save GeneAlias : {}", geneAlias); - return geneAliasRepository.save(geneAlias); - } - - /** - * Partially update a geneAlias. - * - * @param geneAlias the entity to update partially. - * @return the persisted entity. - */ - public Optional partialUpdate(GeneAlias geneAlias) { - log.debug("Request to partially update GeneAlias : {}", geneAlias); - - return geneAliasRepository - .findById(geneAlias.getId()) - .map(existingGeneAlias -> { - if (geneAlias.getName() != null) { - existingGeneAlias.setName(geneAlias.getName()); - } - - return existingGeneAlias; - }) - .map(geneAliasRepository::save); - } - - /** - * Get all the geneAliases. - * - * @return the list of entities. - */ - @Transactional(readOnly = true) - public List findAll() { - log.debug("Request to get all GeneAliases"); - return geneAliasRepository.findAll(); - } - - /** - * Get one geneAlias by id. - * - * @param id the id of the entity. - * @return the entity. - */ - @Transactional(readOnly = true) - public Optional findOne(Long id) { - log.debug("Request to get GeneAlias : {}", id); - return geneAliasRepository.findById(id); - } - - /** - * Delete the geneAlias by id. - * - * @param id the id of the entity. - */ - public void delete(Long id) { - log.debug("Request to delete GeneAlias : {}", id); - geneAliasRepository.deleteById(id); - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/service/GeneService.java b/src/main/java/org/mskcc/oncokb/transcript/service/GeneService.java deleted file mode 100644 index c002015ab..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/service/GeneService.java +++ /dev/null @@ -1,218 +0,0 @@ -package org.mskcc.oncokb.transcript.service; - -import static org.mskcc.oncokb.transcript.util.FileUtils.readTrimmedLinesStream; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.time.Instant; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.stream.Collectors; -import org.apache.commons.lang3.StringUtils; -import org.mskcc.oncokb.transcript.config.cache.CacheCategory; -import org.mskcc.oncokb.transcript.config.cache.CacheKeys; -import org.mskcc.oncokb.transcript.config.cache.CacheNameResolver; -import org.mskcc.oncokb.transcript.domain.Gene; -import org.mskcc.oncokb.transcript.domain.GeneAlias; -import org.mskcc.oncokb.transcript.domain.enumeration.InfoType; -import org.mskcc.oncokb.transcript.repository.GeneAliasRepository; -import org.mskcc.oncokb.transcript.repository.GeneRepository; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.cache.CacheManager; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -/** - * Service Implementation for managing {@link Gene}. - */ -@Service -@Transactional -public class GeneService { - - private final Logger log = LoggerFactory.getLogger(GeneService.class); - - private final String PORTAL_GENE_FILE = - "https://raw.githubusercontent.com/cBioPortal/datahub-study-curation-tools/master/gene-table-update/build-input-for-importer/gene_info.txt"; - private final String SYNONYM_SEPARATOR = "\\|"; - - private final GeneRepository geneRepository; - private final GeneAliasRepository geneAliasRepository; - private final InfoService infoService; - private final CacheNameResolver cacheNameResolver; - private final Optional optionalCacheManager; - - public GeneService( - GeneRepository geneRepository, - GeneAliasRepository geneAliasRepository, - InfoService infoService, - CacheNameResolver cacheNameResolver, - Optional optionalCacheManager - ) { - this.geneRepository = geneRepository; - this.geneAliasRepository = geneAliasRepository; - this.infoService = infoService; - this.cacheNameResolver = cacheNameResolver; - this.optionalCacheManager = optionalCacheManager; - } - - /** - * Save a gene. - * - * @param gene the entity to save. - * @return the persisted entity. - */ - public Gene save(Gene gene) { - log.debug("Request to save Gene : {}", gene); - return geneRepository.save(gene); - } - - /** - * Partially update a gene. - * - * @param gene the entity to update partially. - * @return the persisted entity. - */ - public Optional partialUpdate(Gene gene) { - log.debug("Request to partially update Gene : {}", gene); - - return geneRepository - .findById(gene.getId()) - .map(existingGene -> { - if (gene.getEntrezGeneId() != null) { - existingGene.setEntrezGeneId(gene.getEntrezGeneId()); - } - if (gene.getHugoSymbol() != null) { - existingGene.setHugoSymbol(gene.getHugoSymbol()); - } - - return existingGene; - }) - .map(geneRepository::save); - } - - /** - * Get all the genes. - * We do not use the default find all is because the FetchType.EAGER in the gene model. - * The default will trigger a lot of queries to the database. - * - * @return the list of entities. - */ - @Transactional(readOnly = true) - public List findAll() { - log.debug("Request to get all Genes"); - return geneRepository.findAllWithGeneAliasAndEnsemblGenes(); - } - - /** - * Get one gene by id. - * - * @param id the id of the entity. - * @return the entity. - */ - @Transactional(readOnly = true) - public Optional findOne(Long id) { - log.debug("Request to get Gene : {}", id); - return geneRepository.findById(id); - } - - /** - * Delete the gene by id. - * - * @param id the id of the entity. - */ - public void delete(Long id) { - log.debug("Request to delete Gene : {}", id); - geneRepository.deleteById(id); - } - - public Optional findGeneByEntrezGeneId(Integer entrezGeneId) { - return geneRepository.findByEntrezGeneId(entrezGeneId); - } - - public Optional findGeneByHugoSymbol(String hugoSymbol) { - return geneRepository.findByHugoSymbol(hugoSymbol.toLowerCase()); - } - - public Optional findGeneByAlias(String alias) { - Optional geneAliasOptional = geneAliasRepository.findByName(alias.toLowerCase()); - if (geneAliasOptional.isPresent()) { - return Optional.of(geneAliasOptional.get().getGene()); - } else { - return Optional.empty(); - } - } - - public void updatePortalGenes() throws IOException { - List portalGenes = getPortalGenes() - .stream() - .filter(gene -> gene[1].equalsIgnoreCase("BRAF")) - .collect(Collectors.toList()); - for (var i = 0; i < portalGenes.size(); i++) { - String[] line = portalGenes.get(i); - Integer entrezGeneId = Integer.parseInt(line[0]); - - Gene gene = new Gene(); - gene.setEntrezGeneId(entrezGeneId); - gene.setHugoSymbol(line[1]); - if (line.length > 5) { - gene.setGeneAliases( - Arrays - .stream(line[5].split(SYNONYM_SEPARATOR)) - .filter(synonym -> StringUtils.isNotEmpty(synonym.trim())) - .map(synonym -> { - GeneAlias geneAlias = new GeneAlias(); - geneAlias.setName(synonym.trim()); - return geneAlias; - }) - .collect(Collectors.toSet()) - ); - } - - Optional geneOptional = this.findGeneByEntrezGeneId(entrezGeneId); - if (geneOptional.isPresent()) { - geneRepository.delete(geneOptional.get()); - } - this.geneRepository.save(gene); - this.clearGeneCaches(); - if (i % 1000 == 0) { - System.out.println(i); - } - } - - this.infoService.updateInfo(InfoType.GENE_LAST_UPDATED, null, Instant.now()); - } - - private List getPortalGenes() throws IOException { - URL url = new URL(PORTAL_GENE_FILE); - InputStream is = url.openStream(); - List readmeFileLines = readTrimmedLinesStream(is); - - return readmeFileLines - .stream() - .map(line -> line.split("\t")) - .filter(line -> { - // as long as gene has entrez gene id and hugo symbol, we import - if (line.length >= 2) { - return StringUtils.isNumeric(line[0]); - } else { - return false; - } - }) - .collect(Collectors.toList()); - } - - private void clearGeneCaches() { - if (this.optionalCacheManager.isPresent()) { - for (String cacheKey : this.optionalCacheManager.get().getCacheNames()) { - String cacheKeyPrefix = this.cacheNameResolver.getCacheName(CacheCategory.GENE, ""); - if (cacheKey.startsWith(cacheKeyPrefix)) { - Objects.requireNonNull(this.optionalCacheManager.get().getCache(cacheKey)).clear(); - } - } - } - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/service/GenomeNexusService.java b/src/main/java/org/mskcc/oncokb/transcript/service/GenomeNexusService.java deleted file mode 100644 index b9f7a3e31..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/service/GenomeNexusService.java +++ /dev/null @@ -1,75 +0,0 @@ -package org.mskcc.oncokb.transcript.service; - -import static org.mskcc.oncokb.transcript.config.Constants.ENSEMBL_POST_THRESHOLD; - -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; -import org.genome_nexus.ApiClient; -import org.genome_nexus.ApiException; -import org.genome_nexus.client.EnsemblControllerApi; -import org.genome_nexus.client.EnsemblGene; -import org.mskcc.oncokb.transcript.domain.enumeration.ReferenceGenome; -import org.mskcc.oncokb.transcript.importer.Importer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; - -/** - * Created by Hongxin Zhang on 7/15/20. - */ -@Service -public class GenomeNexusService { - - public final String GN_37_URL = "https://www.genomenexus.org"; - public final String GN_38_URL = "https://grch38.genomenexus.org"; - private final int GN_READ_TIMEOUT_OVERRIDE = 30000; - - private final EnsemblControllerApi ensemblControllerApi38; - private final EnsemblControllerApi ensemblControllerApi37; - - private final Logger log = LoggerFactory.getLogger(GenomeNexusService.class); - - public GenomeNexusService() { - this.ensemblControllerApi37 = getGNEnsemblControllerApi(GN_37_URL); - this.ensemblControllerApi38 = getGNEnsemblControllerApi(GN_38_URL); - } - - private EnsemblControllerApi getGNEnsemblControllerApi(String url) { - ApiClient client = new ApiClient(); - client.setReadTimeout(GN_READ_TIMEOUT_OVERRIDE); - client.setBasePath(url); - return new EnsemblControllerApi(client); - } - - public EnsemblControllerApi getEnsemblControllerApi(ReferenceGenome referenceGenome) { - switch (referenceGenome) { - case GRCh37: - return this.ensemblControllerApi37; - case GRCh38: - return this.ensemblControllerApi38; - default: - return new EnsemblControllerApi(); - } - } - - public EnsemblGene findCanonicalEnsemblGeneTranscript(ReferenceGenome referenceGenome, Integer entrezGeneId) throws ApiException { - return this.getEnsemblControllerApi(referenceGenome).fetchCanonicalEnsemblGeneIdByEntrezGeneIdGET(Integer.toString(entrezGeneId)); - } - - public List findCanonicalEnsemblGeneTranscript(ReferenceGenome referenceGenome, List entrezGeneIds) - throws ApiException { - List ensemblGenesList = new ArrayList<>(); - List idStrs = entrezGeneIds.stream().map(id -> Integer.toString(id)).collect(Collectors.toList()); - log.info("Fetching canonical ensembl genes from GN, total {}", idStrs.size()); - int postThreshold = 1000; - for (int i = 0; i < idStrs.size(); i += postThreshold) { - log.info("\ton index {}", i); - ensemblGenesList.addAll( - this.getEnsemblControllerApi(referenceGenome) - .fetchCanonicalEnsemblGeneIdByEntrezGeneIdsPOST(idStrs.subList(i, Math.min(idStrs.toArray().length, i + postThreshold))) - ); - } - return ensemblGenesList; - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/service/MainService.java b/src/main/java/org/mskcc/oncokb/transcript/service/MainService.java deleted file mode 100644 index 9a30b8b7b..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/service/MainService.java +++ /dev/null @@ -1,265 +0,0 @@ -package org.mskcc.oncokb.transcript.service; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; -import javax.validation.constraints.NotNull; -import org.apache.commons.lang3.StringUtils; -import org.genome_nexus.ApiException; -import org.mskcc.oncokb.transcript.domain.EnsemblGene; -import org.mskcc.oncokb.transcript.domain.Gene; -import org.mskcc.oncokb.transcript.domain.GenomeFragment; -import org.mskcc.oncokb.transcript.domain.enumeration.GenomeFragmentType; -import org.mskcc.oncokb.transcript.domain.enumeration.ReferenceGenome; -import org.mskcc.oncokb.transcript.service.dto.TranscriptDTO; -import org.mskcc.oncokb.transcript.vm.ensembl.EnsemblTranscript; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@Transactional -public class MainService { - - private final Logger log = LoggerFactory.getLogger(MainService.class); - - private final TranscriptService transcriptService; - private final EnsemblService ensemblService; - private final EnsemblGeneService ensemblGeneService; - private final GeneService geneService; - private final GenomeNexusService genomeNexusService; - - public MainService( - TranscriptService transcriptService, - EnsemblService ensemblService, - GeneService geneService, - EnsemblGeneService ensemblGeneService, - GenomeNexusService genomeNexusService - ) { - this.transcriptService = transcriptService; - this.geneService = geneService; - this.ensemblService = ensemblService; - this.ensemblGeneService = ensemblGeneService; - this.genomeNexusService = genomeNexusService; - } - - public void createCanonicalEnsemblGene(@NotNull ReferenceGenome referenceGenome, @NotNull Integer entrezGeneId) { - Optional savedCanonicalEnsemblGeneOptional = ensemblGeneService.findCanonicalEnsemblGene( - entrezGeneId, - referenceGenome - ); - if (savedCanonicalEnsemblGeneOptional.isEmpty()) { - List ensemblGeneFromGN = new ArrayList<>(); - try { - ensemblGeneFromGN = - genomeNexusService.findCanonicalEnsemblGeneTranscript(referenceGenome, Collections.singletonList(entrezGeneId)); - if (ensemblGeneFromGN.size() > 0) { - org.genome_nexus.client.EnsemblGene ensemblGene = ensemblGeneFromGN.get(0); - if (StringUtils.isNotEmpty(ensemblGene.getGeneId())) { - Optional ensemblGeneOptional = createEnsemblGene( - referenceGenome, - ensemblGene.getGeneId(), - entrezGeneId, - true - ); - if (ensemblGeneOptional.isEmpty()) { - log.error("Failed to save the ensembl {} {} {}", referenceGenome, ensemblGene.getGeneId(), entrezGeneId); - } - } else { - log.warn("No ensembl gene id available {} {} {}", referenceGenome, entrezGeneId, ensemblGene); - } - } - } catch (ApiException e) { - e.printStackTrace(); - } - } - } - - public Optional createEnsemblGene( - @NotNull ReferenceGenome referenceGenome, - @NotNull String ensemblGeneId, - @NotNull Integer entrezGeneId, - @NotNull Boolean isCanonical - ) { - Optional previousSavedCanonicalEnsemblGeneOptional = ensemblGeneService.findCanonicalEnsemblGene( - entrezGeneId, - referenceGenome - ); - - Optional savedEnsemblGeneOptional = ensemblGeneService.findByEnsemblGeneIdAndReferenceGenome( - ensemblGeneId, - referenceGenome - ); - if (savedEnsemblGeneOptional.isEmpty()) { - Optional ensemblGeneOptional = ensemblService.getId( - referenceGenome, - ensemblGeneId, - true, - true - ); - Optional geneOptional = geneService.findGeneByEntrezGeneId(entrezGeneId); - if (ensemblGeneOptional.isPresent() && geneOptional.isPresent()) { - org.mskcc.oncokb.transcript.vm.ensembl.EnsemblTranscript remoteEnsemblGene = ensemblGeneOptional.get(); - EnsemblGene ensemblGene = new EnsemblGene(); - ensemblGene.setReferenceGenome(referenceGenome.name()); - ensemblGene.setEnsemblGeneId(remoteEnsemblGene.getId()); - ensemblGene.setChromosome(remoteEnsemblGene.getSeqRegionName()); - ensemblGene.setStart(remoteEnsemblGene.getStart()); - ensemblGene.setEnd(remoteEnsemblGene.getEnd()); - ensemblGene.setStrand(remoteEnsemblGene.getStrand()); - ensemblGene.setGene(geneOptional.get()); - ensemblGene.setCanonical(isCanonical); - savedEnsemblGeneOptional = Optional.of(ensemblGeneService.save(ensemblGene)); - } - } else if (savedEnsemblGeneOptional.get().getCanonical() != isCanonical) { - savedEnsemblGeneOptional.get().setCanonical(isCanonical); - savedEnsemblGeneOptional = ensemblGeneService.partialUpdate(savedEnsemblGeneOptional.get()); - } - if ( - savedEnsemblGeneOptional.isPresent() && - previousSavedCanonicalEnsemblGeneOptional.isPresent() && - !savedEnsemblGeneOptional.get().getEnsemblGeneId().equals(previousSavedCanonicalEnsemblGeneOptional.get().getEnsemblGeneId()) && - isCanonical - ) { - previousSavedCanonicalEnsemblGeneOptional.get().setCanonical(false); - ensemblGeneService.partialUpdate(previousSavedCanonicalEnsemblGeneOptional.get()); - } - return savedEnsemblGeneOptional; - } - - /** - * Create/Update transcript using the info. The method will include genome fragments if the ensemblTranscript is specified - * - * @param referenceGenome - * @param ensemblTranscriptId - * @return an optional with the saved transcript - */ - public Optional createTranscript( - @NotNull ReferenceGenome referenceGenome, - @NotNull String ensemblTranscriptId, - @NotNull Integer entrezGeneId, - @NotNull Boolean isCanonical - ) { - Optional ensemblTranscriptOptional = ensemblService.getTranscript(referenceGenome, ensemblTranscriptId); - if (ensemblTranscriptOptional.isPresent()) { - Optional savedEnsemblGeneOptional = createEnsemblGene( - referenceGenome, - ensemblTranscriptOptional.get().getParent(), - entrezGeneId, - isCanonical - ); - if (savedEnsemblGeneOptional.isPresent()) { - return createTranscript(savedEnsemblGeneOptional.get(), ensemblTranscriptOptional.get(), isCanonical); - } - } - return Optional.empty(); - } - - private Optional createTranscript( - @NotNull EnsemblGene ensemblGene, - @NotNull EnsemblTranscript ensemblTranscript, - @NotNull Boolean isCanonical - ) { - if (isCanonical) { - Optional canonicalTranscript = transcriptService.findByEnsemblGeneAndCanonicalIsTrue(ensemblGene); - if (canonicalTranscript.isPresent() && !canonicalTranscript.get().getEnsemblTranscriptId().equals(ensemblTranscript.getId())) { - canonicalTranscript.get().setCanonical(false); - transcriptService.partialUpdate(canonicalTranscript.get()); - } - } - - Optional transcriptDTOOptional = transcriptService.findByEnsemblGeneAndEnsemblTranscriptId( - ensemblGene, - ensemblTranscript.getId() - ); - if (transcriptDTOOptional.isPresent()) { - if (transcriptDTOOptional.get().getCanonical() != isCanonical) { - transcriptDTOOptional.get().setCanonical(isCanonical); - transcriptDTOOptional = transcriptService.partialUpdate(transcriptDTOOptional.get()); - } - return transcriptDTOOptional; - } - - Optional gnEnsemblTranscriptOptional = transcriptService.getEnsemblTranscript( - ensemblTranscript.getId(), - ReferenceGenome.valueOf(ensemblGene.getReferenceGenome()) - ); - if (gnEnsemblTranscriptOptional.isPresent()) { - org.genome_nexus.client.EnsemblTranscript gnEnsemblTranscript = gnEnsemblTranscriptOptional.get(); - - TranscriptDTO transcriptDTO = new TranscriptDTO(); - transcriptDTO.setEnsemblGene(ensemblGene); - transcriptDTO.setEnsemblTranscriptId(gnEnsemblTranscript.getTranscriptId()); - transcriptDTO.setEnsemblProteinId(gnEnsemblTranscript.getProteinId()); - transcriptDTO.setReferenceSequenceId(gnEnsemblTranscript.getRefseqMrnaId()); - transcriptDTO.setCanonical(isCanonical); - updateGenomeFragments(transcriptDTO, ensemblTranscript); - - Optional savedTranscriptDTO = Optional.of(transcriptService.save(transcriptDTO)); - return savedTranscriptDTO; - } else { - return Optional.empty(); - } - } - - private void updateGenomeFragments( - TranscriptDTO transcriptDTO, - org.mskcc.oncokb.transcript.vm.ensembl.EnsemblTranscript ensemblTranscript - ) { - // save gene fragment - transcriptDTO.setChromosome(ensemblTranscript.getSeqRegionName()); - transcriptDTO.setStart(ensemblTranscript.getStart()); - transcriptDTO.setEnd(ensemblTranscript.getEnd()); - transcriptDTO.setStrand(ensemblTranscript.getStrand()); - - // save UTRs - transcriptDTO.setUtrs( - ensemblTranscript - .getUtrs() - .stream() - .map(utr -> { - GenomeFragment utrFragment = new GenomeFragment(); - GenomeFragmentType genomeFragmentType = null; - switch (utr.getType()) { - case "five_prime_UTR": - genomeFragmentType = GenomeFragmentType.FIVE_PRIME_UTR; - break; - case "three_prime_UTR": - genomeFragmentType = GenomeFragmentType.THREE_PRIME_UTR; - break; - default: - break; - } - if (genomeFragmentType != null) { - utrFragment.setType(genomeFragmentType); - utrFragment.setStrand(utr.getStrand()); - utrFragment.setStart(utr.getStart()); - utrFragment.setEnd(utr.getEnd()); - utrFragment.setChromosome(utr.getSeqRegionName()); - } - return utrFragment; - }) - .collect(Collectors.toList()) - ); - - // save exons - transcriptDTO.setExons( - ensemblTranscript - .getExons() - .stream() - .map(utr -> { - GenomeFragment exonFragment = new GenomeFragment(); - exonFragment.setType(GenomeFragmentType.EXON); - exonFragment.setStrand(utr.getStrand()); - exonFragment.setStart(utr.getStart()); - exonFragment.setEnd(utr.getEnd()); - exonFragment.setChromosome(utr.getSeqRegionName()); - return exonFragment; - }) - .collect(Collectors.toList()) - ); - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/service/NcitService.java b/src/main/java/org/mskcc/oncokb/transcript/service/NcitService.java deleted file mode 100644 index 384f15d45..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/service/NcitService.java +++ /dev/null @@ -1,145 +0,0 @@ -package org.mskcc.oncokb.transcript.service; - -import static org.mskcc.oncokb.transcript.util.FileUtils.readTrimmedLinesStream; -import static org.mskcc.oncokb.transcript.util.GzipUtils.deCompress; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.nio.charset.Charset; -import java.time.Instant; -import java.util.*; -import java.util.stream.Collectors; -import org.apache.commons.lang3.StringUtils; -import org.mskcc.oncokb.transcript.domain.Drug; -import org.mskcc.oncokb.transcript.domain.DrugSynonym; -import org.mskcc.oncokb.transcript.domain.enumeration.InfoType; -import org.mskcc.oncokb.transcript.repository.DrugRepository; -import org.mskcc.oncokb.transcript.repository.DrugSynonymRepository; -import org.mskcc.oncokb.transcript.util.COMPRESSED_FILE_FORMAT; -import org.oncokb.ApiException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -/** - * Created by Hongxin Zhang on 4/21/21. - */ -@Service -public class NcitService { - - private final String NCIT_DOWNLOAD_URL = "https://evs.nci.nih.gov/ftp1/NCI_Thesaurus/"; - private final String NCIT_README = NCIT_DOWNLOAD_URL + "ReadMe.txt"; - private final String NCIT_DATA_FILE = NCIT_DOWNLOAD_URL + "Thesaurus.FLAT.zip"; - - private final String SYNONYMS_SEPARATOR_REGEX = "\\|"; - - @Autowired - private DrugRepository drugRepository; - - @Autowired - private DrugSynonymRepository drugSynonymRepository; - - @Autowired - private InfoService infoService; - - public String updateNcitDrugs() throws IOException, ApiException { - String ncitVersion = getNcitLatestVersion(); - if (ncitVersion == null) { - throw new ApiException("The NCIT README file has no content. Link to the README: " + NCIT_README); - } else { - saveNcitData(); - this.infoService.updateInfo(InfoType.NCIT_VERSION, ncitVersion, Instant.now()); - return ncitVersion; - } - } - - private String getNcitLatestVersion() throws IOException { - URL url = new URL(NCIT_README); - InputStream is = url.openStream(); - List readmeFileLines = readTrimmedLinesStream(is); - if (readmeFileLines.size() > 0) { - return readmeFileLines.get(0); - } else { - return null; - } - } - - private void saveNcitData() throws IOException { - URL url = new URL(NCIT_DATA_FILE); - InputStream is = url.openStream(); - ByteArrayOutputStream os = new ByteArrayOutputStream(); - deCompress(is, os, COMPRESSED_FILE_FORMAT.ZIP); - saveNcitDataToDB(Arrays.asList(os.toString(Charset.forName("UTF-8")).split("\n"))); - } - - public void saveNcitDataToDB(List lines) { - for (int i = 0; i < lines.size(); i++) { - String line = lines.get(i); - if (line.startsWith("#")) continue; - - // Skip the title - if (line.startsWith("Code")) continue; - - String[] parts = line.split("\t"); - if (parts.length >= 6) { - String code = parts[0]; - Optional matchedDrugOptional = drugRepository.findOneByCode(code); - - List synonyms = Arrays - .asList((parts[3] == null ? "" : parts[3]).split(SYNONYMS_SEPARATOR_REGEX)) - .stream() - .map(synonym -> synonym.trim()) - .distinct() - .collect(Collectors.toList()); - String name = parts[5]; - if (StringUtils.isEmpty(name) && synonyms.size() > 0) { - name = synonyms.get(0); - } - String semanticType = parts.length >= 8 ? parts[7] : null; - - if (matchedDrugOptional.isPresent()) { - Drug drug = matchedDrugOptional.get(); - - Set existSynonyms = drug.getSynonyms().stream().map(synonym -> synonym.getName()).collect(Collectors.toSet()); - existSynonyms.add(drug.getName()); - synonyms - .stream() - .forEach(synonym -> { - if (!existSynonyms.contains(synonym)) { - DrugSynonym drugSynonym = new DrugSynonym(); - drugSynonym.setDrug(drug); - drugSynonym.setName(synonym); - drugSynonymRepository.save(drugSynonym); - } - }); - - if (!Objects.equals(drug.getSemanticType(), semanticType)) { - drug.setSemanticType(semanticType); - drugRepository.save(drug); - } - } else { - Drug drug = new Drug(); - drug.setCode(code); - drug.setName(name); - drug.setSemanticType(semanticType); - if (synonyms != null) { - synonyms.remove(name); - Set synonymSet = synonyms - .stream() - .map(synonym -> { - DrugSynonym drugSynonym = new DrugSynonym(); - drugSynonym.setName(synonym.trim()); - drugSynonym.setDrug(drug); - return drugSynonym; - }) - .collect(Collectors.toSet()); - drug.setSynonyms(synonymSet); - } - drugRepository.save(drug); - drugSynonymRepository.saveAll(drug.getSynonyms()); - } - } - } - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/service/OncoKbUrlService.java b/src/main/java/org/mskcc/oncokb/transcript/service/OncoKbUrlService.java deleted file mode 100644 index 64f1a4873..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/service/OncoKbUrlService.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.mskcc.oncokb.transcript.service; - -import java.util.List; -import org.apache.commons.lang3.StringUtils; -import org.mskcc.oncokb.transcript.config.ApplicationProperties; -import org.oncokb.ApiClient; -import org.oncokb.ApiException; -import org.oncokb.client.Gene; -import org.oncokb.client.GenesApi; -import org.springframework.stereotype.Service; - -/** - * Created by Hongxin Zhang on 7/15/20. - */ -@Service -public class OncoKbUrlService { - - public final String ONCOKB_API_URL = "https://www.oncokb.org/api/v1"; - - private final int ONCOKB_READ_TIMEOUT_OVERRIDE = 30000; - - private final ApiClient apiClient; - - private ApplicationProperties applicationProperties; - - public OncoKbUrlService(ApplicationProperties applicationProperties) { - this.applicationProperties = applicationProperties; - - ApiClient client = new ApiClient(); - client.setReadTimeout(ONCOKB_READ_TIMEOUT_OVERRIDE); - if (applicationProperties.getOncokb() != null) { - client.setBasePath( - StringUtils.isEmpty(applicationProperties.getOncokb().getUrl()) - ? ONCOKB_API_URL - : applicationProperties.getOncokb().getUrl() - ); - client.setApiKey(applicationProperties.getOncokb().getApiKey()); - } - client.setApiKeyPrefix("Bearer"); - - this.apiClient = client; - } - - public List getGenes() throws ApiException { - GenesApi genesApi = new GenesApi(this.apiClient); - return genesApi.genesGetUsingGET(null); - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/service/TranscriptService.java b/src/main/java/org/mskcc/oncokb/transcript/service/TranscriptService.java deleted file mode 100644 index a95f0c5c0..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/service/TranscriptService.java +++ /dev/null @@ -1,546 +0,0 @@ -package org.mskcc.oncokb.transcript.service; - -import static org.mskcc.oncokb.transcript.config.Constants.ENSEMBL_POST_THRESHOLD; - -import java.util.*; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; -import org.apache.commons.lang3.StringUtils; -import org.genome_nexus.ApiException; -import org.genome_nexus.client.EnsemblControllerApi; -import org.genome_nexus.client.EnsemblTranscript; -import org.mskcc.oncokb.transcript.config.cache.CacheCategory; -import org.mskcc.oncokb.transcript.config.cache.CacheNameResolver; -import org.mskcc.oncokb.transcript.domain.*; -import org.mskcc.oncokb.transcript.domain.enumeration.GenomeFragmentType; -import org.mskcc.oncokb.transcript.domain.enumeration.ReferenceGenome; -import org.mskcc.oncokb.transcript.domain.enumeration.SequenceType; -import org.mskcc.oncokb.transcript.repository.TranscriptRepository; -import org.mskcc.oncokb.transcript.service.dto.TranscriptDTO; -import org.mskcc.oncokb.transcript.service.mapper.TranscriptMapper; -import org.mskcc.oncokb.transcript.vm.MissMatchPairVM; -import org.mskcc.oncokb.transcript.vm.TranscriptMatchResultVM; -import org.mskcc.oncokb.transcript.vm.TranscriptPairVM; -import org.mskcc.oncokb.transcript.vm.ensembl.EnsemblSequence; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.cache.CacheManager; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -/** - * Service Implementation for managing {@link Transcript}. - */ -@Service -@Transactional -public class TranscriptService { - - private final GenomeNexusService genomeNexusService; - private final EnsemblService ensemblService; - private final AlignmentService alignmentService; - private final SequenceService sequenceService; - private final TranscriptMapper transcriptMapper; - private final CacheNameResolver cacheNameResolver; - private final Optional optionalCacheManager; - - private final Logger log = LoggerFactory.getLogger(TranscriptService.class); - - private final TranscriptRepository transcriptRepository; - private final GenomeFragmentService genomeFragmentService; - - public TranscriptService( - GenomeNexusService genomeNexusService, - EnsemblService ensemblService, - AlignmentService alignmentService, - SequenceService sequenceService, - TranscriptRepository transcriptRepository, - TranscriptMapper transcriptMapper, - GenomeFragmentService genomeFragmentService, - CacheNameResolver cacheNameResolver, - Optional optionalCacheManager - ) { - this.genomeNexusService = genomeNexusService; - this.ensemblService = ensemblService; - this.alignmentService = alignmentService; - this.sequenceService = sequenceService; - this.transcriptRepository = transcriptRepository; - this.transcriptMapper = transcriptMapper; - this.genomeFragmentService = genomeFragmentService; - this.cacheNameResolver = cacheNameResolver; - this.optionalCacheManager = optionalCacheManager; - } - - /** - * Save a transcript. - * - * @param transcriptDTO the entity to save. - * @return the persisted entity. - */ - public TranscriptDTO save(TranscriptDTO transcriptDTO) { - log.debug("Request to save Transcript : {}", transcriptDTO); - Transcript transcript = transcriptMapper.toEntity(transcriptDTO); - Transcript savedTranscript = transcriptRepository.save(transcript); - - List transcriptGenomeFragments = genomeFragmentService.findAllByTranscriptId(transcriptDTO.getId()); - genomeFragmentService.deleteAll(transcriptGenomeFragments); - - GenomeFragment genomeFragment = new GenomeFragment(); - genomeFragment.setTranscript(savedTranscript); - genomeFragment.setChromosome(transcriptDTO.getChromosome()); - genomeFragment.setStart(transcriptDTO.getStart()); - genomeFragment.setEnd(transcriptDTO.getEnd()); - genomeFragment.setStrand(transcriptDTO.getStrand()); - genomeFragment.setType(GenomeFragmentType.GENE); - genomeFragmentService.save(genomeFragment); - - transcriptDTO.getExons().stream().forEach(exon -> exon.setTranscript(savedTranscript)); - genomeFragmentService.saveAll(transcriptDTO.getExons()); - transcriptDTO.getUtrs().stream().forEach(utr -> utr.setTranscript(savedTranscript)); - genomeFragmentService.saveAll(transcriptDTO.getUtrs()); - - // save sequence automatically when a new transcript saved - Optional sequenceOptional = sequenceService.findOneByTranscriptAndSequenceType(savedTranscript, SequenceType.PROTEIN); - if (sequenceOptional.isEmpty() && StringUtils.isNotEmpty(savedTranscript.getEnsemblProteinId())) { - Optional ensemblSequenceOptional = ensemblService.getProteinSequence( - ReferenceGenome.valueOf(savedTranscript.getEnsemblGene().getReferenceGenome()), - savedTranscript.getEnsemblProteinId() - ); - if (ensemblSequenceOptional.isPresent()) { - Sequence sequence = new Sequence(); - sequence.setTranscript(savedTranscript); - sequence.setSequenceType(SequenceType.PROTEIN); - sequence.setSequence(ensemblSequenceOptional.get().getSeq()); - sequenceService.save(sequence); - } - } - clearTranscriptCaches(); - return transcriptMapper.toDto(savedTranscript); - } - - /** - * Partially update a transcript. - * - * @param transcriptDTO the entity to update partially. - * @return the persisted entity. - */ - public Optional partialUpdate(TranscriptDTO transcriptDTO) { - log.debug("Request to partially update Transcript : {}", transcriptDTO); - - return transcriptRepository - .findById(transcriptDTO.getId()) - .map(existingTranscript -> { - transcriptMapper.partialUpdate(existingTranscript, transcriptDTO); - - return existingTranscript; - }) - .map(transcriptRepository::save) - .map(transcriptMapper::toDto); - } - - /** - * Get all the transcripts. - * - * @return the list of entities. - */ - @Transactional(readOnly = true) - public List findAll() { - log.debug("Request to get all Transcripts"); - return transcriptRepository.findAll().stream().map(transcriptMapper::toDto).collect(Collectors.toCollection(LinkedList::new)); - } - - /** - * Get one transcript by id. - * - * @param id the id of the entity. - * @return the entity. - */ - @Transactional(readOnly = true) - public Optional findOne(Long id) { - log.debug("Request to get Transcript : {}", id); - return transcriptRepository.findById(id).map(transcriptMapper::toDto); - } - - /** - * Delete the transcript by id. - * - * @param id the id of the entity. - */ - public void delete(Long id) { - log.debug("Request to delete Transcript : {}", id); - transcriptRepository.deleteById(id); - } - - public Optional findByEnsemblGeneAndEnsemblTranscriptId(EnsemblGene ensemblGene, String ensembleTranscriptId) { - log.debug( - "Request to get transcript by ensembl gene and transcript id : {} {} {}", - ensemblGene.getReferenceGenome(), - ensemblGene.getEnsemblGeneId(), - ensembleTranscriptId - ); - Optional transcriptOptional = transcriptRepository.findByEnsemblGeneAndEnsemblTranscriptId( - ensemblGene, - ensembleTranscriptId - ); - if (transcriptOptional.isPresent()) { - return Optional.of(transcriptMapper.toDto(transcriptOptional.get())); - } else { - return Optional.empty(); - } - } - - public Optional findByEnsemblGeneAndCanonicalIsTrue(EnsemblGene ensemblGene) { - log.debug( - "Request to find canonical transcript for given ensembl gene : {} {}", - ensemblGene.getReferenceGenome(), - ensemblGene.getEnsemblGeneId() - ); - Optional transcriptOptional = transcriptRepository.findByEnsemblGeneAndCanonicalIsTrue(ensemblGene); - if (transcriptOptional.isPresent()) { - return Optional.of(transcriptMapper.toDto(transcriptOptional.get())); - } else { - return Optional.empty(); - } - } - - /** - * Get trancript by reference genome and ensembleTranscriptId - * - * @param referenceGenome - * @param ensembleTranscriptId - * @return - */ - @Transactional(readOnly = true) - public Optional findByReferenceGenomeAndEnsemblTranscriptId( - ReferenceGenome referenceGenome, - String ensembleTranscriptId - ) { - log.debug("Request to get Sequence : {}", ensembleTranscriptId); - Optional transcriptOptional = transcriptRepository.findByReferenceGenomeAndEnsemblTranscriptId( - referenceGenome.name(), - ensembleTranscriptId - ); - if (transcriptOptional.isPresent()) { - return Optional.of(transcriptMapper.toDto(transcriptOptional.get())); - } else { - return Optional.empty(); - } - } - - @Transactional(readOnly = true) - public List findByReferenceGenomeAndEnsemblTranscriptIdIsIn( - ReferenceGenome referenceGenome, - List ensemblTranscriptIds - ) { - return transcriptRepository - .findByReferenceGenomeAndEnsemblTranscriptIdIsIn(referenceGenome.name(), ensemblTranscriptIds) - .stream() - .map(transcriptMapper::toDto) - .collect(Collectors.toList()); - } - - @Transactional(readOnly = true) - public List findByEnsemblGene(EnsemblGene ensemblGene) { - return transcriptMapper.toDto(transcriptRepository.findByEnsemblGene(ensemblGene)); - } - - public List getTranscriptsWithMatchedResidue( - ReferenceGenome referenceGenome, - List transcripts, - int proteinPosition, - String expectedAllele - ) { - return transcripts - .stream() - .filter(ensemblTranscript -> StringUtils.isNotEmpty(ensemblTranscript.getProteinId())) - .filter(ensemblTranscript -> { - Optional sequence = ensemblService.getProteinSequence(referenceGenome, ensemblTranscript.getProteinId()); - if (sequence.isPresent()) { - if (sequence.get().getSeq().length() >= proteinPosition) { - return sequence.get().getSeq().substring(proteinPosition - 1, proteinPosition).equals(expectedAllele); - } else { - return false; - } - } else { - return false; - } - }) - .collect(Collectors.toList()); - } - - public TranscriptMatchResultVM matchTranscript(TranscriptPairVM transcript, ReferenceGenome referenceGenome, String hugoSymbol) { - // Find whether both transcript length are the same - Optional _ensemblTranscript = Optional.empty(); - try { - _ensemblTranscript = getEnsemblTranscript(hugoSymbol, transcript); - } catch (ApiException e) { - e.printStackTrace(); - } - TranscriptMatchResultVM transcriptMatchResultVM = new TranscriptMatchResultVM(); - - if (_ensemblTranscript.isPresent()) { - transcriptMatchResultVM.setOriginalEnsemblTranscript(_ensemblTranscript.get()); - Optional _sequence = ensemblService.getProteinSequence( - transcript.getReferenceGenome(), - _ensemblTranscript.get().getProteinId() - ); - if (_sequence.isPresent()) { - List targetEnsemblTranscripts = getEnsemblTranscriptList(hugoSymbol, referenceGenome); - if (targetEnsemblTranscripts.size() == 0) { - transcriptMatchResultVM.setNote("The target reference genome does not have any ensembl transcripts."); - } else { - try { - pickEnsemblTranscript(transcriptMatchResultVM, referenceGenome, targetEnsemblTranscripts, _sequence.get()); - } catch (Exception exception) { - transcriptMatchResultVM.setNote(exception.getMessage()); - } - } - } else { - transcriptMatchResultVM.setNote("The transcript is invalid"); - } - } else { - transcriptMatchResultVM.setNote("The transcript is invalid"); - } - return transcriptMatchResultVM; - } - - public Optional getEnsemblTranscript(String transcriptId, ReferenceGenome referenceGenome) { - EnsemblControllerApi controllerApi = genomeNexusService.getEnsemblControllerApi(referenceGenome); - try { - EnsemblTranscript ensemblTranscript = controllerApi.fetchEnsemblTranscriptByTranscriptIdGET(transcriptId); - return ensemblTranscript == null ? Optional.empty() : Optional.of(ensemblTranscript); - } catch (Exception e) { - e.printStackTrace(); - return Optional.empty(); - } - } - - public List getEnsemblTranscriptList(String hugoSymbol, ReferenceGenome referenceGenome) { - EnsemblControllerApi controllerApi = genomeNexusService.getEnsemblControllerApi(referenceGenome); - Set transcripts = new LinkedHashSet<>(); - try { - transcripts.add(getCanonicalEnsemblTranscript(hugoSymbol, referenceGenome)); - } catch (ApiException e) { - e.printStackTrace(); - } - try { - transcripts.addAll(controllerApi.fetchEnsemblTranscriptsGET(null, null, hugoSymbol)); - } catch (ApiException e) { - e.printStackTrace(); - } - return new ArrayList<>(transcripts); - } - - public EnsemblTranscript getCanonicalEnsemblTranscript(String hugoSymbol, ReferenceGenome referenceGenome) throws ApiException { - EnsemblControllerApi controllerApi = genomeNexusService.getEnsemblControllerApi(referenceGenome); - return controllerApi.fetchCanonicalEnsemblTranscriptByHugoSymbolGET(hugoSymbol, "msk"); - } - - public Optional getEnsemblTranscript(String hugoSymbol, TranscriptPairVM transcriptPairVM) throws ApiException { - return getEnsemblTranscriptList(hugoSymbol, transcriptPairVM.getReferenceGenome()) - .stream() - .filter(ensemblTranscript -> - !StringUtils.isEmpty(ensemblTranscript.getTranscriptId()) && - ensemblTranscript.getTranscriptId().equalsIgnoreCase(transcriptPairVM.getTranscript()) - ) - .findFirst(); - } - - /** - * Get a list of transcripts from ensembl.org - * - * @param referenceGenome Reference Genome - * @param ids a list of transcript/gene ids that need to be searched - * @return a lit of expanded ensembl transcripts with exon/utr info - */ - public List getEnsemblTranscriptIds( - ReferenceGenome referenceGenome, - List ids, - boolean includeUtr, - boolean expand - ) { - List ensemblTranscriptList = new ArrayList<>(); - log.info("Get {} ensembl trancript ids", ids.size()); - for (int i = 0; i < ids.size(); i += ENSEMBL_POST_THRESHOLD) { - log.info("\tIndex {}", i); - ensemblTranscriptList.addAll( - ensemblService.getIds( - referenceGenome, - ids.subList(i, Math.min(ids.toArray().length, i + ENSEMBL_POST_THRESHOLD)), - includeUtr, - expand - ) - ); - } - return ensemblTranscriptList; - } - - private TranscriptMatchResultVM pickEnsemblTranscript( - TranscriptMatchResultVM transcriptMatchResultVM, - ReferenceGenome referenceGenome, - List availableTranscripts, - EnsemblSequence sequence - ) { - List sameLengthList = availableTranscripts - .stream() - .filter(ensemblTranscript -> - ensemblTranscript.getProteinLength() != null && ensemblTranscript.getProteinLength().equals(sequence.getSeq().length()) - ) - .collect(Collectors.toList()); - - List sequences = ensemblService - .getProteinSequences(referenceGenome, sameLengthList.stream().map(EnsemblTranscript::getProteinId).collect(Collectors.toList())) - .stream() - .filter(filteredSequence -> filteredSequence.getSeq().length() == sequence.getSeq().length()) - .collect(Collectors.toList()); - Optional sequenceSame = sequences - .stream() - .filter(matchedSequence -> matchedSequence.getSeq().equals(sequence.getSeq())) - .findAny(); - - if (sequenceSame.isPresent()) { - Optional ensemblTranscript = getEnsemblTranscriptBySequence(sameLengthList, sequenceSame.get()); - transcriptMatchResultVM.setTargetEnsemblTranscript(ensemblTranscript.get()); - transcriptMatchResultVM.setNote("Same sequence"); - } else if (sequences.size() > 0) { - // We should make some comparison with the original sequence for the same length - sequences.sort(Comparator.comparingInt(s -> getNumOfMismatchSameLengthSequences(sequence.getSeq(), s.getSeq()).size())); - EnsemblSequence pickedSequence = sequences.iterator().next(); - - Optional ensemblTranscript = getEnsemblTranscriptBySequence(availableTranscripts, pickedSequence); - transcriptMatchResultVM.setTargetEnsemblTranscript(ensemblTranscript.get()); - List missMatchPairVMS = getNumOfMismatchSameLengthSequences(sequence.getSeq(), pickedSequence.getSeq()); - transcriptMatchResultVM.setNote( - "Same length, but mismatch: " + - missMatchPairVMS.size() + - ". " + - missMatchPairVMS - .stream() - .map(missMatchPairVM -> - missMatchPairVM.getPosition() + - "(" + - missMatchPairVM.getReferenceAllele() + - "," + - missMatchPairVM.getTargetAlelel() + - ")" - ) - .collect(Collectors.joining(", ")) - ); - } else { - // we want to see whether there is any transcript includes the original sequence - List longerOnes = availableTranscripts - .stream() - .filter(ensemblTranscript -> - ensemblTranscript.getProteinLength() != null && ensemblTranscript.getProteinLength() > sequence.getSeq().length() - ) - .collect(Collectors.toList()); - - List longerSequences = ensemblService.getProteinSequences( - referenceGenome, - longerOnes.stream().map(EnsemblTranscript::getProteinId).collect(Collectors.toList()) - ); - List sequencesContains = longerSequences - .stream() - .filter(matchedSequence -> matchedSequence.getSeq().contains(sequence.getSeq())) - .collect(Collectors.toList()); - sequencesContains.sort((s1, s2) -> s2.getSeq().length() - s1.getSeq().length()); - - if (sequencesContains.size() > 0) { - EnsemblSequence pickedSequence = sequencesContains.iterator().next(); - Optional ensemblTranscript = getEnsemblTranscriptBySequence(longerOnes, pickedSequence); - transcriptMatchResultVM.setTargetEnsemblTranscript(ensemblTranscript.get()); - transcriptMatchResultVM.setNote("Longer one found, length: " + ensemblTranscript.get().getProteinLength()); - } else { - transcriptMatchResultVM.setNote("No matched sequence found"); - } - } - return transcriptMatchResultVM; - } - - public List getAlignmentResult( - ReferenceGenome refReferenceGenome, - EnsemblTranscript refEnsemblTranscript, - ReferenceGenome targetReferenceGenome, - List targetTranscripts - ) { - Optional refSequenceOptional = ensemblService.getProteinSequence( - refReferenceGenome, - refEnsemblTranscript.getProteinId() - ); - if (refSequenceOptional.isPresent()) { - return targetTranscripts - .stream() - .filter(ensemblTranscript -> StringUtils.isNotEmpty(ensemblTranscript.getProteinId())) - .map(ensemblTranscript -> { - Optional targetSequenceOptional = ensemblService.getProteinSequence( - targetReferenceGenome, - ensemblTranscript.getProteinId() - ); - if (targetSequenceOptional.isPresent()) { - AlignmentResult alignmentResult = - this.alignmentService.calcOptimalAlignment( - refSequenceOptional.get().getSeq(), - targetSequenceOptional.get().getSeq(), - true - ); - EnrichedAlignmentResult enrichedAlignmentResult = new EnrichedAlignmentResult(alignmentResult); - enrichedAlignmentResult.setRefEnsemblTranscript(refEnsemblTranscript); - enrichedAlignmentResult.setTargetEnsemblTranscript(ensemblTranscript); - return Optional.of(enrichedAlignmentResult); - } else { - Optional optional = Optional.empty(); - return optional; - } - }) - .filter(Optional::isPresent) - .map(Optional::get) - .sorted(Comparator.comparingInt(EnrichedAlignmentResult::getPenalty)) - .collect(Collectors.toList()); - } else { - return new ArrayList<>(); - } - } - - private Optional getEnsemblTranscriptBySequence( - List availableEnsemblTranscripts, - EnsemblSequence sequence - ) { - return availableEnsemblTranscripts - .stream() - .filter(ensemblTranscript -> { - if (ensemblTranscript.getProteinId() != null && ensemblTranscript.getProteinId().equals(sequence.getId())) { - return true; - } else { - return false; - } - }) - .findAny(); - } - - private List getNumOfMismatchSameLengthSequences(String reference, String newSequence) { - List mismatch = new ArrayList<>(); - for (int i = 0; i < reference.length(); i++) { - char r = reference.charAt(i); - char n = newSequence.charAt(i); - if (r != n) { - MissMatchPairVM missMatchPairVM = new MissMatchPairVM(); - missMatchPairVM.setPosition(i); - missMatchPairVM.setReferenceAllele(r); - missMatchPairVM.setTargetAlelel(n); - mismatch.add(missMatchPairVM); - } - } - return mismatch; - } - - private void clearTranscriptCaches() { - if (this.optionalCacheManager.isPresent()) { - for (String cacheKey : this.optionalCacheManager.get().getCacheNames()) { - String cacheKeyPrefix = this.cacheNameResolver.getCacheName(CacheCategory.TRANSCRIPT, ""); - if (cacheKey.startsWith(cacheKeyPrefix)) { - Objects.requireNonNull(this.optionalCacheManager.get().getCache(cacheKey)).clear(); - } - } - } - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/service/mapper/TranscriptMapper.java b/src/main/java/org/mskcc/oncokb/transcript/service/mapper/TranscriptMapper.java deleted file mode 100644 index bd7d4a0c2..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/service/mapper/TranscriptMapper.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.mskcc.oncokb.transcript.service.mapper; - -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; -import org.mapstruct.*; -import org.mskcc.oncokb.transcript.domain.GenomeFragment; -import org.mskcc.oncokb.transcript.domain.Transcript; -import org.mskcc.oncokb.transcript.domain.enumeration.GenomeFragmentType; -import org.mskcc.oncokb.transcript.repository.GenomeFragmentRepository; -import org.mskcc.oncokb.transcript.service.dto.TranscriptDTO; -import org.springframework.beans.factory.annotation.Autowired; - -/** - * Mapper for the entity {@link Transcript} and its DTO {@link TranscriptDTO}. - */ -@Mapper(componentModel = "spring", uses = {}) -public abstract class TranscriptMapper implements EntityMapper { - - @Autowired - GenomeFragmentRepository genomeFragmentRepository; - - /** - * @param transcriptDTO - */ - @AfterMapping - protected void updateDTO(@MappingTarget TranscriptDTO transcriptDTO) { - List genomeFragmentList = genomeFragmentRepository.findAllByTranscriptId(transcriptDTO.getId()); - - Optional geneInfo = genomeFragmentList - .stream() - .filter(genomeFragment -> genomeFragment.getType().equals(GenomeFragmentType.GENE)) - .findFirst(); - if (geneInfo.isPresent()) { - GenomeFragment gf = geneInfo.get(); - transcriptDTO.setChromosome(gf.getChromosome()); - transcriptDTO.setStart(gf.getStart()); - transcriptDTO.setEnd(gf.getEnd()); - transcriptDTO.setStrand(gf.getStrand()); - } - - List exons = genomeFragmentList - .stream() - .filter(genomeFragment -> genomeFragment.getType().equals(GenomeFragmentType.EXON)) - .collect(Collectors.toList()); - transcriptDTO.setExons(exons); - - List utrs = genomeFragmentList - .stream() - .filter(genomeFragment -> - genomeFragment.getType().equals(GenomeFragmentType.FIVE_PRIME_UTR) || - genomeFragment.getType().equals(GenomeFragmentType.THREE_PRIME_UTR) - ) - .collect(Collectors.toList()); - transcriptDTO.setUtrs(utrs); - } - - @AfterMapping - protected void update(@MappingTarget Transcript transcript) {} -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/service/package-info.java b/src/main/java/org/mskcc/oncokb/transcript/service/package-info.java deleted file mode 100644 index d37cfe012..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/service/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Service layer beans. - */ -package org.mskcc.oncokb.transcript.service; diff --git a/src/main/java/org/mskcc/oncokb/transcript/util/COMPRESSED_FILE_FORMAT.java b/src/main/java/org/mskcc/oncokb/transcript/util/COMPRESSED_FILE_FORMAT.java deleted file mode 100644 index ed5a7e912..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/util/COMPRESSED_FILE_FORMAT.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.mskcc.oncokb.transcript.util; - -/** - * Created by Hongxin Zhang on 4/21/21. - */ -public enum COMPRESSED_FILE_FORMAT { - GZIP, - ZIP, -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/util/FileUtils.java b/src/main/java/org/mskcc/oncokb/transcript/util/FileUtils.java deleted file mode 100644 index f8cf90d30..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/util/FileUtils.java +++ /dev/null @@ -1,73 +0,0 @@ -package org.mskcc.oncokb.transcript.util; - -import java.io.*; -import java.net.URL; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.List; -import org.apache.commons.lang3.StringUtils; - -public class FileUtils { - - /** - * read local files and return content - * - * @param pathToFile - * @return - * @throws IOException - */ - public static String readLocal(String pathToFile) throws IOException { - return readStream(new FileInputStream(pathToFile)); - } - - /** - * return remote files and return content - * - * @param urlToFile - * @return - * @throws IOException - */ - public static String readRemote(String urlToFile) throws IOException { - URL url = new URL(urlToFile); - return readStream(url.openStream()); - } - - /** - * read a stream and return content - * - * @param is - * @return - * @throws IOException - */ - public static String readStream(InputStream is) throws IOException { - List lines = readTrimmedLinesStream(is); - return StringUtils.join(lines, "\n"); - } - - public static List readTrimmedLinesStream(InputStream is) throws IOException { - return readLinesStream(is, true); - } - - /** - * read a stream and return lines - * - * @param is - * @return - * @throws IOException - */ - public static List readLinesStream(InputStream is, boolean trim) throws IOException { - BufferedReader in = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8"))); - - List lines = new ArrayList(); - String line; - while ((line = in.readLine()) != null) { - if (trim) { - line = line.trim(); - } - if (!line.isEmpty()) lines.add(line); - } - in.close(); - - return lines; - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/vm/ensembl/EnsemblTranscript.java b/src/main/java/org/mskcc/oncokb/transcript/vm/ensembl/EnsemblTranscript.java deleted file mode 100644 index b8309fdf0..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/vm/ensembl/EnsemblTranscript.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.mskcc.oncokb.transcript.vm.ensembl; - -import com.google.gson.annotations.SerializedName; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -public class EnsemblTranscript extends EnsemblTranscriptFragment implements Serializable { - - @SerializedName("Parent") - String parent; - - @SerializedName("Transcript") - List transcripts = new ArrayList<>(); - - @SerializedName("Exon") - List exons = new ArrayList<>(); - - @SerializedName("UTR") - List utrs = new ArrayList<>(); - - public String getParent() { - return parent; - } - - public void setParent(String parent) { - this.parent = parent; - } - - public List getTranscripts() { - return transcripts; - } - - public void setTranscripts(List transcripts) { - this.transcripts = transcripts; - } - - public List getExons() { - return exons; - } - - public void setExons(List exons) { - this.exons = exons; - } - - public List getUtrs() { - return utrs; - } - - public void setUtrs(List utrs) { - this.utrs = utrs; - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/vm/package-info.java b/src/main/java/org/mskcc/oncokb/transcript/vm/package-info.java deleted file mode 100644 index c52c59b41..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/vm/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * View Models. - */ -package org.mskcc.oncokb.transcript.vm; diff --git a/src/main/java/org/mskcc/oncokb/transcript/web/rest/AccountResource.java b/src/main/java/org/mskcc/oncokb/transcript/web/rest/AccountResource.java deleted file mode 100644 index 17b6e95d4..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/web/rest/AccountResource.java +++ /dev/null @@ -1,78 +0,0 @@ -package org.mskcc.oncokb.transcript.web.rest; - -import com.fasterxml.jackson.annotation.JsonCreator; -import java.util.Set; -import java.util.stream.Collectors; -import javax.servlet.http.HttpServletRequest; -import org.mskcc.oncokb.transcript.security.SecurityUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping("/api") -public class AccountResource { - - private final Logger log = LoggerFactory.getLogger(AccountResource.class); - - private static class AccountResourceException extends RuntimeException {} - - /** - * {@code GET /account} : get the current user. - * - * @return the current user. - * @throws AccountResourceException {@code 500 (Internal Server Error)} if the user couldn't be returned. - */ - @GetMapping("/account") - public UserVM getAccount() { - String login = SecurityUtils.getCurrentUserLogin().orElseThrow(AccountResourceException::new); - Set authorities = SecurityContextHolder - .getContext() - .getAuthentication() - .getAuthorities() - .stream() - .map(GrantedAuthority::getAuthority) - .collect(Collectors.toSet()); - return new UserVM(login, authorities); - } - - /** - * {@code GET /authenticate} : check if the user is authenticated, and return its login. - * - * @param request the HTTP request. - * @return the login if the user is authenticated. - */ - @GetMapping("/authenticate") - public String isAuthenticated(HttpServletRequest request) { - log.debug("REST request to check if the current user is authenticated"); - return request.getRemoteUser(); - } - - private static class UserVM { - - private String login; - private Set authorities; - - @JsonCreator - UserVM(String login, Set authorities) { - this.login = login; - this.authorities = authorities; - } - - public boolean isActivated() { - return true; - } - - public Set getAuthorities() { - return authorities; - } - - public String getLogin() { - return login; - } - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/web/rest/ClientForwardController.java b/src/main/java/org/mskcc/oncokb/transcript/web/rest/ClientForwardController.java deleted file mode 100644 index ec38a4c05..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/web/rest/ClientForwardController.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.mskcc.oncokb.transcript.web.rest; - -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; - -@Controller -public class ClientForwardController { - - /** - * Forwards any unmapped paths (except those containing a period) to the client {@code index.html}. - * @return forward to client {@code swagger-ui/index.html}. - */ - @GetMapping(value = "/index.html") - public String forwardMain() { - return "redirect:/swagger-ui/index.html"; - } - - /** - * Forwards any unmapped paths (except those containing a period) to the client {@code index.html}. - * @return forward to client {@code swagger-ui/index.html}. - */ - @GetMapping(value = "/**/{path:[^\\.]*}") - public String forward() { - return "forward:/"; - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/web/rest/DrugController.java b/src/main/java/org/mskcc/oncokb/transcript/web/rest/DrugController.java deleted file mode 100644 index 4e1bc309e..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/web/rest/DrugController.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.mskcc.oncokb.transcript.web.rest; - -import java.util.List; -import java.util.Optional; -import org.mskcc.oncokb.transcript.domain.Drug; -import org.mskcc.oncokb.transcript.service.DrugService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.web.bind.annotation.*; - -/** - * REST controller for managing {@link org.mskcc.oncokb.transcript.domain.Drug}. - */ -@RestController -@RequestMapping("/api") -public class DrugController { - - private final Logger log = LoggerFactory.getLogger(DrugController.class); - - private final DrugService drugService; - - public DrugController(DrugService drugService) { - this.drugService = drugService; - } - - @GetMapping("/drugs/search") - public List findDrugs(@RequestParam(value = "query") String query) { - log.debug("REST request to search Drugs"); - return drugService.searchDrug(query); - } - - @GetMapping("/drugs/search-by-code/{code}") - public Optional findDrugByCode(@PathVariable(value = "code") String code) { - log.debug("REST request to search Drugs"); - return drugService.findByCode(code); - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/web/rest/EnsemblGeneController.java b/src/main/java/org/mskcc/oncokb/transcript/web/rest/EnsemblGeneController.java deleted file mode 100644 index 4b9985327..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/web/rest/EnsemblGeneController.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.mskcc.oncokb.transcript.web.rest; - -import io.swagger.annotations.ApiParam; -import java.util.Optional; -import javax.validation.constraints.NotNull; -import org.genome_nexus.ApiException; -import org.mskcc.oncokb.transcript.domain.EnsemblGene; -import org.mskcc.oncokb.transcript.domain.enumeration.ReferenceGenome; -import org.mskcc.oncokb.transcript.service.*; -import org.mskcc.oncokb.transcript.web.rest.model.AddEnsemblGeneBody; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; - -@RestController -@RequestMapping("/api") -public class EnsemblGeneController { - - private final Logger log = LoggerFactory.getLogger(EnsemblGeneController.class); - - private final MainService mainService; - - public EnsemblGeneController(MainService mainService) { - this.mainService = mainService; - } - - @PostMapping("/add-ensembl-gene") - public ResponseEntity addEnsemblGene(@RequestBody AddEnsemblGeneBody body) throws ApiException { - Optional savedEnsemblGeneOptional = mainService.createEnsemblGene( - ReferenceGenome.valueOf(body.getReferenceGenome()), - body.getEnsemblGeneId(), - body.getEntrezGeneId(), - body.getCanonical() - ); - return new ResponseEntity<>(savedEnsemblGeneOptional.get(), HttpStatus.OK); - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/web/rest/GeneResource.java b/src/main/java/org/mskcc/oncokb/transcript/web/rest/GeneResource.java deleted file mode 100644 index 92bba37d4..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/web/rest/GeneResource.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.mskcc.oncokb.transcript.web.rest; - -import java.util.List; -import org.mskcc.oncokb.transcript.domain.Gene; -import org.mskcc.oncokb.transcript.service.GeneService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; - -/** - * REST controller for managing {@link org.mskcc.oncokb.transcript.domain.Gene}. - */ -@RestController -@RequestMapping("/api") -public class GeneResource { - - private final Logger log = LoggerFactory.getLogger(GeneResource.class); - - private final GeneService geneService; - - public GeneResource(GeneService geneService) { - this.geneService = geneService; - } - - /** - * {@code GET /genes} : get all the genes. - * - * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of genes in body. - */ - @GetMapping("/genes") - public List getAllGenes() { - log.debug("REST request to get all Genes"); - return geneService.findAll(); - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/web/rest/PipelineController.java b/src/main/java/org/mskcc/oncokb/transcript/web/rest/PipelineController.java deleted file mode 100644 index 1ddf49224..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/web/rest/PipelineController.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.mskcc.oncokb.transcript.web.rest; - -import org.mskcc.oncokb.transcript.service.GeneService; -import org.mskcc.oncokb.transcript.service.NcitService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; - -/** - * Controller to drugs. - */ -@RestController -@RequestMapping("/api/pipeline/") -public class PipelineController { - - NcitService ncitService; - GeneService geneService; - - private final Logger log = LoggerFactory.getLogger(PipelineController.class); - - public PipelineController(NcitService ncitService, GeneService geneService) { - this.ncitService = ncitService; - this.geneService = geneService; - } - - @PostMapping("/update-ncit") - public ResponseEntity updateNcit() throws Exception { - ncitService.updateNcitDrugs(); - return new ResponseEntity<>(HttpStatus.OK); - } - - @PostMapping("/update-gene") - public ResponseEntity updatePortalGene() throws Exception { - geneService.updatePortalGenes(); - return new ResponseEntity<>(HttpStatus.OK); - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/web/rest/SequenceController.java b/src/main/java/org/mskcc/oncokb/transcript/web/rest/SequenceController.java deleted file mode 100644 index 655fd089b..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/web/rest/SequenceController.java +++ /dev/null @@ -1,94 +0,0 @@ -package org.mskcc.oncokb.transcript.web.rest; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.stream.Collectors; -import org.mskcc.oncokb.transcript.domain.EnsemblGene; -import org.mskcc.oncokb.transcript.domain.Sequence; -import org.mskcc.oncokb.transcript.domain.enumeration.ReferenceGenome; -import org.mskcc.oncokb.transcript.domain.enumeration.SequenceType; -import org.mskcc.oncokb.transcript.service.EnsemblGeneService; -import org.mskcc.oncokb.transcript.service.SequenceService; -import org.mskcc.oncokb.transcript.service.TranscriptService; -import org.mskcc.oncokb.transcript.service.dto.TranscriptDTO; -import org.mskcc.oncokb.transcript.service.mapper.TranscriptMapper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.web.bind.annotation.*; - -/** - * REST controller for managing {@link org.mskcc.oncokb.transcript.domain.Sequence}. - */ -@RestController -@RequestMapping("/api") -public class SequenceController { - - private final Logger log = LoggerFactory.getLogger(SequenceController.class); - - private final EnsemblGeneService ensemblGeneService; - private final TranscriptService transcriptService; - private final SequenceService sequenceService; - - private final TranscriptMapper transcriptMapper; - - public SequenceController( - EnsemblGeneService ensemblGeneService, - TranscriptService transcriptService, - TranscriptMapper transcriptMapper, - SequenceService sequenceService - ) { - this.ensemblGeneService = ensemblGeneService; - this.transcriptService = transcriptService; - this.transcriptMapper = transcriptMapper; - this.sequenceService = sequenceService; - } - - @GetMapping("/find-canonical-sequences") - public Sequence findCanonicalSequence( - @RequestParam ReferenceGenome referenceGenome, - @RequestParam Integer entrezGeneId, - @RequestParam(defaultValue = "PROTEIN") SequenceType sequenceType - ) { - log.debug("GET request to get canonical protein sequence by Gene: {} {}", referenceGenome, entrezGeneId); - return findSequence(referenceGenome, entrezGeneId, sequenceType); - } - - @PostMapping("/find-canonical-sequences") - public List findCanonicalSequences( - @RequestParam ReferenceGenome referenceGenome, - @RequestParam(defaultValue = "PROTEIN") SequenceType sequenceType, - @RequestBody List entrezGeneIds - ) { - log.debug("POST request to get canonical protein sequences"); - if (entrezGeneIds == null || entrezGeneIds.isEmpty()) { - return new ArrayList<>(); - } else { - return entrezGeneIds - .stream() - .map(entrezGeneId -> findSequence(referenceGenome, entrezGeneId, sequenceType)) - .filter(Objects::nonNull) - .collect(Collectors.toList()); - } - } - - private Sequence findSequence(ReferenceGenome referenceGenome, Integer entrezGeneId, SequenceType sequenceType) { - Optional ensemblGeneOptional = ensemblGeneService.findCanonicalEnsemblGene(entrezGeneId, referenceGenome); - if (ensemblGeneOptional.isPresent()) { - Optional transcriptDTOOptional = transcriptService.findByEnsemblGeneAndCanonicalIsTrue( - ensemblGeneOptional.get() - ); - if (transcriptDTOOptional.isPresent()) { - Optional sequenceOptional = sequenceService.findOneByTranscriptAndSequenceType( - transcriptMapper.toEntity(transcriptDTOOptional.get()), - sequenceType - ); - if (sequenceOptional.isPresent()) { - return sequenceOptional.get(); - } - } - } - return null; - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/web/rest/errors/BadRequestAlertException.java b/src/main/java/org/mskcc/oncokb/transcript/web/rest/errors/BadRequestAlertException.java deleted file mode 100644 index 754e8eb2d..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/web/rest/errors/BadRequestAlertException.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.mskcc.oncokb.transcript.web.rest.errors; - -import java.net.URI; -import java.util.HashMap; -import java.util.Map; -import org.zalando.problem.AbstractThrowableProblem; -import org.zalando.problem.Status; - -public class BadRequestAlertException extends AbstractThrowableProblem { - - private static final long serialVersionUID = 1L; - - private final String entityName; - - private final String errorKey; - - public BadRequestAlertException(String defaultMessage, String entityName, String errorKey) { - this(ErrorConstants.DEFAULT_TYPE, defaultMessage, entityName, errorKey); - } - - public BadRequestAlertException(URI type, String defaultMessage, String entityName, String errorKey) { - super(type, defaultMessage, Status.BAD_REQUEST, null, null, null, getAlertParameters(entityName, errorKey)); - this.entityName = entityName; - this.errorKey = errorKey; - } - - public String getEntityName() { - return entityName; - } - - public String getErrorKey() { - return errorKey; - } - - private static Map getAlertParameters(String entityName, String errorKey) { - Map parameters = new HashMap<>(); - parameters.put("message", "error." + errorKey); - parameters.put("params", entityName); - return parameters; - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/web/rest/errors/BadRequestException.java b/src/main/java/org/mskcc/oncokb/transcript/web/rest/errors/BadRequestException.java deleted file mode 100644 index 54951896a..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/web/rest/errors/BadRequestException.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.mskcc.oncokb.transcript.web.rest.errors; - -import java.net.URI; -import org.zalando.problem.AbstractThrowableProblem; -import org.zalando.problem.Status; - -public class BadRequestException extends AbstractThrowableProblem { - - private static final long serialVersionUID = 1L; - - public BadRequestException(String defaultMessage) { - this(ErrorConstants.DEFAULT_TYPE, defaultMessage); - } - - public BadRequestException(URI type, String defaultMessage) { - super(type, defaultMessage, Status.BAD_REQUEST, null, null, null); - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/web/rest/errors/ErrorConstants.java b/src/main/java/org/mskcc/oncokb/transcript/web/rest/errors/ErrorConstants.java deleted file mode 100644 index bc4a86aa6..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/web/rest/errors/ErrorConstants.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.mskcc.oncokb.transcript.web.rest.errors; - -import java.net.URI; - -public final class ErrorConstants { - - public static final String ERR_CONCURRENCY_FAILURE = "error.concurrencyFailure"; - public static final String ERR_VALIDATION = "error.validation"; - public static final String PROBLEM_BASE_URL = "https://www.jhipster.tech/problem"; - public static final URI DEFAULT_TYPE = URI.create(PROBLEM_BASE_URL + "/problem-with-message"); - public static final URI CONSTRAINT_VIOLATION_TYPE = URI.create(PROBLEM_BASE_URL + "/constraint-violation"); - - private ErrorConstants() {} -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/web/rest/errors/ExceptionTranslator.java b/src/main/java/org/mskcc/oncokb/transcript/web/rest/errors/ExceptionTranslator.java deleted file mode 100644 index 68cd839a2..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/web/rest/errors/ExceptionTranslator.java +++ /dev/null @@ -1,188 +0,0 @@ -package org.mskcc.oncokb.transcript.web.rest.errors; - -import java.net.URI; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import javax.servlet.http.HttpServletRequest; -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.core.env.Environment; -import org.springframework.dao.ConcurrencyFailureException; -import org.springframework.dao.DataAccessException; -import org.springframework.http.ResponseEntity; -import org.springframework.http.converter.HttpMessageConversionException; -import org.springframework.validation.BindingResult; -import org.springframework.web.bind.MethodArgumentNotValidException; -import org.springframework.web.bind.annotation.ControllerAdvice; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.context.request.NativeWebRequest; -import org.zalando.problem.DefaultProblem; -import org.zalando.problem.Problem; -import org.zalando.problem.ProblemBuilder; -import org.zalando.problem.Status; -import org.zalando.problem.StatusType; -import org.zalando.problem.spring.web.advice.ProblemHandling; -import org.zalando.problem.spring.web.advice.security.SecurityAdviceTrait; -import org.zalando.problem.violations.ConstraintViolationProblem; -import tech.jhipster.config.JHipsterConstants; -import tech.jhipster.web.util.HeaderUtil; - -/** - * Controller advice to translate the server side exceptions to client-friendly json structures. - * The error response follows RFC7807 - Problem Details for HTTP APIs (https://tools.ietf.org/html/rfc7807). - */ -@ControllerAdvice -public class ExceptionTranslator implements ProblemHandling, SecurityAdviceTrait { - - private static final String FIELD_ERRORS_KEY = "fieldErrors"; - private static final String MESSAGE_KEY = "message"; - private static final String PATH_KEY = "path"; - private static final String VIOLATIONS_KEY = "violations"; - - @Value("${jhipster.clientApp.name}") - private String applicationName; - - private final Environment env; - - public ExceptionTranslator(Environment env) { - this.env = env; - } - - /** - * Post-process the Problem payload to add the message key for the front-end if needed. - */ - @Override - public ResponseEntity process(@Nullable ResponseEntity entity, NativeWebRequest request) { - if (entity == null) { - return null; - } - Problem problem = entity.getBody(); - if (!(problem instanceof ConstraintViolationProblem || problem instanceof DefaultProblem)) { - return entity; - } - - HttpServletRequest nativeRequest = request.getNativeRequest(HttpServletRequest.class); - String requestUri = nativeRequest != null ? nativeRequest.getRequestURI() : StringUtils.EMPTY; - ProblemBuilder builder = Problem - .builder() - .withType(Problem.DEFAULT_TYPE.equals(problem.getType()) ? ErrorConstants.DEFAULT_TYPE : problem.getType()) - .withStatus(problem.getStatus()) - .withTitle(problem.getTitle()) - .with(PATH_KEY, requestUri); - - if (problem instanceof ConstraintViolationProblem) { - builder - .with(VIOLATIONS_KEY, ((ConstraintViolationProblem) problem).getViolations()) - .with(MESSAGE_KEY, ErrorConstants.ERR_VALIDATION); - } else { - builder.withCause(((DefaultProblem) problem).getCause()).withDetail(problem.getDetail()).withInstance(problem.getInstance()); - problem.getParameters().forEach(builder::with); - if (!problem.getParameters().containsKey(MESSAGE_KEY) && problem.getStatus() != null) { - builder.with(MESSAGE_KEY, "error.http." + problem.getStatus().getStatusCode()); - } - } - return new ResponseEntity<>(builder.build(), entity.getHeaders(), entity.getStatusCode()); - } - - @Override - public ResponseEntity handleMethodArgumentNotValid(MethodArgumentNotValidException ex, @Nonnull NativeWebRequest request) { - BindingResult result = ex.getBindingResult(); - List fieldErrors = result - .getFieldErrors() - .stream() - .map(f -> - new FieldErrorVM( - f.getObjectName().replaceFirst("DTO$", ""), - f.getField(), - StringUtils.isNotBlank(f.getDefaultMessage()) ? f.getDefaultMessage() : f.getCode() - ) - ) - .collect(Collectors.toList()); - - Problem problem = Problem - .builder() - .withType(ErrorConstants.CONSTRAINT_VIOLATION_TYPE) - .withTitle("Method argument not valid") - .withStatus(defaultConstraintViolationStatus()) - .with(MESSAGE_KEY, ErrorConstants.ERR_VALIDATION) - .with(FIELD_ERRORS_KEY, fieldErrors) - .build(); - return create(ex, problem, request); - } - - @ExceptionHandler - public ResponseEntity handleBadRequestAlertException(BadRequestAlertException ex, NativeWebRequest request) { - return create( - ex, - request, - HeaderUtil.createFailureAlert(applicationName, false, ex.getEntityName(), ex.getErrorKey(), ex.getMessage()) - ); - } - - @ExceptionHandler - public ResponseEntity handleConcurrencyFailure(ConcurrencyFailureException ex, NativeWebRequest request) { - Problem problem = Problem.builder().withStatus(Status.CONFLICT).with(MESSAGE_KEY, ErrorConstants.ERR_CONCURRENCY_FAILURE).build(); - return create(ex, problem, request); - } - - @Override - public ProblemBuilder prepare(final Throwable throwable, final StatusType status, final URI type) { - Collection activeProfiles = Arrays.asList(env.getActiveProfiles()); - - if (activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_PRODUCTION)) { - if (throwable instanceof HttpMessageConversionException) { - return Problem - .builder() - .withType(type) - .withTitle(status.getReasonPhrase()) - .withStatus(status) - .withDetail("Unable to convert http message") - .withCause( - Optional.ofNullable(throwable.getCause()).filter(cause -> isCausalChainsEnabled()).map(this::toProblem).orElse(null) - ); - } - if (throwable instanceof DataAccessException) { - return Problem - .builder() - .withType(type) - .withTitle(status.getReasonPhrase()) - .withStatus(status) - .withDetail("Failure during data access") - .withCause( - Optional.ofNullable(throwable.getCause()).filter(cause -> isCausalChainsEnabled()).map(this::toProblem).orElse(null) - ); - } - if (containsPackageName(throwable.getMessage())) { - return Problem - .builder() - .withType(type) - .withTitle(status.getReasonPhrase()) - .withStatus(status) - .withDetail("Unexpected runtime exception") - .withCause( - Optional.ofNullable(throwable.getCause()).filter(cause -> isCausalChainsEnabled()).map(this::toProblem).orElse(null) - ); - } - } - - return Problem - .builder() - .withType(type) - .withTitle(status.getReasonPhrase()) - .withStatus(status) - .withDetail(throwable.getMessage()) - .withCause( - Optional.ofNullable(throwable.getCause()).filter(cause -> isCausalChainsEnabled()).map(this::toProblem).orElse(null) - ); - } - - private boolean containsPackageName(String message) { - // This list is for sure not complete - return StringUtils.containsAny(message, "org.", "java.", "net.", "javax.", "com.", "io.", "de.", "org.mskcc.oncokb.transcript"); - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/web/rest/errors/package-info.java b/src/main/java/org/mskcc/oncokb/transcript/web/rest/errors/package-info.java deleted file mode 100644 index feb1d3568..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/web/rest/errors/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Specific errors used with Zalando's "problem-spring-web" library. - * - * More information on https://github.com/zalando/problem-spring-web - */ -package org.mskcc.oncokb.transcript.web.rest.errors; diff --git a/src/main/java/org/mskcc/oncokb/transcript/web/rest/model/AddTranscriptBody.java b/src/main/java/org/mskcc/oncokb/transcript/web/rest/model/AddTranscriptBody.java deleted file mode 100644 index e53df4632..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/web/rest/model/AddTranscriptBody.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.mskcc.oncokb.transcript.web.rest.model; - -import javax.validation.constraints.NotNull; - -public class AddTranscriptBody { - - @NotNull - Integer entrezGeneId; - - @NotNull - String referenceGenome; - - @NotNull - String ensemblTranscriptId; - - @NotNull - Boolean isCanonical = false; - - public Integer getEntrezGeneId() { - return entrezGeneId; - } - - public void setEntrezGeneId(Integer entrezGeneId) { - this.entrezGeneId = entrezGeneId; - } - - public String getReferenceGenome() { - return referenceGenome; - } - - public void setReferenceGenome(String referenceGenome) { - this.referenceGenome = referenceGenome; - } - - public String getEnsemblTranscriptId() { - return ensemblTranscriptId; - } - - public void setEnsemblTranscriptId(String ensemblTranscriptId) { - this.ensemblTranscriptId = ensemblTranscriptId; - } - - public Boolean getCanonical() { - return isCanonical; - } - - public void setCanonical(Boolean canonical) { - isCanonical = canonical; - } -} diff --git a/src/main/java/org/mskcc/oncokb/transcript/web/rest/package-info.java b/src/main/java/org/mskcc/oncokb/transcript/web/rest/package-info.java deleted file mode 100644 index 31f3f3bab..000000000 --- a/src/main/java/org/mskcc/oncokb/transcript/web/rest/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Spring MVC REST controllers. - */ -package org.mskcc.oncokb.transcript.web.rest; diff --git a/src/main/resources/alteration.tsv b/src/main/resources/alteration.tsv new file mode 100644 index 000000000..504c486ee --- /dev/null +++ b/src/main/resources/alteration.tsv @@ -0,0 +1 @@ +#Alteration Name AlterationType ProteinStart ProteinEnd RefResidues VarResidues Consequence EntrezGeneId diff --git a/src/main/resources/config/application-dev-example.yml b/src/main/resources/config/application-dev-example.yml new file mode 100644 index 000000000..9629ff2cc --- /dev/null +++ b/src/main/resources/config/application-dev-example.yml @@ -0,0 +1,140 @@ +# =================================================================== +# Spring Boot configuration for the "dev" profile. +# +# This configuration overrides the application.yml file. +# +# More information on profiles: https://www.jhipster.tech/profiles/ +# More information on configuration properties: https://www.jhipster.tech/common-application-properties/ +# =================================================================== + +# =================================================================== +# Standard Spring Boot properties. +# Full reference is available at: +# http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html +# =================================================================== + +logging: + level: + ROOT: INFO + tech.jhipster: INFO + org.hibernate.SQL: INFO + org.mskcc.oncokb.curation: INFO + +spring: + devtools: + restart: + enabled: true + additional-exclude: static/** + livereload: + enabled: false # we use Webpack dev server + BrowserSync for livereload + jackson: + serialization: + indent-output: true + datasource: + type: com.zaxxer.hikari.HikariDataSource + url: jdbc:mysql://localhost:3306/oncokb_curation?useUnicode=true&characterEncoding=utf8&useSSL=false&useLegacyDatetimeCode=false&serverTimezone=UTC&createDatabaseIfNotExist=true + username: root + password: root + hikari: + poolName: Hikari + auto-commit: false + data-source-properties: + cachePrepStmts: true + prepStmtCacheSize: 250 + prepStmtCacheSqlLimit: 2048 + useServerPrepStmts: true + liquibase: + # Remove 'faker' if you do not want the sample data to be loaded automatically + contexts: dev, faker + mail: + host: localhost + port: 25 + username: + password: + messages: + cache-duration: PT1S # 1 second, see the ISO 8601 standard + thymeleaf: + cache: false + session: + store-type: none + jpa: + show-sql: false + +server: + port: 9090 + +# =================================================================== +# JHipster specific properties +# +# Full reference is available at: https://www.jhipster.tech/common-application-properties/ +# =================================================================== + +jhipster: + cache: # Cache configuration + redis: # Redis configuration + expiration: 3600 # By default objects stay 1 hour (in seconds) in the cache + server: redis://oncokb-public-redis-password@localhost:6379 + cluster: false + # server: redis://localhost:6379,redis://localhost:16379,redis://localhost:26379 + # cluster: true + # CORS is only enabled by default with the "dev" profile + cors: + # Allow Ionic for JHipster by default (* no longer allowed in Spring Boot 2.4+) + allowed-origins: 'http://localhost:8100,https://localhost:8100,http://localhost:9000,https://localhost:9000,http://localhost:9060,https://localhost:9060,https://localhost:8080' + allowed-methods: '*' + allowed-headers: '*' + exposed-headers: 'Authorization,Link,X-Total-Count,X-${jhipster.clientApp.name}-alert,X-${jhipster.clientApp.name}-error,X-${jhipster.clientApp.name}-params' + allow-credentials: true + max-age: 1800 + logging: + use-json-format: false # By default, logs are not in Json format + logstash: # Forward logs to logstash over a socket, used by LoggingConfiguration + enabled: false + host: localhost + port: 5000 + ring-buffer-size: 512 + +# =================================================================== +# Sentry specific properties +# How to configure Sentry Spring Boot: https://docs.sentry.io/platforms/java/guides/spring-boot/ +# Full reference is available at: https://github.com/getsentry/sentry-java/blob/main/sentry-spring-boot-starter/src/main/java/io/sentry/spring/boot/SentryProperties.java +# =================================================================== +sentry: + dsn: + # send handled exception to sentry as well + exception-resolver-order: -2147483647 +# =================================================================== +# Application specific properties +# Add your own application properties here, see the ApplicationProperties class +# to have type-safe configuration, like in the JHipsterProperties above +# +# More documentation is available at: +# https://www.jhipster.tech/common-application-properties/ +# =================================================================== + +application: + oncokb-core: + url: http://localhost:8000/oncokb + oncokb: + api-key: + url: + redis: + enabled: false + type: single + address: redis://localhost:6379 + password: oncokb-public-redis-password + expiration: 3600 # By default objects stay 1 hour (in seconds) in the cache + firebase: + enabled: false + api-key: + auth-domain: + database-url: + project-id: + storage-bucket: + messaging-sender-id: + app-id: + measurement-id: + service-account-credentials-path: firebase.json + oncokb-data-repo-dir: + frontend: + sentry-dsn: diff --git a/src/main/resources/config/application-dev.yml b/src/main/resources/config/application-dev.yml deleted file mode 100644 index a8d9c9673..000000000 --- a/src/main/resources/config/application-dev.yml +++ /dev/null @@ -1,112 +0,0 @@ -# =================================================================== -# Spring Boot configuration for the "dev" profile. -# -# This configuration overrides the application.yml file. -# -# More information on profiles: https://www.jhipster.tech/profiles/ -# More information on configuration properties: https://www.jhipster.tech/common-application-properties/ -# =================================================================== - -# =================================================================== -# Standard Spring Boot properties. -# Full reference is available at: -# http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html -# =================================================================== - -logging: - level: - ROOT: DEBUG - tech.jhipster: DEBUG - org.hibernate.SQL: DEBUG - org.mskcc.oncokb.transcript: DEBUG - -spring: - devtools: - restart: - enabled: true - additional-exclude: static/** - livereload: - enabled: false # we use Webpack dev server + BrowserSync for livereload - jackson: - serialization: - indent-output: true - datasource: - type: com.zaxxer.hikari.HikariDataSource - url: jdbc:mysql://localhost:3306/oncokb_transcript?useUnicode=true&characterEncoding=utf8&useSSL=false&useLegacyDatetimeCode=false&serverTimezone=UTC&createDatabaseIfNotExist=true - username: root - password: root - hikari: - poolName: Hikari - auto-commit: false - data-source-properties: - cachePrepStmts: true - prepStmtCacheSize: 250 - prepStmtCacheSqlLimit: 2048 - useServerPrepStmts: true - jpa: - liquibase: - contexts: dev - messages: - cache-duration: PT1S # 1 second, see the ISO 8601 standard - thymeleaf: - cache: false - -server: - port: 9090 - -# =================================================================== -# JHipster specific properties -# -# Full reference is available at: https://www.jhipster.tech/common-application-properties/ -# =================================================================== - -jhipster: - cache: # Cache configuration - redis: # Redis configuration - expiration: 3600 # By default objects stay 1 hour (in seconds) in the cache - server: redis://oncokb-public-redis-password@localhost:6379 - cluster: false - # server: redis://localhost:6379,redis://localhost:16379,redis://localhost:26379 - # cluster: true - # CORS is only enabled by default with the "dev" profile - cors: - # Allow Ionic for JHipster by default (* no longer allowed in Spring Boot 2.4+) - allowed-origins: 'http://localhost:8100,https://localhost:8100,http://localhost:9000,https://localhost:9000,http://localhost:9060,https://localhost:9060' - allowed-methods: '*' - allowed-headers: '*' - exposed-headers: 'Authorization,Link,X-Total-Count,X-${jhipster.clientApp.name}-alert,X-${jhipster.clientApp.name}-error,X-${jhipster.clientApp.name}-params' - allow-credentials: true - max-age: 1800 - security: - authentication: - jwt: - # This token must be encoded using Base64 and be at least 256 bits long (you can type `openssl rand -base64 64` on your command line to generate a 512 bits one) - base64-secret: NGUwNTlhNDNhOWQ2ZGJlMmEzODczOWJjYWM2MWY4NDAwOTM4YTBmNGFjM2UxNjczZDU2YWZjZjc3MjdkNmU4YjVhZmIwYzI1NDhjMDFkZThiYmE5Mjc5MjM0MGVhODU5MGFhMTAyOTE0M2I3ODA1MGUzZWFhYWUwNWY2ZDgyNjQ= - # Token is valid 24 hours - token-validity-in-seconds: 86400 - token-validity-in-seconds-for-remember-me: 2592000 - logging: - use-json-format: false # By default, logs are not in Json format - logstash: # Forward logs to logstash over a socket, used by LoggingConfiguration - enabled: false - host: localhost - port: 5000 - queue-size: 512 -# =================================================================== -# Application specific properties -# Add your own application properties here, see the ApplicationProperties class -# to have type-safe configuration, like in the JHipsterProperties above -# -# More documentation is available at: -# https://www.jhipster.tech/common-application-properties/ -# =================================================================== - -application: - oncokb: - api-key: - redis: - enabled: false - type: single - address: redis://localhost:6379 - password: oncokb-public-redis-password - expiration: 3600 # By default objects stay 1 hour (in seconds) in the cache diff --git a/src/main/resources/config/application-prod.yml b/src/main/resources/config/application-prod.yml index 05733a876..940314e17 100644 --- a/src/main/resources/config/application-prod.yml +++ b/src/main/resources/config/application-prod.yml @@ -17,7 +17,7 @@ logging: level: ROOT: INFO tech.jhipster: INFO - org.mskcc.oncokb.transcript: INFO + org.mskcc.oncokb.curation: INFO management: metrics: @@ -33,7 +33,7 @@ spring: enabled: false datasource: type: com.zaxxer.hikari.HikariDataSource - url: jdbc:mysql://localhost:3306/oncokb-transcript?useUnicode=true&characterEncoding=utf8&useSSL=false&useLegacyDatetimeCode=false&serverTimezone=UTC&createDatabaseIfNotExist=true + url: jdbc:mysql://localhost:3306/oncokb-curation?useUnicode=true&characterEncoding=utf8&useSSL=false&useLegacyDatetimeCode=false&serverTimezone=UTC&createDatabaseIfNotExist=true username: root password: hikari: @@ -48,12 +48,17 @@ spring: # Replace by 'prod, faker' to add the faker context and have sample data loaded in production liquibase: contexts: prod + mail: + host: localhost + port: 25 + username: + password: thymeleaf: cache: true # =================================================================== # To enable TLS in production, generate a certificate using: -# keytool -genkey -alias oncokb-transcript -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650 +# keytool -genkey -alias oncokb-curation -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650 # # You can also use Let's Encrypt: # https://maximilian-boehm.com/hp2121/Create-a-Java-Keystore-JKS-from-Let-s-Encrypt-Certificates.htm @@ -90,11 +95,18 @@ jhipster: timeToLiveInDays: 1461 cache: # Cache configuration redis: # Redis configuration - expiration: 3600 # By default objects stay 1 hour (in seconds) in the cache + expiration: 3600 # By default, objects stay 1 hour (in seconds) in the cache server: redis://localhost:6379 cluster: false # server: redis://localhost:6379,redis://localhost:16379,redis://localhost:26379 # cluster: true + logging: + use-json-format: false # By default, logs are not in Json format + logstash: # Forward logs to logstash over a socket, used by LoggingConfiguration + enabled: false + host: localhost + port: 5000 + ring-buffer-size: 512 security: authentication: jwt: @@ -107,13 +119,16 @@ jhipster: # Token is valid 24 hours token-validity-in-seconds: 86400 token-validity-in-seconds-for-remember-me: 2592000 - logging: - use-json-format: false # By default, logs are not in Json format - logstash: # Forward logs to logstash over a socket, used by LoggingConfiguration - enabled: false - host: localhost - port: 5000 - queue-size: 512 + +# =================================================================== +# Sentry specific properties +# How to configure Sentry Spring Boot: https://docs.sentry.io/platforms/java/guides/spring-boot/ +# Full reference is available at: https://github.com/getsentry/sentry-java/blob/main/sentry-spring-boot-starter/src/main/java/io/sentry/spring/boot/SentryProperties.java +# =================================================================== +sentry: + dsn: + # send handled exception to sentry as well + exception-resolver-order: -2147483647 # =================================================================== # Application specific properties # Add your own application properties here, see the ApplicationProperties class diff --git a/src/main/resources/config/application.yml b/src/main/resources/config/application.yml index 8e9a4b191..25b454eb2 100644 --- a/src/main/resources/config/application.yml +++ b/src/main/resources/config/application.yml @@ -13,29 +13,96 @@ # Full reference is available at: # http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html # =================================================================== + +--- +# Conditionally disable springdoc on missing api-docs profile +spring: + config: + activate: + on-profile: '!api-docs' +springdoc: + show-actuator: true + api-docs: + enabled: false +--- management: + endpoints: + web: + base-path: /management + exposure: + include: + - configprops + - env + - health + - info + - jhimetrics + - jhiopenapigroups + - logfile + - loggers + - prometheus + - threaddump + - caches + - liquibase + endpoint: + health: + show-details: when_authorized + roles: 'ROLE_ADMIN' + probes: + enabled: true + group: + liveness: + include: livenessState + readiness: + include: readinessState,db + jhimetrics: + enabled: true info: git: mode: full + env: + enabled: true health: mail: - enabled: false + enabled: false # When using the MailService, configure an SMTP server and set this to true + prometheus: + metrics: + export: + enabled: true + step: 60 + observations: + key-values: + application: ${spring.application.name} + metrics: + enable: + http: true + jvm: true + logback: true + process: true + system: true + distribution: + percentiles-histogram: + all: true + percentiles: + all: 0, 0.5, 0.75, 0.95, 0.99, 1.0 + data: + repository: + autotime: + enabled: true spring: application: - name: oncokb-transcript + name: oncokb-curation profiles: # The commented value for `active` can be replaced with valid Spring profiles to load. # Otherwise, it will be filled in by maven when building the JAR file # Either way, it can be overridden by `--spring.profiles.active` value passed in the commandline or `-Dspring.profiles.active` set in `JAVA_OPTS` - active: #spring.profiles.active# + active: '@spring.profiles.active@' group: dev: - dev - api-docs - # - importer - # Uncomment to activate TLS for the dev profile - #- tls + # Uncomment to activate TLS for the dev profile + #- tls jmx: enabled: false data: @@ -46,6 +113,7 @@ spring: open-in-view: false properties: hibernate.jdbc.time_zone: UTC + hibernate.timezone.default_storage: NORMALIZE hibernate.id.new_generator_mappings: true hibernate.connection.provider_disables_autocommit: true hibernate.cache.use_second_level_cache: false @@ -60,28 +128,24 @@ spring: hibernate: ddl-auto: none naming: - physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy + physical-strategy: org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy messages: basename: i18n/messages main: allow-bean-definition-overriding: true - security: - user: - name: admin - password: admin - roles: - - ADMIN - - USER + mvc: + problemdetails: + enabled: true task: execution: - thread-name-prefix: oncokb-transcript-task- + thread-name-prefix: oncokb-curation-task- pool: core-size: 2 max-size: 50 queue-capacity: 10000 scheduling: - thread-name-prefix: oncokb-transcript-scheduling- + thread-name-prefix: oncokb-curation-scheduling- pool: size: 2 thymeleaf: @@ -89,9 +153,17 @@ spring: output: ansi: console-available: true - jackson: - mapper: - accept-case-insensitive-enums: true + security: + oauth2: + client: + provider: + oidc: + issuer-uri: http://localhost:8080/auth/realms/oncokb-curation + registration: + oidc: + client-id: web_app + client-secret: CLIENT_SECRET + scope: openid,profile,email server: servlet: @@ -104,6 +176,9 @@ info: # Comma separated list of profiles that will trigger the ribbon to show display-ribbon-on-profiles: 'dev' +javers: + commitIdGenerator: random + # =================================================================== # JHipster specific properties # @@ -112,7 +187,7 @@ info: jhipster: clientApp: - name: 'oncokbTranscriptApp' + name: 'oncokbCurationApp' # By default CORS is disabled. Uncomment to enable. # cors: # allowed-origins: "http://localhost:8100,http://localhost:9000" @@ -122,21 +197,32 @@ jhipster: # allow-credentials: true # max-age: 1800 mail: - from: oncokb-transcript@localhost + from: oncokb-curation@localhost api-docs: - default-include-pattern: ${server.servlet.context-path:}/api/.* - management-include-pattern: ${server.servlet.context-path:}/management/.* - title: oncokb-transcript API - description: oncokb-transcript API documentation - version: 0.0.1 + default-include-pattern: /api/** + management-include-pattern: /management/** + title: OncoKB Curation Platform API + description: OncoKB Curation Platform API documentation + version: 2.0.0 terms-of-service-url: contact-name: contact-url: contact-email: - license: unlicensed - license-url: + license: 'Terms of Use' + license-url: 'https://www.oncokb.org/terms' security: - content-security-policy: "default-src 'self'; frame-src 'self' data:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://storage.googleapis.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:" + content-security-policy: "default-src 'self'; frame-src 'self' data:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://storage.googleapis.com https://*.firebaseio.com https://www.googletagmanager.com https://*.heapanalytics.com; style-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com; img-src 'self' data: https://*.google.com https://heapanalytics.com https://*.googleusercontent.com; font-src 'self' data: https://cdnjs.cloudflare.com; connect-src 'self' ws://*.firebaseio.com https://*;" + oauth2: + audience: + - account + - api://default + authentication: + jwt: + # This token must be encoded using Base64 and be at least 256 bits long (you can type `openssl rand -base64 64` on your command line to generate a 512 bits one) + base64-secret: NGUwNTlhNDNhOWQ2ZGJlMmEzODczOWJjYWM2MWY4NDAwOTM4YTBmNGFjM2UxNjczZDU2YWZjZjc3MjdkNmU4YjVhZmIwYzI1NDhjMDFkZThiYmE5Mjc5MjM0MGVhODU5MGFhMTAyOTE0M2I3ODA1MGUzZWFhYWUwNWY2ZDgyNjQ= + # Token is valid 24 hours + token-validity-in-seconds: 86400 + token-validity-in-seconds-for-remember-me: 2592000 # =================================================================== # Application specific properties # Add your own application properties here, see the ApplicationProperties class @@ -146,6 +232,5 @@ jhipster: # https://www.jhipster.tech/common-application-properties/ # =================================================================== -# application: application: - name: oncokb-transcript + name: oncokb-curation diff --git a/src/main/resources/config/liquibase/changelog/00000000000000_initial_schema.xml b/src/main/resources/config/liquibase/changelog/00000000000000_initial_schema.xml index e33d9b7d4..ccfba017e 100644 --- a/src/main/resources/config/liquibase/changelog/00000000000000_initial_schema.xml +++ b/src/main/resources/config/liquibase/changelog/00000000000000_initial_schema.xml @@ -3,21 +3,81 @@ xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.5.xsd + xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd"> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + diff --git a/src/main/resources/config/liquibase/changelog/20210129192153_added_entity_Sequence.xml b/src/main/resources/config/liquibase/changelog/20210129192153_added_entity_Sequence.xml deleted file mode 100644 index 1ea2ebf07..000000000 --- a/src/main/resources/config/liquibase/changelog/20210129192153_added_entity_Sequence.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/config/liquibase/changelog/20210129192153_added_entity_constraints_Sequence.xml b/src/main/resources/config/liquibase/changelog/20210129192153_added_entity_constraints_Sequence.xml deleted file mode 100644 index 786d10300..000000000 --- a/src/main/resources/config/liquibase/changelog/20210129192153_added_entity_constraints_Sequence.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - diff --git a/src/main/resources/config/liquibase/changelog/20210201194018_added_entity_Transcript.xml b/src/main/resources/config/liquibase/changelog/20210201194018_added_entity_Transcript.xml deleted file mode 100644 index d76859800..000000000 --- a/src/main/resources/config/liquibase/changelog/20210201194018_added_entity_Transcript.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/config/liquibase/changelog/20210201194018_added_entity_constraints_Transcript.xml b/src/main/resources/config/liquibase/changelog/20210201194018_added_entity_constraints_Transcript.xml deleted file mode 100644 index 7d5e77d09..000000000 --- a/src/main/resources/config/liquibase/changelog/20210201194018_added_entity_constraints_Transcript.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - diff --git a/src/main/resources/config/liquibase/changelog/20210421184924_added_entity_Drug.xml b/src/main/resources/config/liquibase/changelog/20210421184924_added_entity_Drug.xml deleted file mode 100644 index 7117baffd..000000000 --- a/src/main/resources/config/liquibase/changelog/20210421184924_added_entity_Drug.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/config/liquibase/changelog/20210421184925_added_entity_DrugSynonym.xml b/src/main/resources/config/liquibase/changelog/20210421184925_added_entity_DrugSynonym.xml deleted file mode 100644 index 76a292cef..000000000 --- a/src/main/resources/config/liquibase/changelog/20210421184925_added_entity_DrugSynonym.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/config/liquibase/changelog/20210421184925_added_entity_constraints_DrugSynonym.xml b/src/main/resources/config/liquibase/changelog/20210421184925_added_entity_constraints_DrugSynonym.xml deleted file mode 100644 index e96b700dd..000000000 --- a/src/main/resources/config/liquibase/changelog/20210421184925_added_entity_constraints_DrugSynonym.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - diff --git a/src/main/resources/config/liquibase/changelog/20210421184926_added_entity_Info.xml b/src/main/resources/config/liquibase/changelog/20210421184926_added_entity_Info.xml deleted file mode 100644 index e67d6c471..000000000 --- a/src/main/resources/config/liquibase/changelog/20210421184926_added_entity_Info.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/config/liquibase/changelog/20210503173531_added_entity_Gene.xml b/src/main/resources/config/liquibase/changelog/20210503173531_added_entity_Gene.xml deleted file mode 100644 index 95c444df5..000000000 --- a/src/main/resources/config/liquibase/changelog/20210503173531_added_entity_Gene.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/config/liquibase/changelog/20210503173532_added_entity_GeneAlias.xml b/src/main/resources/config/liquibase/changelog/20210503173532_added_entity_GeneAlias.xml deleted file mode 100644 index 887ea16ce..000000000 --- a/src/main/resources/config/liquibase/changelog/20210503173532_added_entity_GeneAlias.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/config/liquibase/changelog/20210503173532_added_entity_constraints_GeneAlias.xml b/src/main/resources/config/liquibase/changelog/20210503173532_added_entity_constraints_GeneAlias.xml deleted file mode 100644 index 92a1afd67..000000000 --- a/src/main/resources/config/liquibase/changelog/20210503173532_added_entity_constraints_GeneAlias.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - diff --git a/src/main/resources/config/liquibase/changelog/20211118024252_added_entity_GenomeFragment.xml b/src/main/resources/config/liquibase/changelog/20211118024252_added_entity_GenomeFragment.xml deleted file mode 100644 index f04c3817c..000000000 --- a/src/main/resources/config/liquibase/changelog/20211118024252_added_entity_GenomeFragment.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/config/liquibase/changelog/20211118024252_added_entity_constraints_GenomeFragment.xml b/src/main/resources/config/liquibase/changelog/20211118024252_added_entity_constraints_GenomeFragment.xml deleted file mode 100644 index 785bd2dc6..000000000 --- a/src/main/resources/config/liquibase/changelog/20211118024252_added_entity_constraints_GenomeFragment.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - diff --git a/src/main/resources/config/liquibase/changelog/20211130002704_added_entity_EnsemblGene.xml b/src/main/resources/config/liquibase/changelog/20211130002704_added_entity_EnsemblGene.xml deleted file mode 100644 index 706dffd07..000000000 --- a/src/main/resources/config/liquibase/changelog/20211130002704_added_entity_EnsemblGene.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/config/liquibase/changelog/20211130002704_added_entity_constraints_EnsemblGene.xml b/src/main/resources/config/liquibase/changelog/20211130002704_added_entity_constraints_EnsemblGene.xml deleted file mode 100644 index 33a07a8e7..000000000 --- a/src/main/resources/config/liquibase/changelog/20211130002704_added_entity_constraints_EnsemblGene.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - diff --git a/src/main/resources/config/liquibase/changelog/20220401174634_added_entity_Sequence.xml b/src/main/resources/config/liquibase/changelog/20220401174634_added_entity_Sequence.xml new file mode 100644 index 000000000..e7ff85ab0 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20220401174634_added_entity_Sequence.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20220401174634_added_entity_constraints_Sequence.xml b/src/main/resources/config/liquibase/changelog/20220401174634_added_entity_constraints_Sequence.xml new file mode 100644 index 000000000..1b69e0131 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20220401174634_added_entity_constraints_Sequence.xml @@ -0,0 +1,17 @@ + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20220401174635_added_entity_Transcript.xml b/src/main/resources/config/liquibase/changelog/20220401174635_added_entity_Transcript.xml new file mode 100644 index 000000000..ac6d3c7ed --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20220401174635_added_entity_Transcript.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20220401174635_added_entity_constraints_Transcript.xml b/src/main/resources/config/liquibase/changelog/20220401174635_added_entity_constraints_Transcript.xml new file mode 100644 index 000000000..7d3a119df --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20220401174635_added_entity_constraints_Transcript.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20220401174636_added_entity_Info.xml b/src/main/resources/config/liquibase/changelog/20220401174636_added_entity_Info.xml new file mode 100644 index 000000000..8ae0ac355 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20220401174636_added_entity_Info.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20220401174637_added_entity_Gene.xml b/src/main/resources/config/liquibase/changelog/20220401174637_added_entity_Gene.xml new file mode 100644 index 000000000..2c1e6f99c --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20220401174637_added_entity_Gene.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20220401174637_added_entity_constraints_Gene.xml b/src/main/resources/config/liquibase/changelog/20220401174637_added_entity_constraints_Gene.xml new file mode 100644 index 000000000..40fe54c82 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20220401174637_added_entity_constraints_Gene.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20220401174639_added_entity_GenomeFragment.xml b/src/main/resources/config/liquibase/changelog/20220401174639_added_entity_GenomeFragment.xml new file mode 100644 index 000000000..9cba61f91 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20220401174639_added_entity_GenomeFragment.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20220401174639_added_entity_constraints_GenomeFragment.xml b/src/main/resources/config/liquibase/changelog/20220401174639_added_entity_constraints_GenomeFragment.xml new file mode 100644 index 000000000..8dc0cf0ef --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20220401174639_added_entity_constraints_GenomeFragment.xml @@ -0,0 +1,23 @@ + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20220401174640_added_entity_EnsemblGene.xml b/src/main/resources/config/liquibase/changelog/20220401174640_added_entity_EnsemblGene.xml new file mode 100644 index 000000000..961254e85 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20220401174640_added_entity_EnsemblGene.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20220401174640_added_entity_constraints_EnsemblGene.xml b/src/main/resources/config/liquibase/changelog/20220401174640_added_entity_constraints_EnsemblGene.xml new file mode 100644 index 000000000..5a7d28bc1 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20220401174640_added_entity_constraints_EnsemblGene.xml @@ -0,0 +1,23 @@ + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20220401174641_added_entity_Drug.xml b/src/main/resources/config/liquibase/changelog/20220401174641_added_entity_Drug.xml new file mode 100644 index 000000000..cd84a28a1 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20220401174641_added_entity_Drug.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20220401174641_added_entity_constraints_Drug.xml b/src/main/resources/config/liquibase/changelog/20220401174641_added_entity_constraints_Drug.xml new file mode 100644 index 000000000..5f7bb9716 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20220401174641_added_entity_constraints_Drug.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20220401174643_added_entity_SpecimenType.xml b/src/main/resources/config/liquibase/changelog/20220401174643_added_entity_SpecimenType.xml new file mode 100644 index 000000000..6d0f60b77 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20220401174643_added_entity_SpecimenType.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20220401174644_added_entity_CompanionDiagnosticDevice.xml b/src/main/resources/config/liquibase/changelog/20220401174644_added_entity_CompanionDiagnosticDevice.xml new file mode 100644 index 000000000..313dbbb93 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20220401174644_added_entity_CompanionDiagnosticDevice.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20220401174644_added_entity_constraints_CompanionDiagnosticDevice.xml b/src/main/resources/config/liquibase/changelog/20220401174644_added_entity_constraints_CompanionDiagnosticDevice.xml new file mode 100644 index 000000000..088fae711 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20220401174644_added_entity_constraints_CompanionDiagnosticDevice.xml @@ -0,0 +1,23 @@ + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20220401174645_added_entity_FdaSubmissionType.xml b/src/main/resources/config/liquibase/changelog/20220401174645_added_entity_FdaSubmissionType.xml new file mode 100644 index 000000000..ebd853a3a --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20220401174645_added_entity_FdaSubmissionType.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20220401174646_added_entity_FdaSubmission.xml b/src/main/resources/config/liquibase/changelog/20220401174646_added_entity_FdaSubmission.xml new file mode 100644 index 000000000..b1180c22b --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20220401174646_added_entity_FdaSubmission.xml @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20220401174646_added_entity_constraints_FdaSubmission.xml b/src/main/resources/config/liquibase/changelog/20220401174646_added_entity_constraints_FdaSubmission.xml new file mode 100644 index 000000000..e17f6f635 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20220401174646_added_entity_constraints_FdaSubmission.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20220401174648_added_entity_Alteration.xml b/src/main/resources/config/liquibase/changelog/20220401174648_added_entity_Alteration.xml new file mode 100644 index 000000000..00ebad4d2 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20220401174648_added_entity_Alteration.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20220401174648_added_entity_constraints_Alteration.xml b/src/main/resources/config/liquibase/changelog/20220401174648_added_entity_constraints_Alteration.xml new file mode 100644 index 000000000..39a70ee5a --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20220401174648_added_entity_constraints_Alteration.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20220401174649_added_entity_CancerType.xml b/src/main/resources/config/liquibase/changelog/20220401174649_added_entity_CancerType.xml new file mode 100644 index 000000000..9287a2d5e --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20220401174649_added_entity_CancerType.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20220401174649_added_entity_constraints_CancerType.xml b/src/main/resources/config/liquibase/changelog/20220401174649_added_entity_constraints_CancerType.xml new file mode 100644 index 000000000..9d66de292 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20220401174649_added_entity_constraints_CancerType.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20220401213213_added_entity_Article.xml b/src/main/resources/config/liquibase/changelog/20220401213213_added_entity_Article.xml new file mode 100644 index 000000000..8bc3699b8 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20220401213213_added_entity_Article.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20220401213213_added_entity_constraints_Article.xml b/src/main/resources/config/liquibase/changelog/20220401213213_added_entity_constraints_Article.xml new file mode 100644 index 000000000..3c2602a14 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20220401213213_added_entity_constraints_Article.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20220428161233_added_entity_CategoricalAlteration.xml b/src/main/resources/config/liquibase/changelog/20220428161233_added_entity_CategoricalAlteration.xml new file mode 100644 index 000000000..b633f4ee3 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20220428161233_added_entity_CategoricalAlteration.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20220428161233_added_entity_constraints_CategoricalAlteration.xml b/src/main/resources/config/liquibase/changelog/20220428161233_added_entity_constraints_CategoricalAlteration.xml new file mode 100644 index 000000000..da2a2499e --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20220428161233_added_entity_constraints_CategoricalAlteration.xml @@ -0,0 +1,17 @@ + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20220513144615_added_entity_Consequence.xml b/src/main/resources/config/liquibase/changelog/20220513144615_added_entity_Consequence.xml new file mode 100644 index 000000000..d6ea47bc5 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20220513144615_added_entity_Consequence.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20230525144705_added_entity_FdaDrug.xml b/src/main/resources/config/liquibase/changelog/20230525144705_added_entity_FdaDrug.xml new file mode 100644 index 000000000..08d86a4b3 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20230525144705_added_entity_FdaDrug.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20230525144705_added_entity_constraints_FdaDrug.xml b/src/main/resources/config/liquibase/changelog/20230525144705_added_entity_constraints_FdaDrug.xml new file mode 100644 index 000000000..e9b5f8d1a --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20230525144705_added_entity_constraints_FdaDrug.xml @@ -0,0 +1,17 @@ + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20230912194141_added_entity_SeqRegion.xml b/src/main/resources/config/liquibase/changelog/20230912194141_added_entity_SeqRegion.xml new file mode 100644 index 000000000..8e1dc3bf2 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20230912194141_added_entity_SeqRegion.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20230916014824_added_entity_Flag.xml b/src/main/resources/config/liquibase/changelog/20230916014824_added_entity_Flag.xml new file mode 100644 index 000000000..b7a87bb47 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20230916014824_added_entity_Flag.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20231101214339_added_entity_Association.xml b/src/main/resources/config/liquibase/changelog/20231101214339_added_entity_Association.xml new file mode 100644 index 000000000..799999d2e --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20231101214339_added_entity_Association.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20231101214339_added_entity_constraints_Association.xml b/src/main/resources/config/liquibase/changelog/20231101214339_added_entity_constraints_Association.xml new file mode 100644 index 000000000..8ddc1d26b --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20231101214339_added_entity_constraints_Association.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20231101214341_added_entity_ClinicalTrial.xml b/src/main/resources/config/liquibase/changelog/20231101214341_added_entity_ClinicalTrial.xml new file mode 100644 index 000000000..f2762268e --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20231101214341_added_entity_ClinicalTrial.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20231101214341_added_entity_constraints_ClinicalTrial.xml b/src/main/resources/config/liquibase/changelog/20231101214341_added_entity_constraints_ClinicalTrial.xml new file mode 100644 index 000000000..f113f56d9 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20231101214341_added_entity_constraints_ClinicalTrial.xml @@ -0,0 +1,23 @@ + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20231101214342_added_entity_ClinicalTrialArm.xml b/src/main/resources/config/liquibase/changelog/20231101214342_added_entity_ClinicalTrialArm.xml new file mode 100644 index 000000000..af0f4a42f --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20231101214342_added_entity_ClinicalTrialArm.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20231101214342_added_entity_constraints_ClinicalTrialArm.xml b/src/main/resources/config/liquibase/changelog/20231101214342_added_entity_constraints_ClinicalTrialArm.xml new file mode 100644 index 000000000..3760c94ba --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20231101214342_added_entity_constraints_ClinicalTrialArm.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20231101214344_added_entity_EligibilityCriteria.xml b/src/main/resources/config/liquibase/changelog/20231101214344_added_entity_EligibilityCriteria.xml new file mode 100644 index 000000000..bf46625b2 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20231101214344_added_entity_EligibilityCriteria.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20231101214344_added_entity_constraints_EligibilityCriteria.xml b/src/main/resources/config/liquibase/changelog/20231101214344_added_entity_constraints_EligibilityCriteria.xml new file mode 100644 index 000000000..21fe98bd0 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20231101214344_added_entity_constraints_EligibilityCriteria.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20231101214345_added_entity_Evidence.xml b/src/main/resources/config/liquibase/changelog/20231101214345_added_entity_Evidence.xml new file mode 100644 index 000000000..c6dced3a7 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20231101214345_added_entity_Evidence.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20231101214345_added_entity_constraints_Evidence.xml b/src/main/resources/config/liquibase/changelog/20231101214345_added_entity_constraints_Evidence.xml new file mode 100644 index 000000000..550603757 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20231101214345_added_entity_constraints_Evidence.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20231101214346_added_entity_GenomicIndicator.xml b/src/main/resources/config/liquibase/changelog/20231101214346_added_entity_GenomicIndicator.xml new file mode 100644 index 000000000..ec6106531 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20231101214346_added_entity_GenomicIndicator.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20231101214346_added_entity_constraints_GenomicIndicator.xml b/src/main/resources/config/liquibase/changelog/20231101214346_added_entity_constraints_GenomicIndicator.xml new file mode 100644 index 000000000..d7c000f9d --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20231101214346_added_entity_constraints_GenomicIndicator.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20231101214348_added_entity_LevelOfEvidence.xml b/src/main/resources/config/liquibase/changelog/20231101214348_added_entity_LevelOfEvidence.xml new file mode 100644 index 000000000..7dfd38969 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20231101214348_added_entity_LevelOfEvidence.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20231101214349_added_entity_NciThesaurus.xml b/src/main/resources/config/liquibase/changelog/20231101214349_added_entity_NciThesaurus.xml new file mode 100644 index 000000000..7a69a8991 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20231101214349_added_entity_NciThesaurus.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20231101214349_added_entity_constraints_NciThesaurus.xml b/src/main/resources/config/liquibase/changelog/20231101214349_added_entity_constraints_NciThesaurus.xml new file mode 100644 index 000000000..8e46b895a --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20231101214349_added_entity_constraints_NciThesaurus.xml @@ -0,0 +1,23 @@ + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20231101214350_added_entity_Synonym.xml b/src/main/resources/config/liquibase/changelog/20231101214350_added_entity_Synonym.xml new file mode 100644 index 000000000..6d51ed699 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20231101214350_added_entity_Synonym.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20240130003658_added_entity_AlleleState.xml b/src/main/resources/config/liquibase/changelog/20240130003658_added_entity_AlleleState.xml new file mode 100644 index 000000000..175eda35c --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20240130003658_added_entity_AlleleState.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20240320171441_added_entity_Rule.xml b/src/main/resources/config/liquibase/changelog/20240320171441_added_entity_Rule.xml new file mode 100644 index 000000000..239bac8a5 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20240320171441_added_entity_Rule.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20240320171441_added_entity_constraints_Rule.xml b/src/main/resources/config/liquibase/changelog/20240320171441_added_entity_constraints_Rule.xml new file mode 100644 index 000000000..8a68e8eeb --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20240320171441_added_entity_constraints_Rule.xml @@ -0,0 +1,17 @@ + + + + + + + + diff --git a/src/main/resources/config/liquibase/changelog/20240516000000_added_entity_constraints_User.xml b/src/main/resources/config/liquibase/changelog/20240516000000_added_entity_constraints_User.xml new file mode 100644 index 000000000..6eb05135a --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20240516000000_added_entity_constraints_User.xml @@ -0,0 +1,18 @@ + + + + + + + + + + diff --git a/src/main/resources/config/liquibase/data/allele_state.csv b/src/main/resources/config/liquibase/data/allele_state.csv new file mode 100644 index 000000000..63b97386e --- /dev/null +++ b/src/main/resources/config/liquibase/data/allele_state.csv @@ -0,0 +1,5 @@ +name +Monoallelic +Biallelic +Mosaic +Carrier diff --git a/src/main/resources/config/liquibase/data/authority.csv b/src/main/resources/config/liquibase/data/authority.csv new file mode 100644 index 000000000..bcff3109f --- /dev/null +++ b/src/main/resources/config/liquibase/data/authority.csv @@ -0,0 +1,5 @@ +name +ROLE_ADMIN +ROLE_DEV +ROLE_USER +ROLE_CURATOR diff --git a/src/main/resources/config/liquibase/data/cancer_type.csv b/src/main/resources/config/liquibase/data/cancer_type.csv new file mode 100644 index 000000000..115218a6d --- /dev/null +++ b/src/main/resources/config/liquibase/data/cancer_type.csv @@ -0,0 +1,990 @@ +id;code;color;level;main_type;subtype;tissue;tumor_form;parent_id +1;;MIXED;-1;All Tumors;NULL;MIXED;MIXED;NULL +2;;MIXED;-1;All Liquid Tumors;NULL;MIXED;LIQUID;NULL +3;;MIXED;-1;All Solid Tumors;NULL;MIXED;SOLID;NULL +4;;MIXED;-1;Germline Disposition;NULL;MIXED;MIXED;NULL +5;;MIXED;-1;Other Tumor Types;NULL;MIXED;MIXED;NULL +6;;MIXED;-1;Other Solid Tumor Types;NULL;MIXED;SOLID;NULL +7;;MIXED;-1;Other Liquid Tumor Types;NULL;MIXED;LIQUID;NULL +8;;NULL;0;Tissue;Tissue;NULL;MIXED;NULL +9;ADRENAL_GLAND;Purple;1;Adrenal Gland Cancer, NOS;Adrenal Gland;Adrenal Gland;SOLID;8 +10;CERVIX;Teal;1;Cervical Cancer, NOS;Cervix;Cervix;SOLID;8 +11;AMPULLA_OF_VATER;Purple;1;Ampullary Carcinoma, NOS;Ampulla of Vater;Ampulla of Vater;SOLID;8 +12;BLADDER;Yellow;1;Bladder/Urinary Tract Cancer, NOS;Bladder/Urinary Tract;Bladder/Urinary Tract;SOLID;8 +13;PERITONEUM;Green;1;Peritoneal Cancer, NOS;Peritoneum;Peritoneum;SOLID;8 +14;PNS;Gray;1;Peripheral Nervous System Cancer, NOS;Peripheral Nervous System;Peripheral Nervous System;SOLID;8 +15;LYMPH;LimeGreen;1;Lymphatic Cancer, NOS;Lymphoid;Lymphoid;LIQUID;8 +16;EYE;Green;1;Eye Cancer, NOS;Eye;Eye;SOLID;8 +17;BOWEL;SaddleBrown;1;Bowel Cancer, NOS;Bowel;Bowel;SOLID;8 +18;HEAD_NECK;DarkRed;1;Head and Neck Cancer, NOS;Head and Neck;Head and Neck;SOLID;8 +19;PROSTATE;Cyan;1;Prostate Cancer, NOS;Prostate;Prostate;SOLID;8 +20;MYELOID;LightSalmon;1;Blood Cancer, NOS;Myeloid;Myeloid;LIQUID;8 +21;BONE;White;1;Bone Cancer, NOS;Bone;Bone;SOLID;8 +22;BILIARY_TRACT;Green;1;Biliary Tract Cancer, NOS;Biliary Tract;Biliary Tract;SOLID;8 +23;KIDNEY;Orange;1;Kidney Cancer, NOS;Kidney;Kidney;SOLID;8 +24;LUNG;Gainsboro;1;Lung Cancer, NOS;Lung;Lung;SOLID;8 +25;PANCREAS;Purple;1;Pancreatic Cancer, NOS;Pancreas;Pancreas;SOLID;8 +26;STOMACH;LightSkyBlue;1;Esophageal/Stomach Cancer, NOS;Esophagus/Stomach;Esophagus/Stomach;SOLID;8 +27;SKIN;Black;1;Skin Cancer, NOS;Skin;Skin;SOLID;8 +28;OVARY;LightBlue;1;Ovarian/Fallopian Tube Cancer, NOS;Ovary/Fallopian Tube;Ovary/Fallopian Tube;SOLID;8 +29;LIVER;MediumSeaGreen;1;Liver Cancer, NOS;Liver;Liver;SOLID;8 +30;TESTIS;Red;1;Testicular Cancer, NOS;Testis;Testis;SOLID;8 +31;UTERUS;PeachPuff;1;Uterine Cancer, NOS;Uterus;Uterus;SOLID;8 +32;BRAIN;Gray;1;CNS/Brain Cancer, NOS;CNS/Brain;CNS/Brain;SOLID;8 +33;THYROID;Teal;1;Thyroid Cancer, NOS;Thyroid;Thyroid;SOLID;8 +34;SOFT_TISSUE;LightYellow;1;Soft Tissue Cancer, NOS;Soft Tissue;Soft Tissue;SOLID;8 +35;THYMUS;Purple;1;Thymic Cancer, NOS;Thymus;Thymus;SOLID;8 +36;PLEURA;Blue;1;Pleural Cancer, NOS;Pleura;Pleura;SOLID;8 +37;OTHER;Black;1;Other Cancer, NOS;Other;Other;SOLID;8 +38;PENIS;Blue;1;Penile Cancer, NOS;Penis;Penis;SOLID;8 +39;BREAST;HotPink;1;Breast Cancer, NOS;Breast;Breast;SOLID;8 +40;VULVA;Purple;1;Vulvar/Vaginal Cancer, NOS;Vulva/Vagina;Vulva/Vagina;SOLID;8 +41;OHNCA;DarkRed;2;Head and Neck Cancer;Head and Neck Carcinoma, Other;Head and Neck;SOLID;18 +42;SCST;LightBlue;2;Sex Cord Stromal Tumor;Sex Cord Stromal Tumor;Ovary/Fallopian Tube;SOLID;28 +43;MBC;HotPink;2;Breast Cancer;Metaplastic Breast Cancer;Breast;SOLID;39 +44;LAM;Gainsboro;2;Non-Small Cell Lung Cancer;Pulmonary Lymphangiomyomatosis;Lung;SOLID;24 +45;SBL;DarkRed;2;Sialoblastoma;Sialoblastoma;Head and Neck;SOLID;18 +46;CABC;Teal;2;Cervical Cancer;Cervical Adenoid Basal Carcinoma;Cervix;SOLID;10 +47;LGT;Green;2;Lacrimal Gland Tumor;Lacrimal Gland Tumor;Eye;SOLID;16 +48;MFS;LightYellow;2;Soft Tissue Sarcoma;Myxofibrosarcoma;Soft Tissue;SOLID;34 +49;AN;Black;2;Skin Cancer, Non-Melanoma;Atypical Nevus;Skin;SOLID;27 +50;SELT;Gray;2;Sellar Tumor;Sellar Tumor;CNS/Brain;SOLID;32 +51;LNM;LimeGreen;2;Lymphatic Cancer, NOS;Lymphoid Neoplasm;Lymphoid;LIQUID;15 +52;PEMESO;Green;2;Mesothelioma;Peritoneal Mesothelioma;Peritoneum;SOLID;13 +53;HNSC;DarkRed;2;Head and Neck Cancer;Head and Neck Squamous Cell Carcinoma;Head and Neck;SOLID;18 +54;EMPSGC;Black;2;Skin Cancer, Non-Melanoma;Endocrine Mucin Producing Sweat Gland Carcinoma;Skin;SOLID;27 +55;CERMS;Teal;2;Cervical Cancer;Cervical Rhabdomyosarcoma;Cervix;SOLID;10 +56;ENCG;Gray;2;Glioma;Encapsulated Glioma;CNS/Brain;SOLID;32 +57;THHC;Teal;2;Thyroid Cancer;Hurthle Cell Thyroid Cancer;Thyroid;SOLID;33 +58;SRCBC;Yellow;2;Bladder Cancer;Plasmacytoid/Signet Ring Cell Bladder Carcinoma;Bladder/Urinary Tract;SOLID;12 +59;CCS;LightYellow;2;Soft Tissue Sarcoma;Clear Cell Sarcoma;Soft Tissue;SOLID;34 +60;UPA;Yellow;2;Bladder Cancer;Urothelial Papilloma;Bladder/Urinary Tract;SOLID;12 +61;MFH;LightYellow;2;Soft Tissue Sarcoma;Undifferentiated Pleomorphic Sarcoma/Malignant Fibrous Histiocytoma/High-Grade Spindle Cell Sarcoma;Soft Tissue;SOLID;34 +62;FIBS;LightYellow;2;Soft Tissue Sarcoma;Fibrosarcoma;Soft Tissue;SOLID;34 +63;SIC;SaddleBrown;2;Small Bowel Cancer;Small Intestinal Carcinoma;Bowel;SOLID;17 +64;NSCLC;Gainsboro;2;Non-Small Cell Lung Cancer;Non-Small Cell Lung Cancer;Lung;SOLID;24 +65;OGCT;LightBlue;2;Germ Cell Tumor;Ovarian Germ Cell Tumor;Ovary/Fallopian Tube;SOLID;28 +66;MAC;Black;2;Skin Cancer, Non-Melanoma;Microcystic Adnexal Carcinoma;Skin;SOLID;27 +67;OM;Green;2;Melanoma;Ocular Melanoma;Eye;SOLID;16 +68;PCNSMT;Gray;2;Primary CNS Melanocytic Tumors;Primary CNS Melanocytic Tumors;CNS/Brain;SOLID;32 +69;ASPS;LightYellow;2;Soft Tissue Sarcoma;Alveolar Soft Part Sarcoma;Soft Tissue;SOLID;34 +70;USARC;PeachPuff;2;Uterine Sarcoma;Uterine Sarcoma/Mesenchymal;Uterus;SOLID;31 +71;DSRCT;LightYellow;2;Soft Tissue Sarcoma;Desmoplastic Small-Round-Cell Tumor;Soft Tissue;SOLID;34 +72;THPD;Teal;2;Thyroid Cancer;Poorly Differentiated Thyroid Cancer;Thyroid;SOLID;33 +73;MBGN;LightSalmon;2;Blood Cancer, NOS;Myeloid Benign;Myeloid;LIQUID;20 +74;WDTC;Teal;2;Thyroid Cancer;Well-Differentiated Thyroid Cancer;Thyroid;SOLID;33 +75;CSCC;Black;2;Skin Cancer, Non-Melanoma;Cutaneous Squamous Cell Carcinoma;Skin;SOLID;27 +76;ADPA;Black;2;Skin Cancer, Non-Melanoma;Aggressive Digital Papillary Adenocarcinoma;Skin;SOLID;27 +77;SEBA;Black;2;Skin Cancer, Non-Melanoma;Sebaceous Carcinoma;Skin;SOLID;27 +78;NPC;DarkRed;2;Head and Neck Cancer;Nasopharyngeal Carcinoma;Head and Neck;SOLID;18 +79;PPCT;Black;2;Skin Cancer, Non-Melanoma;Proliferating Pilar Cystic Tumor;Skin;SOLID;27 +80;TAC;SaddleBrown;2;Tubular Adenoma of the Colon;Tubular Adenoma of the Colon;Bowel;SOLID;17 +81;CEAD;Teal;2;Cervical Cancer;Cervical Adenocarcinoma;Cervix;SOLID;10 +82;HEMA;LightYellow;2;Soft Tissue Sarcoma;Hemangioma;Soft Tissue;SOLID;34 +83;OVT;LightBlue;2;Ovarian Cancer;Ovarian Epithelial Tumor;Ovary/Fallopian Tube;SOLID;28 +84;NSGCT;Red;2;Germ Cell Tumor;Non-Seminomatous Germ Cell Tumor;Testis;SOLID;30 +85;SPN;Purple;2;Pancreatic Cancer;Solid Pseudopapillary Neoplasm of the Pancreas;Pancreas;SOLID;25 +86;MNM;LightSalmon;2;Blood Cancer, NOS;Myeloid Neoplasm;Myeloid;LIQUID;20 +87;AGA;SaddleBrown;2;Anal Cancer;Anal Gland Adenocarcinoma;Bowel;SOLID;17 +88;PAAD;Purple;2;Pancreatic Cancer;Pancreatic Adenocarcinoma;Pancreas;SOLID;25 +89;LMS;LightYellow;2;Soft Tissue Sarcoma;Leiomyosarcoma;Soft Tissue;SOLID;34 +90;SGAD;Black;2;Skin Cancer, Non-Melanoma;Sweat Gland Adenocarcinoma;Skin;SOLID;27 +91;SCBC;Yellow;2;Bladder Cancer;Small Cell Bladder Cancer;Bladder/Urinary Tract;SOLID;12 +92;MRT;Orange;2;Rhabdoid Cancer;Rhabdoid Cancer;Kidney;SOLID;23 +93;IMTB;Yellow;2;Bladder Cancer;Inflammatory Myofibroblastic Bladder Tumor;Bladder/Urinary Tract;SOLID;12 +94;LIMNET;MediumSeaGreen;2;Hepatobiliary Cancer;Malignant Nonepithelial Tumor of the Liver;Liver;SOLID;29 +95;IFS;LightYellow;2;Infantile Fibrosarcoma;Infantile Fibrosarcoma;Soft Tissue;SOLID;34 +96;RMS;LightYellow;2;Soft Tissue Sarcoma;Rhabdomyosarcoma;Soft Tissue;SOLID;34 +97;LAIS;Gainsboro;2;Non-Small Cell Lung Cancer;Lung Adenocarcinoma In Situ;Lung;SOLID;24 +98;VMA;Purple;2;Vulvar Carcinoma;Mucinous Adenocarcinoma of the Vulva/Vagina;Vulva/Vagina;SOLID;40 +99;VA;Purple;2;Vaginal Cancer;Vaginal Adenocarcinoma;Vulva/Vagina;SOLID;40 +100;GNBL;Gray;2;Peripheral Nervous System;Ganglioneuroblastoma;Peripheral Nervous System;SOLID;14 +101;TNET;Purple;2;Thymic Tumor;Thymic Neuroendocrine Tumor;Thymus;SOLID;35 +102;BGCT;Gray;2;Germ Cell Tumor;Germ Cell Tumor, Brain;CNS/Brain;SOLID;32 +103;RBL;Green;2;Retinoblastoma;Retinoblastoma;Eye;SOLID;16 +104;NST;Gray;2;Nerve Sheath Tumor;Nerve Sheath Tumor;Peripheral Nervous System;SOLID;14 +105;EGCT;Black;2;Germ Cell Tumor;Extra Gonadal Germ Cell Tumor;Other;SOLID;37 +106;LATL;LimeGreen;2;Lymphatic Cancer, NOS;Lymphoid Atypical;Lymphoid;LIQUID;15 +107;AFH;LightYellow;2;Angiomatoid Fibrous Histiocytoma;Angiomatoid Fibrous Histiocytoma;Soft Tissue;SOLID;34 +108;BRAME;HotPink;2;Breast Cancer;Adenomyoepithelioma of the Breast;Breast;SOLID;39 +109;PAAC;Purple;2;Pancreatic Cancer;Acinar Cell Carcinoma of the Pancreas;Pancreas;SOLID;25 +110;PINT;Gray;2;Pineal Tumor;Pineal Tumor;CNS/Brain;SOLID;32 +111;VGCE;Teal;2;Cervical Cancer;Villoglandular Adenocarcinoma of the Cervix;Cervix;SOLID;10 +112;PRSC;Cyan;2;Prostate Cancer;Prostate Squamous Cell Carcinoma;Prostate;SOLID;19 +113;CESC;Teal;2;Cervical Cancer;Cervical Squamous Cell Carcinoma;Cervix;SOLID;10 +114;SYNS;LightYellow;2;Soft Tissue Sarcoma;Synovial Sarcoma;Soft Tissue;SOLID;34 +115;CHOL;Green;2;Hepatobiliary Cancer;Cholangiocarcinoma;Biliary Tract;SOLID;22 +116;ESST;LightYellow;2;Soft Tissue Sarcoma;Ewing Sarcoma of Soft Tissue;Soft Tissue;SOLID;34 +117;PTH;DarkRed;2;Parathyroid Cancer;Parathyroid Cancer;Head and Neck;SOLID;18 +118;WT;Orange;2;Wilms Tumor;Wilms' Tumor;Kidney;SOLID;23 +119;TET;Purple;2;Thymic Tumor;Thymic Epithelial Tumor;Thymus;SOLID;35 +120;IUP;Yellow;2;Bladder Cancer;Inverted Urothelial Papilloma;Bladder/Urinary Tract;SOLID;12 +121;PORO;Black;2;Skin Cancer, Non-Melanoma;Poroma/Acrospiroma;Skin;SOLID;27 +122;HTAT;Teal;2;Thyroid Cancer;Hyalinizing Trabecular Adenoma of the Thyroid;Thyroid;SOLID;33 +123;PHC;Purple;2;Pheochromocytoma;Pheochromocytoma;Adrenal Gland;SOLID;9 +124;ESMM;LightSkyBlue;2;Melanoma;Mucosal Melanoma of the Esophagus;Esophagus/Stomach;SOLID;26 +125;LIPO;LightYellow;2;Soft Tissue Sarcoma;Liposarcoma;Soft Tissue;SOLID;34 +126;DCIS;HotPink;2;Breast Cancer;Breast Ductal Carcinoma In Situ;Breast;SOLID;39 +127;MCC;Black;2;Skin Cancer, Non-Melanoma;Merkel Cell Carcinoma;Skin;SOLID;27 +128;URCA;Yellow;2;Bladder Cancer;Urachal Carcinoma;Bladder/Urinary Tract;SOLID;12 +129;AECA;Black;2;Skin Cancer, Non-Melanoma;Sweat Gland Carcinoma/Apocrine Eccrine Carcinoma;Skin;SOLID;27 +130;GINETES;LightSkyBlue;2;Esophagogastric Cancer;Gastrointestinal Neuroendocrine Tumors of the Esophagus/Stomach;Esophagus/Stomach;SOLID;26 +131;DES;LightYellow;2;Soft Tissue Sarcoma;Desmoid/Aggressive Fibromatosis;Soft Tissue;SOLID;34 +132;PAASC;Purple;2;Pancreatic Cancer;Adenosquamous Carcinoma of the Pancreas;Pancreas;SOLID;25 +133;BRCA;HotPink;2;Breast Cancer;Invasive Breast Carcinoma;Breast;SOLID;39 +134;EHAE;LightYellow;2;Soft Tissue Sarcoma;Epithelioid Hemangioendothelioma;Soft Tissue;SOLID;34 +135;EMBT;Gray;2;Embryonal Tumor;Embryonal Tumor;CNS/Brain;SOLID;32 +136;URMM;Yellow;2;Melanoma;Mucosal Melanoma of the Urethra;Bladder/Urinary Tract;SOLID;12 +137;EGC;LightSkyBlue;2;Esophagogastric Cancer;Esophagogastric Adenocarcinoma;Esophagus/Stomach;SOLID;26 +138;MYXO;LightYellow;2;Soft Tissue Sarcoma;Myxoma;Soft Tissue;SOLID;34 +139;DF;Black;2;Skin Cancer, Non-Melanoma;Dermatofibroma;Skin;SOLID;27 +140;NBL;Gray;2;Peripheral Nervous System;Neuroblastoma;Peripheral Nervous System;SOLID;14 +141;INTS;LightYellow;2;Soft Tissue Sarcoma;Intimal Sarcoma;Soft Tissue;SOLID;34 +142;HCC;MediumSeaGreen;2;Hepatobiliary Cancer;Hepatocellular Carcinoma;Liver;SOLID;29 +143;PLMESO;Blue;2;Mesothelioma;Pleural Mesothelioma;Pleura;SOLID;36 +144;LBGN;LimeGreen;2;Lymphatic Cancer, NOS;Lymphoid Benign;Lymphoid;LIQUID;15 +145;COADREAD;SaddleBrown;2;Colorectal Cancer;Colorectal Adenocarcinoma;Bowel;SOLID;17 +146;VGCT;Purple;2;Germ Cell Tumor;Germ Cell Tumor of the Vulva;Vulva/Vagina;SOLID;40 +147;PGNG;Gray;2;Miscellaneous Neuroepithelial Tumor;Paraganglioma;Soft Tissue;SOLID;34 +148;EMPD;Black;2;Skin Cancer, Non-Melanoma;Extramammary Paget Disease;Skin;SOLID;27 +149;PANET;Purple;2;Pancreatic Cancer;Pancreatic Neuroendocrine Tumor;Pancreas;SOLID;25 +150;GINET;SaddleBrown;2;Gastrointestinal Neuroendocrine Tumor;Gastrointestinal Neuroendocrine Tumors;Bowel;SOLID;17 +151;SFT;LightYellow;2;Soft Tissue Sarcoma;Solitary Fibrous Tumor/Hemangiopericytoma;Soft Tissue;SOLID;34 +152;TLYM;Red;2;Non-Hodgkin Lymphoma;Testicular Lymphoma;Testis;SOLID;30 +153;TMESO;Red;2;Mesothelioma;Testicular Mesothelioma;Testis;SOLID;30 +154;DFSP;Black;2;Skin Cancer, Non-Melanoma;Dermatofibrosarcoma Protuberans;Skin;SOLID;27 +155;THAP;Teal;2;Thyroid Cancer;Anaplastic Thyroid Cancer;Thyroid;SOLID;33 +156;TGCT;LightYellow;2;Soft Tissue Sarcoma;Tenosynovial Giant Cell Tumor Diffuse Type;Soft Tissue;SOLID;34 +157;BNNOS;HotPink;2;Breast Cancer;Breast Neoplasm, NOS;Breast;SOLID;39 +158;IBC;HotPink;2;Breast Cancer;Inflammatory Breast Cancer;Breast;SOLID;39 +159;GTD;PeachPuff;2;Gestational Trophoblastic Disease;Gestational Trophoblastic Disease;Uterus;SOLID;31 +160;PCT;Black;2;Skin Cancer, Non-Melanoma;Porphyria Cutania Tarda;Skin;SOLID;27 +161;MNET;Gray;2;Miscellaneous Neuroepithelial Tumor;Miscellaneous Neuroepithelial Tumor;CNS/Brain;SOLID;32 +162;PRAD;Cyan;2;Prostate Cancer;Prostate Adenocarcinoma;Prostate;SOLID;19 +163;MRTL;MediumSeaGreen;2;Malignant Rhabdoid Tumor of the Liver;Malignant Rhabdoid Tumor of the Liver;Liver;SOLID;29 +164;AIS;Black;2;Adenocarcinoma In Situ;Adenocarcinoma In Situ;Other;SOLID;37 +165;IMS;LightYellow;2;Myofibromatosis;Myofibromatosis;Soft Tissue;SOLID;34 +166;SMN;LightSkyBlue;2;Esophagogastric Cancer;Smooth Muscle Neoplasm, NOS;Esophagus/Stomach;SOLID;26 +167;PRSCC;Cyan;2;Prostate Cancer;Prostate Small Cell Carcinoma;Prostate;SOLID;19 +168;SCCE;Teal;2;Cervical Cancer;Small Cell Carcinoma of the Cervix;Cervix;SOLID;10 +169;VMM;Purple;2;Melanoma;Mucosal Melanoma of the Vulva/Vagina;Vulva/Vagina;SOLID;40 +170;MGST;LightYellow;2;Malignant Glomus Tumor;Malignant Glomus Tumor;Soft Tissue;SOLID;34 +171;CHDM;White;2;Bone Cancer;Chordoma;Bone;SOLID;21 +172;MEL;Black;2;Melanoma;Melanoma;Skin;SOLID;27 +173;PACT;Purple;2;Pancreatic Cancer;Cystic Tumor of the Pancreas;Pancreas;SOLID;25 +174;FLC;MediumSeaGreen;2;Hepatobiliary Cancer;Fibrolamellar Carcinoma;Liver;SOLID;29 +175;CMC;SaddleBrown;2;Colorectal Cancer;Medullary Carcinoma of the Colon;Bowel;SOLID;17 +176;ALT;LightYellow;2;Soft Tissue Sarcoma;Atypical Lipomatous Tumor;Soft Tissue;SOLID;34 +177;VPDC;Purple;2;Vaginal Cancer;Poorly Differentiated Vaginal Carcinoma;Vulva/Vagina;SOLID;40 +178;AFX;Black;2;Skin Cancer, Non-Melanoma;Atypical Fibroxanthoma;Skin;SOLID;27 +179;PSCC;Blue;2;Penile Cancer;Penile Squamous Cell Carcinoma;Penis;SOLID;38 +180;CEAIS;Teal;2;Cervical Cancer;Cervical Adenocarcinoma In Situ;Cervix;SOLID;10 +181;ARMM;SaddleBrown;2;Melanoma;Anorectal Mucosal Melanoma;Bowel;SOLID;17 +182;THME;Teal;2;Thyroid Cancer;Medullary Thyroid Cancer;Thyroid;SOLID;33 +183;BLCA;Yellow;2;Bladder Cancer;Bladder Urothelial Carcinoma;Bladder/Urinary Tract;SOLID;12 +184;CELI;Teal;2;Cervical Cancer;Cervical Leiomyosarcoma;Cervix;SOLID;10 +185;IMTL;Gainsboro;2;Non-Small Cell Lung Cancer;Inflammatory Myofibroblastic Lung Tumor;Lung;SOLID;24 +186;PBS;HotPink;2;Breast Sarcoma;Breast Sarcoma;Breast;SOLID;39 +187;MPC;LightYellow;2;Soft Tissue Sarcoma;Myopericytoma;Soft Tissue;SOLID;34 +188;SACA;DarkRed;2;Salivary Gland Cancer;Salivary Carcinoma;Head and Neck;SOLID;18 +189;HNMUCM;DarkRed;2;Melanoma;Head and Neck Mucosal Melanoma;Head and Neck;SOLID;18 +190;LNET;Gainsboro;2;Non-Small Cell Lung Cancer;Lung Neuroendocrine Tumor;Lung;SOLID;24 +191;PMHE;LightYellow;2;Soft Tissue Sarcoma;Pseudomyogenic Hemangioendothelioma;Soft Tissue;SOLID;34 +192;BLSC;Yellow;2;Bladder Cancer;Bladder Squamous Cell Carcinoma;Bladder/Urinary Tract;SOLID;12 +193;CHBL;White;2;Bone Cancer;Chondroblastoma;Bone;SOLID;21 +194;ES;White;2;Bone Cancer;Ewing Sarcoma;Bone;SOLID;21 +195;UCP;Purple;2;Pancreatic Cancer;Undifferentiated Carcinoma of the Pancreas;Pancreas;SOLID;25 +196;GBC;Green;2;Hepatobiliary Cancer;Gallbladder Cancer;Biliary Tract;SOLID;22 +197;TSCST;Red;2;Sex Cord Stromal Tumor;Sex Cord Stromal Tumor;Testis;SOLID;30 +198;APAD;SaddleBrown;2;Appendiceal Cancer;Appendiceal Adenocarcinoma;Bowel;SOLID;17 +199;MCCE;Teal;2;Cervical Cancer;Mixed Cervical Carcinoma;Cervix;SOLID;10 +200;RCSNOS;LightYellow;2;Soft Tissue Sarcoma;Round Cell Sarcoma, NOS;Soft Tissue;SOLID;34 +201;MBT;Gray;2;Miscellaneous Brain Tumor;Miscellaneous Brain Tumor;CNS/Brain;SOLID;32 +202;UTUC;Yellow;2;Bladder Cancer;Upper Tract Urothelial Carcinoma;Bladder/Urinary Tract;SOLID;12 +203;SCB;Yellow;2;Bladder Cancer;Sarcomatoid Carcinoma of the Urinary Bladder;Bladder/Urinary Tract;SOLID;12 +204;EPIS;LightYellow;2;Soft Tissue Sarcoma;Epithelioid Sarcoma;Soft Tissue;SOLID;34 +205;ACA;Purple;2;Adrenocortical Adenoma;Adrenocortical Adenoma;Adrenal Gland;SOLID;9 +206;LGFMS;LightYellow;2;Soft Tissue Sarcoma;Low-Grade Fibromyxoid Sarcoma;Soft Tissue;SOLID;34 +207;PB;Purple;2;Pancreatic Cancer;Pancreatoblastoma;Pancreas;SOLID;25 +208;SEM;Red;2;Germ Cell Tumor;Seminoma;Testis;SOLID;30 +209;DIFG;Gray;2;Glioma;Diffuse Glioma;CNS/Brain;SOLID;32 +210;DTE;Black;2;Skin Cancer, Non-Melanoma;Desmoplastic Trichoepithelioma;Skin;SOLID;27 +211;POCA;Black;2;Skin Cancer, Non-Melanoma;Porocarcinoma/Spiroadenocarcinoma;Skin;SOLID;27 +212;UESL;MediumSeaGreen;2;Undifferentiated Embryonal Sarcoma of the Liver;Undifferentiated Embryonal Sarcoma of the Liver;Liver;SOLID;29 +213;LCIS;HotPink;2;Breast Cancer;Breast Lobular Carcinoma In Situ;Breast;SOLID;39 +214;ANSC;SaddleBrown;2;Anal Cancer;Anal Squamous Cell Carcinoma;Bowel;SOLID;17 +215;OS;White;2;Bone Cancer;Osteosarcoma;Bone;SOLID;21 +216;SARCL;Gainsboro;2;Non-Small Cell Lung Cancer;Sarcomatoid Carcinoma of the Lung;Lung;SOLID;24 +217;GCTB;White;2;Bone Cancer;Giant Cell Tumor of Bone;Bone;SOLID;21 +218;GS;LightYellow;2;Soft Tissue Sarcoma;Glomangiosarcoma;Soft Tissue;SOLID;34 +219;GIST;LightYellow;2;Gastrointestinal Stromal Tumor;Gastrointestinal Stromal Tumor;Soft Tissue;SOLID;34 +220;SPIR;Black;2;Skin Cancer, Non-Melanoma;Spiroma/Spiradenoma;Skin;SOLID;27 +221;UCA;Yellow;2;Bladder Cancer;Urethral Cancer;Bladder/Urinary Tract;SOLID;12 +222;PPB;Gainsboro;2;Non-Small Cell Lung Cancer;Pleuropulmonary Blastoma;Lung;SOLID;24 +223;BFN;HotPink;2;Breast Sarcoma;Breast Fibroepithelial Neoplasms;Breast;SOLID;39 +224;AA;LightYellow;2;Soft Tissue Sarcoma;Aggressive Angiomyxoma;Soft Tissue;SOLID;34 +225;PRNE;Cyan;2;Prostate Cancer;Prostate Neuroendocrine Carcinoma;Prostate;SOLID;19 +226;LM;LightYellow;2;Soft Tissue Cancer;Leiomyoma;Soft Tissue;SOLID;34 +227;SARCNOS;LightYellow;2;Soft Tissue Sarcoma;Sarcoma, NOS;Soft Tissue;SOLID;34 +228;BLAD;Yellow;2;Bladder Cancer;Bladder Adenocarcinoma;Bladder/Urinary Tract;SOLID;12 +229;STMYEC;LightYellow;2;Soft Tissue Sarcoma;Soft Tissue Myoepithelial Carcinoma;Soft Tissue;SOLID;34 +230;CEAS;Teal;2;Cervical Cancer;Cervical Adenosquamous Carcinoma;Cervix;SOLID;10 +231;UCEC;PeachPuff;2;Endometrial Cancer;Endometrial Carcinoma;Uterus;SOLID;31 +232;CSCLC;Gainsboro;2;Small Cell Lung Cancer;Combined Small Cell Lung Carcinoma;Lung;SOLID;24 +233;ACC;Purple;2;Adrenocortical Carcinoma;Adrenocortical Carcinoma;Adrenal Gland;SOLID;9 +234;CACC;Teal;2;Cervical Cancer;Cervical Adenoid Cystic Carcinoma;Cervix;SOLID;10 +235;CUP;Black;2;Cancer of Unknown Primary;Cancer of Unknown Primary;Other;SOLID;37 +236;ANGS;LightYellow;2;Soft Tissue Sarcoma;Angiosarcoma;Soft Tissue;SOLID;34 +237;LAMN;SaddleBrown;2;Appendiceal Cancer;Low-grade Appendiceal Mucinous Neoplasm;Bowel;SOLID;17 +238;AMPCA;Purple;2;Ampullary Cancer;Ampullary Carcinoma;Ampulla of Vater;SOLID;11 +239;RNET;Orange;2;Renal Neuroendocrine Tumor;Renal Neuroendocrine Tumor;Kidney;SOLID;23 +240;CHS;White;2;Bone Cancer;Chondrosarcoma;Bone;SOLID;21 +241;CPT;Gray;2;Choroid Plexus Tumor;Choroid Plexus Tumor;CNS/Brain;SOLID;32 +242;OAT;Teal;2;Thyroid Cancer;Oncocytic Adenoma of the Thyroid;Thyroid;SOLID;33 +243;LIHB;MediumSeaGreen;2;Hepatobiliary Cancer;Hepatoblastoma;Liver;SOLID;29 +244;MNGT;Gray;2;CNS Cancer;Meningothelial Tumor;CNS/Brain;SOLID;32 +245;CENE;Teal;2;Cervical Cancer;Cervical Neuroendocrine Tumor;Cervix;SOLID;10 +246;EPDCA;LightSkyBlue;2;Esophagogastric Cancer;Esophageal Poorly Differentiated Carcinoma;Esophagus/Stomach;SOLID;26 +247;ADMA;White;2;Bone Cancer;Adamantinoma;Bone;SOLID;21 +248;PECOMA;LightYellow;2;Soft Tissue Sarcoma;Perivascular Epithelioid Cell Tumor;Soft Tissue;SOLID;34 +249;GN;Gray;2;Peripheral Nervous System;Ganglioneuroma;Peripheral Nervous System;SOLID;14 +250;ESCC;LightSkyBlue;2;Esophagogastric Cancer;Esophageal Squamous Cell Carcinoma;Esophagus/Stomach;SOLID;26 +251;RAS;LightYellow;2;Soft Tissue Sarcoma;Radiation-Associated Sarcoma;Soft Tissue;SOLID;34 +252;MF;LightYellow;2;Soft Tissue Sarcoma;Myofibroma;Soft Tissue;SOLID;34 +253;LIAS;MediumSeaGreen;2;Hepatobiliary Cancer;Liver Angiosarcoma;Liver;SOLID;29 +254;OUTT;PeachPuff;2;Endometrial Cancer;Other Uterine Tumor;Uterus;SOLID;31 +255;HCCIHCH;MediumSeaGreen;2;Hepatobiliary Cancer;Hepatocellular Carcinoma plus Intrahepatic Cholangiocarcinoma;Liver;SOLID;29 +256;LIAD;MediumSeaGreen;2;Hepatobiliary Cancer;Hepatocellular Adenoma;Liver;SOLID;29 +257;IMT;LightYellow;2;Soft Tissue Sarcoma;Inflammatory Myofibroblastic Tumor;Soft Tissue;SOLID;34 +258;SBC;SaddleBrown;2;Small Bowel Cancer;Small Bowel Cancer;Bowel;SOLID;17 +259;JSCB;HotPink;2;Breast Cancer;Juvenile Secretory Carcinoma of the Breast;Breast;SOLID;39 +260;MATPL;LightSalmon;2;Blood Cancer, NOS;Myeloid Atypical;Myeloid;LIQUID;20 +261;CCSK;Orange;2;Clear Cell Sarcoma of Kidney;Clear Cell Sarcoma of Kidney;Kidney;SOLID;23 +262;CEGCC;Teal;2;Cervical Cancer;Glassy Cell Carcinoma of the Cervix;Cervix;SOLID;10 +263;EPMT;Gray;2;CNS Cancer;Ependymomal Tumor;CNS/Brain;SOLID;32 +264;SKAC;Black;2;Skin Cancer, Non-Melanoma;Skin Adnexal Carcinoma;Skin;SOLID;27 +265;DCS;LightYellow;2;Soft Tissue Sarcoma;Dendritic Cell Sarcoma;Soft Tissue;SOLID;34 +266;BCC;Black;2;Skin Cancer, Non-Melanoma;Basal Cell Carcinoma;Skin;SOLID;27 +267;RCC;Orange;2;Renal Cell Carcinoma;Renal Cell Carcinoma;Kidney;SOLID;23 +268;VSC;Purple;2;Vaginal Cancer;Squamous Cell Carcinoma of the Vulva/Vagina;Vulva/Vagina;SOLID;40 +269;OOVC;LightBlue;2;Ovarian Cancer;Ovarian Cancer, Other;Ovary/Fallopian Tube;SOLID;28 +270;PSEC;Green;2;Peritoneal Cancer, NOS;Peritoneal Serous Carcinoma;Peritoneum;SOLID;13 +271;MMB;Gray;3;Embryonal Tumor;Medullomyoblastoma;CNS/Brain;SOLID;135 +272;PAOS;White;3;Bone Cancer;Parosteal Osteosarcoma;Bone;SOLID;215 +273;ARMS;LightYellow;3;Soft Tissue Sarcoma;Alveolar Rhabdomyosarcoma;Soft Tissue;SOLID;96 +274;AWDNET;SaddleBrown;3;Gastrointestinal Neuroendocrine Tumor;Well-Differentiated Neuroendocrine Tumor of the Appendix;Bowel;SOLID;150 +275;PCGP;Gray;3;Sellar Tumor;Craniopharyngioma, Papillary Type;CNS/Brain;SOLID;50 +276;SCCO;LightBlue;3;Ovarian Cancer;Small Cell Carcinoma of the Ovary;Ovary/Fallopian Tube;SOLID;83 +277;UASC;PeachPuff;3;Endometrial Cancer;Uterine Adenosquamous Carcinoma;Uterus;SOLID;231 +278;PXA;Gray;3;Glioma;Pleomorphic Xanthoastrocytoma;CNS/Brain;SOLID;56 +279;SRAP;SaddleBrown;3;Appendiceal Cancer;Signet Ring Cell Type of the Appendix;Bowel;SOLID;198 +280;MIXED;Black;3;Cancer of Unknown Primary;Mixed Cancer Types;Other;SOLID;235 +281;LXSC;DarkRed;3;Head and Neck Cancer;Larynx Squamous Cell Carcinoma;Head and Neck;SOLID;53 +282;RHM;Gray;3;CNS Cancer;Rhabdoid Meningioma;CNS/Brain;SOLID;244 +283;WDLS;LightYellow;3;Soft Tissue Sarcoma;Well-Differentiated Liposarcoma;Soft Tissue;SOLID;125 +284;DESM;Black;3;Melanoma;Desmoplastic Melanoma;Skin;SOLID;172 +285;OEC;LightBlue;3;Germ Cell Tumor;Embryonal Carcinoma;Ovary/Fallopian Tube;SOLID;65 +286;SCLC;Gainsboro;3;Small Cell Lung Cancer;Small Cell Lung Cancer;Lung;SOLID;190 +287;ACBC;HotPink;3;Breast Cancer;Adenoid Cystic Breast Cancer;Breast;SOLID;133 +288;OPHSC;DarkRed;3;Head and Neck Cancer;Oropharynx Squamous Cell Carcinoma;Head and Neck;SOLID;53 +289;PTLD;LimeGreen;3;Posttransplant Lymphoproliferative Disorders;Posttransplant Lymphoproliferative Disorders;Lymphoid;LIQUID;51 +290;SUBE;Gray;3;CNS Cancer;Subependymoma;CNS/Brain;SOLID;263 +291;SCGBC;Green;3;Hepatobiliary Cancer;Small Cell Gallbladder Carcinoma;Biliary Tract;SOLID;196 +292;FIOS;White;3;Bone Cancer;Fibroblastic Osteosarcoma;Bone;SOLID;215 +293;LUNE;Gainsboro;3;Non-Small Cell Lung Cancer;Large Cell Neuroendocrine Carcinoma;Lung;SOLID;190 +294;UPDC;PeachPuff;3;Endometrial Cancer;Poorly Differentiated Carcinoma of the Uterus;Uterus;SOLID;231 +295;OGBL;LightBlue;3;Sex Cord Stromal Tumor;Gonadoblastoma;Ovary/Fallopian Tube;SOLID;42 +296;PSC;Purple;3;Pancreatic Cancer;Serous Cystadenoma of the Pancreas;Pancreas;SOLID;173 +297;BCCA;Gray;3;Germ Cell Tumor;Choriocarcinoma;CNS/Brain;SOLID;102 +298;BMGCT;Gray;3;Germ Cell Tumor;Mixed Germ Cell Tumor;CNS/Brain;SOLID;102 +299;SCHW;Gray;3;Nerve Sheath Tumor;Schwannoma;Peripheral Nervous System;SOLID;104 +300;CEVG;Teal;3;Cervical Cancer;Villoglandular Carcinoma;Cervix;SOLID;81 +301;VDYS;Purple;3;Germ Cell Tumor;Dysgerminoma;Vulva/Vagina;SOLID;146 +302;PHCH;Green;3;Hepatobiliary Cancer;Perihilar Cholangiocarcinoma;Biliary Tract;SOLID;115 +303;GMN;Gray;3;Germ Cell Tumor;Germinoma;CNS/Brain;SOLID;102 +304;GCTSTM;Red;3;Germ Cell Tumor;Germ Cell Tumor with Somatic-Type Malignancy;Testis;SOLID;84 +305;BCAC;DarkRed;3;Salivary Gland Cancer;Basal Cell Adenocarcinoma;Head and Neck;SOLID;188 +306;BPSCC;Blue;3;Penile Cancer;Basaloid Penile Squamous Cell Carcinoma;Penis;SOLID;179 +307;BLL;LimeGreen;3;B-Lymphoblastic Leukemia/Lymphoma;B-Lymphoblastic Leukemia/Lymphoma;Lymphoid;LIQUID;51 +308;OSMBT;LightBlue;3;Ovarian Cancer;Ovarian Seromucinous Borderline Tumor;Ovary/Fallopian Tube;SOLID;83 +309;NETNOS;Black;3;Cancer of Unknown Primary;Neuroendocrine Tumor, NOS;Other;SOLID;235 +310;TCCA;Red;3;Germ Cell Tumor;Choriocarcinoma;Testis;SOLID;84 +311;MMBL;Gray;3;Embryonal Tumor;Melanotic Medulloblastoma;CNS/Brain;SOLID;135 +312;SWDNET;LightSkyBlue;3;Gastrointestinal Neuroendocrine Tumor;Well-Differentiated Neuroendocrine Tumors of the Stomach;Esophagus/Stomach;SOLID;130 +313;MUCC;DarkRed;3;Salivary Gland Cancer;Mucoepidermoid Carcinoma;Head and Neck;SOLID;188 +314;OCS;LightBlue;3;Ovarian Cancer;Ovarian Carcinosarcoma/Malignant Mixed Mesodermal Tumor;Ovary/Fallopian Tube;SOLID;83 +315;CMPT;Gainsboro;3;Non-Small Cell Lung Cancer;Ciliated Muconodular Papillary Tumor of the Lung;Lung;SOLID;64 +316;ALUCA;Gainsboro;3;Non-Small Cell Lung Cancer;Atypical Lung Carcinoid;Lung;SOLID;190 +317;SPC;HotPink;3;Breast Cancer;Solid Papillary Carcinoma of the Breast;Breast;SOLID;133 +318;EBOV;LightBlue;3;Ovarian Cancer;Endometrioid Borderlin Ovarian Tumor;Ovary/Fallopian Tube;SOLID;83 +319;SGO;DarkRed;3;Salivary Gland Cancer;Salivary Gland Oncocytoma;Head and Neck;SOLID;188 +320;EVN;Gray;3;Miscellaneous Neuroepithelial Tumor;Extraventricular Neurocytoma;CNS/Brain;SOLID;161 +321;USC;PeachPuff;3;Endometrial Cancer;Uterine Serous Carcinoma/Uterine Papillary Serous Carcinoma;Uterus;SOLID;231 +322;NECNOS;Black;3;Cancer of Unknown Primary;Neuroendocrine Carcinoma, NOS;Other;SOLID;235 +323;BYST;Gray;3;Germ Cell Tumor;Yolk Sac Tumor;CNS/Brain;SOLID;102 +324;OSGCT;Purple;3;Pancreatic Cancer;Osteoclastic Giant Cell Tumor;Pancreas;SOLID;195 +325;SBOV;LightBlue;3;Ovarian Cancer;Serous Borderline Ovarian Tumor;Ovary/Fallopian Tube;SOLID;83 +326;EMBCA;Red;3;Germ Cell Tumor;Embryonal Carcinoma;Testis;SOLID;84 +327;HNNE;DarkRed;3;Head and Neck Cancer;Head and Neck Neuroendocrine Carcinoma;Head and Neck;SOLID;41 +328;MCHS;White;3;Bone Cancer;Mesenchymal Chondrosarcoma;Bone;SOLID;240 +329;PLSMESO;Blue;3;Mesothelioma;Pleural Mesothelioma, Sarcomatoid Type;Pleura;SOLID;143 +330;OMGCT;LightBlue;3;Germ Cell Tumor;Mixed Germ Cell Tumor;Ovary/Fallopian Tube;SOLID;65 +331;OPE;LightBlue;3;Germ Cell Tumor;Polyembryoma;Ovary/Fallopian Tube;SOLID;65 +332;UA;Yellow;3;Bladder Cancer;Urachal Adenocarcinoma;Bladder/Urinary Tract;SOLID;128 +333;PLLS;LightYellow;3;Soft Tissue Sarcoma;Pleomorphic Liposarcoma;Soft Tissue;SOLID;125 +334;DDLS;LightYellow;3;Soft Tissue Sarcoma;Dedifferentiated Liposarcoma;Soft Tissue;SOLID;125 +335;MDLC;HotPink;3;Breast Cancer;Breast Mixed Ductal and Lobular Carcinoma;Breast;SOLID;133 +336;OYST;LightBlue;3;Germ Cell Tumor;Yolk Sac Tumor;Ovary/Fallopian Tube;SOLID;65 +337;UMNC;PeachPuff;3;Endometrial Cancer;Uterine Mesonephric Carcinoma;Uterus;SOLID;231 +338;SDCA;DarkRed;3;Salivary Gland Cancer;Salivary Duct Carcinoma;Head and Neck;SOLID;188 +339;BRSRCC;HotPink;3;Breast Cancer;Breast Carcinoma with Signet Ring;Breast;SOLID;133 +340;TYST;Red;3;Germ Cell Tumor;Yolk Sac Tumor;Testis;SOLID;84 +341;MGCT;Red;3;Germ Cell Tumor;Mixed Germ Cell Tumor;Testis;SOLID;84 +342;CECC;Teal;3;Cervical Cancer;Cervical Clear Cell Carcinoma;Cervix;SOLID;81 +343;MPN;LightSalmon;3;Myeloproliferative Neoplasms;Myeloproliferative Neoplasms;Myeloid;LIQUID;86 +344;DIG;Gray;3;Miscellaneous Neuroepithelial Tumor;Desmoplastic Infantile Ganglioglioma;CNS/Brain;SOLID;161 +345;DMBL;Gray;3;Embryonal Tumor;Desmoplastic/Nodular Medulloblastoma;CNS/Brain;SOLID;135 +346;MELC;Gray;3;Melanocytoma;Melanocytoma;CNS/Brain;SOLID;68 +347;APXA;Gray;3;Glioma;Anaplastic Pleomorphic Xanthoastrocytoma;CNS/Brain;SOLID;56 +348;PINC;Gray;3;Pineal Tumor;Pineocytoma;CNS/Brain;SOLID;110 +349;MT;Gray;3;Miscellaneous Brain Tumor;Malignant Tumor;CNS/Brain;SOLID;201 +350;BMGT;Gray;3;Germ Cell Tumor;Malignant Teratoma;CNS/Brain;SOLID;102 +351;CCM;Gray;3;CNS Cancer;Clear cell Meningioma;CNS/Brain;SOLID;244 +352;CUPNOS;Black;3;Cancer of Unknown Primary;Cancer of Unknown Primary, NOS;Other;SOLID;235 +353;OCNOS;LightBlue;3;Ovarian Cancer;Ovarian Choriocarcinoma, NOS;Ovary/Fallopian Tube;SOLID;269 +354;THPA;Teal;3;Thyroid Cancer;Papillary Thyroid Cancer;Thyroid;SOLID;74 +355;ANM;Gray;3;CNS Cancer;Anaplastic Meningioma;CNS/Brain;SOLID;244 +356;UEC;PeachPuff;3;Endometrial Cancer;Uterine Endometrioid Carcinoma;Uterus;SOLID;231 +357;SFTCNS;Gray;3;CNS Cancer;Solitary Fibrous Tumor of the Central Nervous System;CNS/Brain;SOLID;244 +358;ASTR;Gray;3;Glioma;Astrocytoma;CNS/Brain;SOLID;209 +359;MOV;LightBlue;3;Ovarian Cancer;Mucinous Ovarian Cancer;Ovary/Fallopian Tube;SOLID;83 +360;GNC;Gray;3;Glioma;Gangliocytoma;CNS/Brain;SOLID;56 +361;APE;Gray;3;CNS Cancer;Anaplastic Ependymoma;CNS/Brain;SOLID;263 +362;CCHDM;White;3;Bone Cancer;Conventional Type Chordoma;Bone;SOLID;171 +363;CTAAP;SaddleBrown;3;Appendiceal Cancer;Colonic Type Adenocarcinoma of the Appendix;Bowel;SOLID;198 +364;SPCC;Gainsboro;3;Non-Small Cell Lung Cancer;Spindle Cell Carcinoma of the Lung;Lung;SOLID;64 +365;ANGL;Gray;3;Miscellaneous Neuroepithelial Tumor;Angiocentric Glioma;CNS/Brain;SOLID;161 +366;CCRCC;Orange;3;Renal Cell Carcinoma;Renal Clear Cell Carcinoma;Kidney;SOLID;267 +367;UUC;PeachPuff;3;Endometrial Cancer;Uterine Undifferentiated Carcinoma;Uterus;SOLID;231 +368;BMT;Gray;3;Germ Cell Tumor;Mature Teratoma;CNS/Brain;SOLID;102 +369;UCCA;PeachPuff;3;Gestational Trophoblastic Disease;Choriocarcinoma;Uterus;SOLID;159 +370;SCUP;Black;3;Cancer of Unknown Primary;Small Cell Carcinoma of Unknown Primary;Other;SOLID;235 +371;IAMPCA;Purple;3;Ampullary Cancer;Intestinal Ampullary Carcinoma;Ampulla of Vater;SOLID;238 +372;USTAD;LightSkyBlue;3;Esophagogastric Cancer;Undifferentiated Stomach Adenocarcinoma;Esophagus/Stomach;SOLID;137 +373;CESE;Teal;3;Cervical Cancer;Cervical Serous Carcinoma;Cervix;SOLID;81 +374;LGGNOS;Gray;3;Glioma;Low-Grade Glioma, NOS;CNS/Brain;SOLID;56 +375;MLYM;Gray;3;Miscellaneous Brain Tumor;Malignant Lymphoma;CNS/Brain;SOLID;201 +376;SRCCR;SaddleBrown;3;Colorectal Cancer;Signet Ring Cell Adenocarcinoma of the Colon and Rectum;Bowel;SOLID;145 +377;OIMT;LightBlue;3;Germ Cell Tumor;Immature Teratoma;Ovary/Fallopian Tube;SOLID;65 +378;ERMS;LightYellow;3;Soft Tissue Sarcoma;Embryonal Rhabdomyosarcoma;Soft Tissue;SOLID;96 +379;UM;Green;3;Melanoma;Uveal Melanoma;Eye;SOLID;67 +380;MDS/MPN;LightSalmon;3;Myelodysplastic/Myeloproliferative Neoplasms;Myelodysplastic/Myeloproliferative Neoplasms;Myeloid;LIQUID;86 +381;SGTTL;Gainsboro;3;Non-Small Cell Lung Cancer;Salivary Gland-Type Tumor of the Lung;Lung;SOLID;64 +382;TLL;LimeGreen;3;T-Lymphoblastic Leukemia/Lymphoma;T-Lymphoblastic Leukemia/Lymphoma;Lymphoid;LIQUID;51 +383;HGNEC;SaddleBrown;3;Gastrointestinal Neuroendocrine Tumor;High-Grade Neuroendocrine Carcinoma of the Colon and Rectum;Bowel;SOLID;150 +384;AODG;Gray;3;Glioma;Anaplastic Oligodendroglioma;CNS/Brain;SOLID;209 +385;LDD;Gray;3;Miscellaneous Neuroepithelial Tumor;Dysplastic Gangliocytoma of the Cerebellum/Lhermitte-Duclos Disease;CNS/Brain;SOLID;161 +386;HGSFT;LightBlue;3;Ovarian Cancer;High-Grade Serous Fallopian Tube Cancer;Ovary/Fallopian Tube;SOLID;269 +387;NMCHN;DarkRed;3;Head and Neck Cancer;NUT Midline Carcinoma of the Head and Neck;Head and Neck;SOLID;41 +388;UDMN;Black;3;Cancer of Unknown Primary;Undifferentiated Malignant Neoplasm;Other;SOLID;235 +389;ACRM;Black;3;Melanoma;Acral Melanoma;Skin;SOLID;172 +390;PTAD;Gray;3;Sellar Tumor;Pituitary Adenoma;CNS/Brain;SOLID;50 +391;MNG;Gray;3;CNS Cancer;Meningioma;CNS/Brain;SOLID;244 +392;TT;Red;3;Germ Cell Tumor;Teratoma;Testis;SOLID;84 +393;ESCA;LightSkyBlue;3;Esophagogastric Cancer;Esophageal Adenocarcinoma;Esophagus/Stomach;SOLID;137 +394;MCD;LightSalmon;3;Mastocytosis;Mastocytosis;Myeloid;LIQUID;86 +395;OMT;LightBlue;3;Germ Cell Tumor;Mature Teratoma;Ovary/Fallopian Tube;SOLID;65 +396;NUTCL;Gainsboro;3;Non-Small Cell Lung Cancer;NUT Carcinoma of the Lung;Lung;SOLID;64 +397;SEF;LightYellow;3;Soft Tissue Sarcoma;Sclerosing Epithelioid Fibrosarcoma;Soft Tissue;SOLID;62 +398;OAST;Gray;3;Glioma;Oligoastrocytoma;CNS/Brain;SOLID;209 +399;SNSC;DarkRed;3;Head and Neck Cancer;Sinonasal Squamous Cell Carcinoma;Head and Neck;SOLID;53 +400;IHCH;Green;3;Hepatobiliary Cancer;Intrahepatic Cholangiocarcinoma;Biliary Tract;SOLID;115 +401;ODGC;DarkRed;3;Head and Neck Cancer;Odontogenic Carcinoma;Head and Neck;SOLID;41 +402;LCLC;Gainsboro;3;Non-Small Cell Lung Cancer;Large Cell Lung Carcinoma;Lung;SOLID;64 +403;STAS;LightSkyBlue;3;Esophagogastric Cancer;Adenosquamous Carcinoma of the Stomach;Esophagus/Stomach;SOLID;137 +404;COAD;SaddleBrown;3;Colorectal Cancer;Colon Adenocarcinoma;Bowel;SOLID;145 +405;SCT;LightBlue;3;Sex Cord Stromal Tumor;Steroid Cell Tumor, NOS;Ovary/Fallopian Tube;SOLID;42 +406;READ;SaddleBrown;3;Colorectal Cancer;Rectal Adenocarcinoma;Bowel;SOLID;145 +407;CNC;Gray;3;Miscellaneous Neuroepithelial Tumor;Central Neurocytoma;CNS/Brain;SOLID;161 +408;UCS;PeachPuff;3;Endometrial Cancer;Uterine Carcinosarcoma/Uterine Malignant Mixed Mullerian Tumor;Uterus;SOLID;231 +409;HDCN;LightSalmon;3;Histiocytosis;Histiocytic and Dendritic Cell Neoplasms;Myeloid;LIQUID;86 +410;MP;PeachPuff;3;Gestational Trophoblastic Disease;Molar Pregnancy;Uterus;SOLID;159 +411;MDS;LightSalmon;3;Myelodysplastic Syndromes;Myelodysplastic Syndromes;Myeloid;LIQUID;86 +412;VPE;Purple;3;Germ Cell Tumor;Polyembryoma;Vulva/Vagina;SOLID;146 +413;SNUC;DarkRed;3;Head and Neck Cancer;Sinonasal Undifferentiated Carcinoma;Head and Neck;SOLID;41 +414;DDCHDM;White;3;Bone Cancer;Dedifferentiated Chordoma;Bone;SOLID;171 +415;LUAD;Gainsboro;3;Non-Small Cell Lung Cancer;Lung Adenocarcinoma;Lung;SOLID;64 +416;SLCT;LightBlue;3;Sex Cord Stromal Tumor;Sertoli-Leydig Cell Tumor;Ovary/Fallopian Tube;SOLID;42 +417;UAD;Yellow;3;Bladder Cancer;Urethral Adenocarcinoma;Bladder/Urinary Tract;SOLID;221 +418;ACN;Black;3;Cancer of Unknown Primary;Acinar Cell Carcinoma, NOS;Other;SOLID;235 +419;NCCRCC;Orange;3;Renal Cell Carcinoma;Renal Non-Clear Cell Carcinoma;Kidney;SOLID;267 +420;MPE;Gray;3;CNS Cancer;Myxopapillary Ependymoma;CNS/Brain;SOLID;263 +421;CLNC;Gray;3;Miscellaneous Neuroepithelial Tumor;Cerebellar Liponeurocytoma;CNS/Brain;SOLID;161 +422;IPMN;Purple;3;Pancreatic Cancer;Intraductal Papillary Mucinous Neoplasm;Pancreas;SOLID;173 +423;CHOS;White;3;Bone Cancer;Chondroblastic Osteosarcoma;Bone;SOLID;215 +424;OSACA;DarkRed;3;Salivary Gland Cancer;Salivary Carcinoma, Other;Head and Neck;SOLID;188 +425;EPM;Gray;3;Glioma;Ependymoma;CNS/Brain;SOLID;263 +426;HMBL;Gray;3;Miscellaneous Brain Tumor;Hemangioblastoma;CNS/Brain;SOLID;201 +427;HGSOS;White;3;Bone Cancer;High-Grade Surface Osteosarcoma;Bone;SOLID;215 +428;PNET;Gray;3;Embryonal Tumor;Primitive Neuroectodermal Tumor;CNS/Brain;SOLID;135 +429;PAST;Gray;3;Glioma;Pilocytic Astrocytoma;CNS/Brain;SOLID;56 +430;SKLMM;Black;3;Melanoma;Lentigo Maligna Melanoma;Skin;SOLID;172 +431;PTCY;Gray;3;Sellar Tumor;Pituicytoma;CNS/Brain;SOLID;50 +432;ASCT;DarkRed;3;Head and Neck Cancer;Adenosquamous Carcinoma of the Tongue;Head and Neck;SOLID;41 +433;MACR;SaddleBrown;3;Colorectal Cancer;Mucinous Adenocarcinoma of the Colon and Rectum;Bowel;SOLID;145 +434;OSOS;White;3;Bone Cancer;Osteoblastic Osteosarcoma;Bone;SOLID;215 +435;AASTR;Gray;3;Glioma;Anaplastic Astrocytoma;CNS/Brain;SOLID;209 +436;VIMT;Purple;3;Germ Cell Tumor;Immature Teratoma;Vulva/Vagina;SOLID;146 +437;MDEP;Gray;3;Embryonal Tumor;Medulloepithelioma;CNS/Brain;SOLID;135 +438;HNSCUP;DarkRed;3;Head and Neck Cancer;Head and Neck Squamous Cell Carcinoma of Unknown Primary;Head and Neck;SOLID;53 +439;SECOS;White;3;Bone Cancer;Secondary Osteosarcoma;Bone;SOLID;215 +440;PT;HotPink;3;Breast Sarcoma;Phyllodes Tumor of the Breast;Breast;SOLID;223 +441;ACPG;Gray;3;Sellar Tumor;Craniopharyngioma, Adamantinomatous Type;CNS/Brain;SOLID;50 +442;ACPP;Gray;3;Choroid Plexus Tumor;Atypical Choroid Plexus Papilloma;CNS/Brain;SOLID;241 +443;CM;Green;3;Melanoma;Conjunctival Melanoma;Eye;SOLID;67 +444;HGNEE;LightSkyBlue;3;Gastrointestinal Neuroendocrine Tumors of the Esophagus/Stomach;High-Grade Neuroendocrine Carcinoma of the Esophagus;Esophagus/Stomach;SOLID;130 +445;MAMPCA;Purple;3;Ampullary Cancer;Mixed Ampullary Carcinoma;Ampulla of Vater;SOLID;238 +446;LUPC;Gainsboro;3;Non-Small Cell Lung Cancer;Pleomorphic Carcinoma of the Lung;Lung;SOLID;64 +447;VMGCT;Purple;3;Germ Cell Tumor;Mixed Germ Cell Tumor;Vulva/Vagina;SOLID;146 +448;OFMT;LightYellow;3;Soft Tissue Sarcoma;Ossifying Fibromyxoid Tumor;Soft Tissue;SOLID;138 +449;BPDCN;LightSalmon;3;Blastic Plasmacytoid Dendritic Cell Neoplasm;Blastic Plasmacytoid Dendritic Cell Neoplasm;Myeloid;LIQUID;86 +450;EHCH;Green;3;Hepatobiliary Cancer;Extrahepatic Cholangiocarcinoma;Biliary Tract;SOLID;115 +451;LUSC;Gainsboro;3;Non-Small Cell Lung Cancer;Lung Squamous Cell Carcinoma;Lung;SOLID;64 +452;APTAD;Gray;3;Sellar Tumor;Atypical Pituitary Adenoma;CNS/Brain;SOLID;50 +453;ATM;Gray;3;CNS Cancer;Atypical Meningioma;CNS/Brain;SOLID;244 +454;CHOM;Gray;3;CNS Cancer;Chordoid Meningioma;CNS/Brain;SOLID;244 +455;MBOV;LightBlue;3;Ovarian Cancer;Mucinous Borderline Ovarian Tumor;Ovary/Fallopian Tube;SOLID;83 +456;PMA;Gray;3;Glioma;Pilomyxoid Astrocytoma;CNS/Brain;SOLID;56 +457;ODYS;LightBlue;3;Germ Cell Tumor;Dysgerminoma;Ovary/Fallopian Tube;SOLID;65 +458;PD;HotPink;3;Breast Cancer;Paget Disease of the Nipple;Breast;SOLID;126 +459;PCNSM;LightSkyBlue;3;Melanoma;Primary CNS Melanoma;CNS/Brain;SOLID;68 +460;IDC;HotPink;3;Breast Cancer;Breast Invasive Ductal Carcinoma;Breast;SOLID;133 +461;NSCLCPD;Gainsboro;3;Non-Small Cell Lung Cancer;Poorly Differentiated Non-Small Cell Lung Cancer;Lung;SOLID;64 +462;UNEC;PeachPuff;3;Endometrial Cancer;Uterine Neuroendocrine Carcinoma;Uterus;SOLID;231 +463;OSMAD;LightBlue;3;Ovarian Cancer;Ovarian Seromucinous Adenoma;Ovary/Fallopian Tube;SOLID;83 +464;CSNOS;HotPink;3;Breast Cancer;Breast Invasive Carcinosarcoma, NOS;Breast;SOLID;133 +465;USCC;Yellow;3;Bladder Cancer;Urethral Squamous Cell Carcinoma;Bladder/Urinary Tract;SOLID;221 +466;EMCHS;White;3;Bone Cancer;Extraskeletal Myxoid Chondrosarcoma;Bone;SOLID;240 +467;ONBL;Gray;3;Embryonal Tumor;Olfactory Neuroblastoma;CNS/Brain;SOLID;135 +468;HGONEC;LightBlue;3;Ovarian Cancer;High-Grade Neuroendocrine Carcinoma of the Ovary;Ovary/Fallopian Tube;SOLID;269 +469;SPZM;Black;3;Melanoma;Spitzoid Melanoma;Skin;SOLID;172 +470;UMC;PeachPuff;3;Endometrial Cancer;Uterine Mucinous Carcinoma;Uterus;SOLID;231 +471;VMT;Purple;3;Germ Cell Tumor;Mature Teratoma;Vulva/Vagina;SOLID;146 +472;ASTB;Gray;3;Miscellaneous Neuroepithelial Tumor;Astroblastoma;CNS/Brain;SOLID;161 +473;DDCHS;White;3;Bone Cancer;Dedifferentiated Chondrosarcoma;Bone;SOLID;240 +474;PADA;DarkRed;3;Salivary Gland Cancer;Pleomorphic Adenoma;Head and Neck;SOLID;188 +475;PLRMS;LightYellow;3;Soft Tissue Sarcoma;Pleomorphic Rhabdomyosarcoma;Soft Tissue;SOLID;96 +476;AML;LightSalmon;3;Leukemia;Acute Myeloid Leukemia;Myeloid;LIQUID;86 +477;RWDNET;SaddleBrown;3;Gastrointestinal Neuroendocrine Tumor;Well-Differentiated Neuroendocrine Tumor of the Rectum;Bowel;SOLID;150 +478;MAAP;SaddleBrown;3;Appendiceal Cancer;Mucinous Adenocarcinoma of the Appendix;Bowel;SOLID;198 +479;PRNET;Gray;3;Miscellaneous Brain Tumor;Primary Neuroepithelial Tumor;CNS/Brain;SOLID;201 +480;BA;HotPink;3;Breast Sarcoma;Breast Angiosarcoma;Breast;SOLID;186 +481;HGNET;Gray;3;Miscellaneous Brain Tumor;High-Grade Neuroepithelial Tumor;CNS/Brain;SOLID;201 +482;ECAD;Teal;3;Cervical Cancer;Endocervical Adenocarcinoma;Cervix;SOLID;81 +483;SOC;LightBlue;3;Ovarian Cancer;Serous Ovarian Cancer;Ovary/Fallopian Tube;SOLID;83 +484;MBL;Gray;3;Embryonal Tumor;Medulloblastoma;CNS/Brain;SOLID;135 +485;DIA;Gray;3;Miscellaneous Neuroepithelial Tumor;Desmoplastic Infantile Astrocytoma;CNS/Brain;SOLID;161 +486;PBL;Gray;3;Pineal Tumor;Pineoblastoma;CNS/Brain;SOLID;110 +487;PTCA;Gray;3;Sellar Tumor;Pituitary Carcinoma;CNS/Brain;SOLID;50 +488;SNA;DarkRed;3;Head and Neck Cancer;Sinonasal Adenocarcinoma;Head and Neck;SOLID;41 +489;UDDC;PeachPuff;3;Endometrial Cancer;Uterine Dedifferentiated Carcinoma;Uterus;SOLID;231 +490;HDCS;LightYellow;3;Soft Tissue Sarcoma;Histiocytic Dendritic Cell Sarcoma;Soft Tissue;SOLID;265 +491;AOAST;Gray;3;Glioma;Anaplastic Oligoastrocytoma;CNS/Brain;SOLID;209 +492;EMYOCA;DarkRed;3;Head and Neck Cancer;Epithelial-Myoepithelial Carcinoma;Head and Neck;SOLID;41 +493;LUAS;Gainsboro;3;Non-Small Cell Lung Cancer;Lung Adenosquamous Carcinoma;Lung;SOLID;64 +494;CEMN;Teal;3;Cervical Cancer;Mesonephric Carcinoma;Cervix;SOLID;81 +495;HNMASC;DarkRed;3;Salivary Gland Cancer;Mammary Analogue Secretory Carcinoma of Salivary Gland Origin;Head and Neck;SOLID;188 +496;BIMT;Gray;3;Germ Cell Tumor;Immature Teratoma;CNS/Brain;SOLID;102 +497;NHL;LimeGreen;3;Non-Hodgkin Lymphoma;Non-Hodgkin Lymphoma;Lymphoid;LIQUID;51 +498;MNGLP;LightSalmon;3;Myeloid Neoplasms with Germ Line Predisposition;Myeloid Neoplasms with Germ Line Predisposition;Myeloid;LIQUID;86 +499;LGCOS;White;3;Bone Cancer;Low-Grade Central Osteosarcoma;Bone;SOLID;215 +500;GBAD;Green;3;Hepatobiliary Cancer;Gallbladder Adenocarcinoma, NOS;Biliary Tract;SOLID;196 +501;STSC;LightSkyBlue;3;Esophagogastric Cancer;Small Cell Carcinoma of the Stomach;Esophagus/Stomach;SOLID;137 +502;UMEC;PeachPuff;3;Endometrial Cancer;Uterine Mixed Endometrial Carcinoma;Uterus;SOLID;231 +503;SCOAH;Gray;3;Sellar Tumor;Spindle Cell Oncocytoma of the Adenohypophysis;CNS/Brain;SOLID;50 +504;MCHSCNS;Gray;3;Miscellaneous Brain Tumor;Mesenchymal Chondrosarcoma of the CNS;CNS/Brain;SOLID;201 +505;BTOV;LightBlue;3;Ovarian Cancer;Brenner Tumor;Ovary/Fallopian Tube;SOLID;83 +506;ETANTR;Gray;3;Embryonal Tumor;Embryonal Tumor with Abundant Neuropil and True Rosettes;CNS/Brain;SOLID;135 +507;SAAD;DarkRed;3;Salivary Gland Cancer;Salivary Adenocarcinoma;Head and Neck;SOLID;188 +508;RGNT;Gray;3;Miscellaneous Neuroepithelial Tumor;Rosette-forming Glioneuronal Tumor of the Fourth Ventricle;CNS/Brain;SOLID;161 +509;WPSCC;Blue;3;Penile Cancer;Warty Penile Squamous Cell Carcinoma;Penis;SOLID;179 +510;PAC;DarkRed;3;Salivary Gland Cancer;Polymorphous Adenocarcinoma;Head and Neck;SOLID;188 +511;UAS;PeachPuff;3;Uterine Sarcoma;Uterine Adenosarcoma;Uterus;SOLID;70 +512;STAD;LightSkyBlue;3;Esophagogastric Cancer;Stomach Adenocarcinoma;Esophagus/Stomach;SOLID;137 +513;CAEXPA;DarkRed;3;Salivary Gland Cancer;Carcinoma ex Pleomorphic Adenoma;Head and Neck;SOLID;188 +514;SCLG;Green;3;Lacrimal Gland Tumor;Squamous Cell Carcinoma of the Lacrimal Gland;Eye;SOLID;47 +515;ODG;Gray;3;Glioma;Oligodendroglioma;CNS/Brain;SOLID;209 +516;ESS;PeachPuff;3;Uterine Sarcoma;Endometrial Stromal Sarcoma;Uterus;SOLID;70 +517;NFIB;Gray;3;Nerve Sheath Tumor;Neurofibroma;Peripheral Nervous System;SOLID;104 +518;MRLS;LightYellow;3;Soft Tissue Sarcoma;Myxoid/Round-Cell Liposarcoma;Soft Tissue;SOLID;125 +519;PSTT;PeachPuff;3;Gestational Trophoblastic Disease;Placental Site Trophoblastic Tumor;Uterus;SOLID;159 +520;BRCNOS;HotPink;3;Breast Cancer;Breast Invasive Carcinoma, NOS;Breast;SOLID;133 +521;OSMCA;LightBlue;3;Ovarian Cancer;Ovarian Seromucinous Carcinoma;Ovary/Fallopian Tube;SOLID;83 +522;SCOS;White;3;Bone Cancer;Small Cell Osteosarcoma;Bone;SOLID;215 +523;GBASC;Green;3;Hepatobiliary Cancer;Adenosquamous Carcinoma of the Gallbladder;Biliary Tract;SOLID;196 +524;ATRT;Gray;3;Embryonal Tumor;Atypical Teratoid/Rhabdoid Tumor;CNS/Brain;SOLID;135 +525;GB;Gray;3;Glioma;Glioblastoma;CNS/Brain;SOLID;209 +526;FT;LightBlue;3;Sex Cord Stromal Tumor;Fibrothecoma;Ovary/Fallopian Tube;SOLID;42 +527;GNG;Gray;3;Glioma;Ganglioglioma;CNS/Brain;SOLID;56 +528;FA;HotPink;3;Breast Sarcoma;Fibroadenoma;Breast;SOLID;223 +529;EOV;LightBlue;3;Ovarian Cancer;Endometrioid Ovarian Cancer;Ovary/Fallopian Tube;SOLID;83 +530;AGNG;Gray;3;Glioma;Anaplastic Ganglioglioma;CNS/Brain;SOLID;56 +531;PTHC;DarkRed;3;Parathyroid Cancer;Parathyroid Carcinoma;Head and Neck;SOLID;117 +532;PAMPCA;Purple;3;Ampullary Cancer;Pancreatobiliary Ampullary Carcinoma;Ampulla of Vater;SOLID;238 +533;MLNER;LightSalmon;3;Leukemia;Myeloid/Lymphoid Neoplasms with Eosinophilia and Rearrangement of PDGFRA/PDGFRB or FGFR1 or with PCM1-JAK2;Myeloid;LIQUID;86 +534;CPC;Gray;3;Choroid Plexus Tumor;Choroid Plexus Carcinoma;CNS/Brain;SOLID;241 +535;SKCM;Black;3;Melanoma;Cutaneous Melanoma;Skin;SOLID;172 +536;ADNOS;Black;3;Cancer of Unknown Primary;Adenocarcinoma, NOS;Other;SOLID;235 +537;SCCNOS;Black;3;Cancer of Unknown Primary;Squamous Cell Carcinoma, NOS;Other;SOLID;235 +538;SCSRMS;LightYellow;3;Soft Tissue Sarcoma;Spindle Cell/Sclerosing Rhabdomyosarcoma;Soft Tissue;SOLID;96 +539;VOEC;Purple;3;Germ Cell Tumor;Embryonal Carcinoma;Vulva/Vagina;SOLID;146 +540;PPTID;Gray;3;Pineal Tumor;Pineal Parenchymal Tumor of Intermediate Differentiation;CNS/Brain;SOLID;110 +541;CCOV;LightBlue;3;Ovarian Cancer;Clear Cell Ovarian Cancer;Ovary/Fallopian Tube;SOLID;83 +542;GNOS;Gray;3;Glioma;Glioma, NOS;CNS/Brain;SOLID;209 +543;OCSC;DarkRed;3;Head and Neck Cancer;Oral Cavity Squamous Cell Carcinoma;Head and Neck;SOLID;53 +544;GEJ;LightSkyBlue;3;Esophagogastric Cancer;Adenocarcinoma of the Gastroesophageal Junction;Esophagus/Stomach;SOLID;137 +545;CPP;Gray;3;Choroid Plexus Tumor;Choroid Plexus Papilloma;CNS/Brain;SOLID;241 +546;THYC;Purple;3;Thymic Tumor;Thymic Carcinoma;Thymus;SOLID;119 +547;ILC;HotPink;3;Breast Cancer;Breast Invasive Lobular Carcinoma;Breast;SOLID;133 +548;HL;LimeGreen;3;Hodgkin Lymphoma;Hodgkin Lymphoma;Lymphoid;LIQUID;51 +549;PBT;Gray;3;Miscellaneous Brain Tumor;Primary Brain Tumor;CNS/Brain;SOLID;201 +550;ALAL;LightSalmon;3;Leukemia;Acute Leukemias of Ambiguous Lineage;Myeloid;LIQUID;86 +551;DNT;Gray;3;Glioma;Dysembryoplastic Neuroepithelial Tumor;CNS/Brain;SOLID;56 +552;GRCT;LightBlue;3;Sex Cord Stromal Tumor;Granulosa Cell Tumor;Ovary/Fallopian Tube;SOLID;42 +553;ACYC;DarkRed;3;Salivary Gland Cancer;Adenoid Cystic Carcinoma;Head and Neck;SOLID;188 +554;VPSCC;Blue;3;Penile Cancer;Verrucous Penile Squamous Cell Carcinoma;Penis;SOLID;179 +555;CEEN;Teal;3;Cervical Cancer;Cervical Endometrioid Carcinoma;Cervix;SOLID;81 +556;BEC;Gray;3;Germ Cell Tumor;Embryonal Carcinoma;CNS/Brain;SOLID;102 +557;HGGNOS;Gray;3;Glioma;High-Grade Glioma, NOS;CNS/Brain;SOLID;209 +558;HPHSC;DarkRed;3;Head and Neck Cancer;Hypopharynx Squamous Cell Carcinoma;Head and Neck;SOLID;53 +559;CCBOV;LightBlue;3;Ovarian Cancer;Clear Cell Borderline Ovarian Tumor;Ovary/Fallopian Tube;SOLID;83 +560;DIPG;Gray;3;Glioma;Diffuse Intrinsic Pontine Glioma;CNS/Brain;SOLID;209 +561;USMT;PeachPuff;3;Uterine Sarcoma;Uterine Smooth Muscle Tumor;Uterus;SOLID;70 +562;GRC;LightSkyBlue;3;Esophagogastric Cancer;Gastric Remnant Adenocarcinoma;Esophagus/Stomach;SOLID;137 +563;OUSARC;PeachPuff;3;Uterine Sarcoma;Uterine Sarcoma, Other;Uterus;SOLID;70 +564;LUCA;Gainsboro;3;Non-Small Cell Lung Cancer;Lung Carcinoid;Lung;SOLID;190 +565;TEOS;White;3;Bone Cancer;Telangiectatic Osteosarcoma;Bone;SOLID;215 +566;MBEN;Gray;3;Embryonal Tumor;Medulloblastoma with Extensive Nodularity;CNS/Brain;SOLID;135 +567;THYM;Purple;3;Thymic Tumor;Thymoma;Thymus;SOLID;119 +568;ACLG;Green;3;Lacrimal Gland Tumor;Adenoid Cystic Carcinoma of the Lacrimal Gland;Eye;SOLID;47 +569;THFO;Teal;3;Thyroid Cancer;Follicular Thyroid Cancer;Thyroid;SOLID;74 +570;UUS;PeachPuff;3;Uterine Sarcoma;Undifferentiated Uterine Sarcoma;Uterus;SOLID;70 +571;ACCC;DarkRed;3;Salivary Gland Cancer;Acinic Cell Carcinoma;Head and Neck;SOLID;188 +572;SKCN;Black;3;Melanoma;Congenital Nevus;Skin;SOLID;172 +573;MMBC;HotPink;3;Breast Cancer;Mixed Type Metaplastic Breast Cancer;Breast;SOLID;43 +574;PGNT;Gray;3;Miscellaneous Neuroepithelial Tumor;Papillary Glioneuronal Tumor;CNS/Brain;SOLID;161 +575;SBMOV;LightBlue;3;Ovarian Cancer;Serous Borderline Ovarian Tumor, Micropapillary;Ovary/Fallopian Tube;SOLID;83 +576;IMMC;HotPink;3;Breast Cancer;Breast Invasive Mixed Mucinous Carcinoma;Breast;SOLID;133 +577;SBWDNET;SaddleBrown;3;Gastrointestinal Neuroendocrine Tumor;Small Bowel Well-Differentiated Neuroendocrine Tumor;Bowel;SOLID;150 +578;UCCC;PeachPuff;3;Endometrial Cancer;Uterine Clear Cell Carcinoma;Uterus;SOLID;231 +579;VYST;Purple;3;Germ Cell Tumor;Yolk Sac Tumor;Vulva/Vagina;SOLID;146 +580;HPCCNS;Gray;3;CNS Cancer;Hemangiopericytoma of the Central Nervous System;CNS/Brain;SOLID;244 +581;LGNET;Gray;3;Miscellaneous Brain Tumor;Low-Grade Neuroepithelial Tumor;CNS/Brain;SOLID;201 +582;PLEMESO;Blue;3;Mesothelioma;Pleural Mesothelioma, Epithelioid Type;Pleura;SOLID;143 +583;ETT;PeachPuff;3;Gestational Trophoblastic Disease;Epithelioid Trophoblastic Tumor;Uterus;SOLID;159 +584;PDC;Black;3;Cancer of Unknown Primary;Poorly Differentiated Carcinoma, NOS;Other;SOLID;235 +585;CAIS;SaddleBrown;3;Colorectal Cancer;Colon Adenocarcinoma In Situ;Bowel;SOLID;145 +586;MXOV;LightBlue;3;Ovarian Cancer;Mixed Ovarian Carcinoma;Ovary/Fallopian Tube;SOLID;83 +587;MUP;Black;3;Melanoma;Melanoma of Unknown Primary;Skin;SOLID;172 +588;UCU;Yellow;3;Bladder Cancer;Urethral Urothelial Carcinoma;Bladder/Urinary Tract;SOLID;221 +589;HGNES;LightSkyBlue;3;Gastrointestinal Neuroendocrine Tumors of the Esophagus/Stomach;High-Grade Neuroendocrine Carcinoma of the Stomach;Esophagus/Stomach;SOLID;130 +590;MPNST;Gray;3;Nerve Sheath Tumor;Malignant Peripheral Nerve Sheath Tumor;Peripheral Nervous System;SOLID;104 +591;PTPR;Gray;3;Pineal Tumor;Papillary Tumor of the Pineal Region;CNS/Brain;SOLID;110 +592;DA;SaddleBrown;3;Small Bowel Cancer;Duodenal Adenocarcinoma;Bowel;SOLID;258 +593;MYCHS;White;3;Bone Cancer;Myxoid Chondrosarcoma;Bone;SOLID;240 +594;PLBMESO;Blue;3;Mesothelioma;Pleural Mesothelioma, Biphasic Type;Pleura;SOLID;143 +595;MYEC;DarkRed;3;Salivary Gland Cancer;Myoepithelial Carcinoma;Head and Neck;SOLID;188 +596;CEMU;Teal;3;Cervical Cancer;Mucinous Carcinoma;Cervix;SOLID;81 +597;GCT;Gray;3;Sellar Tumor;Granular Cell Tumor;CNS/Brain;SOLID;50 +598;PEOS;White;3;Bone Cancer;Periosteal Osteosarcoma;Bone;SOLID;215 +599;CCE;Gray;3;CNS Cancer;Clear Cell Ependymoma;CNS/Brain;SOLID;263 +600;EMBC;HotPink;3;Breast Cancer;Epithelial Type Metaplastic Breast Cancer;Breast;SOLID;43 +601;UPECOMA;PeachPuff;3;Uterine Sarcoma;Uterine Perivascular Epithelioid Cell Tumor;Uterus;SOLID;70 +602;SCRMS;LightYellow;3;Soft Tissue Sarcoma;Spindle Cell Rhabdomyosarcoma;Soft Tissue;SOLID;96 +603;MCN;Purple;3;Pancreatic Cancer;Mucinous Cystic Neoplasm;Pancreas;SOLID;173 +604;GCCAP;SaddleBrown;3;Appendiceal Cancer;Goblet Cell Carcinoid of the Appendix;Bowel;SOLID;198 +605;AMBL;Gray;3;Embryonal Tumor;Large Cell/Anaplastic Medulloblastoma;CNS/Brain;SOLID;135 +606;CHGL;Gray;3;Miscellaneous Neuroepithelial Tumor;Chordoid Glioma of the Third Ventricle;CNS/Brain;SOLID;161 +607;BRCANOS;HotPink;3;Breast Cancer;Breast Invasive Cancer, NOS;Breast;SOLID;133 +608;DASTR;Gray;3;Glioma;Diffuse Astrocytoma;CNS/Brain;SOLID;209 +609;PTES;LightYellow;3;Soft Tissue Sarcoma;Proximal-Type Epithelioid Sarcoma;Soft Tissue;SOLID;204 +610;PPM;Gray;3;CNS Cancer;Papillary Meningioma;CNS/Brain;SOLID;244 +611;ROCY;Orange;4;Renal Cell Carcinoma;Renal Oncocytoma;Kidney;SOLID;419 +612;AMLMRC;LightSalmon;4;Leukemia;AML with Myelodysplasia-Related Changes;Myeloid;LIQUID;476 +613;GBM;Gray;4;Glioma;Glioblastoma Multiforme;CNS/Brain;SOLID;525 +614;CNL;LightSalmon;4;Myeloproliferative Neoplasms;Chronic Neutrophilic Leukemia;Myeloid;LIQUID;343 +615;BLLRGA;LimeGreen;4;B-Lymphoblastic Leukemia/Lymphoma;B-Lymphoblastic Leukemia/Lymphoma with Recurrent Genetic Abnormalities;Lymphoid;LIQUID;307 +616;GCEMU;Teal;4;Cervical Cancer;Gastric Type Mucinous Carcinoma;Cervix;SOLID;596 +617;HGSOC;LightBlue;4;Ovarian Cancer;High-Grade Serous Ovarian Cancer;Ovary/Fallopian Tube;SOLID;483 +618;CCPRC;Orange;4;Renal Cell Carcinoma;Clear Cell Papillary Renal Cell Carcinoma;Kidney;SOLID;419 +619;RSCC;Orange;4;Renal Cell Carcinoma;Renal Small Cell Carcinoma;Kidney;SOLID;419 +620;COM;HotPink;4;Breast Cancer;Carcinoma with Osseous Metaplasia;Breast;SOLID;573 +621;BTBEOV;LightBlue;4;Ovarian Cancer;Brenner Tumor, Benign;Ovary/Fallopian Tube;SOLID;505 +622;MLNFGFR1;LightSalmon;4;Leukemia;Myeloid/Lymphoid Neoplasms with FGFR1 Rearrangement;Myeloid;LIQUID;533 +623;MDSID5Q;LightSalmon;4;Myelodysplastic Syndromes;MDS with Isolated Del(5q);Myeloid;LIQUID;411 +624;PHPTLD;LimeGreen;4;Posttransplant Lymphoproliferative Disorders;Plasmacytic Hyperplasia PTLD;Lymphoid;LIQUID;289 +625;MPALBCRABL1;LightSalmon;4;Leukemia;"Mixed Phenotype Acute Leukemia with t(9;22)(q34.1;q11.2); BCR-ABL1";Myeloid;LIQUID;550 +626;USTUMP;PeachPuff;4;Uterine Sarcoma;Uterine Smooth Muscle Tumor of Uncertain Malignant Potential;Uterus;SOLID;561 +627;MRC;Orange;4;Renal Cell Carcinoma;Renal Medullary Carcinoma;Kidney;SOLID;419 +628;CSCHW;Gray;4;Nerve Sheath Tumor;Cellular Schwannoma;Peripheral Nervous System;SOLID;299 +629;LGSOC;LightBlue;4;Ovarian Cancer;Low-Grade Serous Ovarian Cancer;Ovary/Fallopian Tube;SOLID;483 +630;HGESS;PeachPuff;4;Uterine Sarcoma;High-Grade Endometrial Stromal Sarcoma;Uterus;SOLID;516 +631;LGESS;PeachPuff;4;Uterine Sarcoma;Low-Grade Endometrial Stromal Sarcoma;Uterus;SOLID;516 +632;CMCD;LightSalmon;4;Mastocytosis;Cutaneous Mastocytosis;Myeloid;LIQUID;394 +633;LUMEC;Gainsboro;4;Non-Small Cell Lung Cancer;Mucoepidermoid Carcinoma of the Lung;Lung;SOLID;381 +634;MDSMPNU;LightSalmon;4;Myelodysplastic/Myeloproliferative Neoplasms;MDS/MPN, Unclassifiable;Myeloid;LIQUID;380 +635;CCHM;HotPink;4;Breast Cancer;Carcinoma with Chondroid Metaplasia;Breast;SOLID;573 +636;AMLRGA;LightSalmon;4;Leukemia;AML with Recurrent Genetic Abnormalities;Myeloid;LIQUID;476 +637;MCSL;LightSalmon;4;Mastocytosis;Mast Cell Sarcoma;Myeloid;LIQUID;394 +638;SM;LightSalmon;4;Mastocytosis;Systemic Mastocytosis;Myeloid;LIQUID;394 +639;LECLC;Gainsboro;4;Non-Small Cell Lung Cancer;Lymphoepithelioma-like Carcinoma of the Lung;Lung;SOLID;402 +640;CHRCC;Orange;4;Renal Cell Carcinoma;Chromophobe Renal Cell Carcinoma;Kidney;SOLID;419 +641;CMML;LightSalmon;4;Myelodysplastic/Myeloproliferative Neoplasms;Chronic Myelomonocytic Leukemia;Myeloid;LIQUID;380 +642;MDSMD;LightSalmon;4;Myelodysplastic Syndromes;MDS with Multilineage Dysplasia;Myeloid;LIQUID;411 +643;BTBOV;LightBlue;4;Ovarian Cancer;Brenner Tumor, Borderline;Ovary/Fallopian Tube;SOLID;505 +644;GSARC;Gray;4;Glioma;Gliosarcoma;CNS/Brain;SOLID;525 +645;MTNN;LimeGreen;4;Mature T and NK Neoplasms;Mature T and NK Neoplasms;Lymphoid;LIQUID;497 +646;SRCC;Orange;4;Renal Cell Carcinoma;Sarcomatoid Renal Cell Carcinoma;Kidney;SOLID;419 +647;MDSRS;LightSalmon;4;Myelodysplastic Syndromes;MDS with Ring Sideroblasts;Myeloid;LIQUID;411 +648;HS;LightSalmon;4;Histiocytosis;Histiocytic Sarcoma;Myeloid;LIQUID;409 +649;CHLPTLD;LimeGreen;4;Posttransplant Lymphoproliferative Disorders;Classical Hodgkin Lymphoma PTLD;Lymphoid;LIQUID;289 +650;MPALKMT2A;LightSalmon;4;Leukemia;"Mixed Phenotype Acute Leukemia with t(v;11q23.3); KMT2A Rearranged";Myeloid;LIQUID;550 +651;UELMS;PeachPuff;4;Uterine Sarcoma;Uterine Epithelioid Leiomyosarcoma;Uterus;SOLID;561 +652;UMLMS;PeachPuff;4;Uterine Sarcoma;Uterine Myxoid Leiomyosarcoma;Uterus;SOLID;561 +653;MLNPDGFRA;LightSalmon;4;Leukemia;Myeloid/Lymphoid Neoplasms with PDGFRA Rearrangement;Myeloid;LIQUID;533 +654;URCC;Orange;4;Renal Cell Carcinoma;Unclassified Renal Cell Carcinoma;Kidney;SOLID;419 +655;SPDAC;LightSkyBlue;4;Esophagogastric Cancer;Poorly Differentiated Carcinoma of the Stomach;Esophagus/Stomach;SOLID;372 +656;MTSCC;Orange;4;Renal Cell Carcinoma;Renal Mucinous Tubular Spindle Cell Carcinoma;Kidney;SOLID;419 +657;FHPTLD;LimeGreen;4;Posttransplant Lymphoproliferative Disorders;Florid Follicular Hyperplasia PTLD;Lymphoid;LIQUID;289 +658;MDSEB;LightSalmon;4;Myelodysplastic Syndromes;MDS with Excess Blasts;Myeloid;LIQUID;411 +659;CCLC;Gainsboro;4;Non-Small Cell Lung Cancer;Clear Cell Carcinoma of the Lung;Lung;SOLID;402 +660;RDD;LightSalmon;4;Histiocytosis;Rosai-Dorfman Disease;Myeloid;LIQUID;409 +661;IDCT;LightSalmon;4;Histiocytosis;Indeterminate Dendritic Cell Tumor;Myeloid;LIQUID;409 +662;RLCLC;Gainsboro;4;Non-Small Cell Lung Cancer;Large Cell Lung Carcinoma With Rhabdoid Phenotype;Lung;SOLID;402 +663;TMN;LightSalmon;4;Leukemia;Therapy-Related Myeloid Neoplasms;Myeloid;LIQUID;476 +664;NKCLL;LimeGreen;4;T-Lymphoblastic Leukemia/Lymphoma;Natural Killer (NK) Cell Lymphoblastic Leukemia/Lymphoma;Lymphoid;LIQUID;382 +665;DSTAD;LightSkyBlue;4;Esophagogastric Cancer;Diffuse Type Stomach Adenocarcinoma;Esophagus/Stomach;SOLID;512 +666;MSCHW;Gray;4;Nerve Sheath Tumor;Melanotic Schwannoma;Peripheral Nervous System;SOLID;299 +667;BTMOV;LightBlue;4;Ovarian Cancer;Brenner Tumor, Malignant;Ovary/Fallopian Tube;SOLID;505 +668;PSTAD;LightSkyBlue;4;Esophagogastric Cancer;Papillary Stomach Adenocarcinoma;Esophagus/Stomach;SOLID;512 +669;PRCC;Orange;4;Renal Cell Carcinoma;Papillary Renal Cell Carcinoma;Kidney;SOLID;419 +670;BLPT;HotPink;4;Breast Sarcoma;Borderline Phyllodes Tumor of the Breast;Breast;SOLID;440 +671;GCLC;Gainsboro;4;Non-Small Cell Lung Cancer;Giant Cell Carcinoma of the Lung;Lung;SOLID;402 +672;MASCC;HotPink;4;Breast Cancer;Metaplastic Adenocarcinoma with Spindle Cell Differentiation;Breast;SOLID;600 +673;FHRCC;Orange;4;Renal Cell Carcinoma;FH-Deficient Renal Cell Carcinoma;Kidney;SOLID;419 +674;FRCT;LightSalmon;4;Histiocytosis;Fibroblastic Reticular Cell Tumor;Myeloid;LIQUID;409 +675;AUL;LightSalmon;4;Leukemia;Acute Undifferentiated Leukemia;Myeloid;LIQUID;550 +676;TSTAD;LightSkyBlue;4;Esophagogastric Cancer;Tubular Stomach Adenocarcinoma;Esophagus/Stomach;SOLID;512 +677;CHL;LimeGreen;4;Hodgkin Lymphoma;Classical Hodgkin Lymphoma;Lymphoid;LIQUID;548 +678;PPTLD;LimeGreen;4;Posttransplant Lymphoproliferative Disorders;Polymorphic PTLD;Lymphoid;LIQUID;289 +679;ICEMU;Teal;4;Cervical Cancer;Intestinal Type Mucinous Carcinoma;Cervix;SOLID;596 +680;CCOC;DarkRed;4;Head and Neck Cancer;Clear Cell Odontogenic Carcinoma;Head and Neck;SOLID;401 +681;MBN;LimeGreen;4;Mature B-Cell Neoplasms;Mature B-Cell Neoplasms;Lymphoid;LIQUID;497 +682;LUACC;Gainsboro;4;Non-Small Cell Lung Cancer;Adenoid Cystic Carcinoma of the Lung;Lung;SOLID;381 +683;CELNOS;LightSalmon;4;Myeloproliferative Neoplasms;Chronic Eosinophilic Leukemia, NOS;Myeloid;LIQUID;343 +684;JXG;LightSalmon;4;Histiocytosis;Disseminated Juvenile Xanthogranuloma;Myeloid;LIQUID;409 +685;CML;LightSalmon;4;Myeloproliferative Neoplasms;Chronic Myelogenous Leukemia;Myeloid;LIQUID;343 +686;MASC;HotPink;4;Breast Cancer;Metaplastic Adenosquamous Carcinoma;Breast;SOLID;600 +687;BLCLC;Gainsboro;4;Non-Small Cell Lung Cancer;Basaloid Large Cell Carcinoma of the Lung;Lung;SOLID;402 +688;MPTLD;LimeGreen;4;Posttransplant Lymphoproliferative Disorders;Monomorphic PTLD (B- and T-/NK-cell types);Lymphoid;LIQUID;289 +689;CDRCC;Orange;4;Renal Cell Carcinoma;Collecting Duct Renal Cell Carcinoma;Kidney;SOLID;419 +690;CHM;PeachPuff;4;Gestational Trophoblastic Disease;Complete Hydatidiform Mole;Uterus;SOLID;410 +691;ISTAD;LightSkyBlue;4;Esophagogastric Cancer;Intestinal Type Stomach Adenocarcinoma;Esophagus/Stomach;SOLID;512 +692;SCEMU;Teal;4;Cervical Cancer;Signet Ring Mucinous Carcinoma;Cervix;SOLID;596 +693;SCCRCC;Orange;4;Renal Cell Carcinoma;Renal Clear Cell Carcinoma with Sarcomatoid Features;Kidney;SOLID;366 +694;AMLNOS;LightSalmon;4;Leukemia;AML, NOS;Myeloid;LIQUID;476 +695;BPT;HotPink;4;Breast Sarcoma;Benign Phyllodes Tumor of the Breast;Breast;SOLID;440 +696;MDSSLD;LightSalmon;4;Myelodysplastic Syndromes;MDS with Single Lineage Dysplasia;Myeloid;LIQUID;411 +697;FDCS;LightYellow;4;Soft Tissue Sarcoma;Follicular Dendritic Cell Sarcoma;Myeloid;LIQUID;409 +698;ECD;LightSalmon;4;Histiocytosis;Erdheim-Chester Disease;Myeloid;LIQUID;409 +699;PMF;LightSalmon;4;Myeloproliferative Neoplasms;Primary Myelofibrosis;Myeloid;LIQUID;343 +700;MPALTNOS;LightSalmon;4;Leukemia;Mixed Phenotype Acute Leukemia, T/Myeloid, NOS;Myeloid;LIQUID;550 +701;MPT;HotPink;4;Breast Sarcoma;Malignant Phyllodes Tumor of the Breast;Breast;SOLID;440 +702;MLNPDGFRB;LightSalmon;4;Leukemia;Myeloid/Lymphoid Neoplasms with PDGFRB Rearrangement;Myeloid;LIQUID;533 +703;LCS;LightSalmon;4;Histiocytosis;Langerhans Cell Sarcoma;Myeloid;LIQUID;409 +704;MPALBNOS;LightSalmon;4;Leukemia;Mixed Phenotype Acute Leukemia, B/Myeloid, NOS;Myeloid;LIQUID;550 +705;RCYC;LightSalmon;4;Myelodysplastic Syndromes;Refractory Cytopenia of Childhood;Myeloid;LIQUID;411 +706;MSCC;HotPink;4;Breast Cancer;Metaplastic Squamous Cell Carcinoma;Breast;SOLID;600 +707;MLNPCM1JAK2;LightSalmon;4;Leukemia;Myeloid/Lymphoid Neoplasms with PCM1-JAK2;Myeloid;LIQUID;533 +708;JMML;LightSalmon;4;Myelodysplastic/Myeloproliferative Neoplasms;Juvenile Myelomonocytic Leukemia;Myeloid;LIQUID;380 +709;ET;LightSalmon;4;Myeloproliferative Neoplasms;Essential Thrombocythemia;Myeloid;LIQUID;343 +710;PHM;PeachPuff;4;Gestational Trophoblastic Disease;Partial Hydatidiform Mole;Uterus;SOLID;410 +711;TRCC;Orange;4;Renal Cell Carcinoma;Translocation-Associated Renal Cell Carcinoma;Kidney;SOLID;419 +712;IHM;PeachPuff;4;Gestational Trophoblastic Disease;Invasive Hydatidiform Mole;Uterus;SOLID;410 +713;MDSU;LightSalmon;4;Myelodysplastic Syndromes;MDS, Unclassifiable;Myeloid;LIQUID;411 +714;RAML;Orange;4;Renal Cell Carcinoma;Renal Angiomyolipoma;Kidney;SOLID;419 +715;NLPHL;LimeGreen;4;Hodgkin Lymphoma;Nodular Lymphocyte-Predominant Hodgkin Lymphoma;Lymphoid;LIQUID;548 +716;ULM;PeachPuff;4;Uterine Sarcoma;Uterine Leiomyoma;Uterus;SOLID;561 +717;IMPTLD;LimeGreen;4;Posttransplant Lymphoproliferative Disorders;Infectious Mononucleosis PTLD;Lymphoid;LIQUID;289 +718;ULMS;PeachPuff;4;Uterine Sarcoma;Uterine Leiomyosarcoma;Uterus;SOLID;561 +719;BLLNOS;LimeGreen;4;B-Lymphoblastic Leukemia/Lymphoma;B-Lymphoblastic Leukemia/Lymphoma, NOS;Lymphoid;LIQUID;307 +720;SCGBM;Gray;4;Glioma;Small Cell Glioblastoma;CNS/Brain;SOLID;525 +721;MS;LightSalmon;4;Leukemia;Myeloid Sarcoma;Myeloid;LIQUID;476 +722;IDCS;LightYellow;4;Soft Tissue Sarcoma;Interdigitating Dendritic Cell Sarcoma;Myeloid;LIQUID;409 +723;MDSMPNRST;LightSalmon;4;Myelodysplastic/Myeloproliferative Neoplasms;MDS/MPN with Ring Sideroblasts and Thrombocytosis;Myeloid;LIQUID;380 +724;PV;LightSalmon;4;Myeloproliferative Neoplasms;Polycythemia Vera;Myeloid;LIQUID;343 +725;MCS;HotPink;4;Breast Cancer;Metaplastic Carcinosarcoma;Breast;SOLID;573 +726;MPNU;LightSalmon;4;Myeloproliferative Neoplasms;Myeloproliferative Neoplasms, Unclassifiable;Myeloid;LIQUID;343 +727;ACML;LightSalmon;4;Myelodysplastic/Myeloproliferative Neoplasms;Atypical Chronic Myeloid Leukemia, BCR-ABL1-;Myeloid;LIQUID;380 +728;MPRDS;LightSalmon;4;Leukemia;Myeloid Proliferations Related to Down Syndrome;Myeloid;LIQUID;476 +729;SSRCC;LightSkyBlue;4;Esophagogastric Cancer;Signet Ring Cell Carcinoma of the Stomach;Esophagus/Stomach;SOLID;372 +730;MSTAD;LightSkyBlue;4;Esophagogastric Cancer;Mucinous Stomach Adenocarcinoma;Esophagus/Stomach;SOLID;512 +731;ETPLL;LimeGreen;4;T-Lymphoblastic Leukemia/Lymphoma;Early T-Cell Precursor Lymphoblastic Leukemia;Lymphoid;LIQUID;382 +732;LCH;LightSalmon;4;Histiocytosis;Langerhans Cell Histiocytosis;Myeloid;LIQUID;409 +733;SBLU;LimeGreen;5;Mature B-Cell Neoplasms;Splenic B-Cell Lymphoma/Leukemia, Unclassifiable;Lymphoid;LIQUID;681 +734;TMDS;LightSalmon;5;Leukemia;Therapy-Related Myelodysplastic Syndrome;Myeloid;LIQUID;663 +735;ITLPDGI;LimeGreen;5;Mature T and NK Neoplasms;Indolent T-Cell Lymphoproliferative Disorder of the GI Tract;Lymphoid;LIQUID;645 +736;AMLCBFBMYH11;LightSalmon;5;Leukemia;"AML with inv(16)(p13.1q22) or t(16;16)(p13.1;q22);CBFB-MYH11";Myeloid;LIQUID;636 +737;AWM;LightSalmon;5;Leukemia;AML without Maturation;Myeloid;LIQUID;694 +738;BL;LimeGreen;5;Mature B-Cell Neoplasms;Burkitt Lymphoma;Lymphoid;LIQUID;681 +739;AMOL;LightSalmon;5;Leukemia;Acute Monoblastic/Monocytic Leukemia;Myeloid;LIQUID;694 +740;PERL;LightSalmon;5;Leukemia;Pure Erythroid Leukemia;Myeloid;LIQUID;694 +741;AMLCEBPA;LightSalmon;5;Leukemia;AML with Biallelic Mutations of CEBPA;Myeloid;LIQUID;636 +742;PMBL;LimeGreen;5;Mature B-Cell Neoplasms;Primary Mediastinal (Thymic) Large B-Cell Lymphoma;Lymphoid;LIQUID;681 +743;PEL;LimeGreen;5;Mature B-Cell Neoplasms;Primary Effusion Lymphoma;Lymphoid;LIQUID;681 +744;PVMF;LightSalmon;5;Myeloproliferative Neoplasms;Polycythaemia Vera Myelofibrosis;Myeloid;LIQUID;724 +745;NSCHL;LimeGreen;5;Hodgkin Lymphoma;Nodular Sclerosis Classical Hodgkin Lymphoma;Lymphoid;LIQUID;677 +746;BPLL;LimeGreen;5;Mature B-Cell Neoplasms;B-Cell Prolymphocytic Leukemia;Lymphoid;LIQUID;681 +747;MCBCL;LimeGreen;5;Mature B-Cell Neoplasms;Monoclonal B-Cell Lymphocytosis;Lymphoid;LIQUID;681 +748;ALKLBCL;LimeGreen;5;Mature B-Cell Neoplasms;ALK Positive Large B-Cell Lymphoma;Lymphoid;LIQUID;681 +749;EATL;LimeGreen;5;Mature T and NK Neoplasms;Enteropathy-Associated T-Cell Lymphoma;Lymphoid;LIQUID;645 +750;SPTCL;LimeGreen;5;Mature T and NK Neoplasms;Subcutaneous Panniculitis-Like T-Cell Lymphoma;Lymphoid;LIQUID;645 +751;AHCD;LimeGreen;5;Mature B-Cell Neoplasms;Alpha Heavy-Chain Disease;Lymphoid;LIQUID;681 +752;BLLHYPER;LimeGreen;5;B-Lymphoblastic Leukemia/Lymphoma;B-Lymphoblastic Leukemia/Lymphoma with Hyperdiploidy;Lymphoid;LIQUID;615 +753;EBVDLBCLNOS;LimeGreen;5;Mature B-Cell Neoplasms;EBV Positive DLBCL, NOS;Lymphoid;LIQUID;681 +754;BLLIAMP21;LimeGreen;5;B-Lymphoblastic Leukemia/Lymphoma;B-Lymphoblastic Leukemia/Lymphoma with iAMP21;Lymphoid;LIQUID;615 +755;APMF;LightSalmon;5;Leukemia;Acute Panmyelosis with Myelofibrosis;Myeloid;LIQUID;694 +756;TPLL;LimeGreen;5;Mature T and NK Neoplasms;T-Cell Prolymphocytic Leukemia;Lymphoid;LIQUID;645 +757;PTFL;LimeGreen;5;Mature B-Cell Neoplasms;Pediatric-Type Follicular Lymphoma;Lymphoid;LIQUID;681 +758;AMLBCRABL1;LightSalmon;5;Leukemia;AML with BCR-ABL1;Myeloid;LIQUID;636 +759;BLLETV6RUNX1;LimeGreen;5;B-Lymphoblastic Leukemia/Lymphoma;"B-Lymphoblastic Leukemia/Lymphoma with t(12;21)(p13.2;q22.1); ETV6-RUNX1";Lymphoid;LIQUID;615 +760;LDCHL;LimeGreen;5;Hodgkin Lymphoma;Lymphocyte-Depleted Classical Hodgkin Lymphoma;Lymphoid;LIQUID;677 +761;SPB;LimeGreen;5;Mature B-Cell Neoplasms;Solitary Plasmacytoma of Bone;Lymphoid;LIQUID;681 +762;BCLU;LimeGreen;5;Mature B-Cell Neoplasms;B-Cell Lymphoma, Unclassifiable, with Features Intermediate between DLBCL and Classical Hodgkin lymphoma;Lymphoid;LIQUID;681 +763;BLLHYPO;LimeGreen;5;B-Lymphoblastic Leukemia/Lymphoma;B-Lymphoblastic Leukemia/Lymphoma with Hypodiploidy;Lymphoid;LIQUID;615 +764;PLBL;LimeGreen;5;Mature B-Cell Neoplasms;Plasmablastic Lymphoma;Lymphoid;LIQUID;681 +765;ENKL;LimeGreen;5;Mature T and NK Neoplasms;Extranodal NK-/T-Cell Lymphoma, Nasal Type;Lymphoid;LIQUID;645 +766;PTCL;LimeGreen;5;Mature T and NK Neoplasms;Peripheral T-Cell lymphoma, NOS;Lymphoid;LIQUID;645 +767;AMLMLLT3KMT2A;LightSalmon;5;Leukemia;"AML with t(9;11)(p21.3;q23.3);MLLT3-KMT2A";Myeloid;LIQUID;636 +768;TAM;LightSalmon;5;Leukemia;Transient Abnormal Myelopoiesis;Myeloid;LIQUID;728 +769;MLADS;LightSalmon;5;Leukemia;Myeloid Leukemia Associated with Down Syndrome;Myeloid;LIQUID;728 +770;APLPMLRARA;LightSalmon;5;Leukemia;APL with PML-RARA;Myeloid;LIQUID;636 +771;AITL;LimeGreen;5;Mature T and NK Neoplasms;Angioimmunoblastic T-Cell Lymphoma;Lymphoid;LIQUID;645 +772;HCL;LimeGreen;5;Mature B-Cell Neoplasms;Hairy Cell Leukemia;Lymphoid;LIQUID;681 +773;ASM;LightSalmon;5;Mastocytosis;Aggressive Systemic Mastocytosis;Myeloid;LIQUID;638 +774;FL;LimeGreen;5;Mature B-Cell Neoplasms;Follicular Lymphoma;Lymphoid;LIQUID;681 +775;SS;LimeGreen;5;Mature T and NK Neoplasms;Sezary Syndrome;Lymphoid;LIQUID;645 +776;ATLL;LimeGreen;5;Mature T and NK Neoplasms;Adult T-Cell Leukemia/Lymphoma;Lymphoid;LIQUID;645 +777;THRLBCL;LimeGreen;5;Mature B-Cell Neoplasms;T-Cell/Histiocyte-Rich Large B-Cell Lymphoma;Lymphoid;LIQUID;681 +778;LBLIRF4;LimeGreen;5;Mature B-Cell Neoplasms;Large B-Cell Lymphoma with IRF4 Rearrangement;Lymphoid;LIQUID;681 +779;PCSMTPLD;LimeGreen;5;Mature T and NK Neoplasms;Primary Cutaneous CD4 Positive Small/Medium T-Cell Lymphoproliferative Disorder;Lymphoid;LIQUID;645 +780;AMML;LightSalmon;5;Leukemia;Acute Myelomonocytic Leukemia;Myeloid;LIQUID;694 +781;LYG;LimeGreen;5;Mature B-Cell Neoplasms;Lymphomatoid Granulomatosis;Lymphoid;LIQUID;681 +782;ETMF;LightSalmon;5;Myeloproliferative Neoplasms;Essential Thrombocythemia Myelofibrosis;Myeloid;LIQUID;709 +783;MDSRSSLD;LightSalmon;5;Myelodysplastic Syndromes;MDS with Ring Sideroblasts and Single Lineage Dysplasia;Myeloid;LIQUID;647 +784;EBVMCU;LimeGreen;5;Mature B-Cell Neoplasms;EBV Positive Mucocutaneous Ulcer;Lymphoid;LIQUID;681 +785;BLLBCRABL1;LimeGreen;5;B-Lymphoblastic Leukemia/Lymphoma;"B-Lymphoblastic Leukemia/Lymphoma with t(9;22)(q34.1;q11.2);BCR-ABL1";Lymphoid;LIQUID;615 +786;BLL11Q;LimeGreen;5;Mature B-Cell Neoplasms;Burkitt-Like Lymphoma with 11q Aberration;Lymphoid;LIQUID;681 +787;FTCL;LimeGreen;5;Mature T and NK Neoplasms;Follicular T-Cell Lymphoma;Lymphoid;LIQUID;645 +788;MDSEB2;LightSalmon;5;Myelodysplastic Syndromes;MDS with excess blasts-2;Myeloid;LIQUID;658 +789;AMLRBM15MKL1;LightSalmon;5;Leukemia;"AML (megakaryoblastic) with t(1;22)(p13.3;q13.3);RBM15-MKL1";Myeloid;LIQUID;636 +790;MGUS;LimeGreen;5;Mature B-Cell Neoplasms;Monoclonal Gammopathy of Undetermined Significance;Lymphoid;LIQUID;681 +791;MEITL;LimeGreen;5;Mature T and NK Neoplasms;Monomorphic Epitheliotropic Intestinal T-Cell Lymphoma;Lymphoid;LIQUID;645 +792;AMLDEKNUP214;LightSalmon;5;Leukemia;"AML with t(6;9)(p23;q34.1);DEK-NUP214";Myeloid;LIQUID;636 +793;SSM;LightSalmon;5;Mastocytosis;Smoldering Systemic Mastocytosis;Myeloid;LIQUID;638 +794;CMML2;LightSalmon;5;Myelodysplastic/Myeloproliferative Neoplasms;Chronic Myelomonocytic Leukemia-2;Myeloid;LIQUID;641 +795;NPTLTFH;LimeGreen;5;Mature T and NK Neoplasms;Nodal Peripheral T-Cell Lymphoma with TFH Phenotype;Lymphoid;LIQUID;645 +796;TAML;LightSalmon;5;Leukemia;Therapy-Related Acute Myeloid Leukemia;Myeloid;LIQUID;663 +797;MYCF;LimeGreen;5;Mature T and NK Neoplasms;Mycosis Fungoides;Lymphoid;LIQUID;645 +798;TLGL;LimeGreen;5;Mature T and NK Neoplasms;T-Cell Large Granular Lymphocytic Leukemia;Lymphoid;LIQUID;645 +799;DLBCLNOS;LimeGreen;5;Mature B-Cell Neoplasms;Diffuse Large B-Cell Lymphoma, NOS;Lymphoid;LIQUID;681 +800;PCLPD;LimeGreen;5;Mature T and NK Neoplasms;Primary Cutaneous CD30 Positive T-Cell Lymphoproliferative Disorders;Lymphoid;LIQUID;645 +801;PMFOFS;LightSalmon;5;Myeloproliferative Neoplasms;Primary Myelofibrosis,Overt Fibrotic Stage;Myeloid;LIQUID;699 +802;HHV8DLBCL;LimeGreen;5;Mature B-Cell Neoplasms;HHV8 Positive DLBCL, NOS;Lymphoid;LIQUID;681 +803;BLLIL3IGH;LimeGreen;5;B-Lymphoblastic Leukemia/Lymphoma;"B-Lymphoblastic Leukemia/Lymphoma with t(5;14)(q31.1;q32.3) IL3-IGH";Lymphoid;LIQUID;615 +804;SMMCL;LightSalmon;5;Mastocytosis;Mast Cell Leukemia;Myeloid;LIQUID;638 +805;HGBCLMYCBCL2;LimeGreen;5;Mature B-Cell Neoplasms;High-Grade B-Cell Lymphoma, with MYC and BCL2 and/or BCL6 Rearrangements;Lymphoid;LIQUID;681 +806;CLLSLL;LimeGreen;5;Mature B-Cell Neoplasms;Chronic Lymphocytic Leukemia/Small Lymphocytic Lymphoma;Lymphoid;LIQUID;681 +807;LPL;LimeGreen;5;Mature B-Cell Neoplasms;Lymphoplasmacytic Lymphoma;Lymphoid;LIQUID;681 +808;AMKL;LightSalmon;5;Leukemia;Acute Megakaryoblastic Leukemia;Myeloid;LIQUID;694 +809;GHCD;LimeGreen;5;Mature B-Cell Neoplasms;Gamma Heavy-Chain Disease;Lymphoid;LIQUID;681 +810;MCL;LimeGreen;5;Mature B-Cell Neoplasms;Mantle Cell Lymphoma;Lymphoid;LIQUID;681 +811;PCLBCLLT;LimeGreen;5;Mature B-Cell Neoplasms;Primary Cutaneous DLBCL, Leg Type;Lymphoid;LIQUID;681 +812;CMML0;LightSalmon;5;Myelodysplastic/Myeloproliferative Neoplasms;Chronic Myelomonocytic Leukemia-0;Myeloid;LIQUID;641 +813;AMLGATA2MECOM;LightSalmon;5;Leukemia;"AML with inv(3)(q21.3q26.2) or t(3;3)(q21.3;q26.2); GATA2, MECOM";Myeloid;LIQUID;636 +814;CMLBCRABL1;LightSalmon;5;Myeloproliferative Neoplasms;Chronic Myeloid Leukemia, BCR-ABL1+;Myeloid;LIQUID;685 +815;SEBVTLC;LimeGreen;5;Mature T and NK Neoplasms;Systemic EBV Positive T-Cell Lymphoma of Childhood;Lymphoid;LIQUID;645 +816;HSTCL;LimeGreen;5;Mature T and NK Neoplasms;Hepatosplenic T-cell Lymphoma;Lymphoid;LIQUID;645 +817;EP;LimeGreen;5;Mature B-Cell Neoplasms;Extraosseous Plasmacytoma;Lymphoid;LIQUID;681 +818;MZL;LimeGreen;5;Mature B-Cell Neoplasms;Marginal Zone Lymphoma;Lymphoid;LIQUID;681 +819;PCM;LimeGreen;5;Mature B-Cell Neoplasms;Plasma Cell Myeloma;Lymphoid;LIQUID;681 +820;SMAHN;LightSalmon;5;Mastocytosis;Systemic Mastocytosis with an Associated Hematological Neoplasm;Myeloid;LIQUID;638 +821;ANKL;LimeGreen;5;Mature T and NK Neoplasms;Aggressive NK-Cell Leukemia;Lymphoid;LIQUID;645 +822;LRCHL;LimeGreen;5;Hodgkin Lymphoma;Lymphocyte-Rich Classical Hodgkin Lymphoma;Lymphoid;LIQUID;677 +823;CLPDNK;LimeGreen;5;Mature T and NK Neoplasms;Chronic Lymphoproliferative Disorder of NK Cells;Lymphoid;LIQUID;645 +824;AMLMD;LightSalmon;5;Leukemia;AML with Minimal Differentiation;Myeloid;LIQUID;694 +825;MHCD;LimeGreen;5;Mature B-Cell Neoplasms;Mu Heavy-Chain Disease;Lymphoid;LIQUID;681 +826;BLLBCRABL1L;LimeGreen;5;B-Lymphoblastic Leukemia/Lymphoma;B-Lymphoblastic Leukemia/Lymphoma, BCR-ABL1 Like;Lymphoid;LIQUID;615 +827;PCGDTCL;LimeGreen;5;Mature T and NK Neoplasms;Primary Cutaneous Gamma Delta T-Cell Lymphoma;Lymphoid;LIQUID;645 +828;HGBCL;LimeGreen;5;Mature B-Cell Neoplasms;High-Grade B-Cell Lymphoma, NOS;Lymphoid;LIQUID;681 +829;HVLL;LimeGreen;5;Mature T and NK Neoplasms;Hydroa Vacciniforme Like Lymphoproliferative Disorder;Lymphoid;LIQUID;645 +830;IVBCL;LimeGreen;5;Mature B-Cell Neoplasms;Intravascular Large B-Cell Lymphoma;Lymphoid;LIQUID;681 +831;PCNSL;LimeGreen;5;Mature B-Cell Neoplasms;Primary DLBCL of the central nervous system;Lymphoid;LIQUID;681 +832;ALCL;LimeGreen;5;Mature T and NK Neoplasms;Anaplastic Large Cell Lymphoma;Lymphoid;LIQUID;645 +833;MCCHL;LimeGreen;5;Hodgkin Lymphoma;Mixed Cellularity Classical Hodgkin Lymphoma;Lymphoid;LIQUID;677 +834;BLLTCF3PBX1;LimeGreen;5;B-Lymphoblastic Leukemia/Lymphoma;"B-Lymphoblastic Leukemia/Lymphoma with t(1;19)(q23;p13.3);TCF3-PBX1";Lymphoid;LIQUID;615 +835;PMFPES;LightSalmon;5;Myeloproliferative Neoplasms;Primary Myelofibrosis, Prefibrotic/Early Stage;Myeloid;LIQUID;699 +836;DLBCLCI;LimeGreen;5;Mature B-Cell Neoplasms;DLBCL Associated with Chronic Inflammation;Lymphoid;LIQUID;681 +837;MDSEB1;LightSalmon;5;Myelodysplastic Syndromes;MDS with excess blasts-1;Myeloid;LIQUID;658 +838;BLLKMT2A;LimeGreen;5;B-Lymphoblastic Leukemia/Lymphoma;"B-Lymphoblastic Leukemia/Lymphoma with t(v;11q23.3);KMT2A Rearranged";Lymphoid;LIQUID;615 +839;PCAECTCL;LimeGreen;5;Mature T and NK Neoplasms;Primary Cutaneous CD8 Positive Aggressive Epidermotropic Cytotoxic T-Cell Lymphoma;Lymphoid;LIQUID;645 +840;AMLNPM1;LightSalmon;5;Leukemia;AML with Mutated NPM1;Myeloid;LIQUID;636 +841;AMLRUNX1RUNX1T1;LightSalmon;5;Leukemia;"AML with t(8;21)(q22;q22.1);RUNX1-RUNX1T1";Myeloid;LIQUID;636 +842;AMLRUNX1;LightSalmon;5;Leukemia;AML with Mutated RUNX1;Myeloid;LIQUID;636 +843;ISM;LightSalmon;5;Mastocytosis;Indolent Systemic Mastocytosis;Myeloid;LIQUID;638 +844;PCATCL;LimeGreen;5;Mature T and NK Neoplasms;Primary Cutaneous Acral CD8 Positive T-Cell Lymphoma;Lymphoid;LIQUID;645 +845;PCFCL;LimeGreen;5;Mature B-Cell Neoplasms;Primary Cutaneous Follicle Center Lymphoma;Lymphoid;LIQUID;681 +846;CMML1;LightSalmon;5;Myelodysplastic/Myeloproliferative Neoplasms;Chronic Myelomonocytic Leukemia-1;Myeloid;LIQUID;641 +847;ABL;LightSalmon;5;Leukemia;Acute Basophilic Leukemia;Myeloid;LIQUID;694 +848;MIDD;LimeGreen;5;Mature B-Cell Neoplasms;Monoclonal Immunoglobulin Deposition Diseases;Lymphoid;LIQUID;681 +849;MDSRSMD;LightSalmon;5;Myelodysplastic Syndromes;MDS with Ring Sideroblasts and Multilineage Dysplasia;Myeloid;LIQUID;647 +850;AM;LightSalmon;5;Leukemia;AML with Maturation;Myeloid;LIQUID;694 +851;GCB;LimeGreen;6;Mature B-Cell Neoplasms;Germinal Center B-Cell Type;Lymphoid;LIQUID;799 +852;BIALCL;LimeGreen;6;Mature T and NK Neoplasms;Breast Implant-Associated Anaplastic Large-Cell Lymphoma;Lymphoid;LIQUID;832 +853;WM;LimeGreen;6;Mature B-Cell Neoplasms;Waldenstrom Macroglobulinemia;Lymphoid;LIQUID;807 +854;MGUSIGG;LimeGreen;6;Mature B-Cell Neoplasms;IgG;Lymphoid;LIQUID;790 +855;MIDDA;LimeGreen;6;Mature B-Cell Neoplasms;Amyloidosis;Lymphoid;LIQUID;848 +856;HCL-V;LimeGreen;6;Mature B-Cell Neoplasms;Hairy Cell Leukemia-Variant;Lymphoid;LIQUID;733 +857;ALCLALKN;LimeGreen;6;Mature T and NK Neoplasms;Anaplastic Large-Cell Lymphoma ALK Negative;Lymphoid;LIQUID;832 +858;ISMCL;LimeGreen;6;Mature B-Cell Neoplasms;In Situ Mantle Cell Neoplasia;Lymphoid;LIQUID;810 +859;MIDDO;LimeGreen;6;Mature B-Cell Neoplasms;Monoclonal Immunoglobulin Deposition Diseases, Other;Lymphoid;LIQUID;848 +860;ALCLALKP;LimeGreen;6;Mature T and NK Neoplasms;Anaplastic Large-Cell Lymphoma ALK Positive;Lymphoid;LIQUID;832 +861;EMALT;LimeGreen;6;Mature B-Cell Neoplasms;Extranodal Marginal Zone Lymphoma of Mucosa-Associated Lymphoid Tissue (MALT lymphoma);Lymphoid;LIQUID;818 +862;MGUSIGA;LimeGreen;6;Mature B-Cell Neoplasms;IgA;Lymphoid;LIQUID;790 +863;NMZL;LimeGreen;6;Mature B-Cell Neoplasms;Nodal Marginal Zone Lymphoma;Lymphoid;LIQUID;818 +864;ABC;LimeGreen;6;Mature B-Cell Neoplasms;Activated B-cell Type;Lymphoid;LIQUID;799 +865;SMZL;LimeGreen;6;Mature B-Cell Neoplasms;Splenic Marginal Zone Lymphoma;Lymphoid;LIQUID;818 +866;PCALCL;LimeGreen;6;Mature T and NK Neoplasms;Primary Cutaneous Anaplastic Large Cell Lymphoma;Lymphoid;LIQUID;800 +867;DFL;LimeGreen;6;Mature B-Cell Neoplasms;Duodenal-Type Follicular Lymphoma;Lymphoid;LIQUID;774 +868;LYP;LimeGreen;6;Mature T and NK Neoplasms;Lymphomatoid Papulosis;Lymphoid;LIQUID;800 +869;SDRPL;LimeGreen;6;Mature B-Cell Neoplasms;Splenic Diffuse Red Pulp Small B-Cell Lymphoma;Lymphoid;LIQUID;733 +870;ISFN;LimeGreen;6;Mature B-Cell Neoplasms;In Situ Follicular Neoplasia;Lymphoid;LIQUID;774 +871;MGUSIGM;LimeGreen;6;Mature B-Cell Neoplasms;IgM;Lymphoid;LIQUID;790 +872;NULL;PeachPuff;0;Endometrial Cancer;NULL;Uterus;SOLID;NULL +873;NULL;Gray;0;Melanocytoma;NULL;CNS/Brain;SOLID;NULL +874;NULL;SaddleBrown;0;Colorectal Cancer;NULL;Bowel;SOLID;NULL +875;NULL;Green;0;Biliary Tract Cancer, NOS;NULL;Biliary Tract;SOLID;NULL +876;NULL;Gray;0;Peripheral Nervous System;NULL;Peripheral Nervous System;SOLID;NULL +877;NULL;PeachPuff;0;Uterine Sarcoma;NULL;Uterus;SOLID;NULL +878;NULL;Gainsboro;0;Non-Small Cell Lung Cancer;NULL;Lung;SOLID;NULL +879;NULL;Purple;0;Thymic Tumor;NULL;Thymus;SOLID;NULL +880;NULL;Black;0;Skin Cancer, Non-Melanoma;NULL;Skin;SOLID;NULL +881;NULL;White;0;Bone Cancer, NOS;NULL;Bone;SOLID;NULL +882;NULL;LightYellow;0;Malignant Glomus Tumor;NULL;Soft Tissue;SOLID;NULL +883;NULL;DarkRed;0;Parathyroid Cancer;NULL;Head and Neck;SOLID;NULL +884;NULL;PeachPuff;0;Gestational Trophoblastic Disease;NULL;Uterus;SOLID;NULL +885;NULL;LightSkyBlue;0;Gastrointestinal Neuroendocrine Tumors of the Esophagus/Stomach;NULL;Esophagus/Stomach;SOLID;NULL +886;NULL;HotPink;0;Breast Sarcoma;NULL;Breast;SOLID;NULL +887;NULL;LightSalmon;0;Myelodysplastic/Myeloproliferative Neoplasms;NULL;Myeloid;LIQUID;NULL +888;NULL;Orange;0;Rhabdoid Cancer;NULL;Kidney;SOLID;NULL +889;NULL;Purple;0;Ampullary Carcinoma, NOS;NULL;Ampulla of Vater;SOLID;NULL +890;NULL;DarkRed;0;Head and Neck Cancer;NULL;Head and Neck;SOLID;NULL +891;NULL;Purple;0;Adrenocortical Carcinoma;NULL;Adrenal Gland;SOLID;NULL +892;NULL;LightYellow;0;Soft Tissue Sarcoma;NULL;MIXED;MIXED;NULL +893;NULL;MIXED;0;Non-Hodgkin Lymphoma;NULL;MIXED;MIXED;NULL +894;NULL;Purple;0;Pancreatic Cancer;NULL;Pancreas;SOLID;NULL +895;NULL;Purple;0;Adrenal Gland Cancer, NOS;NULL;Adrenal Gland;SOLID;NULL +896;NULL;Red;0;Testicular Cancer, NOS;NULL;Testis;SOLID;NULL +897;NULL;Gray;0;Nerve Sheath Tumor;NULL;Peripheral Nervous System;SOLID;NULL +898;NULL;Green;0;Peritoneal Cancer, NOS;NULL;Peritoneum;SOLID;NULL +899;NULL;LightSalmon;0;Mastocytosis;NULL;Myeloid;LIQUID;NULL +900;NULL;MediumSeaGreen;0;Malignant Rhabdoid Tumor of the Liver;NULL;Liver;SOLID;NULL +901;NULL;Blue;0;Penile Cancer, NOS;NULL;Penis;SOLID;NULL +902;NULL;DarkRed;0;Salivary Gland Cancer;NULL;Head and Neck;SOLID;NULL +903;NULL;SaddleBrown;0;Bowel Cancer, NOS;NULL;Bowel;SOLID;NULL +904;NULL;MIXED;0;Sex Cord Stromal Tumor;NULL;MIXED;SOLID;NULL +905;NULL;LightSalmon;0;Leukemia;NULL;Myeloid;LIQUID;NULL +906;NULL;LimeGreen;0;Posttransplant Lymphoproliferative Disorders;NULL;Lymphoid;LIQUID;NULL +907;NULL;MediumSeaGreen;0;Undifferentiated Embryonal Sarcoma of the Liver;NULL;Liver;SOLID;NULL +908;NULL;Gray;0;Primary CNS Melanocytic Tumors;NULL;CNS/Brain;SOLID;NULL +909;NULL;SaddleBrown;0;Small Bowel Cancer;NULL;Bowel;SOLID;NULL +910;NULL;LightBlue;0;Ovarian Cancer;NULL;Ovary/Fallopian Tube;SOLID;NULL +911;NULL;;0;Tissue;NULL;;MIXED;NULL +912;NULL;LightYellow;0;Soft Tissue Cancer;NULL;Soft Tissue;SOLID;NULL +913;NULL;Black;0;Other Cancer, NOS;NULL;Other;SOLID;NULL +914;NULL;SaddleBrown;0;Appendiceal Cancer;NULL;Bowel;SOLID;NULL +915;NULL;Blue;0;Penile Cancer;NULL;Penis;SOLID;NULL +916;NULL;LimeGreen;0;Mature B-Cell Neoplasms;NULL;Lymphoid;LIQUID;NULL +917;NULL;LightSalmon;0;Myelodysplastic Syndromes;NULL;Myeloid;LIQUID;NULL +918;NULL;Gray;0;Sellar Tumor;NULL;CNS/Brain;SOLID;NULL +919;NULL;Black;0;Skin Cancer, NOS;NULL;Skin;SOLID;NULL +920;NULL;Orange;0;Kidney Cancer, NOS;NULL;Kidney;SOLID;NULL +921;NULL;Purple;0;Vulvar Carcinoma;NULL;Vulva/Vagina;SOLID;NULL +922;NULL;LightYellow;0;Gastrointestinal Stromal Tumor;NULL;Soft Tissue;SOLID;NULL +923;NULL;LightSalmon;0;Histiocytosis;NULL;Myeloid;LIQUID;NULL +924;NULL;Green;0;Eye Cancer, NOS;NULL;Eye;SOLID;NULL +925;NULL;PeachPuff;0;Uterine Cancer, NOS;NULL;Uterus;SOLID;NULL +926;NULL;Black;0;Adenocarcinoma In Situ;NULL;Other;SOLID;NULL +927;NULL;Gray;0;CNS/Brain Cancer, NOS;NULL;CNS/Brain;SOLID;NULL +928;NULL;SaddleBrown;0;Tubular Adenoma of the Colon;NULL;Bowel;SOLID;NULL +929;NULL;Teal;0;Thyroid Cancer;NULL;Thyroid;SOLID;NULL +930;NULL;LimeGreen;0;T-Lymphoblastic Leukemia/Lymphoma;NULL;Lymphoid;LIQUID;NULL +931;NULL;Yellow;0;Bladder/Urinary Tract Cancer, NOS;NULL;Bladder/Urinary Tract;SOLID;NULL +932;NULL;LightYellow;0;Myofibromatosis;NULL;Soft Tissue;SOLID;NULL +933;NULL;Purple;0;Pheochromocytoma;NULL;Adrenal Gland;SOLID;NULL +934;NULL;Teal;0;Cervical Cancer, NOS;NULL;Cervix;SOLID;NULL +935;NULL;Cyan;0;Prostate Cancer, NOS;NULL;Prostate;SOLID;NULL +936;NULL;Gainsboro;0;Small Cell Lung Cancer;NULL;Lung;SOLID;NULL +937;NULL;Purple;0;Ampullary Cancer;NULL;Ampulla of Vater;SOLID;NULL +938;NULL;MIXED;0;Mesothelioma;NULL;MIXED;SOLID;NULL +939;NULL;Gray;0;Embryonal Tumor;NULL;CNS/Brain;SOLID;NULL +940;NULL;MIXED;0;Hepatobiliary Cancer;NULL;MIXED;SOLID;NULL +941;NULL;Purple;0;Vulvar/Vaginal Cancer, NOS;NULL;Vulva/Vagina;SOLID;NULL +942;NULL;Black;0;Cancer of Unknown Primary;NULL;Other;SOLID;NULL +943;NULL;LimeGreen;0;Hodgkin Lymphoma;NULL;Lymphoid;LIQUID;NULL +944;NULL;MediumSeaGreen;0;Liver Cancer, NOS;NULL;Liver;SOLID;NULL +945;NULL;LightYellow;0;Soft Tissue Cancer, NOS;NULL;Soft Tissue;SOLID;NULL +946;NULL;Gray;0;Miscellaneous Neuroepithelial Tumor;NULL;MIXED;SOLID;NULL +947;NULL;Teal;0;Thyroid Cancer, NOS;NULL;Thyroid;SOLID;NULL +948;NULL;DarkRed;0;Head and Neck Cancer, NOS;NULL;Head and Neck;SOLID;NULL +949;NULL;LightYellow;0;Angiomatoid Fibrous Histiocytoma;NULL;Soft Tissue;SOLID;NULL +950;NULL;LightYellow;0;Infantile Fibrosarcoma;NULL;Soft Tissue;SOLID;NULL +951;NULL;Orange;0;Renal Cell Carcinoma;NULL;Kidney;SOLID;NULL +952;NULL;Gray;0;Peripheral Nervous System Cancer, NOS;NULL;Peripheral Nervous System;SOLID;NULL +953;NULL;LimeGreen;0;Mature T and NK Neoplasms;NULL;Lymphoid;LIQUID;NULL +954;NULL;Purple;0;Vaginal Cancer;NULL;Vulva/Vagina;SOLID;NULL +955;NULL;Teal;0;Cervical Cancer;NULL;Cervix;SOLID;NULL +956;NULL;MIXED;0;Melanoma;NULL;MIXED;SOLID;NULL +957;NULL;LightSalmon;0;Myeloid Neoplasms with Germ Line Predisposition;NULL;Myeloid;LIQUID;NULL +958;NULL;LimeGreen;0;B-Lymphoblastic Leukemia/Lymphoma;NULL;Lymphoid;LIQUID;NULL +959;NULL;Orange;0;Clear Cell Sarcoma of Kidney;NULL;Kidney;SOLID;NULL +960;NULL;DarkRed;0;Sialoblastoma;NULL;Head and Neck;SOLID;NULL +961;NULL;LimeGreen;0;Lymphatic Cancer, NOS;NULL;Lymphoid;LIQUID;NULL +962;NULL;LightBlue;0;Ovarian/Fallopian Tube Cancer, NOS;NULL;Ovary/Fallopian Tube;SOLID;NULL +963;NULL;SaddleBrown;0;Anal Cancer;NULL;Bowel;SOLID;NULL +964;NULL;Green;0;Lacrimal Gland Tumor;NULL;Eye;SOLID;NULL +965;NULL;Green;0;Retinoblastoma;NULL;Eye;SOLID;NULL +966;NULL;HotPink;0;Breast Cancer, NOS;NULL;Breast;SOLID;NULL +967;NULL;LightSkyBlue;0;Esophagogastric Cancer;NULL;Esophagus/Stomach;SOLID;NULL +968;NULL;Gray;0;CNS Cancer;NULL;CNS/Brain;SOLID;NULL +969;NULL;LightSalmon;0;Blastic Plasmacytoid Dendritic Cell Neoplasm;NULL;Myeloid;LIQUID;NULL +970;NULL;MIXED;0;Germ Cell Tumor;NULL;MIXED;SOLID;NULL +971;NULL;LightSalmon;0;Blood Cancer, NOS;NULL;Myeloid;LIQUID;NULL +972;NULL;Gray;0;Choroid Plexus Tumor;NULL;CNS/Brain;SOLID;NULL +973;NULL;LightSkyBlue;0;Esophageal/Stomach Cancer, NOS;NULL;Esophagus/Stomach;SOLID;NULL +974;NULL;Purple;0;Thymic Cancer, NOS;NULL;Thymus;SOLID;NULL +975;NULL;MIXED;0;Gastrointestinal Neuroendocrine Tumor;NULL;MIXED;SOLID;NULL +976;NULL;Purple;0;Adrenocortical Adenoma;NULL;Adrenal Gland;SOLID;NULL +977;NULL;Yellow;0;Bladder Cancer;NULL;Bladder/Urinary Tract;SOLID;NULL +978;NULL;HotPink;0;Breast Cancer;NULL;Breast;SOLID;NULL +979;NULL;Gray;0;Miscellaneous Brain Tumor;NULL;CNS/Brain;SOLID;NULL +980;NULL;Gray;0;Pineal Tumor;NULL;CNS/Brain;SOLID;NULL +981;NULL;White;0;Bone Cancer;NULL;Bone;SOLID;NULL +982;NULL;Purple;0;Pancreatic Cancer, NOS;NULL;Pancreas;SOLID;NULL +983;NULL;LightSalmon;0;Myeloproliferative Neoplasms;NULL;Myeloid;LIQUID;NULL +984;NULL;Gainsboro;0;Lung Cancer, NOS;NULL;Lung;SOLID;NULL +985;NULL;Gray;0;Glioma;NULL;CNS/Brain;SOLID;NULL +986;NULL;Blue;0;Pleural Cancer, NOS;NULL;Pleura;SOLID;NULL +987;NULL;Cyan;0;Prostate Cancer;NULL;Prostate;SOLID;NULL +988;NULL;Orange;0;Wilms Tumor;NULL;Kidney;SOLID;NULL +989;NULL;Orange;0;Renal Neuroendocrine Tumor;NULL;Kidney;SOLID;NULL diff --git a/src/main/resources/config/liquibase/data/categorical_alteration.csv b/src/main/resources/config/liquibase/data/categorical_alteration.csv new file mode 100644 index 000000000..c2a1d6e08 --- /dev/null +++ b/src/main/resources/config/liquibase/data/categorical_alteration.csv @@ -0,0 +1,20 @@ +id;alteration_type;type;name;consequence +1;ANY;ONCOGENIC_MUTATIONS;Oncogenic Mutations;ANY +2;ANY;GAIN_OF_FUNCTION_MUTATIONS;Gain-of-function Mutations;ANY +3;ANY;LOSS_OF_FUNCTION_MUTATIONS;Loss-of-function Mutations;ANY +4;ANY;SWITCH_OF_FUNCTION_MUTATIONS;Switch-of-function Mutations;ANY +5;STRUCTURAL_VARIANT;KINASE_DOMAIN_DUPLICATION;Kinase Domain Duplication;ANY +6;STRUCTURAL_VARIANT;INTERNAL_TANDEM_DUPLICATION;Internal Tandem Duplication;ANY +7;STRUCTURAL_VARIANT;PARTIAL_TANDEM_DUPLICATION;Partial Tandem Duplication;ANY +8;NA;OVEREXPRESSION;Overexpression;ANY +9;NA;HYPERMETHYLATION;Hypermethylation;ANY +10;NA;EPIGENETIC_SILENCING;Epigenetic Silencing;ANY +11;ANY;VUS;Variants of Unknown Significance;ANY +12;ANY;TRUNCATING_MUTATIONS;Truncating Mutations;ANY +13;STRUCTURAL_VARIANT;FUSIONS;Fusions;ANY +14;COPY_NUMBER_ALTERATION;AMPLIFICATION;Amplification;ANY +15;COPY_NUMBER_ALTERATION;GAIN;Copy Number Gain;ANY +16;COPY_NUMBER_ALTERATION;DELETION;Deletion;ANY +17;COPY_NUMBER_ALTERATION;LOSS;Copy Number Loss;ANY +18;ANY;PROMOTER;Promoter;ANY +19;NA;WILDTYPE;Wildtype;ANY diff --git a/src/main/resources/config/liquibase/data/consequence.csv b/src/main/resources/config/liquibase/data/consequence.csv new file mode 100644 index 000000000..4b1452532 --- /dev/null +++ b/src/main/resources/config/liquibase/data/consequence.csv @@ -0,0 +1,39 @@ +id;term;name;is_generally_truncating;description +1;UTR_3_PRIME_VARIANT;3 Prime UTR Variant;false;A UTR variant of the 3' UTR +2;UTR_5_PRIME_VARIANT;5 Prime UTR Variant;false;A UTR variant of the 5' UTR +3;ANY;Any;false;Any variant +4;CODING_SEQUENCE_VARIANT;Coding Sequence Variant;false;A sequence variant that changes the coding sequence +5;DOWNSTREAM_GENE_VARIANT;Downstream Gene Variant;false;A sequence variant located 3' of a gene +6;FEATURE_ELONGATION;Feature Elongation;false;A sequence variant that causes the extension of a genomic feature, with regard to the reference sequence +7;FEATURE_TRUNCATION;Feature Truncation;true;A sequence variant that causes the reduction of a genomic feature, with regard to the reference sequence +8;FRAMESHIFT_VARIANT;Frameshift Variant;true;A sequence variant which causes a disruption of the translational reading frame, because the number of nucleotides inserted or deleted is not a multiple of three +10;INCOMPLETE_TERMINAL_CODON_VARIANT;Incomplete Terminal Codon Variant;true;A sequence variant where at least one base of the final codon of an incompletely annotated transcript is changed +11;INFRAME_DELETION;Inframe Deletion;false;An inframe non synonymous variant that deletes bases from the coding sequence +12;INFRAME_INSERTION;Inframe Insertion;false;An inframe non synonymous variant that inserts bases into in the coding sequence +13;INTERGENIC_VARIANT;Intergenic Variant;false;A sequence variant located in the intergenic region, between genes +14;INTRON_VARIANT;Intron Variant;false;A transcript variant occurring within an intron +15;MATURE_MIRNA_VARIANT;Mature miRNA Variant;false;A transcript variant located with the sequence of the mature miRNA +16;MISSENSE_VARIANT;Missense Variant;false;A sequence variant, that changes one or more bases, resulting in a different amino acid sequence but where the length is preserved +17;NA;NA;false;NA +18;NMD_TRANSCRIPT_VARIANT;NMD Transcript Variant;false;A variant in a transcript that is the target of NMD +19;NON_CODING_TRANSCRIPT_EXON_VARIANT;Non Coding Transcript Exon Variant;false;A sequence variant that changes non-coding exon sequence in a non-coding transcript +20;NON_CODING_TRANSCRIPT_VARIANT;Non Coding Transcript Variant;false;A transcript variant of a non coding RNA gene +21;NON_TRUNCATING_VARIANT;Non Truncating Variant;false;A change in the DNA that does not truncate or shorten the protein +22;REGULATORY_REGION_ABLATION;Regulatory Region Ablation;false;A feature ablation whereby the deleted region includes a regulatory region +23;REGULATORY_REGION_AMPLIFICATION;Regulatory Region Amplification;false;A feature amplification of a region containing a regulatory region +24;REGULATORY_REGION_VARIANT;Regulatory Region Variant;false;A sequence variant located within a regulatory region +25;SPLICE_ACCEPTOR_VARIANT;Splice Acceptor Variant;true;A splice variant that changes the 2 base region at the 3' end of an intron +26;SPLICE_DONOR_VARIANT;Splice Donor Variant;true;A splice variant that changes the 2 base region at the 5' end of an intron +27;SPLICE_REGION_VARIANT;Splice Region Variant;true;A sequence variant in which a change has occurred within the region of the splice site, either within 1-3 bases of the exon or 3-8 bases of the intron +28;START_LOST;Start Lost;true;A codon variant that changes at least one base of the canonical start codo +29;STOP_GAINED;Stop Gained;true;A sequence variant whereby at least one base of a codon is changed, resulting in a premature stop codon, leading to a shortened transcript +30;STOP_LOST;Stop Lost;true;A sequence variant where at least one base of the terminator codon (stop) is changed, resulting in an elongated transcript +31;STOP_RETAINED_VARIANT;Stop Retained Variant;false;A sequence variant where at least one base in the terminator codon is changed, but the terminator remains +32;SYNONYMOUS_VARIANT;Synonymous Variant;false;A sequence variant where there is no resulting change to the encoded amino acid +33;TFBS_ABLATION;TFBS Ablation;true;A feature ablation whereby the deleted region includes a transcription factor binding site +34;TFBS_AMPLIFICATION;TFBS Amplification;false;A feature amplification of a region containing a transcription factor binding site +35;TF_BINDING_SITE_VARIANT;TF Binding Site Variant;false;A sequence variant located within a transcription factor binding site +36;TRANSCRIPT_ABLATION;Transcript Ablation;true;A feature ablation whereby the deleted region includes a transcript feature +37;TRANSCRIPT_AMPLIFICATION;Transcript Amplification;false;A feature amplification of a region containing a transcript +38;UPSTREAM_GENE_VARIANT;Upstream Gene Variant;false;A sequence variant located 5' of a gene +39;UNKNOWN;Unknown;false;Unknown status diff --git a/src/main/resources/config/liquibase/data/level_of_evidence.csv b/src/main/resources/config/liquibase/data/level_of_evidence.csv new file mode 100644 index 000000000..c29355ef0 --- /dev/null +++ b/src/main/resources/config/liquibase/data/level_of_evidence.csv @@ -0,0 +1,17 @@ +id;type;level;description;html_description;color +1;TX;LEVEL_1;FDA-recognized biomarker predictive of response to an FDA-approved drug in this indication;FDA-recognized biomarker predictive of response to an FDA-approved drug in this indication;#33A02C +2;TX;LEVEL_2;Standard care biomarker recommended by the NCCN or other expert panels predictive of response to an FDA-approved drug in this indication;Standard care biomarker recommended by the NCCN or other expert panels predictive of response to an FDA-approved drug in this indication;#1F78B4 +3;TX;LEVEL_3A;Compelling clinical evidence supports the biomarker as being predictive of response to a drug in this indication;Compelling clinical evidence supports the biomarker as being predictive of response to a drug in this indication but neither biomarker and drug are standard of care;#984EA3 +4;TX;LEVEL_3B;Standard care or investigational biomarker predictive of response to an FDA-approved or investigational drug in another indication;Standard care or investigational biomarker predictive of response to an FDA-approved or investigational drug in another indication;#BE98CE +5;TX;LEVEL_4;Compelling biological evidence supports the biomarker as being predictive of response to a drug;Compelling biological evidence supports the biomarker as being predictive of response to a drug but neither biomarker and drug are standard of care;#424242 +6;TX;LEVEL_R1;Standard care biomarker predictive of resistance to an FDA-approved drug in this indication;Standard of care biomarker predictive of resistance to an FDA-approved drug in this indication;#EE3424 +7;TX;LEVEL_R2;Compelling clinical evidence supports the biomarker as being predictive of resistance to a drug;Compelling clinical evidence supports the biomarker as being predictive of resistance to a drug;#F79A92 +8;DX;LEVEL_Dx1;FDA and/or professional guideline-recognized biomarker required for diagnosis in this indication;FDA and/or professional guideline-recognized biomarker required for diagnosis in this indication;#33A02C +9;DX;LEVEL_Dx2;FDA and/or professional guideline-recognized biomarker that supports diagnosis in this indication;FDA and/or professional guideline-recognized biomarker that supports diagnosis in this indication;#1F78B4 +10;DX;LEVEL_Dx3;Biomarker that may assist disease diagnosis in this indication based on clinical evidence;Biomarker that may assist disease diagnosis in this indication based on clinical evidence;#984EA3 +11;PX;LEVEL_Px1;FDA and/or professional guideline-recognized biomarker prognostic in this indication based on well-powered studie(s);FDA and/or professional guideline-recognized biomarker prognostic in this indication based on well-powered studie(s);#33A02C +12;PX;LEVEL_Px2;FDA and/or professional guideline-recognized biomarker prognostic in this indication based on a single or multiple small studies;FDA and/or professional guideline-recognized biomarker prognostic in this indication based on a single or multiple small studies;#1F78B4 +13;PX;LEVEL_Px3;Biomarker is prognostic in this indication based on clinical evidence in well-powered studies;Biomarker is prognostic in this indication based on clinical evidence in well-powered studies;#984EA3 +14;FDA;LEVEL_Fda1;Companion Diagnostics;Companion Diagnostics; +15;FDA;LEVEL_Fda2;Cancer Mutations with Evidence of Clinical Significance;Cancer Mutations with Evidence of Clinical Significance; +16;FDA;LEVEL_Fda3;Cancer Mutations with Potential of Clinical Significance;Cancer Mutations with Potential of Clinical Significance; diff --git a/src/main/resources/config/liquibase/data/specimen_type.csv b/src/main/resources/config/liquibase/data/specimen_type.csv new file mode 100644 index 000000000..d59bb2d7d --- /dev/null +++ b/src/main/resources/config/liquibase/data/specimen_type.csv @@ -0,0 +1,10 @@ +id;type;name +1;CFDNA;cfDNA from plasma +2;WHOLE_BLOOD;Whole blood +3;FFPE;FFPE +4;BONE_MARROW;Bone marrow +5;MONO_CELLS_BONE_MARROW;Mononuclear cells from bone marrow +6;MONO_CELLS_PERIF_BLOOD;Mononuclear cells from peripheral blood +7;PERIF_BLOOD;Peripheral Blood +8;FFPE_MN_BLOOD;FFPE with matched normal from blood +9;FFPE_MN_SALIVA;FFPE with matched normal from saliva \ No newline at end of file diff --git a/src/main/resources/config/liquibase/master.xml b/src/main/resources/config/liquibase/master.xml index 2f66127ea..07e9fc34f 100644 --- a/src/main/resources/config/liquibase/master.xml +++ b/src/main/resources/config/liquibase/master.xml @@ -2,7 +2,7 @@ + xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.4.xsd"> @@ -15,22 +15,59 @@ - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml index 58150a66e..1f91b3b29 100644 --- a/src/main/resources/logback-spring.xml +++ b/src/main/resources/logback-spring.xml @@ -2,20 +2,20 @@ - + + + + + - - + + --> - - - - - + + + + + + + + @@ -48,23 +51,24 @@ + - + - - - - + + - - + + + + true diff --git a/src/main/webapp/404.html b/src/main/webapp/404.html index 7569d7e21..0debdb123 100644 --- a/src/main/webapp/404.html +++ b/src/main/webapp/404.html @@ -4,7 +4,7 @@ Page Not Found - +