From 62d59e0472cc2df80ae0cfd00b6f6990c8186d40 Mon Sep 17 00:00:00 2001 From: Jules Jacobsen Date: Wed, 26 Jan 2022 16:27:20 +0000 Subject: [PATCH 001/155] Move package phenotools-validator to phenotools-validator-core. Update version to 1.0.0-RC1 --- phenotools-builder/pom.xml | 5 +++-- phenotools-cli/pom.xml | 6 +++--- phenotools-converter/pom.xml | 5 +++-- .../.mvn/wrapper/maven-wrapper.properties | 0 .../mvnw | 0 .../mvnw.cmd | 0 .../pom.xml | 6 +++--- .../validator/core/DefaultValidationInfo.java | 0 .../phenotools/validator/core/ErrorType.java | 0 .../validator/core/PhenopacketValidator.java | 0 .../core/PhenopacketValidatorFactory.java | 0 .../validator/core/ValidationAspect.java | 0 .../validator/core/ValidationItem.java | 0 .../validator/core/ValidatorInfo.java | 0 .../validator/core/ValidatorRunner.java | 0 .../PhenopacketValidatorRuntimeException.java | 0 phenotools-validator-jsonschema/pom.xml | 9 ++++++--- .../.mvn/wrapper/maven-wrapper.jar | Bin 47610 -> 0 bytes pom.xml | 4 ++-- 19 files changed, 20 insertions(+), 15 deletions(-) rename {phenotools-validator => phenotools-validator-core}/.mvn/wrapper/maven-wrapper.properties (100%) rename {phenotools-validator => phenotools-validator-core}/mvnw (100%) rename {phenotools-validator => phenotools-validator-core}/mvnw.cmd (100%) rename {phenotools-validator => phenotools-validator-core}/pom.xml (79%) rename {phenotools-validator => phenotools-validator-core}/src/main/java/org/phenopackets/phenotools/validator/core/DefaultValidationInfo.java (100%) rename {phenotools-validator => phenotools-validator-core}/src/main/java/org/phenopackets/phenotools/validator/core/ErrorType.java (100%) rename {phenotools-validator => phenotools-validator-core}/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidator.java (100%) rename {phenotools-validator => phenotools-validator-core}/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidatorFactory.java (100%) rename {phenotools-validator => phenotools-validator-core}/src/main/java/org/phenopackets/phenotools/validator/core/ValidationAspect.java (100%) rename {phenotools-validator => phenotools-validator-core}/src/main/java/org/phenopackets/phenotools/validator/core/ValidationItem.java (100%) rename {phenotools-validator => phenotools-validator-core}/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorInfo.java (100%) rename {phenotools-validator => phenotools-validator-core}/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorRunner.java (100%) rename {phenotools-validator => phenotools-validator-core}/src/main/java/org/phenopackets/phenotools/validator/core/except/PhenopacketValidatorRuntimeException.java (100%) delete mode 100644 phenotools-validator/.mvn/wrapper/maven-wrapper.jar diff --git a/phenotools-builder/pom.xml b/phenotools-builder/pom.xml index 7f6d8fa1..9e59f84c 100644 --- a/phenotools-builder/pom.xml +++ b/phenotools-builder/pom.xml @@ -2,12 +2,13 @@ + 4.0.0 + org.phenopackets.phenotools phenotools - 0.0.2-SNAPSHOT + 1.0.0-RC1 - 4.0.0 phenotools-builder diff --git a/phenotools-cli/pom.xml b/phenotools-cli/pom.xml index 987e7ac3..0efe8dad 100644 --- a/phenotools-cli/pom.xml +++ b/phenotools-cli/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenotools phenotools - 0.0.2-SNAPSHOT + 1.0.0-RC1 phenotools-cli @@ -33,13 +33,13 @@ org.phenopackets.phenotools - validator-core + phenotools-validator-core ${project.parent.version} compile org.phenopackets.phenotools - validator-jsonschema + phenotools-validator-jsonschema ${project.parent.version} compile diff --git a/phenotools-converter/pom.xml b/phenotools-converter/pom.xml index ad5a7e3e..02ec7269 100644 --- a/phenotools-converter/pom.xml +++ b/phenotools-converter/pom.xml @@ -2,12 +2,13 @@ + 4.0.0 + org.phenopackets.phenotools phenotools - 0.0.2-SNAPSHOT + 1.0.0-RC1 - 4.0.0 phenotools-converter diff --git a/phenotools-validator/.mvn/wrapper/maven-wrapper.properties b/phenotools-validator-core/.mvn/wrapper/maven-wrapper.properties similarity index 100% rename from phenotools-validator/.mvn/wrapper/maven-wrapper.properties rename to phenotools-validator-core/.mvn/wrapper/maven-wrapper.properties diff --git a/phenotools-validator/mvnw b/phenotools-validator-core/mvnw similarity index 100% rename from phenotools-validator/mvnw rename to phenotools-validator-core/mvnw diff --git a/phenotools-validator/mvnw.cmd b/phenotools-validator-core/mvnw.cmd similarity index 100% rename from phenotools-validator/mvnw.cmd rename to phenotools-validator-core/mvnw.cmd diff --git a/phenotools-validator/pom.xml b/phenotools-validator-core/pom.xml similarity index 79% rename from phenotools-validator/pom.xml rename to phenotools-validator-core/pom.xml index 41cf9259..6642f862 100644 --- a/phenotools-validator/pom.xml +++ b/phenotools-validator-core/pom.xml @@ -7,12 +7,12 @@ org.phenopackets.phenotools phenotools - 0.0.2-SNAPSHOT + 1.0.0-RC1 - validator-core + phenotools-validator-core - validator-core + phenotools-validator-core Validator utilities for phenopackets \ No newline at end of file diff --git a/phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/DefaultValidationInfo.java b/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/DefaultValidationInfo.java similarity index 100% rename from phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/DefaultValidationInfo.java rename to phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/DefaultValidationInfo.java diff --git a/phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/ErrorType.java b/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ErrorType.java similarity index 100% rename from phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/ErrorType.java rename to phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ErrorType.java diff --git a/phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidator.java b/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidator.java similarity index 100% rename from phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidator.java rename to phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidator.java diff --git a/phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidatorFactory.java b/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidatorFactory.java similarity index 100% rename from phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidatorFactory.java rename to phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidatorFactory.java diff --git a/phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/ValidationAspect.java b/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidationAspect.java similarity index 100% rename from phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/ValidationAspect.java rename to phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidationAspect.java diff --git a/phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/ValidationItem.java b/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidationItem.java similarity index 100% rename from phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/ValidationItem.java rename to phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidationItem.java diff --git a/phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorInfo.java b/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorInfo.java similarity index 100% rename from phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorInfo.java rename to phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorInfo.java diff --git a/phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorRunner.java b/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorRunner.java similarity index 100% rename from phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorRunner.java rename to phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorRunner.java diff --git a/phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/except/PhenopacketValidatorRuntimeException.java b/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/except/PhenopacketValidatorRuntimeException.java similarity index 100% rename from phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/except/PhenopacketValidatorRuntimeException.java rename to phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/except/PhenopacketValidatorRuntimeException.java diff --git a/phenotools-validator-jsonschema/pom.xml b/phenotools-validator-jsonschema/pom.xml index 1b828c66..b37ddc47 100644 --- a/phenotools-validator-jsonschema/pom.xml +++ b/phenotools-validator-jsonschema/pom.xml @@ -7,15 +7,18 @@ org.phenopackets.phenotools phenotools - 0.0.2-SNAPSHOT + 1.0.0-RC1 - validator-jsonschema + phenotools-validator-jsonschema + + phenotools-validator-jsonschema + JSON schema validator utilities for phenopackets org.phenopackets.phenotools - validator-core + phenotools-validator-core ${project.parent.version} diff --git a/phenotools-validator/.mvn/wrapper/maven-wrapper.jar b/phenotools-validator/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index 9cc84ea9b4d95453115d0c26488d6a78694e0bc6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47610 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 diff --git a/pom.xml b/pom.xml index f03dc5a5..cf5d7b15 100644 --- a/pom.xml +++ b/pom.xml @@ -6,13 +6,13 @@ org.phenopackets.phenotools phenotools - 0.0.2-SNAPSHOT + 1.0.0-RC1 pom phenotools-builder - phenotools-validator + phenotools-validator-core phenotools-validator-jsonschema phenotools-converter phenotools-cli From 4f762b8f22361dec3ae40731e5e225fe71c0cc00 Mon Sep 17 00:00:00 2001 From: Jules Jacobsen Date: Mon, 7 Feb 2022 15:36:36 +0000 Subject: [PATCH 002/155] Update version to 1.0.0 --- phenotools-builder/pom.xml | 2 +- phenotools-cli/pom.xml | 2 +- phenotools-converter/pom.xml | 2 +- phenotools-validator-core/pom.xml | 2 +- pom.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/phenotools-builder/pom.xml b/phenotools-builder/pom.xml index 9e59f84c..14cde2e6 100644 --- a/phenotools-builder/pom.xml +++ b/phenotools-builder/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenotools phenotools - 1.0.0-RC1 + 1.0.0 phenotools-builder diff --git a/phenotools-cli/pom.xml b/phenotools-cli/pom.xml index 0efe8dad..deb828ae 100644 --- a/phenotools-cli/pom.xml +++ b/phenotools-cli/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenotools phenotools - 1.0.0-RC1 + 1.0.0 phenotools-cli diff --git a/phenotools-converter/pom.xml b/phenotools-converter/pom.xml index 02ec7269..760cfb89 100644 --- a/phenotools-converter/pom.xml +++ b/phenotools-converter/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenotools phenotools - 1.0.0-RC1 + 1.0.0 phenotools-converter diff --git a/phenotools-validator-core/pom.xml b/phenotools-validator-core/pom.xml index 6642f862..d524474c 100644 --- a/phenotools-validator-core/pom.xml +++ b/phenotools-validator-core/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenotools phenotools - 1.0.0-RC1 + 1.0.0 phenotools-validator-core diff --git a/pom.xml b/pom.xml index cf5d7b15..ce14ddc2 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.phenopackets.phenotools phenotools - 1.0.0-RC1 + 1.0.0 pom From f9eaa52f325b0263b2104d2a46fa30056b7683b6 Mon Sep 17 00:00:00 2001 From: Jules Jacobsen Date: Mon, 7 Feb 2022 15:36:36 +0000 Subject: [PATCH 003/155] Update version to 1.0.0 --- phenotools-builder/pom.xml | 2 +- phenotools-cli/pom.xml | 2 +- phenotools-converter/pom.xml | 2 +- phenotools-validator-core/pom.xml | 2 +- phenotools-validator-jsonschema/pom.xml | 2 +- pom.xml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/phenotools-builder/pom.xml b/phenotools-builder/pom.xml index 9e59f84c..14cde2e6 100644 --- a/phenotools-builder/pom.xml +++ b/phenotools-builder/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenotools phenotools - 1.0.0-RC1 + 1.0.0 phenotools-builder diff --git a/phenotools-cli/pom.xml b/phenotools-cli/pom.xml index 0efe8dad..deb828ae 100644 --- a/phenotools-cli/pom.xml +++ b/phenotools-cli/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenotools phenotools - 1.0.0-RC1 + 1.0.0 phenotools-cli diff --git a/phenotools-converter/pom.xml b/phenotools-converter/pom.xml index 02ec7269..760cfb89 100644 --- a/phenotools-converter/pom.xml +++ b/phenotools-converter/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenotools phenotools - 1.0.0-RC1 + 1.0.0 phenotools-converter diff --git a/phenotools-validator-core/pom.xml b/phenotools-validator-core/pom.xml index 6642f862..d524474c 100644 --- a/phenotools-validator-core/pom.xml +++ b/phenotools-validator-core/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenotools phenotools - 1.0.0-RC1 + 1.0.0 phenotools-validator-core diff --git a/phenotools-validator-jsonschema/pom.xml b/phenotools-validator-jsonschema/pom.xml index b37ddc47..6d2ffe4a 100644 --- a/phenotools-validator-jsonschema/pom.xml +++ b/phenotools-validator-jsonschema/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenotools phenotools - 1.0.0-RC1 + 1.0.0 phenotools-validator-jsonschema diff --git a/pom.xml b/pom.xml index cf5d7b15..ce14ddc2 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.phenopackets.phenotools phenotools - 1.0.0-RC1 + 1.0.0 pom From ad58f4e321b8a559ee731b8d81b538ab27bcbddb Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Wed, 13 Apr 2022 13:20:05 -0400 Subject: [PATCH 004/155] moving classes to new constants package --- .../builder/builders/PhenotypicFeatureBuilder.java | 1 + .../phenotools/builder/builders/TimeElements.java | 5 +++-- .../builder/builders/{ => constants}/Laterality.java | 3 ++- .../phenotools/builder/builders/{ => constants}/Onset.java | 2 +- .../builder/builders/{ => constants}/Severity.java | 2 +- .../phenotools/builder/builders/{ => constants}/Status.java | 2 +- .../phenotools/builder/builders/{ => constants}/Unit.java | 2 +- .../phenotools/builder/builders/DiagnosisBuilderTest.java | 1 + .../phenopackets/phenotools/examples/BethlehamMyopathy.java | 1 + .../org/phenopackets/phenotools/examples/Retinoblastoma.java | 2 ++ .../phenopackets/phenotools/examples/Thrombocytopenia2.java | 1 + 11 files changed, 15 insertions(+), 7 deletions(-) rename phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/{ => constants}/Laterality.java (86%) rename phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/{ => constants}/Onset.java (97%) rename phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/{ => constants}/Severity.java (96%) rename phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/{ => constants}/Status.java (97%) rename phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/{ => constants}/Unit.java (93%) diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PhenotypicFeatureBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PhenotypicFeatureBuilder.java index 842ad813..fb4abc4c 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PhenotypicFeatureBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PhenotypicFeatureBuilder.java @@ -1,5 +1,6 @@ package org.phenopackets.phenotools.builder.builders; +import org.phenopackets.phenotools.builder.builders.constants.Severity; import org.phenopackets.schema.v2.core.Evidence; import org.phenopackets.schema.v2.core.OntologyClass; import org.phenopackets.schema.v2.core.PhenotypicFeature; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimeElements.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimeElements.java index 3b88ca2e..f688a037 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimeElements.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimeElements.java @@ -1,12 +1,13 @@ package org.phenopackets.phenotools.builder.builders; import com.google.protobuf.Timestamp; +import org.phenopackets.phenotools.builder.builders.constants.Onset; import org.phenopackets.schema.v2.core.*; import java.time.Instant; -import static org.phenopackets.phenotools.builder.builders.Onset.late; -import static org.phenopackets.phenotools.builder.builders.Onset.middleAge; +import static org.phenopackets.phenotools.builder.builders.constants.Onset.late; +import static org.phenopackets.phenotools.builder.builders.constants.Onset.middleAge; /** * The TimeElement is used in many places in the Phenopacket. It is defined as being one of the diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Laterality.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Laterality.java similarity index 86% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Laterality.java rename to phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Laterality.java index 3c12cf4b..def91ce2 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Laterality.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Laterality.java @@ -1,5 +1,6 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenotools.builder.builders.constants; +import org.phenopackets.phenotools.builder.builders.OntologyClassBuilder; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Onset.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Onset.java similarity index 97% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Onset.java rename to phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Onset.java index 6de53cb7..a4008c99 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Onset.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Onset.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenotools.builder.builders.constants; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Severity.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Severity.java similarity index 96% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Severity.java rename to phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Severity.java index 5c0fd5f2..d7d93954 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Severity.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Severity.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenotools.builder.builders.constants; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Status.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Status.java similarity index 97% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Status.java rename to phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Status.java index b8fc6b97..0b52ed85 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Status.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Status.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenotools.builder.builders.constants; import org.phenopackets.schema.v2.core.AcmgPathogenicityClassification; import org.phenopackets.schema.v2.core.GenomicInterpretation.InterpretationStatus; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Unit.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Unit.java similarity index 93% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Unit.java rename to phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Unit.java index ee97647f..86330e9b 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Unit.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Unit.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenotools.builder.builders.constants; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilderTest.java b/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilderTest.java index 83db8c1b..09cb6391 100644 --- a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilderTest.java +++ b/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilderTest.java @@ -1,6 +1,7 @@ package org.phenopackets.phenotools.builder.builders; import org.junit.jupiter.api.Test; +import org.phenopackets.phenotools.builder.builders.constants.Status; import org.phenopackets.schema.v2.core.Diagnosis; import org.phenopackets.schema.v2.core.GenomicInterpretation; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/BethlehamMyopathy.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/BethlehamMyopathy.java index adbebcaa..4e73d232 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/BethlehamMyopathy.java +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/BethlehamMyopathy.java @@ -3,6 +3,7 @@ import org.phenopackets.phenotools.builder.PhenopacketBuilder; import org.phenopackets.phenotools.builder.builders.*; +import org.phenopackets.phenotools.builder.builders.constants.Status; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Retinoblastoma.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Retinoblastoma.java index 9d9e98ee..ab2f36d0 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Retinoblastoma.java +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Retinoblastoma.java @@ -4,6 +4,8 @@ import org.ga4gh.vrsatile.v1.GeneDescriptor; import org.phenopackets.phenotools.builder.PhenopacketBuilder; import org.phenopackets.phenotools.builder.builders.*; +import org.phenopackets.phenotools.builder.builders.constants.Laterality; +import org.phenopackets.phenotools.builder.builders.constants.Unit; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Thrombocytopenia2.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Thrombocytopenia2.java index 6f213ecd..931d66ba 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Thrombocytopenia2.java +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Thrombocytopenia2.java @@ -2,6 +2,7 @@ import org.phenopackets.phenotools.builder.PhenopacketBuilder; import org.phenopackets.phenotools.builder.builders.*; +import org.phenopackets.phenotools.builder.builders.constants.Status; import org.phenopackets.schema.v2.Phenopacket; import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; From 7a9d93844f874209263ed365d7662d5b1ae43dd0 Mon Sep 17 00:00:00 2001 From: Jules Jacobsen Date: Thu, 14 Apr 2022 11:53:47 +0100 Subject: [PATCH 005/155] Update builder methods which add to a list with 'add' prefix. Move constants package up a level Update InterpretationBuilder API to become a state machine. Add back lost VRS sequenceId in NemalineMyopathyPrenatal example. --- .../builder/PhenopacketBuilder.java | 6 + .../builder/builders/BiosampleBuilder.java | 5 + .../builder/builders/DiagnosisBuilder.java | 2 +- .../builder/builders/DiseaseBuilder.java | 4 +- .../builder/builders/FileBuilder.java | 7 + .../builders/GeneDescriptorBuilder.java | 6 +- .../GenomicInterpretationBuilder.java | 2 +- .../builder/builders/IndividualBuilder.java | 4 +- .../builders/InterpretationBuilder.java | 47 ++++--- .../builders/MedicalActionBuilder.java | 2 +- .../builder/builders/MetaDataBuilder.java | 11 +- .../builder/builders/PedigreeBuilder.java | 2 +- .../builder/builders/PersonBuilder.java | 32 ++--- .../builders/PhenotypicFeatureBuilder.java | 19 ++- .../builder/builders/TimeElements.java | 8 +- .../builder/builders/TreatmentBuilder.java | 4 +- .../builders/VariationDescriptorBuilder.java | 31 ++--- .../{builders => }/constants/Laterality.java | 2 +- .../{builders => }/constants/Onset.java | 2 +- .../{builders => }/constants/Severity.java | 2 +- .../{builders => }/constants/Status.java | 2 +- .../{builders => }/constants/Unit.java | 2 +- .../builders/DiagnosisBuilderTest.java | 4 +- .../examples/BethlehamMyopathy.java | 35 +++-- .../phenotools/examples/Covid.java | 16 +-- .../examples/FamilyWithPedigree.java | 4 +- .../phenotools/examples/Marfan.java | 4 +- .../examples/NemalineMyopathyPrenatal.java | 129 ++++++++---------- .../phenotools/examples/Retinoblastoma.java | 99 ++++++-------- .../examples/SquamousCellCancer.java | 14 +- .../examples/Thrombocytopenia2.java | 17 ++- .../phenotools/examples/UrothelialCancer.java | 23 ++-- .../examples/WarburgMicroSyndrome.java | 4 +- 33 files changed, 270 insertions(+), 281 deletions(-) rename phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/{builders => }/constants/Laterality.java (93%) rename phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/{builders => }/constants/Onset.java (97%) rename phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/{builders => }/constants/Severity.java (96%) rename phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/{builders => }/constants/Status.java (97%) rename phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/{builders => }/constants/Unit.java (93%) diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/PhenopacketBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/PhenopacketBuilder.java index c9aac5ee..f5ef9c57 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/PhenopacketBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/PhenopacketBuilder.java @@ -1,5 +1,6 @@ package org.phenopackets.phenotools.builder; +import org.phenopackets.phenotools.builder.builders.PhenotypicFeatureBuilder; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; @@ -22,6 +23,11 @@ public PhenopacketBuilder individual(Individual subject) { return this; } + public PhenopacketBuilder addPhenotypicFeature(String id, String label) { + PhenotypicFeature phenotypicFeature = PhenotypicFeatureBuilder.phenotypicFeature(id, label); + return addPhenotypicFeature(phenotypicFeature); + } + public PhenopacketBuilder addPhenotypicFeature(PhenotypicFeature feature) { builder.addPhenotypicFeatures(feature); return this; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/BiosampleBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/BiosampleBuilder.java index 6373769f..37fa70cb 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/BiosampleBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/BiosampleBuilder.java @@ -41,6 +41,11 @@ public BiosampleBuilder sampledType(OntologyClass tissue) { return this; } + public BiosampleBuilder addPhenotypicFeature(String id, String label) { + PhenotypicFeature phenotypicFeature = PhenotypicFeatureBuilder.phenotypicFeature(id, label); + return addPhenotypicFeature(phenotypicFeature); + } + public BiosampleBuilder addPhenotypicFeature(PhenotypicFeature feature) { builder.addPhenotypicFeatures(feature); return this; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilder.java index fd4cecac..7a799b40 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilder.java @@ -12,7 +12,7 @@ private DiagnosisBuilder(OntologyClass disease) { builder = Diagnosis.newBuilder().setDisease(disease); } - public DiagnosisBuilder genomicInterpretation(GenomicInterpretation interpretation) { + public DiagnosisBuilder addGenomicInterpretation(GenomicInterpretation interpretation) { builder.addGenomicInterpretations(interpretation); return this; } diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DiseaseBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DiseaseBuilder.java index 579ee6b2..c28e5fa7 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DiseaseBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DiseaseBuilder.java @@ -45,12 +45,12 @@ public DiseaseBuilder resolution(TimeElement timeElement) { return this; } - public DiseaseBuilder diseaseStage(OntologyClass stage) { + public DiseaseBuilder addDiseaseStage(OntologyClass stage) { builder.addDiseaseStage(stage); return this; } - public DiseaseBuilder clinicalTnmFinding(OntologyClass tnmFinding) { + public DiseaseBuilder addClinicalTnmFinding(OntologyClass tnmFinding) { builder.addClinicalTnmFinding(tnmFinding); return this; } diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/FileBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/FileBuilder.java index 99aaa511..d6fe7c03 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/FileBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/FileBuilder.java @@ -2,6 +2,8 @@ import org.phenopackets.schema.v2.core.File; +import java.util.Map; + public class FileBuilder { private final File.Builder builder; @@ -23,6 +25,11 @@ public FileBuilder addFileAttribute(String k, String v) { return this; } + public FileBuilder addAllFileAttributes(Map values) { + builder.putAllFileAttributes(values); + return this; + } + public FileBuilder individualToFileIdentifier(String individual, String fileIdentifier) { builder.putIndividualToFileIdentifiers(individual, fileIdentifier); return this; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/GeneDescriptorBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/GeneDescriptorBuilder.java index 5d46840d..98576fb1 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/GeneDescriptorBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/GeneDescriptorBuilder.java @@ -25,7 +25,7 @@ public GeneDescriptorBuilder description(String desc) { return this; } - public GeneDescriptorBuilder alternateId(String altId) { + public GeneDescriptorBuilder addAlternateId(String altId) { builder.addAlternateIds(altId); return this; } @@ -35,7 +35,7 @@ public GeneDescriptorBuilder addAllAlternateIds(List altIds) { return this; } - public GeneDescriptorBuilder xref(String xref) { + public GeneDescriptorBuilder addXref(String xref) { builder.addXrefs(xref); return this; } @@ -45,7 +45,7 @@ public GeneDescriptorBuilder addAllXrefs(List xrefs) { return this; } - public GeneDescriptorBuilder alternateSymbol(String altSymbol) { + public GeneDescriptorBuilder addAlternateSymbol(String altSymbol) { builder.addAlternateSymbols(altSymbol); return this; } diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/GenomicInterpretationBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/GenomicInterpretationBuilder.java index 2d299480..ca224fd2 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/GenomicInterpretationBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/GenomicInterpretationBuilder.java @@ -44,7 +44,7 @@ public GenomicInterpretationBuilder unknown() { return this; } - public GenomicInterpretationBuilder geneDescriptor( GeneDescriptor geneDescriptor) { + public GenomicInterpretationBuilder geneDescriptor(GeneDescriptor geneDescriptor) { builder.setGene(geneDescriptor); return this; } diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/IndividualBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/IndividualBuilder.java index 21db04a8..25593a87 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/IndividualBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/IndividualBuilder.java @@ -37,12 +37,12 @@ public static IndividualBuilder builder(String id) { return new IndividualBuilder(id); } - public IndividualBuilder alternateId(String altId) { + public IndividualBuilder addAlternateId(String altId) { builder.addAlternateIds(altId); return this; } - public IndividualBuilder alternateId(List altIdList) { + public IndividualBuilder addAllAlternateIds(List altIdList) { builder.addAllAlternateIds(altIdList); return this; } diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/InterpretationBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/InterpretationBuilder.java index 834ea004..c32dea86 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/InterpretationBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/InterpretationBuilder.java @@ -11,44 +11,49 @@ private InterpretationBuilder(String interpretationId, Interpretation.ProgressSt builder = Interpretation.newBuilder().setId(interpretationId).setProgressStatus(status); } - public static Interpretation interpretation(String interpretationId, Interpretation.ProgressStatus status, Diagnosis dx, String summary) { - return Interpretation.newBuilder().setId(interpretationId).setProgressStatus(status).setDiagnosis(dx).setSummary(summary).build(); + public static Interpretation interpretation(String interpretationId, Interpretation.ProgressStatus status, Diagnosis diagnosis, String summary) { + return Interpretation.newBuilder().setId(interpretationId).setProgressStatus(status).setDiagnosis(diagnosis).setSummary(summary).build(); } - public static InterpretationBuilder builder(String interpretationId, Interpretation.ProgressStatus status) { - return new InterpretationBuilder(interpretationId, status); + public static InterpretationBuilder builder(String interpretationId) { + return new InterpretationBuilder(interpretationId, Interpretation.ProgressStatus.UNKNOWN_PROGRESS); } +// public static InterpretationBuilder builder(String interpretationId, Interpretation.ProgressStatus status) { +// return new InterpretationBuilder(interpretationId, status); +// } public InterpretationBuilder summary(String summary) { builder.setSummary(summary); return this; } +// +// public InterpretationBuilder diagnosis(Diagnosis diagnosis) { +// builder.setDiagnosis(diagnosis); +// return this; +// } - public InterpretationBuilder diagnosis(Diagnosis diagnosis) { - builder.setDiagnosis(diagnosis); - return this; - } - - public static InterpretationBuilder inProgress(String interpretationId) { - return builder(interpretationId, Interpretation.ProgressStatus.IN_PROGRESS); - } - - public static InterpretationBuilder completed(String interpretationId) { - return builder(interpretationId, Interpretation.ProgressStatus.COMPLETED); + public Interpretation inProgress() { + builder.setProgressStatus(Interpretation.ProgressStatus.IN_PROGRESS); + return builder.build(); } - public static InterpretationBuilder solved(String interpretationId) { - return builder(interpretationId, Interpretation.ProgressStatus.SOLVED); + public Interpretation completed(Diagnosis diagnosis) { + builder.setProgressStatus(Interpretation.ProgressStatus.COMPLETED); + builder.setDiagnosis(diagnosis); + return builder.build(); } - public static InterpretationBuilder unsolved(String interpretationId) { - return builder(interpretationId, Interpretation.ProgressStatus.UNSOLVED); + public Interpretation solved(Diagnosis diagnosis) { + builder.setProgressStatus(Interpretation.ProgressStatus.SOLVED); + builder.setDiagnosis(diagnosis); + return builder.build(); } - public Interpretation build() { + public Interpretation unsolved() { + builder.setProgressStatus(Interpretation.ProgressStatus.UNSOLVED); + builder.clearDiagnosis(); return builder.build(); } - } diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MedicalActionBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MedicalActionBuilder.java index e256f9c4..cf95add2 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MedicalActionBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MedicalActionBuilder.java @@ -71,7 +71,7 @@ public MedicalActionBuilder responseToTreatment(OntologyClass response) { return this; } - public MedicalActionBuilder adverseEvent(OntologyClass event) { + public MedicalActionBuilder addAdverseEvent(OntologyClass event) { builder.addAdverseEvents(event); return this; } diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MetaDataBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MetaDataBuilder.java index 28979fee..73632fbf 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MetaDataBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MetaDataBuilder.java @@ -29,25 +29,24 @@ public MetaDataBuilder submittedBy(String submitter) { return this; } - public MetaDataBuilder resource(Resource r) { + public MetaDataBuilder addResource(Resource r) { builder.addResources(r); return this; } - public MetaDataBuilder update(Update u) { + public MetaDataBuilder addUpdate(Update u) { builder.addUpdates(u); return this; } - public MetaDataBuilder externalReference(ExternalReference er) { + public MetaDataBuilder addExternalReference(ExternalReference er) { builder.addExternalReferences(er); return this; } - public MetaDataBuilder externalReference(String id, String description) { + public MetaDataBuilder addExternalReference(String id, String description) { ExternalReference er = ExternalReference.newBuilder().setId(id).setDescription(description).build(); - builder.addExternalReferences(er); - return this; + return addExternalReference(er); } public MetaData build() { diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PedigreeBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PedigreeBuilder.java index 36b06d4a..c708ced3 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PedigreeBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PedigreeBuilder.java @@ -13,7 +13,7 @@ public PedigreeBuilder() { builder = Pedigree.newBuilder(); } - public PedigreeBuilder person(Pedigree.Person person) { + public PedigreeBuilder addPerson(Pedigree.Person person) { builder.addPersons(person); return this; } diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PersonBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PersonBuilder.java index d083d86b..317862c7 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PersonBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PersonBuilder.java @@ -9,15 +9,15 @@ public class PersonBuilder { private final org.phenopackets.schema.v2.core.Pedigree.Person.Builder builder; - private PersonBuilder(String family_id, - String individual_id, - String paternal_id, - String maternal_id) { + private PersonBuilder(String familyId, + String individualId, + String paternalId, + String maternalId) { builder = Pedigree.Person.newBuilder(); - builder.setFamilyId(family_id); - builder.setIndividualId(individual_id); - builder.setPaternalId(paternal_id); - builder.setMaternalId(maternal_id); + builder.setFamilyId(familyId); + builder.setIndividualId(individualId); + builder.setPaternalId(paternalId); + builder.setMaternalId(maternalId); } public PersonBuilder male() { @@ -50,21 +50,19 @@ public PersonBuilder missing() { return this; } - - public static PersonBuilder builder(String family_id, - String individual_id, - String paternal_id, - String maternal_id) { - return new PersonBuilder(family_id, individual_id, paternal_id, maternal_id); + public static PersonBuilder builder(String familyId, + String individualId, + String paternalId, + String maternalId) { + return new PersonBuilder(familyId, individualId, paternalId, maternalId); } /** * Founders are persons in a PED file whose parents are not included. These parents are * indicated by "0". This function creates a personBuilder with prepopulated father/mother ids of "0" */ - public static PersonBuilder builderWithParentsAsFounders(String family_id, - String individual_id) { - return new PersonBuilder(family_id, individual_id, + public static PersonBuilder builderWithParentsAsFounders(String familyId, String individualId) { + return new PersonBuilder(familyId, individualId, parental_id_not_available, parental_id_not_available); } diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PhenotypicFeatureBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PhenotypicFeatureBuilder.java index fb4abc4c..2ffe1ddf 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PhenotypicFeatureBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PhenotypicFeatureBuilder.java @@ -1,6 +1,5 @@ package org.phenopackets.phenotools.builder.builders; -import org.phenopackets.phenotools.builder.builders.constants.Severity; import org.phenopackets.schema.v2.core.Evidence; import org.phenopackets.schema.v2.core.OntologyClass; import org.phenopackets.schema.v2.core.PhenotypicFeature; @@ -83,12 +82,12 @@ public PhenotypicFeatureBuilder adultOnset() { public PhenotypicFeatureBuilder severity(String id, String label) { OntologyClass severity = OntologyClassBuilder.ontologyClass(id, label); - builder.setSeverity(severity); - return this; + return severity(severity); + } - public PhenotypicFeatureBuilder severe() { - builder.setSeverity(Severity.severe()); + public PhenotypicFeatureBuilder severity(OntologyClass severity) { + builder.setSeverity(severity); return this; } @@ -97,22 +96,22 @@ public PhenotypicFeatureBuilder excluded() { return this; } - public PhenotypicFeatureBuilder evidence(Evidence evidence) { + public PhenotypicFeatureBuilder addEvidence(Evidence evidence) { builder.addEvidence(evidence); return this; } - public PhenotypicFeatureBuilder allEvidence(List evidenceList) { + public PhenotypicFeatureBuilder addAllEvidence(List evidenceList) { builder.addAllEvidence(evidenceList); return this; } - public PhenotypicFeatureBuilder modifier(OntologyClass clz) { - builder.addModifiers(clz); + public PhenotypicFeatureBuilder addModifier(OntologyClass modifier) { + builder.addModifiers(modifier); return this; } - public PhenotypicFeatureBuilder allModifiers(List modifiers) { + public PhenotypicFeatureBuilder addAllModifiers(List modifiers) { builder.addAllModifiers(modifiers); return this; } diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimeElements.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimeElements.java index f688a037..7d58d55f 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimeElements.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimeElements.java @@ -1,13 +1,11 @@ package org.phenopackets.phenotools.builder.builders; import com.google.protobuf.Timestamp; -import org.phenopackets.phenotools.builder.builders.constants.Onset; +import org.phenopackets.phenotools.builder.constants.Onset; import org.phenopackets.schema.v2.core.*; import java.time.Instant; -import static org.phenopackets.phenotools.builder.builders.constants.Onset.late; -import static org.phenopackets.phenotools.builder.builders.constants.Onset.middleAge; /** * The TimeElement is used in many places in the Phenopacket. It is defined as being one of the @@ -34,8 +32,8 @@ public class TimeElements { private static final TimeElement JUVENILE_ONSET = TimeElement.newBuilder().setOntologyClass(Onset.juvenile()).build(); private static final TimeElement INFANTILE_ONSET = TimeElement.newBuilder().setOntologyClass(Onset.infantile()).build(); private static final TimeElement ADULT_ONSET = TimeElement.newBuilder().setOntologyClass(Onset.adult()).build(); - private static final TimeElement LATE_ONSET = TimeElement.newBuilder().setOntologyClass(late()).build(); - private static final TimeElement MIDDLE_AGE_ONSET = TimeElement.newBuilder().setOntologyClass(middleAge()).build(); + private static final TimeElement LATE_ONSET = TimeElement.newBuilder().setOntologyClass(Onset.late()).build(); + private static final TimeElement MIDDLE_AGE_ONSET = TimeElement.newBuilder().setOntologyClass(Onset.middleAge()).build(); private static final TimeElement YOUNG_ADULT_ONSET = TimeElement.newBuilder().setOntologyClass(Onset.youngAdult()).build(); private TimeElements() { diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TreatmentBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TreatmentBuilder.java index 28a0ba64..744b9b66 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TreatmentBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TreatmentBuilder.java @@ -33,12 +33,12 @@ public TreatmentBuilder routeOfAdministration(OntologyClass route) { return this; } - public TreatmentBuilder doseInterval(DoseInterval interval) { + public TreatmentBuilder addDoseInterval(DoseInterval interval) { builder.addDoseIntervals(interval); return this; } - public TreatmentBuilder allDoseIntervals(List intervals) { + public TreatmentBuilder addAllDoseIntervals(List intervals) { builder.addAllDoseIntervals(intervals); return this; } diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VariationDescriptorBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VariationDescriptorBuilder.java index 60fd9c9a..f38ace0a 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VariationDescriptorBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VariationDescriptorBuilder.java @@ -24,6 +24,14 @@ private VariationDescriptorBuilder(String id) { builder = VariationDescriptor.newBuilder().setId(id); } + public static VariationDescriptorBuilder builder() { + return new VariationDescriptorBuilder(); + } + + public static VariationDescriptorBuilder builder(String variantId) { + return new VariationDescriptorBuilder(variantId); + } + public VariationDescriptorBuilder label(String lbl) { builder.setLabel(lbl); return this; @@ -44,12 +52,12 @@ public VariationDescriptorBuilder geneContext(GeneDescriptor gene) { return this; } - public VariationDescriptorBuilder vcfVecord(VcfRecord vcf) { + public VariationDescriptorBuilder vcfRecord(VcfRecord vcf) { builder.setVcfRecord(vcf); return this; } - public VariationDescriptorBuilder xref(String xref) { + public VariationDescriptorBuilder addXref(String xref) { builder.addXrefs(xref); return this; } @@ -59,7 +67,7 @@ public VariationDescriptorBuilder addAllXrefs(List xrefs) { return this; } - public VariationDescriptorBuilder alternateLabels(String altLabel) { + public VariationDescriptorBuilder addAlternateLabel(String altLabel) { builder.addAlternateLabels(altLabel); return this; } @@ -85,8 +93,8 @@ public VariationDescriptorBuilder transcript() { } - public VariationDescriptorBuilder structuralType(OntologyClass clz) { - builder.setStructuralType(clz); + public VariationDescriptorBuilder structuralType(OntologyClass structuralType) { + builder.setStructuralType(structuralType); return this; } @@ -135,7 +143,7 @@ public VariationDescriptorBuilder iscn(String value) { return this; } - public VariationDescriptorBuilder expression(Expression expression) { + public VariationDescriptorBuilder addExpression(Expression expression) { builder.addExpressions(expression); return this; } @@ -158,8 +166,7 @@ public VariationDescriptorBuilder vcfHg37(String chromosome, int position, Strin * @param percentage estimated percentage of cells affected by mosaic variant, e.g., 40% */ public VariationDescriptorBuilder mosaicism(double percentage) { - Extension expression = - Extensions.mosaicism(percentage); + Extension expression = Extensions.mosaicism(percentage); builder.addExtensions(expression); return this; } @@ -178,12 +185,4 @@ public VariationDescriptorBuilder alleleFrequency(double percentage) { public VariationDescriptor build() { return builder.build(); } - - public static VariationDescriptorBuilder builder(String variantId) { - return new VariationDescriptorBuilder(variantId); - } - - public static VariationDescriptorBuilder builder() { - return new VariationDescriptorBuilder(); - } } diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Laterality.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Laterality.java similarity index 93% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Laterality.java rename to phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Laterality.java index def91ce2..02413281 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Laterality.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Laterality.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders.constants; +package org.phenopackets.phenotools.builder.constants; import org.phenopackets.phenotools.builder.builders.OntologyClassBuilder; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Onset.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Onset.java similarity index 97% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Onset.java rename to phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Onset.java index a4008c99..e9ffc9fe 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Onset.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Onset.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders.constants; +package org.phenopackets.phenotools.builder.constants; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Severity.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Severity.java similarity index 96% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Severity.java rename to phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Severity.java index d7d93954..35594d5e 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Severity.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Severity.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders.constants; +package org.phenopackets.phenotools.builder.constants; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Status.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Status.java similarity index 97% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Status.java rename to phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Status.java index 0b52ed85..fec4d29b 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Status.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Status.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders.constants; +package org.phenopackets.phenotools.builder.constants; import org.phenopackets.schema.v2.core.AcmgPathogenicityClassification; import org.phenopackets.schema.v2.core.GenomicInterpretation.InterpretationStatus; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Unit.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Unit.java similarity index 93% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Unit.java rename to phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Unit.java index 86330e9b..e0cbeedb 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Unit.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Unit.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders.constants; +package org.phenopackets.phenotools.builder.constants; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilderTest.java b/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilderTest.java index 09cb6391..196a55be 100644 --- a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilderTest.java +++ b/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilderTest.java @@ -1,7 +1,7 @@ package org.phenopackets.phenotools.builder.builders; import org.junit.jupiter.api.Test; -import org.phenopackets.phenotools.builder.builders.constants.Status; +import org.phenopackets.phenotools.builder.constants.Status; import org.phenopackets.schema.v2.core.Diagnosis; import org.phenopackets.schema.v2.core.GenomicInterpretation; @@ -27,7 +27,7 @@ void testDiagnosisBuilder() { var expectedGenomicInterpretation = genomicInterpretationBuilder.build(); var thrombocytopenia2 = ontologyClass("OMIM:188000", "Thrombocytopenia 2"); Diagnosis diagnosis = DiagnosisBuilder.builder(thrombocytopenia2). - genomicInterpretation(expectedGenomicInterpretation) + addGenomicInterpretation(expectedGenomicInterpretation) .build(); assertThat(diagnosis.getDisease(), equalTo(thrombocytopenia2)); assertEquals(1, diagnosis.getGenomicInterpretationsCount()); diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/BethlehamMyopathy.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/BethlehamMyopathy.java index 4e73d232..c66ee81a 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/BethlehamMyopathy.java +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/BethlehamMyopathy.java @@ -3,9 +3,8 @@ import org.phenopackets.phenotools.builder.PhenopacketBuilder; import org.phenopackets.phenotools.builder.builders.*; -import org.phenopackets.phenotools.builder.builders.constants.Status; +import org.phenopackets.phenotools.builder.constants.Status; import org.phenopackets.schema.v2.Phenopacket; -import org.phenopackets.schema.v2.core.*; import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; @@ -21,9 +20,9 @@ class BethlehamMyopathy implements PhenopacketExample { var bethlehamMyopathy = ontologyClass("OMIM:158810", "Bethlem myopathy 1"); var individual = IndividualBuilder.builder(PROBAND_ID).male().ageAtLastEncounter("P6Y3M").build(); var metaData = MetaDataBuilder.builder("2021-05-14T10:35:00Z", "anonymous biocurator") - .resource(Resources.hpoVersion("2021-08-02")) - .resource(Resources.genoVersion("2020-03-08")) - .externalReference(authorAssertion.getReference()) + .addResource(Resources.hpoVersion("2021-08-02")) + .addResource(Resources.genoVersion("2020-03-08")) + .addExternalReference(authorAssertion.getReference()) .build(); var variationDescriptor = VariationDescriptorBuilder.builder("variant id") @@ -36,56 +35,54 @@ class BethlehamMyopathy implements PhenopacketExample { GenomicInterpretationBuilder.builder(INTERPRETATION_ID) .causative() .variantInterpretation(col6a1VariantInterpretation).build(); - var diagnosis = Diagnosis.newBuilder() - .setDisease(bethlehamMyopathy).addGenomicInterpretations(genomicInterpretation).build(); - var interpretation = InterpretationBuilder.builder(INTERPRETATION_ID, Status.completed()) - .diagnosis(diagnosis).build(); + var diagnosis = DiagnosisBuilder.builder(bethlehamMyopathy).addGenomicInterpretation(genomicInterpretation).build(); + var interpretation = InterpretationBuilder.builder(INTERPRETATION_ID).completed(diagnosis); var ventricularSeptalDefect = PhenotypicFeatureBuilder.builder("HP:0001629", "Ventricular septal defect") .congenitalOnset() - .evidence(authorAssertion) + .addEvidence(authorAssertion) .build(); var coarseFacial = PhenotypicFeatureBuilder.builder("HP:0000280", "Coarse facial features") - .evidence(authorAssertion) + .addEvidence(authorAssertion) .build(); var cryptorchidism = PhenotypicFeatureBuilder.builder("HP:0008689", "Bilateral cryptorchidism") .congenitalOnset() - .evidence(authorAssertion) + .addEvidence(authorAssertion) .build(); var polyhydramnios = PhenotypicFeatureBuilder.builder("HP:0001561", "Polyhydramnios") .fetalOnset() - .evidence(authorAssertion) + .addEvidence(authorAssertion) .build(); var micropenis = PhenotypicFeatureBuilder.builder("HP:0000054", "Micropenis") .congenitalOnset() - .evidence(authorAssertion) + .addEvidence(authorAssertion) .build(); var anonychia = PhenotypicFeatureBuilder.builder("HP:0001798", "Anonychia") .congenitalOnset() - .evidence(authorAssertion) + .addEvidence(authorAssertion) .build(); var vermisHypoplasia = PhenotypicFeatureBuilder.builder("HP:0001320", "Cerebellar vermis hypoplasia") - .evidence(authorAssertion) + .addEvidence(authorAssertion) .build(); var cataract = PhenotypicFeatureBuilder.builder("HP:0000518", "Cataract") .infantileOnset() - .evidence(authorAssertion) + .addEvidence(authorAssertion) .build(); var dilatedFourthVentricle = PhenotypicFeatureBuilder.builder("HP:0002198", "Dilated fourth ventricle") - .evidence(authorAssertion) + .addEvidence(authorAssertion) .build(); var unilateralCleftLip = PhenotypicFeatureBuilder.builder("HP:0100333", "Unilateral cleft lip") .congenitalOnset() - .evidence(authorAssertion) + .addEvidence(authorAssertion) .build(); phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metaData) .individual(individual) diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Covid.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Covid.java index 9cc3ca41..65bee335 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Covid.java +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Covid.java @@ -52,9 +52,9 @@ class Covid implements PhenopacketExample { .description("The Imperfect Cytokine Storm: Severe COVID-19 With ARDS in a Patient on Durable LVAD Support") .build(); var metaData = MetaDataBuilder.builder("2021-08-17T00:00:00Z", "anonymous biocurator") - .resource(Resources.ncitVersion("2019-11-26")) - .resource(Resources.mondoVersion("2021-11-26")) - .externalReference(externalRef) + .addResource(Resources.ncitVersion("2019-11-26")) + .addResource(Resources.mondoVersion("2021-11-26")) + .addExternalReference(externalRef) .build(); @@ -155,8 +155,8 @@ private MedicalAction nasalOxygenAdministered() { TimeIntervalBuilder.timeInterval("2021-02-02T08:22:42Z", "2021-02-02T12:22:42Z")); Treatment nasalOxygen = TreatmentBuilder.builder("NCIT:C722", "Oxygen") .routeOfAdministration(ontologyClass("NCIT:C38284", "Nasal Route of Administration")) - .doseInterval(interval1) - .doseInterval(interval2) + .addDoseInterval(interval1) + .addDoseInterval(interval2) .build(); return MedicalActionBuilder.treatment(nasalOxygen); } @@ -178,7 +178,7 @@ private MedicalAction peepOxygenAdministered() { var doseInterval = DoseIntervalBuilder.doseInterval(quantity, CONTINUOUS, "2020-03-22", "2020-03-28"); Treatment oxygen = TreatmentBuilder.builder(ontologyClass("NCIT:C722", "Oxygen")) .routeOfAdministration(ontologyClass("NCIT:C50254", "Positive end Expiratory Pressure Valve Device")) - .doseInterval(doseInterval) + .addDoseInterval(doseInterval) .build(); return MedicalActionBuilder.treatment(oxygen); } @@ -188,7 +188,7 @@ private MedicalAction tocilizumabAdministered() { OntologyClass q4weeks = ontologyClass("NCIT:C64529", "Every Four Weeks"); var doseInterval = DoseIntervalBuilder.doseInterval(quantity, q4weeks, "2020-03-24", "2020-03-28"); var treatment = TreatmentBuilder.builder("NCIT:C84217", "Tocilizumab") - .doseInterval(doseInterval) + .addDoseInterval(doseInterval) .build(); return MedicalActionBuilder.treatment(treatment); } @@ -200,7 +200,7 @@ private MedicalAction dexamethasone() { var doseInterval = DoseIntervalBuilder.doseInterval(quantity, onceDaily, "2020-03-20", "2020-03-30"); Treatment dexa = TreatmentBuilder.builder("CHEBI:41879", "dexamethasone") - .doseInterval(doseInterval) + .addDoseInterval(doseInterval) .build(); return MedicalActionBuilder.treatment(dexa); } diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/FamilyWithPedigree.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/FamilyWithPedigree.java index a2e43a2e..e5e250f6 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/FamilyWithPedigree.java +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/FamilyWithPedigree.java @@ -45,7 +45,7 @@ public Family getFamily() { public Phenopacket proband() { String phenopacketId = "phenopacket.id.1"; var metadata = MetaDataBuilder.builder("2022-04-17T10:35:00Z", "biocurator") - .resource(Resources.hpoVersion("2022-04-15")) + .addResource(Resources.hpoVersion("2022-04-15")) .build(); Individual proband = IndividualBuilder.builder(SON_ID). ageAtLastEncounter("P10Y2M4D"). @@ -82,7 +82,7 @@ public Pedigree pedigree() { Pedigree.Person daughter1 = PersonBuilder.builder(FAMILY_ID, DAUGHTER1_ID, PATERNAL_ID, MATERNAL_ID).female().unaffected().build(); Pedigree.Person son = PersonBuilder.builder(FAMILY_ID, SON_ID, PATERNAL_ID, MATERNAL_ID).male().affected().build(); Pedigree.Person daughter2 = PersonBuilder.builder(FAMILY_ID, DAUGHTER2_ID, PATERNAL_ID, MATERNAL_ID).female().unaffected().build(); - return pbuilder.person(father).person(mother).person(daughter1).person(son).person(daughter2).build(); + return pbuilder.addPerson(father).addPerson(mother).addPerson(daughter1).addPerson(son).addPerson(daughter2).build(); } diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Marfan.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Marfan.java index 4400e699..aa419890 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Marfan.java +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Marfan.java @@ -27,12 +27,12 @@ class Marfan implements PhenopacketExample { var dosage = DoseIntervalBuilder.doseInterval(quantity, bid, interval); var losartanTreatment = TreatmentBuilder .builder(losartan) - .doseInterval(dosage) + .addDoseInterval(dosage) .routeOfAdministration(administration) .build(); var medicalAction = MedicalActionBuilder.treatment(losartanTreatment); var metaData = MetaDataBuilder.builder("2021-05-14T10:35:00Z", "anonymous biocurator") - .resource(Resources.hpoVersion("2021-08-02")) + .addResource(Resources.hpoVersion("2021-08-02")) .build(); phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metaData) .individual(individual) diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/NemalineMyopathyPrenatal.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/NemalineMyopathyPrenatal.java index 7e5cd342..126ba77d 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/NemalineMyopathyPrenatal.java +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/NemalineMyopathyPrenatal.java @@ -1,5 +1,6 @@ package org.phenopackets.phenotools.examples; +import org.ga4gh.vrs.v1.Variation; import org.ga4gh.vrsatile.v1.Expression; import org.ga4gh.vrsatile.v1.GeneDescriptor; import org.phenopackets.phenotools.builder.PhenopacketBuilder; @@ -7,10 +8,10 @@ import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; -import java.util.ArrayList; import java.util.List; import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenotools.builder.builders.PhenotypicFeatureBuilder.phenotypicFeature; import static org.phenopackets.phenotools.builder.builders.TimeElements.gestationalAge; /** @@ -22,19 +23,19 @@ class NemalineMyopathyPrenatal implements PhenopacketExample { private static final String PHENOPACKET_ID = "arbitrary.id"; private static final String PROBAND_ID = "proband A"; - private final OntologyClass nemalineMyopathy8 = ontologyClass("MONDO:0014138", "nemaline myopathy 8"); + private static final OntologyClass NEMALINE_MYOPATHY_8 = ontologyClass("MONDO:0014138", "nemaline myopathy 8"); private final Phenopacket phenopacket; NemalineMyopathyPrenatal() { var metadata = MetaDataBuilder.builder("2021-05-14T10:35:00Z", "anonymous biocurator") - .resource(Resources.ncitVersion("21.05d")) - .resource(Resources.hpoVersion("2022-02")) - .resource(Resources.mondoVersion("v2022-04-04")) - .resource(Resources.uberonVersion("2021-07-27")) + .addResource(Resources.ncitVersion("21.05d")) + .addResource(Resources.hpoVersion("2022-02")) + .addResource(Resources.mondoVersion("v2022-04-04")) + .addResource(Resources.uberonVersion("2021-07-27")) .build(); - var vitalStatus = VitalStatusBuilder.deceased().causeOfDeath(nemalineMyopathy8).build(); + var vitalStatus = VitalStatusBuilder.deceased().causeOfDeath(NEMALINE_MYOPATHY_8).build(); var individual = IndividualBuilder.builder(PROBAND_ID) .male() .ageAtLastEncounter("P1D") @@ -42,16 +43,14 @@ class NemalineMyopathyPrenatal implements PhenopacketExample { PhenopacketBuilder builder = PhenopacketBuilder.create(PHENOPACKET_ID, metadata) .individual(individual) .addPhenotypicFeature(decreasedFetalMovement()) - .addBiosample(muscleBiopsy()) - .addInterpretation(interpretation()); - - builder.addAllPhenotypicFeatures(sonography33weeks()); - builder.addAllPhenotypicFeatures(apgar()); + .addBiosample(muscleBiopsy()) + .addInterpretation(interpretation()) + .addAllPhenotypicFeatures(sonography33weeks()) + .addAllPhenotypicFeatures(apgar()); phenopacket = builder.build(); } List apgar() { - List phenotypicFeatureList = new ArrayList<>(); TimeElement newbornTime = TimeElements.congenitalOnset(); PhenotypicFeature apgar1 = PhenotypicFeatureBuilder.builder("HP:0030931", "1-minute APGAR score of 4") .onset(newbornTime).build(); @@ -63,17 +62,10 @@ List apgar() { .onset(newbornTime).build(); PhenotypicFeature generalizedHypotonia = PhenotypicFeatureBuilder.builder("HP:0001290", "Generalized hypotonia") .onset(newbornTime).build(); - - phenotypicFeatureList.add(apgar1); - phenotypicFeatureList.add(apgar5); - phenotypicFeatureList.add(apgar10); - phenotypicFeatureList.add(laryngealEdema); - phenotypicFeatureList.add(generalizedHypotonia); - return phenotypicFeatureList; + return List.of(apgar1, apgar5, apgar10, laryngealEdema, generalizedHypotonia); } List sonography33weeks() { - List phenotypicFeatureList = new ArrayList<>(); TimeElement onset = gestationalAge(32,4); OntologyClass borderline = ontologyClass("HP:0012827", "Borderline"); PhenotypicFeature edema = PhenotypicFeatureBuilder.builder("HP:0025672", "Fetal skin edema") @@ -81,43 +73,36 @@ List sonography33weeks() { PhenotypicFeature overlapping = PhenotypicFeatureBuilder.builder("HP:0010557", "Overlapping fingers") .onset(onset).build(); PhenotypicFeature polyhydram = PhenotypicFeatureBuilder.builder("HP:0001561", "Polyhydramnios") - .onset(onset).modifier(borderline).build(); - phenotypicFeatureList.add(edema); - phenotypicFeatureList.add(overlapping); - phenotypicFeatureList.add(polyhydram); - return phenotypicFeatureList; + .onset(onset).addModifier(borderline).build(); + return List.of(edema, overlapping, polyhydram); } PhenotypicFeature decreasedFetalMovement() { - PhenotypicFeatureBuilder builder = PhenotypicFeatureBuilder.builder("HP:0001558", "Decreased fetal movement"); - TimeElement onset = gestationalAge(23); - builder.onset(onset); - return builder.build(); + return PhenotypicFeatureBuilder.builder("HP:0001558", "Decreased fetal movement") + .onset(gestationalAge(23)) + .build(); } Biosample muscleBiopsy() { - String biosampleId = "biosample.1"; - BiosampleBuilder builder = BiosampleBuilder.builder(biosampleId); OntologyClass abdominalMuscle = ontologyClass("UBERON:0002378", "muscle of abdomen"); - builder.sampledTissue(abdominalMuscle); - PhenotypicFeature nemalineRods = PhenotypicFeatureBuilder.builder("HP:0003798","Nemaline bodies").build(); - builder.addPhenotypicFeature(nemalineRods); - ProcedureBuilder pbuilder = ProcedureBuilder.builder("NCIT:C51895", "Muscle Biopsy"); - TimeElement age = TimeElements.age("P1D"); - pbuilder.bodySite(abdominalMuscle).performed(age); - builder.procedure(pbuilder.build()); - return builder.build(); + Procedure muscleBiopsy = ProcedureBuilder.builder("NCIT:C51895", "Muscle Biopsy") + .bodySite(abdominalMuscle) + .performed(TimeElements.age("P1D")) + .build(); + return BiosampleBuilder.builder("biosample.1") + .sampledTissue(abdominalMuscle) + .addPhenotypicFeature("HP:0003798","Nemaline bodies") + .procedure(muscleBiopsy) + .build(); } Interpretation interpretation() { - InterpretationBuilder ibuilder = InterpretationBuilder.solved("interpretation.id"); - OntologyClass nm8 = ontologyClass("MONDO:0014138", "nemaline myopathy 8"); - DiagnosisBuilder dbuilder = DiagnosisBuilder.builder(nm8); - dbuilder.genomicInterpretation(klhl40InterpretationV1()); - dbuilder.genomicInterpretation(klhl40InterpretationV2()); - ibuilder.diagnosis(dbuilder.build()); - return ibuilder.build(); + Diagnosis diagnosis = DiagnosisBuilder.builder(NEMALINE_MYOPATHY_8) + .addGenomicInterpretation(klhl40InterpretationV1()) + .addGenomicInterpretation(klhl40InterpretationV2()) + .build(); + return InterpretationBuilder.builder("interpretation.id").solved(diagnosis); } @@ -136,23 +121,24 @@ GenomicInterpretation klhl40InterpretationV1() { // NC_000003.12:42686219:G:A // rs397509420 //HGNC:30372 - AlleleBuilder abuilder = AlleleBuilder.builder(); //abuilder.setSequenceId("ga4gh:VA.GuPzvZoansqNHPoXkQLXKo31VkTpDKsM"); - abuilder.startEnd( 42686219, 42686220); - abuilder.chromosomeLocation("chr3"); - abuilder.setAltAllele("A"); - VariationDescriptorBuilder vbuilder = VariationDescriptorBuilder.builder("rs397509420"); - vbuilder.variation(abuilder.buildVariation()); - vbuilder.genomic(); - vbuilder.heterozygous(); - vbuilder.label("NM_152393.4(KLHL40):c.602G>A (p.Trp201Ter)"); - vbuilder.transcript(); + Variation variation = AlleleBuilder.builder() + .setSequenceId("NC_000003.12") + .startEnd(42686219, 42686220) + .setAltAllele("A") + .buildVariation(); + VariationDescriptorBuilder vbuilder = VariationDescriptorBuilder.builder("rs397509420") + .variation(variation) + .genomic() + .heterozygous() + .label("NM_152393.4(KLHL40):c.602G>A (p.Trp201Ter)") + .transcript(); GeneDescriptor geneDescriptor = GeneDescriptorBuilder.builder("HGNC:30372", "KLHL40").build(); vbuilder.geneContext(geneDescriptor); Expression hgvs = Expressions.hgvsCdna("NM_152393.4(KLHL40):c.602G>A"); Expression transcriptReference = Expressions.transcriptReference("NM_152393.4"); - vbuilder.expression(hgvs); - vbuilder.expression(transcriptReference); + vbuilder.addExpression(hgvs); + vbuilder.addExpression(transcriptReference); // wrap in VariantInterpretation VariantInterpretationBuilder vibuilder = VariantInterpretationBuilder.builder(vbuilder); vibuilder.pathogenic(); @@ -174,23 +160,22 @@ GenomicInterpretation klhl40InterpretationV2() { // NC_000003.12:42688962:A:C // dbSNP: rs778022582 //HGNC:30372 - AlleleBuilder abuilder = AlleleBuilder.builder(); - //abuilder.setSequenceId("ga4gh:VA.GuPzvZoansqNHPoXkQLXKo31VkTpDKsM"); - abuilder.startEnd( 42688962, 42688963); - abuilder.chromosomeLocation("chr3"); - abuilder.setAltAllele("C"); - VariationDescriptorBuilder vbuilder = VariationDescriptorBuilder.builder("rs778022582"); - vbuilder.variation(abuilder.buildVariation()); - vbuilder.genomic(); - vbuilder.heterozygous(); - vbuilder.label("NM_152393.4(KLHL40):c.1516A>C (p.Thr506Pro)"); - vbuilder.transcript(); + AlleleBuilder abuilder = AlleleBuilder.builder() + .setSequenceId("NC_000003.12") + .startEnd( 42688962, 42688963) + .setAltAllele("C"); + VariationDescriptorBuilder vbuilder = VariationDescriptorBuilder.builder("rs778022582") + .variation(abuilder.buildVariation()) + .genomic() + .heterozygous() + .label("NM_152393.4(KLHL40):c.1516A>C (p.Thr506Pro)") + .transcript(); GeneDescriptor geneDescriptor = GeneDescriptorBuilder.builder("HGNC:30372", "KLHL40").build(); vbuilder.geneContext(geneDescriptor); Expression hgvs = Expressions.hgvsCdna("NM_152393.4(KLHL40):c.1516A>C"); Expression transcriptReference = Expressions.transcriptReference("NM_152393.4"); - vbuilder.expression(hgvs); - vbuilder.expression(transcriptReference); + vbuilder.addExpression(hgvs); + vbuilder.addExpression(transcriptReference); // wrap in VariantInterpretation VariantInterpretationBuilder vibuilder = VariantInterpretationBuilder.builder(vbuilder); vibuilder.pathogenic(); diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Retinoblastoma.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Retinoblastoma.java index ab2f36d0..9b6b0d48 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Retinoblastoma.java +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Retinoblastoma.java @@ -1,11 +1,9 @@ package org.phenopackets.phenotools.examples; -import org.ga4gh.vrsatile.v1.Expression; -import org.ga4gh.vrsatile.v1.GeneDescriptor; import org.phenopackets.phenotools.builder.PhenopacketBuilder; import org.phenopackets.phenotools.builder.builders.*; -import org.phenopackets.phenotools.builder.builders.constants.Laterality; -import org.phenopackets.phenotools.builder.builders.constants.Unit; +import org.phenopackets.phenotools.builder.constants.Laterality; +import org.phenopackets.phenotools.builder.constants.Unit; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; @@ -29,10 +27,10 @@ public class Retinoblastoma implements PhenopacketExample { private final Phenopacket phenopacket; public Retinoblastoma() { var metadata = MetaDataBuilder.builder("2021-05-14T10:35:00Z", "anonymous biocurator") - .resource(Resources.ncitVersion("21.05d")) - .resource(Resources.efoVersion("3.34.0")) - .resource(Resources.uberonVersion("2021-07-27")) - .resource(Resources.ncbiTaxonVersion("2021-06-10")) + .addResource(Resources.ncitVersion("21.05d")) + .addResource(Resources.efoVersion("3.34.0")) + .addResource(Resources.uberonVersion("2021-07-27")) + .addResource(Resources.ncbiTaxonVersion("2021-06-10")) .build(); Individual proband = IndividualBuilder.builder(PROBAND_ID). ageAtLastEncounter("P6M"). @@ -58,13 +56,11 @@ public Retinoblastoma() { Interpretation interpretation() { - InterpretationBuilder ibuilder = InterpretationBuilder.solved("interpretation.id"); - GenomicInterpretation somatic = somaticRb1Missense(); - DiagnosisBuilder dbuilder = DiagnosisBuilder.builder(RETINOBLASTOMA); - dbuilder.genomicInterpretation(somatic); - dbuilder.genomicInterpretation(germlineRb1Deletion()); - ibuilder.diagnosis(dbuilder.build()); - return ibuilder.build(); + Diagnosis diagnosis = DiagnosisBuilder.builder(RETINOBLASTOMA) + .addGenomicInterpretation(somaticRb1Missense()) + .addGenomicInterpretation(germlineRb1Deletion()) + .build(); + return InterpretationBuilder.builder("interpretation.id").solved(diagnosis); } @@ -77,20 +73,17 @@ GenomicInterpretation somaticRb1Missense() { abuilder.setSequenceId("ga4gh:VA.GuPzvZoansqNHPoXkQLXKo31VkTpDKsM"); abuilder.startEnd( 48941647, 48941648); abuilder.setAltAllele("T"); - VariationDescriptorBuilder vbuilder = VariationDescriptorBuilder.builder("rs121913300"); - vbuilder.variation(abuilder.buildVariation()) + VariationDescriptorBuilder vbuilder = VariationDescriptorBuilder.builder("rs121913300") + .variation(abuilder.buildVariation()) .genomic() .heterozygous() .label("RB1 c.958C>T (p.Arg320Ter)") - .transcript(); - vbuilder.vcfHg38("NC_000013.11", 48367512, "C", "T"); - vbuilder.alleleFrequency(25.0); - GeneDescriptor geneDescriptor = GeneDescriptorBuilder.builder("HGNC:9884", "RB1").build(); - vbuilder.geneContext(geneDescriptor); - Expression hgvs = Expressions.hgvsCdna("NM_000321.2:c.958C>T"); - Expression transcriptReference = Expressions.transcriptReference("NM_000321.2"); - vbuilder.expression(hgvs); - vbuilder.expression(transcriptReference); + .transcript() + .vcfHg38("NC_000013.11", 48367512, "C", "T") + .alleleFrequency(25.0) + .geneContext(GeneDescriptorBuilder.geneDescriptor("HGNC:9884", "RB1")) + .addExpression(Expressions.hgvsCdna("NM_000321.2:c.958C>T")) + .addExpression(Expressions.transcriptReference("NM_000321.2")); // wrap in VariantInterpretation VariantInterpretationBuilder vibuilder = VariantInterpretationBuilder.builder(vbuilder); vibuilder.pathogenic(); @@ -150,40 +143,38 @@ Pedigree pedigree() { .affected() .build(); PedigreeBuilder pbuilder = PedigreeBuilder.builder(); - pbuilder.person(father); - pbuilder.person(mother); - pbuilder.person(child); + pbuilder.addPerson(father); + pbuilder.addPerson(mother); + pbuilder.addPerson(child); return pbuilder.build(); } Biosample enucleatedEye() { TimeElement age = TimeElements.age("P8M2W"); - BiosampleBuilder builder = BiosampleBuilder.builder(BIOSAMPLE_ID); - builder.sampledTissue(EYE); + BiosampleBuilder biosampleBuilder = BiosampleBuilder.builder(BIOSAMPLE_ID); + biosampleBuilder.sampledTissue(EYE); //Retinoblastoma with tumor invading optic nerve past lamina cribrosa but not to surgical resection line and exhibiting massive choroidal invasion. - builder.addPathologicalTnmFinding(ontologyClass("NCIT:C88735", "Retinoblastoma pT3b TNM Finding v7")); + biosampleBuilder.addPathologicalTnmFinding(ontologyClass("NCIT:C88735", "Retinoblastoma pT3b TNM Finding v7")); //Retinoblastoma with no regional lymph node involvement. - builder.addPathologicalTnmFinding(ontologyClass("NCIT:C88741","Retinoblastoma pN0 TNM Finding v7")); + biosampleBuilder.addPathologicalTnmFinding(ontologyClass("NCIT:C88741","Retinoblastoma pN0 TNM Finding v7")); - // - PhenotypicFeature pfRosette = PhenotypicFeatureBuilder.phenotypicFeature("NCIT:C35941", "Flexner-Wintersteiner Rosette Formation"); - builder.addPhenotypicFeature(pfRosette); - PhenotypicFeature pfApoptosis = PhenotypicFeatureBuilder.phenotypicFeature("NCIT:C132485", "Apoptosis and Necrosis"); - builder.addPhenotypicFeature(pfApoptosis); + biosampleBuilder.addPhenotypicFeature("NCIT:C35941", "Flexner-Wintersteiner Rosette Formation"); + biosampleBuilder.addPhenotypicFeature("NCIT:C132485", "Apoptosis and Necrosis"); OntologyClass maxTumorSizeTest = OntologyClassBuilder.ontologyClass("LOINC:33728-7", "Size.maximum dimension in Tumor"); Value maxTumorSize = ValueBuilder.value(Unit.mm(), 15); Measurement maxTumorSizeMeasurement = MeasurementBuilder.value(maxTumorSizeTest, maxTumorSize).timeObserved(age).build(); - builder.addMeasurement(maxTumorSizeMeasurement); - - ProcedureBuilder pbuilder = ProcedureBuilder.builder("NCIT:C48601", "Enucleation"); + biosampleBuilder.addMeasurement(maxTumorSizeMeasurement); - pbuilder.bodySite(LEFT_EYE).performed(age); - builder.procedure(pbuilder.build()); - builder.tumorProgression(PRIMARY_NEOPLASM); + Procedure enucleation = ProcedureBuilder.builder("NCIT:C48601", "Enucleation") + .bodySite(LEFT_EYE) + .performed(age) + .build(); + biosampleBuilder.procedure(enucleation); + biosampleBuilder.tumorProgression(PRIMARY_NEOPLASM); // VCF file with results of whole-genome sequencing on this tumor File wgsFile = FileBuilder.file("file://data/fileSomaticWgs.vcf.gz"); - builder.addFile(wgsFile); - return builder.build(); + biosampleBuilder.addFile(wgsFile); + return biosampleBuilder.build(); } @@ -201,10 +192,10 @@ MedicalAction melphalan() { Treatment treatment = TreatmentBuilder.builder(melphalan) .routeOfAdministration(administration) - .doseInterval(doseInterval).build(); + .addDoseInterval(doseInterval).build(); return MedicalActionBuilder.builder(treatment) - .adverseEvent(ontologyClass("HP:0025637", "Vasospasm")) + .addAdverseEvent(ontologyClass("HP:0025637", "Vasospasm")) .treatmentTarget(RETINOBLASTOMA) .treatmentIntent(CURE) .treatmentTerminationReason(ontologyClass("NCIT:C41331", "Adverse Event")) @@ -253,8 +244,8 @@ Disease getDisease() { TimeElement age4m = TimeElements.age("P4M"); return DiseaseBuilder.builder(RETINOBLASTOMA) .onset(age4m) - .diseaseStage(stageE) - .clinicalTnmFinding(noMetastasis) + .addDiseaseStage(stageE) + .addClinicalTnmFinding(noMetastasis) .primarySite(LEFT_EYE) .build(); } @@ -266,25 +257,25 @@ List getPhenotypicFeatures() { TimeElement age3months = TimeElements.age("P3M"); PhenotypicFeature clinodactyly = PhenotypicFeatureBuilder. builder("HP:0030084", "Clinodactyly"). - modifier(Laterality.right()). + addModifier(Laterality.right()). onset(age3months). build(); TimeElement age4months = TimeElements.age("P4M"); PhenotypicFeature leukocoria = PhenotypicFeatureBuilder. builder("HP:0000555", "Leukocoria") - .modifier(Laterality.unilateral()) + .addModifier(Laterality.unilateral()) .onset(age4months) .build(); TimeElement age5months = TimeElements.age("P5M15D"); PhenotypicFeature strabismus = PhenotypicFeatureBuilder. builder("HP:0000486", "Strabismus") - .modifier(Laterality.unilateral()) + .addModifier(Laterality.unilateral()) .onset(age5months) .build(); TimeElement age6months = TimeElements.age("P6M"); PhenotypicFeature retinalDetachment = PhenotypicFeatureBuilder .builder("HP:0000541", "Retinal detachment") - .modifier(Laterality.unilateral()) + .addModifier(Laterality.unilateral()) .onset(age6months) .build(); return List.of(clinodactyly, leukocoria, strabismus, retinalDetachment); diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/SquamousCellCancer.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/SquamousCellCancer.java index ad5596e5..7915ff4b 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/SquamousCellCancer.java +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/SquamousCellCancer.java @@ -18,16 +18,16 @@ class SquamousCellCancer implements PhenopacketExample { SquamousCellCancer() { Individual proband = IndividualBuilder.builder(PROBAND_ID).male().ageAtLastEncounter("P38Y").build(); var metadata = MetaDataBuilder.builder("2021-05-14T10:35:00Z", "anonymous biocurator") - .resource(Resources.ncitVersion("21.05d")) - .resource(Resources.efoVersion("3.34.0")) - .resource(Resources.uberonVersion("2021-07-27")) - .resource(Resources.ncbiTaxonVersion("2021-06-10")) + .addResource(Resources.ncitVersion("21.05d")) + .addResource(Resources.efoVersion("3.34.0")) + .addResource(Resources.uberonVersion("2021-07-27")) + .addResource(Resources.ncbiTaxonVersion("2021-06-10")) .build(); var esophagealSCC = ontologyClass("NCIT:C4024", "Esophageal Squamous Cell Carcinoma"); var disease = DiseaseBuilder.builder(esophagealSCC) - .clinicalTnmFinding(ontologyClass("NCIT:C48724", "T2 Stage Finding")) - .clinicalTnmFinding(ontologyClass("NCIT:C48706", "N1 Stage Finding")) - .clinicalTnmFinding(ontologyClass("NCIT:C48699", "M0 Stage Finding")) + .addClinicalTnmFinding(ontologyClass("NCIT:C48724", "T2 Stage Finding")) + .addClinicalTnmFinding(ontologyClass("NCIT:C48706", "N1 Stage Finding")) + .addClinicalTnmFinding(ontologyClass("NCIT:C48699", "M0 Stage Finding")) .build(); var esophagusBiopsy = BiosampleBuilder.builder("biosample 1") .individualId(PROBAND_ID) diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Thrombocytopenia2.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Thrombocytopenia2.java index 931d66ba..44e4a917 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Thrombocytopenia2.java +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Thrombocytopenia2.java @@ -2,7 +2,7 @@ import org.phenopackets.phenotools.builder.PhenopacketBuilder; import org.phenopackets.phenotools.builder.builders.*; -import org.phenopackets.phenotools.builder.builders.constants.Status; +import org.phenopackets.phenotools.builder.constants.Status; import org.phenopackets.schema.v2.Phenopacket; import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; @@ -19,9 +19,9 @@ class Thrombocytopenia2 implements PhenopacketExample { var thrombocytopenia2 = ontologyClass("OMIM:188000", "Thrombocytopenia 2"); var individual = IndividualBuilder.builder(PROBAND_ID).female().ageAtLastEncounter("P20Y").build(); var metaData = MetaDataBuilder.builder("2021-05-14T10:35:00Z", "anonymous biocurator") - .resource(Resources.hpoVersion("2021-08-02")) - .resource(Resources.genoVersion("2020-03-08")) - .externalReference(authorAssertion.getReference()) + .addResource(Resources.hpoVersion("2021-08-02")) + .addResource(Resources.genoVersion("2020-03-08")) + .addExternalReference(authorAssertion.getReference()) .build(); var variationDescriptor = VariationDescriptorBuilder.builder("variant id") @@ -34,17 +34,16 @@ class Thrombocytopenia2 implements PhenopacketExample { .causative() .variantInterpretation(col6a1VariantInterpretation) .build(); - var diagnosis = DiagnosisBuilder.builder(thrombocytopenia2).genomicInterpretation(genomicInterpretation).build(); - var interpretation = InterpretationBuilder.builder(INTERPRETATION_ID, Status.completed()) - .diagnosis(diagnosis).build(); + var diagnosis = DiagnosisBuilder.builder(thrombocytopenia2).addGenomicInterpretation(genomicInterpretation).build(); + var interpretation = InterpretationBuilder.builder(INTERPRETATION_ID).completed(diagnosis); var excludedAbnormalPlateletSize = PhenotypicFeatureBuilder.builder("HP:0011876", "Abnormal platelet volume") .excluded() - .evidence(authorAssertion) + .addEvidence(authorAssertion) .build(); var brusing = PhenotypicFeatureBuilder.builder("HP:0000978", "Bruising susceptibility") - .evidence(authorAssertion) + .addEvidence(authorAssertion) .build(); phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metaData) .individual(individual) diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/UrothelialCancer.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/UrothelialCancer.java index e6a14aec..d7211829 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/UrothelialCancer.java +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/UrothelialCancer.java @@ -3,6 +3,7 @@ import org.phenopackets.phenotools.builder.PhenopacketBuilder; import org.phenopackets.phenotools.builder.builders.*; +import org.phenopackets.phenotools.builder.constants.Severity; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; @@ -18,15 +19,15 @@ class UrothelialCancer implements PhenopacketExample { UrothelialCancer() { var individual = IndividualBuilder.builder(PROBAND_ID).male().dateOfBirth("1964-03-15T00:00:00Z").build(); - var hematuria = PhenotypicFeatureBuilder.builder("HP:0000790","Hematuria").build(); - var dsyuria = PhenotypicFeatureBuilder.builder("HP:0100518","Dysuria") - .severe() + var hematuria = PhenotypicFeatureBuilder.phenotypicFeature("HP:0000790","Hematuria"); + var dsyuria = PhenotypicFeatureBuilder.builder("HP:0100518", "Dysuria") + .severity(Severity.severe()) .build(); var metadata = MetaDataBuilder.builder("2021-05-14T10:35:00Z", "anonymous biocurator") - .resource(Resources.ncitVersion("21.05d")) - .resource(Resources.efoVersion("3.34.0")) - .resource(Resources.uberonVersion("2021-07-27")) - .resource(Resources.ncbiTaxonVersion("2021-06-10")) + .addResource(Resources.ncitVersion("21.05d")) + .addResource(Resources.efoVersion("3.34.0")) + .addResource(Resources.uberonVersion("2021-07-27")) + .addResource(Resources.ncbiTaxonVersion("2021-06-10")) .build(); phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metadata) .individual(individual) @@ -56,16 +57,16 @@ private File normalGermlineHtsFile() { private Disease infiltratingUrothelialCarcinoma() { return DiseaseBuilder.builder("NCIT:C39853", "Infiltrating Urothelial Carcinoma") // Disease stage here is calculated based on the TMN findings - .diseaseStage(ontologyClass("NCIT:C27971", "Stage IV")) + .addDiseaseStage(ontologyClass("NCIT:C27971", "Stage IV")) // The tumor was staged as pT2b, meaning infiltration into the outer muscle layer of the bladder wall // pT2b Stage Finding (Code C48766) - .clinicalTnmFinding(ontologyClass("NCIT:C48766", "pT2b Stage Finding")) + .addClinicalTnmFinding(ontologyClass("NCIT:C48766", "pT2b Stage Finding")) //pN2 Stage Finding (Code C48750) // cancer has spread to 2 or more lymph nodes in the true pelvis (N2) - .clinicalTnmFinding(ontologyClass("NCIT:C48750", "pN2 Stage Finding")) + .addClinicalTnmFinding(ontologyClass("NCIT:C48750", "pN2 Stage Finding")) // M1 Stage Finding // the tumour has spread from the original site (Metastatic Neoplasm in lymph node - sample5) - .clinicalTnmFinding(ontologyClass("NCIT:C48700", "M1 Stage Finding")) + .addClinicalTnmFinding(ontologyClass("NCIT:C48700", "M1 Stage Finding")) .build(); } diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/WarburgMicroSyndrome.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/WarburgMicroSyndrome.java index 07723457..7b630ed9 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/WarburgMicroSyndrome.java +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/WarburgMicroSyndrome.java @@ -20,8 +20,8 @@ public class WarburgMicroSyndrome implements PhenopacketExample { private final Phenopacket phenopacket; public WarburgMicroSyndrome() { var metadata = MetaDataBuilder.builder("2022-04-17T10:35:00Z", "biocurator") - .resource(Resources.hpoVersion("2022-04-15")) - .resource(Resources.mondoVersion("v2022-04-04")) + .addResource(Resources.hpoVersion("2022-04-15")) + .addResource(Resources.mondoVersion("v2022-04-04")) .build(); Individual proband = IndividualBuilder.builder("case1"). ageAtLastEncounter("P4D"). From 1a10bcaabe2aee951a746bcfa9fadd5d70b9de7e Mon Sep 17 00:00:00 2001 From: Jules Jacobsen Date: Thu, 14 Apr 2022 14:55:28 +0100 Subject: [PATCH 006/155] Change for issue #48 - Update groupId to org.phenopackets.phenopackettools Update artifactIds to start with phenopacket-tools --- .../pom.xml | 6 +-- .../builder/FamilyBuilder.java | 4 +- .../builder/PhenopacketBuilder.java | 4 +- .../builder/builders/AgeBuilder.java | 4 +- .../builder/builders/AlleleBuilder.java | 2 +- .../builder/builders/BiosampleBuilder.java | 2 +- .../builder/builders/ComplexValueBuilder.java | 2 +- .../builder/builders/CopyNumberBuilder.java | 4 +- .../builder/builders/DiagnosisBuilder.java | 2 +- .../builder/builders/DiseaseBuilder.java | 2 +- .../builder/builders/DoseIntervalBuilder.java | 2 +- .../builder/builders/EvidenceBuilder.java | 2 +- .../builder/builders/Expressions.java | 2 +- .../builder/builders/Extensions.java | 2 +- .../builders/ExternalReferenceBuilder.java | 2 +- .../builder/builders/FileBuilder.java | 2 +- .../builders/GeneDescriptorBuilder.java | 2 +- .../GenomicInterpretationBuilder.java | 2 +- .../builder/builders/IndividualBuilder.java | 2 +- .../builders/InterpretationBuilder.java | 2 +- .../builder/builders/MeasurementBuilder.java | 2 +- .../builders/MedicalActionBuilder.java | 2 +- .../builder/builders/MetaDataBuilder.java | 4 +- .../builders/OntologyClassBuilder.java | 2 +- .../builder/builders/PedigreeBuilder.java | 2 +- .../builder/builders/PersonBuilder.java | 2 +- .../builders/PhenotypicFeatureBuilder.java | 2 +- .../builder/builders/ProcedureBuilder.java | 2 +- .../builder/builders/QuantityBuilder.java | 2 +- .../builders/ReferenceRangeBuilder.java | 2 +- .../builder/builders/Resources.java | 2 +- .../builders/TherapeuticRegimenBuilder.java | 2 +- .../builder/builders/TimeElements.java | 4 +- .../builder/builders/TimeIntervalBuilder.java | 4 +- .../builder/builders/TimestampBuilder.java | 2 +- .../builder/builders/TreatmentBuilder.java | 2 +- .../builders/TypedQuantityBuilder.java | 2 +- .../builder/builders/ValueBuilder.java | 2 +- .../VariantInterpretationBuilder.java | 2 +- .../builders/VariationDescriptorBuilder.java | 2 +- .../builder/builders/VcfRecordBuilder.java | 2 +- .../builder/builders/VitalStatusBuilder.java | 2 +- .../builder/constants/Laterality.java | 4 +- .../builder/constants/Onset.java | 2 +- .../builder/constants/Severity.java | 4 +- .../builder/constants/Status.java | 2 +- .../builder/constants/Unit.java | 4 +- .../PhenotoolsRuntimeException.java | 2 +- .../builder/builders/AgeBuilderTest.java | 2 +- .../builder/builders/AlleleBuilderTest.java | 3 +- .../builders/BiosampleBuilderTest.java | 4 +- .../builders/ComplexValueBuilderTest.java | 4 +- .../builders/DiagnosisBuilderTest.java | 6 +-- .../builder/builders/DiseaseBuilderTest.java | 4 +- .../builders/DoseIntervalBuilderTest.java | 4 +- .../builder/builders/FIleBuilderTest.java | 2 +- .../builders/IndividualBuilderTest.java | 6 +-- .../builder/builders/MetaDataBuilderTest.java | 2 +- .../builder/builders/TimeElementsTest.java | 6 +-- .../builders/TimeIntervalBuilderTest.java | 2 +- .../builders/TimestampBuilderTest.java | 2 +- .../pom.xml | 52 +++++-------------- .../phenopackets/phenopackettools}/Main.java | 2 +- .../phenopackettools}/PhenopacketTools.java | 8 +-- .../command/ConvertCommand.java | 4 +- .../command/ExamplesCommand.java | 10 ++-- .../command/ValidateCommand.java | 12 ++--- .../examples/BethlehamMyopathy.java | 10 ++-- .../phenopackettools}/examples/Covid.java | 8 +-- .../examples/FamilyWithPedigree.java | 8 +-- .../phenopackettools}/examples/Marfan.java | 8 +-- .../examples/NemalineMyopathyPrenatal.java | 12 ++--- .../examples/PhenopacketExample.java | 2 +- .../examples/PhenopacketExamples.java | 2 +- .../examples/Retinoblastoma.java | 12 ++--- .../examples/SquamousCellCancer.java | 8 +-- .../examples/Thrombocytopenia2.java | 10 ++-- .../examples/UrothelialCancer.java | 10 ++-- .../examples/WarburgMicroSyndrome.java | 8 +-- .../src/main/resources/logback.xml | 0 .../pom.xml | 6 +-- .../converter/converters/CohortConverter.java | 8 +-- .../converter/converters/FamilyConverter.java | 12 ++--- .../converters/PhenopacketConverter.java | 14 ++--- .../converter/converters/v2/AgeConverter.java | 2 +- .../converters/v2/BiosampleConverter.java | 12 ++--- .../converters/v2/DiseaseConverter.java | 8 +-- .../converters/v2/EvidenceConverter.java | 6 +-- .../v2/ExternalReferenceConverter.java | 2 +- .../converters/v2/FileConverter.java | 2 +- .../converters/v2/IndividualConverter.java | 8 +-- .../converters/v2/MetaDataConverter.java | 6 +-- .../converters/v2/OntologyClassConverter.java | 2 +- .../converters/v2/PedigreeConverter.java | 4 +- .../v2/PhenotypicFeatureConverter.java | 12 ++--- .../converters/v2/ProcedureConverter.java | 4 +- .../converters/v2/ResourceConverter.java | 2 +- .../converter/BethlemMyopathyV1.java | 2 +- .../converter/PhenopacketConverterTest.java | 8 +-- .../.mvn/wrapper/maven-wrapper.properties | 0 .../mvnw | 0 .../mvnw.cmd | 0 .../pom.xml | 8 +-- .../validator/core/DefaultValidationInfo.java | 2 +- .../validator/core/ErrorType.java | 4 +- .../validator/core/PhenopacketValidator.java | 2 +- .../core/PhenopacketValidatorFactory.java | 2 +- .../validator/core/ValidationAspect.java | 2 +- .../validator/core/ValidationItem.java | 2 +- .../validator/core/ValidatorInfo.java | 2 +- .../validator/core/ValidatorRunner.java | 2 +- .../PhenopacketValidatorRuntimeException.java | 2 +- .../pom.xml | 14 ++--- .../ClasspathJsonSchemaValidatorFactory.java | 10 ++-- .../jsonschema/JsonSchemaValidator.java | 10 ++-- .../jsonschema/JsonValidationError.java | 8 +-- .../schema/hpo-rare-disease-schema.json | 0 .../schema/phenopacket-schema-2-0.json | 0 .../JsonSchemaDiseaseValidatorTest.java | 18 +++---- .../jsonschema/JsonSchemaValidatorTest.java | 14 ++--- .../testdatagen/PhenopacketUtil.java | 2 +- .../testdatagen/RareDiseasePhenopacket.java | 4 +- .../testdatagen/SimplePhenopacket.java | 4 +- .../json/bethlehamMyopathyExample.json | 0 .../json/bethlehamMyopathyInvalidExample.json | 0 .../src/test/resources/logback-test.xml | 0 pom.xml | 17 +++--- 127 files changed, 287 insertions(+), 315 deletions(-) rename {phenotools-builder => phenopacket-tools-builder}/pom.xml (83%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/FamilyBuilder.java (92%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/PhenopacketBuilder.java (94%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/AgeBuilder.java (87%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/AlleleBuilder.java (97%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/BiosampleBuilder.java (98%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/ComplexValueBuilder.java (94%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/CopyNumberBuilder.java (93%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/DiagnosisBuilder.java (92%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/DiseaseBuilder.java (96%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/DoseIntervalBuilder.java (94%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/EvidenceBuilder.java (96%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/Expressions.java (92%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/Extensions.java (89%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/ExternalReferenceBuilder.java (94%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/FileBuilder.java (96%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/GeneDescriptorBuilder.java (96%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/GenomicInterpretationBuilder.java (97%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/IndividualBuilder.java (98%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/InterpretationBuilder.java (97%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/MeasurementBuilder.java (96%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/MedicalActionBuilder.java (97%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/MetaDataBuilder.java (91%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/OntologyClassBuilder.java (83%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/PedigreeBuilder.java (93%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/PersonBuilder.java (97%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/PhenotypicFeatureBuilder.java (98%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/ProcedureBuilder.java (95%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/QuantityBuilder.java (97%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/ReferenceRangeBuilder.java (93%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/Resources.java (98%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/TherapeuticRegimenBuilder.java (96%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/TimeElements.java (97%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/TimeIntervalBuilder.java (80%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/TimestampBuilder.java (97%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/TreatmentBuilder.java (96%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/TypedQuantityBuilder.java (87%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/ValueBuilder.java (95%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/VariantInterpretationBuilder.java (98%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/VariationDescriptorBuilder.java (98%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/VcfRecordBuilder.java (97%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/VitalStatusBuilder.java (95%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/constants/Laterality.java (85%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/constants/Onset.java (97%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/constants/Severity.java (92%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/constants/Status.java (97%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/constants/Unit.java (82%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/exceptions/PhenotoolsRuntimeException.java (74%) rename {phenotools-builder/src/test/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools}/builder/builders/AgeBuilderTest.java (96%) rename {phenotools-builder/src/test/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools}/builder/builders/AlleleBuilderTest.java (91%) rename {phenotools-builder/src/test/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools}/builder/builders/BiosampleBuilderTest.java (95%) rename {phenotools-builder/src/test/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools}/builder/builders/ComplexValueBuilderTest.java (89%) rename {phenotools-builder/src/test/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools}/builder/builders/DiagnosisBuilderTest.java (89%) rename {phenotools-builder/src/test/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools}/builder/builders/DiseaseBuilderTest.java (83%) rename {phenotools-builder/src/test/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools}/builder/builders/DoseIntervalBuilderTest.java (87%) rename {phenotools-builder/src/test/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools}/builder/builders/FIleBuilderTest.java (94%) rename {phenotools-builder/src/test/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools}/builder/builders/IndividualBuilderTest.java (91%) rename {phenotools-builder/src/test/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools}/builder/builders/MetaDataBuilderTest.java (90%) rename {phenotools-builder/src/test/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools}/builder/builders/TimeElementsTest.java (93%) rename {phenotools-builder/src/test/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools}/builder/builders/TimeIntervalBuilderTest.java (95%) rename {phenotools-builder/src/test/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools}/builder/builders/TimestampBuilderTest.java (92%) rename {phenotools-cli => phenopacket-tools-cli}/pom.xml (52%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/Main.java (92%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/PhenopacketTools.java (66%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/command/ConvertCommand.java (96%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/command/ExamplesCommand.java (93%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/command/ValidateCommand.java (83%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/examples/BethlehamMyopathy.java (93%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/examples/Covid.java (97%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/examples/FamilyWithPedigree.java (93%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/examples/Marfan.java (87%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/examples/NemalineMyopathyPrenatal.java (94%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/examples/PhenopacketExample.java (69%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/examples/PhenopacketExamples.java (97%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/examples/Retinoblastoma.java (97%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/examples/SquamousCellCancer.java (92%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/examples/Thrombocytopenia2.java (89%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/examples/UrothelialCancer.java (95%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/examples/WarburgMicroSyndrome.java (92%) rename {phenotools-cli => phenopacket-tools-cli}/src/main/resources/logback.xml (100%) rename {phenotools-converter => phenopacket-tools-converter}/pom.xml (83%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/CohortConverter.java (70%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/FamilyConverter.java (63%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/PhenopacketConverter.java (70%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/v2/AgeConverter.java (89%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/v2/BiosampleConverter.java (85%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/v2/DiseaseConverter.java (81%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/v2/EvidenceConverter.java (74%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/v2/ExternalReferenceConverter.java (94%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/v2/FileConverter.java (93%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/v2/IndividualConverter.java (88%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/v2/MetaDataConverter.java (82%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/v2/OntologyClassConverter.java (93%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/v2/PedigreeConverter.java (92%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/v2/PhenotypicFeatureConverter.java (82%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/v2/ProcedureConverter.java (79%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/v2/ResourceConverter.java (92%) rename {phenotools-converter/src/test/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools}/converter/BethlemMyopathyV1.java (99%) rename {phenotools-converter/src/test/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools}/converter/PhenopacketConverterTest.java (61%) rename {phenotools-validator-core => phenopacket-tools-validator-core}/.mvn/wrapper/maven-wrapper.properties (100%) rename {phenotools-validator-core => phenopacket-tools-validator-core}/mvnw (100%) rename {phenotools-validator-core => phenopacket-tools-validator-core}/mvnw.cmd (100%) rename {phenotools-validator-core => phenopacket-tools-validator-core}/pom.xml (66%) rename {phenotools-validator-core/src/main/java/org/phenopackets/phenotools => phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools}/validator/core/DefaultValidationInfo.java (96%) rename {phenotools-validator-core/src/main/java/org/phenopackets/phenotools => phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools}/validator/core/ErrorType.java (88%) rename {phenotools-validator-core/src/main/java/org/phenopackets/phenotools => phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools}/validator/core/PhenopacketValidator.java (94%) rename {phenotools-validator-core/src/main/java/org/phenopackets/phenotools => phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools}/validator/core/PhenopacketValidatorFactory.java (85%) rename {phenotools-validator-core/src/main/java/org/phenopackets/phenotools => phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools}/validator/core/ValidationAspect.java (86%) rename {phenotools-validator-core/src/main/java/org/phenopackets/phenotools => phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools}/validator/core/ValidationItem.java (90%) rename {phenotools-validator-core/src/main/java/org/phenopackets/phenotools => phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools}/validator/core/ValidatorInfo.java (93%) rename {phenotools-validator-core/src/main/java/org/phenopackets/phenotools => phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools}/validator/core/ValidatorRunner.java (96%) rename {phenotools-validator-core/src/main/java/org/phenopackets/phenotools => phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools}/validator/core/except/PhenopacketValidatorRuntimeException.java (91%) rename {phenotools-validator-jsonschema => phenopacket-tools-validator-jsonschema}/pom.xml (77%) rename {phenotools-validator-jsonschema/src/main/java/org/phenopackets/phenotools => phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools}/validator/jsonschema/ClasspathJsonSchemaValidatorFactory.java (84%) rename {phenotools-validator-jsonschema/src/main/java/org/phenopackets/phenotools => phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools}/validator/jsonschema/JsonSchemaValidator.java (90%) rename {phenotools-validator-jsonschema/src/main/java/org/phenopackets/phenotools => phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools}/validator/jsonschema/JsonValidationError.java (85%) rename {phenotools-validator-jsonschema => phenopacket-tools-validator-jsonschema}/src/main/resources/schema/hpo-rare-disease-schema.json (100%) rename {phenotools-validator-jsonschema => phenopacket-tools-validator-jsonschema}/src/main/resources/schema/phenopacket-schema-2-0.json (100%) rename {phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools => phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools}/validator/jsonschema/JsonSchemaDiseaseValidatorTest.java (84%) rename {phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools => phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools}/validator/jsonschema/JsonSchemaValidatorTest.java (88%) rename {phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools => phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools}/validator/testdatagen/PhenopacketUtil.java (99%) rename {phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools => phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools}/validator/testdatagen/RareDiseasePhenopacket.java (93%) rename {phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools => phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools}/validator/testdatagen/SimplePhenopacket.java (83%) rename {phenotools-validator-jsonschema => phenopacket-tools-validator-jsonschema}/src/test/resources/json/bethlehamMyopathyExample.json (100%) rename {phenotools-validator-jsonschema => phenopacket-tools-validator-jsonschema}/src/test/resources/json/bethlehamMyopathyInvalidExample.json (100%) rename {phenotools-validator-jsonschema => phenopacket-tools-validator-jsonschema}/src/test/resources/logback-test.xml (100%) diff --git a/phenotools-builder/pom.xml b/phenopacket-tools-builder/pom.xml similarity index 83% rename from phenotools-builder/pom.xml rename to phenopacket-tools-builder/pom.xml index 14cde2e6..ae71ee17 100644 --- a/phenotools-builder/pom.xml +++ b/phenopacket-tools-builder/pom.xml @@ -5,12 +5,12 @@ 4.0.0 - org.phenopackets.phenotools - phenotools + org.phenopackets.phenopackettools + phenopacket-tools 1.0.0 - phenotools-builder + phenopacket-tools-builder diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/FamilyBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/FamilyBuilder.java similarity index 92% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/FamilyBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/FamilyBuilder.java index 41643af4..9f8a5654 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/FamilyBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/FamilyBuilder.java @@ -1,6 +1,6 @@ -package org.phenopackets.phenotools.builder; +package org.phenopackets.phenopackettools.builder; -import org.phenopackets.phenotools.builder.exceptions.PhenotoolsRuntimeException; +import org.phenopackets.phenopackettools.builder.exceptions.PhenotoolsRuntimeException; import org.phenopackets.schema.v2.Family; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.File; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/PhenopacketBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/PhenopacketBuilder.java similarity index 94% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/PhenopacketBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/PhenopacketBuilder.java index f5ef9c57..0f399bd5 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/PhenopacketBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/PhenopacketBuilder.java @@ -1,6 +1,6 @@ -package org.phenopackets.phenotools.builder; +package org.phenopackets.phenopackettools.builder; -import org.phenopackets.phenotools.builder.builders.PhenotypicFeatureBuilder; +import org.phenopackets.phenopackettools.builder.builders.PhenotypicFeatureBuilder; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/AgeBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/AgeBuilder.java similarity index 87% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/AgeBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/AgeBuilder.java index 694cb145..20691682 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/AgeBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/AgeBuilder.java @@ -1,6 +1,6 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; -import org.phenopackets.phenotools.builder.exceptions.PhenotoolsRuntimeException; +import org.phenopackets.phenopackettools.builder.exceptions.PhenotoolsRuntimeException; import org.phenopackets.schema.v2.core.Age; import org.phenopackets.schema.v2.core.AgeRange; import org.phenopackets.schema.v2.core.GestationalAge; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/AlleleBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilder.java similarity index 97% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/AlleleBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilder.java index 1c97ac66..7e7b7a07 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/AlleleBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.ga4gh.vrs.v1.*; import org.ga4gh.vrs.v1.Number; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/BiosampleBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilder.java similarity index 98% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/BiosampleBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilder.java index 37fa70cb..4c15789e 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/BiosampleBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.*; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/ComplexValueBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilder.java similarity index 94% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/ComplexValueBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilder.java index b75f8646..ff370bcf 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/ComplexValueBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.ComplexValue; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/CopyNumberBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/CopyNumberBuilder.java similarity index 93% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/CopyNumberBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/CopyNumberBuilder.java index 2eaa2f2d..fb9a2b6b 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/CopyNumberBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/CopyNumberBuilder.java @@ -1,8 +1,8 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.ga4gh.vrs.v1.*; import org.ga4gh.vrs.v1.Number; -import org.phenopackets.phenotools.builder.exceptions.PhenotoolsRuntimeException; +import org.phenopackets.phenopackettools.builder.exceptions.PhenotoolsRuntimeException; public class CopyNumberBuilder { diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DiagnosisBuilder.java similarity index 92% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DiagnosisBuilder.java index 7a799b40..138669d4 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DiagnosisBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.Diagnosis; import org.phenopackets.schema.v2.core.GenomicInterpretation; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DiseaseBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilder.java similarity index 96% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DiseaseBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilder.java index c28e5fa7..3c648524 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DiseaseBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.Disease; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DoseIntervalBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DoseIntervalBuilder.java similarity index 94% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DoseIntervalBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DoseIntervalBuilder.java index 5927a7ea..52850cce 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DoseIntervalBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DoseIntervalBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.DoseInterval; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/EvidenceBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/EvidenceBuilder.java similarity index 96% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/EvidenceBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/EvidenceBuilder.java index d48dd974..f9064b09 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/EvidenceBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/EvidenceBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.Evidence; import org.phenopackets.schema.v2.core.ExternalReference; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Expressions.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Expressions.java similarity index 92% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Expressions.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Expressions.java index 62fac158..cc5a0535 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Expressions.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Expressions.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.ga4gh.vrsatile.v1.Expression; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Extensions.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Extensions.java similarity index 89% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Extensions.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Extensions.java index f355f762..c8069ff7 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Extensions.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Extensions.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import com.google.protobuf.Any; import com.google.protobuf.ByteString; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/ExternalReferenceBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ExternalReferenceBuilder.java similarity index 94% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/ExternalReferenceBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ExternalReferenceBuilder.java index c55101c0..d441a7ea 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/ExternalReferenceBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ExternalReferenceBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.ExternalReference; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/FileBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/FileBuilder.java similarity index 96% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/FileBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/FileBuilder.java index d6fe7c03..c24fa37a 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/FileBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/FileBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.File; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/GeneDescriptorBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/GeneDescriptorBuilder.java similarity index 96% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/GeneDescriptorBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/GeneDescriptorBuilder.java index 98576fb1..af870423 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/GeneDescriptorBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/GeneDescriptorBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.ga4gh.vrsatile.v1.GeneDescriptor; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/GenomicInterpretationBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/GenomicInterpretationBuilder.java similarity index 97% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/GenomicInterpretationBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/GenomicInterpretationBuilder.java index ca224fd2..8ec96a09 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/GenomicInterpretationBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/GenomicInterpretationBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.ga4gh.vrsatile.v1.GeneDescriptor; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/IndividualBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilder.java similarity index 98% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/IndividualBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilder.java index 25593a87..87f92377 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/IndividualBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import com.google.protobuf.Timestamp; import org.phenopackets.schema.v2.core.*; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/InterpretationBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/InterpretationBuilder.java similarity index 97% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/InterpretationBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/InterpretationBuilder.java index c32dea86..24ccc346 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/InterpretationBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/InterpretationBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.Diagnosis; import org.phenopackets.schema.v2.core.Interpretation; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MeasurementBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MeasurementBuilder.java similarity index 96% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MeasurementBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MeasurementBuilder.java index b6fdaf31..cdb63a7e 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MeasurementBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MeasurementBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.*; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MedicalActionBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MedicalActionBuilder.java similarity index 97% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MedicalActionBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MedicalActionBuilder.java index cf95add2..7cc55220 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MedicalActionBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MedicalActionBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.*; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MetaDataBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MetaDataBuilder.java similarity index 91% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MetaDataBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MetaDataBuilder.java index 73632fbf..00a567f3 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MetaDataBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MetaDataBuilder.java @@ -1,11 +1,11 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.ExternalReference; import org.phenopackets.schema.v2.core.MetaData; import org.phenopackets.schema.v2.core.Resource; import org.phenopackets.schema.v2.core.Update; -import static org.phenopackets.phenotools.builder.builders.TimestampBuilder.fromISO8601; +import static org.phenopackets.phenopackettools.builder.builders.TimestampBuilder.fromISO8601; public class MetaDataBuilder { diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/OntologyClassBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/OntologyClassBuilder.java similarity index 83% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/OntologyClassBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/OntologyClassBuilder.java index c9b9f472..aa72d392 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/OntologyClassBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/OntologyClassBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PedigreeBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/PedigreeBuilder.java similarity index 93% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PedigreeBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/PedigreeBuilder.java index c708ced3..14ea1916 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PedigreeBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/PedigreeBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.Pedigree; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PersonBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/PersonBuilder.java similarity index 97% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PersonBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/PersonBuilder.java index 317862c7..08eb9e90 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PersonBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/PersonBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.Pedigree; import org.phenopackets.schema.v2.core.Sex; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PhenotypicFeatureBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/PhenotypicFeatureBuilder.java similarity index 98% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PhenotypicFeatureBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/PhenotypicFeatureBuilder.java index 2ffe1ddf..0899b58b 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PhenotypicFeatureBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/PhenotypicFeatureBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.Evidence; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/ProcedureBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ProcedureBuilder.java similarity index 95% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/ProcedureBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ProcedureBuilder.java index f656f2db..6a17c2f2 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/ProcedureBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ProcedureBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.OntologyClass; import org.phenopackets.schema.v2.core.Procedure; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/QuantityBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/QuantityBuilder.java similarity index 97% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/QuantityBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/QuantityBuilder.java index 163b8630..c83c6298 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/QuantityBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/QuantityBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.OntologyClass; import org.phenopackets.schema.v2.core.Quantity; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/ReferenceRangeBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ReferenceRangeBuilder.java similarity index 93% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/ReferenceRangeBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ReferenceRangeBuilder.java index 5d67372a..8beca5e3 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/ReferenceRangeBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ReferenceRangeBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.OntologyClass; import org.phenopackets.schema.v2.core.ReferenceRange; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Resources.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Resources.java similarity index 98% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Resources.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Resources.java index ea09e04a..871edc75 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Resources.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Resources.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.Resource; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TherapeuticRegimenBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TherapeuticRegimenBuilder.java similarity index 96% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TherapeuticRegimenBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TherapeuticRegimenBuilder.java index 63d04ce4..583bf529 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TherapeuticRegimenBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TherapeuticRegimenBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.OntologyClass; import org.phenopackets.schema.v2.core.TherapeuticRegimen; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimeElements.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimeElements.java similarity index 97% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimeElements.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimeElements.java index 7d58d55f..3e40b9e2 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimeElements.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimeElements.java @@ -1,7 +1,7 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import com.google.protobuf.Timestamp; -import org.phenopackets.phenotools.builder.constants.Onset; +import org.phenopackets.phenopackettools.builder.constants.Onset; import org.phenopackets.schema.v2.core.*; import java.time.Instant; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimeIntervalBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilder.java similarity index 80% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimeIntervalBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilder.java index bb3af87f..13cf6eec 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimeIntervalBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilder.java @@ -1,9 +1,9 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import com.google.protobuf.Timestamp; import org.phenopackets.schema.v2.core.TimeInterval; -import static org.phenopackets.phenotools.builder.builders.TimestampBuilder.fromISO8601; +import static org.phenopackets.phenopackettools.builder.builders.TimestampBuilder.fromISO8601; public class TimeIntervalBuilder { diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimestampBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimestampBuilder.java similarity index 97% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimestampBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimestampBuilder.java index c5da9c26..3a8e186a 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimestampBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimestampBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import com.google.protobuf.Timestamp; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TreatmentBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TreatmentBuilder.java similarity index 96% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TreatmentBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TreatmentBuilder.java index 744b9b66..4cf3946d 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TreatmentBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TreatmentBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.*; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TypedQuantityBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TypedQuantityBuilder.java similarity index 87% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TypedQuantityBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TypedQuantityBuilder.java index 171ec624..158058b5 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TypedQuantityBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TypedQuantityBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.OntologyClass; import org.phenopackets.schema.v2.core.Quantity; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/ValueBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ValueBuilder.java similarity index 95% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/ValueBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ValueBuilder.java index f0555639..f4ebb983 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/ValueBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ValueBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VariantInterpretationBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariantInterpretationBuilder.java similarity index 98% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VariantInterpretationBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariantInterpretationBuilder.java index 2191834d..2e985087 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VariantInterpretationBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariantInterpretationBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.ga4gh.vrsatile.v1.VariationDescriptor; import org.phenopackets.schema.v2.core.AcmgPathogenicityClassification; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VariationDescriptorBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariationDescriptorBuilder.java similarity index 98% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VariationDescriptorBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariationDescriptorBuilder.java index f38ace0a..153db950 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VariationDescriptorBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariationDescriptorBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.ga4gh.vrs.v1.Variation; import org.ga4gh.vrsatile.v1.*; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VcfRecordBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VcfRecordBuilder.java similarity index 97% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VcfRecordBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VcfRecordBuilder.java index 7063824e..bfd1c190 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VcfRecordBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VcfRecordBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.ga4gh.vrsatile.v1.VcfRecord; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VitalStatusBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VitalStatusBuilder.java similarity index 95% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VitalStatusBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VitalStatusBuilder.java index 9dfe82bc..a327c39d 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VitalStatusBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VitalStatusBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.OntologyClass; import org.phenopackets.schema.v2.core.TimeElement; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Laterality.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Laterality.java similarity index 85% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Laterality.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Laterality.java index 02413281..17e9c70f 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Laterality.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Laterality.java @@ -1,6 +1,6 @@ -package org.phenopackets.phenotools.builder.constants; +package org.phenopackets.phenopackettools.builder.constants; -import org.phenopackets.phenotools.builder.builders.OntologyClassBuilder; +import org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Onset.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Onset.java similarity index 97% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Onset.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Onset.java index e9ffc9fe..2dd221f0 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Onset.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Onset.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.constants; +package org.phenopackets.phenopackettools.builder.constants; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Severity.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Severity.java similarity index 92% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Severity.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Severity.java index 35594d5e..9a0fb7e4 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Severity.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Severity.java @@ -1,8 +1,8 @@ -package org.phenopackets.phenotools.builder.constants; +package org.phenopackets.phenopackettools.builder.constants; import org.phenopackets.schema.v2.core.OntologyClass; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; public class Severity { diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Status.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Status.java similarity index 97% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Status.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Status.java index fec4d29b..a1c80ea2 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Status.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Status.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.constants; +package org.phenopackets.phenopackettools.builder.constants; import org.phenopackets.schema.v2.core.AcmgPathogenicityClassification; import org.phenopackets.schema.v2.core.GenomicInterpretation.InterpretationStatus; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Unit.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Unit.java similarity index 82% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Unit.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Unit.java index e0cbeedb..28337117 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Unit.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Unit.java @@ -1,8 +1,8 @@ -package org.phenopackets.phenotools.builder.constants; +package org.phenopackets.phenopackettools.builder.constants; import org.phenopackets.schema.v2.core.OntologyClass; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; public class Unit { diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/exceptions/PhenotoolsRuntimeException.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/exceptions/PhenotoolsRuntimeException.java similarity index 74% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/exceptions/PhenotoolsRuntimeException.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/exceptions/PhenotoolsRuntimeException.java index 9f8ac33f..7735686d 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/exceptions/PhenotoolsRuntimeException.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/exceptions/PhenotoolsRuntimeException.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.exceptions; +package org.phenopackets.phenopackettools.builder.exceptions; public class PhenotoolsRuntimeException extends RuntimeException { public PhenotoolsRuntimeException() { super();} diff --git a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/AgeBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AgeBuilderTest.java similarity index 96% rename from phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/AgeBuilderTest.java rename to phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AgeBuilderTest.java index 63d9a4da..6729abc4 100644 --- a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/AgeBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AgeBuilderTest.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.junit.jupiter.api.Test; import org.phenopackets.schema.v2.core.Age; diff --git a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/AlleleBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilderTest.java similarity index 91% rename from phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/AlleleBuilderTest.java rename to phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilderTest.java index f260d7c1..4890a1d9 100644 --- a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/AlleleBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilderTest.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.ga4gh.vrs.v1.Allele; import org.ga4gh.vrs.v1.Variation; @@ -6,7 +6,6 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; -import static org.junit.jupiter.api.Assertions.*; class AlleleBuilderTest { diff --git a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/BiosampleBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilderTest.java similarity index 95% rename from phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/BiosampleBuilderTest.java rename to phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilderTest.java index 27cc3095..e3eafb5b 100644 --- a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/BiosampleBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilderTest.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.junit.jupiter.api.Test; import org.phenopackets.schema.v2.core.Biosample; @@ -7,7 +7,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; class BiosampleBuilderTest { diff --git a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/ComplexValueBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilderTest.java similarity index 89% rename from phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/ComplexValueBuilderTest.java rename to phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilderTest.java index 409da2c4..379bb619 100644 --- a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/ComplexValueBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilderTest.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.junit.jupiter.api.Test; import org.phenopackets.schema.v2.core.ComplexValue; @@ -9,7 +9,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; class ComplexValueBuilderTest { diff --git a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiagnosisBuilderTest.java similarity index 89% rename from phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilderTest.java rename to phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiagnosisBuilderTest.java index 196a55be..64bc4bf7 100644 --- a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiagnosisBuilderTest.java @@ -1,14 +1,14 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.junit.jupiter.api.Test; -import org.phenopackets.phenotools.builder.constants.Status; +import org.phenopackets.phenopackettools.builder.constants.Status; import org.phenopackets.schema.v2.core.Diagnosis; import org.phenopackets.schema.v2.core.GenomicInterpretation; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; class DiagnosisBuilderTest { diff --git a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DiseaseBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilderTest.java similarity index 83% rename from phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DiseaseBuilderTest.java rename to phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilderTest.java index a1d2bacb..5002696b 100644 --- a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DiseaseBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilderTest.java @@ -1,11 +1,11 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.junit.jupiter.api.Test; import org.phenopackets.schema.v2.core.Disease; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; class DiseaseBuilderTest { diff --git a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DoseIntervalBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DoseIntervalBuilderTest.java similarity index 87% rename from phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DoseIntervalBuilderTest.java rename to phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DoseIntervalBuilderTest.java index 6b727c67..d1a22e70 100644 --- a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DoseIntervalBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DoseIntervalBuilderTest.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import com.google.protobuf.Timestamp; import org.junit.jupiter.api.Test; @@ -8,7 +8,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; public class DoseIntervalBuilderTest { diff --git a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/FIleBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/FIleBuilderTest.java similarity index 94% rename from phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/FIleBuilderTest.java rename to phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/FIleBuilderTest.java index 4c7a6391..d66cbb2e 100644 --- a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/FIleBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/FIleBuilderTest.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.junit.jupiter.api.Test; import org.phenopackets.schema.v2.core.File; diff --git a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/IndividualBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilderTest.java similarity index 91% rename from phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/IndividualBuilderTest.java rename to phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilderTest.java index 2b09f21e..27c1034f 100644 --- a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/IndividualBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilderTest.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import com.google.protobuf.Timestamp; import org.junit.jupiter.api.Test; import org.phenopackets.schema.v2.core.Individual; @@ -7,8 +7,8 @@ import org.phenopackets.schema.v2.core.VitalStatus; import static org.junit.jupiter.api.Assertions.*; -import static org.phenopackets.phenotools.builder.builders.IndividualBuilder.HOMO_SAPIENS; -import static org.phenopackets.phenotools.builder.builders.TimestampBuilder.fromISO8601; +import static org.phenopackets.phenopackettools.builder.builders.IndividualBuilder.HOMO_SAPIENS; +import static org.phenopackets.phenopackettools.builder.builders.TimestampBuilder.fromISO8601; public class IndividualBuilderTest { diff --git a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/MetaDataBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/MetaDataBuilderTest.java similarity index 90% rename from phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/MetaDataBuilderTest.java rename to phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/MetaDataBuilderTest.java index 5cd666aa..d4b42021 100644 --- a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/MetaDataBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/MetaDataBuilderTest.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.junit.jupiter.api.Test; import org.phenopackets.schema.v2.core.MetaData; diff --git a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/TimeElementsTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimeElementsTest.java similarity index 93% rename from phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/TimeElementsTest.java rename to phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimeElementsTest.java index 8b1162c8..f16bb59b 100644 --- a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/TimeElementsTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimeElementsTest.java @@ -1,16 +1,16 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import com.google.protobuf.Timestamp; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import org.phenopackets.phenotools.builder.exceptions.PhenotoolsRuntimeException; +import org.phenopackets.phenopackettools.builder.exceptions.PhenotoolsRuntimeException; import org.phenopackets.schema.v2.core.OntologyClass; import org.phenopackets.schema.v2.core.TimeElement; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.phenopackets.phenotools.builder.builders.TimestampBuilder.fromISO8601; +import static org.phenopackets.phenopackettools.builder.builders.TimestampBuilder.fromISO8601; public class TimeElementsTest { diff --git a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/TimeIntervalBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilderTest.java similarity index 95% rename from phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/TimeIntervalBuilderTest.java rename to phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilderTest.java index 0aecb11b..9e5c9315 100644 --- a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/TimeIntervalBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilderTest.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import com.google.protobuf.Timestamp; import org.junit.jupiter.api.Test; diff --git a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/TimestampBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimestampBuilderTest.java similarity index 92% rename from phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/TimestampBuilderTest.java rename to phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimestampBuilderTest.java index 9af79f20..2002dcf5 100644 --- a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/TimestampBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimestampBuilderTest.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import com.google.protobuf.Timestamp; import com.google.protobuf.util.Timestamps; diff --git a/phenotools-cli/pom.xml b/phenopacket-tools-cli/pom.xml similarity index 52% rename from phenotools-cli/pom.xml rename to phenopacket-tools-cli/pom.xml index 0d9887e4..7fe7c7fe 100644 --- a/phenotools-cli/pom.xml +++ b/phenopacket-tools-cli/pom.xml @@ -5,67 +5,42 @@ 4.0.0 - org.phenopackets.phenotools - phenotools + org.phenopackets.phenopackettools + phenopacket-tools 1.0.0 - phenotools-cli + phenopacket-tools-cli - phenotools-cli + phenopacket-tools-cli Command-line utility for phenopacket-tools - org.phenopackets.phenotools - phenotools-builder + org.phenopackets.phenopackettools + phenopacket-tools-builder ${project.parent.version} - org.phenopackets.phenotools - phenotools-converter + org.phenopackets.phenopackettools + phenopacket-tools-converter ${project.parent.version} - info.picocli - picocli - 4.6.3 - - - org.phenopackets.phenotools - phenotools-validator-core + org.phenopackets.phenopackettools + phenopacket-tools-validator-jsonschema ${project.parent.version} compile - org.phenopackets.phenotools - phenotools-validator-jsonschema - ${project.parent.version} - compile + info.picocli + picocli + 4.6.3 ch.qos.logback logback-classic - - com.fasterxml.jackson - jackson-bom - 2.13.2 - import - pom - - - com.fasterxml.jackson.core - jackson-databind - 2.13.2 - test - - - com.fasterxml.jackson.dataformat - jackson-dataformat-yaml - 2.13.2 - test - com.fasterxml.jackson.core jackson-databind @@ -81,7 +56,6 @@ org.springframework.boot spring-boot-maven-plugin - 2.6.4 diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/Main.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/Main.java similarity index 92% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/Main.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/Main.java index 8b5dea73..e20959cf 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/Main.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/Main.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools; +package org.phenopackets.phenopackettools; import picocli.CommandLine; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/PhenopacketTools.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/PhenopacketTools.java similarity index 66% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/PhenopacketTools.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/PhenopacketTools.java index c38a5f69..91651c51 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/PhenopacketTools.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/PhenopacketTools.java @@ -1,8 +1,8 @@ -package org.phenopackets.phenotools; +package org.phenopackets.phenopackettools; -import org.phenopackets.phenotools.command.ConvertCommand; -import org.phenopackets.phenotools.command.ExamplesCommand; -import org.phenopackets.phenotools.command.ValidateCommand; +import org.phenopackets.phenopackettools.command.ConvertCommand; +import org.phenopackets.phenopackettools.command.ExamplesCommand; +import org.phenopackets.phenopackettools.command.ValidateCommand; import picocli.AutoComplete; import static picocli.CommandLine.*; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/command/ConvertCommand.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ConvertCommand.java similarity index 96% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/command/ConvertCommand.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ConvertCommand.java index f5d0fe1f..4b82b46e 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/command/ConvertCommand.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ConvertCommand.java @@ -1,8 +1,8 @@ -package org.phenopackets.phenotools.command; +package org.phenopackets.phenopackettools.command; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.util.JsonFormat; -import org.phenopackets.phenotools.converter.converters.PhenopacketConverter; +import org.phenopackets.phenopackettools.converter.converters.PhenopacketConverter; import org.phenopackets.schema.v2.Phenopacket; import picocli.CommandLine.Command; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/command/ExamplesCommand.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java similarity index 93% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/command/ExamplesCommand.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java index 1965f222..08f039ae 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/command/ExamplesCommand.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.command; +package org.phenopackets.phenopackettools.command; @@ -10,10 +10,10 @@ import com.google.protobuf.Message; import com.google.protobuf.util.JsonFormat; -import org.phenopackets.phenotools.builder.exceptions.PhenotoolsRuntimeException; -import org.phenopackets.phenotools.examples.FamilyWithPedigree; -import org.phenopackets.phenotools.examples.PhenopacketExamples; -import org.phenopackets.phenotools.examples.WarburgMicroSyndrome; +import org.phenopackets.phenopackettools.builder.exceptions.PhenotoolsRuntimeException; +import org.phenopackets.phenopackettools.examples.FamilyWithPedigree; +import org.phenopackets.phenopackettools.examples.PhenopacketExamples; +import org.phenopackets.phenopackettools.examples.WarburgMicroSyndrome; import picocli.CommandLine; import picocli.CommandLine.Command; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/command/ValidateCommand.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ValidateCommand.java similarity index 83% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/command/ValidateCommand.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ValidateCommand.java index ce1ebcbc..e82cd644 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/command/ValidateCommand.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ValidateCommand.java @@ -1,11 +1,11 @@ -package org.phenopackets.phenotools.command; +package org.phenopackets.phenopackettools.command; -import org.phenopackets.phenotools.validator.core.PhenopacketValidatorFactory; -import org.phenopackets.phenotools.validator.core.ValidationItem; -import org.phenopackets.phenotools.validator.core.ValidatorInfo; -import org.phenopackets.phenotools.validator.core.ValidatorRunner; -import org.phenopackets.phenotools.validator.jsonschema.ClasspathJsonSchemaValidatorFactory; +import org.phenopackets.phenopackettools.validator.core.PhenopacketValidatorFactory; +import org.phenopackets.phenopackettools.validator.core.ValidationItem; +import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; +import org.phenopackets.phenopackettools.validator.core.ValidatorRunner; +import org.phenopackets.phenopackettools.validator.jsonschema.ClasspathJsonSchemaValidatorFactory; import picocli.CommandLine.Command; import picocli.CommandLine.Option; import picocli.CommandLine.Parameters; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/BethlehamMyopathy.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/BethlehamMyopathy.java similarity index 93% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/BethlehamMyopathy.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/BethlehamMyopathy.java index c66ee81a..785b8745 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/BethlehamMyopathy.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/BethlehamMyopathy.java @@ -1,12 +1,12 @@ -package org.phenopackets.phenotools.examples; +package org.phenopackets.phenopackettools.examples; -import org.phenopackets.phenotools.builder.PhenopacketBuilder; -import org.phenopackets.phenotools.builder.builders.*; -import org.phenopackets.phenotools.builder.constants.Status; +import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; +import org.phenopackets.phenopackettools.builder.builders.*; +import org.phenopackets.phenopackettools.builder.constants.Status; import org.phenopackets.schema.v2.Phenopacket; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; class BethlehamMyopathy implements PhenopacketExample { private static final String PHENOPACKET_ID = "arbitrary proband id"; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Covid.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Covid.java similarity index 97% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Covid.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Covid.java index 65bee335..b0c67f83 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Covid.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Covid.java @@ -1,14 +1,14 @@ -package org.phenopackets.phenotools.examples; +package org.phenopackets.phenopackettools.examples; -import org.phenopackets.phenotools.builder.PhenopacketBuilder; -import org.phenopackets.phenotools.builder.builders.*; +import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; +import org.phenopackets.phenopackettools.builder.builders.*; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; import java.util.ArrayList; import java.util.List; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; class Covid implements PhenopacketExample { diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/FamilyWithPedigree.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/FamilyWithPedigree.java similarity index 93% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/FamilyWithPedigree.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/FamilyWithPedigree.java index e5e250f6..b00d2ca8 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/FamilyWithPedigree.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/FamilyWithPedigree.java @@ -1,9 +1,9 @@ -package org.phenopackets.phenotools.examples; +package org.phenopackets.phenopackettools.examples; -import org.phenopackets.phenotools.builder.FamilyBuilder; -import org.phenopackets.phenotools.builder.PhenopacketBuilder; -import org.phenopackets.phenotools.builder.builders.*; +import org.phenopackets.phenopackettools.builder.FamilyBuilder; +import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; +import org.phenopackets.phenopackettools.builder.builders.*; import org.phenopackets.schema.v2.Family; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Marfan.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Marfan.java similarity index 87% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Marfan.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Marfan.java index aa419890..ffe55020 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Marfan.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Marfan.java @@ -1,10 +1,10 @@ -package org.phenopackets.phenotools.examples; +package org.phenopackets.phenopackettools.examples; -import org.phenopackets.phenotools.builder.PhenopacketBuilder; -import org.phenopackets.phenotools.builder.builders.*; +import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; +import org.phenopackets.phenopackettools.builder.builders.*; import org.phenopackets.schema.v2.Phenopacket; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; class Marfan implements PhenopacketExample { diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/NemalineMyopathyPrenatal.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/NemalineMyopathyPrenatal.java similarity index 94% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/NemalineMyopathyPrenatal.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/NemalineMyopathyPrenatal.java index 126ba77d..aa934690 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/NemalineMyopathyPrenatal.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/NemalineMyopathyPrenatal.java @@ -1,18 +1,18 @@ -package org.phenopackets.phenotools.examples; +package org.phenopackets.phenopackettools.examples; import org.ga4gh.vrs.v1.Variation; import org.ga4gh.vrsatile.v1.Expression; import org.ga4gh.vrsatile.v1.GeneDescriptor; -import org.phenopackets.phenotools.builder.PhenopacketBuilder; -import org.phenopackets.phenotools.builder.builders.*; +import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; +import org.phenopackets.phenopackettools.builder.builders.*; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; import java.util.List; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; -import static org.phenopackets.phenotools.builder.builders.PhenotypicFeatureBuilder.phenotypicFeature; -import static org.phenopackets.phenotools.builder.builders.TimeElements.gestationalAge; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.PhenotypicFeatureBuilder.phenotypicFeature; +import static org.phenopackets.phenopackettools.builder.builders.TimeElements.gestationalAge; /** * From Clin. Exp. Obstet. Gynecol. - ISSN: 0390-6663 diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/PhenopacketExample.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/PhenopacketExample.java similarity index 69% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/PhenopacketExample.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/PhenopacketExample.java index d020b68f..bef790d8 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/PhenopacketExample.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/PhenopacketExample.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.examples; +package org.phenopackets.phenopackettools.examples; import org.phenopackets.schema.v2.Phenopacket; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/PhenopacketExamples.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/PhenopacketExamples.java similarity index 97% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/PhenopacketExamples.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/PhenopacketExamples.java index 3d9de639..8ef52ddf 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/PhenopacketExamples.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/PhenopacketExamples.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.examples; +package org.phenopackets.phenopackettools.examples; import org.phenopackets.schema.v2.Phenopacket; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Retinoblastoma.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java similarity index 97% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Retinoblastoma.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java index 9b6b0d48..d11fff8a 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Retinoblastoma.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java @@ -1,15 +1,15 @@ -package org.phenopackets.phenotools.examples; +package org.phenopackets.phenopackettools.examples; -import org.phenopackets.phenotools.builder.PhenopacketBuilder; -import org.phenopackets.phenotools.builder.builders.*; -import org.phenopackets.phenotools.builder.constants.Laterality; -import org.phenopackets.phenotools.builder.constants.Unit; +import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; +import org.phenopackets.phenopackettools.builder.builders.*; +import org.phenopackets.phenopackettools.builder.constants.Laterality; +import org.phenopackets.phenopackettools.builder.constants.Unit; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; import java.util.List; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; public class Retinoblastoma implements PhenopacketExample { private static final String PHENOPACKET_ID = "arbitrary.id"; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/SquamousCellCancer.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SquamousCellCancer.java similarity index 92% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/SquamousCellCancer.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SquamousCellCancer.java index 7915ff4b..8626dc28 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/SquamousCellCancer.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SquamousCellCancer.java @@ -1,12 +1,12 @@ -package org.phenopackets.phenotools.examples; +package org.phenopackets.phenopackettools.examples; -import org.phenopackets.phenotools.builder.PhenopacketBuilder; -import org.phenopackets.phenotools.builder.builders.*; +import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; +import org.phenopackets.phenopackettools.builder.builders.*; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.Individual; import org.phenopackets.schema.v2.core.OntologyClass; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; class SquamousCellCancer implements PhenopacketExample { private static final String PHENOPACKET_ID = "arbitrary.id"; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Thrombocytopenia2.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Thrombocytopenia2.java similarity index 89% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Thrombocytopenia2.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Thrombocytopenia2.java index 44e4a917..ba0d8e0d 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Thrombocytopenia2.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Thrombocytopenia2.java @@ -1,11 +1,11 @@ -package org.phenopackets.phenotools.examples; +package org.phenopackets.phenopackettools.examples; -import org.phenopackets.phenotools.builder.PhenopacketBuilder; -import org.phenopackets.phenotools.builder.builders.*; -import org.phenopackets.phenotools.builder.constants.Status; +import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; +import org.phenopackets.phenopackettools.builder.builders.*; +import org.phenopackets.phenopackettools.builder.constants.Status; import org.phenopackets.schema.v2.Phenopacket; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; class Thrombocytopenia2 implements PhenopacketExample { private static final String PHENOPACKET_ID = "id-C"; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/UrothelialCancer.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/UrothelialCancer.java similarity index 95% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/UrothelialCancer.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/UrothelialCancer.java index d7211829..5f9e0cc0 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/UrothelialCancer.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/UrothelialCancer.java @@ -1,13 +1,13 @@ -package org.phenopackets.phenotools.examples; +package org.phenopackets.phenopackettools.examples; -import org.phenopackets.phenotools.builder.PhenopacketBuilder; -import org.phenopackets.phenotools.builder.builders.*; -import org.phenopackets.phenotools.builder.constants.Severity; +import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; +import org.phenopackets.phenopackettools.builder.builders.*; +import org.phenopackets.phenopackettools.builder.constants.Severity; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; class UrothelialCancer implements PhenopacketExample { private static final String PHENOPACKET_ID = "arbitrary.id"; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/WarburgMicroSyndrome.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/WarburgMicroSyndrome.java similarity index 92% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/WarburgMicroSyndrome.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/WarburgMicroSyndrome.java index 7b630ed9..ba45b25f 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/WarburgMicroSyndrome.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/WarburgMicroSyndrome.java @@ -1,14 +1,14 @@ -package org.phenopackets.phenotools.examples; +package org.phenopackets.phenopackettools.examples; -import org.phenopackets.phenotools.builder.PhenopacketBuilder; -import org.phenopackets.phenotools.builder.builders.*; +import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; +import org.phenopackets.phenopackettools.builder.builders.*; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; import java.util.ArrayList; import java.util.List; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; /** * Léonard A, et al. Prenatal diagnosis of fetal cataract: case report and review of the literature. diff --git a/phenotools-cli/src/main/resources/logback.xml b/phenopacket-tools-cli/src/main/resources/logback.xml similarity index 100% rename from phenotools-cli/src/main/resources/logback.xml rename to phenopacket-tools-cli/src/main/resources/logback.xml diff --git a/phenotools-converter/pom.xml b/phenopacket-tools-converter/pom.xml similarity index 83% rename from phenotools-converter/pom.xml rename to phenopacket-tools-converter/pom.xml index 760cfb89..bdc3f39b 100644 --- a/phenotools-converter/pom.xml +++ b/phenopacket-tools-converter/pom.xml @@ -5,12 +5,12 @@ 4.0.0 - org.phenopackets.phenotools - phenotools + org.phenopackets.phenopackettools + phenopacket-tools 1.0.0 - phenotools-converter + phenopacket-tools-converter diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/CohortConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/CohortConverter.java similarity index 70% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/CohortConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/CohortConverter.java index f54f9bae..15613e88 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/CohortConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/CohortConverter.java @@ -1,10 +1,10 @@ -package org.phenopackets.phenotools.converter.converters; +package org.phenopackets.phenopackettools.converter.converters; import org.phenopackets.schema.v2.Cohort; -import static org.phenopackets.phenotools.converter.converters.PhenopacketConverter.toV2Phenopackets; -import static org.phenopackets.phenotools.converter.converters.v2.FileConverter.toFiles; -import static org.phenopackets.phenotools.converter.converters.v2.MetaDataConverter.toMetaData; +import static org.phenopackets.phenopackettools.converter.converters.PhenopacketConverter.toV2Phenopackets; +import static org.phenopackets.phenopackettools.converter.converters.v2.FileConverter.toFiles; +import static org.phenopackets.phenopackettools.converter.converters.v2.MetaDataConverter.toMetaData; public class CohortConverter { diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/FamilyConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/FamilyConverter.java similarity index 63% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/FamilyConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/FamilyConverter.java index a41f0a4f..d1c66c99 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/FamilyConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/FamilyConverter.java @@ -1,12 +1,12 @@ -package org.phenopackets.phenotools.converter.converters; +package org.phenopackets.phenopackettools.converter.converters; import org.phenopackets.schema.v2.Family; -import static org.phenopackets.phenotools.converter.converters.PhenopacketConverter.toV2Phenopacket; -import static org.phenopackets.phenotools.converter.converters.PhenopacketConverter.toV2Phenopackets; -import static org.phenopackets.phenotools.converter.converters.v2.FileConverter.toFiles; -import static org.phenopackets.phenotools.converter.converters.v2.MetaDataConverter.toMetaData; -import static org.phenopackets.phenotools.converter.converters.v2.PedigreeConverter.toPedigree; +import static org.phenopackets.phenopackettools.converter.converters.PhenopacketConverter.toV2Phenopacket; +import static org.phenopackets.phenopackettools.converter.converters.PhenopacketConverter.toV2Phenopackets; +import static org.phenopackets.phenopackettools.converter.converters.v2.FileConverter.toFiles; +import static org.phenopackets.phenopackettools.converter.converters.v2.MetaDataConverter.toMetaData; +import static org.phenopackets.phenopackettools.converter.converters.v2.PedigreeConverter.toPedigree; public class FamilyConverter { diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/PhenopacketConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/PhenopacketConverter.java similarity index 70% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/PhenopacketConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/PhenopacketConverter.java index 64701c3c..45017aeb 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/PhenopacketConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/PhenopacketConverter.java @@ -1,16 +1,16 @@ -package org.phenopackets.phenotools.converter.converters; +package org.phenopackets.phenopackettools.converter.converters; import org.phenopackets.schema.v2.Phenopacket; import java.util.List; import java.util.stream.Collectors; -import static org.phenopackets.phenotools.converter.converters.v2.BiosampleConverter.toBiosamples; -import static org.phenopackets.phenotools.converter.converters.v2.DiseaseConverter.toDiseases; -import static org.phenopackets.phenotools.converter.converters.v2.FileConverter.toFiles; -import static org.phenopackets.phenotools.converter.converters.v2.IndividualConverter.toIndividual; -import static org.phenopackets.phenotools.converter.converters.v2.MetaDataConverter.toMetaData; -import static org.phenopackets.phenotools.converter.converters.v2.PhenotypicFeatureConverter.toPhenotypicFeatures; +import static org.phenopackets.phenopackettools.converter.converters.v2.BiosampleConverter.toBiosamples; +import static org.phenopackets.phenopackettools.converter.converters.v2.DiseaseConverter.toDiseases; +import static org.phenopackets.phenopackettools.converter.converters.v2.FileConverter.toFiles; +import static org.phenopackets.phenopackettools.converter.converters.v2.IndividualConverter.toIndividual; +import static org.phenopackets.phenopackettools.converter.converters.v2.MetaDataConverter.toMetaData; +import static org.phenopackets.phenopackettools.converter.converters.v2.PhenotypicFeatureConverter.toPhenotypicFeatures; public class PhenopacketConverter { diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/AgeConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/AgeConverter.java similarity index 89% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/AgeConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/AgeConverter.java index dfde86cc..fc07233b 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/AgeConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/AgeConverter.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.converter.converters.v2; +package org.phenopackets.phenopackettools.converter.converters.v2; import org.phenopackets.schema.v2.core.Age; import org.phenopackets.schema.v2.core.AgeRange; diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/BiosampleConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/BiosampleConverter.java similarity index 85% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/BiosampleConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/BiosampleConverter.java index 82f81ee3..ec675f08 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/BiosampleConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/BiosampleConverter.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.converter.converters.v2; +package org.phenopackets.phenopackettools.converter.converters.v2; import org.phenopackets.schema.v2.core.Biosample; import org.phenopackets.schema.v2.core.OntologyClass; @@ -7,11 +7,11 @@ import java.util.List; import java.util.stream.Collectors; -import static org.phenopackets.phenotools.converter.converters.v2.FileConverter.toFiles; -import static org.phenopackets.phenotools.converter.converters.v2.OntologyClassConverter.toOntologyClass; -import static org.phenopackets.phenotools.converter.converters.v2.OntologyClassConverter.toOntologyClassList; -import static org.phenopackets.phenotools.converter.converters.v2.PhenotypicFeatureConverter.*; -import static org.phenopackets.phenotools.converter.converters.v2.ProcedureConverter.toProcedure; +import static org.phenopackets.phenopackettools.converter.converters.v2.FileConverter.toFiles; +import static org.phenopackets.phenopackettools.converter.converters.v2.OntologyClassConverter.toOntologyClass; +import static org.phenopackets.phenopackettools.converter.converters.v2.OntologyClassConverter.toOntologyClassList; +import static org.phenopackets.phenopackettools.converter.converters.v2.PhenotypicFeatureConverter.*; +import static org.phenopackets.phenopackettools.converter.converters.v2.ProcedureConverter.toProcedure; public class BiosampleConverter { diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/DiseaseConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/DiseaseConverter.java similarity index 81% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/DiseaseConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/DiseaseConverter.java index 82a9717a..54b61d40 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/DiseaseConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/DiseaseConverter.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.converter.converters.v2; +package org.phenopackets.phenopackettools.converter.converters.v2; import org.phenopackets.schema.v2.core.Disease; import org.phenopackets.schema.v2.core.TimeElement; @@ -6,9 +6,9 @@ import java.util.List; import java.util.stream.Collectors; -import static org.phenopackets.phenotools.converter.converters.v2.AgeConverter.toAge; -import static org.phenopackets.phenotools.converter.converters.v2.AgeConverter.toAgeRange; -import static org.phenopackets.phenotools.converter.converters.v2.OntologyClassConverter.*; +import static org.phenopackets.phenopackettools.converter.converters.v2.AgeConverter.toAge; +import static org.phenopackets.phenopackettools.converter.converters.v2.AgeConverter.toAgeRange; +import static org.phenopackets.phenopackettools.converter.converters.v2.OntologyClassConverter.*; public class DiseaseConverter { diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/EvidenceConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/EvidenceConverter.java similarity index 74% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/EvidenceConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/EvidenceConverter.java index bb757d71..6aafb9fa 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/EvidenceConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/EvidenceConverter.java @@ -1,12 +1,12 @@ -package org.phenopackets.phenotools.converter.converters.v2; +package org.phenopackets.phenopackettools.converter.converters.v2; import org.phenopackets.schema.v2.core.Evidence; import java.util.List; import java.util.stream.Collectors; -import static org.phenopackets.phenotools.converter.converters.v2.ExternalReferenceConverter.toExternalReference; -import static org.phenopackets.phenotools.converter.converters.v2.OntologyClassConverter.toOntologyClass; +import static org.phenopackets.phenopackettools.converter.converters.v2.ExternalReferenceConverter.toExternalReference; +import static org.phenopackets.phenopackettools.converter.converters.v2.OntologyClassConverter.toOntologyClass; public class EvidenceConverter { diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/ExternalReferenceConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/ExternalReferenceConverter.java similarity index 94% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/ExternalReferenceConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/ExternalReferenceConverter.java index 53f9b3e4..2b7b6ba8 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/ExternalReferenceConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/ExternalReferenceConverter.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.converter.converters.v2; +package org.phenopackets.phenopackettools.converter.converters.v2; import org.phenopackets.schema.v2.core.ExternalReference; diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/FileConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/FileConverter.java similarity index 93% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/FileConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/FileConverter.java index 7fa211e7..8ccb90ec 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/FileConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/FileConverter.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.converter.converters.v2; +package org.phenopackets.phenopackettools.converter.converters.v2; import org.phenopackets.schema.v1.core.HtsFile; import org.phenopackets.schema.v2.core.File; diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/IndividualConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/IndividualConverter.java similarity index 88% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/IndividualConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/IndividualConverter.java index 8ee5e4ea..b78595e3 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/IndividualConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/IndividualConverter.java @@ -1,13 +1,13 @@ -package org.phenopackets.phenotools.converter.converters.v2; +package org.phenopackets.phenopackettools.converter.converters.v2; import org.phenopackets.schema.v2.core.Individual; import org.phenopackets.schema.v2.core.KaryotypicSex; import org.phenopackets.schema.v2.core.Sex; import org.phenopackets.schema.v2.core.TimeElement; -import static org.phenopackets.phenotools.converter.converters.v2.AgeConverter.toAge; -import static org.phenopackets.phenotools.converter.converters.v2.AgeConverter.toAgeRange; -import static org.phenopackets.phenotools.converter.converters.v2.OntologyClassConverter.toOntologyClass; +import static org.phenopackets.phenopackettools.converter.converters.v2.AgeConverter.toAge; +import static org.phenopackets.phenopackettools.converter.converters.v2.AgeConverter.toAgeRange; +import static org.phenopackets.phenopackettools.converter.converters.v2.OntologyClassConverter.toOntologyClass; public class IndividualConverter { diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/MetaDataConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/MetaDataConverter.java similarity index 82% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/MetaDataConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/MetaDataConverter.java index d56e15f5..89d1dc1f 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/MetaDataConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/MetaDataConverter.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.converter.converters.v2; +package org.phenopackets.phenopackettools.converter.converters.v2; import org.phenopackets.schema.v2.core.MetaData; import org.phenopackets.schema.v2.core.Update; @@ -6,8 +6,8 @@ import java.util.List; import java.util.stream.Collectors; -import static org.phenopackets.phenotools.converter.converters.v2.ExternalReferenceConverter.toExternalReferences; -import static org.phenopackets.phenotools.converter.converters.v2.ResourceConverter.toResources; +import static org.phenopackets.phenopackettools.converter.converters.v2.ExternalReferenceConverter.toExternalReferences; +import static org.phenopackets.phenopackettools.converter.converters.v2.ResourceConverter.toResources; public class MetaDataConverter { diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/OntologyClassConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/OntologyClassConverter.java similarity index 93% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/OntologyClassConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/OntologyClassConverter.java index 91b62a78..cfa36290 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/OntologyClassConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/OntologyClassConverter.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.converter.converters.v2; +package org.phenopackets.phenopackettools.converter.converters.v2; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/PedigreeConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/PedigreeConverter.java similarity index 92% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/PedigreeConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/PedigreeConverter.java index b8e8f471..fefc12fa 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/PedigreeConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/PedigreeConverter.java @@ -1,11 +1,11 @@ -package org.phenopackets.phenotools.converter.converters.v2; +package org.phenopackets.phenopackettools.converter.converters.v2; import org.phenopackets.schema.v2.core.Pedigree; import java.util.List; import java.util.stream.Collectors; -import static org.phenopackets.phenotools.converter.converters.v2.IndividualConverter.toSex; +import static org.phenopackets.phenopackettools.converter.converters.v2.IndividualConverter.toSex; public class PedigreeConverter { diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/PhenotypicFeatureConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/PhenotypicFeatureConverter.java similarity index 82% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/PhenotypicFeatureConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/PhenotypicFeatureConverter.java index 0f2f2780..eae73185 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/PhenotypicFeatureConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/PhenotypicFeatureConverter.java @@ -1,15 +1,15 @@ -package org.phenopackets.phenotools.converter.converters.v2; +package org.phenopackets.phenopackettools.converter.converters.v2; import org.phenopackets.schema.v2.core.*; import java.util.List; import java.util.stream.Collectors; -import static org.phenopackets.phenotools.converter.converters.v2.AgeConverter.toAge; -import static org.phenopackets.phenotools.converter.converters.v2.AgeConverter.toAgeRange; -import static org.phenopackets.phenotools.converter.converters.v2.EvidenceConverter.toEvidences; -import static org.phenopackets.phenotools.converter.converters.v2.OntologyClassConverter.toOntologyClass; -import static org.phenopackets.phenotools.converter.converters.v2.OntologyClassConverter.toOntologyClassList; +import static org.phenopackets.phenopackettools.converter.converters.v2.AgeConverter.toAge; +import static org.phenopackets.phenopackettools.converter.converters.v2.AgeConverter.toAgeRange; +import static org.phenopackets.phenopackettools.converter.converters.v2.EvidenceConverter.toEvidences; +import static org.phenopackets.phenopackettools.converter.converters.v2.OntologyClassConverter.toOntologyClass; +import static org.phenopackets.phenopackettools.converter.converters.v2.OntologyClassConverter.toOntologyClassList; public class PhenotypicFeatureConverter { diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/ProcedureConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/ProcedureConverter.java similarity index 79% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/ProcedureConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/ProcedureConverter.java index 55c9b5ad..efe6aa89 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/ProcedureConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/ProcedureConverter.java @@ -1,8 +1,8 @@ -package org.phenopackets.phenotools.converter.converters.v2; +package org.phenopackets.phenopackettools.converter.converters.v2; import org.phenopackets.schema.v2.core.Procedure; -import static org.phenopackets.phenotools.converter.converters.v2.OntologyClassConverter.toOntologyClass; +import static org.phenopackets.phenopackettools.converter.converters.v2.OntologyClassConverter.toOntologyClass; public class ProcedureConverter { diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/ResourceConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/ResourceConverter.java similarity index 92% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/ResourceConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/ResourceConverter.java index 2143bbdc..9df11e55 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/ResourceConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/ResourceConverter.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.converter.converters.v2; +package org.phenopackets.phenopackettools.converter.converters.v2; import org.phenopackets.schema.v2.core.Resource; diff --git a/phenotools-converter/src/test/java/org/phenopackets/phenotools/converter/BethlemMyopathyV1.java b/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/BethlemMyopathyV1.java similarity index 99% rename from phenotools-converter/src/test/java/org/phenopackets/phenotools/converter/BethlemMyopathyV1.java rename to phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/BethlemMyopathyV1.java index 36bb8d0a..5a1c5375 100644 --- a/phenotools-converter/src/test/java/org/phenopackets/phenotools/converter/BethlemMyopathyV1.java +++ b/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/BethlemMyopathyV1.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.converter; +package org.phenopackets.phenopackettools.converter; import com.google.protobuf.Timestamp; import org.phenopackets.schema.v1.Phenopacket; diff --git a/phenotools-converter/src/test/java/org/phenopackets/phenotools/converter/PhenopacketConverterTest.java b/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java similarity index 61% rename from phenotools-converter/src/test/java/org/phenopackets/phenotools/converter/PhenopacketConverterTest.java rename to phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java index d093a52d..44f63d7e 100644 --- a/phenotools-converter/src/test/java/org/phenopackets/phenotools/converter/PhenopacketConverterTest.java +++ b/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java @@ -1,9 +1,9 @@ -package org.phenopackets.phenotools.converter; +package org.phenopackets.phenopackettools.converter; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.util.JsonFormat; import org.junit.jupiter.api.Test; -import org.phenopackets.phenotools.converter.converters.PhenopacketConverter; +import org.phenopackets.phenopackettools.converter.converters.PhenopacketConverter; class PhenopacketConverterTest { @@ -13,7 +13,7 @@ void name() throws InvalidProtocolBufferException { org.phenopackets.schema.v2.Phenopacket v2Phenopacket = PhenopacketConverter.toV2Phenopacket(v1Phenopacket); - System.out.println(JsonFormat.printer().print(v1Phenopacket)); - System.out.println(JsonFormat.printer().print(v2Phenopacket)); +// System.out.println(JsonFormat.printer().print(v1Phenopacket)); +// System.out.println(JsonFormat.printer().print(v2Phenopacket)); } } \ No newline at end of file diff --git a/phenotools-validator-core/.mvn/wrapper/maven-wrapper.properties b/phenopacket-tools-validator-core/.mvn/wrapper/maven-wrapper.properties similarity index 100% rename from phenotools-validator-core/.mvn/wrapper/maven-wrapper.properties rename to phenopacket-tools-validator-core/.mvn/wrapper/maven-wrapper.properties diff --git a/phenotools-validator-core/mvnw b/phenopacket-tools-validator-core/mvnw similarity index 100% rename from phenotools-validator-core/mvnw rename to phenopacket-tools-validator-core/mvnw diff --git a/phenotools-validator-core/mvnw.cmd b/phenopacket-tools-validator-core/mvnw.cmd similarity index 100% rename from phenotools-validator-core/mvnw.cmd rename to phenopacket-tools-validator-core/mvnw.cmd diff --git a/phenotools-validator-core/pom.xml b/phenopacket-tools-validator-core/pom.xml similarity index 66% rename from phenotools-validator-core/pom.xml rename to phenopacket-tools-validator-core/pom.xml index d524474c..77457cb5 100644 --- a/phenotools-validator-core/pom.xml +++ b/phenopacket-tools-validator-core/pom.xml @@ -5,14 +5,14 @@ 4.0.0 - org.phenopackets.phenotools - phenotools + org.phenopackets.phenopackettools + phenopacket-tools 1.0.0 - phenotools-validator-core + phenopacket-tools-validator-core - phenotools-validator-core + phenopacket-tools-validator-core Validator utilities for phenopackets \ No newline at end of file diff --git a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/DefaultValidationInfo.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidationInfo.java similarity index 96% rename from phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/DefaultValidationInfo.java rename to phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidationInfo.java index 6db64beb..6ca82b34 100644 --- a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/DefaultValidationInfo.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidationInfo.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.validator.core; +package org.phenopackets.phenopackettools.validator.core; import java.util.Objects; diff --git a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ErrorType.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ErrorType.java similarity index 88% rename from phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ErrorType.java rename to phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ErrorType.java index dbc06a51..bf87300c 100644 --- a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ErrorType.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ErrorType.java @@ -1,6 +1,6 @@ -package org.phenopackets.phenotools.validator.core; +package org.phenopackets.phenopackettools.validator.core; -import org.phenopackets.phenotools.validator.core.except.PhenopacketValidatorRuntimeException; +import org.phenopackets.phenopackettools.validator.core.except.PhenopacketValidatorRuntimeException; public enum ErrorType { /** JSON schema error meaning that the JSON code contained a property not present in the schema. */ diff --git a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidator.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidator.java similarity index 94% rename from phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidator.java rename to phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidator.java index 6be6b4c7..1b6fe42a 100644 --- a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidator.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidator.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.validator.core; +package org.phenopackets.phenopackettools.validator.core; import java.io.ByteArrayInputStream; import java.io.File; diff --git a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidatorFactory.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidatorFactory.java similarity index 85% rename from phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidatorFactory.java rename to phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidatorFactory.java index 7664fae0..1eb427e7 100644 --- a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidatorFactory.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidatorFactory.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.validator.core; +package org.phenopackets.phenopackettools.validator.core; import java.util.Optional; diff --git a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidationAspect.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationAspect.java similarity index 86% rename from phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidationAspect.java rename to phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationAspect.java index 75034e5b..122594f7 100644 --- a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidationAspect.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationAspect.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.validator.core; +package org.phenopackets.phenopackettools.validator.core; public enum ValidationAspect { diff --git a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidationItem.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationItem.java similarity index 90% rename from phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidationItem.java rename to phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationItem.java index 73361c60..b076eb8f 100644 --- a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidationItem.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationItem.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.validator.core; +package org.phenopackets.phenopackettools.validator.core; /** * The interface represents a single issue found during validation. diff --git a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorInfo.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorInfo.java similarity index 93% rename from phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorInfo.java rename to phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorInfo.java index 66b7e9b2..9beb6b00 100644 --- a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorInfo.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorInfo.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.validator.core; +package org.phenopackets.phenopackettools.validator.core; public interface ValidatorInfo { diff --git a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorRunner.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorRunner.java similarity index 96% rename from phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorRunner.java rename to phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorRunner.java index 9d1f56bf..ed898d25 100644 --- a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorRunner.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorRunner.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.validator.core; +package org.phenopackets.phenopackettools.validator.core; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/except/PhenopacketValidatorRuntimeException.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/except/PhenopacketValidatorRuntimeException.java similarity index 91% rename from phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/except/PhenopacketValidatorRuntimeException.java rename to phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/except/PhenopacketValidatorRuntimeException.java index c8168200..663d3e15 100644 --- a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/except/PhenopacketValidatorRuntimeException.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/except/PhenopacketValidatorRuntimeException.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.validator.core.except; +package org.phenopackets.phenopackettools.validator.core.except; public class PhenopacketValidatorRuntimeException extends RuntimeException { diff --git a/phenotools-validator-jsonschema/pom.xml b/phenopacket-tools-validator-jsonschema/pom.xml similarity index 77% rename from phenotools-validator-jsonschema/pom.xml rename to phenopacket-tools-validator-jsonschema/pom.xml index 6d2ffe4a..9c40e153 100644 --- a/phenotools-validator-jsonschema/pom.xml +++ b/phenopacket-tools-validator-jsonschema/pom.xml @@ -5,20 +5,20 @@ 4.0.0 - org.phenopackets.phenotools - phenotools + org.phenopackets.phenopackettools + phenopacket-tools 1.0.0 - phenotools-validator-jsonschema + phenopacket-tools-validator-jsonschema - phenotools-validator-jsonschema + phenopacket-tools-validator-jsonschema JSON schema validator utilities for phenopackets - org.phenopackets.phenotools - phenotools-validator-core + org.phenopackets.phenopackettools + phenopacket-tools-validator-core ${project.parent.version} @@ -46,4 +46,4 @@ - \ No newline at end of file + diff --git a/phenotools-validator-jsonschema/src/main/java/org/phenopackets/phenotools/validator/jsonschema/ClasspathJsonSchemaValidatorFactory.java b/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/ClasspathJsonSchemaValidatorFactory.java similarity index 84% rename from phenotools-validator-jsonschema/src/main/java/org/phenopackets/phenotools/validator/jsonschema/ClasspathJsonSchemaValidatorFactory.java rename to phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/ClasspathJsonSchemaValidatorFactory.java index 042af326..e9d3f21c 100644 --- a/phenotools-validator-jsonschema/src/main/java/org/phenopackets/phenotools/validator/jsonschema/ClasspathJsonSchemaValidatorFactory.java +++ b/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/ClasspathJsonSchemaValidatorFactory.java @@ -1,9 +1,9 @@ -package org.phenopackets.phenotools.validator.jsonschema; +package org.phenopackets.phenopackettools.validator.jsonschema; -import org.phenopackets.phenotools.validator.core.PhenopacketValidator; -import org.phenopackets.phenotools.validator.core.PhenopacketValidatorFactory; -import org.phenopackets.phenotools.validator.core.ValidatorInfo; -import org.phenopackets.phenotools.validator.core.except.PhenopacketValidatorRuntimeException; +import org.phenopackets.phenopackettools.validator.core.PhenopacketValidator; +import org.phenopackets.phenopackettools.validator.core.PhenopacketValidatorFactory; +import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; +import org.phenopackets.phenopackettools.validator.core.except.PhenopacketValidatorRuntimeException; import java.io.InputStream; import java.util.Map; diff --git a/phenotools-validator-jsonschema/src/main/java/org/phenopackets/phenotools/validator/jsonschema/JsonSchemaValidator.java b/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidator.java similarity index 90% rename from phenotools-validator-jsonschema/src/main/java/org/phenopackets/phenotools/validator/jsonschema/JsonSchemaValidator.java rename to phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidator.java index 1679ffd9..004e99e5 100644 --- a/phenotools-validator-jsonschema/src/main/java/org/phenopackets/phenotools/validator/jsonschema/JsonSchemaValidator.java +++ b/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidator.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.validator.jsonschema; +package org.phenopackets.phenopackettools.validator.jsonschema; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -6,10 +6,10 @@ import com.networknt.schema.JsonSchema; import com.networknt.schema.JsonSchemaFactory; import com.networknt.schema.SpecVersion; -import org.phenopackets.phenotools.validator.core.PhenopacketValidator; -import org.phenopackets.phenotools.validator.core.ValidatorInfo; -import org.phenopackets.phenotools.validator.core.except.PhenopacketValidatorRuntimeException; -import org.phenopackets.phenotools.validator.core.ValidationItem; +import org.phenopackets.phenopackettools.validator.core.PhenopacketValidator; +import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; +import org.phenopackets.phenopackettools.validator.core.except.PhenopacketValidatorRuntimeException; +import org.phenopackets.phenopackettools.validator.core.ValidationItem; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/phenotools-validator-jsonschema/src/main/java/org/phenopackets/phenotools/validator/jsonschema/JsonValidationError.java b/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonValidationError.java similarity index 85% rename from phenotools-validator-jsonschema/src/main/java/org/phenopackets/phenotools/validator/jsonschema/JsonValidationError.java rename to phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonValidationError.java index de45c9ac..82ad27da 100644 --- a/phenotools-validator-jsonschema/src/main/java/org/phenopackets/phenotools/validator/jsonschema/JsonValidationError.java +++ b/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonValidationError.java @@ -1,9 +1,9 @@ -package org.phenopackets.phenotools.validator.jsonschema; +package org.phenopackets.phenopackettools.validator.jsonschema; import com.networknt.schema.ValidationMessage; -import org.phenopackets.phenotools.validator.core.ErrorType; -import org.phenopackets.phenotools.validator.core.ValidationItem; -import org.phenopackets.phenotools.validator.core.ValidatorInfo; +import org.phenopackets.phenopackettools.validator.core.ErrorType; +import org.phenopackets.phenopackettools.validator.core.ValidationItem; +import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; import java.util.Objects; diff --git a/phenotools-validator-jsonschema/src/main/resources/schema/hpo-rare-disease-schema.json b/phenopacket-tools-validator-jsonschema/src/main/resources/schema/hpo-rare-disease-schema.json similarity index 100% rename from phenotools-validator-jsonschema/src/main/resources/schema/hpo-rare-disease-schema.json rename to phenopacket-tools-validator-jsonschema/src/main/resources/schema/hpo-rare-disease-schema.json diff --git a/phenotools-validator-jsonschema/src/main/resources/schema/phenopacket-schema-2-0.json b/phenopacket-tools-validator-jsonschema/src/main/resources/schema/phenopacket-schema-2-0.json similarity index 100% rename from phenotools-validator-jsonschema/src/main/resources/schema/phenopacket-schema-2-0.json rename to phenopacket-tools-validator-jsonschema/src/main/resources/schema/phenopacket-schema-2-0.json diff --git a/phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools/validator/jsonschema/JsonSchemaDiseaseValidatorTest.java b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaDiseaseValidatorTest.java similarity index 84% rename from phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools/validator/jsonschema/JsonSchemaDiseaseValidatorTest.java rename to phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaDiseaseValidatorTest.java index 6e7fe83f..93fc037a 100644 --- a/phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools/validator/jsonschema/JsonSchemaDiseaseValidatorTest.java +++ b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaDiseaseValidatorTest.java @@ -1,14 +1,14 @@ -package org.phenopackets.phenotools.validator.jsonschema; +package org.phenopackets.phenopackettools.validator.jsonschema; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.util.JsonFormat; import org.junit.jupiter.api.Test; -import org.phenopackets.phenotools.validator.core.PhenopacketValidator; -import org.phenopackets.phenotools.validator.core.ErrorType; -import org.phenopackets.phenotools.validator.core.ValidationItem; -import org.phenopackets.phenotools.validator.core.ValidatorInfo; -import org.phenopackets.phenotools.validator.testdatagen.PhenopacketUtil; +import org.phenopackets.phenopackettools.validator.core.PhenopacketValidator; +import org.phenopackets.phenopackettools.validator.core.ErrorType; +import org.phenopackets.phenopackettools.validator.core.ValidationItem; +import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; +import org.phenopackets.phenopackettools.validator.testdatagen.PhenopacketUtil; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.Disease; import org.phenopackets.schema.v2.core.MetaData; @@ -19,7 +19,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.phenopackets.phenotools.validator.testdatagen.PhenopacketUtil.*; +import static org.phenopackets.phenopackettools.validator.testdatagen.PhenopacketUtil.*; /** * This class creates a simple phenopacket with a Disease object and creates some variations with @@ -77,9 +77,9 @@ public void testLacksId() throws InvalidProtocolBufferException { // the Phenopacket is not valid if we remove the id Phenopacket p1 = Phenopacket.newBuilder(phenopacket).clearId().build(); String json = JsonFormat.printer().print(p1); - System.out.println(json); +// System.out.println(json); List errors = validator.validate(json); - System.out.println(errors); +// System.out.println(errors); assertEquals(1, errors.size()); ValidationItem error = errors.get(0); assertEquals(ErrorType.JSON_REQUIRED, error.errorType()); diff --git a/phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools/validator/jsonschema/JsonSchemaValidatorTest.java b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidatorTest.java similarity index 88% rename from phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools/validator/jsonschema/JsonSchemaValidatorTest.java rename to phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidatorTest.java index 4732c94c..9ecbc547 100644 --- a/phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools/validator/jsonschema/JsonSchemaValidatorTest.java +++ b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidatorTest.java @@ -1,13 +1,13 @@ -package org.phenopackets.phenotools.validator.jsonschema; +package org.phenopackets.phenopackettools.validator.jsonschema; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import org.phenopackets.phenotools.validator.core.ErrorType; -import org.phenopackets.phenotools.validator.core.PhenopacketValidator; -import org.phenopackets.phenotools.validator.core.ValidationItem; -import org.phenopackets.phenotools.validator.core.ValidatorInfo; -import org.phenopackets.phenotools.validator.testdatagen.RareDiseasePhenopacket; -import org.phenopackets.phenotools.validator.testdatagen.SimplePhenopacket; +import org.phenopackets.phenopackettools.validator.core.ErrorType; +import org.phenopackets.phenopackettools.validator.core.PhenopacketValidator; +import org.phenopackets.phenopackettools.validator.core.ValidationItem; +import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; +import org.phenopackets.phenopackettools.validator.testdatagen.RareDiseasePhenopacket; +import org.phenopackets.phenopackettools.validator.testdatagen.SimplePhenopacket; import org.phenopackets.schema.v2.Phenopacket; import java.io.File; diff --git a/phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools/validator/testdatagen/PhenopacketUtil.java b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/testdatagen/PhenopacketUtil.java similarity index 99% rename from phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools/validator/testdatagen/PhenopacketUtil.java rename to phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/testdatagen/PhenopacketUtil.java index b43009c0..ffe9f473 100644 --- a/phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools/validator/testdatagen/PhenopacketUtil.java +++ b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/testdatagen/PhenopacketUtil.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.validator.testdatagen; +package org.phenopackets.phenopackettools.validator.testdatagen; import java.time.LocalDateTime; diff --git a/phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools/validator/testdatagen/RareDiseasePhenopacket.java b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/testdatagen/RareDiseasePhenopacket.java similarity index 93% rename from phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools/validator/testdatagen/RareDiseasePhenopacket.java rename to phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/testdatagen/RareDiseasePhenopacket.java index 9465c249..00e54ff8 100644 --- a/phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools/validator/testdatagen/RareDiseasePhenopacket.java +++ b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/testdatagen/RareDiseasePhenopacket.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.validator.testdatagen; +package org.phenopackets.phenopackettools.validator.testdatagen; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.File; @@ -6,7 +6,7 @@ import org.phenopackets.schema.v2.core.MetaData; import org.phenopackets.schema.v2.core.Resource; -import static org.phenopackets.phenotools.validator.testdatagen.PhenopacketUtil.*; +import static org.phenopackets.phenopackettools.validator.testdatagen.PhenopacketUtil.*; public class RareDiseasePhenopacket { diff --git a/phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools/validator/testdatagen/SimplePhenopacket.java b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/testdatagen/SimplePhenopacket.java similarity index 83% rename from phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools/validator/testdatagen/SimplePhenopacket.java rename to phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/testdatagen/SimplePhenopacket.java index 068aac3a..c6983130 100644 --- a/phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools/validator/testdatagen/SimplePhenopacket.java +++ b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/testdatagen/SimplePhenopacket.java @@ -1,10 +1,10 @@ -package org.phenopackets.phenotools.validator.testdatagen; +package org.phenopackets.phenopackettools.validator.testdatagen; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.MetaData; import org.phenopackets.schema.v2.core.Resource; -import static org.phenopackets.phenotools.validator.testdatagen.PhenopacketUtil.hpoResource; +import static org.phenopackets.phenopackettools.validator.testdatagen.PhenopacketUtil.hpoResource; /** diff --git a/phenotools-validator-jsonschema/src/test/resources/json/bethlehamMyopathyExample.json b/phenopacket-tools-validator-jsonschema/src/test/resources/json/bethlehamMyopathyExample.json similarity index 100% rename from phenotools-validator-jsonschema/src/test/resources/json/bethlehamMyopathyExample.json rename to phenopacket-tools-validator-jsonschema/src/test/resources/json/bethlehamMyopathyExample.json diff --git a/phenotools-validator-jsonschema/src/test/resources/json/bethlehamMyopathyInvalidExample.json b/phenopacket-tools-validator-jsonschema/src/test/resources/json/bethlehamMyopathyInvalidExample.json similarity index 100% rename from phenotools-validator-jsonschema/src/test/resources/json/bethlehamMyopathyInvalidExample.json rename to phenopacket-tools-validator-jsonschema/src/test/resources/json/bethlehamMyopathyInvalidExample.json diff --git a/phenotools-validator-jsonschema/src/test/resources/logback-test.xml b/phenopacket-tools-validator-jsonschema/src/test/resources/logback-test.xml similarity index 100% rename from phenotools-validator-jsonschema/src/test/resources/logback-test.xml rename to phenopacket-tools-validator-jsonschema/src/test/resources/logback-test.xml diff --git a/pom.xml b/pom.xml index ce14ddc2..e963c532 100644 --- a/pom.xml +++ b/pom.xml @@ -4,24 +4,24 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.phenopackets.phenotools - phenotools + org.phenopackets.phenopackettools + phenopacket-tools 1.0.0 pom - phenotools-builder - phenotools-validator-core - phenotools-validator-jsonschema - phenotools-converter - phenotools-cli + phenopacket-tools-builder + phenopacket-tools-validator-core + phenopacket-tools-validator-jsonschema + phenopacket-tools-converter + phenopacket-tools-cli org.springframework.boot spring-boot-starter-parent - 2.5.4 + 2.6.3 @@ -97,7 +97,6 @@ org.springframework.boot spring-boot-maven-plugin - 2.5.4 From 652a777cd6e001341d3163b53c11e41e70024e9f Mon Sep 17 00:00:00 2001 From: Jules Jacobsen Date: Thu, 14 Apr 2022 15:05:23 +0100 Subject: [PATCH 007/155] Update README.md example with new groupId --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 64b84869..23bb96fe 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ The cli application works in a standard UNIX-like manner. ```shell mvn package -alias pfx-tools='java -jar phenotools-cli/target/phenotools-cli-0.0.2-SNAPSHOT.jar' +alias pfx-tools='java -jar phenopacket-tools/phenopacket-tools-cli/target/phenopacket-tools-cli-1.0.0.jar' ``` ### Example Phenopackets From 99d274aa8996fae1f7db962dc08f47cd15a0c0a1 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Thu, 14 Apr 2022 12:02:28 -0400 Subject: [PATCH 008/155] adding constants for SpatialPattern --- .../builder/constants/SpatialPattern.java | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/SpatialPattern.java diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/SpatialPattern.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/SpatialPattern.java new file mode 100644 index 00000000..154425d2 --- /dev/null +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/SpatialPattern.java @@ -0,0 +1,84 @@ +package org.phenopackets.phenopackettools.builder.constants; + +import org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder; +import org.phenopackets.schema.v2.core.OntologyClass; + +public class SpatialPattern { + private static final OntologyClass PREDOMINANT_SMALL_JOINT_LOCALIZATION = OntologyClassBuilder.ontologyClass("HP:0032544", "Predominant small joint localization"); + private static final OntologyClass POLYCYCLIC = OntologyClassBuilder.ontologyClass("HP:0031450", "Polycyclic"); + private static final OntologyClass AXIAL = OntologyClassBuilder.ontologyClass("HP:0025287", "Axial"); + private static final OntologyClass PERILOBULAR = OntologyClassBuilder.ontologyClass("HP:0033813", "Perilobular"); + private static final OntologyClass PARASEPTAL = OntologyClassBuilder.ontologyClass("HP:0033814", "Paraseptal"); + private static final OntologyClass BRONCHOCENTRIC = OntologyClassBuilder.ontologyClass("HP:0033815", "Bronchocentric"); + private static final OntologyClass CENTRILOBULAR = OntologyClassBuilder.ontologyClass("HP:0033816", "Centrilobular"); + private static final OntologyClass MILIARY = OntologyClassBuilder.ontologyClass("HP:0033817", "Miliary"); + private static final OntologyClass GENERALIZED = OntologyClassBuilder.ontologyClass("HP:0012837", "Generalized"); + private static final OntologyClass PERILYMPHATIC = OntologyClassBuilder.ontologyClass("HP:0033819", "Perilymphatic"); + private static final OntologyClass LOCALIZED = OntologyClassBuilder.ontologyClass("HP:0012838", "Localized"); + private static final OntologyClass RETICULAR = OntologyClassBuilder.ontologyClass("HP:0033818", "Reticular"); + private static final OntologyClass DISTAL = OntologyClassBuilder.ontologyClass("HP:0012839", "Distal"); + private static final OntologyClass CERVICAL_NECK = OntologyClassBuilder.ontologyClass("HP:0032535", "Cervical (neck)"); + private static final OntologyClass CENTRAL = OntologyClassBuilder.ontologyClass("HP:0030645", "Central"); + private static final OntologyClass UPPER_BODY_PREDOMINANCE = OntologyClassBuilder.ontologyClass("HP:0025290", "Upper-body predominance"); + private static final OntologyClass SPATIAL_PATTERN = OntologyClassBuilder.ontologyClass("HP:0012836", "Spatial pattern"); + private static final OntologyClass JOINT_EXTENSOR_SURFACE_LOCALIZATION = OntologyClassBuilder.ontologyClass("HP:0032539", "Joint extensor surface localization"); + private static final OntologyClass HERPETIFORM = OntologyClassBuilder.ontologyClass("HP:0025295", "Herpetiform"); + private static final OntologyClass MORBILLIFORM = OntologyClassBuilder.ontologyClass("HP:0025296", "Morbilliform"); + private static final OntologyClass PERICENTRAL = OntologyClassBuilder.ontologyClass("HP:0030649", "Pericentral"); + private static final OntologyClass DERMATOMAL = OntologyClassBuilder.ontologyClass("HP:0025294", "Dermatomal"); + private static final OntologyClass MIDPERIPHERAL = OntologyClassBuilder.ontologyClass("HP:0030648", "Midperipheral"); + private static final OntologyClass DISTRIBUTED_ALONG_BLASCHKO_LINES = OntologyClassBuilder.ontologyClass("HP:0025293", "Distributed along Blaschko lines"); + private static final OntologyClass ACRAL = OntologyClassBuilder.ontologyClass("HP:0025292", "Acral"); + private static final OntologyClass PARACENTRAL = OntologyClassBuilder.ontologyClass("HP:0030647", "Paracentral"); + private static final OntologyClass LATERAL = OntologyClassBuilder.ontologyClass("HP:0025275", "Lateral"); + private static final OntologyClass PERIPHERAL = OntologyClassBuilder.ontologyClass("HP:0030646", "Peripheral"); + private static final OntologyClass LOWER_BODY_PREDOMINANCE = OntologyClassBuilder.ontologyClass("HP:0025291", "Lower-body predominance"); + private static final OntologyClass DIFFUSE = OntologyClassBuilder.ontologyClass("HP:0020034", "Diffuse"); + private static final OntologyClass PROXIMAL = OntologyClassBuilder.ontologyClass("HP:0012840", "Proximal"); + private static final OntologyClass APICAL = OntologyClassBuilder.ontologyClass("HP:0033820", "Apical"); + private static final OntologyClass FOCAL = OntologyClassBuilder.ontologyClass("HP:0030650", "Focal"); + private static final OntologyClass MULTIFOCAL = OntologyClassBuilder.ontologyClass("HP:0030651", "Multifocal"); + private static final OntologyClass JOINT_FLEXOR_SURFACE_LOCALIZATION = OntologyClassBuilder.ontologyClass("HP:0032540", "Joint flexor surface localization"); + + /** Do not allow instation of the constructor, this class just provides constants from the HPO + * Spatial Pattern subhierarchy, which is in the Clinical modifier subhierarchy. + */ + private SpatialPattern() {} + + + public static OntologyClass paraseptal() { return PARASEPTAL; } + public static OntologyClass lateral() { return LATERAL; } + public static OntologyClass perilobular() { return PERILOBULAR; } + public static OntologyClass morbilliform() { return MORBILLIFORM; } + public static OntologyClass centrilobular() { return CENTRILOBULAR; } + public static OntologyClass herpetiform() { return HERPETIFORM; } + public static OntologyClass bronchocentric() { return BRONCHOCENTRIC; } + public static OntologyClass dermatomal() { return DERMATOMAL; } + public static OntologyClass reticular() { return RETICULAR; } + public static OntologyClass spatialPattern() { return SPATIAL_PATTERN; } + public static OntologyClass miliary() { return MILIARY; } + public static OntologyClass generalized() { return GENERALIZED; } + public static OntologyClass localized() { return LOCALIZED; } + public static OntologyClass perilymphatic() { return PERILYMPHATIC; } + public static OntologyClass distal() { return DISTAL; } + public static OntologyClass jointFlexorSurfaceLocalization() { return JOINT_FLEXOR_SURFACE_LOCALIZATION; } + public static OntologyClass pericentral() { return PERICENTRAL; } + public static OntologyClass predominantSmallJointLocalization() { return PREDOMINANT_SMALL_JOINT_LOCALIZATION; } + public static OntologyClass midperipheral() { return MIDPERIPHERAL; } + public static OntologyClass distributedAlongBlaschkoLines() { return DISTRIBUTED_ALONG_BLASCHKO_LINES; } + public static OntologyClass acral() { return ACRAL; } + public static OntologyClass paracentral() { return PARACENTRAL; } + public static OntologyClass peripheral() { return PERIPHERAL; } + public static OntologyClass lowerBodyPredominance() { return LOWER_BODY_PREDOMINANCE; } + public static OntologyClass central() { return CENTRAL; } + public static OntologyClass upperBodyPredominance() { return UPPER_BODY_PREDOMINANCE; } + public static OntologyClass diffuse() { return DIFFUSE; } + public static OntologyClass jointExtensorSurfaceLocalization() { return JOINT_EXTENSOR_SURFACE_LOCALIZATION; } + public static OntologyClass multifocal() { return MULTIFOCAL; } + public static OntologyClass focal() { return FOCAL; } + public static OntologyClass axial() { return AXIAL; } + public static OntologyClass proximal() { return PROXIMAL; } + public static OntologyClass apical() { return APICAL; } + public static OntologyClass cervicalNeck() { return CERVICAL_NECK; } + public static OntologyClass polycyclic() { return POLYCYCLIC; } +} From 11cec406af06c7252955f12bb60b884787646d3e Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Sat, 16 Apr 2022 18:57:43 -0400 Subject: [PATCH 009/155] output phtp features. --- .../phenopackettools/PhenopacketTools.java | 2 + .../command/HtmlOutputCommand.java | 46 ++++ .../examples/Retinoblastoma.java | 13 +- .../phenopackettools/html/HtmlOutputter.java | 183 +++++++++++++ .../phenopackettools/html/HtmlUtil.java | 246 ++++++++++++++++++ 5 files changed, 484 insertions(+), 6 deletions(-) create mode 100644 phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/HtmlOutputCommand.java create mode 100644 phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlOutputter.java create mode 100644 phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlUtil.java diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/PhenopacketTools.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/PhenopacketTools.java index 91651c51..f32c7247 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/PhenopacketTools.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/PhenopacketTools.java @@ -2,6 +2,7 @@ import org.phenopackets.phenopackettools.command.ConvertCommand; import org.phenopackets.phenopackettools.command.ExamplesCommand; +import org.phenopackets.phenopackettools.command.HtmlOutputCommand; import org.phenopackets.phenopackettools.command.ValidateCommand; import picocli.AutoComplete; @@ -15,6 +16,7 @@ AutoComplete.GenerateCompletion.class, ExamplesCommand.class, ConvertCommand.class, + HtmlOutputCommand.class, ValidateCommand.class } ) diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/HtmlOutputCommand.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/HtmlOutputCommand.java new file mode 100644 index 00000000..48c02765 --- /dev/null +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/HtmlOutputCommand.java @@ -0,0 +1,46 @@ +package org.phenopackets.phenopackettools.command; + + +import com.google.protobuf.util.JsonFormat; +import org.phenopackets.phenopackettools.html.HtmlOutputter; +import org.phenopackets.schema.v2.Phenopacket; +import picocli.CommandLine; + +import java.io.BufferedReader; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.concurrent.Callable; + +/** + * Create an HTML file to represent a Phenopacket for human consumption. + * This command does not check validity of the Phenopacket, but the code + * can be combined with the validator if needed. + * @author Peter N. Robinson + */ +@CommandLine.Command(name = "html", + mixinStandardHelpOptions = true, + description = "Format phenopacket as HTML.") +public class HtmlOutputCommand implements Callable { + + @CommandLine.Parameters(index = "0", description = "Input phenopacket file") + private Path inPath; + + @CommandLine.Option(names = {"-o","--outfile"}, description = "name of output file (default ${DEFAULT})") + private String outName = "phenopacket.html"; + + @Override + public Integer call() { + var builder = Phenopacket.newBuilder(); + try (BufferedReader reader = Files.newBufferedReader(inPath)) { + JsonFormat.parser().ignoringUnknownFields().merge(reader, builder); + } catch (IOException e) { + System.err.println("Error! Unable to read input file, " + e.getMessage() + "\nPlease check the format of file " + inPath); + return 1; + } + var v2Phenopacket = builder.build(); + HtmlOutputter outputter = new HtmlOutputter(v2Phenopacket, outName); + outputter.write(); + return 0; + } +} diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java index d11fff8a..90ca282a 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java @@ -57,8 +57,8 @@ public Retinoblastoma() { Interpretation interpretation() { Diagnosis diagnosis = DiagnosisBuilder.builder(RETINOBLASTOMA) - .addGenomicInterpretation(somaticRb1Missense()) .addGenomicInterpretation(germlineRb1Deletion()) + .addGenomicInterpretation(somaticRb1Missense()) .build(); return InterpretationBuilder.builder("interpretation.id").solved(diagnosis); } @@ -70,7 +70,8 @@ Interpretation interpretation() { */ GenomicInterpretation somaticRb1Missense() { AlleleBuilder abuilder = AlleleBuilder.builder(); - abuilder.setSequenceId("ga4gh:VA.GuPzvZoansqNHPoXkQLXKo31VkTpDKsM"); + // abuilder.setSequenceId("ga4gh:VA.GuPzvZoansqNHPoXkQLXKo31VkTpDKsM"); + abuilder.setSequenceId("refseq:NC_000013.14"); abuilder.startEnd( 48941647, 48941648); abuilder.setAltAllele("T"); VariationDescriptorBuilder vbuilder = VariationDescriptorBuilder.builder("rs121913300") @@ -90,7 +91,7 @@ GenomicInterpretation somaticRb1Missense() { vibuilder.actionable(); - GenomicInterpretationBuilder gbuilder = GenomicInterpretationBuilder.builder(PROBAND_ID); + GenomicInterpretationBuilder gbuilder = GenomicInterpretationBuilder.builder(BIOSAMPLE_ID); gbuilder.causative(); gbuilder.variantInterpretation(vibuilder); @@ -100,18 +101,18 @@ GenomicInterpretation somaticRb1Missense() { GenomicInterpretation germlineRb1Deletion() { CopyNumberBuilder abuilder = CopyNumberBuilder.builder(); - abuilder.copyNumberId("ga4gh:VCN.AFfJws1M4Lg8w1O3XknmHYc9TU2hHYpp"); + //abuilder.copyNumberId("ga4gh:VCN.AFfJws1M4Lg8w1O3XknmHYc9TU2hHYpp"); abuilder.alleleLocation("refseq:NC_000013.14",26555377, 62280955);//VRS uses inter-residue coordinates abuilder.oneCopy(); VariationDescriptorBuilder vbuilder = VariationDescriptorBuilder.builder(); vbuilder.variation(abuilder.buildVariation()); - vbuilder.mosaicism(40.0); + // vbuilder.mosaicism(40.0); VariantInterpretationBuilder vibuilder = VariantInterpretationBuilder.builder(vbuilder); vibuilder.pathogenic(); vibuilder.actionable(); - GenomicInterpretationBuilder gbuilder = GenomicInterpretationBuilder.builder(BIOSAMPLE_ID); + GenomicInterpretationBuilder gbuilder = GenomicInterpretationBuilder.builder(PROBAND_ID); gbuilder.causative(); gbuilder.variantInterpretation(vibuilder); diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlOutputter.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlOutputter.java new file mode 100644 index 00000000..9df8bb3e --- /dev/null +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlOutputter.java @@ -0,0 +1,183 @@ +package org.phenopackets.phenopackettools.html; + +import org.phenopackets.schema.v2.Phenopacket; +import org.phenopackets.schema.v2.core.*; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Writer; +import java.util.*; +import java.util.stream.Collectors; + +/** + * Class to display information contained in a Phenopacket in HTML + * @author Peter Robinson + */ +public class HtmlOutputter { + + private final Phenopacket phenopacket; + private final String outname; + + enum Section {PROBAND, PHENOTYPICFEATURE, MEASUREMENT} + + public HtmlOutputter(Phenopacket phenopacket, String outname) { + this.phenopacket = phenopacket; + this.outname = outname; + } + + public void write() { + String phenopacketId = phenopacket.getId(); + try (BufferedWriter writer = new BufferedWriter(new FileWriter(outname))) { + writer.write(HtmlUtil.header(phenopacketId)); + writer.write(HtmlUtil.htmlTop()); + wrap(Section.PROBAND, writer); + wrap(Section.PHENOTYPICFEATURE, writer); + writer.write(HtmlUtil.bottom()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void startSection(Writer writer) throws IOException { + writer.write("
\n"); + } + + private void endSection(Writer writer) throws IOException { + writer.write("
\n"); + } + + private void wrap(Section section,Writer writer) throws IOException { + startSection(writer); + switch (section) { + case PROBAND: outputProband(writer); break; + case PHENOTYPICFEATURE: outputPhenotypicFeatures(writer); + } + endSection(writer); + } + + private void outputProband(Writer writer) throws IOException { + Individual proband = phenopacket.getSubject(); + String probandId = proband.getId(); // required + Map kv = new TreeMap<>(); + kv.put("id", probandId); + kv.put("sex", proband.getSex().name()); + if (proband.hasVitalStatus()) { + kv.put("vital status", proband.getVitalStatus().getStatus().name()); + } + writer.write("

Proband

\n"); + writer.write("\n"); + for (var e : kv.entrySet()) { + writer.write(row2(e.getKey(), e.getValue())); + } + writer.write("
\n"); + } + + private void outputPhenotypicFeatures(Writer writer) throws IOException { + List phenotypicFeatureList = phenopacket.getPhenotypicFeaturesList(); + if (phenotypicFeatureList.isEmpty()) { + writer.write("

No phenotypic features.

"); + return; + } + writer.write("

Phenotypic Features

\n"); + writer.write("\n"); + writer.write(""); + List fields = List.of("Term", "Id", "Status", "Modifiers", "onset", "resolution", "evidence"); + for (var f: fields) { + writer.write(""); + } + writer.write("\n"); + for (var feature : phenotypicFeatureList) { + List pffields = getPhenotypicFeatureFields(feature); + writer.write(row(pffields)); + } + writer.write("
" + f + "
\n"); + } + + private String getOntologyTermList(List terms) { + List oclsList = new ArrayList<>(); + for (var ocls : terms) { + oclsList.add(String.format("%s(%s)", ocls.getLabel(), ocls.getId())); + } + return String.join(";", oclsList); + } + + private List getPhenotypicFeatureFields(PhenotypicFeature feature) { + List fields = new ArrayList<>(); + OntologyClass ocls = feature.getType(); + fields.add(ocls.getLabel()); + fields.add(ocls.getId()); + if (feature.getExcluded()) { + fields.add("Excluded"); + } else { + fields.add("Observed"); + } + if (feature.getModifiersCount() > 0) { + fields.add(getOntologyTermList(feature.getModifiersList())); + } else { + fields.add("-"); + } + if (feature.hasOnset()) { + String timeAge = getTimeAge(feature.getOnset()); + fields.add(timeAge); + } else { + fields.add("-"); + } + if (feature.hasResolution()) { + String timeAge = getTimeAge(feature.getResolution()); + fields.add(timeAge); + } else { + fields.add("-"); + } + if (feature.getEvidenceCount() > 0) { + List evilist = feature.getEvidenceList(); + String evi = getEvidenceString(evilist); + fields.add(evi); + } else { + fields.add("-"); + } + return fields; + } + + private String getEvidenceString(List evilist) { + List eviStrList = new ArrayList<>(); + for (var evi : evilist) { + OntologyClass clz = evi.getEvidenceCode(); + eviStrList.add(String.format("%s", clz.getId())); + + } + return String.join(";", eviStrList); + } + + private String getTimeAge(TimeElement onset) { + if (onset.hasAge()) { + return onset.getAge().getIso8601Duration(); + } + + return "todo"; + } + + + private String row2(String s1, String s2) { + return String.format("%s%s\n", s1, s2); + } + + private String row(List fields) { + StringBuilder sb = new StringBuilder(); + sb.append(""); + for (var s : fields) { + sb.append("").append(s).append(""); + } + sb.append("\n"); + return sb.toString(); + } + + + private void outputSection(Writer writer, String Title, Map kv) { + + } + + + + +} diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlUtil.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlUtil.java new file mode 100644 index 00000000..593da50a --- /dev/null +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlUtil.java @@ -0,0 +1,246 @@ +package org.phenopackets.phenopackettools.html; + +import java.util.List; + +public class HtmlUtil { + + + public static String header(String phenopacketId) { + return "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "Phenopacket: " + phenopacketId + "\n" + + "\n" + + "\n" + + css() + + "\n\n"; + } + + + private static String css() { + return "\n"; + } + + + public static String htmlTop() { + return "\n" + + "
\n" + + "

Isopret

\n" + + "
\n" + + "
\n"; + } + + + public static String bottom() { + return " \n" + + "
\n" + + "\n" + + ""; + } + + + public static String tableHeader(String tableClass, List widths, List headerFields) { + StringBuilder sb = new StringBuilder(); + sb.append(""); + if (widths.size() == headerFields.size()) { + for (int i=0; i").append(head).append(""); + } + } else { + for (String head: headerFields) { + sb.append(""); + } + } + sb.append("\n"); + return sb.toString(); + } + +} From 6c9c46966a4a2cc3e5b4b8fc8f14dd55bfada412 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Sun, 17 Apr 2022 08:29:53 -0400 Subject: [PATCH 010/155] output proband complete --- .../builders/InterpretationBuilder.java | 9 --- .../examples/NemalineMyopathyPrenatal.java | 1 - .../phenopackettools/html/HtmlOutputter.java | 76 +++++++++++++++---- .../phenopackettools/html/HtmlUtil.java | 29 ++----- .../converter/PhenopacketConverterTest.java | 1 - 5 files changed, 67 insertions(+), 49 deletions(-) diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/InterpretationBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/InterpretationBuilder.java index 24ccc346..ddc3ca67 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/InterpretationBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/InterpretationBuilder.java @@ -19,19 +19,10 @@ public static InterpretationBuilder builder(String interpretationId) { return new InterpretationBuilder(interpretationId, Interpretation.ProgressStatus.UNKNOWN_PROGRESS); } -// public static InterpretationBuilder builder(String interpretationId, Interpretation.ProgressStatus status) { -// return new InterpretationBuilder(interpretationId, status); -// } - public InterpretationBuilder summary(String summary) { builder.setSummary(summary); return this; } -// -// public InterpretationBuilder diagnosis(Diagnosis diagnosis) { -// builder.setDiagnosis(diagnosis); -// return this; -// } public Interpretation inProgress() { builder.setProgressStatus(Interpretation.ProgressStatus.IN_PROGRESS); diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/NemalineMyopathyPrenatal.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/NemalineMyopathyPrenatal.java index aa934690..aed615af 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/NemalineMyopathyPrenatal.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/NemalineMyopathyPrenatal.java @@ -11,7 +11,6 @@ import java.util.List; import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; -import static org.phenopackets.phenopackettools.builder.builders.PhenotypicFeatureBuilder.phenotypicFeature; import static org.phenopackets.phenopackettools.builder.builders.TimeElements.gestationalAge; /** diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlOutputter.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlOutputter.java index 9df8bb3e..bae9e749 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlOutputter.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlOutputter.java @@ -1,5 +1,7 @@ package org.phenopackets.phenopackettools.html; +import com.google.protobuf.Timestamp; +import com.google.protobuf.util.Timestamps; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; @@ -8,7 +10,6 @@ import java.io.IOException; import java.io.Writer; import java.util.*; -import java.util.stream.Collectors; /** * Class to display information contained in a Phenopacket in HTML @@ -33,7 +34,7 @@ public void write() { writer.write(HtmlUtil.htmlTop()); wrap(Section.PROBAND, writer); wrap(Section.PHENOTYPICFEATURE, writer); - writer.write(HtmlUtil.bottom()); + writer.write(HtmlUtil.htmlBottom()); } catch (IOException e) { e.printStackTrace(); } @@ -59,17 +60,47 @@ private void wrap(Section section,Writer writer) throws IOException { private void outputProband(Writer writer) throws IOException { Individual proband = phenopacket.getSubject(); String probandId = proband.getId(); // required - Map kv = new TreeMap<>(); - kv.put("id", probandId); - kv.put("sex", proband.getSex().name()); + + List thisRow = new ArrayList<>(); + thisRow.add(probandId); + thisRow.add(proband.getSex().toString()); + if (proband.hasDateOfBirth()) { + Timestamp dob = proband.getDateOfBirth(); + thisRow.add(Timestamps.toString(dob)); + } else { + thisRow.add("-"); + } + if (proband.hasTimeAtLastEncounter()) { + String age = getTimeAge(proband.getTimeAtLastEncounter()); + thisRow.add(age); + } else { + thisRow.add("-"); + } if (proband.hasVitalStatus()) { - kv.put("vital status", proband.getVitalStatus().getStatus().name()); + thisRow.add( proband.getVitalStatus().getStatus().name()); + } else { + thisRow.add("-"); + } + if (proband.getKaryotypicSex().getNumber() >0) { + thisRow.add(proband.getKaryotypicSex().toString()); + } else { + thisRow.add("-"); + } + if (proband.hasGender()) { + OntologyClass clz = proband.getGender(); + thisRow.add(String.format("%s (%s)", clz.getLabel(), clz.getId())); + } else { + thisRow.add("-"); } writer.write("

Proband

\n"); writer.write("
").append(head).append("
\n"); - for (var e : kv.entrySet()) { - writer.write(row2(e.getKey(), e.getValue())); + writer.write(""); + List fields = List.of("id", "sex", "birthdate", "age", "vital status", "karyotypic_sex", "gender"); + for (var f: fields) { + writer.write(""); } + writer.write("\n"); + writer.write(row(thisRow)); writer.write("
" + f + "
\n"); } @@ -152,14 +183,29 @@ private String getEvidenceString(List evilist) { private String getTimeAge(TimeElement onset) { if (onset.hasAge()) { return onset.getAge().getIso8601Duration(); + } else if (onset.hasGestationalAge()) { + GestationalAge ga = onset.getGestationalAge(); + return String.format("GA: %dW+%d D", ga.getWeeks(), ga.getDays()); + } else if (onset.hasAgeRange()) { + AgeRange ar = onset.getAgeRange(); + String start = ar.getStart().getIso8601Duration(); + String end = ar.getEnd().getIso8601Duration(); + return String.format("%s - %s", start, end); + } else if (onset.hasTimestamp()) { + Timestamp ts = onset.getTimestamp(); + return Timestamps.toString(ts); + } else if (onset.hasOntologyClass()) { + OntologyClass clz = onset.getOntologyClass(); + return String.format("%s (%s)", clz.getLabel(), clz.getId()); + } else if (onset.hasInterval()) { + TimeInterval ti = onset.getInterval(); + String start = Timestamps.toString(ti.getStart()); + String end = Timestamps.toString(ti.getEnd()); + return String.format("%s - %s", start, end); + } else { + // we have exhausted all possibilities and should never get here, but... + return "N/A"; } - - return "todo"; - } - - - private String row2(String s1, String s2) { - return String.format("%s%s\n", s1, s2); } private String row(List fields) { diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlUtil.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlUtil.java index 593da50a..213b45d1 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlUtil.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlUtil.java @@ -1,7 +1,9 @@ package org.phenopackets.phenopackettools.html; -import java.util.List; - +/** + * Some CSS and boilerplate HTML for writing phenopackets. + * @author Peter N Robinson + */ public class HtmlUtil { @@ -211,13 +213,12 @@ private static String css() { public static String htmlTop() { return "\n" + "
\n" + - "

Isopret

\n" + + "

Phenopacket-Tools

\n" + "
\n" + "
\n"; } - - public static String bottom() { + public static String htmlBottom() { return " \n" + "
\n" + "\n" + @@ -225,22 +226,4 @@ public static String bottom() { } - public static String tableHeader(String tableClass, List widths, List headerFields) { - StringBuilder sb = new StringBuilder(); - sb.append(""); - if (widths.size() == headerFields.size()) { - for (int i=0; i").append(head).append(""); - } - } else { - for (String head: headerFields) { - sb.append(""); - } - } - sb.append("\n"); - return sb.toString(); - } - } diff --git a/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java b/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java index 44f63d7e..bc8c64f7 100644 --- a/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java +++ b/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java @@ -1,7 +1,6 @@ package org.phenopackets.phenopackettools.converter; import com.google.protobuf.InvalidProtocolBufferException; -import com.google.protobuf.util.JsonFormat; import org.junit.jupiter.api.Test; import org.phenopackets.phenopackettools.converter.converters.PhenopacketConverter; From c50e92b5f6d8e00de9272cc29583b546e656b5f2 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Sun, 17 Apr 2022 16:43:21 -0400 Subject: [PATCH 011/155] adding functionality to MetaDataBuilder --- .../builder/builders/MetaDataBuilder.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MetaDataBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MetaDataBuilder.java index 00a567f3..5b218707 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MetaDataBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MetaDataBuilder.java @@ -1,10 +1,13 @@ package org.phenopackets.phenopackettools.builder.builders; +import com.google.protobuf.Timestamp; import org.phenopackets.schema.v2.core.ExternalReference; import org.phenopackets.schema.v2.core.MetaData; import org.phenopackets.schema.v2.core.Resource; import org.phenopackets.schema.v2.core.Update; +import java.time.Instant; + import static org.phenopackets.phenopackettools.builder.builders.TimestampBuilder.fromISO8601; public class MetaDataBuilder { @@ -20,10 +23,31 @@ private MetaDataBuilder(String created, String createdBy) { .setPhenopacketSchemaVersion(SCHEMA_VERSION); // only one option for schema version! } + private MetaDataBuilder(Timestamp createdTimeStamp, String createdBy) { + builder = MetaData.newBuilder() + .setCreated(createdTimeStamp) + .setCreatedBy(createdBy) + .setPhenopacketSchemaVersion(SCHEMA_VERSION); // only one option for schema version! + } + public static MetaDataBuilder builder(String created, String createdBy) { return new MetaDataBuilder(created, createdBy); } + public static MetaDataBuilder builder(Timestamp createdTimeStamp, String createdBy) { + return new MetaDataBuilder(createdTimeStamp, createdBy); + } + + /** + * Create a new MetaDataBuilder with time set to now. + */ + public static MetaDataBuilder builder(String createdBy) { + Instant time = Instant.now(); + Timestamp timestamp = Timestamp.newBuilder().setSeconds(time.getEpochSecond()) + .setNanos(time.getNano()).build(); + return new MetaDataBuilder(timestamp, createdBy); + } + public MetaDataBuilder submittedBy(String submitter) { builder.setSubmittedBy(submitter); return this; From 49d21c3066830d54c9a806bad8b8a6d730592415 Mon Sep 17 00:00:00 2001 From: Tudor Groza Date: Thu, 21 Apr 2022 19:37:03 +0800 Subject: [PATCH 012/155] WIP - First PXF example. --- .../PneumothoraxSecondaryToCOVID.java | 215 ++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/PneumothoraxSecondaryToCOVID.java diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/PneumothoraxSecondaryToCOVID.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/PneumothoraxSecondaryToCOVID.java new file mode 100644 index 00000000..3d53aa11 --- /dev/null +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/PneumothoraxSecondaryToCOVID.java @@ -0,0 +1,215 @@ +package org.phenopackets.phenotools.examples; + +import org.phenopackets.phenotools.builder.PhenopacketBuilder; +import org.phenopackets.phenotools.builder.builders.*; +import org.phenopackets.schema.v2.Phenopacket; +import org.phenopackets.schema.v2.core.*; + +import java.util.ArrayList; +import java.util.List; + +public class PneumothoraxSecondaryToCOVID { + + private static final String PHENOPACKET_ID = "arbitrary.id"; + private static final String PROBAND_ID = "proband A"; + + // Organs + + private final Phenopacket phenopacket; + + public PneumothoraxSecondaryToCOVID() { + + //TODO: Fix ontology versions + var metadata = MetaDataBuilder.builder("2022-04-21T10:35:00Z", "anonymous biocurator") + .resource(Resources.ncitVersion("21.05d")) + .resource(Resources.hpoVersion("2021-08-02")) + .resource(Resources.efoVersion("3.34.0")) + .resource(Resources.uberonVersion("2021-07-27")) + .resource(Resources.ncbiTaxonVersion("2021-06-10")) + .build(); + + Individual proband = IndividualBuilder.builder(PROBAND_ID). + ageAtLastEncounter("P36Y"). + male(). + build(); + + phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metadata) + .individual(proband) + .addAllPhenotypicFeatures(getMedicalHistory()) + .addAllPhenotypicFeatures(getLast3WeekHistory()) + .addAllPhenotypicFeatures(getSymptomsOnPresentation()) + .addAllMeasurements(getMeasurementsOnPresentation()) + .addAllPhenotypicFeatures(getChestRadiograph()) + .build(); + + } + + /** + * A 12-lead ECG showed a sinus tachycardia at 155 beats/min. + * + * The patient’s full blood count demonstrated a raised white cell count (13.64×109/L) with a neutrophilia (8.91×109/L), lymphocyte count (3.81×109/L), haemoglobin (146g/L), and platelets (1051×109/L); biochemical markers demonstrated a raised C-reactive protein (28.7mg/L) and alanine aminotransferase (107IU/L). + * Diagnosis: tension pneumothorax, secondary to underlying COVID-19 + * + * Treatment: + * emergency needle decompression: + * - 14-gauge cannula inserted in the second rib space and mid-clavicular line + * - 12-French Seldinger chest drain inserted into the patients left axilla + * + * Outcome: + * repeat chest radiograph => lung re-expansion + * Within an hour the patient’s oxygen requirement reduced to 4L/min via nasal cannula + * normalisation of respiratory and heart rate. + */ + + + /** + * Emergency portable chest radiograph + * - large left-sided pneumothorax with mediastinal shift + * - radiological signs of tension + * - right lung compressed BUT widespread patchy consolidative changes + */ + + private List getChestRadiograph() { + // How to associate phenotypes with procedures? + + return new ArrayList<>(); + } + + /** + * On presentation: << How to specify the temporal element? + * - SpO2 of 88% on 15L/min oxygen via non-rebreathe mask + * - respiratory rate of 50 breaths per minute + * - heart rate of 150 beats/min + * - blood pressure of 110/65 mm Hg + */ + private List getMeasurementsOnPresentation() { + OntologyClass respiratoryRate = OntologyClassBuilder.ontologyClass("LOINC:9279-1", "Respiratory rate"); + + // Couldn't find 'breaths per minute' as a measurement unit and UCUM has not been published. + // This applies to all measurements below + Value respiratoryRateValue = ValueBuilder.value("UCUM:{breaths}/min", "Breaths/minute", 50); + + // Time observed: on presentation? This applies to all measurements below + Measurement respiratoryRateMeasurement = MeasurementBuilder. + value(respiratoryRate, respiratoryRateValue). + build(); + + OntologyClass heartRate = OntologyClassBuilder.ontologyClass("LOINC:8867-4", "Heart rate"); + Value heartRateValue = ValueBuilder.value("UCUM:{beats}/min", "Beats/minute", 150); + Measurement heartRateMeasurement = MeasurementBuilder. + value(heartRate, heartRateValue). + build(); + + OntologyClass systBloodPressure = OntologyClassBuilder.ontologyClass("LOINC:8480-6", "Systolic blood pressure"); + Value systBloodPressureValue = ValueBuilder.value("UCUM:mm[Hg]", "mm[Hg]", 110); + Measurement systBloodPressureMeasurement = MeasurementBuilder. + value(systBloodPressure, systBloodPressureValue). + build(); + + OntologyClass diastBloodPressure = OntologyClassBuilder.ontologyClass("LOINC:8480-6", "Systolic blood pressure"); + Value diastBloodPressureValue = ValueBuilder.value("UCUM:mm[Hg]", "mm[Hg]", 65); + Measurement diastBloodPressureMeasurement = MeasurementBuilder. + value(diastBloodPressure, diastBloodPressureValue). + build(); + + + // How to define the 'intervention' component SpO2 of 88% << on 15L/min oxygen via non-rebreathe mask >> + // It's not a procedure + + OntologyClass spO2 = OntologyClassBuilder.ontologyClass("LOINC:20564-1", "Oxygen saturation in Blood"); + Value spO2Value = ValueBuilder.value("UCUM:%", "%", 88); + Measurement spO2Measurement = MeasurementBuilder. + value(spO2, spO2Value). + build(); + + + return List.of(respiratoryRateMeasurement, + heartRateMeasurement, + systBloodPressureMeasurement, + diastBloodPressureMeasurement, + spO2Measurement); + } + + /** + * On presentation: << How to represent this from a temporal perspective? + * - hypoxaemic + * - tachycardic + * - left-sided pleuritic chest pain + * - trachea remained central + *

+ * On ascultation: + * - no audible breath sounds of the left hemithorax + * - reduced vocal fremitus + * - asymmetrical chest expansion + */ + private List getSymptomsOnPresentation() { + PhenotypicFeature hypoxemia = PhenotypicFeatureBuilder. + builder("HP:0012418", "Hypoxemia"). + build(); + + PhenotypicFeature tachycardia = PhenotypicFeatureBuilder. + builder("HP:0001649", "Tachycardia"). + build(); + + PhenotypicFeature chestPain = PhenotypicFeatureBuilder. + builder("HP:0033771", "Pleuritic chest pain"). + modifier(Laterality.left()). + build(); + + PhenotypicFeature trachea = PhenotypicFeatureBuilder. + builder("HP:0002778", "Abnormal tracheal morphology"). + excluded(). + build(); + + // How to combine a procedure < ascultation > with phenotypic features? + + return List.of(hypoxemia, tachycardia, chestPain, trachea); + } + + /** + * medical history: + * - Childhood asthma + * - 10 pack-year history of smoking << How to represent this !? + * - NO history of trauma << Did I represent correct the absence of the phenotype? + * - NO history of pneumothoraces + */ + private List getMedicalHistory() { + PhenotypicFeature asthma = PhenotypicFeatureBuilder. + builder("HP:0002099", "Asthma"). + childhoodOnset(). + build(); + PhenotypicFeature trauma = PhenotypicFeatureBuilder. + builder("SCTID:417746004", "Trauma"). + excluded(). + build(); + PhenotypicFeature pneumothorax = PhenotypicFeatureBuilder. + builder("HP:0002107", "Pneumothorax"). + excluded(). + build(); + + return List.of(asthma, trauma, pneumothorax); + } + + /** + * 3-week history: << How to represent relative time periods? + * - cough + * - fevers + * - shortness of breath + */ + private List getLast3WeekHistory() { + PhenotypicFeature cough = PhenotypicFeatureBuilder. + builder("HP:0012735", "Cough"). + build(); + + PhenotypicFeature fever = PhenotypicFeatureBuilder. + builder("HP:0001945", "Fever"). + build(); + + PhenotypicFeature dyspnea = PhenotypicFeatureBuilder. + builder("HP:0002094", "Dyspnea"). + build(); + + return List.of(cough, fever, dyspnea); + } + +} From c3e7430b9b125321c1b50d8348175d5e0621d6ae Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Thu, 21 Apr 2022 09:40:41 -0400 Subject: [PATCH 013/155] hotfix -- replacing unilateral by left in an example --- .../phenopackettools/examples/Retinoblastoma.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java index 90ca282a..a3849afc 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java @@ -264,19 +264,19 @@ List getPhenotypicFeatures() { TimeElement age4months = TimeElements.age("P4M"); PhenotypicFeature leukocoria = PhenotypicFeatureBuilder. builder("HP:0000555", "Leukocoria") - .addModifier(Laterality.unilateral()) + .addModifier(Laterality.left()) .onset(age4months) .build(); TimeElement age5months = TimeElements.age("P5M15D"); PhenotypicFeature strabismus = PhenotypicFeatureBuilder. builder("HP:0000486", "Strabismus") - .addModifier(Laterality.unilateral()) + .addModifier(Laterality.left()) .onset(age5months) .build(); TimeElement age6months = TimeElements.age("P6M"); PhenotypicFeature retinalDetachment = PhenotypicFeatureBuilder .builder("HP:0000541", "Retinal detachment") - .addModifier(Laterality.unilateral()) + .addModifier(Laterality.left()) .onset(age6months) .build(); return List.of(clinodactyly, leukocoria, strabismus, retinalDetachment); From fed02cf1718c6135bce442933ca20e4b17edde0d Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Thu, 21 Apr 2022 17:54:43 -0400 Subject: [PATCH 014/155] standardizing function names to of and builder --- .../builder/PhenopacketBuilder.java | 2 +- .../builders/{AgeBuilder.java => Ages.java} | 4 +- .../builder/builders/AlleleBuilder.java | 4 +- .../builder/builders/BiosampleBuilder.java | 2 +- .../builder/builders/ComplexValueBuilder.java | 12 ++--- .../builder/builders/CopyNumberBuilder.java | 2 +- .../builder/builders/DiseaseBuilder.java | 6 +-- .../builder/builders/DoseIntervalBuilder.java | 6 +-- .../builder/builders/EvidenceBuilder.java | 10 ++--- .../builder/builders/Extensions.java | 18 +++++--- .../builders/ExternalReferenceBuilder.java | 6 +-- .../builders/GeneDescriptorBuilder.java | 2 +- .../builder/builders/IndividualBuilder.java | 2 +- .../builders/InterpretationBuilder.java | 2 +- .../builder/builders/MeasurementBuilder.java | 8 ++-- .../builders/PhenotypicFeatureBuilder.java | 6 +-- .../builder/builders/ProcedureBuilder.java | 6 +-- .../builder/builders/QuantityBuilder.java | 20 ++++----- .../builders/ReferenceRangeBuilder.java | 6 +-- .../builder/builders/TimeElements.java | 4 +- .../builder/builders/TimeIntervalBuilder.java | 4 +- .../builder/builders/TreatmentBuilder.java | 6 +-- .../builders/TypedQuantityBuilder.java | 2 +- .../builder/builders/ValueBuilder.java | 26 +++++------ .../VariantInterpretationBuilder.java | 4 +- .../builders/VariationDescriptorBuilder.java | 18 ++++---- .../builder/builders/VcfRecordBuilder.java | 2 +- .../builder/builders/AgeBuilderTest.java | 10 ++--- .../builder/builders/AlleleBuilderTest.java | 4 +- .../builders/BiosampleBuilderTest.java | 4 +- .../builders/ComplexValueBuilderTest.java | 6 +-- .../builders/DiagnosisBuilderTest.java | 2 +- .../builder/builders/DiseaseBuilderTest.java | 2 +- .../builders/DoseIntervalBuilderTest.java | 6 +-- .../builders/TimeIntervalBuilderTest.java | 4 +- .../examples/BethlehamMyopathy.java | 2 +- .../phenopackettools/examples/Covid.java | 44 +++++++++---------- .../phenopackettools/examples/Marfan.java | 10 ++--- .../examples/NemalineMyopathyPrenatal.java | 8 ++-- .../examples/Retinoblastoma.java | 43 ++++++++++-------- .../examples/Thrombocytopenia2.java | 2 +- .../examples/UrothelialCancer.java | 2 +- .../phenopackettools/html/HtmlOutputter.java | 7 --- .../converter/PhenopacketConverterTest.java | 13 +++--- 44 files changed, 183 insertions(+), 176 deletions(-) rename phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/{AgeBuilder.java => Ages.java} (95%) diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/PhenopacketBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/PhenopacketBuilder.java index 0f399bd5..b06ef364 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/PhenopacketBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/PhenopacketBuilder.java @@ -24,7 +24,7 @@ public PhenopacketBuilder individual(Individual subject) { } public PhenopacketBuilder addPhenotypicFeature(String id, String label) { - PhenotypicFeature phenotypicFeature = PhenotypicFeatureBuilder.phenotypicFeature(id, label); + PhenotypicFeature phenotypicFeature = PhenotypicFeatureBuilder.of(id, label); return addPhenotypicFeature(phenotypicFeature); } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/AgeBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Ages.java similarity index 95% rename from phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/AgeBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Ages.java index 20691682..4711e498 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/AgeBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Ages.java @@ -8,9 +8,9 @@ import java.time.Period; import java.time.format.DateTimeParseException; -public class AgeBuilder { +public class Ages { - private AgeBuilder() { + private Ages() { } public static Age age(String iso8601duration) { diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilder.java index 7e7b7a07..86c08a7b 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilder.java @@ -54,12 +54,12 @@ public AlleleBuilder startEnd(int start, int end) { return this; } - public AlleleBuilder setAltAllele(String alt) { + public AlleleBuilder altAllele(String alt) { builder.setLiteralSequenceExpression(LiteralSequenceExpression.newBuilder().setSequence(alt)); return this; } - public AlleleBuilder setSequenceId(String sequenceId) { + public AlleleBuilder sequenceId(String sequenceId) { slbuilder.setSequenceId(sequenceId); return this; } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilder.java index 4c15789e..4c47995b 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilder.java @@ -42,7 +42,7 @@ public BiosampleBuilder sampledType(OntologyClass tissue) { } public BiosampleBuilder addPhenotypicFeature(String id, String label) { - PhenotypicFeature phenotypicFeature = PhenotypicFeatureBuilder.phenotypicFeature(id, label); + PhenotypicFeature phenotypicFeature = PhenotypicFeatureBuilder.of(id, label); return addPhenotypicFeature(phenotypicFeature); } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilder.java index ff370bcf..ed671e56 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilder.java @@ -12,20 +12,20 @@ public class ComplexValueBuilder { private ComplexValueBuilder() { } - public static ComplexValue complexValue(TypedQuantity typedQuantity) { + public static ComplexValue of(TypedQuantity typedQuantity) { return ComplexValue.newBuilder().addTypedQuantities(typedQuantity).build(); } - public static ComplexValue complexValue(TypedQuantity... typedQuantities) { + public static ComplexValue of(TypedQuantity... typedQuantities) { return ComplexValue.newBuilder().addAllTypedQuantities(List.of(typedQuantities)).build(); } - public static ComplexValue complexValue(List typedQuantities) { + public static ComplexValue of(List typedQuantities) { return ComplexValue.newBuilder().addAllTypedQuantities(typedQuantities).build(); } - public static ComplexValue complexValue(OntologyClass type, Quantity quantity) { - TypedQuantity typedQuantity = TypedQuantityBuilder.typedQuantity(type, quantity); - return complexValue(typedQuantity); + public static ComplexValue of(OntologyClass type, Quantity quantity) { + TypedQuantity typedQuantity = TypedQuantityBuilder.of(type, quantity); + return of(typedQuantity); } } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/CopyNumberBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/CopyNumberBuilder.java index fb9a2b6b..3c8074ba 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/CopyNumberBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/CopyNumberBuilder.java @@ -24,7 +24,7 @@ public CopyNumberBuilder copyNumberId(String id) { */ public CopyNumberBuilder alleleLocation(String contig, int interbaseStartPos, int interbaseEndPos) { AlleleBuilder abuilder = AlleleBuilder.builder() - .setSequenceId(contig) + .sequenceId(contig) .startEnd(interbaseStartPos, interbaseEndPos); builder.setAllele(abuilder.build()); return this; diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilder.java index 3c648524..f9166b2c 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilder.java @@ -12,13 +12,13 @@ private DiseaseBuilder(OntologyClass term) { builder = Disease.newBuilder().setTerm(term); } - public static Disease disease(OntologyClass term) { + public static Disease of(OntologyClass term) { return Disease.newBuilder().setTerm(term).build(); } - public static Disease disease(String id, String label) { + public static Disease of(String id, String label) { OntologyClass term = OntologyClassBuilder.ontologyClass(id, label); - return disease(term); + return of(term); } public static DiseaseBuilder builder(OntologyClass term) { diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DoseIntervalBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DoseIntervalBuilder.java index 52850cce..d1bc2d09 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DoseIntervalBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DoseIntervalBuilder.java @@ -10,7 +10,7 @@ public class DoseIntervalBuilder { private DoseIntervalBuilder() { } - public static DoseInterval doseInterval(Quantity quantity, OntologyClass scheduleFrequency, TimeInterval interval) { + public static DoseInterval of(Quantity quantity, OntologyClass scheduleFrequency, TimeInterval interval) { return DoseInterval.newBuilder() .setQuantity(quantity) .setScheduleFrequency(scheduleFrequency) @@ -18,8 +18,8 @@ public static DoseInterval doseInterval(Quantity quantity, OntologyClass schedul .build(); } - public static DoseInterval doseInterval(Quantity quantity, OntologyClass scheduleFrequency, String start, String end) { - var interval = TimeIntervalBuilder.timeInterval(start, end); + public static DoseInterval of(Quantity quantity, OntologyClass scheduleFrequency, String start, String end) { + var interval = TimeIntervalBuilder.of(start, end); return DoseInterval.newBuilder() .setQuantity(quantity) .setScheduleFrequency(scheduleFrequency) diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/EvidenceBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/EvidenceBuilder.java index f9064b09..2a06d762 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/EvidenceBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/EvidenceBuilder.java @@ -13,16 +13,16 @@ private EvidenceBuilder(OntologyClass evidenceCode) { builder = Evidence.newBuilder().setEvidenceCode(evidenceCode); } - public static Evidence evidence(String id, String label) { + public static Evidence of(String id, String label) { OntologyClass evidenceCode = OntologyClassBuilder.ontologyClass(id, label); return new EvidenceBuilder(evidenceCode).build(); } - public static Evidence evidence(OntologyClass evidenceCode) { + public static Evidence of(OntologyClass evidenceCode) { return new EvidenceBuilder(evidenceCode).build(); } - public static Evidence evidence(OntologyClass evidenceCode, ExternalReference externalReference) { + public static Evidence of(OntologyClass evidenceCode, ExternalReference externalReference) { return new EvidenceBuilder(evidenceCode).reference(externalReference).build(); } @@ -39,8 +39,8 @@ public static Evidence authorStatementEvidence(String pmid, String title) { String id = "ECO:0000033"; String label = "author statement supported by traceable reference"; OntologyClass evidenceCode = OntologyClassBuilder.ontologyClass(id, label); - ExternalReference externalReference = ExternalReferenceBuilder.externalReference(pmid, title); - return evidence(evidenceCode, externalReference); + ExternalReference externalReference = ExternalReferenceBuilder.of(pmid, title); + return of(evidenceCode, externalReference); } public EvidenceBuilder reference(ExternalReference externalReference) { diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Extensions.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Extensions.java index c8069ff7..326edb9d 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Extensions.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Extensions.java @@ -1,17 +1,25 @@ package org.phenopackets.phenopackettools.builder.builders; -import com.google.protobuf.Any; -import com.google.protobuf.ByteString; import org.ga4gh.vrsatile.v1.Extension; public class Extensions { + public static final String MOSAICISM = "mosaicism"; + public static final String ALLELE_FREQUENCY = "allele-frequency"; public static Extension mosaicism(double percentage) { String percentageString = String.format("%.1f%%", percentage); - ByteString bstring = ByteString.copyFromUtf8(percentageString); - Any perc = Any.newBuilder().setValue(bstring).build(); - return Extension.newBuilder().setName("mosaicism").addValue(perc).build(); + return Extension.newBuilder().setName(MOSAICISM).setValue(percentageString).build(); } + + /** + * @param frequency estimated frequency (IN PERCENT) of an allele (generally a somatic mutation) + */ + public static Extension alleleFrequency(double frequency) { + String percentageString = String.format("%.1f%%", frequency); + return Extension.newBuilder().setName(ALLELE_FREQUENCY).setValue(percentageString).build(); + } + + } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ExternalReferenceBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ExternalReferenceBuilder.java index d441a7ea..37281a1d 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ExternalReferenceBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ExternalReferenceBuilder.java @@ -10,11 +10,11 @@ private ExternalReferenceBuilder() { builder = ExternalReference.newBuilder(); } - public static ExternalReference externalReference(String id, String description) { + public static ExternalReference of(String id, String description) { return ExternalReference.newBuilder().setId(id).setDescription(description).build(); } - public static ExternalReferenceBuilder builder() { + public static ExternalReferenceBuilder reference() { return new ExternalReferenceBuilder(); } @@ -23,7 +23,7 @@ public ExternalReferenceBuilder id(String id) { return this; } - public ExternalReferenceBuilder builder(String ref) { + public ExternalReferenceBuilder reference(String ref) { builder.setReference(ref); return this; } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/GeneDescriptorBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/GeneDescriptorBuilder.java index af870423..6c281190 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/GeneDescriptorBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/GeneDescriptorBuilder.java @@ -12,7 +12,7 @@ private GeneDescriptorBuilder(String identifier, String symbol) { builder = GeneDescriptor.newBuilder().setValueId(identifier).setSymbol(symbol); } - public static GeneDescriptor geneDescriptor(String identifier, String symbol) { + public static GeneDescriptor of(String identifier, String symbol) { return GeneDescriptor.newBuilder().setValueId(identifier).setSymbol(symbol).build(); } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilder.java index 87f92377..32079ab7 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilder.java @@ -29,7 +29,7 @@ private IndividualBuilder(String id) { builder = Individual.newBuilder().setId(id); } - public static Individual individual(String id) { + public static Individual of(String id) { return Individual.newBuilder().setId(id).build(); } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/InterpretationBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/InterpretationBuilder.java index ddc3ca67..4baa5cf3 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/InterpretationBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/InterpretationBuilder.java @@ -11,7 +11,7 @@ private InterpretationBuilder(String interpretationId, Interpretation.ProgressSt builder = Interpretation.newBuilder().setId(interpretationId).setProgressStatus(status); } - public static Interpretation interpretation(String interpretationId, Interpretation.ProgressStatus status, Diagnosis diagnosis, String summary) { + public static Interpretation of(String interpretationId, Interpretation.ProgressStatus status, Diagnosis diagnosis, String summary) { return Interpretation.newBuilder().setId(interpretationId).setProgressStatus(status).setDiagnosis(diagnosis).setSummary(summary).build(); } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MeasurementBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MeasurementBuilder.java index cdb63a7e..b79253cf 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MeasurementBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MeasurementBuilder.java @@ -14,19 +14,19 @@ private MeasurementBuilder(OntologyClass assay, ComplexValue complexValue) { builder = Measurement.newBuilder().setAssay(assay).setComplexValue(complexValue); } - public static Measurement measurement(OntologyClass assay, Value value) { + public static Measurement of(OntologyClass assay, Value value) { return Measurement.newBuilder().setAssay(assay).setValue(value).build(); } - public static Measurement measurement(OntologyClass assay, ComplexValue complexValue) { + public static Measurement of(OntologyClass assay, ComplexValue complexValue) { return Measurement.newBuilder().setAssay(assay).setComplexValue(complexValue).build(); } - public static MeasurementBuilder value(OntologyClass assay, Value value) { + public static MeasurementBuilder builder(OntologyClass assay, Value value) { return new MeasurementBuilder(assay, value); } - public static MeasurementBuilder complexValue(OntologyClass assay, ComplexValue complexValue) { + public static MeasurementBuilder builder(OntologyClass assay, ComplexValue complexValue) { return new MeasurementBuilder(assay, complexValue); } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/PhenotypicFeatureBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/PhenotypicFeatureBuilder.java index 0899b58b..3901df93 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/PhenotypicFeatureBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/PhenotypicFeatureBuilder.java @@ -21,13 +21,13 @@ private PhenotypicFeatureBuilder(OntologyClass feature) { builder = PhenotypicFeature.newBuilder().setType(feature); } - public static PhenotypicFeature phenotypicFeature(OntologyClass feature) { + public static PhenotypicFeature of(OntologyClass feature) { return PhenotypicFeature.newBuilder().setType(feature).build(); } - public static PhenotypicFeature phenotypicFeature(String id, String label) { + public static PhenotypicFeature of(String id, String label) { OntologyClass ontologyClass = OntologyClassBuilder.ontologyClass(id, label); - return phenotypicFeature(ontologyClass); + return of(ontologyClass); } public static PhenotypicFeatureBuilder builder(OntologyClass feature) { diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ProcedureBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ProcedureBuilder.java index 6a17c2f2..7ff8745c 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ProcedureBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ProcedureBuilder.java @@ -12,12 +12,12 @@ private ProcedureBuilder(OntologyClass procedure) { builder = Procedure.newBuilder().setCode(procedure); } - public static Procedure procedure(OntologyClass procedure) { + public static Procedure of(OntologyClass procedure) { return Procedure.newBuilder().setCode(procedure).build(); } - public static Procedure procedure(String id, String label) { - return procedure(OntologyClassBuilder.ontologyClass(id, label)); + public static Procedure of(String id, String label) { + return of(OntologyClassBuilder.ontologyClass(id, label)); } public static ProcedureBuilder builder(OntologyClass procedure) { diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/QuantityBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/QuantityBuilder.java index c83c6298..56861658 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/QuantityBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/QuantityBuilder.java @@ -12,28 +12,28 @@ private QuantityBuilder(OntologyClass unit, double value) { builder = Quantity.newBuilder().setUnit(unit).setValue(value); } - public static Quantity quantity(OntologyClass unit, double value) { + public static Quantity of(OntologyClass unit, double value) { return Quantity.newBuilder().setUnit(unit).setValue(value).build(); } - public static Quantity quantity(String id, String label, double value) { - return quantity(OntologyClassBuilder.ontologyClass(id, label), value); + public static Quantity of(String id, String label, double value) { + return of(OntologyClassBuilder.ontologyClass(id, label), value); } - public static Quantity quantity(String id, String label, double value, ReferenceRange ref) { - return quantity(OntologyClassBuilder.ontologyClass(id, label), value); + public static Quantity of(String id, String label, double value, ReferenceRange ref) { + return of(OntologyClassBuilder.ontologyClass(id, label), value); } - public static Quantity quantity(OntologyClass unit, double value, ReferenceRange ref) { + public static Quantity of(OntologyClass unit, double value, ReferenceRange ref) { return Quantity.newBuilder().setUnit(unit).setValue(value).setReferenceRange(ref).build(); } - public static QuantityBuilder unitValue(OntologyClass unit, double value) { + public static QuantityBuilder builder(OntologyClass unit, double value) { return new QuantityBuilder(unit, value); } - public static QuantityBuilder unitValue(String id, String label, double value) { + public static QuantityBuilder builder(String id, String label, double value) { return new QuantityBuilder(OntologyClassBuilder.ontologyClass(id, label), value); } @@ -43,13 +43,13 @@ public QuantityBuilder referenceRange(ReferenceRange range) { } public QuantityBuilder referenceRange(OntologyClass unit, double low, double high) { - ReferenceRange range = ReferenceRangeBuilder.referenceRange(unit, low, high); + ReferenceRange range = ReferenceRangeBuilder.of(unit, low, high); builder.setReferenceRange(range); return this; } public QuantityBuilder referenceRange(String id, String label, double low, double high) { - ReferenceRange range = ReferenceRangeBuilder.referenceRange(id, label, low, high); + ReferenceRange range = ReferenceRangeBuilder.of(id, label, low, high); builder.setReferenceRange(range); return this; } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ReferenceRangeBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ReferenceRangeBuilder.java index 8beca5e3..20ef3800 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ReferenceRangeBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ReferenceRangeBuilder.java @@ -17,13 +17,13 @@ public class ReferenceRangeBuilder { private ReferenceRangeBuilder() { } - public static ReferenceRange referenceRange(OntologyClass unit, double low, double high) { + public static ReferenceRange of(OntologyClass unit, double low, double high) { return ReferenceRange.newBuilder().setUnit(unit).setLow(low).setHigh(high).build(); } - public static ReferenceRange referenceRange(String id, String label, double low, double high) { + public static ReferenceRange of(String id, String label, double low, double high) { OntologyClass unit = OntologyClassBuilder.ontologyClass(id, label); - return referenceRange(unit, low, high); + return of(unit, low, high); } } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimeElements.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimeElements.java index 3e40b9e2..6a7d6f70 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimeElements.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimeElements.java @@ -48,12 +48,12 @@ public static TimeElement gestationalAge(int weeks) { } public static TimeElement age(String iso8601duration) { - Age age = AgeBuilder.age(iso8601duration); + Age age = Ages.age(iso8601duration); return TimeElement.newBuilder().setAge(age).build(); } public static TimeElement ageRange(String iso8601start, String iso8601End) { - AgeRange ageRange = AgeBuilder.ageRange(iso8601start, iso8601End); + AgeRange ageRange = Ages.ageRange(iso8601start, iso8601End); return TimeElement.newBuilder().setAgeRange(ageRange).build(); } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilder.java index 13cf6eec..239b8754 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilder.java @@ -10,14 +10,14 @@ public class TimeIntervalBuilder { private TimeIntervalBuilder() { } - public static TimeInterval timeInterval(Timestamp start, Timestamp end) { + public static TimeInterval of(Timestamp start, Timestamp end) { return TimeInterval.newBuilder() .setStart(start) .setEnd(end) .build(); } - public static TimeInterval timeInterval(String start, String end) { + public static TimeInterval of(String start, String end) { return TimeInterval.newBuilder() .setStart(fromISO8601(start)) .setEnd(fromISO8601(end)) diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TreatmentBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TreatmentBuilder.java index 4cf3946d..9404214a 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TreatmentBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TreatmentBuilder.java @@ -12,12 +12,12 @@ private TreatmentBuilder(OntologyClass agent) { builder = Treatment.newBuilder().setAgent(agent); } - public static Treatment treatment(OntologyClass agent) { + public static Treatment of(OntologyClass agent) { return Treatment.newBuilder().setAgent(agent).build(); } - public static Treatment treatment(String agentId, String agentLabel) { - return treatment(OntologyClassBuilder.ontologyClass(agentId, agentLabel)); + public static Treatment of(String agentId, String agentLabel) { + return of(OntologyClassBuilder.ontologyClass(agentId, agentLabel)); } public static TreatmentBuilder builder(OntologyClass agent) { diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TypedQuantityBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TypedQuantityBuilder.java index 158058b5..1e67040a 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TypedQuantityBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TypedQuantityBuilder.java @@ -9,7 +9,7 @@ public class TypedQuantityBuilder { private TypedQuantityBuilder() { } - public static TypedQuantity typedQuantity(OntologyClass type, Quantity quantity) { + public static TypedQuantity of(OntologyClass type, Quantity quantity) { return TypedQuantity.newBuilder().setType(type).setQuantity(quantity).build(); } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ValueBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ValueBuilder.java index f4ebb983..d84e96ba 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ValueBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ValueBuilder.java @@ -12,32 +12,32 @@ public class ValueBuilder { private ValueBuilder() { } - public static Value value(String id, String label) { + public static Value of(String id, String label) { OntologyClass ontologyClass = OntologyClassBuilder.ontologyClass(id, label); - return value(ontologyClass); + return of(ontologyClass); } - public static Value value(OntologyClass ontologyClass) { + public static Value of(OntologyClass ontologyClass) { return Value.newBuilder().setOntologyClass(ontologyClass).build(); } - public static Value value(Quantity quantity) { + public static Value of(Quantity quantity) { return Value.newBuilder().setQuantity(quantity).build(); } - public static Value value(String id, String label, double value) { - Quantity quantity = QuantityBuilder.quantity(id, label, value); - return value(quantity); + public static Value of(String id, String label, double value) { + Quantity quantity = QuantityBuilder.of(id, label, value); + return of(quantity); } - public static Value value(OntologyClass ontologyClass, double value) { - Quantity quantity = QuantityBuilder.quantity(ontologyClass, value); - return value(quantity); + public static Value of(OntologyClass ontologyClass, double value) { + Quantity quantity = QuantityBuilder.of(ontologyClass, value); + return of(quantity); } - public static Value value(OntologyClass ontologyClass, double value, ReferenceRange ref) { - Quantity quantity = QuantityBuilder.quantity(ontologyClass, value, ref); - return value(quantity); + public static Value of(OntologyClass ontologyClass, double value, ReferenceRange ref) { + Quantity quantity = QuantityBuilder.of(ontologyClass, value, ref); + return of(quantity); } } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariantInterpretationBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariantInterpretationBuilder.java index 2e985087..88ad8da9 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariantInterpretationBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariantInterpretationBuilder.java @@ -13,7 +13,7 @@ private VariantInterpretationBuilder(VariationDescriptor descriptor) { builder = VariantInterpretation.newBuilder().setVariationDescriptor(descriptor); } - public static VariantInterpretation variantInterpretation(VariationDescriptor descriptor, AcmgPathogenicityClassification acmgPathogenicityClassification) { + public static VariantInterpretation of(VariationDescriptor descriptor, AcmgPathogenicityClassification acmgPathogenicityClassification) { return VariantInterpretation.newBuilder() .setVariationDescriptor(descriptor) .setAcmgPathogenicityClassification(acmgPathogenicityClassification) @@ -21,7 +21,7 @@ public static VariantInterpretation variantInterpretation(VariationDescriptor de .build(); } - public static VariantInterpretation variantInterpretation(VariationDescriptor descriptor, AcmgPathogenicityClassification acmgPathogenicityClassification, TherapeuticActionability therapeuticActionability) { + public static VariantInterpretation of(VariationDescriptor descriptor, AcmgPathogenicityClassification acmgPathogenicityClassification, TherapeuticActionability therapeuticActionability) { return VariantInterpretation.newBuilder() .setVariationDescriptor(descriptor) .setAcmgPathogenicityClassification(acmgPathogenicityClassification) diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariationDescriptorBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariationDescriptorBuilder.java index 153db950..fe7c631a 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariationDescriptorBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariationDescriptorBuilder.java @@ -149,13 +149,13 @@ public VariationDescriptorBuilder addExpression(Expression expression) { } public VariationDescriptorBuilder vcfHg38(String chromosome, int position, String ref, String alt) { - VcfRecord vcf = VcfRecordBuilder.vcfRecord("GRCh38", chromosome, position, ref, alt); + VcfRecord vcf = VcfRecordBuilder.of("GRCh38", chromosome, position, ref, alt); builder.setVcfRecord(vcf); return this; } public VariationDescriptorBuilder vcfHg37(String chromosome, int position, String ref, String alt) { - VcfRecord vcf = VcfRecordBuilder.vcfRecord("GRCh37", chromosome, position, ref, alt); + VcfRecord vcf = VcfRecordBuilder.of("GRCh37", chromosome, position, ref, alt); builder.setVcfRecord(vcf); return this; } @@ -166,18 +166,18 @@ public VariationDescriptorBuilder vcfHg37(String chromosome, int position, Strin * @param percentage estimated percentage of cells affected by mosaic variant, e.g., 40% */ public VariationDescriptorBuilder mosaicism(double percentage) { - Extension expression = Extensions.mosaicism(percentage); - builder.addExtensions(expression); + Extension percentageExtension = Extensions.mosaicism(percentage); + builder.addExtensions(percentageExtension); return this; } + /** - * @param percentage estimated frequency of an allele (generally a somatic mutation) 25% + * @param frequency estimated frequency (IN PERCENT) of an allele (generally a somatic mutation) */ - public VariationDescriptorBuilder alleleFrequency(double percentage) { - Expression expression = - Expression.newBuilder().setSyntax("allele-frequency").setValue(String.format("%.1f%%", percentage)).build(); - builder.addExpressions(expression); + public VariationDescriptorBuilder alleleFrequency(double frequency) { + Extension alleleFrequencyExtension = Extensions.alleleFrequency(frequency); + builder.addExtensions(alleleFrequencyExtension); return this; } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VcfRecordBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VcfRecordBuilder.java index bfd1c190..472c56b8 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VcfRecordBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VcfRecordBuilder.java @@ -15,7 +15,7 @@ private VcfRecordBuilder(String assembly, String chromosome, int position, Strin .setAlt(alt); } - public static VcfRecord vcfRecord(String assembly, String chromosome, int position, String ref, String alt) { + public static VcfRecord of(String assembly, String chromosome, int position, String ref, String alt) { return VcfRecord.newBuilder() .setGenomeAssembly(assembly) .setChrom(chromosome) diff --git a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AgeBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AgeBuilderTest.java index 6729abc4..aa714128 100644 --- a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AgeBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AgeBuilderTest.java @@ -15,7 +15,7 @@ class AgeBuilderTest { */ @Test void testAge() { - Age age = AgeBuilder.age("P25Y3M2D"); + Age age = Ages.age("P25Y3M2D"); assertThat(age.getIso8601Duration(), equalTo("P25Y3M2D")); } @@ -24,9 +24,9 @@ void testAge() { */ @Test void testAgeRange() { - AgeRange ageRange = AgeBuilder.ageRange("P45Y", "P49Y"); - assertThat(ageRange.getStart(), equalTo(AgeBuilder.age("P45Y"))); - assertThat(ageRange.getEnd(), equalTo(AgeBuilder.age("P49Y"))); + AgeRange ageRange = Ages.ageRange("P45Y", "P49Y"); + assertThat(ageRange.getStart(), equalTo(Ages.age("P45Y"))); + assertThat(ageRange.getEnd(), equalTo(Ages.age("P49Y"))); } /** @@ -34,7 +34,7 @@ void testAgeRange() { */ @Test void testGestationalAge() { - GestationalAge gestationalAge = AgeBuilder.gestationalAge(33, 2); + GestationalAge gestationalAge = Ages.gestationalAge(33, 2); assertThat(gestationalAge.getWeeks(), equalTo(33)); assertThat(gestationalAge.getDays(), equalTo(2)); } diff --git a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilderTest.java index 4890a1d9..3b918608 100644 --- a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilderTest.java @@ -12,10 +12,10 @@ class AlleleBuilderTest { @Test void testBuild() { Variation variation = AlleleBuilder.builder() - .setSequenceId("NC_000003.12") + .sequenceId("NC_000003.12") .startEnd(42686219, 42686220) .chromosomeLocation("chr3") - .setAltAllele("A") + .altAllele("A") .buildVariation(); assertThat(variation.hasAllele(), equalTo(true)); diff --git a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilderTest.java index e3eafb5b..17b3d3a4 100644 --- a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilderTest.java @@ -29,7 +29,7 @@ void biosampleBuilderTest() { .histologicalDiagnosis(ontologyClass("NCIT:C39853", "Infiltrating Urothelial Carcinoma")) .tumorProgression(ontologyClass("NCIT:C84509", "Primary Malignant Neoplasm")) .tumorGrade(ontologyClass("NCIT:C36136", "Grade 2 Lesion")) - .procedure(ProcedureBuilder.procedure("NCIT:C5189", "Radical Cystoprostatectomy")) + .procedure(ProcedureBuilder.of("NCIT:C5189", "Radical Cystoprostatectomy")) .addFile(FileBuilder.builder("file:///data/genomes/urothelial_ca_wgs.vcf.gz") .individualToFileIdentifier("patient1", "NA12345") .addFileAttribute("genomeAssembly", "GRCh38") @@ -48,7 +48,7 @@ void biosampleBuilderTest() { assertThat(biosample.getHistologicalDiagnosis(), equalTo(ontologyClass("NCIT:C39853", "Infiltrating Urothelial Carcinoma"))); assertThat(biosample.getTumorProgression(), equalTo(ontologyClass("NCIT:C84509", "Primary Malignant Neoplasm"))); assertThat(biosample.getTumorGrade(), equalTo(ontologyClass("NCIT:C36136", "Grade 2 Lesion"))); - assertThat(biosample.getProcedure(), equalTo(ProcedureBuilder.procedure("NCIT:C5189", "Radical Cystoprostatectomy"))); + assertThat(biosample.getProcedure(), equalTo(ProcedureBuilder.of("NCIT:C5189", "Radical Cystoprostatectomy"))); assertThat(biosample.getFilesList(), equalTo(List.of(FileBuilder.builder("file:///data/genomes/urothelial_ca_wgs.vcf.gz") .individualToFileIdentifier("patient1", "NA12345") .addFileAttribute("genomeAssembly", "GRCh38") diff --git a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilderTest.java index 379bb619..6c245dbd 100644 --- a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilderTest.java @@ -19,9 +19,9 @@ class ComplexValueBuilderTest { @Test void testComplexValue() { OntologyClass millimeterOfMercury = ontologyClass("NCIT:C49670", "Millimeter of Mercury"); - TypedQuantity systolicBloodPressure = TypedQuantityBuilder.typedQuantity(ontologyClass("NCIT:C25298", "Systolic Blood Pressure"), QuantityBuilder.quantity(millimeterOfMercury, 120)); - TypedQuantity diastolicBloodPressure = TypedQuantityBuilder.typedQuantity(ontologyClass("NCIT:C25299", "Diastolic Blood Pressure"), QuantityBuilder.quantity(millimeterOfMercury, 70)); - ComplexValue complexValue = ComplexValueBuilder.complexValue(systolicBloodPressure, diastolicBloodPressure); + TypedQuantity systolicBloodPressure = TypedQuantityBuilder.of(ontologyClass("NCIT:C25298", "Systolic Blood Pressure"), QuantityBuilder.of(millimeterOfMercury, 120)); + TypedQuantity diastolicBloodPressure = TypedQuantityBuilder.of(ontologyClass("NCIT:C25299", "Diastolic Blood Pressure"), QuantityBuilder.of(millimeterOfMercury, 70)); + ComplexValue complexValue = ComplexValueBuilder.of(systolicBloodPressure, diastolicBloodPressure); assertThat(complexValue.getTypedQuantitiesList(), equalTo(List.of(systolicBloodPressure, diastolicBloodPressure))); } diff --git a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiagnosisBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiagnosisBuilderTest.java index 64bc4bf7..755bb20d 100644 --- a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiagnosisBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiagnosisBuilderTest.java @@ -19,7 +19,7 @@ void testDiagnosisBuilder() { .heterozygous() .hgvs("NM_014915.2:c.-128G>A") .build(); - var col6a1VariantInterpretation = VariantInterpretationBuilder.variantInterpretation(variationDescriptor, Status.pathogenic()); + var col6a1VariantInterpretation = VariantInterpretationBuilder.of(variationDescriptor, Status.pathogenic()); var genomicInterpretationBuilder = GenomicInterpretationBuilder.builder("genomic interpretation id"); genomicInterpretationBuilder.causative(); diff --git a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilderTest.java index 5002696b..6cefcf80 100644 --- a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilderTest.java @@ -11,7 +11,7 @@ class DiseaseBuilderTest { @Test void testMinimalData() { - Disease disease = DiseaseBuilder.disease("MONDO:0004994", "cardiomyopathy"); + Disease disease = DiseaseBuilder.of("MONDO:0004994", "cardiomyopathy"); assertThat(disease.getTerm(), equalTo(ontologyClass("MONDO:0004994", "cardiomyopathy"))); } diff --git a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DoseIntervalBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DoseIntervalBuilderTest.java index d1a22e70..481a66f8 100644 --- a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DoseIntervalBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DoseIntervalBuilderTest.java @@ -15,11 +15,11 @@ public class DoseIntervalBuilderTest { @Test public void testDoseInterval1() { var mg = ontologyClass("UO:0000022", "milligram"); - var quantity = QuantityBuilder.quantity(mg, 30.0); + var quantity = QuantityBuilder.of(mg, 30.0); var administration = ontologyClass("NCIT:C38288", "Oral Route of Administration"); var bid = ontologyClass("NCIT:C64496", "Twice Daily"); - var interval = TimeIntervalBuilder.timeInterval("2019-03-20T00:00:00Z", "2021-03-20T00:00:00Z"); - DoseInterval dosage = DoseIntervalBuilder.doseInterval(quantity, bid, interval); + var interval = TimeIntervalBuilder.of("2019-03-20T00:00:00Z", "2021-03-20T00:00:00Z"); + DoseInterval dosage = DoseIntervalBuilder.of(quantity, bid, interval); assertEquals(30.0, dosage.getQuantity().getValue()); TimeInterval timeInterval = dosage.getInterval(); Timestamp start = timeInterval.getStart(); diff --git a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilderTest.java index 9e5c9315..48c9b6b3 100644 --- a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilderTest.java @@ -14,7 +14,7 @@ class TimeIntervalBuilderTest { */ @Test void timeIntervalFromStringTest() { - TimeInterval instance = TimeIntervalBuilder.timeInterval("2020-03-15T13:00:00Z", "2020-03-25T09:00:00Z"); + TimeInterval instance = TimeIntervalBuilder.of("2020-03-15T13:00:00Z", "2020-03-25T09:00:00Z"); assertThat(instance.getStart().getSeconds(), equalTo(1584277200L)); assertThat(instance.getEnd().getSeconds(), equalTo(1585126800L)); } @@ -23,7 +23,7 @@ void timeIntervalFromStringTest() { void timeIntervalFromTimestampTest() { Timestamp start = TimestampBuilder.fromISO8601("2020-03-15T13:00:00Z"); Timestamp end = TimestampBuilder.fromISO8601("2020-03-25T09:00:00Z"); - TimeInterval instance = TimeIntervalBuilder.timeInterval(start, end); + TimeInterval instance = TimeIntervalBuilder.of(start, end); assertThat(instance.getStart(), equalTo(start)); assertThat(instance.getEnd(), equalTo(end)); } diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/BethlehamMyopathy.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/BethlehamMyopathy.java index 785b8745..9d1c8796 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/BethlehamMyopathy.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/BethlehamMyopathy.java @@ -30,7 +30,7 @@ class BethlehamMyopathy implements PhenopacketExample { .hgvs("NM_001848.2:c.877G>A") .build(); var col6a1VariantInterpretation = - VariantInterpretationBuilder.variantInterpretation(variationDescriptor, Status.pathogenic()); + VariantInterpretationBuilder.of(variationDescriptor, Status.pathogenic()); var genomicInterpretation = GenomicInterpretationBuilder.builder(INTERPRETATION_ID) .causative() diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Covid.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Covid.java index b0c67f83..df5ab395 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Covid.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Covid.java @@ -38,17 +38,17 @@ class Covid implements PhenopacketExample { .vitalStatus(VitalStatusBuilder.deceased().causeOfDeath("MONDO:0100096", "COVID-19").build()) .build(); - Disease cardiomyopathy = DiseaseBuilder.disease("MONDO:0004994", "cardiomyopathy"); + Disease cardiomyopathy = DiseaseBuilder.of("MONDO:0004994", "cardiomyopathy"); Disease covid = DiseaseBuilder .builder("MONDO:0100096", "COVID-19") .onset(TimeElements.timestamp("2020-03-17T00:00:00Z")) .build(); - var bloodGroupA = PhenotypicFeatureBuilder.phenotypicFeature("HP:0032370", "Blood group A"); - var rhesusPositive = PhenotypicFeatureBuilder.phenotypicFeature("NCIT:C76251", "Rh Positive Blood Group"); - var obesityPhenotype = PhenotypicFeatureBuilder.phenotypicFeature(obesity); - var externalRef = ExternalReferenceBuilder.builder() + var bloodGroupA = PhenotypicFeatureBuilder.of("HP:0032370", "Blood group A"); + var rhesusPositive = PhenotypicFeatureBuilder.of("NCIT:C76251", "Rh Positive Blood Group"); + var obesityPhenotype = PhenotypicFeatureBuilder.of(obesity); + var externalRef = ExternalReferenceBuilder.reference() .id("DOI:10.1016/j.jaccas.2020.04.001") - .builder("PMID:32292915") + .reference("PMID:32292915") .description("The Imperfect Cytokine Storm: Severe COVID-19 With ARDS in a Patient on Durable LVAD Support") .build(); var metaData = MetaDataBuilder.builder("2021-08-17T00:00:00Z", "anonymous biocurator") @@ -129,15 +129,15 @@ private List getAllPhenotypicFeatures() { private List getAllMeasurements() { List measurements = new ArrayList<>(); - Value value = ValueBuilder.value(QuantityBuilder.quantity("NCIT:C67245", "Thousand Cells", 1.4)); + Value value = ValueBuilder.of(QuantityBuilder.of("NCIT:C67245", "Thousand Cells", 1.4)); var assay = ontologyClass("LOINC:26474-7", "Lymphocytes [#/volume] in Blood"); - var initialBloodLymphocyteCount = MeasurementBuilder.value(assay, value) + var initialBloodLymphocyteCount = MeasurementBuilder.builder(assay, value) .timeObserved(TimeElements.interval("2019-09-01T00:00:00Z", "2020-03-01T00:00:00Z")) .build(); measurements.add(initialBloodLymphocyteCount); - Value value2 = ValueBuilder.value(QuantityBuilder.quantity("NCIT:C67245", "Thousand Cells", 0.7)); + Value value2 = ValueBuilder.of(QuantityBuilder.of("NCIT:C67245", "Thousand Cells", 0.7)); - var hoD0bloodLymphocyteCount = MeasurementBuilder.value(assay, value2) + var hoD0bloodLymphocyteCount = MeasurementBuilder.builder(assay, value2) .timeObserved(TimeElements.timestamp(RETURN_TO_HOSPITAL_TIME)) .build(); measurements.add(hoD0bloodLymphocyteCount); @@ -145,14 +145,14 @@ private List getAllMeasurements() { } private MedicalAction nasalOxygenAdministered() { - Quantity twoLperMin = QuantityBuilder.quantity("NCIT:C67388", "Liter per Minute", 2); - var interval1 = DoseIntervalBuilder.doseInterval(twoLperMin, + Quantity twoLperMin = QuantityBuilder.of("NCIT:C67388", "Liter per Minute", 2); + var interval1 = DoseIntervalBuilder.of(twoLperMin, CONTINUOUS, - TimeIntervalBuilder.timeInterval("2021-02-01T18:58:43Z", "2021-02-02T08:22:42Z")); - Quantity fiftyLperMin = QuantityBuilder.quantity("NCIT:C67388", "Liter per Minute", 50); - var interval2 = DoseIntervalBuilder.doseInterval(fiftyLperMin, + TimeIntervalBuilder.of("2021-02-01T18:58:43Z", "2021-02-02T08:22:42Z")); + Quantity fiftyLperMin = QuantityBuilder.of("NCIT:C67388", "Liter per Minute", 50); + var interval2 = DoseIntervalBuilder.of(fiftyLperMin, CONTINUOUS, - TimeIntervalBuilder.timeInterval("2021-02-02T08:22:42Z", "2021-02-02T12:22:42Z")); + TimeIntervalBuilder.of("2021-02-02T08:22:42Z", "2021-02-02T12:22:42Z")); Treatment nasalOxygen = TreatmentBuilder.builder("NCIT:C722", "Oxygen") .routeOfAdministration(ontologyClass("NCIT:C38284", "Nasal Route of Administration")) .addDoseInterval(interval1) @@ -174,8 +174,8 @@ private MedicalAction trachealIntubation() { } private MedicalAction peepOxygenAdministered() { - Quantity quantity = QuantityBuilder.quantity("NCIT:C91060", "Centimeters of Water", 14); - var doseInterval = DoseIntervalBuilder.doseInterval(quantity, CONTINUOUS, "2020-03-22", "2020-03-28"); + Quantity quantity = QuantityBuilder.of("NCIT:C91060", "Centimeters of Water", 14); + var doseInterval = DoseIntervalBuilder.of(quantity, CONTINUOUS, "2020-03-22", "2020-03-28"); Treatment oxygen = TreatmentBuilder.builder(ontologyClass("NCIT:C722", "Oxygen")) .routeOfAdministration(ontologyClass("NCIT:C50254", "Positive end Expiratory Pressure Valve Device")) .addDoseInterval(doseInterval) @@ -184,9 +184,9 @@ private MedicalAction peepOxygenAdministered() { } private MedicalAction tocilizumabAdministered() { - Quantity quantity = QuantityBuilder.quantity("NCIT:C124458", "Milligram per Kilogram per Dose", 4); + Quantity quantity = QuantityBuilder.of("NCIT:C124458", "Milligram per Kilogram per Dose", 4); OntologyClass q4weeks = ontologyClass("NCIT:C64529", "Every Four Weeks"); - var doseInterval = DoseIntervalBuilder.doseInterval(quantity, q4weeks, "2020-03-24", "2020-03-28"); + var doseInterval = DoseIntervalBuilder.of(quantity, q4weeks, "2020-03-24", "2020-03-28"); var treatment = TreatmentBuilder.builder("NCIT:C84217", "Tocilizumab") .addDoseInterval(doseInterval) .build(); @@ -195,9 +195,9 @@ private MedicalAction tocilizumabAdministered() { private MedicalAction dexamethasone() { // ten days, 6 mg once a day - Quantity quantity = QuantityBuilder.quantity("UO:0000022", "milligram", 6); + Quantity quantity = QuantityBuilder.of("UO:0000022", "milligram", 6); OntologyClass onceDaily = ontologyClass("NCIT:C125004", "Once Daily"); - var doseInterval = DoseIntervalBuilder.doseInterval(quantity, onceDaily, "2020-03-20", "2020-03-30"); + var doseInterval = DoseIntervalBuilder.of(quantity, onceDaily, "2020-03-20", "2020-03-30"); Treatment dexa = TreatmentBuilder.builder("CHEBI:41879", "dexamethasone") .addDoseInterval(doseInterval) diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Marfan.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Marfan.java index ffe55020..ec6aaa41 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Marfan.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Marfan.java @@ -14,17 +14,17 @@ class Marfan implements PhenopacketExample { private final Phenopacket phenopacket; Marfan() { - var marfan = DiseaseBuilder.disease("OMIM:154700 ", "Marfan syndrome"); + var marfan = DiseaseBuilder.of("OMIM:154700 ", "Marfan syndrome"); var individual = IndividualBuilder.builder(PROBAND_ID).female().ageAtLastEncounter("P27Y").build(); var losartan = ontologyClass("DrugCentral:1610", "losartan"); var mg = ontologyClass("UO:0000022", "milligram"); var aorticAneurysm = - PhenotypicFeatureBuilder.phenotypicFeature("HP:0002616", "Aortic root aneurysm"); - var quantity = QuantityBuilder.quantity(mg, 30.0); + PhenotypicFeatureBuilder.of("HP:0002616", "Aortic root aneurysm"); + var quantity = QuantityBuilder.of(mg, 30.0); var administration = ontologyClass("NCIT:C38288", "Oral Route of Administration"); var bid = ontologyClass("NCIT:C64496", "Twice Daily"); - var interval = TimeIntervalBuilder.timeInterval("2019-03-20T00:00:00Z", "2021-03-20T00:00:00Z"); - var dosage = DoseIntervalBuilder.doseInterval(quantity, bid, interval); + var interval = TimeIntervalBuilder.of("2019-03-20T00:00:00Z", "2021-03-20T00:00:00Z"); + var dosage = DoseIntervalBuilder.of(quantity, bid, interval); var losartanTreatment = TreatmentBuilder .builder(losartan) .addDoseInterval(dosage) diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/NemalineMyopathyPrenatal.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/NemalineMyopathyPrenatal.java index aed615af..edcb8042 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/NemalineMyopathyPrenatal.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/NemalineMyopathyPrenatal.java @@ -122,9 +122,9 @@ GenomicInterpretation klhl40InterpretationV1() { //HGNC:30372 //abuilder.setSequenceId("ga4gh:VA.GuPzvZoansqNHPoXkQLXKo31VkTpDKsM"); Variation variation = AlleleBuilder.builder() - .setSequenceId("NC_000003.12") + .sequenceId("NC_000003.12") .startEnd(42686219, 42686220) - .setAltAllele("A") + .altAllele("A") .buildVariation(); VariationDescriptorBuilder vbuilder = VariationDescriptorBuilder.builder("rs397509420") .variation(variation) @@ -160,9 +160,9 @@ GenomicInterpretation klhl40InterpretationV2() { // dbSNP: rs778022582 //HGNC:30372 AlleleBuilder abuilder = AlleleBuilder.builder() - .setSequenceId("NC_000003.12") + .sequenceId("NC_000003.12") .startEnd( 42688962, 42688963) - .setAltAllele("C"); + .altAllele("C"); VariationDescriptorBuilder vbuilder = VariationDescriptorBuilder.builder("rs778022582") .variation(abuilder.buildVariation()) .genomic() diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java index a3849afc..e02f1127 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java @@ -38,7 +38,9 @@ public Retinoblastoma() { XX(). build(); // VCF file with results of germline whole-genome sequencing - File wgsFile = FileBuilder.file("file://data/germlineWgs.vcf.gz"); + File wgsFile = FileBuilder.hg38vcf("file://data/germlineWgs.vcf.gz") + .individualToFileIdentifier(PROBAND_ID, "sample1") + .build(); phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metadata) .individual(proband) @@ -70,10 +72,9 @@ Interpretation interpretation() { */ GenomicInterpretation somaticRb1Missense() { AlleleBuilder abuilder = AlleleBuilder.builder(); - // abuilder.setSequenceId("ga4gh:VA.GuPzvZoansqNHPoXkQLXKo31VkTpDKsM"); - abuilder.setSequenceId("refseq:NC_000013.14"); + abuilder.sequenceId("refseq:NC_000013.14"); abuilder.startEnd( 48941647, 48941648); - abuilder.setAltAllele("T"); + abuilder.altAllele("T"); VariationDescriptorBuilder vbuilder = VariationDescriptorBuilder.builder("rs121913300") .variation(abuilder.buildVariation()) .genomic() @@ -82,7 +83,7 @@ GenomicInterpretation somaticRb1Missense() { .transcript() .vcfHg38("NC_000013.11", 48367512, "C", "T") .alleleFrequency(25.0) - .geneContext(GeneDescriptorBuilder.geneDescriptor("HGNC:9884", "RB1")) + .geneContext(GeneDescriptorBuilder.of("HGNC:9884", "RB1")) .addExpression(Expressions.hgvsCdna("NM_000321.2:c.958C>T")) .addExpression(Expressions.transcriptReference("NM_000321.2")); // wrap in VariantInterpretation @@ -90,7 +91,6 @@ GenomicInterpretation somaticRb1Missense() { vibuilder.pathogenic(); vibuilder.actionable(); - GenomicInterpretationBuilder gbuilder = GenomicInterpretationBuilder.builder(BIOSAMPLE_ID); gbuilder.causative(); gbuilder.variantInterpretation(vibuilder); @@ -102,11 +102,14 @@ GenomicInterpretation somaticRb1Missense() { GenomicInterpretation germlineRb1Deletion() { CopyNumberBuilder abuilder = CopyNumberBuilder.builder(); //abuilder.copyNumberId("ga4gh:VCN.AFfJws1M4Lg8w1O3XknmHYc9TU2hHYpp"); - abuilder.alleleLocation("refseq:NC_000013.14",26555377, 62280955);//VRS uses inter-residue coordinates + // original coordinates in paper were given as 13q12.13q21.2(26,555,387–62,280,955 for hg19 + //chr13 25981249 61706822 -- lifted over to hg38 + + abuilder.alleleLocation("refseq:NC_000013.14",25981249, 61706822);//VRS uses inter-residue coordinates abuilder.oneCopy(); VariationDescriptorBuilder vbuilder = VariationDescriptorBuilder.builder(); vbuilder.variation(abuilder.buildVariation()); - // vbuilder.mosaicism(40.0); + vbuilder.mosaicism(40.0); VariantInterpretationBuilder vibuilder = VariantInterpretationBuilder.builder(vbuilder); vibuilder.pathogenic(); vibuilder.actionable(); @@ -162,8 +165,8 @@ Biosample enucleatedEye() { biosampleBuilder.addPhenotypicFeature("NCIT:C35941", "Flexner-Wintersteiner Rosette Formation"); biosampleBuilder.addPhenotypicFeature("NCIT:C132485", "Apoptosis and Necrosis"); OntologyClass maxTumorSizeTest = OntologyClassBuilder.ontologyClass("LOINC:33728-7", "Size.maximum dimension in Tumor"); - Value maxTumorSize = ValueBuilder.value(Unit.mm(), 15); - Measurement maxTumorSizeMeasurement = MeasurementBuilder.value(maxTumorSizeTest, maxTumorSize).timeObserved(age).build(); + Value maxTumorSize = ValueBuilder.of(Unit.mm(), 15); + Measurement maxTumorSizeMeasurement = MeasurementBuilder.builder(maxTumorSizeTest, maxTumorSize).timeObserved(age).build(); biosampleBuilder.addMeasurement(maxTumorSizeMeasurement); Procedure enucleation = ProcedureBuilder.builder("NCIT:C48601", "Enucleation") @@ -173,7 +176,9 @@ Biosample enucleatedEye() { biosampleBuilder.procedure(enucleation); biosampleBuilder.tumorProgression(PRIMARY_NEOPLASM); // VCF file with results of whole-genome sequencing on this tumor - File wgsFile = FileBuilder.file("file://data/fileSomaticWgs.vcf.gz"); + File wgsFile = FileBuilder.hg38vcf("file://data/fileSomaticWgs.vcf.gz") + .individualToFileIdentifier(BIOSAMPLE_ID, "specimen.1") + .build(); biosampleBuilder.addFile(wgsFile); return biosampleBuilder.build(); } @@ -184,11 +189,11 @@ MedicalAction melphalan() { OntologyClass melphalan = ontologyClass("DrugCentral:1678", "melphalan"); OntologyClass administration = ontologyClass("NCIT:C38222", "Intraarterial Route of Administration"); //0.4 mg/kg (up to a starting dose of 5 mg) - Quantity quantity = QuantityBuilder.quantity(Unit.mgPerKg(), 0.4); - TimeInterval interval = TimeIntervalBuilder.timeInterval("2020-09-02", "2020-09-02"); + Quantity quantity = QuantityBuilder.of(Unit.mgPerKg(), 0.4); + TimeInterval interval = TimeIntervalBuilder.of("2020-09-02", "2020-09-02"); OntologyClass once = ontologyClass("NCIT:C64576", "Once"); - DoseInterval doseInterval = DoseIntervalBuilder.doseInterval(quantity, once, interval); + DoseInterval doseInterval = DoseIntervalBuilder.of(quantity, once, interval); Treatment treatment = TreatmentBuilder.builder(melphalan) @@ -289,17 +294,17 @@ List getPhenotypicFeatures() { */ List getMeasurements() { OntologyClass iop = ontologyClass("56844-4","Intraocular pressure of Eye"); - ReferenceRange ref = ReferenceRangeBuilder.referenceRange(iop, 10, 21); + ReferenceRange ref = ReferenceRangeBuilder.of(iop, 10, 21); OntologyClass leftEyeIop = OntologyClassBuilder.ontologyClass("LOINC:79893-4", "Left eye Intraocular pressure"); - Value leftEyeValue = ValueBuilder.value(Unit.mmHg(), 25, ref); + Value leftEyeValue = ValueBuilder.of(Unit.mmHg(), 25, ref); OntologyClass rightEyeIop = OntologyClassBuilder.ontologyClass("LOINC:79892-6", "Right eye Intraocular pressure"); - Value rightEyeValue = ValueBuilder.value(Unit.mmHg(), 15, ref); + Value rightEyeValue = ValueBuilder.of(Unit.mmHg(), 15, ref); TimeElement age = TimeElements.age("P6M"); - Measurement leftEyeMeasurement = MeasurementBuilder.value(leftEyeIop, leftEyeValue).timeObserved(age).build(); - Measurement rightEyeMeasurement = MeasurementBuilder.value(rightEyeIop, rightEyeValue).timeObserved(age).build(); + Measurement leftEyeMeasurement = MeasurementBuilder.builder(leftEyeIop, leftEyeValue).timeObserved(age).build(); + Measurement rightEyeMeasurement = MeasurementBuilder.builder(rightEyeIop, rightEyeValue).timeObserved(age).build(); //33728-7 Size.maximum dimension in Tumor //14 × 13 × 11 mm left eye tumor return List.of(leftEyeMeasurement, rightEyeMeasurement); diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Thrombocytopenia2.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Thrombocytopenia2.java index ba0d8e0d..97d76747 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Thrombocytopenia2.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Thrombocytopenia2.java @@ -28,7 +28,7 @@ class Thrombocytopenia2 implements PhenopacketExample { .heterozygous() .hgvs("NM_014915.2:c.-128G>A") .build(); - var col6a1VariantInterpretation = VariantInterpretationBuilder.variantInterpretation(variationDescriptor, Status.pathogenic()); + var col6a1VariantInterpretation = VariantInterpretationBuilder.of(variationDescriptor, Status.pathogenic()); var genomicInterpretation = GenomicInterpretationBuilder.builder("genomic interpretation id") .causative() diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/UrothelialCancer.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/UrothelialCancer.java index 5f9e0cc0..72fe95ab 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/UrothelialCancer.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/UrothelialCancer.java @@ -19,7 +19,7 @@ class UrothelialCancer implements PhenopacketExample { UrothelialCancer() { var individual = IndividualBuilder.builder(PROBAND_ID).male().dateOfBirth("1964-03-15T00:00:00Z").build(); - var hematuria = PhenotypicFeatureBuilder.phenotypicFeature("HP:0000790","Hematuria"); + var hematuria = PhenotypicFeatureBuilder.of("HP:0000790","Hematuria"); var dsyuria = PhenotypicFeatureBuilder.builder("HP:0100518", "Dysuria") .severity(Severity.severe()) .build(); diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlOutputter.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlOutputter.java index bae9e749..b8b6862b 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlOutputter.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlOutputter.java @@ -219,11 +219,4 @@ private String row(List fields) { } - private void outputSection(Writer writer, String Title, Map kv) { - - } - - - - } diff --git a/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java b/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java index bc8c64f7..ac6473ce 100644 --- a/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java +++ b/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java @@ -4,15 +4,16 @@ import org.junit.jupiter.api.Test; import org.phenopackets.phenopackettools.converter.converters.PhenopacketConverter; -class PhenopacketConverterTest { +import static org.junit.jupiter.api.Assertions.assertNotNull; +class PhenopacketConverterTest { + /** + * To output: System.out.println(JsonFormat.printer().print(v2Phenopacket)); + */ @Test - void name() throws InvalidProtocolBufferException { + void name() { org.phenopackets.schema.v1.Phenopacket v1Phenopacket = BethlemMyopathyV1.proband(); - org.phenopackets.schema.v2.Phenopacket v2Phenopacket = PhenopacketConverter.toV2Phenopacket(v1Phenopacket); - -// System.out.println(JsonFormat.printer().print(v1Phenopacket)); -// System.out.println(JsonFormat.printer().print(v2Phenopacket)); + assertNotNull(v2Phenopacket); } } \ No newline at end of file From b21fdc55cbb086fd285a24e79b4e5d4310279036 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Thu, 21 Apr 2022 17:59:17 -0400 Subject: [PATCH 015/155] Adding GNU3 license --- LICENSE | 677 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 677 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..0a170278 --- /dev/null +++ b/LICENSE @@ -0,0 +1,677 @@ +Copyright (c) 2022, Global Alliance for Genomics and Health + All rights reserved. + + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. \ No newline at end of file From 5cc588b8133c58ed222744f85d18b7bb425ed5fb Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Thu, 21 Apr 2022 18:07:55 -0400 Subject: [PATCH 016/155] cleanup --- .../builder/builders/IndividualBuilder.java | 10 ++++++++++ .../converter/PhenopacketConverterTest.java | 1 - 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilder.java index 32079ab7..6a54534d 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilder.java @@ -91,6 +91,16 @@ public IndividualBuilder female() { return this; } + public IndividualBuilder unknownSex() { + builder.setSex(Sex.UNKNOWN_SEX); + return this; + } + + public IndividualBuilder otherSex() { + builder.setSex(Sex.OTHER_SEX); + return this; + } + public IndividualBuilder XX() { builder.setKaryotypicSex(KaryotypicSex.XX); return this; diff --git a/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java b/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java index ac6473ce..d6b10593 100644 --- a/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java +++ b/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java @@ -1,6 +1,5 @@ package org.phenopackets.phenopackettools.converter; -import com.google.protobuf.InvalidProtocolBufferException; import org.junit.jupiter.api.Test; import org.phenopackets.phenopackettools.converter.converters.PhenopacketConverter; From 4cb95a75b0d8626286d9212489797bbf9d4d4d94 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Sat, 23 Apr 2022 09:03:16 -0400 Subject: [PATCH 017/155] updating TNM --- .../phenopackettools/examples/Retinoblastoma.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java index e02f1127..c8eae4fb 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java @@ -158,9 +158,9 @@ Biosample enucleatedEye() { BiosampleBuilder biosampleBuilder = BiosampleBuilder.builder(BIOSAMPLE_ID); biosampleBuilder.sampledTissue(EYE); //Retinoblastoma with tumor invading optic nerve past lamina cribrosa but not to surgical resection line and exhibiting massive choroidal invasion. - biosampleBuilder.addPathologicalTnmFinding(ontologyClass("NCIT:C88735", "Retinoblastoma pT3b TNM Finding v7")); + biosampleBuilder.addPathologicalTnmFinding(ontologyClass("NCIT:C140720", "Retinoblastoma pT3 TNM Finding v8")); //Retinoblastoma with no regional lymph node involvement. - biosampleBuilder.addPathologicalTnmFinding(ontologyClass("NCIT:C88741","Retinoblastoma pN0 TNM Finding v7")); + biosampleBuilder.addPathologicalTnmFinding(ontologyClass("NCIT:C140711","Retinoblastoma pN0 TNM Finding v8")); biosampleBuilder.addPhenotypicFeature("NCIT:C35941", "Flexner-Wintersteiner Rosette Formation"); biosampleBuilder.addPhenotypicFeature("NCIT:C132485", "Apoptosis and Necrosis"); From b5b35cfc72a4a2ba622b41b6574064073cfb836a Mon Sep 17 00:00:00 2001 From: Tudor Groza Date: Mon, 25 Apr 2022 23:07:53 +0800 Subject: [PATCH 018/155] WIP - First PXF examples. --- ...rvicofacialActinomycosisOfTheMandible.java | 170 ++++++++++++++++++ ...ngSyndromeWithMultifocalOsteonecrosis.java | 165 +++++++++++++++++ .../PneumothoraxSecondaryToCOVID.java | 138 ++++++++++---- ...SevereStatinInducedAutoimmuneMyopathy.java | 162 +++++++++++++++++ 4 files changed, 605 insertions(+), 30 deletions(-) create mode 100644 phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/CervicofacialActinomycosisOfTheMandible.java create mode 100644 phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/CushingSyndromeWithMultifocalOsteonecrosis.java create mode 100644 phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/SevereStatinInducedAutoimmuneMyopathy.java diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/CervicofacialActinomycosisOfTheMandible.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/CervicofacialActinomycosisOfTheMandible.java new file mode 100644 index 00000000..503f4e30 --- /dev/null +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/CervicofacialActinomycosisOfTheMandible.java @@ -0,0 +1,170 @@ +package org.phenopackets.phenotools.examples; + +import org.phenopackets.phenotools.builder.PhenopacketBuilder; +import org.phenopackets.phenotools.builder.builders.*; +import org.phenopackets.schema.v2.Phenopacket; +import org.phenopackets.schema.v2.core.Individual; +import org.phenopackets.schema.v2.core.Interpretation; +import org.phenopackets.schema.v2.core.MedicalAction; +import org.phenopackets.schema.v2.core.PhenotypicFeature; + +import java.util.List; + +import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; + +public class CervicofacialActinomycosisOfTheMandible { + + + private static final String PHENOPACKET_ID = "arbitrary.id"; + private static final String INDIVIDUAL = "individual A"; + + private final Phenopacket phenopacket; + + public CervicofacialActinomycosisOfTheMandible() { + + var externalRef = ExternalReferenceBuilder.builder() + .id("DOI:10.1136/bcr-2019-233681") + .builder("PMID:32467116") + .description("Cervicofacial actinomycosis of the mandible in a paediatric patient") + .build(); + + //TODO: Fix ontology versions + var metadata = MetaDataBuilder.builder("2022-04-21T10:35:00Z", "anonymous biocurator") + .resource(Resources.ncitVersion("21.05d")) + .resource(Resources.hpoVersion("2021-08-02")) + .resource(Resources.efoVersion("3.34.0")) + .resource(Resources.uberonVersion("2021-07-27")) + .resource(Resources.ncbiTaxonVersion("2021-06-10")) + .externalReference(externalRef) + .build(); + + Individual proband = IndividualBuilder.builder(INDIVIDUAL). + ageAtLastEncounter("P10Y"). + female(). + build(); + + phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metadata) + .individual(proband) + .addAllPhenotypicFeatures(getMedicalHistory()) + .addAllPhenotypicFeatures(getLast8Monthsistory()) + .addMedicalAction(neckCT()) + .addMedicalAction(mri()) + .addPhenotypicFeature(examination()) + .addInterpretation(interpretation()) + .addMedicalAction(biopsy()) + .addMedicalAction(frozenSection()) + .addMedicalAction(tissueCultures()) + .addMedicalAction(anaerobicCultures()) + .addMedicalAction(treatment()) + .build(); + } + + /** + * - Expanded medullary spaces with oedema and vascular proliferation + * - No cytological atypia + * - negative for D2-40 and PROX1 + */ + private MedicalAction frozenSection() { + return null; + } + + /** + * Negative for fungal and acid-fast bacilli + */ + private MedicalAction tissueCultures() { + return null; + } + + /** + * Anaerobic cultures: Actinomyces odontolyticus + */ + private MedicalAction anaerobicCultures() { + return null; + } + + /** + * - Incisional biopsy culture under general anaesthetic + * - Subperiosteal dissection exposing the ascending ramus + * - No granules encountered + */ + private MedicalAction biopsy() { + return null; + } + + /** + * - clinically healthy periodontium with mild tenderness on palpation + */ + private PhenotypicFeature examination() { + return null; + } + + /** + * Contrast-enhanced MRI + * + * - hyperintense T2 signal abnormality in the left mandibular bone marrow with periosteal thickening + * - no drainable fluid collection + */ + private MedicalAction mri() { + return null; + } + + /** + * Contrast-enhanced neck CT + * - bony expansion of the left mandible + * - overlying soft tissue swelling + */ + private MedicalAction neckCT() { + return null; + } + + /** + * Last 8 months: + * + * - waxing and waning left sided mandible pain and swelling + * - denied erythema or drainage + * - no history of facial trauma + * - no history of dental procedures + * - no history of dental caries + * - intermittent fevers + * + * - Oral steroid courses - no improvement in facial swelling + */ + private List getLast8Monthsistory() { + return null; + } + + /** + * - 6-month course of oral amoxicillin 1000mg two times per day + */ + private MedicalAction treatment() { + return null; + } + + /** + * Outcome: + * + * At 1 month: + * - occasional mild pain in her mandible + * + * At 5 months: + * - maxillofacial CT: resolving/chronic osteomyelitis + * - extended antibiotic treatment to a 12-month course + */ + + /** + * - no significant medical history + */ + private List getMedicalHistory() { + return null; + } + + /** + * Diagnosis: cervicofacial actinomycosis + */ + private Interpretation interpretation() { + InterpretationBuilder ibuilder = InterpretationBuilder.solved("interpretation.id"); + DiagnosisBuilder dbuilder = DiagnosisBuilder.builder(ontologyClass("???", "Cervicofacial actinomycosis")); + ibuilder.diagnosis(dbuilder.build()); + return ibuilder.build(); + } +} diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/CushingSyndromeWithMultifocalOsteonecrosis.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/CushingSyndromeWithMultifocalOsteonecrosis.java new file mode 100644 index 00000000..f70ed7dc --- /dev/null +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/CushingSyndromeWithMultifocalOsteonecrosis.java @@ -0,0 +1,165 @@ +package org.phenopackets.phenotools.examples; + +import org.phenopackets.phenotools.builder.PhenopacketBuilder; +import org.phenopackets.phenotools.builder.builders.*; +import org.phenopackets.schema.v2.Phenopacket; +import org.phenopackets.schema.v2.core.*; + +import java.util.List; + +import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; + +public class CushingSyndromeWithMultifocalOsteonecrosis { + + + private static final String PHENOPACKET_ID = "arbitrary.id"; + private static final String INDIVIDUAL = "individual A"; + + private final Phenopacket phenopacket; + + public CushingSyndromeWithMultifocalOsteonecrosis() { + + var externalRef = ExternalReferenceBuilder.builder() + .id("DOI:10.1136/bcr-2019-233712") + .builder("PMID:32467117") + .description("Iatrogenic Cushing syndrome and multifocal osteonecrosis caused by the interaction between inhaled fluticasone and ritonavir") + .build(); + + //TODO: Fix ontology versions + var metadata = MetaDataBuilder.builder("2022-04-21T10:35:00Z", "anonymous biocurator") + .resource(Resources.ncitVersion("21.05d")) + .resource(Resources.hpoVersion("2021-08-02")) + .resource(Resources.efoVersion("3.34.0")) + .resource(Resources.uberonVersion("2021-07-27")) + .resource(Resources.ncbiTaxonVersion("2021-06-10")) + .externalReference(externalRef) + .build(); + + Individual proband = IndividualBuilder.builder(INDIVIDUAL). + ageAtLastEncounter("P40Y"). + male(). + build(); + + phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metadata) + .individual(proband) + .addAllPhenotypicFeatures(getMedicalHistory()) + .addAllPhenotypicFeatures(getMedicalBackground()) + .addMedicalAction(existingTreatment()) + .addAllPhenotypicFeatures(getSymptomsOnPresentation()) + .addAllMeasurements(getMeasurementsOnPresentation()) + .addInterpretation(interpretation()) + .addMedicalAction(treatment()) + .build(); + } + + /** + * Outcomes: + * + * 10 months after: + * + * - less ‘full moon’ facies + * - no oedema + * - less purpuric striae + * - 6kg weight loss + * - BMI of 33kg/m2 + * - improvement of erectile dysfunction + * - Serum and urinary cortisol almost normal + * - ACTH not suppressed + */ + + /** + * Treatment: + * + * First 4 months: + * - antihypertensive + * - corticosteroids at a halved dose + * - statin therapy + * + * At 7 months: + * - fluticasone ceased + * - indacaterol 150µg one time a day + */ + private MedicalAction treatment() { + return null; + } + + /** + * Labs: + * + * - Low serum and urinary cortisol + * - low serum adrenocorticotrophic hormone (ACTH) concentrations + * => Indicates: suppression of the HPA axis + */ + private List getMeasurementsOnPresentation() { + return null; + } + + /** + * Medical history: + * + * - well controlled HIV1 infection + * - CD4+ T cell count of 518 cells/mm3 + * - undetectable HIV1 RNA + * + * At 36Y old: + * - avascular necrosis of the right femoral head + * - total hip arthroplasty + */ + private List getMedicalHistory() { + return null; + } + + /** + * Medical background: + * + * - COPD + * - alcohol & tobacco abuse + * - intravenous heroin abuse + * - HIV1 infection diagnosed at 25Y old + */ + private List getMedicalBackground() { + return null; + } + + /** + * HIV Treatment background (started at 33Y old) + * + * - lopinavir/ritonavir 400mg/100mg two times per day + * - saquinavir 1000mg two times per day + * - tenofovir 300mg one time a day + * + * COPD Treatment background (started at 35Y old) + * + * - inhaled therapy with fluticasone/salmeterol 250µg/50µg two times per day + * - tiotropium bromide 18µg one time a day + */ + private MedicalAction existingTreatment() { + return null; + } + + /** + * On presentation: + * + * - gradual increase in abdominal and cervical volume + * - 15kg weight gain over the previous 6months + * - abdominal and limb striae + * - gynecomastia + * - ankle oedema + * - erectile dysfunction + * - humoral lability + */ + private List getSymptomsOnPresentation() { + return null; + } + + + /** + * Diagnosis: exogenous/iatrogenic Cushing syndrome secondary to inhaled fluticasone + */ + private Interpretation interpretation() { + InterpretationBuilder ibuilder = InterpretationBuilder.solved("interpretation.id"); + DiagnosisBuilder dbuilder = DiagnosisBuilder.builder(ontologyClass("???", "Exogenous/iatrogenic Cushing syndrome")); + ibuilder.diagnosis(dbuilder.build()); + return ibuilder.build(); + } +} diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/PneumothoraxSecondaryToCOVID.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/PneumothoraxSecondaryToCOVID.java index 3d53aa11..2dc58e14 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/PneumothoraxSecondaryToCOVID.java +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/PneumothoraxSecondaryToCOVID.java @@ -5,20 +5,25 @@ import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; -import java.util.ArrayList; import java.util.List; +import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; + public class PneumothoraxSecondaryToCOVID { private static final String PHENOPACKET_ID = "arbitrary.id"; - private static final String PROBAND_ID = "proband A"; - - // Organs + private static final String INDIVIDUAL = "individual A"; private final Phenopacket phenopacket; public PneumothoraxSecondaryToCOVID() { + var externalRef = ExternalReferenceBuilder.builder() + .id("DOI:10.1136/bcr-2020-235861") + .builder("PMID:32423911") + .description("Tension pneumothorax in a patient with COVID-19") + .build(); + //TODO: Fix ontology versions var metadata = MetaDataBuilder.builder("2022-04-21T10:35:00Z", "anonymous biocurator") .resource(Resources.ncitVersion("21.05d")) @@ -26,9 +31,10 @@ public PneumothoraxSecondaryToCOVID() { .resource(Resources.efoVersion("3.34.0")) .resource(Resources.uberonVersion("2021-07-27")) .resource(Resources.ncbiTaxonVersion("2021-06-10")) + .externalReference(externalRef) .build(); - Individual proband = IndividualBuilder.builder(PROBAND_ID). + Individual proband = IndividualBuilder.builder(INDIVIDUAL). ageAtLastEncounter("P36Y"). male(). build(); @@ -40,29 +46,62 @@ public PneumothoraxSecondaryToCOVID() { .addAllPhenotypicFeatures(getSymptomsOnPresentation()) .addAllMeasurements(getMeasurementsOnPresentation()) .addAllPhenotypicFeatures(getChestRadiograph()) + .addInterpretation(interpretation()) + .addMedicalAction(decompression()) + .addMedicalAction(chestDrain()) .build(); - } /** - * A 12-lead ECG showed a sinus tachycardia at 155 beats/min. - * - * The patient’s full blood count demonstrated a raised white cell count (13.64×109/L) with a neutrophilia (8.91×109/L), lymphocyte count (3.81×109/L), haemoglobin (146g/L), and platelets (1051×109/L); biochemical markers demonstrated a raised C-reactive protein (28.7mg/L) and alanine aminotransferase (107IU/L). - * Diagnosis: tension pneumothorax, secondary to underlying COVID-19 - * - * Treatment: - * emergency needle decompression: - * - 14-gauge cannula inserted in the second rib space and mid-clavicular line - * - 12-French Seldinger chest drain inserted into the patients left axilla + * TODO: How to represent outcomes? * * Outcome: - * repeat chest radiograph => lung re-expansion - * Within an hour the patient’s oxygen requirement reduced to 4L/min via nasal cannula - * normalisation of respiratory and heart rate. + * - Repeat chest radiograph => lung re-expansion + * - Oxygen requirement reduced to 4L/min via nasal cannula + * - normalisation of respiratory and heart rate + */ + + /** + * TODO: Anatomical site improperly represented + * TODO: Intent should be: lung decompression not 'Cure' + *

+ * Intervention: 14-gauge cannula inserted in the second rib space and mid-clavicular line */ + private MedicalAction decompression() { + ProcedureBuilder builder = ProcedureBuilder.builder("SCTID:42825003", "Cannulation (procedure)"); + builder.bodySite(ontologyClass("???", "space between second rib and mid-clavicular line")); + MedicalActionBuilder mabuilder = MedicalActionBuilder.builder(builder.build()) + .treatmentTarget(ontologyClass("SCTID:233645004", "Tension pneumothorax (disorder)")) + .treatmentIntent(ontologyClass("NCIT:C62220", "Cure")); + return mabuilder.build(); + } + /** + * Intervention: 12-French Seldinger chest drain inserted into the patients left axilla + */ + private MedicalAction chestDrain() { + ProcedureBuilder builder = ProcedureBuilder.builder("SCTID:264957007", "Insertion of pleural tube drain (procedure)"); + builder.bodySite(ontologyClass("FMA:45303", "Left axilla")); + MedicalActionBuilder mabuilder = MedicalActionBuilder.builder(builder.build()) + .treatmentTarget(ontologyClass("SCTID:233645004", "Tension pneumothorax (disorder)")) + .treatmentIntent(ontologyClass("NCIT:C62220", "Cure")); + return mabuilder.build(); + } /** + * Diagnosis: tension pneumothorax, secondary to underlying COVID-19 + */ + private Interpretation interpretation() { + InterpretationBuilder ibuilder = InterpretationBuilder.solved("interpretation.id"); + DiagnosisBuilder dbuilder = DiagnosisBuilder.builder(ontologyClass("SCTID:233645004", "Tension pneumothorax (disorder)")); + ibuilder.diagnosis(dbuilder.build()); + return ibuilder.build(); + } + + /** + * TODO: How to represent co-occurring phenotypes: pneumothorax WITH mediastinal shift? + * TODO: How to associate these phenotypes with the procedure SCTID:399208008 'Plain chest X-ray'? + *

* Emergency portable chest radiograph * - large left-sided pneumothorax with mediastinal shift * - radiological signs of tension @@ -70,14 +109,34 @@ public PneumothoraxSecondaryToCOVID() { */ private List getChestRadiograph() { - // How to associate phenotypes with procedures? + PhenotypicFeature pneumothorax = PhenotypicFeatureBuilder + .builder("HP:0002107", "Pneumothorax") + .modifier(OntologyClassBuilder.ontologyClass("PATO:0000600", "increased width")) + .modifier(Laterality.left()) + .build(); + + PhenotypicFeature rightLungNormal = PhenotypicFeatureBuilder + .builder("HP:0031983", "Abnormal pulmonary thoracic imaging finding") + .modifier(Laterality.right()) + .excluded() + .build(); + + PhenotypicFeature rightLungConsolidated = PhenotypicFeatureBuilder + .builder("SCTID:95436008", "Lung consolidation (disorder)") // Probably incorrect + .modifier(Laterality.right()) + .modifier(OntologyClassBuilder.ontologyClass("PATO:0001630", "dispersed")) + .modifier(OntologyClassBuilder.ontologyClass("PATO:0001608", "patchy")) + .build(); - return new ArrayList<>(); + return List.of(pneumothorax, rightLungNormal, rightLungConsolidated); } /** - * On presentation: << How to specify the temporal element? - * - SpO2 of 88% on 15L/min oxygen via non-rebreathe mask + * TODO: How to associate these phenotypes with the temporal aspect 'on presentation'? + * TODO: Fix measurement units + *

+ * On presentation: + * - SpO2 of 88% on 15L/min oxygen via non-rebreather mask * - respiratory rate of 50 breaths per minute * - heart rate of 150 beats/min * - blood pressure of 110/65 mm Hg @@ -113,8 +172,9 @@ private List getMeasurementsOnPresentation() { build(); - // How to define the 'intervention' component SpO2 of 88% << on 15L/min oxygen via non-rebreathe mask >> - // It's not a procedure + /** + * TODO: How to associate SpO2 of 88% on 15L/min oxygen with the 'intervention' 'non rebreather mask oxygen delivery'? + */ OntologyClass spO2 = OntologyClassBuilder.ontologyClass("LOINC:20564-1", "Oxygen saturation in Blood"); Value spO2Value = ValueBuilder.value("UCUM:%", "%", 88); @@ -131,14 +191,16 @@ private List getMeasurementsOnPresentation() { } /** - * On presentation: << How to represent this from a temporal perspective? + * TODO: How to associate these phenotypes with the temporal aspect 'on presentation'? + *

+ * On presentation: * - hypoxaemic * - tachycardic * - left-sided pleuritic chest pain * - trachea remained central *

* On ascultation: - * - no audible breath sounds of the left hemithorax + * - NO audible breath sounds of the left hemithorax << Not sure how to code this * - reduced vocal fremitus * - asymmetrical chest expansion */ @@ -161,16 +223,26 @@ private List getSymptomsOnPresentation() { excluded(). build(); - // How to combine a procedure < ascultation > with phenotypic features? - return List.of(hypoxemia, tachycardia, chestPain, trachea); + /** + * TODO: How to associate these phenotypes with the procedure SCTID:37931006 'Auscultation'? + */ + PhenotypicFeature vocalFremitus = PhenotypicFeatureBuilder. + builder("SCTID:301278006", "Vocal fremitus decreased"). + build(); + + PhenotypicFeature asymmetricalChestExpansion = PhenotypicFeatureBuilder. + builder("SCTID:271623001", "Chest movement unequal"). + build(); + + return List.of(hypoxemia, tachycardia, chestPain, trachea, vocalFremitus, asymmetricalChestExpansion); } /** * medical history: * - Childhood asthma * - 10 pack-year history of smoking << How to represent this !? - * - NO history of trauma << Did I represent correct the absence of the phenotype? + * - NO history of trauma * - NO history of pneumothoraces */ private List getMedicalHistory() { @@ -178,6 +250,10 @@ private List getMedicalHistory() { builder("HP:0002099", "Asthma"). childhoodOnset(). build(); + + /** + * TODO: How to represent the difference between no HISTORY vs no PRESENT observation for a phenotype? + */ PhenotypicFeature trauma = PhenotypicFeatureBuilder. builder("SCTID:417746004", "Trauma"). excluded(). @@ -191,7 +267,9 @@ private List getMedicalHistory() { } /** - * 3-week history: << How to represent relative time periods? + * TODO: How to represent relative time periods? (e.g., 3 weeks prior to diagnosis) + *

+ * 3-week history: * - cough * - fevers * - shortness of breath diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/SevereStatinInducedAutoimmuneMyopathy.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/SevereStatinInducedAutoimmuneMyopathy.java new file mode 100644 index 00000000..1d7ddb39 --- /dev/null +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/SevereStatinInducedAutoimmuneMyopathy.java @@ -0,0 +1,162 @@ +package org.phenopackets.phenotools.examples; + +import org.phenopackets.phenotools.builder.PhenopacketBuilder; +import org.phenopackets.phenotools.builder.builders.*; +import org.phenopackets.schema.v2.Phenopacket; +import org.phenopackets.schema.v2.core.*; + +import java.util.List; + +import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; + +public class SevereStatinInducedAutoimmuneMyopathy { + + + private static final String PHENOPACKET_ID = "arbitrary.id"; + private static final String INDIVIDUAL = "individual A"; + + private final Phenopacket phenopacket; + + public SevereStatinInducedAutoimmuneMyopathy() { + + var externalRef = ExternalReferenceBuilder.builder() + .id("DOI:10.1136/bcr-2020-234805") + .builder("PMID:32444443") + .description("Severe statin-induced autoimmune myopathy successfully treated with intravenous immunoglobulin") + .build(); + + //TODO: Fix ontology versions + var metadata = MetaDataBuilder.builder("2022-04-21T10:35:00Z", "anonymous biocurator") + .resource(Resources.ncitVersion("21.05d")) + .resource(Resources.hpoVersion("2021-08-02")) + .resource(Resources.efoVersion("3.34.0")) + .resource(Resources.uberonVersion("2021-07-27")) + .resource(Resources.ncbiTaxonVersion("2021-06-10")) + .externalReference(externalRef) + .build(); + + Individual proband = IndividualBuilder.builder(INDIVIDUAL). + ageAtLastEncounter("P65Y"). + male(). + build(); + + phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metadata) + .individual(proband) + .addAllPhenotypicFeatures(getMedicalHistory()) + .addMedicalAction(existingTreatment()) + .addAllPhenotypicFeatures(getLastMonthHistory()) + .addAllPhenotypicFeatures(getSymptomsOnPresentation()) + .addAllMeasurements(getLabsOnPresentation()) + .addAllPhenotypicFeatures(getEMG()) + .addInterpretation(interpretation()) + .addMedicalAction(treatment()) + .build(); + } + + /** + * Outcome: + * + * 7weeks after the fourth round of IVIg, the patient nearly regained full strength in his legs and CK did not show any further increase. + */ + + /** + * Atorvastatin was stopped + * muscle weakness deteriorated in his legs + * spread to his arms making immune-modulating treatment necessary + * 155 g IVIg, equivalent to 1.6 g/kg of body weight, was administered over 3 days + * 55 g on the first day and 50 g on the second and third day + * developed a headache after first dose + * lack of significant improvement of the CK + * treatment was continued every 6 weeks slightly reducing the dose to 150 g + * After the third course of treatment, the CK in serum drastically fell to a mildly elevated level + * Following the fourth administration, CK was stable around 500 U/L and weakness in his limbs had been greatly improved. + */ + private MedicalAction treatment() { + return null; + } + + /** + * active denervation + * and fasciculation potentials along with chronic denervation/re-innervation motor unit patterns + * from the craniobulbar, thoracic, paraspinal as well as upper and lower limb muscles. + * @return + */ + private List getEMG() { + return null; + } + + /** + * creatine kinase (CK) level was raised up to 4292 U/L + * alanine transaminase (ALT) was raised to 234 U/L + * Alkaline phosphatase and bilirubin were normal + * Autoantibodies against HMG-CoA reductase were positive. + * Haemoglobin A1C was 51 mmol/mol. + * Full blood count, thyroid function tests, renal profile, vitamin D and B12 were all normal. + */ + private List getLabsOnPresentation() { + return null; + } + + /** + * On examination: + * + * fasciculations and wasting were noticed in both quadriceps muscles + * muscular tone was normal + * proximal weakness in both legs + * Trendelenburg's and Gower's signs were positive + * knee jerks were brisk + * Sensation was intact + * loss of vibration sense up to the tibial plateau bilaterally + * Examination of the cranial nerves and the upper limbs was unremarkable. + */ + private List getSymptomsOnPresentation() { + return null; + } + + /** + * Last month history: + * + * - weakness started about 2 months ago; got progressively worse + * difficulties climbing stairs + * getting up from the squatting position + * walking or even putting on his trousers + * started using a wheelchair + * denied having any associated pain, and upper limbs as well as speech and swallowing were uninvolved. + * + * longstanding mild sensory symptoms in both feet + * lost around 6 lb (about 2.72 kg) in weight in the previous month + */ + private List getLastMonthHistory() { + return null; + } + + /** + * Medical history: + * + * - hypertension diagnosed 10 years back + * - type 2 diabetes mellitus diagnosed 10 years back + */ + private List getMedicalHistory() { + return null; + } + + /** + * HIV Treatment background (started at 33Y old) + * + * - atorvastatin 10 mg and aspirin 75 mg alongside antihypertensive (ramipril and amlodipine) and anti-diabetic (metformin, dapagliflozin, sitagliptin and gliclazide) medication + */ + private MedicalAction existingTreatment() { + return null; + } + + + /** + * Diagnosis: statin-associated autoimmune myopathy + */ + private Interpretation interpretation() { + InterpretationBuilder ibuilder = InterpretationBuilder.solved("interpretation.id"); + DiagnosisBuilder dbuilder = DiagnosisBuilder.builder(ontologyClass("????", "Statin-associated autoimmune myopathy")); + ibuilder.diagnosis(dbuilder.build()); + return ibuilder.build(); + } +} From d5bf3f5f99078a53427e8aaa5efe3674f01ab3fb Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Tue, 26 Apr 2022 07:43:42 -0400 Subject: [PATCH 019/155] fixing position --- .../phenopackettools/examples/Retinoblastoma.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java index c8eae4fb..b7dd471d 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java @@ -72,8 +72,8 @@ Interpretation interpretation() { */ GenomicInterpretation somaticRb1Missense() { AlleleBuilder abuilder = AlleleBuilder.builder(); - abuilder.sequenceId("refseq:NC_000013.14"); - abuilder.startEnd( 48941647, 48941648); + abuilder.sequenceId("refseq:NC_000013.11"); + abuilder.startEnd( 48367511, 48367512); abuilder.altAllele("T"); VariationDescriptorBuilder vbuilder = VariationDescriptorBuilder.builder("rs121913300") .variation(abuilder.buildVariation()) From e0cbb4d4f6dfbccf9def1a66056c86fdf268a336 Mon Sep 17 00:00:00 2001 From: pnrobinson Date: Sun, 1 May 2022 12:43:47 -0400 Subject: [PATCH 020/155] glaucoma example framework --- .../command/ExamplesCommand.java | 1 + .../examples/GlaucomaSurgery.java | 31 +++++++++++++++++++ .../examples/PhenopacketExamples.java | 2 ++ 3 files changed, 34 insertions(+) create mode 100644 phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/GlaucomaSurgery.java diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java index 08f039ae..423534be 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java @@ -120,6 +120,7 @@ private int outputAllPhenopackets() { output(PhenopacketExamples.thrombocytopenia2(), outDirectory, "thrombocytopenia2"); output(PhenopacketExamples.marfanSyndrome(), outDirectory, "marfan"); output(PhenopacketExamples.acuteMyeloidLeukemia(), outDirectory, "nemalineMyopathy"); + output(PhenopacketExamples.GLAUCOMA, outDirectory, "glaucoma"); output(PhenopacketExamples.squamousCellEsophagealCarcinoma(), outDirectory, "squamous-cell-esophageal-carcinoma"); output(PhenopacketExamples.urothelialCarcinoma(), outDirectory, "urothelial-cancer"); output(PhenopacketExamples.covid19(), outDirectory, "covid"); diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/GlaucomaSurgery.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/GlaucomaSurgery.java new file mode 100644 index 00000000..a6dc97cc --- /dev/null +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/GlaucomaSurgery.java @@ -0,0 +1,31 @@ +package org.phenopackets.phenopackettools.examples; + +import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; +import org.phenopackets.phenopackettools.builder.builders.MetaDataBuilder; +import org.phenopackets.phenopackettools.builder.builders.Resources; +import org.phenopackets.schema.v2.Phenopacket; + +public class GlaucomaSurgery implements PhenopacketExample { + private static final String PHENOPACKET_ID = "arbitrary.id"; + + private final Phenopacket phenopacket; + + + public GlaucomaSurgery() { + var metadata = MetaDataBuilder.builder("2021-05-14T10:35:00Z", "anonymous biocurator") + .addResource(Resources.ncitVersion("21.05d")) + .addResource(Resources.efoVersion("3.34.0")) + .addResource(Resources.uberonVersion("2021-07-27")) + .addResource(Resources.ncbiTaxonVersion("2021-06-10")) + .build(); + + PhenopacketBuilder builder = PhenopacketBuilder.create(PHENOPACKET_ID, metadata); + + phenopacket = builder.build(); + } + + @Override + public Phenopacket getPhenopacket() { + return phenopacket; + } +} diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/PhenopacketExamples.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/PhenopacketExamples.java index 8ef52ddf..9b17a3d8 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/PhenopacketExamples.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/PhenopacketExamples.java @@ -13,6 +13,8 @@ public class PhenopacketExamples { public static final Phenopacket COVID_19 = new Covid().getPhenopacket(); public static final Phenopacket RETINOBLASTOMA = new Retinoblastoma().getPhenopacket(); public static final Phenopacket NEMALINE_MYOPATHY = new NemalineMyopathyPrenatal().getPhenopacket(); + public static final Phenopacket GLAUCOMA = new GlaucomaSurgery().getPhenopacket(); + private PhenopacketExamples() { } From 9909faf64a498db917d3c0f2ad580f635abce288 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Mon, 9 May 2022 11:48:43 -0400 Subject: [PATCH 021/155] new example started --- .../examples/SleKidneyTransplantation.java | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SleKidneyTransplantation.java diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SleKidneyTransplantation.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SleKidneyTransplantation.java new file mode 100644 index 00000000..2fbd60ae --- /dev/null +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SleKidneyTransplantation.java @@ -0,0 +1,54 @@ +package org.phenopackets.phenopackettools.examples; + +import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; +import org.phenopackets.phenopackettools.builder.builders.IndividualBuilder; +import org.phenopackets.phenopackettools.builder.builders.MetaDataBuilder; +import org.phenopackets.phenopackettools.builder.builders.Resources; +import org.phenopackets.schema.v2.Phenopacket; +import org.phenopackets.schema.v2.core.Individual; +import org.phenopackets.schema.v2.core.OntologyClass; + +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; + +/** + * Pavlakou P, et al. Case Report: Kidney Transplantation in a Patient With Acquired Agammaglobulinemia and SLE. + * Issues and Challenges. Front Med (Lausanne). 2021 Mar 12;8:665475. + * PMID: 33777986. + */ +public class SleKidneyTransplantation implements PhenopacketExample { + private static final String PHENOPACKET_ID = "arbitrary.id"; + private static final String PROBAND_ID = "proband A"; + private static final String BIOSAMPLE_ID = "biosample.1"; + private static final OntologyClass BIOPSY = ontologyClass("NCIT:C15189", "Biopsy"); + private static final OntologyClass SYSTEMIC_LUPUS = ontologyClass("MONDO:0007915", "systemic lupus erythematosus"); + private static final OntologyClass PRIMARY_NEOPLASM = ontologyClass("NCIT:C8509", "Primary Neoplasm"); + + // Organs + private static final OntologyClass EYE = ontologyClass("UBERON:0000970", "eye"); + private static final OntologyClass CURE = ontologyClass("NCIT:C62220", "Cure"); + private static final OntologyClass LEFT_EYE = ontologyClass("UBERON:0004548", "left eye"); + + private final Phenopacket phenopacket; + + public SleKidneyTransplantation() { + var metadata = MetaDataBuilder.builder("2021-05-14T10:35:00Z", "anonymous biocurator") + .addResource(Resources.ncitVersion("21.05d")) + .addResource(Resources.efoVersion("3.34.0")) + .addResource(Resources.uberonVersion("2021-07-27")) + .addResource(Resources.ncbiTaxonVersion("2021-06-10")) + .build(); + Individual proband = IndividualBuilder.builder(PROBAND_ID). + ageAtLastEncounter("P39Y"). + female(). + build(); + phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metadata) + .individual(proband) + .build(); + } + + + @Override + public Phenopacket getPhenopacket() { + return phenopacket; + } +} From a77e6039a66297c8147b1e3ab713f66e58a2cddd Mon Sep 17 00:00:00 2001 From: Jules Jacobsen Date: Wed, 26 Jan 2022 16:27:20 +0000 Subject: [PATCH 022/155] Move package phenotools-validator to phenotools-validator-core. Update version to 1.0.0-RC1 --- phenotools-builder/pom.xml | 5 +++-- phenotools-cli/pom.xml | 6 +++--- phenotools-converter/pom.xml | 5 +++-- .../.mvn/wrapper/maven-wrapper.properties | 0 .../mvnw | 0 .../mvnw.cmd | 0 .../pom.xml | 6 +++--- .../validator/core/DefaultValidationInfo.java | 0 .../phenotools/validator/core/ErrorType.java | 0 .../validator/core/PhenopacketValidator.java | 0 .../core/PhenopacketValidatorFactory.java | 0 .../validator/core/ValidationAspect.java | 0 .../validator/core/ValidationItem.java | 0 .../validator/core/ValidatorInfo.java | 0 .../validator/core/ValidatorRunner.java | 0 .../PhenopacketValidatorRuntimeException.java | 0 phenotools-validator-jsonschema/pom.xml | 9 ++++++--- .../.mvn/wrapper/maven-wrapper.jar | Bin 47610 -> 0 bytes pom.xml | 4 ++-- 19 files changed, 20 insertions(+), 15 deletions(-) rename {phenotools-validator => phenotools-validator-core}/.mvn/wrapper/maven-wrapper.properties (100%) rename {phenotools-validator => phenotools-validator-core}/mvnw (100%) rename {phenotools-validator => phenotools-validator-core}/mvnw.cmd (100%) rename {phenotools-validator => phenotools-validator-core}/pom.xml (79%) rename {phenotools-validator => phenotools-validator-core}/src/main/java/org/phenopackets/phenotools/validator/core/DefaultValidationInfo.java (100%) rename {phenotools-validator => phenotools-validator-core}/src/main/java/org/phenopackets/phenotools/validator/core/ErrorType.java (100%) rename {phenotools-validator => phenotools-validator-core}/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidator.java (100%) rename {phenotools-validator => phenotools-validator-core}/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidatorFactory.java (100%) rename {phenotools-validator => phenotools-validator-core}/src/main/java/org/phenopackets/phenotools/validator/core/ValidationAspect.java (100%) rename {phenotools-validator => phenotools-validator-core}/src/main/java/org/phenopackets/phenotools/validator/core/ValidationItem.java (100%) rename {phenotools-validator => phenotools-validator-core}/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorInfo.java (100%) rename {phenotools-validator => phenotools-validator-core}/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorRunner.java (100%) rename {phenotools-validator => phenotools-validator-core}/src/main/java/org/phenopackets/phenotools/validator/core/except/PhenopacketValidatorRuntimeException.java (100%) delete mode 100644 phenotools-validator/.mvn/wrapper/maven-wrapper.jar diff --git a/phenotools-builder/pom.xml b/phenotools-builder/pom.xml index 7f6d8fa1..9e59f84c 100644 --- a/phenotools-builder/pom.xml +++ b/phenotools-builder/pom.xml @@ -2,12 +2,13 @@ + 4.0.0 + org.phenopackets.phenotools phenotools - 0.0.2-SNAPSHOT + 1.0.0-RC1 - 4.0.0 phenotools-builder diff --git a/phenotools-cli/pom.xml b/phenotools-cli/pom.xml index b32c5b7a..d0b6dd6c 100644 --- a/phenotools-cli/pom.xml +++ b/phenotools-cli/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenotools phenotools - 0.0.2-SNAPSHOT + 1.0.0-RC1 phenotools-cli @@ -33,13 +33,13 @@ org.phenopackets.phenotools - validator-core + phenotools-validator-core ${project.parent.version} compile org.phenopackets.phenotools - validator-jsonschema + phenotools-validator-jsonschema ${project.parent.version} compile diff --git a/phenotools-converter/pom.xml b/phenotools-converter/pom.xml index ad5a7e3e..02ec7269 100644 --- a/phenotools-converter/pom.xml +++ b/phenotools-converter/pom.xml @@ -2,12 +2,13 @@ + 4.0.0 + org.phenopackets.phenotools phenotools - 0.0.2-SNAPSHOT + 1.0.0-RC1 - 4.0.0 phenotools-converter diff --git a/phenotools-validator/.mvn/wrapper/maven-wrapper.properties b/phenotools-validator-core/.mvn/wrapper/maven-wrapper.properties similarity index 100% rename from phenotools-validator/.mvn/wrapper/maven-wrapper.properties rename to phenotools-validator-core/.mvn/wrapper/maven-wrapper.properties diff --git a/phenotools-validator/mvnw b/phenotools-validator-core/mvnw similarity index 100% rename from phenotools-validator/mvnw rename to phenotools-validator-core/mvnw diff --git a/phenotools-validator/mvnw.cmd b/phenotools-validator-core/mvnw.cmd similarity index 100% rename from phenotools-validator/mvnw.cmd rename to phenotools-validator-core/mvnw.cmd diff --git a/phenotools-validator/pom.xml b/phenotools-validator-core/pom.xml similarity index 79% rename from phenotools-validator/pom.xml rename to phenotools-validator-core/pom.xml index 41cf9259..6642f862 100644 --- a/phenotools-validator/pom.xml +++ b/phenotools-validator-core/pom.xml @@ -7,12 +7,12 @@ org.phenopackets.phenotools phenotools - 0.0.2-SNAPSHOT + 1.0.0-RC1 - validator-core + phenotools-validator-core - validator-core + phenotools-validator-core Validator utilities for phenopackets \ No newline at end of file diff --git a/phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/DefaultValidationInfo.java b/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/DefaultValidationInfo.java similarity index 100% rename from phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/DefaultValidationInfo.java rename to phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/DefaultValidationInfo.java diff --git a/phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/ErrorType.java b/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ErrorType.java similarity index 100% rename from phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/ErrorType.java rename to phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ErrorType.java diff --git a/phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidator.java b/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidator.java similarity index 100% rename from phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidator.java rename to phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidator.java diff --git a/phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidatorFactory.java b/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidatorFactory.java similarity index 100% rename from phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidatorFactory.java rename to phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidatorFactory.java diff --git a/phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/ValidationAspect.java b/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidationAspect.java similarity index 100% rename from phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/ValidationAspect.java rename to phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidationAspect.java diff --git a/phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/ValidationItem.java b/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidationItem.java similarity index 100% rename from phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/ValidationItem.java rename to phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidationItem.java diff --git a/phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorInfo.java b/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorInfo.java similarity index 100% rename from phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorInfo.java rename to phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorInfo.java diff --git a/phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorRunner.java b/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorRunner.java similarity index 100% rename from phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorRunner.java rename to phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorRunner.java diff --git a/phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/except/PhenopacketValidatorRuntimeException.java b/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/except/PhenopacketValidatorRuntimeException.java similarity index 100% rename from phenotools-validator/src/main/java/org/phenopackets/phenotools/validator/core/except/PhenopacketValidatorRuntimeException.java rename to phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/except/PhenopacketValidatorRuntimeException.java diff --git a/phenotools-validator-jsonschema/pom.xml b/phenotools-validator-jsonschema/pom.xml index 1b828c66..b37ddc47 100644 --- a/phenotools-validator-jsonschema/pom.xml +++ b/phenotools-validator-jsonschema/pom.xml @@ -7,15 +7,18 @@ org.phenopackets.phenotools phenotools - 0.0.2-SNAPSHOT + 1.0.0-RC1 - validator-jsonschema + phenotools-validator-jsonschema + + phenotools-validator-jsonschema + JSON schema validator utilities for phenopackets org.phenopackets.phenotools - validator-core + phenotools-validator-core ${project.parent.version} diff --git a/phenotools-validator/.mvn/wrapper/maven-wrapper.jar b/phenotools-validator/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index 9cc84ea9b4d95453115d0c26488d6a78694e0bc6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47610 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 diff --git a/pom.xml b/pom.xml index f03dc5a5..cf5d7b15 100644 --- a/pom.xml +++ b/pom.xml @@ -6,13 +6,13 @@ org.phenopackets.phenotools phenotools - 0.0.2-SNAPSHOT + 1.0.0-RC1 pom phenotools-builder - phenotools-validator + phenotools-validator-core phenotools-validator-jsonschema phenotools-converter phenotools-cli From 3d1f3ea809b2855806223406cf422e196937be45 Mon Sep 17 00:00:00 2001 From: Jules Jacobsen Date: Mon, 7 Feb 2022 15:36:36 +0000 Subject: [PATCH 023/155] Update version to 1.0.0 --- phenotools-builder/pom.xml | 2 +- phenotools-cli/pom.xml | 2 +- phenotools-converter/pom.xml | 2 +- phenotools-validator-core/pom.xml | 2 +- phenotools-validator-jsonschema/pom.xml | 2 +- pom.xml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/phenotools-builder/pom.xml b/phenotools-builder/pom.xml index 9e59f84c..14cde2e6 100644 --- a/phenotools-builder/pom.xml +++ b/phenotools-builder/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenotools phenotools - 1.0.0-RC1 + 1.0.0 phenotools-builder diff --git a/phenotools-cli/pom.xml b/phenotools-cli/pom.xml index d0b6dd6c..0d9887e4 100644 --- a/phenotools-cli/pom.xml +++ b/phenotools-cli/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenotools phenotools - 1.0.0-RC1 + 1.0.0 phenotools-cli diff --git a/phenotools-converter/pom.xml b/phenotools-converter/pom.xml index 02ec7269..760cfb89 100644 --- a/phenotools-converter/pom.xml +++ b/phenotools-converter/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenotools phenotools - 1.0.0-RC1 + 1.0.0 phenotools-converter diff --git a/phenotools-validator-core/pom.xml b/phenotools-validator-core/pom.xml index 6642f862..d524474c 100644 --- a/phenotools-validator-core/pom.xml +++ b/phenotools-validator-core/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenotools phenotools - 1.0.0-RC1 + 1.0.0 phenotools-validator-core diff --git a/phenotools-validator-jsonschema/pom.xml b/phenotools-validator-jsonschema/pom.xml index b37ddc47..6d2ffe4a 100644 --- a/phenotools-validator-jsonschema/pom.xml +++ b/phenotools-validator-jsonschema/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenotools phenotools - 1.0.0-RC1 + 1.0.0 phenotools-validator-jsonschema diff --git a/pom.xml b/pom.xml index cf5d7b15..ce14ddc2 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.phenopackets.phenotools phenotools - 1.0.0-RC1 + 1.0.0 pom From 5fab8a488731faf6d5c9d360c1ddafb49036c674 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Wed, 13 Apr 2022 13:20:05 -0400 Subject: [PATCH 024/155] moving classes to new constants package --- .../builder/builders/PhenotypicFeatureBuilder.java | 1 + .../phenotools/builder/builders/TimeElements.java | 5 +++-- .../builder/builders/{ => constants}/Laterality.java | 3 ++- .../phenotools/builder/builders/{ => constants}/Onset.java | 2 +- .../builder/builders/{ => constants}/Severity.java | 2 +- .../phenotools/builder/builders/{ => constants}/Status.java | 2 +- .../phenotools/builder/builders/{ => constants}/Unit.java | 2 +- .../phenotools/builder/builders/DiagnosisBuilderTest.java | 1 + .../phenopackets/phenotools/examples/BethlehamMyopathy.java | 1 + .../org/phenopackets/phenotools/examples/Retinoblastoma.java | 2 ++ .../phenopackets/phenotools/examples/Thrombocytopenia2.java | 1 + 11 files changed, 15 insertions(+), 7 deletions(-) rename phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/{ => constants}/Laterality.java (86%) rename phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/{ => constants}/Onset.java (97%) rename phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/{ => constants}/Severity.java (96%) rename phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/{ => constants}/Status.java (97%) rename phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/{ => constants}/Unit.java (93%) diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PhenotypicFeatureBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PhenotypicFeatureBuilder.java index 842ad813..fb4abc4c 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PhenotypicFeatureBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PhenotypicFeatureBuilder.java @@ -1,5 +1,6 @@ package org.phenopackets.phenotools.builder.builders; +import org.phenopackets.phenotools.builder.builders.constants.Severity; import org.phenopackets.schema.v2.core.Evidence; import org.phenopackets.schema.v2.core.OntologyClass; import org.phenopackets.schema.v2.core.PhenotypicFeature; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimeElements.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimeElements.java index 3b88ca2e..f688a037 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimeElements.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimeElements.java @@ -1,12 +1,13 @@ package org.phenopackets.phenotools.builder.builders; import com.google.protobuf.Timestamp; +import org.phenopackets.phenotools.builder.builders.constants.Onset; import org.phenopackets.schema.v2.core.*; import java.time.Instant; -import static org.phenopackets.phenotools.builder.builders.Onset.late; -import static org.phenopackets.phenotools.builder.builders.Onset.middleAge; +import static org.phenopackets.phenotools.builder.builders.constants.Onset.late; +import static org.phenopackets.phenotools.builder.builders.constants.Onset.middleAge; /** * The TimeElement is used in many places in the Phenopacket. It is defined as being one of the diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Laterality.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Laterality.java similarity index 86% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Laterality.java rename to phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Laterality.java index 3c12cf4b..def91ce2 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Laterality.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Laterality.java @@ -1,5 +1,6 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenotools.builder.builders.constants; +import org.phenopackets.phenotools.builder.builders.OntologyClassBuilder; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Onset.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Onset.java similarity index 97% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Onset.java rename to phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Onset.java index 6de53cb7..a4008c99 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Onset.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Onset.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenotools.builder.builders.constants; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Severity.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Severity.java similarity index 96% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Severity.java rename to phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Severity.java index 5c0fd5f2..d7d93954 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Severity.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Severity.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenotools.builder.builders.constants; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Status.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Status.java similarity index 97% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Status.java rename to phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Status.java index b8fc6b97..0b52ed85 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Status.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Status.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenotools.builder.builders.constants; import org.phenopackets.schema.v2.core.AcmgPathogenicityClassification; import org.phenopackets.schema.v2.core.GenomicInterpretation.InterpretationStatus; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Unit.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Unit.java similarity index 93% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Unit.java rename to phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Unit.java index ee97647f..86330e9b 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Unit.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Unit.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenotools.builder.builders.constants; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilderTest.java b/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilderTest.java index 83db8c1b..09cb6391 100644 --- a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilderTest.java +++ b/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilderTest.java @@ -1,6 +1,7 @@ package org.phenopackets.phenotools.builder.builders; import org.junit.jupiter.api.Test; +import org.phenopackets.phenotools.builder.builders.constants.Status; import org.phenopackets.schema.v2.core.Diagnosis; import org.phenopackets.schema.v2.core.GenomicInterpretation; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/BethlehamMyopathy.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/BethlehamMyopathy.java index adbebcaa..4e73d232 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/BethlehamMyopathy.java +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/BethlehamMyopathy.java @@ -3,6 +3,7 @@ import org.phenopackets.phenotools.builder.PhenopacketBuilder; import org.phenopackets.phenotools.builder.builders.*; +import org.phenopackets.phenotools.builder.builders.constants.Status; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Retinoblastoma.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Retinoblastoma.java index 9d9e98ee..ab2f36d0 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Retinoblastoma.java +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Retinoblastoma.java @@ -4,6 +4,8 @@ import org.ga4gh.vrsatile.v1.GeneDescriptor; import org.phenopackets.phenotools.builder.PhenopacketBuilder; import org.phenopackets.phenotools.builder.builders.*; +import org.phenopackets.phenotools.builder.builders.constants.Laterality; +import org.phenopackets.phenotools.builder.builders.constants.Unit; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Thrombocytopenia2.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Thrombocytopenia2.java index 6f213ecd..931d66ba 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Thrombocytopenia2.java +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Thrombocytopenia2.java @@ -2,6 +2,7 @@ import org.phenopackets.phenotools.builder.PhenopacketBuilder; import org.phenopackets.phenotools.builder.builders.*; +import org.phenopackets.phenotools.builder.builders.constants.Status; import org.phenopackets.schema.v2.Phenopacket; import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; From bd724397d5f7d13a843bfb1154a576a2dd6a5b05 Mon Sep 17 00:00:00 2001 From: Jules Jacobsen Date: Thu, 14 Apr 2022 11:53:47 +0100 Subject: [PATCH 025/155] Update builder methods which add to a list with 'add' prefix. Move constants package up a level Update InterpretationBuilder API to become a state machine. Add back lost VRS sequenceId in NemalineMyopathyPrenatal example. --- .../builder/PhenopacketBuilder.java | 6 + .../builder/builders/BiosampleBuilder.java | 5 + .../builder/builders/DiagnosisBuilder.java | 2 +- .../builder/builders/DiseaseBuilder.java | 4 +- .../builder/builders/FileBuilder.java | 7 + .../builders/GeneDescriptorBuilder.java | 6 +- .../GenomicInterpretationBuilder.java | 2 +- .../builder/builders/IndividualBuilder.java | 4 +- .../builders/InterpretationBuilder.java | 47 ++++--- .../builders/MedicalActionBuilder.java | 2 +- .../builder/builders/MetaDataBuilder.java | 11 +- .../builder/builders/PedigreeBuilder.java | 2 +- .../builder/builders/PersonBuilder.java | 32 ++--- .../builders/PhenotypicFeatureBuilder.java | 19 ++- .../builder/builders/TimeElements.java | 8 +- .../builder/builders/TreatmentBuilder.java | 4 +- .../builders/VariationDescriptorBuilder.java | 31 ++--- .../{builders => }/constants/Laterality.java | 2 +- .../{builders => }/constants/Onset.java | 2 +- .../{builders => }/constants/Severity.java | 2 +- .../{builders => }/constants/Status.java | 2 +- .../{builders => }/constants/Unit.java | 2 +- .../builders/DiagnosisBuilderTest.java | 4 +- .../examples/BethlehamMyopathy.java | 35 +++-- .../phenotools/examples/Covid.java | 16 +-- .../examples/FamilyWithPedigree.java | 4 +- .../phenotools/examples/Marfan.java | 4 +- .../examples/NemalineMyopathyPrenatal.java | 129 ++++++++---------- .../phenotools/examples/Retinoblastoma.java | 99 ++++++-------- .../examples/SquamousCellCancer.java | 14 +- .../examples/Thrombocytopenia2.java | 17 ++- .../phenotools/examples/UrothelialCancer.java | 23 ++-- .../examples/WarburgMicroSyndrome.java | 4 +- 33 files changed, 270 insertions(+), 281 deletions(-) rename phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/{builders => }/constants/Laterality.java (93%) rename phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/{builders => }/constants/Onset.java (97%) rename phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/{builders => }/constants/Severity.java (96%) rename phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/{builders => }/constants/Status.java (97%) rename phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/{builders => }/constants/Unit.java (93%) diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/PhenopacketBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/PhenopacketBuilder.java index c9aac5ee..f5ef9c57 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/PhenopacketBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/PhenopacketBuilder.java @@ -1,5 +1,6 @@ package org.phenopackets.phenotools.builder; +import org.phenopackets.phenotools.builder.builders.PhenotypicFeatureBuilder; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; @@ -22,6 +23,11 @@ public PhenopacketBuilder individual(Individual subject) { return this; } + public PhenopacketBuilder addPhenotypicFeature(String id, String label) { + PhenotypicFeature phenotypicFeature = PhenotypicFeatureBuilder.phenotypicFeature(id, label); + return addPhenotypicFeature(phenotypicFeature); + } + public PhenopacketBuilder addPhenotypicFeature(PhenotypicFeature feature) { builder.addPhenotypicFeatures(feature); return this; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/BiosampleBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/BiosampleBuilder.java index 6373769f..37fa70cb 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/BiosampleBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/BiosampleBuilder.java @@ -41,6 +41,11 @@ public BiosampleBuilder sampledType(OntologyClass tissue) { return this; } + public BiosampleBuilder addPhenotypicFeature(String id, String label) { + PhenotypicFeature phenotypicFeature = PhenotypicFeatureBuilder.phenotypicFeature(id, label); + return addPhenotypicFeature(phenotypicFeature); + } + public BiosampleBuilder addPhenotypicFeature(PhenotypicFeature feature) { builder.addPhenotypicFeatures(feature); return this; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilder.java index fd4cecac..7a799b40 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilder.java @@ -12,7 +12,7 @@ private DiagnosisBuilder(OntologyClass disease) { builder = Diagnosis.newBuilder().setDisease(disease); } - public DiagnosisBuilder genomicInterpretation(GenomicInterpretation interpretation) { + public DiagnosisBuilder addGenomicInterpretation(GenomicInterpretation interpretation) { builder.addGenomicInterpretations(interpretation); return this; } diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DiseaseBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DiseaseBuilder.java index 579ee6b2..c28e5fa7 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DiseaseBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DiseaseBuilder.java @@ -45,12 +45,12 @@ public DiseaseBuilder resolution(TimeElement timeElement) { return this; } - public DiseaseBuilder diseaseStage(OntologyClass stage) { + public DiseaseBuilder addDiseaseStage(OntologyClass stage) { builder.addDiseaseStage(stage); return this; } - public DiseaseBuilder clinicalTnmFinding(OntologyClass tnmFinding) { + public DiseaseBuilder addClinicalTnmFinding(OntologyClass tnmFinding) { builder.addClinicalTnmFinding(tnmFinding); return this; } diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/FileBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/FileBuilder.java index 99aaa511..d6fe7c03 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/FileBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/FileBuilder.java @@ -2,6 +2,8 @@ import org.phenopackets.schema.v2.core.File; +import java.util.Map; + public class FileBuilder { private final File.Builder builder; @@ -23,6 +25,11 @@ public FileBuilder addFileAttribute(String k, String v) { return this; } + public FileBuilder addAllFileAttributes(Map values) { + builder.putAllFileAttributes(values); + return this; + } + public FileBuilder individualToFileIdentifier(String individual, String fileIdentifier) { builder.putIndividualToFileIdentifiers(individual, fileIdentifier); return this; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/GeneDescriptorBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/GeneDescriptorBuilder.java index 5d46840d..98576fb1 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/GeneDescriptorBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/GeneDescriptorBuilder.java @@ -25,7 +25,7 @@ public GeneDescriptorBuilder description(String desc) { return this; } - public GeneDescriptorBuilder alternateId(String altId) { + public GeneDescriptorBuilder addAlternateId(String altId) { builder.addAlternateIds(altId); return this; } @@ -35,7 +35,7 @@ public GeneDescriptorBuilder addAllAlternateIds(List altIds) { return this; } - public GeneDescriptorBuilder xref(String xref) { + public GeneDescriptorBuilder addXref(String xref) { builder.addXrefs(xref); return this; } @@ -45,7 +45,7 @@ public GeneDescriptorBuilder addAllXrefs(List xrefs) { return this; } - public GeneDescriptorBuilder alternateSymbol(String altSymbol) { + public GeneDescriptorBuilder addAlternateSymbol(String altSymbol) { builder.addAlternateSymbols(altSymbol); return this; } diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/GenomicInterpretationBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/GenomicInterpretationBuilder.java index 2d299480..ca224fd2 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/GenomicInterpretationBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/GenomicInterpretationBuilder.java @@ -44,7 +44,7 @@ public GenomicInterpretationBuilder unknown() { return this; } - public GenomicInterpretationBuilder geneDescriptor( GeneDescriptor geneDescriptor) { + public GenomicInterpretationBuilder geneDescriptor(GeneDescriptor geneDescriptor) { builder.setGene(geneDescriptor); return this; } diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/IndividualBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/IndividualBuilder.java index 21db04a8..25593a87 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/IndividualBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/IndividualBuilder.java @@ -37,12 +37,12 @@ public static IndividualBuilder builder(String id) { return new IndividualBuilder(id); } - public IndividualBuilder alternateId(String altId) { + public IndividualBuilder addAlternateId(String altId) { builder.addAlternateIds(altId); return this; } - public IndividualBuilder alternateId(List altIdList) { + public IndividualBuilder addAllAlternateIds(List altIdList) { builder.addAllAlternateIds(altIdList); return this; } diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/InterpretationBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/InterpretationBuilder.java index 834ea004..c32dea86 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/InterpretationBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/InterpretationBuilder.java @@ -11,44 +11,49 @@ private InterpretationBuilder(String interpretationId, Interpretation.ProgressSt builder = Interpretation.newBuilder().setId(interpretationId).setProgressStatus(status); } - public static Interpretation interpretation(String interpretationId, Interpretation.ProgressStatus status, Diagnosis dx, String summary) { - return Interpretation.newBuilder().setId(interpretationId).setProgressStatus(status).setDiagnosis(dx).setSummary(summary).build(); + public static Interpretation interpretation(String interpretationId, Interpretation.ProgressStatus status, Diagnosis diagnosis, String summary) { + return Interpretation.newBuilder().setId(interpretationId).setProgressStatus(status).setDiagnosis(diagnosis).setSummary(summary).build(); } - public static InterpretationBuilder builder(String interpretationId, Interpretation.ProgressStatus status) { - return new InterpretationBuilder(interpretationId, status); + public static InterpretationBuilder builder(String interpretationId) { + return new InterpretationBuilder(interpretationId, Interpretation.ProgressStatus.UNKNOWN_PROGRESS); } +// public static InterpretationBuilder builder(String interpretationId, Interpretation.ProgressStatus status) { +// return new InterpretationBuilder(interpretationId, status); +// } public InterpretationBuilder summary(String summary) { builder.setSummary(summary); return this; } +// +// public InterpretationBuilder diagnosis(Diagnosis diagnosis) { +// builder.setDiagnosis(diagnosis); +// return this; +// } - public InterpretationBuilder diagnosis(Diagnosis diagnosis) { - builder.setDiagnosis(diagnosis); - return this; - } - - public static InterpretationBuilder inProgress(String interpretationId) { - return builder(interpretationId, Interpretation.ProgressStatus.IN_PROGRESS); - } - - public static InterpretationBuilder completed(String interpretationId) { - return builder(interpretationId, Interpretation.ProgressStatus.COMPLETED); + public Interpretation inProgress() { + builder.setProgressStatus(Interpretation.ProgressStatus.IN_PROGRESS); + return builder.build(); } - public static InterpretationBuilder solved(String interpretationId) { - return builder(interpretationId, Interpretation.ProgressStatus.SOLVED); + public Interpretation completed(Diagnosis diagnosis) { + builder.setProgressStatus(Interpretation.ProgressStatus.COMPLETED); + builder.setDiagnosis(diagnosis); + return builder.build(); } - public static InterpretationBuilder unsolved(String interpretationId) { - return builder(interpretationId, Interpretation.ProgressStatus.UNSOLVED); + public Interpretation solved(Diagnosis diagnosis) { + builder.setProgressStatus(Interpretation.ProgressStatus.SOLVED); + builder.setDiagnosis(diagnosis); + return builder.build(); } - public Interpretation build() { + public Interpretation unsolved() { + builder.setProgressStatus(Interpretation.ProgressStatus.UNSOLVED); + builder.clearDiagnosis(); return builder.build(); } - } diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MedicalActionBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MedicalActionBuilder.java index e256f9c4..cf95add2 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MedicalActionBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MedicalActionBuilder.java @@ -71,7 +71,7 @@ public MedicalActionBuilder responseToTreatment(OntologyClass response) { return this; } - public MedicalActionBuilder adverseEvent(OntologyClass event) { + public MedicalActionBuilder addAdverseEvent(OntologyClass event) { builder.addAdverseEvents(event); return this; } diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MetaDataBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MetaDataBuilder.java index 28979fee..73632fbf 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MetaDataBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MetaDataBuilder.java @@ -29,25 +29,24 @@ public MetaDataBuilder submittedBy(String submitter) { return this; } - public MetaDataBuilder resource(Resource r) { + public MetaDataBuilder addResource(Resource r) { builder.addResources(r); return this; } - public MetaDataBuilder update(Update u) { + public MetaDataBuilder addUpdate(Update u) { builder.addUpdates(u); return this; } - public MetaDataBuilder externalReference(ExternalReference er) { + public MetaDataBuilder addExternalReference(ExternalReference er) { builder.addExternalReferences(er); return this; } - public MetaDataBuilder externalReference(String id, String description) { + public MetaDataBuilder addExternalReference(String id, String description) { ExternalReference er = ExternalReference.newBuilder().setId(id).setDescription(description).build(); - builder.addExternalReferences(er); - return this; + return addExternalReference(er); } public MetaData build() { diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PedigreeBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PedigreeBuilder.java index 36b06d4a..c708ced3 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PedigreeBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PedigreeBuilder.java @@ -13,7 +13,7 @@ public PedigreeBuilder() { builder = Pedigree.newBuilder(); } - public PedigreeBuilder person(Pedigree.Person person) { + public PedigreeBuilder addPerson(Pedigree.Person person) { builder.addPersons(person); return this; } diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PersonBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PersonBuilder.java index d083d86b..317862c7 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PersonBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PersonBuilder.java @@ -9,15 +9,15 @@ public class PersonBuilder { private final org.phenopackets.schema.v2.core.Pedigree.Person.Builder builder; - private PersonBuilder(String family_id, - String individual_id, - String paternal_id, - String maternal_id) { + private PersonBuilder(String familyId, + String individualId, + String paternalId, + String maternalId) { builder = Pedigree.Person.newBuilder(); - builder.setFamilyId(family_id); - builder.setIndividualId(individual_id); - builder.setPaternalId(paternal_id); - builder.setMaternalId(maternal_id); + builder.setFamilyId(familyId); + builder.setIndividualId(individualId); + builder.setPaternalId(paternalId); + builder.setMaternalId(maternalId); } public PersonBuilder male() { @@ -50,21 +50,19 @@ public PersonBuilder missing() { return this; } - - public static PersonBuilder builder(String family_id, - String individual_id, - String paternal_id, - String maternal_id) { - return new PersonBuilder(family_id, individual_id, paternal_id, maternal_id); + public static PersonBuilder builder(String familyId, + String individualId, + String paternalId, + String maternalId) { + return new PersonBuilder(familyId, individualId, paternalId, maternalId); } /** * Founders are persons in a PED file whose parents are not included. These parents are * indicated by "0". This function creates a personBuilder with prepopulated father/mother ids of "0" */ - public static PersonBuilder builderWithParentsAsFounders(String family_id, - String individual_id) { - return new PersonBuilder(family_id, individual_id, + public static PersonBuilder builderWithParentsAsFounders(String familyId, String individualId) { + return new PersonBuilder(familyId, individualId, parental_id_not_available, parental_id_not_available); } diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PhenotypicFeatureBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PhenotypicFeatureBuilder.java index fb4abc4c..2ffe1ddf 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PhenotypicFeatureBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PhenotypicFeatureBuilder.java @@ -1,6 +1,5 @@ package org.phenopackets.phenotools.builder.builders; -import org.phenopackets.phenotools.builder.builders.constants.Severity; import org.phenopackets.schema.v2.core.Evidence; import org.phenopackets.schema.v2.core.OntologyClass; import org.phenopackets.schema.v2.core.PhenotypicFeature; @@ -83,12 +82,12 @@ public PhenotypicFeatureBuilder adultOnset() { public PhenotypicFeatureBuilder severity(String id, String label) { OntologyClass severity = OntologyClassBuilder.ontologyClass(id, label); - builder.setSeverity(severity); - return this; + return severity(severity); + } - public PhenotypicFeatureBuilder severe() { - builder.setSeverity(Severity.severe()); + public PhenotypicFeatureBuilder severity(OntologyClass severity) { + builder.setSeverity(severity); return this; } @@ -97,22 +96,22 @@ public PhenotypicFeatureBuilder excluded() { return this; } - public PhenotypicFeatureBuilder evidence(Evidence evidence) { + public PhenotypicFeatureBuilder addEvidence(Evidence evidence) { builder.addEvidence(evidence); return this; } - public PhenotypicFeatureBuilder allEvidence(List evidenceList) { + public PhenotypicFeatureBuilder addAllEvidence(List evidenceList) { builder.addAllEvidence(evidenceList); return this; } - public PhenotypicFeatureBuilder modifier(OntologyClass clz) { - builder.addModifiers(clz); + public PhenotypicFeatureBuilder addModifier(OntologyClass modifier) { + builder.addModifiers(modifier); return this; } - public PhenotypicFeatureBuilder allModifiers(List modifiers) { + public PhenotypicFeatureBuilder addAllModifiers(List modifiers) { builder.addAllModifiers(modifiers); return this; } diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimeElements.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimeElements.java index f688a037..7d58d55f 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimeElements.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimeElements.java @@ -1,13 +1,11 @@ package org.phenopackets.phenotools.builder.builders; import com.google.protobuf.Timestamp; -import org.phenopackets.phenotools.builder.builders.constants.Onset; +import org.phenopackets.phenotools.builder.constants.Onset; import org.phenopackets.schema.v2.core.*; import java.time.Instant; -import static org.phenopackets.phenotools.builder.builders.constants.Onset.late; -import static org.phenopackets.phenotools.builder.builders.constants.Onset.middleAge; /** * The TimeElement is used in many places in the Phenopacket. It is defined as being one of the @@ -34,8 +32,8 @@ public class TimeElements { private static final TimeElement JUVENILE_ONSET = TimeElement.newBuilder().setOntologyClass(Onset.juvenile()).build(); private static final TimeElement INFANTILE_ONSET = TimeElement.newBuilder().setOntologyClass(Onset.infantile()).build(); private static final TimeElement ADULT_ONSET = TimeElement.newBuilder().setOntologyClass(Onset.adult()).build(); - private static final TimeElement LATE_ONSET = TimeElement.newBuilder().setOntologyClass(late()).build(); - private static final TimeElement MIDDLE_AGE_ONSET = TimeElement.newBuilder().setOntologyClass(middleAge()).build(); + private static final TimeElement LATE_ONSET = TimeElement.newBuilder().setOntologyClass(Onset.late()).build(); + private static final TimeElement MIDDLE_AGE_ONSET = TimeElement.newBuilder().setOntologyClass(Onset.middleAge()).build(); private static final TimeElement YOUNG_ADULT_ONSET = TimeElement.newBuilder().setOntologyClass(Onset.youngAdult()).build(); private TimeElements() { diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TreatmentBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TreatmentBuilder.java index 28a0ba64..744b9b66 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TreatmentBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TreatmentBuilder.java @@ -33,12 +33,12 @@ public TreatmentBuilder routeOfAdministration(OntologyClass route) { return this; } - public TreatmentBuilder doseInterval(DoseInterval interval) { + public TreatmentBuilder addDoseInterval(DoseInterval interval) { builder.addDoseIntervals(interval); return this; } - public TreatmentBuilder allDoseIntervals(List intervals) { + public TreatmentBuilder addAllDoseIntervals(List intervals) { builder.addAllDoseIntervals(intervals); return this; } diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VariationDescriptorBuilder.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VariationDescriptorBuilder.java index 60fd9c9a..f38ace0a 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VariationDescriptorBuilder.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VariationDescriptorBuilder.java @@ -24,6 +24,14 @@ private VariationDescriptorBuilder(String id) { builder = VariationDescriptor.newBuilder().setId(id); } + public static VariationDescriptorBuilder builder() { + return new VariationDescriptorBuilder(); + } + + public static VariationDescriptorBuilder builder(String variantId) { + return new VariationDescriptorBuilder(variantId); + } + public VariationDescriptorBuilder label(String lbl) { builder.setLabel(lbl); return this; @@ -44,12 +52,12 @@ public VariationDescriptorBuilder geneContext(GeneDescriptor gene) { return this; } - public VariationDescriptorBuilder vcfVecord(VcfRecord vcf) { + public VariationDescriptorBuilder vcfRecord(VcfRecord vcf) { builder.setVcfRecord(vcf); return this; } - public VariationDescriptorBuilder xref(String xref) { + public VariationDescriptorBuilder addXref(String xref) { builder.addXrefs(xref); return this; } @@ -59,7 +67,7 @@ public VariationDescriptorBuilder addAllXrefs(List xrefs) { return this; } - public VariationDescriptorBuilder alternateLabels(String altLabel) { + public VariationDescriptorBuilder addAlternateLabel(String altLabel) { builder.addAlternateLabels(altLabel); return this; } @@ -85,8 +93,8 @@ public VariationDescriptorBuilder transcript() { } - public VariationDescriptorBuilder structuralType(OntologyClass clz) { - builder.setStructuralType(clz); + public VariationDescriptorBuilder structuralType(OntologyClass structuralType) { + builder.setStructuralType(structuralType); return this; } @@ -135,7 +143,7 @@ public VariationDescriptorBuilder iscn(String value) { return this; } - public VariationDescriptorBuilder expression(Expression expression) { + public VariationDescriptorBuilder addExpression(Expression expression) { builder.addExpressions(expression); return this; } @@ -158,8 +166,7 @@ public VariationDescriptorBuilder vcfHg37(String chromosome, int position, Strin * @param percentage estimated percentage of cells affected by mosaic variant, e.g., 40% */ public VariationDescriptorBuilder mosaicism(double percentage) { - Extension expression = - Extensions.mosaicism(percentage); + Extension expression = Extensions.mosaicism(percentage); builder.addExtensions(expression); return this; } @@ -178,12 +185,4 @@ public VariationDescriptorBuilder alleleFrequency(double percentage) { public VariationDescriptor build() { return builder.build(); } - - public static VariationDescriptorBuilder builder(String variantId) { - return new VariationDescriptorBuilder(variantId); - } - - public static VariationDescriptorBuilder builder() { - return new VariationDescriptorBuilder(); - } } diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Laterality.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Laterality.java similarity index 93% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Laterality.java rename to phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Laterality.java index def91ce2..02413281 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Laterality.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Laterality.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders.constants; +package org.phenopackets.phenotools.builder.constants; import org.phenopackets.phenotools.builder.builders.OntologyClassBuilder; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Onset.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Onset.java similarity index 97% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Onset.java rename to phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Onset.java index a4008c99..e9ffc9fe 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Onset.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Onset.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders.constants; +package org.phenopackets.phenotools.builder.constants; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Severity.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Severity.java similarity index 96% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Severity.java rename to phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Severity.java index d7d93954..35594d5e 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Severity.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Severity.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders.constants; +package org.phenopackets.phenotools.builder.constants; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Status.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Status.java similarity index 97% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Status.java rename to phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Status.java index 0b52ed85..fec4d29b 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Status.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Status.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders.constants; +package org.phenopackets.phenotools.builder.constants; import org.phenopackets.schema.v2.core.AcmgPathogenicityClassification; import org.phenopackets.schema.v2.core.GenomicInterpretation.InterpretationStatus; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Unit.java b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Unit.java similarity index 93% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Unit.java rename to phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Unit.java index 86330e9b..e0cbeedb 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/constants/Unit.java +++ b/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Unit.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders.constants; +package org.phenopackets.phenotools.builder.constants; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilderTest.java b/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilderTest.java index 09cb6391..196a55be 100644 --- a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilderTest.java +++ b/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilderTest.java @@ -1,7 +1,7 @@ package org.phenopackets.phenotools.builder.builders; import org.junit.jupiter.api.Test; -import org.phenopackets.phenotools.builder.builders.constants.Status; +import org.phenopackets.phenotools.builder.constants.Status; import org.phenopackets.schema.v2.core.Diagnosis; import org.phenopackets.schema.v2.core.GenomicInterpretation; @@ -27,7 +27,7 @@ void testDiagnosisBuilder() { var expectedGenomicInterpretation = genomicInterpretationBuilder.build(); var thrombocytopenia2 = ontologyClass("OMIM:188000", "Thrombocytopenia 2"); Diagnosis diagnosis = DiagnosisBuilder.builder(thrombocytopenia2). - genomicInterpretation(expectedGenomicInterpretation) + addGenomicInterpretation(expectedGenomicInterpretation) .build(); assertThat(diagnosis.getDisease(), equalTo(thrombocytopenia2)); assertEquals(1, diagnosis.getGenomicInterpretationsCount()); diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/BethlehamMyopathy.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/BethlehamMyopathy.java index 4e73d232..c66ee81a 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/BethlehamMyopathy.java +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/BethlehamMyopathy.java @@ -3,9 +3,8 @@ import org.phenopackets.phenotools.builder.PhenopacketBuilder; import org.phenopackets.phenotools.builder.builders.*; -import org.phenopackets.phenotools.builder.builders.constants.Status; +import org.phenopackets.phenotools.builder.constants.Status; import org.phenopackets.schema.v2.Phenopacket; -import org.phenopackets.schema.v2.core.*; import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; @@ -21,9 +20,9 @@ class BethlehamMyopathy implements PhenopacketExample { var bethlehamMyopathy = ontologyClass("OMIM:158810", "Bethlem myopathy 1"); var individual = IndividualBuilder.builder(PROBAND_ID).male().ageAtLastEncounter("P6Y3M").build(); var metaData = MetaDataBuilder.builder("2021-05-14T10:35:00Z", "anonymous biocurator") - .resource(Resources.hpoVersion("2021-08-02")) - .resource(Resources.genoVersion("2020-03-08")) - .externalReference(authorAssertion.getReference()) + .addResource(Resources.hpoVersion("2021-08-02")) + .addResource(Resources.genoVersion("2020-03-08")) + .addExternalReference(authorAssertion.getReference()) .build(); var variationDescriptor = VariationDescriptorBuilder.builder("variant id") @@ -36,56 +35,54 @@ class BethlehamMyopathy implements PhenopacketExample { GenomicInterpretationBuilder.builder(INTERPRETATION_ID) .causative() .variantInterpretation(col6a1VariantInterpretation).build(); - var diagnosis = Diagnosis.newBuilder() - .setDisease(bethlehamMyopathy).addGenomicInterpretations(genomicInterpretation).build(); - var interpretation = InterpretationBuilder.builder(INTERPRETATION_ID, Status.completed()) - .diagnosis(diagnosis).build(); + var diagnosis = DiagnosisBuilder.builder(bethlehamMyopathy).addGenomicInterpretation(genomicInterpretation).build(); + var interpretation = InterpretationBuilder.builder(INTERPRETATION_ID).completed(diagnosis); var ventricularSeptalDefect = PhenotypicFeatureBuilder.builder("HP:0001629", "Ventricular septal defect") .congenitalOnset() - .evidence(authorAssertion) + .addEvidence(authorAssertion) .build(); var coarseFacial = PhenotypicFeatureBuilder.builder("HP:0000280", "Coarse facial features") - .evidence(authorAssertion) + .addEvidence(authorAssertion) .build(); var cryptorchidism = PhenotypicFeatureBuilder.builder("HP:0008689", "Bilateral cryptorchidism") .congenitalOnset() - .evidence(authorAssertion) + .addEvidence(authorAssertion) .build(); var polyhydramnios = PhenotypicFeatureBuilder.builder("HP:0001561", "Polyhydramnios") .fetalOnset() - .evidence(authorAssertion) + .addEvidence(authorAssertion) .build(); var micropenis = PhenotypicFeatureBuilder.builder("HP:0000054", "Micropenis") .congenitalOnset() - .evidence(authorAssertion) + .addEvidence(authorAssertion) .build(); var anonychia = PhenotypicFeatureBuilder.builder("HP:0001798", "Anonychia") .congenitalOnset() - .evidence(authorAssertion) + .addEvidence(authorAssertion) .build(); var vermisHypoplasia = PhenotypicFeatureBuilder.builder("HP:0001320", "Cerebellar vermis hypoplasia") - .evidence(authorAssertion) + .addEvidence(authorAssertion) .build(); var cataract = PhenotypicFeatureBuilder.builder("HP:0000518", "Cataract") .infantileOnset() - .evidence(authorAssertion) + .addEvidence(authorAssertion) .build(); var dilatedFourthVentricle = PhenotypicFeatureBuilder.builder("HP:0002198", "Dilated fourth ventricle") - .evidence(authorAssertion) + .addEvidence(authorAssertion) .build(); var unilateralCleftLip = PhenotypicFeatureBuilder.builder("HP:0100333", "Unilateral cleft lip") .congenitalOnset() - .evidence(authorAssertion) + .addEvidence(authorAssertion) .build(); phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metaData) .individual(individual) diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Covid.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Covid.java index 9cc3ca41..65bee335 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Covid.java +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Covid.java @@ -52,9 +52,9 @@ class Covid implements PhenopacketExample { .description("The Imperfect Cytokine Storm: Severe COVID-19 With ARDS in a Patient on Durable LVAD Support") .build(); var metaData = MetaDataBuilder.builder("2021-08-17T00:00:00Z", "anonymous biocurator") - .resource(Resources.ncitVersion("2019-11-26")) - .resource(Resources.mondoVersion("2021-11-26")) - .externalReference(externalRef) + .addResource(Resources.ncitVersion("2019-11-26")) + .addResource(Resources.mondoVersion("2021-11-26")) + .addExternalReference(externalRef) .build(); @@ -155,8 +155,8 @@ private MedicalAction nasalOxygenAdministered() { TimeIntervalBuilder.timeInterval("2021-02-02T08:22:42Z", "2021-02-02T12:22:42Z")); Treatment nasalOxygen = TreatmentBuilder.builder("NCIT:C722", "Oxygen") .routeOfAdministration(ontologyClass("NCIT:C38284", "Nasal Route of Administration")) - .doseInterval(interval1) - .doseInterval(interval2) + .addDoseInterval(interval1) + .addDoseInterval(interval2) .build(); return MedicalActionBuilder.treatment(nasalOxygen); } @@ -178,7 +178,7 @@ private MedicalAction peepOxygenAdministered() { var doseInterval = DoseIntervalBuilder.doseInterval(quantity, CONTINUOUS, "2020-03-22", "2020-03-28"); Treatment oxygen = TreatmentBuilder.builder(ontologyClass("NCIT:C722", "Oxygen")) .routeOfAdministration(ontologyClass("NCIT:C50254", "Positive end Expiratory Pressure Valve Device")) - .doseInterval(doseInterval) + .addDoseInterval(doseInterval) .build(); return MedicalActionBuilder.treatment(oxygen); } @@ -188,7 +188,7 @@ private MedicalAction tocilizumabAdministered() { OntologyClass q4weeks = ontologyClass("NCIT:C64529", "Every Four Weeks"); var doseInterval = DoseIntervalBuilder.doseInterval(quantity, q4weeks, "2020-03-24", "2020-03-28"); var treatment = TreatmentBuilder.builder("NCIT:C84217", "Tocilizumab") - .doseInterval(doseInterval) + .addDoseInterval(doseInterval) .build(); return MedicalActionBuilder.treatment(treatment); } @@ -200,7 +200,7 @@ private MedicalAction dexamethasone() { var doseInterval = DoseIntervalBuilder.doseInterval(quantity, onceDaily, "2020-03-20", "2020-03-30"); Treatment dexa = TreatmentBuilder.builder("CHEBI:41879", "dexamethasone") - .doseInterval(doseInterval) + .addDoseInterval(doseInterval) .build(); return MedicalActionBuilder.treatment(dexa); } diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/FamilyWithPedigree.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/FamilyWithPedigree.java index a2e43a2e..e5e250f6 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/FamilyWithPedigree.java +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/FamilyWithPedigree.java @@ -45,7 +45,7 @@ public Family getFamily() { public Phenopacket proband() { String phenopacketId = "phenopacket.id.1"; var metadata = MetaDataBuilder.builder("2022-04-17T10:35:00Z", "biocurator") - .resource(Resources.hpoVersion("2022-04-15")) + .addResource(Resources.hpoVersion("2022-04-15")) .build(); Individual proband = IndividualBuilder.builder(SON_ID). ageAtLastEncounter("P10Y2M4D"). @@ -82,7 +82,7 @@ public Pedigree pedigree() { Pedigree.Person daughter1 = PersonBuilder.builder(FAMILY_ID, DAUGHTER1_ID, PATERNAL_ID, MATERNAL_ID).female().unaffected().build(); Pedigree.Person son = PersonBuilder.builder(FAMILY_ID, SON_ID, PATERNAL_ID, MATERNAL_ID).male().affected().build(); Pedigree.Person daughter2 = PersonBuilder.builder(FAMILY_ID, DAUGHTER2_ID, PATERNAL_ID, MATERNAL_ID).female().unaffected().build(); - return pbuilder.person(father).person(mother).person(daughter1).person(son).person(daughter2).build(); + return pbuilder.addPerson(father).addPerson(mother).addPerson(daughter1).addPerson(son).addPerson(daughter2).build(); } diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Marfan.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Marfan.java index 4400e699..aa419890 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Marfan.java +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Marfan.java @@ -27,12 +27,12 @@ class Marfan implements PhenopacketExample { var dosage = DoseIntervalBuilder.doseInterval(quantity, bid, interval); var losartanTreatment = TreatmentBuilder .builder(losartan) - .doseInterval(dosage) + .addDoseInterval(dosage) .routeOfAdministration(administration) .build(); var medicalAction = MedicalActionBuilder.treatment(losartanTreatment); var metaData = MetaDataBuilder.builder("2021-05-14T10:35:00Z", "anonymous biocurator") - .resource(Resources.hpoVersion("2021-08-02")) + .addResource(Resources.hpoVersion("2021-08-02")) .build(); phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metaData) .individual(individual) diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/NemalineMyopathyPrenatal.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/NemalineMyopathyPrenatal.java index 7e5cd342..126ba77d 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/NemalineMyopathyPrenatal.java +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/NemalineMyopathyPrenatal.java @@ -1,5 +1,6 @@ package org.phenopackets.phenotools.examples; +import org.ga4gh.vrs.v1.Variation; import org.ga4gh.vrsatile.v1.Expression; import org.ga4gh.vrsatile.v1.GeneDescriptor; import org.phenopackets.phenotools.builder.PhenopacketBuilder; @@ -7,10 +8,10 @@ import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; -import java.util.ArrayList; import java.util.List; import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenotools.builder.builders.PhenotypicFeatureBuilder.phenotypicFeature; import static org.phenopackets.phenotools.builder.builders.TimeElements.gestationalAge; /** @@ -22,19 +23,19 @@ class NemalineMyopathyPrenatal implements PhenopacketExample { private static final String PHENOPACKET_ID = "arbitrary.id"; private static final String PROBAND_ID = "proband A"; - private final OntologyClass nemalineMyopathy8 = ontologyClass("MONDO:0014138", "nemaline myopathy 8"); + private static final OntologyClass NEMALINE_MYOPATHY_8 = ontologyClass("MONDO:0014138", "nemaline myopathy 8"); private final Phenopacket phenopacket; NemalineMyopathyPrenatal() { var metadata = MetaDataBuilder.builder("2021-05-14T10:35:00Z", "anonymous biocurator") - .resource(Resources.ncitVersion("21.05d")) - .resource(Resources.hpoVersion("2022-02")) - .resource(Resources.mondoVersion("v2022-04-04")) - .resource(Resources.uberonVersion("2021-07-27")) + .addResource(Resources.ncitVersion("21.05d")) + .addResource(Resources.hpoVersion("2022-02")) + .addResource(Resources.mondoVersion("v2022-04-04")) + .addResource(Resources.uberonVersion("2021-07-27")) .build(); - var vitalStatus = VitalStatusBuilder.deceased().causeOfDeath(nemalineMyopathy8).build(); + var vitalStatus = VitalStatusBuilder.deceased().causeOfDeath(NEMALINE_MYOPATHY_8).build(); var individual = IndividualBuilder.builder(PROBAND_ID) .male() .ageAtLastEncounter("P1D") @@ -42,16 +43,14 @@ class NemalineMyopathyPrenatal implements PhenopacketExample { PhenopacketBuilder builder = PhenopacketBuilder.create(PHENOPACKET_ID, metadata) .individual(individual) .addPhenotypicFeature(decreasedFetalMovement()) - .addBiosample(muscleBiopsy()) - .addInterpretation(interpretation()); - - builder.addAllPhenotypicFeatures(sonography33weeks()); - builder.addAllPhenotypicFeatures(apgar()); + .addBiosample(muscleBiopsy()) + .addInterpretation(interpretation()) + .addAllPhenotypicFeatures(sonography33weeks()) + .addAllPhenotypicFeatures(apgar()); phenopacket = builder.build(); } List apgar() { - List phenotypicFeatureList = new ArrayList<>(); TimeElement newbornTime = TimeElements.congenitalOnset(); PhenotypicFeature apgar1 = PhenotypicFeatureBuilder.builder("HP:0030931", "1-minute APGAR score of 4") .onset(newbornTime).build(); @@ -63,17 +62,10 @@ List apgar() { .onset(newbornTime).build(); PhenotypicFeature generalizedHypotonia = PhenotypicFeatureBuilder.builder("HP:0001290", "Generalized hypotonia") .onset(newbornTime).build(); - - phenotypicFeatureList.add(apgar1); - phenotypicFeatureList.add(apgar5); - phenotypicFeatureList.add(apgar10); - phenotypicFeatureList.add(laryngealEdema); - phenotypicFeatureList.add(generalizedHypotonia); - return phenotypicFeatureList; + return List.of(apgar1, apgar5, apgar10, laryngealEdema, generalizedHypotonia); } List sonography33weeks() { - List phenotypicFeatureList = new ArrayList<>(); TimeElement onset = gestationalAge(32,4); OntologyClass borderline = ontologyClass("HP:0012827", "Borderline"); PhenotypicFeature edema = PhenotypicFeatureBuilder.builder("HP:0025672", "Fetal skin edema") @@ -81,43 +73,36 @@ List sonography33weeks() { PhenotypicFeature overlapping = PhenotypicFeatureBuilder.builder("HP:0010557", "Overlapping fingers") .onset(onset).build(); PhenotypicFeature polyhydram = PhenotypicFeatureBuilder.builder("HP:0001561", "Polyhydramnios") - .onset(onset).modifier(borderline).build(); - phenotypicFeatureList.add(edema); - phenotypicFeatureList.add(overlapping); - phenotypicFeatureList.add(polyhydram); - return phenotypicFeatureList; + .onset(onset).addModifier(borderline).build(); + return List.of(edema, overlapping, polyhydram); } PhenotypicFeature decreasedFetalMovement() { - PhenotypicFeatureBuilder builder = PhenotypicFeatureBuilder.builder("HP:0001558", "Decreased fetal movement"); - TimeElement onset = gestationalAge(23); - builder.onset(onset); - return builder.build(); + return PhenotypicFeatureBuilder.builder("HP:0001558", "Decreased fetal movement") + .onset(gestationalAge(23)) + .build(); } Biosample muscleBiopsy() { - String biosampleId = "biosample.1"; - BiosampleBuilder builder = BiosampleBuilder.builder(biosampleId); OntologyClass abdominalMuscle = ontologyClass("UBERON:0002378", "muscle of abdomen"); - builder.sampledTissue(abdominalMuscle); - PhenotypicFeature nemalineRods = PhenotypicFeatureBuilder.builder("HP:0003798","Nemaline bodies").build(); - builder.addPhenotypicFeature(nemalineRods); - ProcedureBuilder pbuilder = ProcedureBuilder.builder("NCIT:C51895", "Muscle Biopsy"); - TimeElement age = TimeElements.age("P1D"); - pbuilder.bodySite(abdominalMuscle).performed(age); - builder.procedure(pbuilder.build()); - return builder.build(); + Procedure muscleBiopsy = ProcedureBuilder.builder("NCIT:C51895", "Muscle Biopsy") + .bodySite(abdominalMuscle) + .performed(TimeElements.age("P1D")) + .build(); + return BiosampleBuilder.builder("biosample.1") + .sampledTissue(abdominalMuscle) + .addPhenotypicFeature("HP:0003798","Nemaline bodies") + .procedure(muscleBiopsy) + .build(); } Interpretation interpretation() { - InterpretationBuilder ibuilder = InterpretationBuilder.solved("interpretation.id"); - OntologyClass nm8 = ontologyClass("MONDO:0014138", "nemaline myopathy 8"); - DiagnosisBuilder dbuilder = DiagnosisBuilder.builder(nm8); - dbuilder.genomicInterpretation(klhl40InterpretationV1()); - dbuilder.genomicInterpretation(klhl40InterpretationV2()); - ibuilder.diagnosis(dbuilder.build()); - return ibuilder.build(); + Diagnosis diagnosis = DiagnosisBuilder.builder(NEMALINE_MYOPATHY_8) + .addGenomicInterpretation(klhl40InterpretationV1()) + .addGenomicInterpretation(klhl40InterpretationV2()) + .build(); + return InterpretationBuilder.builder("interpretation.id").solved(diagnosis); } @@ -136,23 +121,24 @@ GenomicInterpretation klhl40InterpretationV1() { // NC_000003.12:42686219:G:A // rs397509420 //HGNC:30372 - AlleleBuilder abuilder = AlleleBuilder.builder(); //abuilder.setSequenceId("ga4gh:VA.GuPzvZoansqNHPoXkQLXKo31VkTpDKsM"); - abuilder.startEnd( 42686219, 42686220); - abuilder.chromosomeLocation("chr3"); - abuilder.setAltAllele("A"); - VariationDescriptorBuilder vbuilder = VariationDescriptorBuilder.builder("rs397509420"); - vbuilder.variation(abuilder.buildVariation()); - vbuilder.genomic(); - vbuilder.heterozygous(); - vbuilder.label("NM_152393.4(KLHL40):c.602G>A (p.Trp201Ter)"); - vbuilder.transcript(); + Variation variation = AlleleBuilder.builder() + .setSequenceId("NC_000003.12") + .startEnd(42686219, 42686220) + .setAltAllele("A") + .buildVariation(); + VariationDescriptorBuilder vbuilder = VariationDescriptorBuilder.builder("rs397509420") + .variation(variation) + .genomic() + .heterozygous() + .label("NM_152393.4(KLHL40):c.602G>A (p.Trp201Ter)") + .transcript(); GeneDescriptor geneDescriptor = GeneDescriptorBuilder.builder("HGNC:30372", "KLHL40").build(); vbuilder.geneContext(geneDescriptor); Expression hgvs = Expressions.hgvsCdna("NM_152393.4(KLHL40):c.602G>A"); Expression transcriptReference = Expressions.transcriptReference("NM_152393.4"); - vbuilder.expression(hgvs); - vbuilder.expression(transcriptReference); + vbuilder.addExpression(hgvs); + vbuilder.addExpression(transcriptReference); // wrap in VariantInterpretation VariantInterpretationBuilder vibuilder = VariantInterpretationBuilder.builder(vbuilder); vibuilder.pathogenic(); @@ -174,23 +160,22 @@ GenomicInterpretation klhl40InterpretationV2() { // NC_000003.12:42688962:A:C // dbSNP: rs778022582 //HGNC:30372 - AlleleBuilder abuilder = AlleleBuilder.builder(); - //abuilder.setSequenceId("ga4gh:VA.GuPzvZoansqNHPoXkQLXKo31VkTpDKsM"); - abuilder.startEnd( 42688962, 42688963); - abuilder.chromosomeLocation("chr3"); - abuilder.setAltAllele("C"); - VariationDescriptorBuilder vbuilder = VariationDescriptorBuilder.builder("rs778022582"); - vbuilder.variation(abuilder.buildVariation()); - vbuilder.genomic(); - vbuilder.heterozygous(); - vbuilder.label("NM_152393.4(KLHL40):c.1516A>C (p.Thr506Pro)"); - vbuilder.transcript(); + AlleleBuilder abuilder = AlleleBuilder.builder() + .setSequenceId("NC_000003.12") + .startEnd( 42688962, 42688963) + .setAltAllele("C"); + VariationDescriptorBuilder vbuilder = VariationDescriptorBuilder.builder("rs778022582") + .variation(abuilder.buildVariation()) + .genomic() + .heterozygous() + .label("NM_152393.4(KLHL40):c.1516A>C (p.Thr506Pro)") + .transcript(); GeneDescriptor geneDescriptor = GeneDescriptorBuilder.builder("HGNC:30372", "KLHL40").build(); vbuilder.geneContext(geneDescriptor); Expression hgvs = Expressions.hgvsCdna("NM_152393.4(KLHL40):c.1516A>C"); Expression transcriptReference = Expressions.transcriptReference("NM_152393.4"); - vbuilder.expression(hgvs); - vbuilder.expression(transcriptReference); + vbuilder.addExpression(hgvs); + vbuilder.addExpression(transcriptReference); // wrap in VariantInterpretation VariantInterpretationBuilder vibuilder = VariantInterpretationBuilder.builder(vbuilder); vibuilder.pathogenic(); diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Retinoblastoma.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Retinoblastoma.java index ab2f36d0..9b6b0d48 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Retinoblastoma.java +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Retinoblastoma.java @@ -1,11 +1,9 @@ package org.phenopackets.phenotools.examples; -import org.ga4gh.vrsatile.v1.Expression; -import org.ga4gh.vrsatile.v1.GeneDescriptor; import org.phenopackets.phenotools.builder.PhenopacketBuilder; import org.phenopackets.phenotools.builder.builders.*; -import org.phenopackets.phenotools.builder.builders.constants.Laterality; -import org.phenopackets.phenotools.builder.builders.constants.Unit; +import org.phenopackets.phenotools.builder.constants.Laterality; +import org.phenopackets.phenotools.builder.constants.Unit; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; @@ -29,10 +27,10 @@ public class Retinoblastoma implements PhenopacketExample { private final Phenopacket phenopacket; public Retinoblastoma() { var metadata = MetaDataBuilder.builder("2021-05-14T10:35:00Z", "anonymous biocurator") - .resource(Resources.ncitVersion("21.05d")) - .resource(Resources.efoVersion("3.34.0")) - .resource(Resources.uberonVersion("2021-07-27")) - .resource(Resources.ncbiTaxonVersion("2021-06-10")) + .addResource(Resources.ncitVersion("21.05d")) + .addResource(Resources.efoVersion("3.34.0")) + .addResource(Resources.uberonVersion("2021-07-27")) + .addResource(Resources.ncbiTaxonVersion("2021-06-10")) .build(); Individual proband = IndividualBuilder.builder(PROBAND_ID). ageAtLastEncounter("P6M"). @@ -58,13 +56,11 @@ public Retinoblastoma() { Interpretation interpretation() { - InterpretationBuilder ibuilder = InterpretationBuilder.solved("interpretation.id"); - GenomicInterpretation somatic = somaticRb1Missense(); - DiagnosisBuilder dbuilder = DiagnosisBuilder.builder(RETINOBLASTOMA); - dbuilder.genomicInterpretation(somatic); - dbuilder.genomicInterpretation(germlineRb1Deletion()); - ibuilder.diagnosis(dbuilder.build()); - return ibuilder.build(); + Diagnosis diagnosis = DiagnosisBuilder.builder(RETINOBLASTOMA) + .addGenomicInterpretation(somaticRb1Missense()) + .addGenomicInterpretation(germlineRb1Deletion()) + .build(); + return InterpretationBuilder.builder("interpretation.id").solved(diagnosis); } @@ -77,20 +73,17 @@ GenomicInterpretation somaticRb1Missense() { abuilder.setSequenceId("ga4gh:VA.GuPzvZoansqNHPoXkQLXKo31VkTpDKsM"); abuilder.startEnd( 48941647, 48941648); abuilder.setAltAllele("T"); - VariationDescriptorBuilder vbuilder = VariationDescriptorBuilder.builder("rs121913300"); - vbuilder.variation(abuilder.buildVariation()) + VariationDescriptorBuilder vbuilder = VariationDescriptorBuilder.builder("rs121913300") + .variation(abuilder.buildVariation()) .genomic() .heterozygous() .label("RB1 c.958C>T (p.Arg320Ter)") - .transcript(); - vbuilder.vcfHg38("NC_000013.11", 48367512, "C", "T"); - vbuilder.alleleFrequency(25.0); - GeneDescriptor geneDescriptor = GeneDescriptorBuilder.builder("HGNC:9884", "RB1").build(); - vbuilder.geneContext(geneDescriptor); - Expression hgvs = Expressions.hgvsCdna("NM_000321.2:c.958C>T"); - Expression transcriptReference = Expressions.transcriptReference("NM_000321.2"); - vbuilder.expression(hgvs); - vbuilder.expression(transcriptReference); + .transcript() + .vcfHg38("NC_000013.11", 48367512, "C", "T") + .alleleFrequency(25.0) + .geneContext(GeneDescriptorBuilder.geneDescriptor("HGNC:9884", "RB1")) + .addExpression(Expressions.hgvsCdna("NM_000321.2:c.958C>T")) + .addExpression(Expressions.transcriptReference("NM_000321.2")); // wrap in VariantInterpretation VariantInterpretationBuilder vibuilder = VariantInterpretationBuilder.builder(vbuilder); vibuilder.pathogenic(); @@ -150,40 +143,38 @@ Pedigree pedigree() { .affected() .build(); PedigreeBuilder pbuilder = PedigreeBuilder.builder(); - pbuilder.person(father); - pbuilder.person(mother); - pbuilder.person(child); + pbuilder.addPerson(father); + pbuilder.addPerson(mother); + pbuilder.addPerson(child); return pbuilder.build(); } Biosample enucleatedEye() { TimeElement age = TimeElements.age("P8M2W"); - BiosampleBuilder builder = BiosampleBuilder.builder(BIOSAMPLE_ID); - builder.sampledTissue(EYE); + BiosampleBuilder biosampleBuilder = BiosampleBuilder.builder(BIOSAMPLE_ID); + biosampleBuilder.sampledTissue(EYE); //Retinoblastoma with tumor invading optic nerve past lamina cribrosa but not to surgical resection line and exhibiting massive choroidal invasion. - builder.addPathologicalTnmFinding(ontologyClass("NCIT:C88735", "Retinoblastoma pT3b TNM Finding v7")); + biosampleBuilder.addPathologicalTnmFinding(ontologyClass("NCIT:C88735", "Retinoblastoma pT3b TNM Finding v7")); //Retinoblastoma with no regional lymph node involvement. - builder.addPathologicalTnmFinding(ontologyClass("NCIT:C88741","Retinoblastoma pN0 TNM Finding v7")); + biosampleBuilder.addPathologicalTnmFinding(ontologyClass("NCIT:C88741","Retinoblastoma pN0 TNM Finding v7")); - // - PhenotypicFeature pfRosette = PhenotypicFeatureBuilder.phenotypicFeature("NCIT:C35941", "Flexner-Wintersteiner Rosette Formation"); - builder.addPhenotypicFeature(pfRosette); - PhenotypicFeature pfApoptosis = PhenotypicFeatureBuilder.phenotypicFeature("NCIT:C132485", "Apoptosis and Necrosis"); - builder.addPhenotypicFeature(pfApoptosis); + biosampleBuilder.addPhenotypicFeature("NCIT:C35941", "Flexner-Wintersteiner Rosette Formation"); + biosampleBuilder.addPhenotypicFeature("NCIT:C132485", "Apoptosis and Necrosis"); OntologyClass maxTumorSizeTest = OntologyClassBuilder.ontologyClass("LOINC:33728-7", "Size.maximum dimension in Tumor"); Value maxTumorSize = ValueBuilder.value(Unit.mm(), 15); Measurement maxTumorSizeMeasurement = MeasurementBuilder.value(maxTumorSizeTest, maxTumorSize).timeObserved(age).build(); - builder.addMeasurement(maxTumorSizeMeasurement); - - ProcedureBuilder pbuilder = ProcedureBuilder.builder("NCIT:C48601", "Enucleation"); + biosampleBuilder.addMeasurement(maxTumorSizeMeasurement); - pbuilder.bodySite(LEFT_EYE).performed(age); - builder.procedure(pbuilder.build()); - builder.tumorProgression(PRIMARY_NEOPLASM); + Procedure enucleation = ProcedureBuilder.builder("NCIT:C48601", "Enucleation") + .bodySite(LEFT_EYE) + .performed(age) + .build(); + biosampleBuilder.procedure(enucleation); + biosampleBuilder.tumorProgression(PRIMARY_NEOPLASM); // VCF file with results of whole-genome sequencing on this tumor File wgsFile = FileBuilder.file("file://data/fileSomaticWgs.vcf.gz"); - builder.addFile(wgsFile); - return builder.build(); + biosampleBuilder.addFile(wgsFile); + return biosampleBuilder.build(); } @@ -201,10 +192,10 @@ MedicalAction melphalan() { Treatment treatment = TreatmentBuilder.builder(melphalan) .routeOfAdministration(administration) - .doseInterval(doseInterval).build(); + .addDoseInterval(doseInterval).build(); return MedicalActionBuilder.builder(treatment) - .adverseEvent(ontologyClass("HP:0025637", "Vasospasm")) + .addAdverseEvent(ontologyClass("HP:0025637", "Vasospasm")) .treatmentTarget(RETINOBLASTOMA) .treatmentIntent(CURE) .treatmentTerminationReason(ontologyClass("NCIT:C41331", "Adverse Event")) @@ -253,8 +244,8 @@ Disease getDisease() { TimeElement age4m = TimeElements.age("P4M"); return DiseaseBuilder.builder(RETINOBLASTOMA) .onset(age4m) - .diseaseStage(stageE) - .clinicalTnmFinding(noMetastasis) + .addDiseaseStage(stageE) + .addClinicalTnmFinding(noMetastasis) .primarySite(LEFT_EYE) .build(); } @@ -266,25 +257,25 @@ List getPhenotypicFeatures() { TimeElement age3months = TimeElements.age("P3M"); PhenotypicFeature clinodactyly = PhenotypicFeatureBuilder. builder("HP:0030084", "Clinodactyly"). - modifier(Laterality.right()). + addModifier(Laterality.right()). onset(age3months). build(); TimeElement age4months = TimeElements.age("P4M"); PhenotypicFeature leukocoria = PhenotypicFeatureBuilder. builder("HP:0000555", "Leukocoria") - .modifier(Laterality.unilateral()) + .addModifier(Laterality.unilateral()) .onset(age4months) .build(); TimeElement age5months = TimeElements.age("P5M15D"); PhenotypicFeature strabismus = PhenotypicFeatureBuilder. builder("HP:0000486", "Strabismus") - .modifier(Laterality.unilateral()) + .addModifier(Laterality.unilateral()) .onset(age5months) .build(); TimeElement age6months = TimeElements.age("P6M"); PhenotypicFeature retinalDetachment = PhenotypicFeatureBuilder .builder("HP:0000541", "Retinal detachment") - .modifier(Laterality.unilateral()) + .addModifier(Laterality.unilateral()) .onset(age6months) .build(); return List.of(clinodactyly, leukocoria, strabismus, retinalDetachment); diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/SquamousCellCancer.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/SquamousCellCancer.java index ad5596e5..7915ff4b 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/SquamousCellCancer.java +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/SquamousCellCancer.java @@ -18,16 +18,16 @@ class SquamousCellCancer implements PhenopacketExample { SquamousCellCancer() { Individual proband = IndividualBuilder.builder(PROBAND_ID).male().ageAtLastEncounter("P38Y").build(); var metadata = MetaDataBuilder.builder("2021-05-14T10:35:00Z", "anonymous biocurator") - .resource(Resources.ncitVersion("21.05d")) - .resource(Resources.efoVersion("3.34.0")) - .resource(Resources.uberonVersion("2021-07-27")) - .resource(Resources.ncbiTaxonVersion("2021-06-10")) + .addResource(Resources.ncitVersion("21.05d")) + .addResource(Resources.efoVersion("3.34.0")) + .addResource(Resources.uberonVersion("2021-07-27")) + .addResource(Resources.ncbiTaxonVersion("2021-06-10")) .build(); var esophagealSCC = ontologyClass("NCIT:C4024", "Esophageal Squamous Cell Carcinoma"); var disease = DiseaseBuilder.builder(esophagealSCC) - .clinicalTnmFinding(ontologyClass("NCIT:C48724", "T2 Stage Finding")) - .clinicalTnmFinding(ontologyClass("NCIT:C48706", "N1 Stage Finding")) - .clinicalTnmFinding(ontologyClass("NCIT:C48699", "M0 Stage Finding")) + .addClinicalTnmFinding(ontologyClass("NCIT:C48724", "T2 Stage Finding")) + .addClinicalTnmFinding(ontologyClass("NCIT:C48706", "N1 Stage Finding")) + .addClinicalTnmFinding(ontologyClass("NCIT:C48699", "M0 Stage Finding")) .build(); var esophagusBiopsy = BiosampleBuilder.builder("biosample 1") .individualId(PROBAND_ID) diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Thrombocytopenia2.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Thrombocytopenia2.java index 931d66ba..44e4a917 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Thrombocytopenia2.java +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Thrombocytopenia2.java @@ -2,7 +2,7 @@ import org.phenopackets.phenotools.builder.PhenopacketBuilder; import org.phenopackets.phenotools.builder.builders.*; -import org.phenopackets.phenotools.builder.builders.constants.Status; +import org.phenopackets.phenotools.builder.constants.Status; import org.phenopackets.schema.v2.Phenopacket; import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; @@ -19,9 +19,9 @@ class Thrombocytopenia2 implements PhenopacketExample { var thrombocytopenia2 = ontologyClass("OMIM:188000", "Thrombocytopenia 2"); var individual = IndividualBuilder.builder(PROBAND_ID).female().ageAtLastEncounter("P20Y").build(); var metaData = MetaDataBuilder.builder("2021-05-14T10:35:00Z", "anonymous biocurator") - .resource(Resources.hpoVersion("2021-08-02")) - .resource(Resources.genoVersion("2020-03-08")) - .externalReference(authorAssertion.getReference()) + .addResource(Resources.hpoVersion("2021-08-02")) + .addResource(Resources.genoVersion("2020-03-08")) + .addExternalReference(authorAssertion.getReference()) .build(); var variationDescriptor = VariationDescriptorBuilder.builder("variant id") @@ -34,17 +34,16 @@ class Thrombocytopenia2 implements PhenopacketExample { .causative() .variantInterpretation(col6a1VariantInterpretation) .build(); - var diagnosis = DiagnosisBuilder.builder(thrombocytopenia2).genomicInterpretation(genomicInterpretation).build(); - var interpretation = InterpretationBuilder.builder(INTERPRETATION_ID, Status.completed()) - .diagnosis(diagnosis).build(); + var diagnosis = DiagnosisBuilder.builder(thrombocytopenia2).addGenomicInterpretation(genomicInterpretation).build(); + var interpretation = InterpretationBuilder.builder(INTERPRETATION_ID).completed(diagnosis); var excludedAbnormalPlateletSize = PhenotypicFeatureBuilder.builder("HP:0011876", "Abnormal platelet volume") .excluded() - .evidence(authorAssertion) + .addEvidence(authorAssertion) .build(); var brusing = PhenotypicFeatureBuilder.builder("HP:0000978", "Bruising susceptibility") - .evidence(authorAssertion) + .addEvidence(authorAssertion) .build(); phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metaData) .individual(individual) diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/UrothelialCancer.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/UrothelialCancer.java index e6a14aec..d7211829 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/UrothelialCancer.java +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/UrothelialCancer.java @@ -3,6 +3,7 @@ import org.phenopackets.phenotools.builder.PhenopacketBuilder; import org.phenopackets.phenotools.builder.builders.*; +import org.phenopackets.phenotools.builder.constants.Severity; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; @@ -18,15 +19,15 @@ class UrothelialCancer implements PhenopacketExample { UrothelialCancer() { var individual = IndividualBuilder.builder(PROBAND_ID).male().dateOfBirth("1964-03-15T00:00:00Z").build(); - var hematuria = PhenotypicFeatureBuilder.builder("HP:0000790","Hematuria").build(); - var dsyuria = PhenotypicFeatureBuilder.builder("HP:0100518","Dysuria") - .severe() + var hematuria = PhenotypicFeatureBuilder.phenotypicFeature("HP:0000790","Hematuria"); + var dsyuria = PhenotypicFeatureBuilder.builder("HP:0100518", "Dysuria") + .severity(Severity.severe()) .build(); var metadata = MetaDataBuilder.builder("2021-05-14T10:35:00Z", "anonymous biocurator") - .resource(Resources.ncitVersion("21.05d")) - .resource(Resources.efoVersion("3.34.0")) - .resource(Resources.uberonVersion("2021-07-27")) - .resource(Resources.ncbiTaxonVersion("2021-06-10")) + .addResource(Resources.ncitVersion("21.05d")) + .addResource(Resources.efoVersion("3.34.0")) + .addResource(Resources.uberonVersion("2021-07-27")) + .addResource(Resources.ncbiTaxonVersion("2021-06-10")) .build(); phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metadata) .individual(individual) @@ -56,16 +57,16 @@ private File normalGermlineHtsFile() { private Disease infiltratingUrothelialCarcinoma() { return DiseaseBuilder.builder("NCIT:C39853", "Infiltrating Urothelial Carcinoma") // Disease stage here is calculated based on the TMN findings - .diseaseStage(ontologyClass("NCIT:C27971", "Stage IV")) + .addDiseaseStage(ontologyClass("NCIT:C27971", "Stage IV")) // The tumor was staged as pT2b, meaning infiltration into the outer muscle layer of the bladder wall // pT2b Stage Finding (Code C48766) - .clinicalTnmFinding(ontologyClass("NCIT:C48766", "pT2b Stage Finding")) + .addClinicalTnmFinding(ontologyClass("NCIT:C48766", "pT2b Stage Finding")) //pN2 Stage Finding (Code C48750) // cancer has spread to 2 or more lymph nodes in the true pelvis (N2) - .clinicalTnmFinding(ontologyClass("NCIT:C48750", "pN2 Stage Finding")) + .addClinicalTnmFinding(ontologyClass("NCIT:C48750", "pN2 Stage Finding")) // M1 Stage Finding // the tumour has spread from the original site (Metastatic Neoplasm in lymph node - sample5) - .clinicalTnmFinding(ontologyClass("NCIT:C48700", "M1 Stage Finding")) + .addClinicalTnmFinding(ontologyClass("NCIT:C48700", "M1 Stage Finding")) .build(); } diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/WarburgMicroSyndrome.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/WarburgMicroSyndrome.java index 07723457..7b630ed9 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/WarburgMicroSyndrome.java +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/WarburgMicroSyndrome.java @@ -20,8 +20,8 @@ public class WarburgMicroSyndrome implements PhenopacketExample { private final Phenopacket phenopacket; public WarburgMicroSyndrome() { var metadata = MetaDataBuilder.builder("2022-04-17T10:35:00Z", "biocurator") - .resource(Resources.hpoVersion("2022-04-15")) - .resource(Resources.mondoVersion("v2022-04-04")) + .addResource(Resources.hpoVersion("2022-04-15")) + .addResource(Resources.mondoVersion("v2022-04-04")) .build(); Individual proband = IndividualBuilder.builder("case1"). ageAtLastEncounter("P4D"). From b9e286bc224c085963755eb8dd20ccdf7dcf4c1e Mon Sep 17 00:00:00 2001 From: Jules Jacobsen Date: Thu, 14 Apr 2022 14:55:28 +0100 Subject: [PATCH 026/155] Change for issue #48 - Update groupId to org.phenopackets.phenopackettools Update artifactIds to start with phenopacket-tools --- .../pom.xml | 6 +-- .../builder/FamilyBuilder.java | 4 +- .../builder/PhenopacketBuilder.java | 4 +- .../builder/builders/AgeBuilder.java | 4 +- .../builder/builders/AlleleBuilder.java | 2 +- .../builder/builders/BiosampleBuilder.java | 2 +- .../builder/builders/ComplexValueBuilder.java | 2 +- .../builder/builders/CopyNumberBuilder.java | 4 +- .../builder/builders/DiagnosisBuilder.java | 2 +- .../builder/builders/DiseaseBuilder.java | 2 +- .../builder/builders/DoseIntervalBuilder.java | 2 +- .../builder/builders/EvidenceBuilder.java | 2 +- .../builder/builders/Expressions.java | 2 +- .../builder/builders/Extensions.java | 2 +- .../builders/ExternalReferenceBuilder.java | 2 +- .../builder/builders/FileBuilder.java | 2 +- .../builders/GeneDescriptorBuilder.java | 2 +- .../GenomicInterpretationBuilder.java | 2 +- .../builder/builders/IndividualBuilder.java | 2 +- .../builders/InterpretationBuilder.java | 2 +- .../builder/builders/MeasurementBuilder.java | 2 +- .../builders/MedicalActionBuilder.java | 2 +- .../builder/builders/MetaDataBuilder.java | 4 +- .../builders/OntologyClassBuilder.java | 2 +- .../builder/builders/PedigreeBuilder.java | 2 +- .../builder/builders/PersonBuilder.java | 2 +- .../builders/PhenotypicFeatureBuilder.java | 2 +- .../builder/builders/ProcedureBuilder.java | 2 +- .../builder/builders/QuantityBuilder.java | 2 +- .../builders/ReferenceRangeBuilder.java | 2 +- .../builder/builders/Resources.java | 2 +- .../builders/TherapeuticRegimenBuilder.java | 2 +- .../builder/builders/TimeElements.java | 4 +- .../builder/builders/TimeIntervalBuilder.java | 4 +- .../builder/builders/TimestampBuilder.java | 2 +- .../builder/builders/TreatmentBuilder.java | 2 +- .../builders/TypedQuantityBuilder.java | 2 +- .../builder/builders/ValueBuilder.java | 2 +- .../VariantInterpretationBuilder.java | 2 +- .../builders/VariationDescriptorBuilder.java | 2 +- .../builder/builders/VcfRecordBuilder.java | 2 +- .../builder/builders/VitalStatusBuilder.java | 2 +- .../builder/constants/Laterality.java | 4 +- .../builder/constants/Onset.java | 2 +- .../builder/constants/Severity.java | 4 +- .../builder/constants/Status.java | 2 +- .../builder/constants/Unit.java | 4 +- .../PhenotoolsRuntimeException.java | 2 +- .../builder/builders/AgeBuilderTest.java | 2 +- .../builder/builders/AlleleBuilderTest.java | 3 +- .../builders/BiosampleBuilderTest.java | 4 +- .../builders/ComplexValueBuilderTest.java | 4 +- .../builders/DiagnosisBuilderTest.java | 6 +-- .../builder/builders/DiseaseBuilderTest.java | 4 +- .../builders/DoseIntervalBuilderTest.java | 4 +- .../builder/builders/FIleBuilderTest.java | 2 +- .../builders/IndividualBuilderTest.java | 6 +-- .../builder/builders/MetaDataBuilderTest.java | 2 +- .../builder/builders/TimeElementsTest.java | 6 +-- .../builders/TimeIntervalBuilderTest.java | 2 +- .../builders/TimestampBuilderTest.java | 2 +- .../pom.xml | 52 +++++-------------- .../phenopackets/phenopackettools}/Main.java | 2 +- .../phenopackettools}/PhenopacketTools.java | 8 +-- .../command/ConvertCommand.java | 4 +- .../command/ExamplesCommand.java | 10 ++-- .../command/ValidateCommand.java | 12 ++--- .../examples/BethlehamMyopathy.java | 10 ++-- .../phenopackettools}/examples/Covid.java | 8 +-- .../examples/FamilyWithPedigree.java | 8 +-- .../phenopackettools}/examples/Marfan.java | 8 +-- .../examples/NemalineMyopathyPrenatal.java | 12 ++--- .../examples/PhenopacketExample.java | 2 +- .../examples/PhenopacketExamples.java | 2 +- .../examples/Retinoblastoma.java | 12 ++--- .../examples/SquamousCellCancer.java | 8 +-- .../examples/Thrombocytopenia2.java | 10 ++-- .../examples/UrothelialCancer.java | 10 ++-- .../examples/WarburgMicroSyndrome.java | 8 +-- .../src/main/resources/logback.xml | 0 .../pom.xml | 6 +-- .../converter/converters/CohortConverter.java | 8 +-- .../converter/converters/FamilyConverter.java | 12 ++--- .../converters/PhenopacketConverter.java | 14 ++--- .../converter/converters/v2/AgeConverter.java | 2 +- .../converters/v2/BiosampleConverter.java | 12 ++--- .../converters/v2/DiseaseConverter.java | 8 +-- .../converters/v2/EvidenceConverter.java | 6 +-- .../v2/ExternalReferenceConverter.java | 2 +- .../converters/v2/FileConverter.java | 2 +- .../converters/v2/IndividualConverter.java | 8 +-- .../converters/v2/MetaDataConverter.java | 6 +-- .../converters/v2/OntologyClassConverter.java | 2 +- .../converters/v2/PedigreeConverter.java | 4 +- .../v2/PhenotypicFeatureConverter.java | 12 ++--- .../converters/v2/ProcedureConverter.java | 4 +- .../converters/v2/ResourceConverter.java | 2 +- .../converter/BethlemMyopathyV1.java | 2 +- .../converter/PhenopacketConverterTest.java | 8 +-- .../.mvn/wrapper/maven-wrapper.properties | 0 .../mvnw | 0 .../mvnw.cmd | 0 .../pom.xml | 8 +-- .../validator/core/DefaultValidationInfo.java | 2 +- .../validator/core/ErrorType.java | 4 +- .../validator/core/PhenopacketValidator.java | 2 +- .../core/PhenopacketValidatorFactory.java | 2 +- .../validator/core/ValidationAspect.java | 2 +- .../validator/core/ValidationItem.java | 2 +- .../validator/core/ValidatorInfo.java | 2 +- .../validator/core/ValidatorRunner.java | 2 +- .../PhenopacketValidatorRuntimeException.java | 2 +- .../pom.xml | 14 ++--- .../ClasspathJsonSchemaValidatorFactory.java | 10 ++-- .../jsonschema/JsonSchemaValidator.java | 10 ++-- .../jsonschema/JsonValidationError.java | 8 +-- .../schema/hpo-rare-disease-schema.json | 0 .../schema/phenopacket-schema-2-0.json | 0 .../JsonSchemaDiseaseValidatorTest.java | 18 +++---- .../jsonschema/JsonSchemaValidatorTest.java | 14 ++--- .../testdatagen/PhenopacketUtil.java | 2 +- .../testdatagen/RareDiseasePhenopacket.java | 4 +- .../testdatagen/SimplePhenopacket.java | 4 +- .../json/bethlehamMyopathyExample.json | 0 .../json/bethlehamMyopathyInvalidExample.json | 0 .../src/test/resources/logback-test.xml | 0 pom.xml | 17 +++--- 127 files changed, 287 insertions(+), 315 deletions(-) rename {phenotools-builder => phenopacket-tools-builder}/pom.xml (83%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/FamilyBuilder.java (92%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/PhenopacketBuilder.java (94%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/AgeBuilder.java (87%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/AlleleBuilder.java (97%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/BiosampleBuilder.java (98%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/ComplexValueBuilder.java (94%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/CopyNumberBuilder.java (93%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/DiagnosisBuilder.java (92%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/DiseaseBuilder.java (96%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/DoseIntervalBuilder.java (94%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/EvidenceBuilder.java (96%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/Expressions.java (92%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/Extensions.java (89%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/ExternalReferenceBuilder.java (94%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/FileBuilder.java (96%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/GeneDescriptorBuilder.java (96%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/GenomicInterpretationBuilder.java (97%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/IndividualBuilder.java (98%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/InterpretationBuilder.java (97%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/MeasurementBuilder.java (96%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/MedicalActionBuilder.java (97%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/MetaDataBuilder.java (91%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/OntologyClassBuilder.java (83%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/PedigreeBuilder.java (93%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/PersonBuilder.java (97%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/PhenotypicFeatureBuilder.java (98%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/ProcedureBuilder.java (95%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/QuantityBuilder.java (97%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/ReferenceRangeBuilder.java (93%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/Resources.java (98%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/TherapeuticRegimenBuilder.java (96%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/TimeElements.java (97%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/TimeIntervalBuilder.java (80%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/TimestampBuilder.java (97%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/TreatmentBuilder.java (96%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/TypedQuantityBuilder.java (87%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/ValueBuilder.java (95%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/VariantInterpretationBuilder.java (98%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/VariationDescriptorBuilder.java (98%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/VcfRecordBuilder.java (97%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/builders/VitalStatusBuilder.java (95%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/constants/Laterality.java (85%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/constants/Onset.java (97%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/constants/Severity.java (92%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/constants/Status.java (97%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/constants/Unit.java (82%) rename {phenotools-builder/src/main/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools}/builder/exceptions/PhenotoolsRuntimeException.java (74%) rename {phenotools-builder/src/test/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools}/builder/builders/AgeBuilderTest.java (96%) rename {phenotools-builder/src/test/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools}/builder/builders/AlleleBuilderTest.java (91%) rename {phenotools-builder/src/test/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools}/builder/builders/BiosampleBuilderTest.java (95%) rename {phenotools-builder/src/test/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools}/builder/builders/ComplexValueBuilderTest.java (89%) rename {phenotools-builder/src/test/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools}/builder/builders/DiagnosisBuilderTest.java (89%) rename {phenotools-builder/src/test/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools}/builder/builders/DiseaseBuilderTest.java (83%) rename {phenotools-builder/src/test/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools}/builder/builders/DoseIntervalBuilderTest.java (87%) rename {phenotools-builder/src/test/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools}/builder/builders/FIleBuilderTest.java (94%) rename {phenotools-builder/src/test/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools}/builder/builders/IndividualBuilderTest.java (91%) rename {phenotools-builder/src/test/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools}/builder/builders/MetaDataBuilderTest.java (90%) rename {phenotools-builder/src/test/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools}/builder/builders/TimeElementsTest.java (93%) rename {phenotools-builder/src/test/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools}/builder/builders/TimeIntervalBuilderTest.java (95%) rename {phenotools-builder/src/test/java/org/phenopackets/phenotools => phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools}/builder/builders/TimestampBuilderTest.java (92%) rename {phenotools-cli => phenopacket-tools-cli}/pom.xml (52%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/Main.java (92%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/PhenopacketTools.java (66%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/command/ConvertCommand.java (96%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/command/ExamplesCommand.java (93%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/command/ValidateCommand.java (83%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/examples/BethlehamMyopathy.java (93%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/examples/Covid.java (97%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/examples/FamilyWithPedigree.java (93%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/examples/Marfan.java (87%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/examples/NemalineMyopathyPrenatal.java (94%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/examples/PhenopacketExample.java (69%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/examples/PhenopacketExamples.java (97%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/examples/Retinoblastoma.java (97%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/examples/SquamousCellCancer.java (92%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/examples/Thrombocytopenia2.java (89%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/examples/UrothelialCancer.java (95%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/examples/WarburgMicroSyndrome.java (92%) rename {phenotools-cli => phenopacket-tools-cli}/src/main/resources/logback.xml (100%) rename {phenotools-converter => phenopacket-tools-converter}/pom.xml (83%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/CohortConverter.java (70%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/FamilyConverter.java (63%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/PhenopacketConverter.java (70%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/v2/AgeConverter.java (89%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/v2/BiosampleConverter.java (85%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/v2/DiseaseConverter.java (81%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/v2/EvidenceConverter.java (74%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/v2/ExternalReferenceConverter.java (94%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/v2/FileConverter.java (93%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/v2/IndividualConverter.java (88%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/v2/MetaDataConverter.java (82%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/v2/OntologyClassConverter.java (93%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/v2/PedigreeConverter.java (92%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/v2/PhenotypicFeatureConverter.java (82%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/v2/ProcedureConverter.java (79%) rename {phenotools-converter/src/main/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools}/converter/converters/v2/ResourceConverter.java (92%) rename {phenotools-converter/src/test/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools}/converter/BethlemMyopathyV1.java (99%) rename {phenotools-converter/src/test/java/org/phenopackets/phenotools => phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools}/converter/PhenopacketConverterTest.java (61%) rename {phenotools-validator-core => phenopacket-tools-validator-core}/.mvn/wrapper/maven-wrapper.properties (100%) rename {phenotools-validator-core => phenopacket-tools-validator-core}/mvnw (100%) rename {phenotools-validator-core => phenopacket-tools-validator-core}/mvnw.cmd (100%) rename {phenotools-validator-core => phenopacket-tools-validator-core}/pom.xml (66%) rename {phenotools-validator-core/src/main/java/org/phenopackets/phenotools => phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools}/validator/core/DefaultValidationInfo.java (96%) rename {phenotools-validator-core/src/main/java/org/phenopackets/phenotools => phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools}/validator/core/ErrorType.java (88%) rename {phenotools-validator-core/src/main/java/org/phenopackets/phenotools => phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools}/validator/core/PhenopacketValidator.java (94%) rename {phenotools-validator-core/src/main/java/org/phenopackets/phenotools => phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools}/validator/core/PhenopacketValidatorFactory.java (85%) rename {phenotools-validator-core/src/main/java/org/phenopackets/phenotools => phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools}/validator/core/ValidationAspect.java (86%) rename {phenotools-validator-core/src/main/java/org/phenopackets/phenotools => phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools}/validator/core/ValidationItem.java (90%) rename {phenotools-validator-core/src/main/java/org/phenopackets/phenotools => phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools}/validator/core/ValidatorInfo.java (93%) rename {phenotools-validator-core/src/main/java/org/phenopackets/phenotools => phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools}/validator/core/ValidatorRunner.java (96%) rename {phenotools-validator-core/src/main/java/org/phenopackets/phenotools => phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools}/validator/core/except/PhenopacketValidatorRuntimeException.java (91%) rename {phenotools-validator-jsonschema => phenopacket-tools-validator-jsonschema}/pom.xml (77%) rename {phenotools-validator-jsonschema/src/main/java/org/phenopackets/phenotools => phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools}/validator/jsonschema/ClasspathJsonSchemaValidatorFactory.java (84%) rename {phenotools-validator-jsonschema/src/main/java/org/phenopackets/phenotools => phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools}/validator/jsonschema/JsonSchemaValidator.java (90%) rename {phenotools-validator-jsonschema/src/main/java/org/phenopackets/phenotools => phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools}/validator/jsonschema/JsonValidationError.java (85%) rename {phenotools-validator-jsonschema => phenopacket-tools-validator-jsonschema}/src/main/resources/schema/hpo-rare-disease-schema.json (100%) rename {phenotools-validator-jsonschema => phenopacket-tools-validator-jsonschema}/src/main/resources/schema/phenopacket-schema-2-0.json (100%) rename {phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools => phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools}/validator/jsonschema/JsonSchemaDiseaseValidatorTest.java (84%) rename {phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools => phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools}/validator/jsonschema/JsonSchemaValidatorTest.java (88%) rename {phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools => phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools}/validator/testdatagen/PhenopacketUtil.java (99%) rename {phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools => phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools}/validator/testdatagen/RareDiseasePhenopacket.java (93%) rename {phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools => phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools}/validator/testdatagen/SimplePhenopacket.java (83%) rename {phenotools-validator-jsonschema => phenopacket-tools-validator-jsonschema}/src/test/resources/json/bethlehamMyopathyExample.json (100%) rename {phenotools-validator-jsonschema => phenopacket-tools-validator-jsonschema}/src/test/resources/json/bethlehamMyopathyInvalidExample.json (100%) rename {phenotools-validator-jsonschema => phenopacket-tools-validator-jsonschema}/src/test/resources/logback-test.xml (100%) diff --git a/phenotools-builder/pom.xml b/phenopacket-tools-builder/pom.xml similarity index 83% rename from phenotools-builder/pom.xml rename to phenopacket-tools-builder/pom.xml index 14cde2e6..ae71ee17 100644 --- a/phenotools-builder/pom.xml +++ b/phenopacket-tools-builder/pom.xml @@ -5,12 +5,12 @@ 4.0.0 - org.phenopackets.phenotools - phenotools + org.phenopackets.phenopackettools + phenopacket-tools 1.0.0 - phenotools-builder + phenopacket-tools-builder diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/FamilyBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/FamilyBuilder.java similarity index 92% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/FamilyBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/FamilyBuilder.java index 41643af4..9f8a5654 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/FamilyBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/FamilyBuilder.java @@ -1,6 +1,6 @@ -package org.phenopackets.phenotools.builder; +package org.phenopackets.phenopackettools.builder; -import org.phenopackets.phenotools.builder.exceptions.PhenotoolsRuntimeException; +import org.phenopackets.phenopackettools.builder.exceptions.PhenotoolsRuntimeException; import org.phenopackets.schema.v2.Family; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.File; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/PhenopacketBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/PhenopacketBuilder.java similarity index 94% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/PhenopacketBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/PhenopacketBuilder.java index f5ef9c57..0f399bd5 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/PhenopacketBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/PhenopacketBuilder.java @@ -1,6 +1,6 @@ -package org.phenopackets.phenotools.builder; +package org.phenopackets.phenopackettools.builder; -import org.phenopackets.phenotools.builder.builders.PhenotypicFeatureBuilder; +import org.phenopackets.phenopackettools.builder.builders.PhenotypicFeatureBuilder; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/AgeBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/AgeBuilder.java similarity index 87% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/AgeBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/AgeBuilder.java index 694cb145..20691682 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/AgeBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/AgeBuilder.java @@ -1,6 +1,6 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; -import org.phenopackets.phenotools.builder.exceptions.PhenotoolsRuntimeException; +import org.phenopackets.phenopackettools.builder.exceptions.PhenotoolsRuntimeException; import org.phenopackets.schema.v2.core.Age; import org.phenopackets.schema.v2.core.AgeRange; import org.phenopackets.schema.v2.core.GestationalAge; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/AlleleBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilder.java similarity index 97% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/AlleleBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilder.java index 1c97ac66..7e7b7a07 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/AlleleBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.ga4gh.vrs.v1.*; import org.ga4gh.vrs.v1.Number; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/BiosampleBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilder.java similarity index 98% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/BiosampleBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilder.java index 37fa70cb..4c15789e 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/BiosampleBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.*; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/ComplexValueBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilder.java similarity index 94% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/ComplexValueBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilder.java index b75f8646..ff370bcf 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/ComplexValueBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.ComplexValue; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/CopyNumberBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/CopyNumberBuilder.java similarity index 93% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/CopyNumberBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/CopyNumberBuilder.java index 2eaa2f2d..fb9a2b6b 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/CopyNumberBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/CopyNumberBuilder.java @@ -1,8 +1,8 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.ga4gh.vrs.v1.*; import org.ga4gh.vrs.v1.Number; -import org.phenopackets.phenotools.builder.exceptions.PhenotoolsRuntimeException; +import org.phenopackets.phenopackettools.builder.exceptions.PhenotoolsRuntimeException; public class CopyNumberBuilder { diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DiagnosisBuilder.java similarity index 92% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DiagnosisBuilder.java index 7a799b40..138669d4 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DiagnosisBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.Diagnosis; import org.phenopackets.schema.v2.core.GenomicInterpretation; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DiseaseBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilder.java similarity index 96% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DiseaseBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilder.java index c28e5fa7..3c648524 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DiseaseBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.Disease; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DoseIntervalBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DoseIntervalBuilder.java similarity index 94% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DoseIntervalBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DoseIntervalBuilder.java index 5927a7ea..52850cce 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/DoseIntervalBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DoseIntervalBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.DoseInterval; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/EvidenceBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/EvidenceBuilder.java similarity index 96% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/EvidenceBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/EvidenceBuilder.java index d48dd974..f9064b09 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/EvidenceBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/EvidenceBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.Evidence; import org.phenopackets.schema.v2.core.ExternalReference; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Expressions.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Expressions.java similarity index 92% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Expressions.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Expressions.java index 62fac158..cc5a0535 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Expressions.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Expressions.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.ga4gh.vrsatile.v1.Expression; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Extensions.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Extensions.java similarity index 89% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Extensions.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Extensions.java index f355f762..c8069ff7 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Extensions.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Extensions.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import com.google.protobuf.Any; import com.google.protobuf.ByteString; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/ExternalReferenceBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ExternalReferenceBuilder.java similarity index 94% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/ExternalReferenceBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ExternalReferenceBuilder.java index c55101c0..d441a7ea 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/ExternalReferenceBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ExternalReferenceBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.ExternalReference; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/FileBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/FileBuilder.java similarity index 96% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/FileBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/FileBuilder.java index d6fe7c03..c24fa37a 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/FileBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/FileBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.File; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/GeneDescriptorBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/GeneDescriptorBuilder.java similarity index 96% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/GeneDescriptorBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/GeneDescriptorBuilder.java index 98576fb1..af870423 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/GeneDescriptorBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/GeneDescriptorBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.ga4gh.vrsatile.v1.GeneDescriptor; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/GenomicInterpretationBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/GenomicInterpretationBuilder.java similarity index 97% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/GenomicInterpretationBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/GenomicInterpretationBuilder.java index ca224fd2..8ec96a09 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/GenomicInterpretationBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/GenomicInterpretationBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.ga4gh.vrsatile.v1.GeneDescriptor; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/IndividualBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilder.java similarity index 98% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/IndividualBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilder.java index 25593a87..87f92377 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/IndividualBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import com.google.protobuf.Timestamp; import org.phenopackets.schema.v2.core.*; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/InterpretationBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/InterpretationBuilder.java similarity index 97% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/InterpretationBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/InterpretationBuilder.java index c32dea86..24ccc346 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/InterpretationBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/InterpretationBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.Diagnosis; import org.phenopackets.schema.v2.core.Interpretation; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MeasurementBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MeasurementBuilder.java similarity index 96% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MeasurementBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MeasurementBuilder.java index b6fdaf31..cdb63a7e 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MeasurementBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MeasurementBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.*; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MedicalActionBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MedicalActionBuilder.java similarity index 97% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MedicalActionBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MedicalActionBuilder.java index cf95add2..7cc55220 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MedicalActionBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MedicalActionBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.*; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MetaDataBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MetaDataBuilder.java similarity index 91% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MetaDataBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MetaDataBuilder.java index 73632fbf..00a567f3 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/MetaDataBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MetaDataBuilder.java @@ -1,11 +1,11 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.ExternalReference; import org.phenopackets.schema.v2.core.MetaData; import org.phenopackets.schema.v2.core.Resource; import org.phenopackets.schema.v2.core.Update; -import static org.phenopackets.phenotools.builder.builders.TimestampBuilder.fromISO8601; +import static org.phenopackets.phenopackettools.builder.builders.TimestampBuilder.fromISO8601; public class MetaDataBuilder { diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/OntologyClassBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/OntologyClassBuilder.java similarity index 83% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/OntologyClassBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/OntologyClassBuilder.java index c9b9f472..aa72d392 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/OntologyClassBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/OntologyClassBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PedigreeBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/PedigreeBuilder.java similarity index 93% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PedigreeBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/PedigreeBuilder.java index c708ced3..14ea1916 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PedigreeBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/PedigreeBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.Pedigree; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PersonBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/PersonBuilder.java similarity index 97% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PersonBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/PersonBuilder.java index 317862c7..08eb9e90 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PersonBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/PersonBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.Pedigree; import org.phenopackets.schema.v2.core.Sex; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PhenotypicFeatureBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/PhenotypicFeatureBuilder.java similarity index 98% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PhenotypicFeatureBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/PhenotypicFeatureBuilder.java index 2ffe1ddf..0899b58b 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/PhenotypicFeatureBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/PhenotypicFeatureBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.Evidence; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/ProcedureBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ProcedureBuilder.java similarity index 95% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/ProcedureBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ProcedureBuilder.java index f656f2db..6a17c2f2 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/ProcedureBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ProcedureBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.OntologyClass; import org.phenopackets.schema.v2.core.Procedure; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/QuantityBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/QuantityBuilder.java similarity index 97% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/QuantityBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/QuantityBuilder.java index 163b8630..c83c6298 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/QuantityBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/QuantityBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.OntologyClass; import org.phenopackets.schema.v2.core.Quantity; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/ReferenceRangeBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ReferenceRangeBuilder.java similarity index 93% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/ReferenceRangeBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ReferenceRangeBuilder.java index 5d67372a..8beca5e3 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/ReferenceRangeBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ReferenceRangeBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.OntologyClass; import org.phenopackets.schema.v2.core.ReferenceRange; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Resources.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Resources.java similarity index 98% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Resources.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Resources.java index ea09e04a..871edc75 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/Resources.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Resources.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.Resource; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TherapeuticRegimenBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TherapeuticRegimenBuilder.java similarity index 96% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TherapeuticRegimenBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TherapeuticRegimenBuilder.java index 63d04ce4..583bf529 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TherapeuticRegimenBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TherapeuticRegimenBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.OntologyClass; import org.phenopackets.schema.v2.core.TherapeuticRegimen; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimeElements.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimeElements.java similarity index 97% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimeElements.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimeElements.java index 7d58d55f..3e40b9e2 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimeElements.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimeElements.java @@ -1,7 +1,7 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import com.google.protobuf.Timestamp; -import org.phenopackets.phenotools.builder.constants.Onset; +import org.phenopackets.phenopackettools.builder.constants.Onset; import org.phenopackets.schema.v2.core.*; import java.time.Instant; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimeIntervalBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilder.java similarity index 80% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimeIntervalBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilder.java index bb3af87f..13cf6eec 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimeIntervalBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilder.java @@ -1,9 +1,9 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import com.google.protobuf.Timestamp; import org.phenopackets.schema.v2.core.TimeInterval; -import static org.phenopackets.phenotools.builder.builders.TimestampBuilder.fromISO8601; +import static org.phenopackets.phenopackettools.builder.builders.TimestampBuilder.fromISO8601; public class TimeIntervalBuilder { diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimestampBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimestampBuilder.java similarity index 97% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimestampBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimestampBuilder.java index c5da9c26..3a8e186a 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TimestampBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimestampBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import com.google.protobuf.Timestamp; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TreatmentBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TreatmentBuilder.java similarity index 96% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TreatmentBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TreatmentBuilder.java index 744b9b66..4cf3946d 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TreatmentBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TreatmentBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.*; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TypedQuantityBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TypedQuantityBuilder.java similarity index 87% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TypedQuantityBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TypedQuantityBuilder.java index 171ec624..158058b5 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/TypedQuantityBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TypedQuantityBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.OntologyClass; import org.phenopackets.schema.v2.core.Quantity; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/ValueBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ValueBuilder.java similarity index 95% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/ValueBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ValueBuilder.java index f0555639..f4ebb983 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/ValueBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ValueBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VariantInterpretationBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariantInterpretationBuilder.java similarity index 98% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VariantInterpretationBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariantInterpretationBuilder.java index 2191834d..2e985087 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VariantInterpretationBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariantInterpretationBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.ga4gh.vrsatile.v1.VariationDescriptor; import org.phenopackets.schema.v2.core.AcmgPathogenicityClassification; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VariationDescriptorBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariationDescriptorBuilder.java similarity index 98% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VariationDescriptorBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariationDescriptorBuilder.java index f38ace0a..153db950 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VariationDescriptorBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariationDescriptorBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.ga4gh.vrs.v1.Variation; import org.ga4gh.vrsatile.v1.*; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VcfRecordBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VcfRecordBuilder.java similarity index 97% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VcfRecordBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VcfRecordBuilder.java index 7063824e..bfd1c190 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VcfRecordBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VcfRecordBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.ga4gh.vrsatile.v1.VcfRecord; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VitalStatusBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VitalStatusBuilder.java similarity index 95% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VitalStatusBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VitalStatusBuilder.java index 9dfe82bc..a327c39d 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/builders/VitalStatusBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VitalStatusBuilder.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.phenopackets.schema.v2.core.OntologyClass; import org.phenopackets.schema.v2.core.TimeElement; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Laterality.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Laterality.java similarity index 85% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Laterality.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Laterality.java index 02413281..17e9c70f 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Laterality.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Laterality.java @@ -1,6 +1,6 @@ -package org.phenopackets.phenotools.builder.constants; +package org.phenopackets.phenopackettools.builder.constants; -import org.phenopackets.phenotools.builder.builders.OntologyClassBuilder; +import org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Onset.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Onset.java similarity index 97% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Onset.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Onset.java index e9ffc9fe..2dd221f0 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Onset.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Onset.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.constants; +package org.phenopackets.phenopackettools.builder.constants; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Severity.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Severity.java similarity index 92% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Severity.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Severity.java index 35594d5e..9a0fb7e4 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Severity.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Severity.java @@ -1,8 +1,8 @@ -package org.phenopackets.phenotools.builder.constants; +package org.phenopackets.phenopackettools.builder.constants; import org.phenopackets.schema.v2.core.OntologyClass; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; public class Severity { diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Status.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Status.java similarity index 97% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Status.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Status.java index fec4d29b..a1c80ea2 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Status.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Status.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.constants; +package org.phenopackets.phenopackettools.builder.constants; import org.phenopackets.schema.v2.core.AcmgPathogenicityClassification; import org.phenopackets.schema.v2.core.GenomicInterpretation.InterpretationStatus; diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Unit.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Unit.java similarity index 82% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Unit.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Unit.java index e0cbeedb..28337117 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/constants/Unit.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Unit.java @@ -1,8 +1,8 @@ -package org.phenopackets.phenotools.builder.constants; +package org.phenopackets.phenopackettools.builder.constants; import org.phenopackets.schema.v2.core.OntologyClass; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; public class Unit { diff --git a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/exceptions/PhenotoolsRuntimeException.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/exceptions/PhenotoolsRuntimeException.java similarity index 74% rename from phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/exceptions/PhenotoolsRuntimeException.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/exceptions/PhenotoolsRuntimeException.java index 9f8ac33f..7735686d 100644 --- a/phenotools-builder/src/main/java/org/phenopackets/phenotools/builder/exceptions/PhenotoolsRuntimeException.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/exceptions/PhenotoolsRuntimeException.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.exceptions; +package org.phenopackets.phenopackettools.builder.exceptions; public class PhenotoolsRuntimeException extends RuntimeException { public PhenotoolsRuntimeException() { super();} diff --git a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/AgeBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AgeBuilderTest.java similarity index 96% rename from phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/AgeBuilderTest.java rename to phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AgeBuilderTest.java index 63d9a4da..6729abc4 100644 --- a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/AgeBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AgeBuilderTest.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.junit.jupiter.api.Test; import org.phenopackets.schema.v2.core.Age; diff --git a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/AlleleBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilderTest.java similarity index 91% rename from phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/AlleleBuilderTest.java rename to phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilderTest.java index f260d7c1..4890a1d9 100644 --- a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/AlleleBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilderTest.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.ga4gh.vrs.v1.Allele; import org.ga4gh.vrs.v1.Variation; @@ -6,7 +6,6 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; -import static org.junit.jupiter.api.Assertions.*; class AlleleBuilderTest { diff --git a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/BiosampleBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilderTest.java similarity index 95% rename from phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/BiosampleBuilderTest.java rename to phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilderTest.java index 27cc3095..e3eafb5b 100644 --- a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/BiosampleBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilderTest.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.junit.jupiter.api.Test; import org.phenopackets.schema.v2.core.Biosample; @@ -7,7 +7,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; class BiosampleBuilderTest { diff --git a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/ComplexValueBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilderTest.java similarity index 89% rename from phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/ComplexValueBuilderTest.java rename to phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilderTest.java index 409da2c4..379bb619 100644 --- a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/ComplexValueBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilderTest.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.junit.jupiter.api.Test; import org.phenopackets.schema.v2.core.ComplexValue; @@ -9,7 +9,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; class ComplexValueBuilderTest { diff --git a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiagnosisBuilderTest.java similarity index 89% rename from phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilderTest.java rename to phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiagnosisBuilderTest.java index 196a55be..64bc4bf7 100644 --- a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DiagnosisBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiagnosisBuilderTest.java @@ -1,14 +1,14 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.junit.jupiter.api.Test; -import org.phenopackets.phenotools.builder.constants.Status; +import org.phenopackets.phenopackettools.builder.constants.Status; import org.phenopackets.schema.v2.core.Diagnosis; import org.phenopackets.schema.v2.core.GenomicInterpretation; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; class DiagnosisBuilderTest { diff --git a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DiseaseBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilderTest.java similarity index 83% rename from phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DiseaseBuilderTest.java rename to phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilderTest.java index a1d2bacb..5002696b 100644 --- a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DiseaseBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilderTest.java @@ -1,11 +1,11 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.junit.jupiter.api.Test; import org.phenopackets.schema.v2.core.Disease; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; class DiseaseBuilderTest { diff --git a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DoseIntervalBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DoseIntervalBuilderTest.java similarity index 87% rename from phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DoseIntervalBuilderTest.java rename to phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DoseIntervalBuilderTest.java index 6b727c67..d1a22e70 100644 --- a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/DoseIntervalBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DoseIntervalBuilderTest.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import com.google.protobuf.Timestamp; import org.junit.jupiter.api.Test; @@ -8,7 +8,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; public class DoseIntervalBuilderTest { diff --git a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/FIleBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/FIleBuilderTest.java similarity index 94% rename from phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/FIleBuilderTest.java rename to phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/FIleBuilderTest.java index 4c7a6391..d66cbb2e 100644 --- a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/FIleBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/FIleBuilderTest.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.junit.jupiter.api.Test; import org.phenopackets.schema.v2.core.File; diff --git a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/IndividualBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilderTest.java similarity index 91% rename from phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/IndividualBuilderTest.java rename to phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilderTest.java index 2b09f21e..27c1034f 100644 --- a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/IndividualBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilderTest.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import com.google.protobuf.Timestamp; import org.junit.jupiter.api.Test; import org.phenopackets.schema.v2.core.Individual; @@ -7,8 +7,8 @@ import org.phenopackets.schema.v2.core.VitalStatus; import static org.junit.jupiter.api.Assertions.*; -import static org.phenopackets.phenotools.builder.builders.IndividualBuilder.HOMO_SAPIENS; -import static org.phenopackets.phenotools.builder.builders.TimestampBuilder.fromISO8601; +import static org.phenopackets.phenopackettools.builder.builders.IndividualBuilder.HOMO_SAPIENS; +import static org.phenopackets.phenopackettools.builder.builders.TimestampBuilder.fromISO8601; public class IndividualBuilderTest { diff --git a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/MetaDataBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/MetaDataBuilderTest.java similarity index 90% rename from phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/MetaDataBuilderTest.java rename to phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/MetaDataBuilderTest.java index 5cd666aa..d4b42021 100644 --- a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/MetaDataBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/MetaDataBuilderTest.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import org.junit.jupiter.api.Test; import org.phenopackets.schema.v2.core.MetaData; diff --git a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/TimeElementsTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimeElementsTest.java similarity index 93% rename from phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/TimeElementsTest.java rename to phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimeElementsTest.java index 8b1162c8..f16bb59b 100644 --- a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/TimeElementsTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimeElementsTest.java @@ -1,16 +1,16 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import com.google.protobuf.Timestamp; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import org.phenopackets.phenotools.builder.exceptions.PhenotoolsRuntimeException; +import org.phenopackets.phenopackettools.builder.exceptions.PhenotoolsRuntimeException; import org.phenopackets.schema.v2.core.OntologyClass; import org.phenopackets.schema.v2.core.TimeElement; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.phenopackets.phenotools.builder.builders.TimestampBuilder.fromISO8601; +import static org.phenopackets.phenopackettools.builder.builders.TimestampBuilder.fromISO8601; public class TimeElementsTest { diff --git a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/TimeIntervalBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilderTest.java similarity index 95% rename from phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/TimeIntervalBuilderTest.java rename to phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilderTest.java index 0aecb11b..9e5c9315 100644 --- a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/TimeIntervalBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilderTest.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import com.google.protobuf.Timestamp; import org.junit.jupiter.api.Test; diff --git a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/TimestampBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimestampBuilderTest.java similarity index 92% rename from phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/TimestampBuilderTest.java rename to phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimestampBuilderTest.java index 9af79f20..2002dcf5 100644 --- a/phenotools-builder/src/test/java/org/phenopackets/phenotools/builder/builders/TimestampBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimestampBuilderTest.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.builder.builders; +package org.phenopackets.phenopackettools.builder.builders; import com.google.protobuf.Timestamp; import com.google.protobuf.util.Timestamps; diff --git a/phenotools-cli/pom.xml b/phenopacket-tools-cli/pom.xml similarity index 52% rename from phenotools-cli/pom.xml rename to phenopacket-tools-cli/pom.xml index 0d9887e4..7fe7c7fe 100644 --- a/phenotools-cli/pom.xml +++ b/phenopacket-tools-cli/pom.xml @@ -5,67 +5,42 @@ 4.0.0 - org.phenopackets.phenotools - phenotools + org.phenopackets.phenopackettools + phenopacket-tools 1.0.0 - phenotools-cli + phenopacket-tools-cli - phenotools-cli + phenopacket-tools-cli Command-line utility for phenopacket-tools - org.phenopackets.phenotools - phenotools-builder + org.phenopackets.phenopackettools + phenopacket-tools-builder ${project.parent.version} - org.phenopackets.phenotools - phenotools-converter + org.phenopackets.phenopackettools + phenopacket-tools-converter ${project.parent.version} - info.picocli - picocli - 4.6.3 - - - org.phenopackets.phenotools - phenotools-validator-core + org.phenopackets.phenopackettools + phenopacket-tools-validator-jsonschema ${project.parent.version} compile - org.phenopackets.phenotools - phenotools-validator-jsonschema - ${project.parent.version} - compile + info.picocli + picocli + 4.6.3 ch.qos.logback logback-classic - - com.fasterxml.jackson - jackson-bom - 2.13.2 - import - pom - - - com.fasterxml.jackson.core - jackson-databind - 2.13.2 - test - - - com.fasterxml.jackson.dataformat - jackson-dataformat-yaml - 2.13.2 - test - com.fasterxml.jackson.core jackson-databind @@ -81,7 +56,6 @@ org.springframework.boot spring-boot-maven-plugin - 2.6.4 diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/Main.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/Main.java similarity index 92% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/Main.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/Main.java index 8b5dea73..e20959cf 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/Main.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/Main.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools; +package org.phenopackets.phenopackettools; import picocli.CommandLine; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/PhenopacketTools.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/PhenopacketTools.java similarity index 66% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/PhenopacketTools.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/PhenopacketTools.java index c38a5f69..91651c51 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/PhenopacketTools.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/PhenopacketTools.java @@ -1,8 +1,8 @@ -package org.phenopackets.phenotools; +package org.phenopackets.phenopackettools; -import org.phenopackets.phenotools.command.ConvertCommand; -import org.phenopackets.phenotools.command.ExamplesCommand; -import org.phenopackets.phenotools.command.ValidateCommand; +import org.phenopackets.phenopackettools.command.ConvertCommand; +import org.phenopackets.phenopackettools.command.ExamplesCommand; +import org.phenopackets.phenopackettools.command.ValidateCommand; import picocli.AutoComplete; import static picocli.CommandLine.*; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/command/ConvertCommand.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ConvertCommand.java similarity index 96% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/command/ConvertCommand.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ConvertCommand.java index f5d0fe1f..4b82b46e 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/command/ConvertCommand.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ConvertCommand.java @@ -1,8 +1,8 @@ -package org.phenopackets.phenotools.command; +package org.phenopackets.phenopackettools.command; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.util.JsonFormat; -import org.phenopackets.phenotools.converter.converters.PhenopacketConverter; +import org.phenopackets.phenopackettools.converter.converters.PhenopacketConverter; import org.phenopackets.schema.v2.Phenopacket; import picocli.CommandLine.Command; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/command/ExamplesCommand.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java similarity index 93% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/command/ExamplesCommand.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java index 1965f222..08f039ae 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/command/ExamplesCommand.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.command; +package org.phenopackets.phenopackettools.command; @@ -10,10 +10,10 @@ import com.google.protobuf.Message; import com.google.protobuf.util.JsonFormat; -import org.phenopackets.phenotools.builder.exceptions.PhenotoolsRuntimeException; -import org.phenopackets.phenotools.examples.FamilyWithPedigree; -import org.phenopackets.phenotools.examples.PhenopacketExamples; -import org.phenopackets.phenotools.examples.WarburgMicroSyndrome; +import org.phenopackets.phenopackettools.builder.exceptions.PhenotoolsRuntimeException; +import org.phenopackets.phenopackettools.examples.FamilyWithPedigree; +import org.phenopackets.phenopackettools.examples.PhenopacketExamples; +import org.phenopackets.phenopackettools.examples.WarburgMicroSyndrome; import picocli.CommandLine; import picocli.CommandLine.Command; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/command/ValidateCommand.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ValidateCommand.java similarity index 83% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/command/ValidateCommand.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ValidateCommand.java index ce1ebcbc..e82cd644 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/command/ValidateCommand.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ValidateCommand.java @@ -1,11 +1,11 @@ -package org.phenopackets.phenotools.command; +package org.phenopackets.phenopackettools.command; -import org.phenopackets.phenotools.validator.core.PhenopacketValidatorFactory; -import org.phenopackets.phenotools.validator.core.ValidationItem; -import org.phenopackets.phenotools.validator.core.ValidatorInfo; -import org.phenopackets.phenotools.validator.core.ValidatorRunner; -import org.phenopackets.phenotools.validator.jsonschema.ClasspathJsonSchemaValidatorFactory; +import org.phenopackets.phenopackettools.validator.core.PhenopacketValidatorFactory; +import org.phenopackets.phenopackettools.validator.core.ValidationItem; +import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; +import org.phenopackets.phenopackettools.validator.core.ValidatorRunner; +import org.phenopackets.phenopackettools.validator.jsonschema.ClasspathJsonSchemaValidatorFactory; import picocli.CommandLine.Command; import picocli.CommandLine.Option; import picocli.CommandLine.Parameters; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/BethlehamMyopathy.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/BethlehamMyopathy.java similarity index 93% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/BethlehamMyopathy.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/BethlehamMyopathy.java index c66ee81a..785b8745 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/BethlehamMyopathy.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/BethlehamMyopathy.java @@ -1,12 +1,12 @@ -package org.phenopackets.phenotools.examples; +package org.phenopackets.phenopackettools.examples; -import org.phenopackets.phenotools.builder.PhenopacketBuilder; -import org.phenopackets.phenotools.builder.builders.*; -import org.phenopackets.phenotools.builder.constants.Status; +import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; +import org.phenopackets.phenopackettools.builder.builders.*; +import org.phenopackets.phenopackettools.builder.constants.Status; import org.phenopackets.schema.v2.Phenopacket; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; class BethlehamMyopathy implements PhenopacketExample { private static final String PHENOPACKET_ID = "arbitrary proband id"; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Covid.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Covid.java similarity index 97% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Covid.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Covid.java index 65bee335..b0c67f83 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Covid.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Covid.java @@ -1,14 +1,14 @@ -package org.phenopackets.phenotools.examples; +package org.phenopackets.phenopackettools.examples; -import org.phenopackets.phenotools.builder.PhenopacketBuilder; -import org.phenopackets.phenotools.builder.builders.*; +import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; +import org.phenopackets.phenopackettools.builder.builders.*; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; import java.util.ArrayList; import java.util.List; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; class Covid implements PhenopacketExample { diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/FamilyWithPedigree.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/FamilyWithPedigree.java similarity index 93% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/FamilyWithPedigree.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/FamilyWithPedigree.java index e5e250f6..b00d2ca8 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/FamilyWithPedigree.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/FamilyWithPedigree.java @@ -1,9 +1,9 @@ -package org.phenopackets.phenotools.examples; +package org.phenopackets.phenopackettools.examples; -import org.phenopackets.phenotools.builder.FamilyBuilder; -import org.phenopackets.phenotools.builder.PhenopacketBuilder; -import org.phenopackets.phenotools.builder.builders.*; +import org.phenopackets.phenopackettools.builder.FamilyBuilder; +import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; +import org.phenopackets.phenopackettools.builder.builders.*; import org.phenopackets.schema.v2.Family; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Marfan.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Marfan.java similarity index 87% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Marfan.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Marfan.java index aa419890..ffe55020 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Marfan.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Marfan.java @@ -1,10 +1,10 @@ -package org.phenopackets.phenotools.examples; +package org.phenopackets.phenopackettools.examples; -import org.phenopackets.phenotools.builder.PhenopacketBuilder; -import org.phenopackets.phenotools.builder.builders.*; +import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; +import org.phenopackets.phenopackettools.builder.builders.*; import org.phenopackets.schema.v2.Phenopacket; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; class Marfan implements PhenopacketExample { diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/NemalineMyopathyPrenatal.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/NemalineMyopathyPrenatal.java similarity index 94% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/NemalineMyopathyPrenatal.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/NemalineMyopathyPrenatal.java index 126ba77d..aa934690 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/NemalineMyopathyPrenatal.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/NemalineMyopathyPrenatal.java @@ -1,18 +1,18 @@ -package org.phenopackets.phenotools.examples; +package org.phenopackets.phenopackettools.examples; import org.ga4gh.vrs.v1.Variation; import org.ga4gh.vrsatile.v1.Expression; import org.ga4gh.vrsatile.v1.GeneDescriptor; -import org.phenopackets.phenotools.builder.PhenopacketBuilder; -import org.phenopackets.phenotools.builder.builders.*; +import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; +import org.phenopackets.phenopackettools.builder.builders.*; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; import java.util.List; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; -import static org.phenopackets.phenotools.builder.builders.PhenotypicFeatureBuilder.phenotypicFeature; -import static org.phenopackets.phenotools.builder.builders.TimeElements.gestationalAge; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.PhenotypicFeatureBuilder.phenotypicFeature; +import static org.phenopackets.phenopackettools.builder.builders.TimeElements.gestationalAge; /** * From Clin. Exp. Obstet. Gynecol. - ISSN: 0390-6663 diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/PhenopacketExample.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/PhenopacketExample.java similarity index 69% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/PhenopacketExample.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/PhenopacketExample.java index d020b68f..bef790d8 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/PhenopacketExample.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/PhenopacketExample.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.examples; +package org.phenopackets.phenopackettools.examples; import org.phenopackets.schema.v2.Phenopacket; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/PhenopacketExamples.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/PhenopacketExamples.java similarity index 97% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/PhenopacketExamples.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/PhenopacketExamples.java index 3d9de639..8ef52ddf 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/PhenopacketExamples.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/PhenopacketExamples.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.examples; +package org.phenopackets.phenopackettools.examples; import org.phenopackets.schema.v2.Phenopacket; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Retinoblastoma.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java similarity index 97% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Retinoblastoma.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java index 9b6b0d48..d11fff8a 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Retinoblastoma.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java @@ -1,15 +1,15 @@ -package org.phenopackets.phenotools.examples; +package org.phenopackets.phenopackettools.examples; -import org.phenopackets.phenotools.builder.PhenopacketBuilder; -import org.phenopackets.phenotools.builder.builders.*; -import org.phenopackets.phenotools.builder.constants.Laterality; -import org.phenopackets.phenotools.builder.constants.Unit; +import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; +import org.phenopackets.phenopackettools.builder.builders.*; +import org.phenopackets.phenopackettools.builder.constants.Laterality; +import org.phenopackets.phenopackettools.builder.constants.Unit; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; import java.util.List; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; public class Retinoblastoma implements PhenopacketExample { private static final String PHENOPACKET_ID = "arbitrary.id"; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/SquamousCellCancer.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SquamousCellCancer.java similarity index 92% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/SquamousCellCancer.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SquamousCellCancer.java index 7915ff4b..8626dc28 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/SquamousCellCancer.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SquamousCellCancer.java @@ -1,12 +1,12 @@ -package org.phenopackets.phenotools.examples; +package org.phenopackets.phenopackettools.examples; -import org.phenopackets.phenotools.builder.PhenopacketBuilder; -import org.phenopackets.phenotools.builder.builders.*; +import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; +import org.phenopackets.phenopackettools.builder.builders.*; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.Individual; import org.phenopackets.schema.v2.core.OntologyClass; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; class SquamousCellCancer implements PhenopacketExample { private static final String PHENOPACKET_ID = "arbitrary.id"; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Thrombocytopenia2.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Thrombocytopenia2.java similarity index 89% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Thrombocytopenia2.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Thrombocytopenia2.java index 44e4a917..ba0d8e0d 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/Thrombocytopenia2.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Thrombocytopenia2.java @@ -1,11 +1,11 @@ -package org.phenopackets.phenotools.examples; +package org.phenopackets.phenopackettools.examples; -import org.phenopackets.phenotools.builder.PhenopacketBuilder; -import org.phenopackets.phenotools.builder.builders.*; -import org.phenopackets.phenotools.builder.constants.Status; +import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; +import org.phenopackets.phenopackettools.builder.builders.*; +import org.phenopackets.phenopackettools.builder.constants.Status; import org.phenopackets.schema.v2.Phenopacket; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; class Thrombocytopenia2 implements PhenopacketExample { private static final String PHENOPACKET_ID = "id-C"; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/UrothelialCancer.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/UrothelialCancer.java similarity index 95% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/UrothelialCancer.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/UrothelialCancer.java index d7211829..5f9e0cc0 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/UrothelialCancer.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/UrothelialCancer.java @@ -1,13 +1,13 @@ -package org.phenopackets.phenotools.examples; +package org.phenopackets.phenopackettools.examples; -import org.phenopackets.phenotools.builder.PhenopacketBuilder; -import org.phenopackets.phenotools.builder.builders.*; -import org.phenopackets.phenotools.builder.constants.Severity; +import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; +import org.phenopackets.phenopackettools.builder.builders.*; +import org.phenopackets.phenopackettools.builder.constants.Severity; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; class UrothelialCancer implements PhenopacketExample { private static final String PHENOPACKET_ID = "arbitrary.id"; diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/WarburgMicroSyndrome.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/WarburgMicroSyndrome.java similarity index 92% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/WarburgMicroSyndrome.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/WarburgMicroSyndrome.java index 7b630ed9..ba45b25f 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/WarburgMicroSyndrome.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/WarburgMicroSyndrome.java @@ -1,14 +1,14 @@ -package org.phenopackets.phenotools.examples; +package org.phenopackets.phenopackettools.examples; -import org.phenopackets.phenotools.builder.PhenopacketBuilder; -import org.phenopackets.phenotools.builder.builders.*; +import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; +import org.phenopackets.phenopackettools.builder.builders.*; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; import java.util.ArrayList; import java.util.List; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; /** * Léonard A, et al. Prenatal diagnosis of fetal cataract: case report and review of the literature. diff --git a/phenotools-cli/src/main/resources/logback.xml b/phenopacket-tools-cli/src/main/resources/logback.xml similarity index 100% rename from phenotools-cli/src/main/resources/logback.xml rename to phenopacket-tools-cli/src/main/resources/logback.xml diff --git a/phenotools-converter/pom.xml b/phenopacket-tools-converter/pom.xml similarity index 83% rename from phenotools-converter/pom.xml rename to phenopacket-tools-converter/pom.xml index 760cfb89..bdc3f39b 100644 --- a/phenotools-converter/pom.xml +++ b/phenopacket-tools-converter/pom.xml @@ -5,12 +5,12 @@ 4.0.0 - org.phenopackets.phenotools - phenotools + org.phenopackets.phenopackettools + phenopacket-tools 1.0.0 - phenotools-converter + phenopacket-tools-converter diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/CohortConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/CohortConverter.java similarity index 70% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/CohortConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/CohortConverter.java index f54f9bae..15613e88 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/CohortConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/CohortConverter.java @@ -1,10 +1,10 @@ -package org.phenopackets.phenotools.converter.converters; +package org.phenopackets.phenopackettools.converter.converters; import org.phenopackets.schema.v2.Cohort; -import static org.phenopackets.phenotools.converter.converters.PhenopacketConverter.toV2Phenopackets; -import static org.phenopackets.phenotools.converter.converters.v2.FileConverter.toFiles; -import static org.phenopackets.phenotools.converter.converters.v2.MetaDataConverter.toMetaData; +import static org.phenopackets.phenopackettools.converter.converters.PhenopacketConverter.toV2Phenopackets; +import static org.phenopackets.phenopackettools.converter.converters.v2.FileConverter.toFiles; +import static org.phenopackets.phenopackettools.converter.converters.v2.MetaDataConverter.toMetaData; public class CohortConverter { diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/FamilyConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/FamilyConverter.java similarity index 63% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/FamilyConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/FamilyConverter.java index a41f0a4f..d1c66c99 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/FamilyConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/FamilyConverter.java @@ -1,12 +1,12 @@ -package org.phenopackets.phenotools.converter.converters; +package org.phenopackets.phenopackettools.converter.converters; import org.phenopackets.schema.v2.Family; -import static org.phenopackets.phenotools.converter.converters.PhenopacketConverter.toV2Phenopacket; -import static org.phenopackets.phenotools.converter.converters.PhenopacketConverter.toV2Phenopackets; -import static org.phenopackets.phenotools.converter.converters.v2.FileConverter.toFiles; -import static org.phenopackets.phenotools.converter.converters.v2.MetaDataConverter.toMetaData; -import static org.phenopackets.phenotools.converter.converters.v2.PedigreeConverter.toPedigree; +import static org.phenopackets.phenopackettools.converter.converters.PhenopacketConverter.toV2Phenopacket; +import static org.phenopackets.phenopackettools.converter.converters.PhenopacketConverter.toV2Phenopackets; +import static org.phenopackets.phenopackettools.converter.converters.v2.FileConverter.toFiles; +import static org.phenopackets.phenopackettools.converter.converters.v2.MetaDataConverter.toMetaData; +import static org.phenopackets.phenopackettools.converter.converters.v2.PedigreeConverter.toPedigree; public class FamilyConverter { diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/PhenopacketConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/PhenopacketConverter.java similarity index 70% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/PhenopacketConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/PhenopacketConverter.java index 64701c3c..45017aeb 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/PhenopacketConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/PhenopacketConverter.java @@ -1,16 +1,16 @@ -package org.phenopackets.phenotools.converter.converters; +package org.phenopackets.phenopackettools.converter.converters; import org.phenopackets.schema.v2.Phenopacket; import java.util.List; import java.util.stream.Collectors; -import static org.phenopackets.phenotools.converter.converters.v2.BiosampleConverter.toBiosamples; -import static org.phenopackets.phenotools.converter.converters.v2.DiseaseConverter.toDiseases; -import static org.phenopackets.phenotools.converter.converters.v2.FileConverter.toFiles; -import static org.phenopackets.phenotools.converter.converters.v2.IndividualConverter.toIndividual; -import static org.phenopackets.phenotools.converter.converters.v2.MetaDataConverter.toMetaData; -import static org.phenopackets.phenotools.converter.converters.v2.PhenotypicFeatureConverter.toPhenotypicFeatures; +import static org.phenopackets.phenopackettools.converter.converters.v2.BiosampleConverter.toBiosamples; +import static org.phenopackets.phenopackettools.converter.converters.v2.DiseaseConverter.toDiseases; +import static org.phenopackets.phenopackettools.converter.converters.v2.FileConverter.toFiles; +import static org.phenopackets.phenopackettools.converter.converters.v2.IndividualConverter.toIndividual; +import static org.phenopackets.phenopackettools.converter.converters.v2.MetaDataConverter.toMetaData; +import static org.phenopackets.phenopackettools.converter.converters.v2.PhenotypicFeatureConverter.toPhenotypicFeatures; public class PhenopacketConverter { diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/AgeConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/AgeConverter.java similarity index 89% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/AgeConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/AgeConverter.java index dfde86cc..fc07233b 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/AgeConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/AgeConverter.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.converter.converters.v2; +package org.phenopackets.phenopackettools.converter.converters.v2; import org.phenopackets.schema.v2.core.Age; import org.phenopackets.schema.v2.core.AgeRange; diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/BiosampleConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/BiosampleConverter.java similarity index 85% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/BiosampleConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/BiosampleConverter.java index 82f81ee3..ec675f08 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/BiosampleConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/BiosampleConverter.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.converter.converters.v2; +package org.phenopackets.phenopackettools.converter.converters.v2; import org.phenopackets.schema.v2.core.Biosample; import org.phenopackets.schema.v2.core.OntologyClass; @@ -7,11 +7,11 @@ import java.util.List; import java.util.stream.Collectors; -import static org.phenopackets.phenotools.converter.converters.v2.FileConverter.toFiles; -import static org.phenopackets.phenotools.converter.converters.v2.OntologyClassConverter.toOntologyClass; -import static org.phenopackets.phenotools.converter.converters.v2.OntologyClassConverter.toOntologyClassList; -import static org.phenopackets.phenotools.converter.converters.v2.PhenotypicFeatureConverter.*; -import static org.phenopackets.phenotools.converter.converters.v2.ProcedureConverter.toProcedure; +import static org.phenopackets.phenopackettools.converter.converters.v2.FileConverter.toFiles; +import static org.phenopackets.phenopackettools.converter.converters.v2.OntologyClassConverter.toOntologyClass; +import static org.phenopackets.phenopackettools.converter.converters.v2.OntologyClassConverter.toOntologyClassList; +import static org.phenopackets.phenopackettools.converter.converters.v2.PhenotypicFeatureConverter.*; +import static org.phenopackets.phenopackettools.converter.converters.v2.ProcedureConverter.toProcedure; public class BiosampleConverter { diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/DiseaseConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/DiseaseConverter.java similarity index 81% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/DiseaseConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/DiseaseConverter.java index 82a9717a..54b61d40 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/DiseaseConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/DiseaseConverter.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.converter.converters.v2; +package org.phenopackets.phenopackettools.converter.converters.v2; import org.phenopackets.schema.v2.core.Disease; import org.phenopackets.schema.v2.core.TimeElement; @@ -6,9 +6,9 @@ import java.util.List; import java.util.stream.Collectors; -import static org.phenopackets.phenotools.converter.converters.v2.AgeConverter.toAge; -import static org.phenopackets.phenotools.converter.converters.v2.AgeConverter.toAgeRange; -import static org.phenopackets.phenotools.converter.converters.v2.OntologyClassConverter.*; +import static org.phenopackets.phenopackettools.converter.converters.v2.AgeConverter.toAge; +import static org.phenopackets.phenopackettools.converter.converters.v2.AgeConverter.toAgeRange; +import static org.phenopackets.phenopackettools.converter.converters.v2.OntologyClassConverter.*; public class DiseaseConverter { diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/EvidenceConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/EvidenceConverter.java similarity index 74% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/EvidenceConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/EvidenceConverter.java index bb757d71..6aafb9fa 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/EvidenceConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/EvidenceConverter.java @@ -1,12 +1,12 @@ -package org.phenopackets.phenotools.converter.converters.v2; +package org.phenopackets.phenopackettools.converter.converters.v2; import org.phenopackets.schema.v2.core.Evidence; import java.util.List; import java.util.stream.Collectors; -import static org.phenopackets.phenotools.converter.converters.v2.ExternalReferenceConverter.toExternalReference; -import static org.phenopackets.phenotools.converter.converters.v2.OntologyClassConverter.toOntologyClass; +import static org.phenopackets.phenopackettools.converter.converters.v2.ExternalReferenceConverter.toExternalReference; +import static org.phenopackets.phenopackettools.converter.converters.v2.OntologyClassConverter.toOntologyClass; public class EvidenceConverter { diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/ExternalReferenceConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/ExternalReferenceConverter.java similarity index 94% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/ExternalReferenceConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/ExternalReferenceConverter.java index 53f9b3e4..2b7b6ba8 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/ExternalReferenceConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/ExternalReferenceConverter.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.converter.converters.v2; +package org.phenopackets.phenopackettools.converter.converters.v2; import org.phenopackets.schema.v2.core.ExternalReference; diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/FileConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/FileConverter.java similarity index 93% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/FileConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/FileConverter.java index 7fa211e7..8ccb90ec 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/FileConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/FileConverter.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.converter.converters.v2; +package org.phenopackets.phenopackettools.converter.converters.v2; import org.phenopackets.schema.v1.core.HtsFile; import org.phenopackets.schema.v2.core.File; diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/IndividualConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/IndividualConverter.java similarity index 88% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/IndividualConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/IndividualConverter.java index 8ee5e4ea..b78595e3 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/IndividualConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/IndividualConverter.java @@ -1,13 +1,13 @@ -package org.phenopackets.phenotools.converter.converters.v2; +package org.phenopackets.phenopackettools.converter.converters.v2; import org.phenopackets.schema.v2.core.Individual; import org.phenopackets.schema.v2.core.KaryotypicSex; import org.phenopackets.schema.v2.core.Sex; import org.phenopackets.schema.v2.core.TimeElement; -import static org.phenopackets.phenotools.converter.converters.v2.AgeConverter.toAge; -import static org.phenopackets.phenotools.converter.converters.v2.AgeConverter.toAgeRange; -import static org.phenopackets.phenotools.converter.converters.v2.OntologyClassConverter.toOntologyClass; +import static org.phenopackets.phenopackettools.converter.converters.v2.AgeConverter.toAge; +import static org.phenopackets.phenopackettools.converter.converters.v2.AgeConverter.toAgeRange; +import static org.phenopackets.phenopackettools.converter.converters.v2.OntologyClassConverter.toOntologyClass; public class IndividualConverter { diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/MetaDataConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/MetaDataConverter.java similarity index 82% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/MetaDataConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/MetaDataConverter.java index d56e15f5..89d1dc1f 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/MetaDataConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/MetaDataConverter.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.converter.converters.v2; +package org.phenopackets.phenopackettools.converter.converters.v2; import org.phenopackets.schema.v2.core.MetaData; import org.phenopackets.schema.v2.core.Update; @@ -6,8 +6,8 @@ import java.util.List; import java.util.stream.Collectors; -import static org.phenopackets.phenotools.converter.converters.v2.ExternalReferenceConverter.toExternalReferences; -import static org.phenopackets.phenotools.converter.converters.v2.ResourceConverter.toResources; +import static org.phenopackets.phenopackettools.converter.converters.v2.ExternalReferenceConverter.toExternalReferences; +import static org.phenopackets.phenopackettools.converter.converters.v2.ResourceConverter.toResources; public class MetaDataConverter { diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/OntologyClassConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/OntologyClassConverter.java similarity index 93% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/OntologyClassConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/OntologyClassConverter.java index 91b62a78..cfa36290 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/OntologyClassConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/OntologyClassConverter.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.converter.converters.v2; +package org.phenopackets.phenopackettools.converter.converters.v2; import org.phenopackets.schema.v2.core.OntologyClass; diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/PedigreeConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/PedigreeConverter.java similarity index 92% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/PedigreeConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/PedigreeConverter.java index b8e8f471..fefc12fa 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/PedigreeConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/PedigreeConverter.java @@ -1,11 +1,11 @@ -package org.phenopackets.phenotools.converter.converters.v2; +package org.phenopackets.phenopackettools.converter.converters.v2; import org.phenopackets.schema.v2.core.Pedigree; import java.util.List; import java.util.stream.Collectors; -import static org.phenopackets.phenotools.converter.converters.v2.IndividualConverter.toSex; +import static org.phenopackets.phenopackettools.converter.converters.v2.IndividualConverter.toSex; public class PedigreeConverter { diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/PhenotypicFeatureConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/PhenotypicFeatureConverter.java similarity index 82% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/PhenotypicFeatureConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/PhenotypicFeatureConverter.java index 0f2f2780..eae73185 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/PhenotypicFeatureConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/PhenotypicFeatureConverter.java @@ -1,15 +1,15 @@ -package org.phenopackets.phenotools.converter.converters.v2; +package org.phenopackets.phenopackettools.converter.converters.v2; import org.phenopackets.schema.v2.core.*; import java.util.List; import java.util.stream.Collectors; -import static org.phenopackets.phenotools.converter.converters.v2.AgeConverter.toAge; -import static org.phenopackets.phenotools.converter.converters.v2.AgeConverter.toAgeRange; -import static org.phenopackets.phenotools.converter.converters.v2.EvidenceConverter.toEvidences; -import static org.phenopackets.phenotools.converter.converters.v2.OntologyClassConverter.toOntologyClass; -import static org.phenopackets.phenotools.converter.converters.v2.OntologyClassConverter.toOntologyClassList; +import static org.phenopackets.phenopackettools.converter.converters.v2.AgeConverter.toAge; +import static org.phenopackets.phenopackettools.converter.converters.v2.AgeConverter.toAgeRange; +import static org.phenopackets.phenopackettools.converter.converters.v2.EvidenceConverter.toEvidences; +import static org.phenopackets.phenopackettools.converter.converters.v2.OntologyClassConverter.toOntologyClass; +import static org.phenopackets.phenopackettools.converter.converters.v2.OntologyClassConverter.toOntologyClassList; public class PhenotypicFeatureConverter { diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/ProcedureConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/ProcedureConverter.java similarity index 79% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/ProcedureConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/ProcedureConverter.java index 55c9b5ad..efe6aa89 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/ProcedureConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/ProcedureConverter.java @@ -1,8 +1,8 @@ -package org.phenopackets.phenotools.converter.converters.v2; +package org.phenopackets.phenopackettools.converter.converters.v2; import org.phenopackets.schema.v2.core.Procedure; -import static org.phenopackets.phenotools.converter.converters.v2.OntologyClassConverter.toOntologyClass; +import static org.phenopackets.phenopackettools.converter.converters.v2.OntologyClassConverter.toOntologyClass; public class ProcedureConverter { diff --git a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/ResourceConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/ResourceConverter.java similarity index 92% rename from phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/ResourceConverter.java rename to phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/ResourceConverter.java index 2143bbdc..9df11e55 100644 --- a/phenotools-converter/src/main/java/org/phenopackets/phenotools/converter/converters/v2/ResourceConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/ResourceConverter.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.converter.converters.v2; +package org.phenopackets.phenopackettools.converter.converters.v2; import org.phenopackets.schema.v2.core.Resource; diff --git a/phenotools-converter/src/test/java/org/phenopackets/phenotools/converter/BethlemMyopathyV1.java b/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/BethlemMyopathyV1.java similarity index 99% rename from phenotools-converter/src/test/java/org/phenopackets/phenotools/converter/BethlemMyopathyV1.java rename to phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/BethlemMyopathyV1.java index 36bb8d0a..5a1c5375 100644 --- a/phenotools-converter/src/test/java/org/phenopackets/phenotools/converter/BethlemMyopathyV1.java +++ b/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/BethlemMyopathyV1.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.converter; +package org.phenopackets.phenopackettools.converter; import com.google.protobuf.Timestamp; import org.phenopackets.schema.v1.Phenopacket; diff --git a/phenotools-converter/src/test/java/org/phenopackets/phenotools/converter/PhenopacketConverterTest.java b/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java similarity index 61% rename from phenotools-converter/src/test/java/org/phenopackets/phenotools/converter/PhenopacketConverterTest.java rename to phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java index d093a52d..44f63d7e 100644 --- a/phenotools-converter/src/test/java/org/phenopackets/phenotools/converter/PhenopacketConverterTest.java +++ b/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java @@ -1,9 +1,9 @@ -package org.phenopackets.phenotools.converter; +package org.phenopackets.phenopackettools.converter; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.util.JsonFormat; import org.junit.jupiter.api.Test; -import org.phenopackets.phenotools.converter.converters.PhenopacketConverter; +import org.phenopackets.phenopackettools.converter.converters.PhenopacketConverter; class PhenopacketConverterTest { @@ -13,7 +13,7 @@ void name() throws InvalidProtocolBufferException { org.phenopackets.schema.v2.Phenopacket v2Phenopacket = PhenopacketConverter.toV2Phenopacket(v1Phenopacket); - System.out.println(JsonFormat.printer().print(v1Phenopacket)); - System.out.println(JsonFormat.printer().print(v2Phenopacket)); +// System.out.println(JsonFormat.printer().print(v1Phenopacket)); +// System.out.println(JsonFormat.printer().print(v2Phenopacket)); } } \ No newline at end of file diff --git a/phenotools-validator-core/.mvn/wrapper/maven-wrapper.properties b/phenopacket-tools-validator-core/.mvn/wrapper/maven-wrapper.properties similarity index 100% rename from phenotools-validator-core/.mvn/wrapper/maven-wrapper.properties rename to phenopacket-tools-validator-core/.mvn/wrapper/maven-wrapper.properties diff --git a/phenotools-validator-core/mvnw b/phenopacket-tools-validator-core/mvnw similarity index 100% rename from phenotools-validator-core/mvnw rename to phenopacket-tools-validator-core/mvnw diff --git a/phenotools-validator-core/mvnw.cmd b/phenopacket-tools-validator-core/mvnw.cmd similarity index 100% rename from phenotools-validator-core/mvnw.cmd rename to phenopacket-tools-validator-core/mvnw.cmd diff --git a/phenotools-validator-core/pom.xml b/phenopacket-tools-validator-core/pom.xml similarity index 66% rename from phenotools-validator-core/pom.xml rename to phenopacket-tools-validator-core/pom.xml index d524474c..77457cb5 100644 --- a/phenotools-validator-core/pom.xml +++ b/phenopacket-tools-validator-core/pom.xml @@ -5,14 +5,14 @@ 4.0.0 - org.phenopackets.phenotools - phenotools + org.phenopackets.phenopackettools + phenopacket-tools 1.0.0 - phenotools-validator-core + phenopacket-tools-validator-core - phenotools-validator-core + phenopacket-tools-validator-core Validator utilities for phenopackets \ No newline at end of file diff --git a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/DefaultValidationInfo.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidationInfo.java similarity index 96% rename from phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/DefaultValidationInfo.java rename to phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidationInfo.java index 6db64beb..6ca82b34 100644 --- a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/DefaultValidationInfo.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidationInfo.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.validator.core; +package org.phenopackets.phenopackettools.validator.core; import java.util.Objects; diff --git a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ErrorType.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ErrorType.java similarity index 88% rename from phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ErrorType.java rename to phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ErrorType.java index dbc06a51..bf87300c 100644 --- a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ErrorType.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ErrorType.java @@ -1,6 +1,6 @@ -package org.phenopackets.phenotools.validator.core; +package org.phenopackets.phenopackettools.validator.core; -import org.phenopackets.phenotools.validator.core.except.PhenopacketValidatorRuntimeException; +import org.phenopackets.phenopackettools.validator.core.except.PhenopacketValidatorRuntimeException; public enum ErrorType { /** JSON schema error meaning that the JSON code contained a property not present in the schema. */ diff --git a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidator.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidator.java similarity index 94% rename from phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidator.java rename to phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidator.java index 6be6b4c7..1b6fe42a 100644 --- a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidator.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidator.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.validator.core; +package org.phenopackets.phenopackettools.validator.core; import java.io.ByteArrayInputStream; import java.io.File; diff --git a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidatorFactory.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidatorFactory.java similarity index 85% rename from phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidatorFactory.java rename to phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidatorFactory.java index 7664fae0..1eb427e7 100644 --- a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/PhenopacketValidatorFactory.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidatorFactory.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.validator.core; +package org.phenopackets.phenopackettools.validator.core; import java.util.Optional; diff --git a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidationAspect.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationAspect.java similarity index 86% rename from phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidationAspect.java rename to phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationAspect.java index 75034e5b..122594f7 100644 --- a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidationAspect.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationAspect.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.validator.core; +package org.phenopackets.phenopackettools.validator.core; public enum ValidationAspect { diff --git a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidationItem.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationItem.java similarity index 90% rename from phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidationItem.java rename to phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationItem.java index 73361c60..b076eb8f 100644 --- a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidationItem.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationItem.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.validator.core; +package org.phenopackets.phenopackettools.validator.core; /** * The interface represents a single issue found during validation. diff --git a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorInfo.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorInfo.java similarity index 93% rename from phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorInfo.java rename to phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorInfo.java index 66b7e9b2..9beb6b00 100644 --- a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorInfo.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorInfo.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.validator.core; +package org.phenopackets.phenopackettools.validator.core; public interface ValidatorInfo { diff --git a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorRunner.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorRunner.java similarity index 96% rename from phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorRunner.java rename to phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorRunner.java index 9d1f56bf..ed898d25 100644 --- a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/ValidatorRunner.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorRunner.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.validator.core; +package org.phenopackets.phenopackettools.validator.core; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/except/PhenopacketValidatorRuntimeException.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/except/PhenopacketValidatorRuntimeException.java similarity index 91% rename from phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/except/PhenopacketValidatorRuntimeException.java rename to phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/except/PhenopacketValidatorRuntimeException.java index c8168200..663d3e15 100644 --- a/phenotools-validator-core/src/main/java/org/phenopackets/phenotools/validator/core/except/PhenopacketValidatorRuntimeException.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/except/PhenopacketValidatorRuntimeException.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.validator.core.except; +package org.phenopackets.phenopackettools.validator.core.except; public class PhenopacketValidatorRuntimeException extends RuntimeException { diff --git a/phenotools-validator-jsonschema/pom.xml b/phenopacket-tools-validator-jsonschema/pom.xml similarity index 77% rename from phenotools-validator-jsonschema/pom.xml rename to phenopacket-tools-validator-jsonschema/pom.xml index 6d2ffe4a..9c40e153 100644 --- a/phenotools-validator-jsonschema/pom.xml +++ b/phenopacket-tools-validator-jsonschema/pom.xml @@ -5,20 +5,20 @@ 4.0.0 - org.phenopackets.phenotools - phenotools + org.phenopackets.phenopackettools + phenopacket-tools 1.0.0 - phenotools-validator-jsonschema + phenopacket-tools-validator-jsonschema - phenotools-validator-jsonschema + phenopacket-tools-validator-jsonschema JSON schema validator utilities for phenopackets - org.phenopackets.phenotools - phenotools-validator-core + org.phenopackets.phenopackettools + phenopacket-tools-validator-core ${project.parent.version} @@ -46,4 +46,4 @@ - \ No newline at end of file + diff --git a/phenotools-validator-jsonschema/src/main/java/org/phenopackets/phenotools/validator/jsonschema/ClasspathJsonSchemaValidatorFactory.java b/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/ClasspathJsonSchemaValidatorFactory.java similarity index 84% rename from phenotools-validator-jsonschema/src/main/java/org/phenopackets/phenotools/validator/jsonschema/ClasspathJsonSchemaValidatorFactory.java rename to phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/ClasspathJsonSchemaValidatorFactory.java index 042af326..e9d3f21c 100644 --- a/phenotools-validator-jsonschema/src/main/java/org/phenopackets/phenotools/validator/jsonschema/ClasspathJsonSchemaValidatorFactory.java +++ b/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/ClasspathJsonSchemaValidatorFactory.java @@ -1,9 +1,9 @@ -package org.phenopackets.phenotools.validator.jsonschema; +package org.phenopackets.phenopackettools.validator.jsonschema; -import org.phenopackets.phenotools.validator.core.PhenopacketValidator; -import org.phenopackets.phenotools.validator.core.PhenopacketValidatorFactory; -import org.phenopackets.phenotools.validator.core.ValidatorInfo; -import org.phenopackets.phenotools.validator.core.except.PhenopacketValidatorRuntimeException; +import org.phenopackets.phenopackettools.validator.core.PhenopacketValidator; +import org.phenopackets.phenopackettools.validator.core.PhenopacketValidatorFactory; +import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; +import org.phenopackets.phenopackettools.validator.core.except.PhenopacketValidatorRuntimeException; import java.io.InputStream; import java.util.Map; diff --git a/phenotools-validator-jsonschema/src/main/java/org/phenopackets/phenotools/validator/jsonschema/JsonSchemaValidator.java b/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidator.java similarity index 90% rename from phenotools-validator-jsonschema/src/main/java/org/phenopackets/phenotools/validator/jsonschema/JsonSchemaValidator.java rename to phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidator.java index 1679ffd9..004e99e5 100644 --- a/phenotools-validator-jsonschema/src/main/java/org/phenopackets/phenotools/validator/jsonschema/JsonSchemaValidator.java +++ b/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidator.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.validator.jsonschema; +package org.phenopackets.phenopackettools.validator.jsonschema; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -6,10 +6,10 @@ import com.networknt.schema.JsonSchema; import com.networknt.schema.JsonSchemaFactory; import com.networknt.schema.SpecVersion; -import org.phenopackets.phenotools.validator.core.PhenopacketValidator; -import org.phenopackets.phenotools.validator.core.ValidatorInfo; -import org.phenopackets.phenotools.validator.core.except.PhenopacketValidatorRuntimeException; -import org.phenopackets.phenotools.validator.core.ValidationItem; +import org.phenopackets.phenopackettools.validator.core.PhenopacketValidator; +import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; +import org.phenopackets.phenopackettools.validator.core.except.PhenopacketValidatorRuntimeException; +import org.phenopackets.phenopackettools.validator.core.ValidationItem; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/phenotools-validator-jsonschema/src/main/java/org/phenopackets/phenotools/validator/jsonschema/JsonValidationError.java b/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonValidationError.java similarity index 85% rename from phenotools-validator-jsonschema/src/main/java/org/phenopackets/phenotools/validator/jsonschema/JsonValidationError.java rename to phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonValidationError.java index de45c9ac..82ad27da 100644 --- a/phenotools-validator-jsonschema/src/main/java/org/phenopackets/phenotools/validator/jsonschema/JsonValidationError.java +++ b/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonValidationError.java @@ -1,9 +1,9 @@ -package org.phenopackets.phenotools.validator.jsonschema; +package org.phenopackets.phenopackettools.validator.jsonschema; import com.networknt.schema.ValidationMessage; -import org.phenopackets.phenotools.validator.core.ErrorType; -import org.phenopackets.phenotools.validator.core.ValidationItem; -import org.phenopackets.phenotools.validator.core.ValidatorInfo; +import org.phenopackets.phenopackettools.validator.core.ErrorType; +import org.phenopackets.phenopackettools.validator.core.ValidationItem; +import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; import java.util.Objects; diff --git a/phenotools-validator-jsonschema/src/main/resources/schema/hpo-rare-disease-schema.json b/phenopacket-tools-validator-jsonschema/src/main/resources/schema/hpo-rare-disease-schema.json similarity index 100% rename from phenotools-validator-jsonschema/src/main/resources/schema/hpo-rare-disease-schema.json rename to phenopacket-tools-validator-jsonschema/src/main/resources/schema/hpo-rare-disease-schema.json diff --git a/phenotools-validator-jsonschema/src/main/resources/schema/phenopacket-schema-2-0.json b/phenopacket-tools-validator-jsonschema/src/main/resources/schema/phenopacket-schema-2-0.json similarity index 100% rename from phenotools-validator-jsonschema/src/main/resources/schema/phenopacket-schema-2-0.json rename to phenopacket-tools-validator-jsonschema/src/main/resources/schema/phenopacket-schema-2-0.json diff --git a/phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools/validator/jsonschema/JsonSchemaDiseaseValidatorTest.java b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaDiseaseValidatorTest.java similarity index 84% rename from phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools/validator/jsonschema/JsonSchemaDiseaseValidatorTest.java rename to phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaDiseaseValidatorTest.java index 6e7fe83f..93fc037a 100644 --- a/phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools/validator/jsonschema/JsonSchemaDiseaseValidatorTest.java +++ b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaDiseaseValidatorTest.java @@ -1,14 +1,14 @@ -package org.phenopackets.phenotools.validator.jsonschema; +package org.phenopackets.phenopackettools.validator.jsonschema; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.util.JsonFormat; import org.junit.jupiter.api.Test; -import org.phenopackets.phenotools.validator.core.PhenopacketValidator; -import org.phenopackets.phenotools.validator.core.ErrorType; -import org.phenopackets.phenotools.validator.core.ValidationItem; -import org.phenopackets.phenotools.validator.core.ValidatorInfo; -import org.phenopackets.phenotools.validator.testdatagen.PhenopacketUtil; +import org.phenopackets.phenopackettools.validator.core.PhenopacketValidator; +import org.phenopackets.phenopackettools.validator.core.ErrorType; +import org.phenopackets.phenopackettools.validator.core.ValidationItem; +import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; +import org.phenopackets.phenopackettools.validator.testdatagen.PhenopacketUtil; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.Disease; import org.phenopackets.schema.v2.core.MetaData; @@ -19,7 +19,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.phenopackets.phenotools.validator.testdatagen.PhenopacketUtil.*; +import static org.phenopackets.phenopackettools.validator.testdatagen.PhenopacketUtil.*; /** * This class creates a simple phenopacket with a Disease object and creates some variations with @@ -77,9 +77,9 @@ public void testLacksId() throws InvalidProtocolBufferException { // the Phenopacket is not valid if we remove the id Phenopacket p1 = Phenopacket.newBuilder(phenopacket).clearId().build(); String json = JsonFormat.printer().print(p1); - System.out.println(json); +// System.out.println(json); List errors = validator.validate(json); - System.out.println(errors); +// System.out.println(errors); assertEquals(1, errors.size()); ValidationItem error = errors.get(0); assertEquals(ErrorType.JSON_REQUIRED, error.errorType()); diff --git a/phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools/validator/jsonschema/JsonSchemaValidatorTest.java b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidatorTest.java similarity index 88% rename from phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools/validator/jsonschema/JsonSchemaValidatorTest.java rename to phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidatorTest.java index 4732c94c..9ecbc547 100644 --- a/phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools/validator/jsonschema/JsonSchemaValidatorTest.java +++ b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidatorTest.java @@ -1,13 +1,13 @@ -package org.phenopackets.phenotools.validator.jsonschema; +package org.phenopackets.phenopackettools.validator.jsonschema; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import org.phenopackets.phenotools.validator.core.ErrorType; -import org.phenopackets.phenotools.validator.core.PhenopacketValidator; -import org.phenopackets.phenotools.validator.core.ValidationItem; -import org.phenopackets.phenotools.validator.core.ValidatorInfo; -import org.phenopackets.phenotools.validator.testdatagen.RareDiseasePhenopacket; -import org.phenopackets.phenotools.validator.testdatagen.SimplePhenopacket; +import org.phenopackets.phenopackettools.validator.core.ErrorType; +import org.phenopackets.phenopackettools.validator.core.PhenopacketValidator; +import org.phenopackets.phenopackettools.validator.core.ValidationItem; +import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; +import org.phenopackets.phenopackettools.validator.testdatagen.RareDiseasePhenopacket; +import org.phenopackets.phenopackettools.validator.testdatagen.SimplePhenopacket; import org.phenopackets.schema.v2.Phenopacket; import java.io.File; diff --git a/phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools/validator/testdatagen/PhenopacketUtil.java b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/testdatagen/PhenopacketUtil.java similarity index 99% rename from phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools/validator/testdatagen/PhenopacketUtil.java rename to phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/testdatagen/PhenopacketUtil.java index b43009c0..ffe9f473 100644 --- a/phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools/validator/testdatagen/PhenopacketUtil.java +++ b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/testdatagen/PhenopacketUtil.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.validator.testdatagen; +package org.phenopackets.phenopackettools.validator.testdatagen; import java.time.LocalDateTime; diff --git a/phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools/validator/testdatagen/RareDiseasePhenopacket.java b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/testdatagen/RareDiseasePhenopacket.java similarity index 93% rename from phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools/validator/testdatagen/RareDiseasePhenopacket.java rename to phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/testdatagen/RareDiseasePhenopacket.java index 9465c249..00e54ff8 100644 --- a/phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools/validator/testdatagen/RareDiseasePhenopacket.java +++ b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/testdatagen/RareDiseasePhenopacket.java @@ -1,4 +1,4 @@ -package org.phenopackets.phenotools.validator.testdatagen; +package org.phenopackets.phenopackettools.validator.testdatagen; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.File; @@ -6,7 +6,7 @@ import org.phenopackets.schema.v2.core.MetaData; import org.phenopackets.schema.v2.core.Resource; -import static org.phenopackets.phenotools.validator.testdatagen.PhenopacketUtil.*; +import static org.phenopackets.phenopackettools.validator.testdatagen.PhenopacketUtil.*; public class RareDiseasePhenopacket { diff --git a/phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools/validator/testdatagen/SimplePhenopacket.java b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/testdatagen/SimplePhenopacket.java similarity index 83% rename from phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools/validator/testdatagen/SimplePhenopacket.java rename to phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/testdatagen/SimplePhenopacket.java index 068aac3a..c6983130 100644 --- a/phenotools-validator-jsonschema/src/test/java/org/phenopackets/phenotools/validator/testdatagen/SimplePhenopacket.java +++ b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/testdatagen/SimplePhenopacket.java @@ -1,10 +1,10 @@ -package org.phenopackets.phenotools.validator.testdatagen; +package org.phenopackets.phenopackettools.validator.testdatagen; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.MetaData; import org.phenopackets.schema.v2.core.Resource; -import static org.phenopackets.phenotools.validator.testdatagen.PhenopacketUtil.hpoResource; +import static org.phenopackets.phenopackettools.validator.testdatagen.PhenopacketUtil.hpoResource; /** diff --git a/phenotools-validator-jsonschema/src/test/resources/json/bethlehamMyopathyExample.json b/phenopacket-tools-validator-jsonschema/src/test/resources/json/bethlehamMyopathyExample.json similarity index 100% rename from phenotools-validator-jsonschema/src/test/resources/json/bethlehamMyopathyExample.json rename to phenopacket-tools-validator-jsonschema/src/test/resources/json/bethlehamMyopathyExample.json diff --git a/phenotools-validator-jsonschema/src/test/resources/json/bethlehamMyopathyInvalidExample.json b/phenopacket-tools-validator-jsonschema/src/test/resources/json/bethlehamMyopathyInvalidExample.json similarity index 100% rename from phenotools-validator-jsonschema/src/test/resources/json/bethlehamMyopathyInvalidExample.json rename to phenopacket-tools-validator-jsonschema/src/test/resources/json/bethlehamMyopathyInvalidExample.json diff --git a/phenotools-validator-jsonschema/src/test/resources/logback-test.xml b/phenopacket-tools-validator-jsonschema/src/test/resources/logback-test.xml similarity index 100% rename from phenotools-validator-jsonschema/src/test/resources/logback-test.xml rename to phenopacket-tools-validator-jsonschema/src/test/resources/logback-test.xml diff --git a/pom.xml b/pom.xml index ce14ddc2..e963c532 100644 --- a/pom.xml +++ b/pom.xml @@ -4,24 +4,24 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.phenopackets.phenotools - phenotools + org.phenopackets.phenopackettools + phenopacket-tools 1.0.0 pom - phenotools-builder - phenotools-validator-core - phenotools-validator-jsonschema - phenotools-converter - phenotools-cli + phenopacket-tools-builder + phenopacket-tools-validator-core + phenopacket-tools-validator-jsonschema + phenopacket-tools-converter + phenopacket-tools-cli org.springframework.boot spring-boot-starter-parent - 2.5.4 + 2.6.3 @@ -97,7 +97,6 @@ org.springframework.boot spring-boot-maven-plugin - 2.5.4 From c76d892cfeed022c85a539cccf48eb8df7a82fe2 Mon Sep 17 00:00:00 2001 From: Jules Jacobsen Date: Thu, 14 Apr 2022 15:05:23 +0100 Subject: [PATCH 027/155] Update README.md example with new groupId --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 64b84869..23bb96fe 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ The cli application works in a standard UNIX-like manner. ```shell mvn package -alias pfx-tools='java -jar phenotools-cli/target/phenotools-cli-0.0.2-SNAPSHOT.jar' +alias pfx-tools='java -jar phenopacket-tools/phenopacket-tools-cli/target/phenopacket-tools-cli-1.0.0.jar' ``` ### Example Phenopackets From ebff496e58c68356c0b79b42aa45d08fde7d6917 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Thu, 14 Apr 2022 12:02:28 -0400 Subject: [PATCH 028/155] adding constants for SpatialPattern --- .../builder/constants/SpatialPattern.java | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/SpatialPattern.java diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/SpatialPattern.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/SpatialPattern.java new file mode 100644 index 00000000..154425d2 --- /dev/null +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/SpatialPattern.java @@ -0,0 +1,84 @@ +package org.phenopackets.phenopackettools.builder.constants; + +import org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder; +import org.phenopackets.schema.v2.core.OntologyClass; + +public class SpatialPattern { + private static final OntologyClass PREDOMINANT_SMALL_JOINT_LOCALIZATION = OntologyClassBuilder.ontologyClass("HP:0032544", "Predominant small joint localization"); + private static final OntologyClass POLYCYCLIC = OntologyClassBuilder.ontologyClass("HP:0031450", "Polycyclic"); + private static final OntologyClass AXIAL = OntologyClassBuilder.ontologyClass("HP:0025287", "Axial"); + private static final OntologyClass PERILOBULAR = OntologyClassBuilder.ontologyClass("HP:0033813", "Perilobular"); + private static final OntologyClass PARASEPTAL = OntologyClassBuilder.ontologyClass("HP:0033814", "Paraseptal"); + private static final OntologyClass BRONCHOCENTRIC = OntologyClassBuilder.ontologyClass("HP:0033815", "Bronchocentric"); + private static final OntologyClass CENTRILOBULAR = OntologyClassBuilder.ontologyClass("HP:0033816", "Centrilobular"); + private static final OntologyClass MILIARY = OntologyClassBuilder.ontologyClass("HP:0033817", "Miliary"); + private static final OntologyClass GENERALIZED = OntologyClassBuilder.ontologyClass("HP:0012837", "Generalized"); + private static final OntologyClass PERILYMPHATIC = OntologyClassBuilder.ontologyClass("HP:0033819", "Perilymphatic"); + private static final OntologyClass LOCALIZED = OntologyClassBuilder.ontologyClass("HP:0012838", "Localized"); + private static final OntologyClass RETICULAR = OntologyClassBuilder.ontologyClass("HP:0033818", "Reticular"); + private static final OntologyClass DISTAL = OntologyClassBuilder.ontologyClass("HP:0012839", "Distal"); + private static final OntologyClass CERVICAL_NECK = OntologyClassBuilder.ontologyClass("HP:0032535", "Cervical (neck)"); + private static final OntologyClass CENTRAL = OntologyClassBuilder.ontologyClass("HP:0030645", "Central"); + private static final OntologyClass UPPER_BODY_PREDOMINANCE = OntologyClassBuilder.ontologyClass("HP:0025290", "Upper-body predominance"); + private static final OntologyClass SPATIAL_PATTERN = OntologyClassBuilder.ontologyClass("HP:0012836", "Spatial pattern"); + private static final OntologyClass JOINT_EXTENSOR_SURFACE_LOCALIZATION = OntologyClassBuilder.ontologyClass("HP:0032539", "Joint extensor surface localization"); + private static final OntologyClass HERPETIFORM = OntologyClassBuilder.ontologyClass("HP:0025295", "Herpetiform"); + private static final OntologyClass MORBILLIFORM = OntologyClassBuilder.ontologyClass("HP:0025296", "Morbilliform"); + private static final OntologyClass PERICENTRAL = OntologyClassBuilder.ontologyClass("HP:0030649", "Pericentral"); + private static final OntologyClass DERMATOMAL = OntologyClassBuilder.ontologyClass("HP:0025294", "Dermatomal"); + private static final OntologyClass MIDPERIPHERAL = OntologyClassBuilder.ontologyClass("HP:0030648", "Midperipheral"); + private static final OntologyClass DISTRIBUTED_ALONG_BLASCHKO_LINES = OntologyClassBuilder.ontologyClass("HP:0025293", "Distributed along Blaschko lines"); + private static final OntologyClass ACRAL = OntologyClassBuilder.ontologyClass("HP:0025292", "Acral"); + private static final OntologyClass PARACENTRAL = OntologyClassBuilder.ontologyClass("HP:0030647", "Paracentral"); + private static final OntologyClass LATERAL = OntologyClassBuilder.ontologyClass("HP:0025275", "Lateral"); + private static final OntologyClass PERIPHERAL = OntologyClassBuilder.ontologyClass("HP:0030646", "Peripheral"); + private static final OntologyClass LOWER_BODY_PREDOMINANCE = OntologyClassBuilder.ontologyClass("HP:0025291", "Lower-body predominance"); + private static final OntologyClass DIFFUSE = OntologyClassBuilder.ontologyClass("HP:0020034", "Diffuse"); + private static final OntologyClass PROXIMAL = OntologyClassBuilder.ontologyClass("HP:0012840", "Proximal"); + private static final OntologyClass APICAL = OntologyClassBuilder.ontologyClass("HP:0033820", "Apical"); + private static final OntologyClass FOCAL = OntologyClassBuilder.ontologyClass("HP:0030650", "Focal"); + private static final OntologyClass MULTIFOCAL = OntologyClassBuilder.ontologyClass("HP:0030651", "Multifocal"); + private static final OntologyClass JOINT_FLEXOR_SURFACE_LOCALIZATION = OntologyClassBuilder.ontologyClass("HP:0032540", "Joint flexor surface localization"); + + /** Do not allow instation of the constructor, this class just provides constants from the HPO + * Spatial Pattern subhierarchy, which is in the Clinical modifier subhierarchy. + */ + private SpatialPattern() {} + + + public static OntologyClass paraseptal() { return PARASEPTAL; } + public static OntologyClass lateral() { return LATERAL; } + public static OntologyClass perilobular() { return PERILOBULAR; } + public static OntologyClass morbilliform() { return MORBILLIFORM; } + public static OntologyClass centrilobular() { return CENTRILOBULAR; } + public static OntologyClass herpetiform() { return HERPETIFORM; } + public static OntologyClass bronchocentric() { return BRONCHOCENTRIC; } + public static OntologyClass dermatomal() { return DERMATOMAL; } + public static OntologyClass reticular() { return RETICULAR; } + public static OntologyClass spatialPattern() { return SPATIAL_PATTERN; } + public static OntologyClass miliary() { return MILIARY; } + public static OntologyClass generalized() { return GENERALIZED; } + public static OntologyClass localized() { return LOCALIZED; } + public static OntologyClass perilymphatic() { return PERILYMPHATIC; } + public static OntologyClass distal() { return DISTAL; } + public static OntologyClass jointFlexorSurfaceLocalization() { return JOINT_FLEXOR_SURFACE_LOCALIZATION; } + public static OntologyClass pericentral() { return PERICENTRAL; } + public static OntologyClass predominantSmallJointLocalization() { return PREDOMINANT_SMALL_JOINT_LOCALIZATION; } + public static OntologyClass midperipheral() { return MIDPERIPHERAL; } + public static OntologyClass distributedAlongBlaschkoLines() { return DISTRIBUTED_ALONG_BLASCHKO_LINES; } + public static OntologyClass acral() { return ACRAL; } + public static OntologyClass paracentral() { return PARACENTRAL; } + public static OntologyClass peripheral() { return PERIPHERAL; } + public static OntologyClass lowerBodyPredominance() { return LOWER_BODY_PREDOMINANCE; } + public static OntologyClass central() { return CENTRAL; } + public static OntologyClass upperBodyPredominance() { return UPPER_BODY_PREDOMINANCE; } + public static OntologyClass diffuse() { return DIFFUSE; } + public static OntologyClass jointExtensorSurfaceLocalization() { return JOINT_EXTENSOR_SURFACE_LOCALIZATION; } + public static OntologyClass multifocal() { return MULTIFOCAL; } + public static OntologyClass focal() { return FOCAL; } + public static OntologyClass axial() { return AXIAL; } + public static OntologyClass proximal() { return PROXIMAL; } + public static OntologyClass apical() { return APICAL; } + public static OntologyClass cervicalNeck() { return CERVICAL_NECK; } + public static OntologyClass polycyclic() { return POLYCYCLIC; } +} From e03ed6632c85a8374c92cb4108e2c47c0c8e1284 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Sat, 16 Apr 2022 18:57:43 -0400 Subject: [PATCH 029/155] output phtp features. --- .../phenopackettools/PhenopacketTools.java | 2 + .../command/HtmlOutputCommand.java | 46 ++++ .../examples/Retinoblastoma.java | 13 +- .../phenopackettools/html/HtmlOutputter.java | 183 +++++++++++++ .../phenopackettools/html/HtmlUtil.java | 246 ++++++++++++++++++ 5 files changed, 484 insertions(+), 6 deletions(-) create mode 100644 phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/HtmlOutputCommand.java create mode 100644 phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlOutputter.java create mode 100644 phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlUtil.java diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/PhenopacketTools.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/PhenopacketTools.java index 91651c51..f32c7247 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/PhenopacketTools.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/PhenopacketTools.java @@ -2,6 +2,7 @@ import org.phenopackets.phenopackettools.command.ConvertCommand; import org.phenopackets.phenopackettools.command.ExamplesCommand; +import org.phenopackets.phenopackettools.command.HtmlOutputCommand; import org.phenopackets.phenopackettools.command.ValidateCommand; import picocli.AutoComplete; @@ -15,6 +16,7 @@ AutoComplete.GenerateCompletion.class, ExamplesCommand.class, ConvertCommand.class, + HtmlOutputCommand.class, ValidateCommand.class } ) diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/HtmlOutputCommand.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/HtmlOutputCommand.java new file mode 100644 index 00000000..48c02765 --- /dev/null +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/HtmlOutputCommand.java @@ -0,0 +1,46 @@ +package org.phenopackets.phenopackettools.command; + + +import com.google.protobuf.util.JsonFormat; +import org.phenopackets.phenopackettools.html.HtmlOutputter; +import org.phenopackets.schema.v2.Phenopacket; +import picocli.CommandLine; + +import java.io.BufferedReader; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.concurrent.Callable; + +/** + * Create an HTML file to represent a Phenopacket for human consumption. + * This command does not check validity of the Phenopacket, but the code + * can be combined with the validator if needed. + * @author Peter N. Robinson + */ +@CommandLine.Command(name = "html", + mixinStandardHelpOptions = true, + description = "Format phenopacket as HTML.") +public class HtmlOutputCommand implements Callable { + + @CommandLine.Parameters(index = "0", description = "Input phenopacket file") + private Path inPath; + + @CommandLine.Option(names = {"-o","--outfile"}, description = "name of output file (default ${DEFAULT})") + private String outName = "phenopacket.html"; + + @Override + public Integer call() { + var builder = Phenopacket.newBuilder(); + try (BufferedReader reader = Files.newBufferedReader(inPath)) { + JsonFormat.parser().ignoringUnknownFields().merge(reader, builder); + } catch (IOException e) { + System.err.println("Error! Unable to read input file, " + e.getMessage() + "\nPlease check the format of file " + inPath); + return 1; + } + var v2Phenopacket = builder.build(); + HtmlOutputter outputter = new HtmlOutputter(v2Phenopacket, outName); + outputter.write(); + return 0; + } +} diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java index d11fff8a..90ca282a 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java @@ -57,8 +57,8 @@ public Retinoblastoma() { Interpretation interpretation() { Diagnosis diagnosis = DiagnosisBuilder.builder(RETINOBLASTOMA) - .addGenomicInterpretation(somaticRb1Missense()) .addGenomicInterpretation(germlineRb1Deletion()) + .addGenomicInterpretation(somaticRb1Missense()) .build(); return InterpretationBuilder.builder("interpretation.id").solved(diagnosis); } @@ -70,7 +70,8 @@ Interpretation interpretation() { */ GenomicInterpretation somaticRb1Missense() { AlleleBuilder abuilder = AlleleBuilder.builder(); - abuilder.setSequenceId("ga4gh:VA.GuPzvZoansqNHPoXkQLXKo31VkTpDKsM"); + // abuilder.setSequenceId("ga4gh:VA.GuPzvZoansqNHPoXkQLXKo31VkTpDKsM"); + abuilder.setSequenceId("refseq:NC_000013.14"); abuilder.startEnd( 48941647, 48941648); abuilder.setAltAllele("T"); VariationDescriptorBuilder vbuilder = VariationDescriptorBuilder.builder("rs121913300") @@ -90,7 +91,7 @@ GenomicInterpretation somaticRb1Missense() { vibuilder.actionable(); - GenomicInterpretationBuilder gbuilder = GenomicInterpretationBuilder.builder(PROBAND_ID); + GenomicInterpretationBuilder gbuilder = GenomicInterpretationBuilder.builder(BIOSAMPLE_ID); gbuilder.causative(); gbuilder.variantInterpretation(vibuilder); @@ -100,18 +101,18 @@ GenomicInterpretation somaticRb1Missense() { GenomicInterpretation germlineRb1Deletion() { CopyNumberBuilder abuilder = CopyNumberBuilder.builder(); - abuilder.copyNumberId("ga4gh:VCN.AFfJws1M4Lg8w1O3XknmHYc9TU2hHYpp"); + //abuilder.copyNumberId("ga4gh:VCN.AFfJws1M4Lg8w1O3XknmHYc9TU2hHYpp"); abuilder.alleleLocation("refseq:NC_000013.14",26555377, 62280955);//VRS uses inter-residue coordinates abuilder.oneCopy(); VariationDescriptorBuilder vbuilder = VariationDescriptorBuilder.builder(); vbuilder.variation(abuilder.buildVariation()); - vbuilder.mosaicism(40.0); + // vbuilder.mosaicism(40.0); VariantInterpretationBuilder vibuilder = VariantInterpretationBuilder.builder(vbuilder); vibuilder.pathogenic(); vibuilder.actionable(); - GenomicInterpretationBuilder gbuilder = GenomicInterpretationBuilder.builder(BIOSAMPLE_ID); + GenomicInterpretationBuilder gbuilder = GenomicInterpretationBuilder.builder(PROBAND_ID); gbuilder.causative(); gbuilder.variantInterpretation(vibuilder); diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlOutputter.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlOutputter.java new file mode 100644 index 00000000..9df8bb3e --- /dev/null +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlOutputter.java @@ -0,0 +1,183 @@ +package org.phenopackets.phenopackettools.html; + +import org.phenopackets.schema.v2.Phenopacket; +import org.phenopackets.schema.v2.core.*; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Writer; +import java.util.*; +import java.util.stream.Collectors; + +/** + * Class to display information contained in a Phenopacket in HTML + * @author Peter Robinson + */ +public class HtmlOutputter { + + private final Phenopacket phenopacket; + private final String outname; + + enum Section {PROBAND, PHENOTYPICFEATURE, MEASUREMENT} + + public HtmlOutputter(Phenopacket phenopacket, String outname) { + this.phenopacket = phenopacket; + this.outname = outname; + } + + public void write() { + String phenopacketId = phenopacket.getId(); + try (BufferedWriter writer = new BufferedWriter(new FileWriter(outname))) { + writer.write(HtmlUtil.header(phenopacketId)); + writer.write(HtmlUtil.htmlTop()); + wrap(Section.PROBAND, writer); + wrap(Section.PHENOTYPICFEATURE, writer); + writer.write(HtmlUtil.bottom()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void startSection(Writer writer) throws IOException { + writer.write("

\n"); + } + + private void endSection(Writer writer) throws IOException { + writer.write("
\n"); + } + + private void wrap(Section section,Writer writer) throws IOException { + startSection(writer); + switch (section) { + case PROBAND: outputProband(writer); break; + case PHENOTYPICFEATURE: outputPhenotypicFeatures(writer); + } + endSection(writer); + } + + private void outputProband(Writer writer) throws IOException { + Individual proband = phenopacket.getSubject(); + String probandId = proband.getId(); // required + Map kv = new TreeMap<>(); + kv.put("id", probandId); + kv.put("sex", proband.getSex().name()); + if (proband.hasVitalStatus()) { + kv.put("vital status", proband.getVitalStatus().getStatus().name()); + } + writer.write("

Proband

\n"); + writer.write("
").append(head).append("
\n"); + for (var e : kv.entrySet()) { + writer.write(row2(e.getKey(), e.getValue())); + } + writer.write("
\n"); + } + + private void outputPhenotypicFeatures(Writer writer) throws IOException { + List phenotypicFeatureList = phenopacket.getPhenotypicFeaturesList(); + if (phenotypicFeatureList.isEmpty()) { + writer.write("

No phenotypic features.

"); + return; + } + writer.write("

Phenotypic Features

\n"); + writer.write("\n"); + writer.write(""); + List fields = List.of("Term", "Id", "Status", "Modifiers", "onset", "resolution", "evidence"); + for (var f: fields) { + writer.write(""); + } + writer.write("\n"); + for (var feature : phenotypicFeatureList) { + List pffields = getPhenotypicFeatureFields(feature); + writer.write(row(pffields)); + } + writer.write("
" + f + "
\n"); + } + + private String getOntologyTermList(List terms) { + List oclsList = new ArrayList<>(); + for (var ocls : terms) { + oclsList.add(String.format("%s(%s)", ocls.getLabel(), ocls.getId())); + } + return String.join(";", oclsList); + } + + private List getPhenotypicFeatureFields(PhenotypicFeature feature) { + List fields = new ArrayList<>(); + OntologyClass ocls = feature.getType(); + fields.add(ocls.getLabel()); + fields.add(ocls.getId()); + if (feature.getExcluded()) { + fields.add("Excluded"); + } else { + fields.add("Observed"); + } + if (feature.getModifiersCount() > 0) { + fields.add(getOntologyTermList(feature.getModifiersList())); + } else { + fields.add("-"); + } + if (feature.hasOnset()) { + String timeAge = getTimeAge(feature.getOnset()); + fields.add(timeAge); + } else { + fields.add("-"); + } + if (feature.hasResolution()) { + String timeAge = getTimeAge(feature.getResolution()); + fields.add(timeAge); + } else { + fields.add("-"); + } + if (feature.getEvidenceCount() > 0) { + List evilist = feature.getEvidenceList(); + String evi = getEvidenceString(evilist); + fields.add(evi); + } else { + fields.add("-"); + } + return fields; + } + + private String getEvidenceString(List evilist) { + List eviStrList = new ArrayList<>(); + for (var evi : evilist) { + OntologyClass clz = evi.getEvidenceCode(); + eviStrList.add(String.format("%s", clz.getId())); + + } + return String.join(";", eviStrList); + } + + private String getTimeAge(TimeElement onset) { + if (onset.hasAge()) { + return onset.getAge().getIso8601Duration(); + } + + return "todo"; + } + + + private String row2(String s1, String s2) { + return String.format("%s%s\n", s1, s2); + } + + private String row(List fields) { + StringBuilder sb = new StringBuilder(); + sb.append(""); + for (var s : fields) { + sb.append("").append(s).append(""); + } + sb.append("\n"); + return sb.toString(); + } + + + private void outputSection(Writer writer, String Title, Map kv) { + + } + + + + +} diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlUtil.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlUtil.java new file mode 100644 index 00000000..593da50a --- /dev/null +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlUtil.java @@ -0,0 +1,246 @@ +package org.phenopackets.phenopackettools.html; + +import java.util.List; + +public class HtmlUtil { + + + public static String header(String phenopacketId) { + return "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "Phenopacket: " + phenopacketId + "\n" + + "\n" + + "\n" + + css() + + "\n\n"; + } + + + private static String css() { + return "\n"; + } + + + public static String htmlTop() { + return "\n" + + "
\n" + + "

Isopret

\n" + + "
\n" + + "
\n"; + } + + + public static String bottom() { + return " \n" + + "
\n" + + "\n" + + ""; + } + + + public static String tableHeader(String tableClass, List widths, List headerFields) { + StringBuilder sb = new StringBuilder(); + sb.append(""); + if (widths.size() == headerFields.size()) { + for (int i=0; i").append(head).append(""); + } + } else { + for (String head: headerFields) { + sb.append(""); + } + } + sb.append("\n"); + return sb.toString(); + } + +} From 13c6d287b3b74ca478c790cb954ba7cdf34d71d4 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Sun, 17 Apr 2022 08:29:53 -0400 Subject: [PATCH 030/155] output proband complete --- .../builders/InterpretationBuilder.java | 9 --- .../examples/NemalineMyopathyPrenatal.java | 1 - .../phenopackettools/html/HtmlOutputter.java | 76 +++++++++++++++---- .../phenopackettools/html/HtmlUtil.java | 29 ++----- .../converter/PhenopacketConverterTest.java | 1 - 5 files changed, 67 insertions(+), 49 deletions(-) diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/InterpretationBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/InterpretationBuilder.java index 24ccc346..ddc3ca67 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/InterpretationBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/InterpretationBuilder.java @@ -19,19 +19,10 @@ public static InterpretationBuilder builder(String interpretationId) { return new InterpretationBuilder(interpretationId, Interpretation.ProgressStatus.UNKNOWN_PROGRESS); } -// public static InterpretationBuilder builder(String interpretationId, Interpretation.ProgressStatus status) { -// return new InterpretationBuilder(interpretationId, status); -// } - public InterpretationBuilder summary(String summary) { builder.setSummary(summary); return this; } -// -// public InterpretationBuilder diagnosis(Diagnosis diagnosis) { -// builder.setDiagnosis(diagnosis); -// return this; -// } public Interpretation inProgress() { builder.setProgressStatus(Interpretation.ProgressStatus.IN_PROGRESS); diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/NemalineMyopathyPrenatal.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/NemalineMyopathyPrenatal.java index aa934690..aed615af 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/NemalineMyopathyPrenatal.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/NemalineMyopathyPrenatal.java @@ -11,7 +11,6 @@ import java.util.List; import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; -import static org.phenopackets.phenopackettools.builder.builders.PhenotypicFeatureBuilder.phenotypicFeature; import static org.phenopackets.phenopackettools.builder.builders.TimeElements.gestationalAge; /** diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlOutputter.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlOutputter.java index 9df8bb3e..bae9e749 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlOutputter.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlOutputter.java @@ -1,5 +1,7 @@ package org.phenopackets.phenopackettools.html; +import com.google.protobuf.Timestamp; +import com.google.protobuf.util.Timestamps; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; @@ -8,7 +10,6 @@ import java.io.IOException; import java.io.Writer; import java.util.*; -import java.util.stream.Collectors; /** * Class to display information contained in a Phenopacket in HTML @@ -33,7 +34,7 @@ public void write() { writer.write(HtmlUtil.htmlTop()); wrap(Section.PROBAND, writer); wrap(Section.PHENOTYPICFEATURE, writer); - writer.write(HtmlUtil.bottom()); + writer.write(HtmlUtil.htmlBottom()); } catch (IOException e) { e.printStackTrace(); } @@ -59,17 +60,47 @@ private void wrap(Section section,Writer writer) throws IOException { private void outputProband(Writer writer) throws IOException { Individual proband = phenopacket.getSubject(); String probandId = proband.getId(); // required - Map kv = new TreeMap<>(); - kv.put("id", probandId); - kv.put("sex", proband.getSex().name()); + + List thisRow = new ArrayList<>(); + thisRow.add(probandId); + thisRow.add(proband.getSex().toString()); + if (proband.hasDateOfBirth()) { + Timestamp dob = proband.getDateOfBirth(); + thisRow.add(Timestamps.toString(dob)); + } else { + thisRow.add("-"); + } + if (proband.hasTimeAtLastEncounter()) { + String age = getTimeAge(proband.getTimeAtLastEncounter()); + thisRow.add(age); + } else { + thisRow.add("-"); + } if (proband.hasVitalStatus()) { - kv.put("vital status", proband.getVitalStatus().getStatus().name()); + thisRow.add( proband.getVitalStatus().getStatus().name()); + } else { + thisRow.add("-"); + } + if (proband.getKaryotypicSex().getNumber() >0) { + thisRow.add(proband.getKaryotypicSex().toString()); + } else { + thisRow.add("-"); + } + if (proband.hasGender()) { + OntologyClass clz = proband.getGender(); + thisRow.add(String.format("%s (%s)", clz.getLabel(), clz.getId())); + } else { + thisRow.add("-"); } writer.write("

Proband

\n"); writer.write("
").append(head).append("
\n"); - for (var e : kv.entrySet()) { - writer.write(row2(e.getKey(), e.getValue())); + writer.write(""); + List fields = List.of("id", "sex", "birthdate", "age", "vital status", "karyotypic_sex", "gender"); + for (var f: fields) { + writer.write(""); } + writer.write("\n"); + writer.write(row(thisRow)); writer.write("
" + f + "
\n"); } @@ -152,14 +183,29 @@ private String getEvidenceString(List evilist) { private String getTimeAge(TimeElement onset) { if (onset.hasAge()) { return onset.getAge().getIso8601Duration(); + } else if (onset.hasGestationalAge()) { + GestationalAge ga = onset.getGestationalAge(); + return String.format("GA: %dW+%d D", ga.getWeeks(), ga.getDays()); + } else if (onset.hasAgeRange()) { + AgeRange ar = onset.getAgeRange(); + String start = ar.getStart().getIso8601Duration(); + String end = ar.getEnd().getIso8601Duration(); + return String.format("%s - %s", start, end); + } else if (onset.hasTimestamp()) { + Timestamp ts = onset.getTimestamp(); + return Timestamps.toString(ts); + } else if (onset.hasOntologyClass()) { + OntologyClass clz = onset.getOntologyClass(); + return String.format("%s (%s)", clz.getLabel(), clz.getId()); + } else if (onset.hasInterval()) { + TimeInterval ti = onset.getInterval(); + String start = Timestamps.toString(ti.getStart()); + String end = Timestamps.toString(ti.getEnd()); + return String.format("%s - %s", start, end); + } else { + // we have exhausted all possibilities and should never get here, but... + return "N/A"; } - - return "todo"; - } - - - private String row2(String s1, String s2) { - return String.format("%s%s\n", s1, s2); } private String row(List fields) { diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlUtil.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlUtil.java index 593da50a..213b45d1 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlUtil.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlUtil.java @@ -1,7 +1,9 @@ package org.phenopackets.phenopackettools.html; -import java.util.List; - +/** + * Some CSS and boilerplate HTML for writing phenopackets. + * @author Peter N Robinson + */ public class HtmlUtil { @@ -211,13 +213,12 @@ private static String css() { public static String htmlTop() { return "\n" + "
\n" + - "

Isopret

\n" + + "

Phenopacket-Tools

\n" + "
\n" + "
\n"; } - - public static String bottom() { + public static String htmlBottom() { return " \n" + "
\n" + "\n" + @@ -225,22 +226,4 @@ public static String bottom() { } - public static String tableHeader(String tableClass, List widths, List headerFields) { - StringBuilder sb = new StringBuilder(); - sb.append(""); - if (widths.size() == headerFields.size()) { - for (int i=0; i").append(head).append(""); - } - } else { - for (String head: headerFields) { - sb.append(""); - } - } - sb.append("\n"); - return sb.toString(); - } - } diff --git a/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java b/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java index 44f63d7e..bc8c64f7 100644 --- a/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java +++ b/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java @@ -1,7 +1,6 @@ package org.phenopackets.phenopackettools.converter; import com.google.protobuf.InvalidProtocolBufferException; -import com.google.protobuf.util.JsonFormat; import org.junit.jupiter.api.Test; import org.phenopackets.phenopackettools.converter.converters.PhenopacketConverter; From 1b53789b6e1ccb9d5a3b7f75a07469f2d2ac625c Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Sun, 17 Apr 2022 16:43:21 -0400 Subject: [PATCH 031/155] adding functionality to MetaDataBuilder --- .../builder/builders/MetaDataBuilder.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MetaDataBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MetaDataBuilder.java index 00a567f3..5b218707 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MetaDataBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MetaDataBuilder.java @@ -1,10 +1,13 @@ package org.phenopackets.phenopackettools.builder.builders; +import com.google.protobuf.Timestamp; import org.phenopackets.schema.v2.core.ExternalReference; import org.phenopackets.schema.v2.core.MetaData; import org.phenopackets.schema.v2.core.Resource; import org.phenopackets.schema.v2.core.Update; +import java.time.Instant; + import static org.phenopackets.phenopackettools.builder.builders.TimestampBuilder.fromISO8601; public class MetaDataBuilder { @@ -20,10 +23,31 @@ private MetaDataBuilder(String created, String createdBy) { .setPhenopacketSchemaVersion(SCHEMA_VERSION); // only one option for schema version! } + private MetaDataBuilder(Timestamp createdTimeStamp, String createdBy) { + builder = MetaData.newBuilder() + .setCreated(createdTimeStamp) + .setCreatedBy(createdBy) + .setPhenopacketSchemaVersion(SCHEMA_VERSION); // only one option for schema version! + } + public static MetaDataBuilder builder(String created, String createdBy) { return new MetaDataBuilder(created, createdBy); } + public static MetaDataBuilder builder(Timestamp createdTimeStamp, String createdBy) { + return new MetaDataBuilder(createdTimeStamp, createdBy); + } + + /** + * Create a new MetaDataBuilder with time set to now. + */ + public static MetaDataBuilder builder(String createdBy) { + Instant time = Instant.now(); + Timestamp timestamp = Timestamp.newBuilder().setSeconds(time.getEpochSecond()) + .setNanos(time.getNano()).build(); + return new MetaDataBuilder(timestamp, createdBy); + } + public MetaDataBuilder submittedBy(String submitter) { builder.setSubmittedBy(submitter); return this; From c3d20c022e522a2b069a885d5565b1c6b0030301 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Thu, 21 Apr 2022 09:40:41 -0400 Subject: [PATCH 032/155] hotfix -- replacing unilateral by left in an example --- .../phenopackettools/examples/Retinoblastoma.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java index 90ca282a..a3849afc 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java @@ -264,19 +264,19 @@ List getPhenotypicFeatures() { TimeElement age4months = TimeElements.age("P4M"); PhenotypicFeature leukocoria = PhenotypicFeatureBuilder. builder("HP:0000555", "Leukocoria") - .addModifier(Laterality.unilateral()) + .addModifier(Laterality.left()) .onset(age4months) .build(); TimeElement age5months = TimeElements.age("P5M15D"); PhenotypicFeature strabismus = PhenotypicFeatureBuilder. builder("HP:0000486", "Strabismus") - .addModifier(Laterality.unilateral()) + .addModifier(Laterality.left()) .onset(age5months) .build(); TimeElement age6months = TimeElements.age("P6M"); PhenotypicFeature retinalDetachment = PhenotypicFeatureBuilder .builder("HP:0000541", "Retinal detachment") - .addModifier(Laterality.unilateral()) + .addModifier(Laterality.left()) .onset(age6months) .build(); return List.of(clinodactyly, leukocoria, strabismus, retinalDetachment); From 1f29eb5b759973591c383177157fabe7a1fdda2d Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Thu, 21 Apr 2022 17:54:43 -0400 Subject: [PATCH 033/155] standardizing function names to of and builder --- .../builder/PhenopacketBuilder.java | 2 +- .../builders/{AgeBuilder.java => Ages.java} | 4 +- .../builder/builders/AlleleBuilder.java | 4 +- .../builder/builders/BiosampleBuilder.java | 2 +- .../builder/builders/ComplexValueBuilder.java | 12 ++--- .../builder/builders/CopyNumberBuilder.java | 2 +- .../builder/builders/DiseaseBuilder.java | 6 +-- .../builder/builders/DoseIntervalBuilder.java | 6 +-- .../builder/builders/EvidenceBuilder.java | 10 ++--- .../builder/builders/Extensions.java | 18 +++++--- .../builders/ExternalReferenceBuilder.java | 6 +-- .../builders/GeneDescriptorBuilder.java | 2 +- .../builder/builders/IndividualBuilder.java | 2 +- .../builders/InterpretationBuilder.java | 2 +- .../builder/builders/MeasurementBuilder.java | 8 ++-- .../builders/PhenotypicFeatureBuilder.java | 6 +-- .../builder/builders/ProcedureBuilder.java | 6 +-- .../builder/builders/QuantityBuilder.java | 20 ++++----- .../builders/ReferenceRangeBuilder.java | 6 +-- .../builder/builders/TimeElements.java | 4 +- .../builder/builders/TimeIntervalBuilder.java | 4 +- .../builder/builders/TreatmentBuilder.java | 6 +-- .../builders/TypedQuantityBuilder.java | 2 +- .../builder/builders/ValueBuilder.java | 26 +++++------ .../VariantInterpretationBuilder.java | 4 +- .../builders/VariationDescriptorBuilder.java | 18 ++++---- .../builder/builders/VcfRecordBuilder.java | 2 +- .../builder/builders/AgeBuilderTest.java | 10 ++--- .../builder/builders/AlleleBuilderTest.java | 4 +- .../builders/BiosampleBuilderTest.java | 4 +- .../builders/ComplexValueBuilderTest.java | 6 +-- .../builders/DiagnosisBuilderTest.java | 2 +- .../builder/builders/DiseaseBuilderTest.java | 2 +- .../builders/DoseIntervalBuilderTest.java | 6 +-- .../builders/TimeIntervalBuilderTest.java | 4 +- .../examples/BethlehamMyopathy.java | 2 +- .../phenopackettools/examples/Covid.java | 44 +++++++++---------- .../phenopackettools/examples/Marfan.java | 10 ++--- .../examples/NemalineMyopathyPrenatal.java | 8 ++-- .../examples/Retinoblastoma.java | 43 ++++++++++-------- .../examples/Thrombocytopenia2.java | 2 +- .../examples/UrothelialCancer.java | 2 +- .../phenopackettools/html/HtmlOutputter.java | 7 --- .../converter/PhenopacketConverterTest.java | 13 +++--- 44 files changed, 183 insertions(+), 176 deletions(-) rename phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/{AgeBuilder.java => Ages.java} (95%) diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/PhenopacketBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/PhenopacketBuilder.java index 0f399bd5..b06ef364 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/PhenopacketBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/PhenopacketBuilder.java @@ -24,7 +24,7 @@ public PhenopacketBuilder individual(Individual subject) { } public PhenopacketBuilder addPhenotypicFeature(String id, String label) { - PhenotypicFeature phenotypicFeature = PhenotypicFeatureBuilder.phenotypicFeature(id, label); + PhenotypicFeature phenotypicFeature = PhenotypicFeatureBuilder.of(id, label); return addPhenotypicFeature(phenotypicFeature); } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/AgeBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Ages.java similarity index 95% rename from phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/AgeBuilder.java rename to phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Ages.java index 20691682..4711e498 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/AgeBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Ages.java @@ -8,9 +8,9 @@ import java.time.Period; import java.time.format.DateTimeParseException; -public class AgeBuilder { +public class Ages { - private AgeBuilder() { + private Ages() { } public static Age age(String iso8601duration) { diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilder.java index 7e7b7a07..86c08a7b 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilder.java @@ -54,12 +54,12 @@ public AlleleBuilder startEnd(int start, int end) { return this; } - public AlleleBuilder setAltAllele(String alt) { + public AlleleBuilder altAllele(String alt) { builder.setLiteralSequenceExpression(LiteralSequenceExpression.newBuilder().setSequence(alt)); return this; } - public AlleleBuilder setSequenceId(String sequenceId) { + public AlleleBuilder sequenceId(String sequenceId) { slbuilder.setSequenceId(sequenceId); return this; } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilder.java index 4c15789e..4c47995b 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilder.java @@ -42,7 +42,7 @@ public BiosampleBuilder sampledType(OntologyClass tissue) { } public BiosampleBuilder addPhenotypicFeature(String id, String label) { - PhenotypicFeature phenotypicFeature = PhenotypicFeatureBuilder.phenotypicFeature(id, label); + PhenotypicFeature phenotypicFeature = PhenotypicFeatureBuilder.of(id, label); return addPhenotypicFeature(phenotypicFeature); } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilder.java index ff370bcf..ed671e56 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilder.java @@ -12,20 +12,20 @@ public class ComplexValueBuilder { private ComplexValueBuilder() { } - public static ComplexValue complexValue(TypedQuantity typedQuantity) { + public static ComplexValue of(TypedQuantity typedQuantity) { return ComplexValue.newBuilder().addTypedQuantities(typedQuantity).build(); } - public static ComplexValue complexValue(TypedQuantity... typedQuantities) { + public static ComplexValue of(TypedQuantity... typedQuantities) { return ComplexValue.newBuilder().addAllTypedQuantities(List.of(typedQuantities)).build(); } - public static ComplexValue complexValue(List typedQuantities) { + public static ComplexValue of(List typedQuantities) { return ComplexValue.newBuilder().addAllTypedQuantities(typedQuantities).build(); } - public static ComplexValue complexValue(OntologyClass type, Quantity quantity) { - TypedQuantity typedQuantity = TypedQuantityBuilder.typedQuantity(type, quantity); - return complexValue(typedQuantity); + public static ComplexValue of(OntologyClass type, Quantity quantity) { + TypedQuantity typedQuantity = TypedQuantityBuilder.of(type, quantity); + return of(typedQuantity); } } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/CopyNumberBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/CopyNumberBuilder.java index fb9a2b6b..3c8074ba 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/CopyNumberBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/CopyNumberBuilder.java @@ -24,7 +24,7 @@ public CopyNumberBuilder copyNumberId(String id) { */ public CopyNumberBuilder alleleLocation(String contig, int interbaseStartPos, int interbaseEndPos) { AlleleBuilder abuilder = AlleleBuilder.builder() - .setSequenceId(contig) + .sequenceId(contig) .startEnd(interbaseStartPos, interbaseEndPos); builder.setAllele(abuilder.build()); return this; diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilder.java index 3c648524..f9166b2c 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilder.java @@ -12,13 +12,13 @@ private DiseaseBuilder(OntologyClass term) { builder = Disease.newBuilder().setTerm(term); } - public static Disease disease(OntologyClass term) { + public static Disease of(OntologyClass term) { return Disease.newBuilder().setTerm(term).build(); } - public static Disease disease(String id, String label) { + public static Disease of(String id, String label) { OntologyClass term = OntologyClassBuilder.ontologyClass(id, label); - return disease(term); + return of(term); } public static DiseaseBuilder builder(OntologyClass term) { diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DoseIntervalBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DoseIntervalBuilder.java index 52850cce..d1bc2d09 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DoseIntervalBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DoseIntervalBuilder.java @@ -10,7 +10,7 @@ public class DoseIntervalBuilder { private DoseIntervalBuilder() { } - public static DoseInterval doseInterval(Quantity quantity, OntologyClass scheduleFrequency, TimeInterval interval) { + public static DoseInterval of(Quantity quantity, OntologyClass scheduleFrequency, TimeInterval interval) { return DoseInterval.newBuilder() .setQuantity(quantity) .setScheduleFrequency(scheduleFrequency) @@ -18,8 +18,8 @@ public static DoseInterval doseInterval(Quantity quantity, OntologyClass schedul .build(); } - public static DoseInterval doseInterval(Quantity quantity, OntologyClass scheduleFrequency, String start, String end) { - var interval = TimeIntervalBuilder.timeInterval(start, end); + public static DoseInterval of(Quantity quantity, OntologyClass scheduleFrequency, String start, String end) { + var interval = TimeIntervalBuilder.of(start, end); return DoseInterval.newBuilder() .setQuantity(quantity) .setScheduleFrequency(scheduleFrequency) diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/EvidenceBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/EvidenceBuilder.java index f9064b09..2a06d762 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/EvidenceBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/EvidenceBuilder.java @@ -13,16 +13,16 @@ private EvidenceBuilder(OntologyClass evidenceCode) { builder = Evidence.newBuilder().setEvidenceCode(evidenceCode); } - public static Evidence evidence(String id, String label) { + public static Evidence of(String id, String label) { OntologyClass evidenceCode = OntologyClassBuilder.ontologyClass(id, label); return new EvidenceBuilder(evidenceCode).build(); } - public static Evidence evidence(OntologyClass evidenceCode) { + public static Evidence of(OntologyClass evidenceCode) { return new EvidenceBuilder(evidenceCode).build(); } - public static Evidence evidence(OntologyClass evidenceCode, ExternalReference externalReference) { + public static Evidence of(OntologyClass evidenceCode, ExternalReference externalReference) { return new EvidenceBuilder(evidenceCode).reference(externalReference).build(); } @@ -39,8 +39,8 @@ public static Evidence authorStatementEvidence(String pmid, String title) { String id = "ECO:0000033"; String label = "author statement supported by traceable reference"; OntologyClass evidenceCode = OntologyClassBuilder.ontologyClass(id, label); - ExternalReference externalReference = ExternalReferenceBuilder.externalReference(pmid, title); - return evidence(evidenceCode, externalReference); + ExternalReference externalReference = ExternalReferenceBuilder.of(pmid, title); + return of(evidenceCode, externalReference); } public EvidenceBuilder reference(ExternalReference externalReference) { diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Extensions.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Extensions.java index c8069ff7..326edb9d 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Extensions.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Extensions.java @@ -1,17 +1,25 @@ package org.phenopackets.phenopackettools.builder.builders; -import com.google.protobuf.Any; -import com.google.protobuf.ByteString; import org.ga4gh.vrsatile.v1.Extension; public class Extensions { + public static final String MOSAICISM = "mosaicism"; + public static final String ALLELE_FREQUENCY = "allele-frequency"; public static Extension mosaicism(double percentage) { String percentageString = String.format("%.1f%%", percentage); - ByteString bstring = ByteString.copyFromUtf8(percentageString); - Any perc = Any.newBuilder().setValue(bstring).build(); - return Extension.newBuilder().setName("mosaicism").addValue(perc).build(); + return Extension.newBuilder().setName(MOSAICISM).setValue(percentageString).build(); } + + /** + * @param frequency estimated frequency (IN PERCENT) of an allele (generally a somatic mutation) + */ + public static Extension alleleFrequency(double frequency) { + String percentageString = String.format("%.1f%%", frequency); + return Extension.newBuilder().setName(ALLELE_FREQUENCY).setValue(percentageString).build(); + } + + } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ExternalReferenceBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ExternalReferenceBuilder.java index d441a7ea..37281a1d 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ExternalReferenceBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ExternalReferenceBuilder.java @@ -10,11 +10,11 @@ private ExternalReferenceBuilder() { builder = ExternalReference.newBuilder(); } - public static ExternalReference externalReference(String id, String description) { + public static ExternalReference of(String id, String description) { return ExternalReference.newBuilder().setId(id).setDescription(description).build(); } - public static ExternalReferenceBuilder builder() { + public static ExternalReferenceBuilder reference() { return new ExternalReferenceBuilder(); } @@ -23,7 +23,7 @@ public ExternalReferenceBuilder id(String id) { return this; } - public ExternalReferenceBuilder builder(String ref) { + public ExternalReferenceBuilder reference(String ref) { builder.setReference(ref); return this; } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/GeneDescriptorBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/GeneDescriptorBuilder.java index af870423..6c281190 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/GeneDescriptorBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/GeneDescriptorBuilder.java @@ -12,7 +12,7 @@ private GeneDescriptorBuilder(String identifier, String symbol) { builder = GeneDescriptor.newBuilder().setValueId(identifier).setSymbol(symbol); } - public static GeneDescriptor geneDescriptor(String identifier, String symbol) { + public static GeneDescriptor of(String identifier, String symbol) { return GeneDescriptor.newBuilder().setValueId(identifier).setSymbol(symbol).build(); } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilder.java index 87f92377..32079ab7 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilder.java @@ -29,7 +29,7 @@ private IndividualBuilder(String id) { builder = Individual.newBuilder().setId(id); } - public static Individual individual(String id) { + public static Individual of(String id) { return Individual.newBuilder().setId(id).build(); } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/InterpretationBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/InterpretationBuilder.java index ddc3ca67..4baa5cf3 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/InterpretationBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/InterpretationBuilder.java @@ -11,7 +11,7 @@ private InterpretationBuilder(String interpretationId, Interpretation.ProgressSt builder = Interpretation.newBuilder().setId(interpretationId).setProgressStatus(status); } - public static Interpretation interpretation(String interpretationId, Interpretation.ProgressStatus status, Diagnosis diagnosis, String summary) { + public static Interpretation of(String interpretationId, Interpretation.ProgressStatus status, Diagnosis diagnosis, String summary) { return Interpretation.newBuilder().setId(interpretationId).setProgressStatus(status).setDiagnosis(diagnosis).setSummary(summary).build(); } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MeasurementBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MeasurementBuilder.java index cdb63a7e..b79253cf 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MeasurementBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/MeasurementBuilder.java @@ -14,19 +14,19 @@ private MeasurementBuilder(OntologyClass assay, ComplexValue complexValue) { builder = Measurement.newBuilder().setAssay(assay).setComplexValue(complexValue); } - public static Measurement measurement(OntologyClass assay, Value value) { + public static Measurement of(OntologyClass assay, Value value) { return Measurement.newBuilder().setAssay(assay).setValue(value).build(); } - public static Measurement measurement(OntologyClass assay, ComplexValue complexValue) { + public static Measurement of(OntologyClass assay, ComplexValue complexValue) { return Measurement.newBuilder().setAssay(assay).setComplexValue(complexValue).build(); } - public static MeasurementBuilder value(OntologyClass assay, Value value) { + public static MeasurementBuilder builder(OntologyClass assay, Value value) { return new MeasurementBuilder(assay, value); } - public static MeasurementBuilder complexValue(OntologyClass assay, ComplexValue complexValue) { + public static MeasurementBuilder builder(OntologyClass assay, ComplexValue complexValue) { return new MeasurementBuilder(assay, complexValue); } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/PhenotypicFeatureBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/PhenotypicFeatureBuilder.java index 0899b58b..3901df93 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/PhenotypicFeatureBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/PhenotypicFeatureBuilder.java @@ -21,13 +21,13 @@ private PhenotypicFeatureBuilder(OntologyClass feature) { builder = PhenotypicFeature.newBuilder().setType(feature); } - public static PhenotypicFeature phenotypicFeature(OntologyClass feature) { + public static PhenotypicFeature of(OntologyClass feature) { return PhenotypicFeature.newBuilder().setType(feature).build(); } - public static PhenotypicFeature phenotypicFeature(String id, String label) { + public static PhenotypicFeature of(String id, String label) { OntologyClass ontologyClass = OntologyClassBuilder.ontologyClass(id, label); - return phenotypicFeature(ontologyClass); + return of(ontologyClass); } public static PhenotypicFeatureBuilder builder(OntologyClass feature) { diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ProcedureBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ProcedureBuilder.java index 6a17c2f2..7ff8745c 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ProcedureBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ProcedureBuilder.java @@ -12,12 +12,12 @@ private ProcedureBuilder(OntologyClass procedure) { builder = Procedure.newBuilder().setCode(procedure); } - public static Procedure procedure(OntologyClass procedure) { + public static Procedure of(OntologyClass procedure) { return Procedure.newBuilder().setCode(procedure).build(); } - public static Procedure procedure(String id, String label) { - return procedure(OntologyClassBuilder.ontologyClass(id, label)); + public static Procedure of(String id, String label) { + return of(OntologyClassBuilder.ontologyClass(id, label)); } public static ProcedureBuilder builder(OntologyClass procedure) { diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/QuantityBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/QuantityBuilder.java index c83c6298..56861658 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/QuantityBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/QuantityBuilder.java @@ -12,28 +12,28 @@ private QuantityBuilder(OntologyClass unit, double value) { builder = Quantity.newBuilder().setUnit(unit).setValue(value); } - public static Quantity quantity(OntologyClass unit, double value) { + public static Quantity of(OntologyClass unit, double value) { return Quantity.newBuilder().setUnit(unit).setValue(value).build(); } - public static Quantity quantity(String id, String label, double value) { - return quantity(OntologyClassBuilder.ontologyClass(id, label), value); + public static Quantity of(String id, String label, double value) { + return of(OntologyClassBuilder.ontologyClass(id, label), value); } - public static Quantity quantity(String id, String label, double value, ReferenceRange ref) { - return quantity(OntologyClassBuilder.ontologyClass(id, label), value); + public static Quantity of(String id, String label, double value, ReferenceRange ref) { + return of(OntologyClassBuilder.ontologyClass(id, label), value); } - public static Quantity quantity(OntologyClass unit, double value, ReferenceRange ref) { + public static Quantity of(OntologyClass unit, double value, ReferenceRange ref) { return Quantity.newBuilder().setUnit(unit).setValue(value).setReferenceRange(ref).build(); } - public static QuantityBuilder unitValue(OntologyClass unit, double value) { + public static QuantityBuilder builder(OntologyClass unit, double value) { return new QuantityBuilder(unit, value); } - public static QuantityBuilder unitValue(String id, String label, double value) { + public static QuantityBuilder builder(String id, String label, double value) { return new QuantityBuilder(OntologyClassBuilder.ontologyClass(id, label), value); } @@ -43,13 +43,13 @@ public QuantityBuilder referenceRange(ReferenceRange range) { } public QuantityBuilder referenceRange(OntologyClass unit, double low, double high) { - ReferenceRange range = ReferenceRangeBuilder.referenceRange(unit, low, high); + ReferenceRange range = ReferenceRangeBuilder.of(unit, low, high); builder.setReferenceRange(range); return this; } public QuantityBuilder referenceRange(String id, String label, double low, double high) { - ReferenceRange range = ReferenceRangeBuilder.referenceRange(id, label, low, high); + ReferenceRange range = ReferenceRangeBuilder.of(id, label, low, high); builder.setReferenceRange(range); return this; } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ReferenceRangeBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ReferenceRangeBuilder.java index 8beca5e3..20ef3800 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ReferenceRangeBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ReferenceRangeBuilder.java @@ -17,13 +17,13 @@ public class ReferenceRangeBuilder { private ReferenceRangeBuilder() { } - public static ReferenceRange referenceRange(OntologyClass unit, double low, double high) { + public static ReferenceRange of(OntologyClass unit, double low, double high) { return ReferenceRange.newBuilder().setUnit(unit).setLow(low).setHigh(high).build(); } - public static ReferenceRange referenceRange(String id, String label, double low, double high) { + public static ReferenceRange of(String id, String label, double low, double high) { OntologyClass unit = OntologyClassBuilder.ontologyClass(id, label); - return referenceRange(unit, low, high); + return of(unit, low, high); } } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimeElements.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimeElements.java index 3e40b9e2..6a7d6f70 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimeElements.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimeElements.java @@ -48,12 +48,12 @@ public static TimeElement gestationalAge(int weeks) { } public static TimeElement age(String iso8601duration) { - Age age = AgeBuilder.age(iso8601duration); + Age age = Ages.age(iso8601duration); return TimeElement.newBuilder().setAge(age).build(); } public static TimeElement ageRange(String iso8601start, String iso8601End) { - AgeRange ageRange = AgeBuilder.ageRange(iso8601start, iso8601End); + AgeRange ageRange = Ages.ageRange(iso8601start, iso8601End); return TimeElement.newBuilder().setAgeRange(ageRange).build(); } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilder.java index 13cf6eec..239b8754 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilder.java @@ -10,14 +10,14 @@ public class TimeIntervalBuilder { private TimeIntervalBuilder() { } - public static TimeInterval timeInterval(Timestamp start, Timestamp end) { + public static TimeInterval of(Timestamp start, Timestamp end) { return TimeInterval.newBuilder() .setStart(start) .setEnd(end) .build(); } - public static TimeInterval timeInterval(String start, String end) { + public static TimeInterval of(String start, String end) { return TimeInterval.newBuilder() .setStart(fromISO8601(start)) .setEnd(fromISO8601(end)) diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TreatmentBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TreatmentBuilder.java index 4cf3946d..9404214a 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TreatmentBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TreatmentBuilder.java @@ -12,12 +12,12 @@ private TreatmentBuilder(OntologyClass agent) { builder = Treatment.newBuilder().setAgent(agent); } - public static Treatment treatment(OntologyClass agent) { + public static Treatment of(OntologyClass agent) { return Treatment.newBuilder().setAgent(agent).build(); } - public static Treatment treatment(String agentId, String agentLabel) { - return treatment(OntologyClassBuilder.ontologyClass(agentId, agentLabel)); + public static Treatment of(String agentId, String agentLabel) { + return of(OntologyClassBuilder.ontologyClass(agentId, agentLabel)); } public static TreatmentBuilder builder(OntologyClass agent) { diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TypedQuantityBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TypedQuantityBuilder.java index 158058b5..1e67040a 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TypedQuantityBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TypedQuantityBuilder.java @@ -9,7 +9,7 @@ public class TypedQuantityBuilder { private TypedQuantityBuilder() { } - public static TypedQuantity typedQuantity(OntologyClass type, Quantity quantity) { + public static TypedQuantity of(OntologyClass type, Quantity quantity) { return TypedQuantity.newBuilder().setType(type).setQuantity(quantity).build(); } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ValueBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ValueBuilder.java index f4ebb983..d84e96ba 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ValueBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/ValueBuilder.java @@ -12,32 +12,32 @@ public class ValueBuilder { private ValueBuilder() { } - public static Value value(String id, String label) { + public static Value of(String id, String label) { OntologyClass ontologyClass = OntologyClassBuilder.ontologyClass(id, label); - return value(ontologyClass); + return of(ontologyClass); } - public static Value value(OntologyClass ontologyClass) { + public static Value of(OntologyClass ontologyClass) { return Value.newBuilder().setOntologyClass(ontologyClass).build(); } - public static Value value(Quantity quantity) { + public static Value of(Quantity quantity) { return Value.newBuilder().setQuantity(quantity).build(); } - public static Value value(String id, String label, double value) { - Quantity quantity = QuantityBuilder.quantity(id, label, value); - return value(quantity); + public static Value of(String id, String label, double value) { + Quantity quantity = QuantityBuilder.of(id, label, value); + return of(quantity); } - public static Value value(OntologyClass ontologyClass, double value) { - Quantity quantity = QuantityBuilder.quantity(ontologyClass, value); - return value(quantity); + public static Value of(OntologyClass ontologyClass, double value) { + Quantity quantity = QuantityBuilder.of(ontologyClass, value); + return of(quantity); } - public static Value value(OntologyClass ontologyClass, double value, ReferenceRange ref) { - Quantity quantity = QuantityBuilder.quantity(ontologyClass, value, ref); - return value(quantity); + public static Value of(OntologyClass ontologyClass, double value, ReferenceRange ref) { + Quantity quantity = QuantityBuilder.of(ontologyClass, value, ref); + return of(quantity); } } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariantInterpretationBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariantInterpretationBuilder.java index 2e985087..88ad8da9 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariantInterpretationBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariantInterpretationBuilder.java @@ -13,7 +13,7 @@ private VariantInterpretationBuilder(VariationDescriptor descriptor) { builder = VariantInterpretation.newBuilder().setVariationDescriptor(descriptor); } - public static VariantInterpretation variantInterpretation(VariationDescriptor descriptor, AcmgPathogenicityClassification acmgPathogenicityClassification) { + public static VariantInterpretation of(VariationDescriptor descriptor, AcmgPathogenicityClassification acmgPathogenicityClassification) { return VariantInterpretation.newBuilder() .setVariationDescriptor(descriptor) .setAcmgPathogenicityClassification(acmgPathogenicityClassification) @@ -21,7 +21,7 @@ public static VariantInterpretation variantInterpretation(VariationDescriptor de .build(); } - public static VariantInterpretation variantInterpretation(VariationDescriptor descriptor, AcmgPathogenicityClassification acmgPathogenicityClassification, TherapeuticActionability therapeuticActionability) { + public static VariantInterpretation of(VariationDescriptor descriptor, AcmgPathogenicityClassification acmgPathogenicityClassification, TherapeuticActionability therapeuticActionability) { return VariantInterpretation.newBuilder() .setVariationDescriptor(descriptor) .setAcmgPathogenicityClassification(acmgPathogenicityClassification) diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariationDescriptorBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariationDescriptorBuilder.java index 153db950..fe7c631a 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariationDescriptorBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariationDescriptorBuilder.java @@ -149,13 +149,13 @@ public VariationDescriptorBuilder addExpression(Expression expression) { } public VariationDescriptorBuilder vcfHg38(String chromosome, int position, String ref, String alt) { - VcfRecord vcf = VcfRecordBuilder.vcfRecord("GRCh38", chromosome, position, ref, alt); + VcfRecord vcf = VcfRecordBuilder.of("GRCh38", chromosome, position, ref, alt); builder.setVcfRecord(vcf); return this; } public VariationDescriptorBuilder vcfHg37(String chromosome, int position, String ref, String alt) { - VcfRecord vcf = VcfRecordBuilder.vcfRecord("GRCh37", chromosome, position, ref, alt); + VcfRecord vcf = VcfRecordBuilder.of("GRCh37", chromosome, position, ref, alt); builder.setVcfRecord(vcf); return this; } @@ -166,18 +166,18 @@ public VariationDescriptorBuilder vcfHg37(String chromosome, int position, Strin * @param percentage estimated percentage of cells affected by mosaic variant, e.g., 40% */ public VariationDescriptorBuilder mosaicism(double percentage) { - Extension expression = Extensions.mosaicism(percentage); - builder.addExtensions(expression); + Extension percentageExtension = Extensions.mosaicism(percentage); + builder.addExtensions(percentageExtension); return this; } + /** - * @param percentage estimated frequency of an allele (generally a somatic mutation) 25% + * @param frequency estimated frequency (IN PERCENT) of an allele (generally a somatic mutation) */ - public VariationDescriptorBuilder alleleFrequency(double percentage) { - Expression expression = - Expression.newBuilder().setSyntax("allele-frequency").setValue(String.format("%.1f%%", percentage)).build(); - builder.addExpressions(expression); + public VariationDescriptorBuilder alleleFrequency(double frequency) { + Extension alleleFrequencyExtension = Extensions.alleleFrequency(frequency); + builder.addExtensions(alleleFrequencyExtension); return this; } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VcfRecordBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VcfRecordBuilder.java index bfd1c190..472c56b8 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VcfRecordBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VcfRecordBuilder.java @@ -15,7 +15,7 @@ private VcfRecordBuilder(String assembly, String chromosome, int position, Strin .setAlt(alt); } - public static VcfRecord vcfRecord(String assembly, String chromosome, int position, String ref, String alt) { + public static VcfRecord of(String assembly, String chromosome, int position, String ref, String alt) { return VcfRecord.newBuilder() .setGenomeAssembly(assembly) .setChrom(chromosome) diff --git a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AgeBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AgeBuilderTest.java index 6729abc4..aa714128 100644 --- a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AgeBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AgeBuilderTest.java @@ -15,7 +15,7 @@ class AgeBuilderTest { */ @Test void testAge() { - Age age = AgeBuilder.age("P25Y3M2D"); + Age age = Ages.age("P25Y3M2D"); assertThat(age.getIso8601Duration(), equalTo("P25Y3M2D")); } @@ -24,9 +24,9 @@ void testAge() { */ @Test void testAgeRange() { - AgeRange ageRange = AgeBuilder.ageRange("P45Y", "P49Y"); - assertThat(ageRange.getStart(), equalTo(AgeBuilder.age("P45Y"))); - assertThat(ageRange.getEnd(), equalTo(AgeBuilder.age("P49Y"))); + AgeRange ageRange = Ages.ageRange("P45Y", "P49Y"); + assertThat(ageRange.getStart(), equalTo(Ages.age("P45Y"))); + assertThat(ageRange.getEnd(), equalTo(Ages.age("P49Y"))); } /** @@ -34,7 +34,7 @@ void testAgeRange() { */ @Test void testGestationalAge() { - GestationalAge gestationalAge = AgeBuilder.gestationalAge(33, 2); + GestationalAge gestationalAge = Ages.gestationalAge(33, 2); assertThat(gestationalAge.getWeeks(), equalTo(33)); assertThat(gestationalAge.getDays(), equalTo(2)); } diff --git a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilderTest.java index 4890a1d9..3b918608 100644 --- a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilderTest.java @@ -12,10 +12,10 @@ class AlleleBuilderTest { @Test void testBuild() { Variation variation = AlleleBuilder.builder() - .setSequenceId("NC_000003.12") + .sequenceId("NC_000003.12") .startEnd(42686219, 42686220) .chromosomeLocation("chr3") - .setAltAllele("A") + .altAllele("A") .buildVariation(); assertThat(variation.hasAllele(), equalTo(true)); diff --git a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilderTest.java index e3eafb5b..17b3d3a4 100644 --- a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilderTest.java @@ -29,7 +29,7 @@ void biosampleBuilderTest() { .histologicalDiagnosis(ontologyClass("NCIT:C39853", "Infiltrating Urothelial Carcinoma")) .tumorProgression(ontologyClass("NCIT:C84509", "Primary Malignant Neoplasm")) .tumorGrade(ontologyClass("NCIT:C36136", "Grade 2 Lesion")) - .procedure(ProcedureBuilder.procedure("NCIT:C5189", "Radical Cystoprostatectomy")) + .procedure(ProcedureBuilder.of("NCIT:C5189", "Radical Cystoprostatectomy")) .addFile(FileBuilder.builder("file:///data/genomes/urothelial_ca_wgs.vcf.gz") .individualToFileIdentifier("patient1", "NA12345") .addFileAttribute("genomeAssembly", "GRCh38") @@ -48,7 +48,7 @@ void biosampleBuilderTest() { assertThat(biosample.getHistologicalDiagnosis(), equalTo(ontologyClass("NCIT:C39853", "Infiltrating Urothelial Carcinoma"))); assertThat(biosample.getTumorProgression(), equalTo(ontologyClass("NCIT:C84509", "Primary Malignant Neoplasm"))); assertThat(biosample.getTumorGrade(), equalTo(ontologyClass("NCIT:C36136", "Grade 2 Lesion"))); - assertThat(biosample.getProcedure(), equalTo(ProcedureBuilder.procedure("NCIT:C5189", "Radical Cystoprostatectomy"))); + assertThat(biosample.getProcedure(), equalTo(ProcedureBuilder.of("NCIT:C5189", "Radical Cystoprostatectomy"))); assertThat(biosample.getFilesList(), equalTo(List.of(FileBuilder.builder("file:///data/genomes/urothelial_ca_wgs.vcf.gz") .individualToFileIdentifier("patient1", "NA12345") .addFileAttribute("genomeAssembly", "GRCh38") diff --git a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilderTest.java index 379bb619..6c245dbd 100644 --- a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilderTest.java @@ -19,9 +19,9 @@ class ComplexValueBuilderTest { @Test void testComplexValue() { OntologyClass millimeterOfMercury = ontologyClass("NCIT:C49670", "Millimeter of Mercury"); - TypedQuantity systolicBloodPressure = TypedQuantityBuilder.typedQuantity(ontologyClass("NCIT:C25298", "Systolic Blood Pressure"), QuantityBuilder.quantity(millimeterOfMercury, 120)); - TypedQuantity diastolicBloodPressure = TypedQuantityBuilder.typedQuantity(ontologyClass("NCIT:C25299", "Diastolic Blood Pressure"), QuantityBuilder.quantity(millimeterOfMercury, 70)); - ComplexValue complexValue = ComplexValueBuilder.complexValue(systolicBloodPressure, diastolicBloodPressure); + TypedQuantity systolicBloodPressure = TypedQuantityBuilder.of(ontologyClass("NCIT:C25298", "Systolic Blood Pressure"), QuantityBuilder.of(millimeterOfMercury, 120)); + TypedQuantity diastolicBloodPressure = TypedQuantityBuilder.of(ontologyClass("NCIT:C25299", "Diastolic Blood Pressure"), QuantityBuilder.of(millimeterOfMercury, 70)); + ComplexValue complexValue = ComplexValueBuilder.of(systolicBloodPressure, diastolicBloodPressure); assertThat(complexValue.getTypedQuantitiesList(), equalTo(List.of(systolicBloodPressure, diastolicBloodPressure))); } diff --git a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiagnosisBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiagnosisBuilderTest.java index 64bc4bf7..755bb20d 100644 --- a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiagnosisBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiagnosisBuilderTest.java @@ -19,7 +19,7 @@ void testDiagnosisBuilder() { .heterozygous() .hgvs("NM_014915.2:c.-128G>A") .build(); - var col6a1VariantInterpretation = VariantInterpretationBuilder.variantInterpretation(variationDescriptor, Status.pathogenic()); + var col6a1VariantInterpretation = VariantInterpretationBuilder.of(variationDescriptor, Status.pathogenic()); var genomicInterpretationBuilder = GenomicInterpretationBuilder.builder("genomic interpretation id"); genomicInterpretationBuilder.causative(); diff --git a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilderTest.java index 5002696b..6cefcf80 100644 --- a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilderTest.java @@ -11,7 +11,7 @@ class DiseaseBuilderTest { @Test void testMinimalData() { - Disease disease = DiseaseBuilder.disease("MONDO:0004994", "cardiomyopathy"); + Disease disease = DiseaseBuilder.of("MONDO:0004994", "cardiomyopathy"); assertThat(disease.getTerm(), equalTo(ontologyClass("MONDO:0004994", "cardiomyopathy"))); } diff --git a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DoseIntervalBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DoseIntervalBuilderTest.java index d1a22e70..481a66f8 100644 --- a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DoseIntervalBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DoseIntervalBuilderTest.java @@ -15,11 +15,11 @@ public class DoseIntervalBuilderTest { @Test public void testDoseInterval1() { var mg = ontologyClass("UO:0000022", "milligram"); - var quantity = QuantityBuilder.quantity(mg, 30.0); + var quantity = QuantityBuilder.of(mg, 30.0); var administration = ontologyClass("NCIT:C38288", "Oral Route of Administration"); var bid = ontologyClass("NCIT:C64496", "Twice Daily"); - var interval = TimeIntervalBuilder.timeInterval("2019-03-20T00:00:00Z", "2021-03-20T00:00:00Z"); - DoseInterval dosage = DoseIntervalBuilder.doseInterval(quantity, bid, interval); + var interval = TimeIntervalBuilder.of("2019-03-20T00:00:00Z", "2021-03-20T00:00:00Z"); + DoseInterval dosage = DoseIntervalBuilder.of(quantity, bid, interval); assertEquals(30.0, dosage.getQuantity().getValue()); TimeInterval timeInterval = dosage.getInterval(); Timestamp start = timeInterval.getStart(); diff --git a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilderTest.java index 9e5c9315..48c9b6b3 100644 --- a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilderTest.java @@ -14,7 +14,7 @@ class TimeIntervalBuilderTest { */ @Test void timeIntervalFromStringTest() { - TimeInterval instance = TimeIntervalBuilder.timeInterval("2020-03-15T13:00:00Z", "2020-03-25T09:00:00Z"); + TimeInterval instance = TimeIntervalBuilder.of("2020-03-15T13:00:00Z", "2020-03-25T09:00:00Z"); assertThat(instance.getStart().getSeconds(), equalTo(1584277200L)); assertThat(instance.getEnd().getSeconds(), equalTo(1585126800L)); } @@ -23,7 +23,7 @@ void timeIntervalFromStringTest() { void timeIntervalFromTimestampTest() { Timestamp start = TimestampBuilder.fromISO8601("2020-03-15T13:00:00Z"); Timestamp end = TimestampBuilder.fromISO8601("2020-03-25T09:00:00Z"); - TimeInterval instance = TimeIntervalBuilder.timeInterval(start, end); + TimeInterval instance = TimeIntervalBuilder.of(start, end); assertThat(instance.getStart(), equalTo(start)); assertThat(instance.getEnd(), equalTo(end)); } diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/BethlehamMyopathy.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/BethlehamMyopathy.java index 785b8745..9d1c8796 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/BethlehamMyopathy.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/BethlehamMyopathy.java @@ -30,7 +30,7 @@ class BethlehamMyopathy implements PhenopacketExample { .hgvs("NM_001848.2:c.877G>A") .build(); var col6a1VariantInterpretation = - VariantInterpretationBuilder.variantInterpretation(variationDescriptor, Status.pathogenic()); + VariantInterpretationBuilder.of(variationDescriptor, Status.pathogenic()); var genomicInterpretation = GenomicInterpretationBuilder.builder(INTERPRETATION_ID) .causative() diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Covid.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Covid.java index b0c67f83..df5ab395 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Covid.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Covid.java @@ -38,17 +38,17 @@ class Covid implements PhenopacketExample { .vitalStatus(VitalStatusBuilder.deceased().causeOfDeath("MONDO:0100096", "COVID-19").build()) .build(); - Disease cardiomyopathy = DiseaseBuilder.disease("MONDO:0004994", "cardiomyopathy"); + Disease cardiomyopathy = DiseaseBuilder.of("MONDO:0004994", "cardiomyopathy"); Disease covid = DiseaseBuilder .builder("MONDO:0100096", "COVID-19") .onset(TimeElements.timestamp("2020-03-17T00:00:00Z")) .build(); - var bloodGroupA = PhenotypicFeatureBuilder.phenotypicFeature("HP:0032370", "Blood group A"); - var rhesusPositive = PhenotypicFeatureBuilder.phenotypicFeature("NCIT:C76251", "Rh Positive Blood Group"); - var obesityPhenotype = PhenotypicFeatureBuilder.phenotypicFeature(obesity); - var externalRef = ExternalReferenceBuilder.builder() + var bloodGroupA = PhenotypicFeatureBuilder.of("HP:0032370", "Blood group A"); + var rhesusPositive = PhenotypicFeatureBuilder.of("NCIT:C76251", "Rh Positive Blood Group"); + var obesityPhenotype = PhenotypicFeatureBuilder.of(obesity); + var externalRef = ExternalReferenceBuilder.reference() .id("DOI:10.1016/j.jaccas.2020.04.001") - .builder("PMID:32292915") + .reference("PMID:32292915") .description("The Imperfect Cytokine Storm: Severe COVID-19 With ARDS in a Patient on Durable LVAD Support") .build(); var metaData = MetaDataBuilder.builder("2021-08-17T00:00:00Z", "anonymous biocurator") @@ -129,15 +129,15 @@ private List getAllPhenotypicFeatures() { private List getAllMeasurements() { List measurements = new ArrayList<>(); - Value value = ValueBuilder.value(QuantityBuilder.quantity("NCIT:C67245", "Thousand Cells", 1.4)); + Value value = ValueBuilder.of(QuantityBuilder.of("NCIT:C67245", "Thousand Cells", 1.4)); var assay = ontologyClass("LOINC:26474-7", "Lymphocytes [#/volume] in Blood"); - var initialBloodLymphocyteCount = MeasurementBuilder.value(assay, value) + var initialBloodLymphocyteCount = MeasurementBuilder.builder(assay, value) .timeObserved(TimeElements.interval("2019-09-01T00:00:00Z", "2020-03-01T00:00:00Z")) .build(); measurements.add(initialBloodLymphocyteCount); - Value value2 = ValueBuilder.value(QuantityBuilder.quantity("NCIT:C67245", "Thousand Cells", 0.7)); + Value value2 = ValueBuilder.of(QuantityBuilder.of("NCIT:C67245", "Thousand Cells", 0.7)); - var hoD0bloodLymphocyteCount = MeasurementBuilder.value(assay, value2) + var hoD0bloodLymphocyteCount = MeasurementBuilder.builder(assay, value2) .timeObserved(TimeElements.timestamp(RETURN_TO_HOSPITAL_TIME)) .build(); measurements.add(hoD0bloodLymphocyteCount); @@ -145,14 +145,14 @@ private List getAllMeasurements() { } private MedicalAction nasalOxygenAdministered() { - Quantity twoLperMin = QuantityBuilder.quantity("NCIT:C67388", "Liter per Minute", 2); - var interval1 = DoseIntervalBuilder.doseInterval(twoLperMin, + Quantity twoLperMin = QuantityBuilder.of("NCIT:C67388", "Liter per Minute", 2); + var interval1 = DoseIntervalBuilder.of(twoLperMin, CONTINUOUS, - TimeIntervalBuilder.timeInterval("2021-02-01T18:58:43Z", "2021-02-02T08:22:42Z")); - Quantity fiftyLperMin = QuantityBuilder.quantity("NCIT:C67388", "Liter per Minute", 50); - var interval2 = DoseIntervalBuilder.doseInterval(fiftyLperMin, + TimeIntervalBuilder.of("2021-02-01T18:58:43Z", "2021-02-02T08:22:42Z")); + Quantity fiftyLperMin = QuantityBuilder.of("NCIT:C67388", "Liter per Minute", 50); + var interval2 = DoseIntervalBuilder.of(fiftyLperMin, CONTINUOUS, - TimeIntervalBuilder.timeInterval("2021-02-02T08:22:42Z", "2021-02-02T12:22:42Z")); + TimeIntervalBuilder.of("2021-02-02T08:22:42Z", "2021-02-02T12:22:42Z")); Treatment nasalOxygen = TreatmentBuilder.builder("NCIT:C722", "Oxygen") .routeOfAdministration(ontologyClass("NCIT:C38284", "Nasal Route of Administration")) .addDoseInterval(interval1) @@ -174,8 +174,8 @@ private MedicalAction trachealIntubation() { } private MedicalAction peepOxygenAdministered() { - Quantity quantity = QuantityBuilder.quantity("NCIT:C91060", "Centimeters of Water", 14); - var doseInterval = DoseIntervalBuilder.doseInterval(quantity, CONTINUOUS, "2020-03-22", "2020-03-28"); + Quantity quantity = QuantityBuilder.of("NCIT:C91060", "Centimeters of Water", 14); + var doseInterval = DoseIntervalBuilder.of(quantity, CONTINUOUS, "2020-03-22", "2020-03-28"); Treatment oxygen = TreatmentBuilder.builder(ontologyClass("NCIT:C722", "Oxygen")) .routeOfAdministration(ontologyClass("NCIT:C50254", "Positive end Expiratory Pressure Valve Device")) .addDoseInterval(doseInterval) @@ -184,9 +184,9 @@ private MedicalAction peepOxygenAdministered() { } private MedicalAction tocilizumabAdministered() { - Quantity quantity = QuantityBuilder.quantity("NCIT:C124458", "Milligram per Kilogram per Dose", 4); + Quantity quantity = QuantityBuilder.of("NCIT:C124458", "Milligram per Kilogram per Dose", 4); OntologyClass q4weeks = ontologyClass("NCIT:C64529", "Every Four Weeks"); - var doseInterval = DoseIntervalBuilder.doseInterval(quantity, q4weeks, "2020-03-24", "2020-03-28"); + var doseInterval = DoseIntervalBuilder.of(quantity, q4weeks, "2020-03-24", "2020-03-28"); var treatment = TreatmentBuilder.builder("NCIT:C84217", "Tocilizumab") .addDoseInterval(doseInterval) .build(); @@ -195,9 +195,9 @@ private MedicalAction tocilizumabAdministered() { private MedicalAction dexamethasone() { // ten days, 6 mg once a day - Quantity quantity = QuantityBuilder.quantity("UO:0000022", "milligram", 6); + Quantity quantity = QuantityBuilder.of("UO:0000022", "milligram", 6); OntologyClass onceDaily = ontologyClass("NCIT:C125004", "Once Daily"); - var doseInterval = DoseIntervalBuilder.doseInterval(quantity, onceDaily, "2020-03-20", "2020-03-30"); + var doseInterval = DoseIntervalBuilder.of(quantity, onceDaily, "2020-03-20", "2020-03-30"); Treatment dexa = TreatmentBuilder.builder("CHEBI:41879", "dexamethasone") .addDoseInterval(doseInterval) diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Marfan.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Marfan.java index ffe55020..ec6aaa41 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Marfan.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Marfan.java @@ -14,17 +14,17 @@ class Marfan implements PhenopacketExample { private final Phenopacket phenopacket; Marfan() { - var marfan = DiseaseBuilder.disease("OMIM:154700 ", "Marfan syndrome"); + var marfan = DiseaseBuilder.of("OMIM:154700 ", "Marfan syndrome"); var individual = IndividualBuilder.builder(PROBAND_ID).female().ageAtLastEncounter("P27Y").build(); var losartan = ontologyClass("DrugCentral:1610", "losartan"); var mg = ontologyClass("UO:0000022", "milligram"); var aorticAneurysm = - PhenotypicFeatureBuilder.phenotypicFeature("HP:0002616", "Aortic root aneurysm"); - var quantity = QuantityBuilder.quantity(mg, 30.0); + PhenotypicFeatureBuilder.of("HP:0002616", "Aortic root aneurysm"); + var quantity = QuantityBuilder.of(mg, 30.0); var administration = ontologyClass("NCIT:C38288", "Oral Route of Administration"); var bid = ontologyClass("NCIT:C64496", "Twice Daily"); - var interval = TimeIntervalBuilder.timeInterval("2019-03-20T00:00:00Z", "2021-03-20T00:00:00Z"); - var dosage = DoseIntervalBuilder.doseInterval(quantity, bid, interval); + var interval = TimeIntervalBuilder.of("2019-03-20T00:00:00Z", "2021-03-20T00:00:00Z"); + var dosage = DoseIntervalBuilder.of(quantity, bid, interval); var losartanTreatment = TreatmentBuilder .builder(losartan) .addDoseInterval(dosage) diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/NemalineMyopathyPrenatal.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/NemalineMyopathyPrenatal.java index aed615af..edcb8042 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/NemalineMyopathyPrenatal.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/NemalineMyopathyPrenatal.java @@ -122,9 +122,9 @@ GenomicInterpretation klhl40InterpretationV1() { //HGNC:30372 //abuilder.setSequenceId("ga4gh:VA.GuPzvZoansqNHPoXkQLXKo31VkTpDKsM"); Variation variation = AlleleBuilder.builder() - .setSequenceId("NC_000003.12") + .sequenceId("NC_000003.12") .startEnd(42686219, 42686220) - .setAltAllele("A") + .altAllele("A") .buildVariation(); VariationDescriptorBuilder vbuilder = VariationDescriptorBuilder.builder("rs397509420") .variation(variation) @@ -160,9 +160,9 @@ GenomicInterpretation klhl40InterpretationV2() { // dbSNP: rs778022582 //HGNC:30372 AlleleBuilder abuilder = AlleleBuilder.builder() - .setSequenceId("NC_000003.12") + .sequenceId("NC_000003.12") .startEnd( 42688962, 42688963) - .setAltAllele("C"); + .altAllele("C"); VariationDescriptorBuilder vbuilder = VariationDescriptorBuilder.builder("rs778022582") .variation(abuilder.buildVariation()) .genomic() diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java index a3849afc..e02f1127 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java @@ -38,7 +38,9 @@ public Retinoblastoma() { XX(). build(); // VCF file with results of germline whole-genome sequencing - File wgsFile = FileBuilder.file("file://data/germlineWgs.vcf.gz"); + File wgsFile = FileBuilder.hg38vcf("file://data/germlineWgs.vcf.gz") + .individualToFileIdentifier(PROBAND_ID, "sample1") + .build(); phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metadata) .individual(proband) @@ -70,10 +72,9 @@ Interpretation interpretation() { */ GenomicInterpretation somaticRb1Missense() { AlleleBuilder abuilder = AlleleBuilder.builder(); - // abuilder.setSequenceId("ga4gh:VA.GuPzvZoansqNHPoXkQLXKo31VkTpDKsM"); - abuilder.setSequenceId("refseq:NC_000013.14"); + abuilder.sequenceId("refseq:NC_000013.14"); abuilder.startEnd( 48941647, 48941648); - abuilder.setAltAllele("T"); + abuilder.altAllele("T"); VariationDescriptorBuilder vbuilder = VariationDescriptorBuilder.builder("rs121913300") .variation(abuilder.buildVariation()) .genomic() @@ -82,7 +83,7 @@ GenomicInterpretation somaticRb1Missense() { .transcript() .vcfHg38("NC_000013.11", 48367512, "C", "T") .alleleFrequency(25.0) - .geneContext(GeneDescriptorBuilder.geneDescriptor("HGNC:9884", "RB1")) + .geneContext(GeneDescriptorBuilder.of("HGNC:9884", "RB1")) .addExpression(Expressions.hgvsCdna("NM_000321.2:c.958C>T")) .addExpression(Expressions.transcriptReference("NM_000321.2")); // wrap in VariantInterpretation @@ -90,7 +91,6 @@ GenomicInterpretation somaticRb1Missense() { vibuilder.pathogenic(); vibuilder.actionable(); - GenomicInterpretationBuilder gbuilder = GenomicInterpretationBuilder.builder(BIOSAMPLE_ID); gbuilder.causative(); gbuilder.variantInterpretation(vibuilder); @@ -102,11 +102,14 @@ GenomicInterpretation somaticRb1Missense() { GenomicInterpretation germlineRb1Deletion() { CopyNumberBuilder abuilder = CopyNumberBuilder.builder(); //abuilder.copyNumberId("ga4gh:VCN.AFfJws1M4Lg8w1O3XknmHYc9TU2hHYpp"); - abuilder.alleleLocation("refseq:NC_000013.14",26555377, 62280955);//VRS uses inter-residue coordinates + // original coordinates in paper were given as 13q12.13q21.2(26,555,387–62,280,955 for hg19 + //chr13 25981249 61706822 -- lifted over to hg38 + + abuilder.alleleLocation("refseq:NC_000013.14",25981249, 61706822);//VRS uses inter-residue coordinates abuilder.oneCopy(); VariationDescriptorBuilder vbuilder = VariationDescriptorBuilder.builder(); vbuilder.variation(abuilder.buildVariation()); - // vbuilder.mosaicism(40.0); + vbuilder.mosaicism(40.0); VariantInterpretationBuilder vibuilder = VariantInterpretationBuilder.builder(vbuilder); vibuilder.pathogenic(); vibuilder.actionable(); @@ -162,8 +165,8 @@ Biosample enucleatedEye() { biosampleBuilder.addPhenotypicFeature("NCIT:C35941", "Flexner-Wintersteiner Rosette Formation"); biosampleBuilder.addPhenotypicFeature("NCIT:C132485", "Apoptosis and Necrosis"); OntologyClass maxTumorSizeTest = OntologyClassBuilder.ontologyClass("LOINC:33728-7", "Size.maximum dimension in Tumor"); - Value maxTumorSize = ValueBuilder.value(Unit.mm(), 15); - Measurement maxTumorSizeMeasurement = MeasurementBuilder.value(maxTumorSizeTest, maxTumorSize).timeObserved(age).build(); + Value maxTumorSize = ValueBuilder.of(Unit.mm(), 15); + Measurement maxTumorSizeMeasurement = MeasurementBuilder.builder(maxTumorSizeTest, maxTumorSize).timeObserved(age).build(); biosampleBuilder.addMeasurement(maxTumorSizeMeasurement); Procedure enucleation = ProcedureBuilder.builder("NCIT:C48601", "Enucleation") @@ -173,7 +176,9 @@ Biosample enucleatedEye() { biosampleBuilder.procedure(enucleation); biosampleBuilder.tumorProgression(PRIMARY_NEOPLASM); // VCF file with results of whole-genome sequencing on this tumor - File wgsFile = FileBuilder.file("file://data/fileSomaticWgs.vcf.gz"); + File wgsFile = FileBuilder.hg38vcf("file://data/fileSomaticWgs.vcf.gz") + .individualToFileIdentifier(BIOSAMPLE_ID, "specimen.1") + .build(); biosampleBuilder.addFile(wgsFile); return biosampleBuilder.build(); } @@ -184,11 +189,11 @@ MedicalAction melphalan() { OntologyClass melphalan = ontologyClass("DrugCentral:1678", "melphalan"); OntologyClass administration = ontologyClass("NCIT:C38222", "Intraarterial Route of Administration"); //0.4 mg/kg (up to a starting dose of 5 mg) - Quantity quantity = QuantityBuilder.quantity(Unit.mgPerKg(), 0.4); - TimeInterval interval = TimeIntervalBuilder.timeInterval("2020-09-02", "2020-09-02"); + Quantity quantity = QuantityBuilder.of(Unit.mgPerKg(), 0.4); + TimeInterval interval = TimeIntervalBuilder.of("2020-09-02", "2020-09-02"); OntologyClass once = ontologyClass("NCIT:C64576", "Once"); - DoseInterval doseInterval = DoseIntervalBuilder.doseInterval(quantity, once, interval); + DoseInterval doseInterval = DoseIntervalBuilder.of(quantity, once, interval); Treatment treatment = TreatmentBuilder.builder(melphalan) @@ -289,17 +294,17 @@ List getPhenotypicFeatures() { */ List getMeasurements() { OntologyClass iop = ontologyClass("56844-4","Intraocular pressure of Eye"); - ReferenceRange ref = ReferenceRangeBuilder.referenceRange(iop, 10, 21); + ReferenceRange ref = ReferenceRangeBuilder.of(iop, 10, 21); OntologyClass leftEyeIop = OntologyClassBuilder.ontologyClass("LOINC:79893-4", "Left eye Intraocular pressure"); - Value leftEyeValue = ValueBuilder.value(Unit.mmHg(), 25, ref); + Value leftEyeValue = ValueBuilder.of(Unit.mmHg(), 25, ref); OntologyClass rightEyeIop = OntologyClassBuilder.ontologyClass("LOINC:79892-6", "Right eye Intraocular pressure"); - Value rightEyeValue = ValueBuilder.value(Unit.mmHg(), 15, ref); + Value rightEyeValue = ValueBuilder.of(Unit.mmHg(), 15, ref); TimeElement age = TimeElements.age("P6M"); - Measurement leftEyeMeasurement = MeasurementBuilder.value(leftEyeIop, leftEyeValue).timeObserved(age).build(); - Measurement rightEyeMeasurement = MeasurementBuilder.value(rightEyeIop, rightEyeValue).timeObserved(age).build(); + Measurement leftEyeMeasurement = MeasurementBuilder.builder(leftEyeIop, leftEyeValue).timeObserved(age).build(); + Measurement rightEyeMeasurement = MeasurementBuilder.builder(rightEyeIop, rightEyeValue).timeObserved(age).build(); //33728-7 Size.maximum dimension in Tumor //14 × 13 × 11 mm left eye tumor return List.of(leftEyeMeasurement, rightEyeMeasurement); diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Thrombocytopenia2.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Thrombocytopenia2.java index ba0d8e0d..97d76747 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Thrombocytopenia2.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Thrombocytopenia2.java @@ -28,7 +28,7 @@ class Thrombocytopenia2 implements PhenopacketExample { .heterozygous() .hgvs("NM_014915.2:c.-128G>A") .build(); - var col6a1VariantInterpretation = VariantInterpretationBuilder.variantInterpretation(variationDescriptor, Status.pathogenic()); + var col6a1VariantInterpretation = VariantInterpretationBuilder.of(variationDescriptor, Status.pathogenic()); var genomicInterpretation = GenomicInterpretationBuilder.builder("genomic interpretation id") .causative() diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/UrothelialCancer.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/UrothelialCancer.java index 5f9e0cc0..72fe95ab 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/UrothelialCancer.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/UrothelialCancer.java @@ -19,7 +19,7 @@ class UrothelialCancer implements PhenopacketExample { UrothelialCancer() { var individual = IndividualBuilder.builder(PROBAND_ID).male().dateOfBirth("1964-03-15T00:00:00Z").build(); - var hematuria = PhenotypicFeatureBuilder.phenotypicFeature("HP:0000790","Hematuria"); + var hematuria = PhenotypicFeatureBuilder.of("HP:0000790","Hematuria"); var dsyuria = PhenotypicFeatureBuilder.builder("HP:0100518", "Dysuria") .severity(Severity.severe()) .build(); diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlOutputter.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlOutputter.java index bae9e749..b8b6862b 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlOutputter.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlOutputter.java @@ -219,11 +219,4 @@ private String row(List fields) { } - private void outputSection(Writer writer, String Title, Map kv) { - - } - - - - } diff --git a/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java b/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java index bc8c64f7..ac6473ce 100644 --- a/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java +++ b/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java @@ -4,15 +4,16 @@ import org.junit.jupiter.api.Test; import org.phenopackets.phenopackettools.converter.converters.PhenopacketConverter; -class PhenopacketConverterTest { +import static org.junit.jupiter.api.Assertions.assertNotNull; +class PhenopacketConverterTest { + /** + * To output: System.out.println(JsonFormat.printer().print(v2Phenopacket)); + */ @Test - void name() throws InvalidProtocolBufferException { + void name() { org.phenopackets.schema.v1.Phenopacket v1Phenopacket = BethlemMyopathyV1.proband(); - org.phenopackets.schema.v2.Phenopacket v2Phenopacket = PhenopacketConverter.toV2Phenopacket(v1Phenopacket); - -// System.out.println(JsonFormat.printer().print(v1Phenopacket)); -// System.out.println(JsonFormat.printer().print(v2Phenopacket)); + assertNotNull(v2Phenopacket); } } \ No newline at end of file From 96a0ac523e776bb164104fa8db3092cc19791100 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Thu, 21 Apr 2022 17:59:17 -0400 Subject: [PATCH 034/155] Adding GNU3 license --- LICENSE | 677 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 677 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..0a170278 --- /dev/null +++ b/LICENSE @@ -0,0 +1,677 @@ +Copyright (c) 2022, Global Alliance for Genomics and Health + All rights reserved. + + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. \ No newline at end of file From 4a624cfa678219e14a179d8ea59bb71ddbc951b2 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Thu, 21 Apr 2022 18:07:55 -0400 Subject: [PATCH 035/155] cleanup --- .../builder/builders/IndividualBuilder.java | 10 ++++++++++ .../converter/PhenopacketConverterTest.java | 1 - 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilder.java index 32079ab7..6a54534d 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilder.java @@ -91,6 +91,16 @@ public IndividualBuilder female() { return this; } + public IndividualBuilder unknownSex() { + builder.setSex(Sex.UNKNOWN_SEX); + return this; + } + + public IndividualBuilder otherSex() { + builder.setSex(Sex.OTHER_SEX); + return this; + } + public IndividualBuilder XX() { builder.setKaryotypicSex(KaryotypicSex.XX); return this; diff --git a/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java b/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java index ac6473ce..d6b10593 100644 --- a/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java +++ b/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java @@ -1,6 +1,5 @@ package org.phenopackets.phenopackettools.converter; -import com.google.protobuf.InvalidProtocolBufferException; import org.junit.jupiter.api.Test; import org.phenopackets.phenopackettools.converter.converters.PhenopacketConverter; From 8bcdaf9f89a68c5baba3b15a4b69dc90f4a172db Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Sat, 23 Apr 2022 09:03:16 -0400 Subject: [PATCH 036/155] updating TNM --- .../phenopackettools/examples/Retinoblastoma.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java index e02f1127..c8eae4fb 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java @@ -158,9 +158,9 @@ Biosample enucleatedEye() { BiosampleBuilder biosampleBuilder = BiosampleBuilder.builder(BIOSAMPLE_ID); biosampleBuilder.sampledTissue(EYE); //Retinoblastoma with tumor invading optic nerve past lamina cribrosa but not to surgical resection line and exhibiting massive choroidal invasion. - biosampleBuilder.addPathologicalTnmFinding(ontologyClass("NCIT:C88735", "Retinoblastoma pT3b TNM Finding v7")); + biosampleBuilder.addPathologicalTnmFinding(ontologyClass("NCIT:C140720", "Retinoblastoma pT3 TNM Finding v8")); //Retinoblastoma with no regional lymph node involvement. - biosampleBuilder.addPathologicalTnmFinding(ontologyClass("NCIT:C88741","Retinoblastoma pN0 TNM Finding v7")); + biosampleBuilder.addPathologicalTnmFinding(ontologyClass("NCIT:C140711","Retinoblastoma pN0 TNM Finding v8")); biosampleBuilder.addPhenotypicFeature("NCIT:C35941", "Flexner-Wintersteiner Rosette Formation"); biosampleBuilder.addPhenotypicFeature("NCIT:C132485", "Apoptosis and Necrosis"); From e6db5a354ccc0bc6d05c35709c4a9683745c8a4c Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Tue, 26 Apr 2022 07:43:42 -0400 Subject: [PATCH 037/155] fixing position --- .../phenopackettools/examples/Retinoblastoma.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java index c8eae4fb..b7dd471d 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java @@ -72,8 +72,8 @@ Interpretation interpretation() { */ GenomicInterpretation somaticRb1Missense() { AlleleBuilder abuilder = AlleleBuilder.builder(); - abuilder.sequenceId("refseq:NC_000013.14"); - abuilder.startEnd( 48941647, 48941648); + abuilder.sequenceId("refseq:NC_000013.11"); + abuilder.startEnd( 48367511, 48367512); abuilder.altAllele("T"); VariationDescriptorBuilder vbuilder = VariationDescriptorBuilder.builder("rs121913300") .variation(abuilder.buildVariation()) From 48f1e5e9331eeb247c3235c22e17aad4339b29d0 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Mon, 9 May 2022 11:48:43 -0400 Subject: [PATCH 038/155] new example started --- .../examples/SleKidneyTransplantation.java | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SleKidneyTransplantation.java diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SleKidneyTransplantation.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SleKidneyTransplantation.java new file mode 100644 index 00000000..2fbd60ae --- /dev/null +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SleKidneyTransplantation.java @@ -0,0 +1,54 @@ +package org.phenopackets.phenopackettools.examples; + +import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; +import org.phenopackets.phenopackettools.builder.builders.IndividualBuilder; +import org.phenopackets.phenopackettools.builder.builders.MetaDataBuilder; +import org.phenopackets.phenopackettools.builder.builders.Resources; +import org.phenopackets.schema.v2.Phenopacket; +import org.phenopackets.schema.v2.core.Individual; +import org.phenopackets.schema.v2.core.OntologyClass; + +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; + +/** + * Pavlakou P, et al. Case Report: Kidney Transplantation in a Patient With Acquired Agammaglobulinemia and SLE. + * Issues and Challenges. Front Med (Lausanne). 2021 Mar 12;8:665475. + * PMID: 33777986. + */ +public class SleKidneyTransplantation implements PhenopacketExample { + private static final String PHENOPACKET_ID = "arbitrary.id"; + private static final String PROBAND_ID = "proband A"; + private static final String BIOSAMPLE_ID = "biosample.1"; + private static final OntologyClass BIOPSY = ontologyClass("NCIT:C15189", "Biopsy"); + private static final OntologyClass SYSTEMIC_LUPUS = ontologyClass("MONDO:0007915", "systemic lupus erythematosus"); + private static final OntologyClass PRIMARY_NEOPLASM = ontologyClass("NCIT:C8509", "Primary Neoplasm"); + + // Organs + private static final OntologyClass EYE = ontologyClass("UBERON:0000970", "eye"); + private static final OntologyClass CURE = ontologyClass("NCIT:C62220", "Cure"); + private static final OntologyClass LEFT_EYE = ontologyClass("UBERON:0004548", "left eye"); + + private final Phenopacket phenopacket; + + public SleKidneyTransplantation() { + var metadata = MetaDataBuilder.builder("2021-05-14T10:35:00Z", "anonymous biocurator") + .addResource(Resources.ncitVersion("21.05d")) + .addResource(Resources.efoVersion("3.34.0")) + .addResource(Resources.uberonVersion("2021-07-27")) + .addResource(Resources.ncbiTaxonVersion("2021-06-10")) + .build(); + Individual proband = IndividualBuilder.builder(PROBAND_ID). + ageAtLastEncounter("P39Y"). + female(). + build(); + phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metadata) + .individual(proband) + .build(); + } + + + @Override + public Phenopacket getPhenopacket() { + return phenopacket; + } +} From acc40fe7c7defb016211699ef9beefb7162d189a Mon Sep 17 00:00:00 2001 From: pnrobinson Date: Sun, 1 May 2022 12:43:47 -0400 Subject: [PATCH 039/155] glaucoma example framework --- .../command/ExamplesCommand.java | 1 + .../examples/GlaucomaSurgery.java | 31 +++++++++++++++++++ .../examples/PhenopacketExamples.java | 2 ++ 3 files changed, 34 insertions(+) create mode 100644 phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/GlaucomaSurgery.java diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java index 08f039ae..423534be 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java @@ -120,6 +120,7 @@ private int outputAllPhenopackets() { output(PhenopacketExamples.thrombocytopenia2(), outDirectory, "thrombocytopenia2"); output(PhenopacketExamples.marfanSyndrome(), outDirectory, "marfan"); output(PhenopacketExamples.acuteMyeloidLeukemia(), outDirectory, "nemalineMyopathy"); + output(PhenopacketExamples.GLAUCOMA, outDirectory, "glaucoma"); output(PhenopacketExamples.squamousCellEsophagealCarcinoma(), outDirectory, "squamous-cell-esophageal-carcinoma"); output(PhenopacketExamples.urothelialCarcinoma(), outDirectory, "urothelial-cancer"); output(PhenopacketExamples.covid19(), outDirectory, "covid"); diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/GlaucomaSurgery.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/GlaucomaSurgery.java new file mode 100644 index 00000000..a6dc97cc --- /dev/null +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/GlaucomaSurgery.java @@ -0,0 +1,31 @@ +package org.phenopackets.phenopackettools.examples; + +import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; +import org.phenopackets.phenopackettools.builder.builders.MetaDataBuilder; +import org.phenopackets.phenopackettools.builder.builders.Resources; +import org.phenopackets.schema.v2.Phenopacket; + +public class GlaucomaSurgery implements PhenopacketExample { + private static final String PHENOPACKET_ID = "arbitrary.id"; + + private final Phenopacket phenopacket; + + + public GlaucomaSurgery() { + var metadata = MetaDataBuilder.builder("2021-05-14T10:35:00Z", "anonymous biocurator") + .addResource(Resources.ncitVersion("21.05d")) + .addResource(Resources.efoVersion("3.34.0")) + .addResource(Resources.uberonVersion("2021-07-27")) + .addResource(Resources.ncbiTaxonVersion("2021-06-10")) + .build(); + + PhenopacketBuilder builder = PhenopacketBuilder.create(PHENOPACKET_ID, metadata); + + phenopacket = builder.build(); + } + + @Override + public Phenopacket getPhenopacket() { + return phenopacket; + } +} diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/PhenopacketExamples.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/PhenopacketExamples.java index 8ef52ddf..9b17a3d8 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/PhenopacketExamples.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/PhenopacketExamples.java @@ -13,6 +13,8 @@ public class PhenopacketExamples { public static final Phenopacket COVID_19 = new Covid().getPhenopacket(); public static final Phenopacket RETINOBLASTOMA = new Retinoblastoma().getPhenopacket(); public static final Phenopacket NEMALINE_MYOPATHY = new NemalineMyopathyPrenatal().getPhenopacket(); + public static final Phenopacket GLAUCOMA = new GlaucomaSurgery().getPhenopacket(); + private PhenopacketExamples() { } From a7aa27baa975102062916c5c55efb61e6228a394 Mon Sep 17 00:00:00 2001 From: Tudor Groza Date: Thu, 21 Apr 2022 19:37:03 +0800 Subject: [PATCH 040/155] WIP - First PXF example. --- .../PneumothoraxSecondaryToCOVID.java | 215 ++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/PneumothoraxSecondaryToCOVID.java diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/PneumothoraxSecondaryToCOVID.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/PneumothoraxSecondaryToCOVID.java new file mode 100644 index 00000000..3d53aa11 --- /dev/null +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/PneumothoraxSecondaryToCOVID.java @@ -0,0 +1,215 @@ +package org.phenopackets.phenotools.examples; + +import org.phenopackets.phenotools.builder.PhenopacketBuilder; +import org.phenopackets.phenotools.builder.builders.*; +import org.phenopackets.schema.v2.Phenopacket; +import org.phenopackets.schema.v2.core.*; + +import java.util.ArrayList; +import java.util.List; + +public class PneumothoraxSecondaryToCOVID { + + private static final String PHENOPACKET_ID = "arbitrary.id"; + private static final String PROBAND_ID = "proband A"; + + // Organs + + private final Phenopacket phenopacket; + + public PneumothoraxSecondaryToCOVID() { + + //TODO: Fix ontology versions + var metadata = MetaDataBuilder.builder("2022-04-21T10:35:00Z", "anonymous biocurator") + .resource(Resources.ncitVersion("21.05d")) + .resource(Resources.hpoVersion("2021-08-02")) + .resource(Resources.efoVersion("3.34.0")) + .resource(Resources.uberonVersion("2021-07-27")) + .resource(Resources.ncbiTaxonVersion("2021-06-10")) + .build(); + + Individual proband = IndividualBuilder.builder(PROBAND_ID). + ageAtLastEncounter("P36Y"). + male(). + build(); + + phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metadata) + .individual(proband) + .addAllPhenotypicFeatures(getMedicalHistory()) + .addAllPhenotypicFeatures(getLast3WeekHistory()) + .addAllPhenotypicFeatures(getSymptomsOnPresentation()) + .addAllMeasurements(getMeasurementsOnPresentation()) + .addAllPhenotypicFeatures(getChestRadiograph()) + .build(); + + } + + /** + * A 12-lead ECG showed a sinus tachycardia at 155 beats/min. + * + * The patient’s full blood count demonstrated a raised white cell count (13.64×109/L) with a neutrophilia (8.91×109/L), lymphocyte count (3.81×109/L), haemoglobin (146g/L), and platelets (1051×109/L); biochemical markers demonstrated a raised C-reactive protein (28.7mg/L) and alanine aminotransferase (107IU/L). + * Diagnosis: tension pneumothorax, secondary to underlying COVID-19 + * + * Treatment: + * emergency needle decompression: + * - 14-gauge cannula inserted in the second rib space and mid-clavicular line + * - 12-French Seldinger chest drain inserted into the patients left axilla + * + * Outcome: + * repeat chest radiograph => lung re-expansion + * Within an hour the patient’s oxygen requirement reduced to 4L/min via nasal cannula + * normalisation of respiratory and heart rate. + */ + + + /** + * Emergency portable chest radiograph + * - large left-sided pneumothorax with mediastinal shift + * - radiological signs of tension + * - right lung compressed BUT widespread patchy consolidative changes + */ + + private List getChestRadiograph() { + // How to associate phenotypes with procedures? + + return new ArrayList<>(); + } + + /** + * On presentation: << How to specify the temporal element? + * - SpO2 of 88% on 15L/min oxygen via non-rebreathe mask + * - respiratory rate of 50 breaths per minute + * - heart rate of 150 beats/min + * - blood pressure of 110/65 mm Hg + */ + private List getMeasurementsOnPresentation() { + OntologyClass respiratoryRate = OntologyClassBuilder.ontologyClass("LOINC:9279-1", "Respiratory rate"); + + // Couldn't find 'breaths per minute' as a measurement unit and UCUM has not been published. + // This applies to all measurements below + Value respiratoryRateValue = ValueBuilder.value("UCUM:{breaths}/min", "Breaths/minute", 50); + + // Time observed: on presentation? This applies to all measurements below + Measurement respiratoryRateMeasurement = MeasurementBuilder. + value(respiratoryRate, respiratoryRateValue). + build(); + + OntologyClass heartRate = OntologyClassBuilder.ontologyClass("LOINC:8867-4", "Heart rate"); + Value heartRateValue = ValueBuilder.value("UCUM:{beats}/min", "Beats/minute", 150); + Measurement heartRateMeasurement = MeasurementBuilder. + value(heartRate, heartRateValue). + build(); + + OntologyClass systBloodPressure = OntologyClassBuilder.ontologyClass("LOINC:8480-6", "Systolic blood pressure"); + Value systBloodPressureValue = ValueBuilder.value("UCUM:mm[Hg]", "mm[Hg]", 110); + Measurement systBloodPressureMeasurement = MeasurementBuilder. + value(systBloodPressure, systBloodPressureValue). + build(); + + OntologyClass diastBloodPressure = OntologyClassBuilder.ontologyClass("LOINC:8480-6", "Systolic blood pressure"); + Value diastBloodPressureValue = ValueBuilder.value("UCUM:mm[Hg]", "mm[Hg]", 65); + Measurement diastBloodPressureMeasurement = MeasurementBuilder. + value(diastBloodPressure, diastBloodPressureValue). + build(); + + + // How to define the 'intervention' component SpO2 of 88% << on 15L/min oxygen via non-rebreathe mask >> + // It's not a procedure + + OntologyClass spO2 = OntologyClassBuilder.ontologyClass("LOINC:20564-1", "Oxygen saturation in Blood"); + Value spO2Value = ValueBuilder.value("UCUM:%", "%", 88); + Measurement spO2Measurement = MeasurementBuilder. + value(spO2, spO2Value). + build(); + + + return List.of(respiratoryRateMeasurement, + heartRateMeasurement, + systBloodPressureMeasurement, + diastBloodPressureMeasurement, + spO2Measurement); + } + + /** + * On presentation: << How to represent this from a temporal perspective? + * - hypoxaemic + * - tachycardic + * - left-sided pleuritic chest pain + * - trachea remained central + *

+ * On ascultation: + * - no audible breath sounds of the left hemithorax + * - reduced vocal fremitus + * - asymmetrical chest expansion + */ + private List getSymptomsOnPresentation() { + PhenotypicFeature hypoxemia = PhenotypicFeatureBuilder. + builder("HP:0012418", "Hypoxemia"). + build(); + + PhenotypicFeature tachycardia = PhenotypicFeatureBuilder. + builder("HP:0001649", "Tachycardia"). + build(); + + PhenotypicFeature chestPain = PhenotypicFeatureBuilder. + builder("HP:0033771", "Pleuritic chest pain"). + modifier(Laterality.left()). + build(); + + PhenotypicFeature trachea = PhenotypicFeatureBuilder. + builder("HP:0002778", "Abnormal tracheal morphology"). + excluded(). + build(); + + // How to combine a procedure < ascultation > with phenotypic features? + + return List.of(hypoxemia, tachycardia, chestPain, trachea); + } + + /** + * medical history: + * - Childhood asthma + * - 10 pack-year history of smoking << How to represent this !? + * - NO history of trauma << Did I represent correct the absence of the phenotype? + * - NO history of pneumothoraces + */ + private List getMedicalHistory() { + PhenotypicFeature asthma = PhenotypicFeatureBuilder. + builder("HP:0002099", "Asthma"). + childhoodOnset(). + build(); + PhenotypicFeature trauma = PhenotypicFeatureBuilder. + builder("SCTID:417746004", "Trauma"). + excluded(). + build(); + PhenotypicFeature pneumothorax = PhenotypicFeatureBuilder. + builder("HP:0002107", "Pneumothorax"). + excluded(). + build(); + + return List.of(asthma, trauma, pneumothorax); + } + + /** + * 3-week history: << How to represent relative time periods? + * - cough + * - fevers + * - shortness of breath + */ + private List getLast3WeekHistory() { + PhenotypicFeature cough = PhenotypicFeatureBuilder. + builder("HP:0012735", "Cough"). + build(); + + PhenotypicFeature fever = PhenotypicFeatureBuilder. + builder("HP:0001945", "Fever"). + build(); + + PhenotypicFeature dyspnea = PhenotypicFeatureBuilder. + builder("HP:0002094", "Dyspnea"). + build(); + + return List.of(cough, fever, dyspnea); + } + +} From 7d281ff95d48fdbcdd6a26d9507861f6d029e6b9 Mon Sep 17 00:00:00 2001 From: Tudor Groza Date: Mon, 25 Apr 2022 23:07:53 +0800 Subject: [PATCH 041/155] WIP - First PXF examples. --- ...rvicofacialActinomycosisOfTheMandible.java | 170 ++++++++++++++++++ ...ngSyndromeWithMultifocalOsteonecrosis.java | 165 +++++++++++++++++ .../PneumothoraxSecondaryToCOVID.java | 138 ++++++++++---- ...SevereStatinInducedAutoimmuneMyopathy.java | 162 +++++++++++++++++ 4 files changed, 605 insertions(+), 30 deletions(-) create mode 100644 phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/CervicofacialActinomycosisOfTheMandible.java create mode 100644 phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/CushingSyndromeWithMultifocalOsteonecrosis.java create mode 100644 phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/SevereStatinInducedAutoimmuneMyopathy.java diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/CervicofacialActinomycosisOfTheMandible.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/CervicofacialActinomycosisOfTheMandible.java new file mode 100644 index 00000000..503f4e30 --- /dev/null +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/CervicofacialActinomycosisOfTheMandible.java @@ -0,0 +1,170 @@ +package org.phenopackets.phenotools.examples; + +import org.phenopackets.phenotools.builder.PhenopacketBuilder; +import org.phenopackets.phenotools.builder.builders.*; +import org.phenopackets.schema.v2.Phenopacket; +import org.phenopackets.schema.v2.core.Individual; +import org.phenopackets.schema.v2.core.Interpretation; +import org.phenopackets.schema.v2.core.MedicalAction; +import org.phenopackets.schema.v2.core.PhenotypicFeature; + +import java.util.List; + +import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; + +public class CervicofacialActinomycosisOfTheMandible { + + + private static final String PHENOPACKET_ID = "arbitrary.id"; + private static final String INDIVIDUAL = "individual A"; + + private final Phenopacket phenopacket; + + public CervicofacialActinomycosisOfTheMandible() { + + var externalRef = ExternalReferenceBuilder.builder() + .id("DOI:10.1136/bcr-2019-233681") + .builder("PMID:32467116") + .description("Cervicofacial actinomycosis of the mandible in a paediatric patient") + .build(); + + //TODO: Fix ontology versions + var metadata = MetaDataBuilder.builder("2022-04-21T10:35:00Z", "anonymous biocurator") + .resource(Resources.ncitVersion("21.05d")) + .resource(Resources.hpoVersion("2021-08-02")) + .resource(Resources.efoVersion("3.34.0")) + .resource(Resources.uberonVersion("2021-07-27")) + .resource(Resources.ncbiTaxonVersion("2021-06-10")) + .externalReference(externalRef) + .build(); + + Individual proband = IndividualBuilder.builder(INDIVIDUAL). + ageAtLastEncounter("P10Y"). + female(). + build(); + + phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metadata) + .individual(proband) + .addAllPhenotypicFeatures(getMedicalHistory()) + .addAllPhenotypicFeatures(getLast8Monthsistory()) + .addMedicalAction(neckCT()) + .addMedicalAction(mri()) + .addPhenotypicFeature(examination()) + .addInterpretation(interpretation()) + .addMedicalAction(biopsy()) + .addMedicalAction(frozenSection()) + .addMedicalAction(tissueCultures()) + .addMedicalAction(anaerobicCultures()) + .addMedicalAction(treatment()) + .build(); + } + + /** + * - Expanded medullary spaces with oedema and vascular proliferation + * - No cytological atypia + * - negative for D2-40 and PROX1 + */ + private MedicalAction frozenSection() { + return null; + } + + /** + * Negative for fungal and acid-fast bacilli + */ + private MedicalAction tissueCultures() { + return null; + } + + /** + * Anaerobic cultures: Actinomyces odontolyticus + */ + private MedicalAction anaerobicCultures() { + return null; + } + + /** + * - Incisional biopsy culture under general anaesthetic + * - Subperiosteal dissection exposing the ascending ramus + * - No granules encountered + */ + private MedicalAction biopsy() { + return null; + } + + /** + * - clinically healthy periodontium with mild tenderness on palpation + */ + private PhenotypicFeature examination() { + return null; + } + + /** + * Contrast-enhanced MRI + * + * - hyperintense T2 signal abnormality in the left mandibular bone marrow with periosteal thickening + * - no drainable fluid collection + */ + private MedicalAction mri() { + return null; + } + + /** + * Contrast-enhanced neck CT + * - bony expansion of the left mandible + * - overlying soft tissue swelling + */ + private MedicalAction neckCT() { + return null; + } + + /** + * Last 8 months: + * + * - waxing and waning left sided mandible pain and swelling + * - denied erythema or drainage + * - no history of facial trauma + * - no history of dental procedures + * - no history of dental caries + * - intermittent fevers + * + * - Oral steroid courses - no improvement in facial swelling + */ + private List getLast8Monthsistory() { + return null; + } + + /** + * - 6-month course of oral amoxicillin 1000mg two times per day + */ + private MedicalAction treatment() { + return null; + } + + /** + * Outcome: + * + * At 1 month: + * - occasional mild pain in her mandible + * + * At 5 months: + * - maxillofacial CT: resolving/chronic osteomyelitis + * - extended antibiotic treatment to a 12-month course + */ + + /** + * - no significant medical history + */ + private List getMedicalHistory() { + return null; + } + + /** + * Diagnosis: cervicofacial actinomycosis + */ + private Interpretation interpretation() { + InterpretationBuilder ibuilder = InterpretationBuilder.solved("interpretation.id"); + DiagnosisBuilder dbuilder = DiagnosisBuilder.builder(ontologyClass("???", "Cervicofacial actinomycosis")); + ibuilder.diagnosis(dbuilder.build()); + return ibuilder.build(); + } +} diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/CushingSyndromeWithMultifocalOsteonecrosis.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/CushingSyndromeWithMultifocalOsteonecrosis.java new file mode 100644 index 00000000..f70ed7dc --- /dev/null +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/CushingSyndromeWithMultifocalOsteonecrosis.java @@ -0,0 +1,165 @@ +package org.phenopackets.phenotools.examples; + +import org.phenopackets.phenotools.builder.PhenopacketBuilder; +import org.phenopackets.phenotools.builder.builders.*; +import org.phenopackets.schema.v2.Phenopacket; +import org.phenopackets.schema.v2.core.*; + +import java.util.List; + +import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; + +public class CushingSyndromeWithMultifocalOsteonecrosis { + + + private static final String PHENOPACKET_ID = "arbitrary.id"; + private static final String INDIVIDUAL = "individual A"; + + private final Phenopacket phenopacket; + + public CushingSyndromeWithMultifocalOsteonecrosis() { + + var externalRef = ExternalReferenceBuilder.builder() + .id("DOI:10.1136/bcr-2019-233712") + .builder("PMID:32467117") + .description("Iatrogenic Cushing syndrome and multifocal osteonecrosis caused by the interaction between inhaled fluticasone and ritonavir") + .build(); + + //TODO: Fix ontology versions + var metadata = MetaDataBuilder.builder("2022-04-21T10:35:00Z", "anonymous biocurator") + .resource(Resources.ncitVersion("21.05d")) + .resource(Resources.hpoVersion("2021-08-02")) + .resource(Resources.efoVersion("3.34.0")) + .resource(Resources.uberonVersion("2021-07-27")) + .resource(Resources.ncbiTaxonVersion("2021-06-10")) + .externalReference(externalRef) + .build(); + + Individual proband = IndividualBuilder.builder(INDIVIDUAL). + ageAtLastEncounter("P40Y"). + male(). + build(); + + phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metadata) + .individual(proband) + .addAllPhenotypicFeatures(getMedicalHistory()) + .addAllPhenotypicFeatures(getMedicalBackground()) + .addMedicalAction(existingTreatment()) + .addAllPhenotypicFeatures(getSymptomsOnPresentation()) + .addAllMeasurements(getMeasurementsOnPresentation()) + .addInterpretation(interpretation()) + .addMedicalAction(treatment()) + .build(); + } + + /** + * Outcomes: + * + * 10 months after: + * + * - less ‘full moon’ facies + * - no oedema + * - less purpuric striae + * - 6kg weight loss + * - BMI of 33kg/m2 + * - improvement of erectile dysfunction + * - Serum and urinary cortisol almost normal + * - ACTH not suppressed + */ + + /** + * Treatment: + * + * First 4 months: + * - antihypertensive + * - corticosteroids at a halved dose + * - statin therapy + * + * At 7 months: + * - fluticasone ceased + * - indacaterol 150µg one time a day + */ + private MedicalAction treatment() { + return null; + } + + /** + * Labs: + * + * - Low serum and urinary cortisol + * - low serum adrenocorticotrophic hormone (ACTH) concentrations + * => Indicates: suppression of the HPA axis + */ + private List getMeasurementsOnPresentation() { + return null; + } + + /** + * Medical history: + * + * - well controlled HIV1 infection + * - CD4+ T cell count of 518 cells/mm3 + * - undetectable HIV1 RNA + * + * At 36Y old: + * - avascular necrosis of the right femoral head + * - total hip arthroplasty + */ + private List getMedicalHistory() { + return null; + } + + /** + * Medical background: + * + * - COPD + * - alcohol & tobacco abuse + * - intravenous heroin abuse + * - HIV1 infection diagnosed at 25Y old + */ + private List getMedicalBackground() { + return null; + } + + /** + * HIV Treatment background (started at 33Y old) + * + * - lopinavir/ritonavir 400mg/100mg two times per day + * - saquinavir 1000mg two times per day + * - tenofovir 300mg one time a day + * + * COPD Treatment background (started at 35Y old) + * + * - inhaled therapy with fluticasone/salmeterol 250µg/50µg two times per day + * - tiotropium bromide 18µg one time a day + */ + private MedicalAction existingTreatment() { + return null; + } + + /** + * On presentation: + * + * - gradual increase in abdominal and cervical volume + * - 15kg weight gain over the previous 6months + * - abdominal and limb striae + * - gynecomastia + * - ankle oedema + * - erectile dysfunction + * - humoral lability + */ + private List getSymptomsOnPresentation() { + return null; + } + + + /** + * Diagnosis: exogenous/iatrogenic Cushing syndrome secondary to inhaled fluticasone + */ + private Interpretation interpretation() { + InterpretationBuilder ibuilder = InterpretationBuilder.solved("interpretation.id"); + DiagnosisBuilder dbuilder = DiagnosisBuilder.builder(ontologyClass("???", "Exogenous/iatrogenic Cushing syndrome")); + ibuilder.diagnosis(dbuilder.build()); + return ibuilder.build(); + } +} diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/PneumothoraxSecondaryToCOVID.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/PneumothoraxSecondaryToCOVID.java index 3d53aa11..2dc58e14 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/PneumothoraxSecondaryToCOVID.java +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/PneumothoraxSecondaryToCOVID.java @@ -5,20 +5,25 @@ import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; -import java.util.ArrayList; import java.util.List; +import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; + public class PneumothoraxSecondaryToCOVID { private static final String PHENOPACKET_ID = "arbitrary.id"; - private static final String PROBAND_ID = "proband A"; - - // Organs + private static final String INDIVIDUAL = "individual A"; private final Phenopacket phenopacket; public PneumothoraxSecondaryToCOVID() { + var externalRef = ExternalReferenceBuilder.builder() + .id("DOI:10.1136/bcr-2020-235861") + .builder("PMID:32423911") + .description("Tension pneumothorax in a patient with COVID-19") + .build(); + //TODO: Fix ontology versions var metadata = MetaDataBuilder.builder("2022-04-21T10:35:00Z", "anonymous biocurator") .resource(Resources.ncitVersion("21.05d")) @@ -26,9 +31,10 @@ public PneumothoraxSecondaryToCOVID() { .resource(Resources.efoVersion("3.34.0")) .resource(Resources.uberonVersion("2021-07-27")) .resource(Resources.ncbiTaxonVersion("2021-06-10")) + .externalReference(externalRef) .build(); - Individual proband = IndividualBuilder.builder(PROBAND_ID). + Individual proband = IndividualBuilder.builder(INDIVIDUAL). ageAtLastEncounter("P36Y"). male(). build(); @@ -40,29 +46,62 @@ public PneumothoraxSecondaryToCOVID() { .addAllPhenotypicFeatures(getSymptomsOnPresentation()) .addAllMeasurements(getMeasurementsOnPresentation()) .addAllPhenotypicFeatures(getChestRadiograph()) + .addInterpretation(interpretation()) + .addMedicalAction(decompression()) + .addMedicalAction(chestDrain()) .build(); - } /** - * A 12-lead ECG showed a sinus tachycardia at 155 beats/min. - * - * The patient’s full blood count demonstrated a raised white cell count (13.64×109/L) with a neutrophilia (8.91×109/L), lymphocyte count (3.81×109/L), haemoglobin (146g/L), and platelets (1051×109/L); biochemical markers demonstrated a raised C-reactive protein (28.7mg/L) and alanine aminotransferase (107IU/L). - * Diagnosis: tension pneumothorax, secondary to underlying COVID-19 - * - * Treatment: - * emergency needle decompression: - * - 14-gauge cannula inserted in the second rib space and mid-clavicular line - * - 12-French Seldinger chest drain inserted into the patients left axilla + * TODO: How to represent outcomes? * * Outcome: - * repeat chest radiograph => lung re-expansion - * Within an hour the patient’s oxygen requirement reduced to 4L/min via nasal cannula - * normalisation of respiratory and heart rate. + * - Repeat chest radiograph => lung re-expansion + * - Oxygen requirement reduced to 4L/min via nasal cannula + * - normalisation of respiratory and heart rate + */ + + /** + * TODO: Anatomical site improperly represented + * TODO: Intent should be: lung decompression not 'Cure' + *

+ * Intervention: 14-gauge cannula inserted in the second rib space and mid-clavicular line */ + private MedicalAction decompression() { + ProcedureBuilder builder = ProcedureBuilder.builder("SCTID:42825003", "Cannulation (procedure)"); + builder.bodySite(ontologyClass("???", "space between second rib and mid-clavicular line")); + MedicalActionBuilder mabuilder = MedicalActionBuilder.builder(builder.build()) + .treatmentTarget(ontologyClass("SCTID:233645004", "Tension pneumothorax (disorder)")) + .treatmentIntent(ontologyClass("NCIT:C62220", "Cure")); + return mabuilder.build(); + } + /** + * Intervention: 12-French Seldinger chest drain inserted into the patients left axilla + */ + private MedicalAction chestDrain() { + ProcedureBuilder builder = ProcedureBuilder.builder("SCTID:264957007", "Insertion of pleural tube drain (procedure)"); + builder.bodySite(ontologyClass("FMA:45303", "Left axilla")); + MedicalActionBuilder mabuilder = MedicalActionBuilder.builder(builder.build()) + .treatmentTarget(ontologyClass("SCTID:233645004", "Tension pneumothorax (disorder)")) + .treatmentIntent(ontologyClass("NCIT:C62220", "Cure")); + return mabuilder.build(); + } /** + * Diagnosis: tension pneumothorax, secondary to underlying COVID-19 + */ + private Interpretation interpretation() { + InterpretationBuilder ibuilder = InterpretationBuilder.solved("interpretation.id"); + DiagnosisBuilder dbuilder = DiagnosisBuilder.builder(ontologyClass("SCTID:233645004", "Tension pneumothorax (disorder)")); + ibuilder.diagnosis(dbuilder.build()); + return ibuilder.build(); + } + + /** + * TODO: How to represent co-occurring phenotypes: pneumothorax WITH mediastinal shift? + * TODO: How to associate these phenotypes with the procedure SCTID:399208008 'Plain chest X-ray'? + *

* Emergency portable chest radiograph * - large left-sided pneumothorax with mediastinal shift * - radiological signs of tension @@ -70,14 +109,34 @@ public PneumothoraxSecondaryToCOVID() { */ private List getChestRadiograph() { - // How to associate phenotypes with procedures? + PhenotypicFeature pneumothorax = PhenotypicFeatureBuilder + .builder("HP:0002107", "Pneumothorax") + .modifier(OntologyClassBuilder.ontologyClass("PATO:0000600", "increased width")) + .modifier(Laterality.left()) + .build(); + + PhenotypicFeature rightLungNormal = PhenotypicFeatureBuilder + .builder("HP:0031983", "Abnormal pulmonary thoracic imaging finding") + .modifier(Laterality.right()) + .excluded() + .build(); + + PhenotypicFeature rightLungConsolidated = PhenotypicFeatureBuilder + .builder("SCTID:95436008", "Lung consolidation (disorder)") // Probably incorrect + .modifier(Laterality.right()) + .modifier(OntologyClassBuilder.ontologyClass("PATO:0001630", "dispersed")) + .modifier(OntologyClassBuilder.ontologyClass("PATO:0001608", "patchy")) + .build(); - return new ArrayList<>(); + return List.of(pneumothorax, rightLungNormal, rightLungConsolidated); } /** - * On presentation: << How to specify the temporal element? - * - SpO2 of 88% on 15L/min oxygen via non-rebreathe mask + * TODO: How to associate these phenotypes with the temporal aspect 'on presentation'? + * TODO: Fix measurement units + *

+ * On presentation: + * - SpO2 of 88% on 15L/min oxygen via non-rebreather mask * - respiratory rate of 50 breaths per minute * - heart rate of 150 beats/min * - blood pressure of 110/65 mm Hg @@ -113,8 +172,9 @@ private List getMeasurementsOnPresentation() { build(); - // How to define the 'intervention' component SpO2 of 88% << on 15L/min oxygen via non-rebreathe mask >> - // It's not a procedure + /** + * TODO: How to associate SpO2 of 88% on 15L/min oxygen with the 'intervention' 'non rebreather mask oxygen delivery'? + */ OntologyClass spO2 = OntologyClassBuilder.ontologyClass("LOINC:20564-1", "Oxygen saturation in Blood"); Value spO2Value = ValueBuilder.value("UCUM:%", "%", 88); @@ -131,14 +191,16 @@ private List getMeasurementsOnPresentation() { } /** - * On presentation: << How to represent this from a temporal perspective? + * TODO: How to associate these phenotypes with the temporal aspect 'on presentation'? + *

+ * On presentation: * - hypoxaemic * - tachycardic * - left-sided pleuritic chest pain * - trachea remained central *

* On ascultation: - * - no audible breath sounds of the left hemithorax + * - NO audible breath sounds of the left hemithorax << Not sure how to code this * - reduced vocal fremitus * - asymmetrical chest expansion */ @@ -161,16 +223,26 @@ private List getSymptomsOnPresentation() { excluded(). build(); - // How to combine a procedure < ascultation > with phenotypic features? - return List.of(hypoxemia, tachycardia, chestPain, trachea); + /** + * TODO: How to associate these phenotypes with the procedure SCTID:37931006 'Auscultation'? + */ + PhenotypicFeature vocalFremitus = PhenotypicFeatureBuilder. + builder("SCTID:301278006", "Vocal fremitus decreased"). + build(); + + PhenotypicFeature asymmetricalChestExpansion = PhenotypicFeatureBuilder. + builder("SCTID:271623001", "Chest movement unequal"). + build(); + + return List.of(hypoxemia, tachycardia, chestPain, trachea, vocalFremitus, asymmetricalChestExpansion); } /** * medical history: * - Childhood asthma * - 10 pack-year history of smoking << How to represent this !? - * - NO history of trauma << Did I represent correct the absence of the phenotype? + * - NO history of trauma * - NO history of pneumothoraces */ private List getMedicalHistory() { @@ -178,6 +250,10 @@ private List getMedicalHistory() { builder("HP:0002099", "Asthma"). childhoodOnset(). build(); + + /** + * TODO: How to represent the difference between no HISTORY vs no PRESENT observation for a phenotype? + */ PhenotypicFeature trauma = PhenotypicFeatureBuilder. builder("SCTID:417746004", "Trauma"). excluded(). @@ -191,7 +267,9 @@ private List getMedicalHistory() { } /** - * 3-week history: << How to represent relative time periods? + * TODO: How to represent relative time periods? (e.g., 3 weeks prior to diagnosis) + *

+ * 3-week history: * - cough * - fevers * - shortness of breath diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/SevereStatinInducedAutoimmuneMyopathy.java b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/SevereStatinInducedAutoimmuneMyopathy.java new file mode 100644 index 00000000..1d7ddb39 --- /dev/null +++ b/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/SevereStatinInducedAutoimmuneMyopathy.java @@ -0,0 +1,162 @@ +package org.phenopackets.phenotools.examples; + +import org.phenopackets.phenotools.builder.PhenopacketBuilder; +import org.phenopackets.phenotools.builder.builders.*; +import org.phenopackets.schema.v2.Phenopacket; +import org.phenopackets.schema.v2.core.*; + +import java.util.List; + +import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; + +public class SevereStatinInducedAutoimmuneMyopathy { + + + private static final String PHENOPACKET_ID = "arbitrary.id"; + private static final String INDIVIDUAL = "individual A"; + + private final Phenopacket phenopacket; + + public SevereStatinInducedAutoimmuneMyopathy() { + + var externalRef = ExternalReferenceBuilder.builder() + .id("DOI:10.1136/bcr-2020-234805") + .builder("PMID:32444443") + .description("Severe statin-induced autoimmune myopathy successfully treated with intravenous immunoglobulin") + .build(); + + //TODO: Fix ontology versions + var metadata = MetaDataBuilder.builder("2022-04-21T10:35:00Z", "anonymous biocurator") + .resource(Resources.ncitVersion("21.05d")) + .resource(Resources.hpoVersion("2021-08-02")) + .resource(Resources.efoVersion("3.34.0")) + .resource(Resources.uberonVersion("2021-07-27")) + .resource(Resources.ncbiTaxonVersion("2021-06-10")) + .externalReference(externalRef) + .build(); + + Individual proband = IndividualBuilder.builder(INDIVIDUAL). + ageAtLastEncounter("P65Y"). + male(). + build(); + + phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metadata) + .individual(proband) + .addAllPhenotypicFeatures(getMedicalHistory()) + .addMedicalAction(existingTreatment()) + .addAllPhenotypicFeatures(getLastMonthHistory()) + .addAllPhenotypicFeatures(getSymptomsOnPresentation()) + .addAllMeasurements(getLabsOnPresentation()) + .addAllPhenotypicFeatures(getEMG()) + .addInterpretation(interpretation()) + .addMedicalAction(treatment()) + .build(); + } + + /** + * Outcome: + * + * 7weeks after the fourth round of IVIg, the patient nearly regained full strength in his legs and CK did not show any further increase. + */ + + /** + * Atorvastatin was stopped + * muscle weakness deteriorated in his legs + * spread to his arms making immune-modulating treatment necessary + * 155 g IVIg, equivalent to 1.6 g/kg of body weight, was administered over 3 days + * 55 g on the first day and 50 g on the second and third day + * developed a headache after first dose + * lack of significant improvement of the CK + * treatment was continued every 6 weeks slightly reducing the dose to 150 g + * After the third course of treatment, the CK in serum drastically fell to a mildly elevated level + * Following the fourth administration, CK was stable around 500 U/L and weakness in his limbs had been greatly improved. + */ + private MedicalAction treatment() { + return null; + } + + /** + * active denervation + * and fasciculation potentials along with chronic denervation/re-innervation motor unit patterns + * from the craniobulbar, thoracic, paraspinal as well as upper and lower limb muscles. + * @return + */ + private List getEMG() { + return null; + } + + /** + * creatine kinase (CK) level was raised up to 4292 U/L + * alanine transaminase (ALT) was raised to 234 U/L + * Alkaline phosphatase and bilirubin were normal + * Autoantibodies against HMG-CoA reductase were positive. + * Haemoglobin A1C was 51 mmol/mol. + * Full blood count, thyroid function tests, renal profile, vitamin D and B12 were all normal. + */ + private List getLabsOnPresentation() { + return null; + } + + /** + * On examination: + * + * fasciculations and wasting were noticed in both quadriceps muscles + * muscular tone was normal + * proximal weakness in both legs + * Trendelenburg's and Gower's signs were positive + * knee jerks were brisk + * Sensation was intact + * loss of vibration sense up to the tibial plateau bilaterally + * Examination of the cranial nerves and the upper limbs was unremarkable. + */ + private List getSymptomsOnPresentation() { + return null; + } + + /** + * Last month history: + * + * - weakness started about 2 months ago; got progressively worse + * difficulties climbing stairs + * getting up from the squatting position + * walking or even putting on his trousers + * started using a wheelchair + * denied having any associated pain, and upper limbs as well as speech and swallowing were uninvolved. + * + * longstanding mild sensory symptoms in both feet + * lost around 6 lb (about 2.72 kg) in weight in the previous month + */ + private List getLastMonthHistory() { + return null; + } + + /** + * Medical history: + * + * - hypertension diagnosed 10 years back + * - type 2 diabetes mellitus diagnosed 10 years back + */ + private List getMedicalHistory() { + return null; + } + + /** + * HIV Treatment background (started at 33Y old) + * + * - atorvastatin 10 mg and aspirin 75 mg alongside antihypertensive (ramipril and amlodipine) and anti-diabetic (metformin, dapagliflozin, sitagliptin and gliclazide) medication + */ + private MedicalAction existingTreatment() { + return null; + } + + + /** + * Diagnosis: statin-associated autoimmune myopathy + */ + private Interpretation interpretation() { + InterpretationBuilder ibuilder = InterpretationBuilder.solved("interpretation.id"); + DiagnosisBuilder dbuilder = DiagnosisBuilder.builder(ontologyClass("????", "Statin-associated autoimmune myopathy")); + ibuilder.diagnosis(dbuilder.build()); + return ibuilder.build(); + } +} From 621d0e0a81be31534026b8ef54cf35654c619822 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Sat, 14 May 2022 10:38:43 -0400 Subject: [PATCH 042/155] glaucoma --- .../examples/GlaucomaSurgery.java | 108 +++++++++++++++++- pom.xml | 2 +- 2 files changed, 108 insertions(+), 2 deletions(-) diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/GlaucomaSurgery.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/GlaucomaSurgery.java index a6dc97cc..ee60564a 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/GlaucomaSurgery.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/GlaucomaSurgery.java @@ -4,28 +4,134 @@ import org.phenopackets.phenopackettools.builder.builders.MetaDataBuilder; import org.phenopackets.phenopackettools.builder.builders.Resources; import org.phenopackets.schema.v2.Phenopacket; +import org.phenopackets.phenopackettools.builder.builders.*; +import org.phenopackets.phenopackettools.builder.constants.Laterality; +import org.phenopackets.phenopackettools.builder.constants.Unit; +import org.phenopackets.schema.v2.Phenopacket; +import org.phenopackets.schema.v2.core.*; + +import java.util.List; + +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; + public class GlaucomaSurgery implements PhenopacketExample { private static final String PHENOPACKET_ID = "arbitrary.id"; + private static final String PROBAND_ID = "proband A"; + private static final String BIOSAMPLE_ID = "biosample.1"; + + // Organs + private static final OntologyClass EYE = ontologyClass("UBERON:0000970", "eye"); + private static final OntologyClass CURE = ontologyClass("NCIT:C62220", "Cure"); + private static final OntologyClass LEFT_EYE = ontologyClass("UBERON:0004548", "left eye"); + + private final Phenopacket phenopacket; public GlaucomaSurgery() { + // hallo var metadata = MetaDataBuilder.builder("2021-05-14T10:35:00Z", "anonymous biocurator") .addResource(Resources.ncitVersion("21.05d")) .addResource(Resources.efoVersion("3.34.0")) .addResource(Resources.uberonVersion("2021-07-27")) .addResource(Resources.ncbiTaxonVersion("2021-06-10")) .build(); + Individual proband = IndividualBuilder.builder(PROBAND_ID). + ageAtLastEncounter("P6M"). + female(). + XX(). + build(); + + + + + PhenopacketBuilder builder = PhenopacketBuilder.create(PHENOPACKET_ID, metadata) + .individual(proband) + .addAllMeasurements(getMeasurements()) + .addAllPhenotypicFeatures(getPhenotypicFeatures()) + .addDisease(getDisease()); + // (Genom-Sequenz) .addInterpretation(interpretation()) - PhenopacketBuilder builder = PhenopacketBuilder.create(PHENOPACKET_ID, metadata); phenopacket = builder.build(); } + Disease getDisease() { + // NCIT:C27980 + // Stage E + // Group E = LOINC:LA24739-7 + // Retinoblastoma , NCIT:C7541 + // No metastasis is NCIT:C140678, Retinoblastoma cM0 TNM Finding v8 + // Retinoblastoma with no signs or symptoms of intracranial or distant metastasis. (from AJCC 8th Ed.) [ NCI ] + // OntologyClass stageE = ontologyClass("LOINC:LA24739-7", "Group E"); + // OntologyClass noMetastasis = ontologyClass("NCIT:C140678", "Retinoblastoma cM0 TNM Finding v8"); + OntologyClass exfoliationSyndrome = ontologyClass("MONDO:0008327", "exfoliation syndrome"); + // TimeElement age4m = TimeElements.age("P4M"); + TimeElement adult = TimeElements.adultOnset(); + return DiseaseBuilder.builder(exfoliationSyndrome) + .onset(adult) + // .addDiseaseStage(stageE) + // .addClinicalTnmFinding(noMetastasis) + + // .primarySite(LEFT_EYE) + .build(); + } @Override public Phenopacket getPhenopacket() { return phenopacket; } + + /* + The intraocular pressure was 25 mmHg in the right eye and 15 mmHg in the left eye, + measured with the Perkins tonometer. + */ + List getMeasurements() { + OntologyClass iop = ontologyClass("56844-4","Intraocular pressure of Eye"); + ReferenceRange ref = ReferenceRangeBuilder.of(iop, 10, 21); + OntologyClass leftEyeIop = + OntologyClassBuilder.ontologyClass("LOINC:79893-4", "Left eye Intraocular pressure"); + Value leftEyeValue = ValueBuilder.of(Unit.mmHg(), 25, ref); + OntologyClass rightEyeIop = + OntologyClassBuilder.ontologyClass("LOINC:79892-6", "Right eye Intraocular pressure"); + Value rightEyeValue = ValueBuilder.of(Unit.mmHg(), 15, ref); + TimeElement age = TimeElements.age("P6M"); + + Measurement leftEyeMeasurement = MeasurementBuilder.builder(leftEyeIop, leftEyeValue).timeObserved(age).build(); + Measurement rightEyeMeasurement = MeasurementBuilder.builder(rightEyeIop, rightEyeValue).timeObserved(age).build(); + //33728-7 Size.maximum dimension in Tumor + //14 × 13 × 11 mm left eye tumor + return List.of(leftEyeMeasurement, rightEyeMeasurement); + } + + List getPhenotypicFeatures() { + TimeElement age3months = TimeElements.age("P3M"); + PhenotypicFeature clinodactyly = PhenotypicFeatureBuilder. + builder("HP:0030084", "Clinodactyly"). + addModifier(Laterality.right()). + onset(age3months). + build(); + TimeElement age4months = TimeElements.age("P4M"); + PhenotypicFeature leukocoria = PhenotypicFeatureBuilder. + builder("HP:0000555", "Leukocoria") + .addModifier(Laterality.left()) + .onset(age4months) + .build(); + TimeElement age5months = TimeElements.age("P5M15D"); + PhenotypicFeature strabismus = PhenotypicFeatureBuilder. + builder("HP:0000486", "Strabismus") + .addModifier(Laterality.left()) + .onset(age5months) + .build(); + TimeElement age6months = TimeElements.age("P6M"); + PhenotypicFeature retinalDetachment = PhenotypicFeatureBuilder + .builder("HP:0000541", "Retinal detachment") + .addModifier(Laterality.left()) + .onset(age6months) + .build(); + return List.of(clinodactyly, leukocoria, strabismus, retinalDetachment); + } + } + diff --git a/pom.xml b/pom.xml index e963c532..9478837b 100644 --- a/pom.xml +++ b/pom.xml @@ -72,7 +72,7 @@ 11 3.14.0 - 2.0.0 + 2.0.1 5.7.1 From 43d3fa818184188778850851a8edb599c1924445 Mon Sep 17 00:00:00 2001 From: Daniel Danis Date: Thu, 19 May 2022 16:50:54 -0400 Subject: [PATCH 043/155] Fix test visibility modifiers. --- .../phenopackettools/builder/builders/AgeBuilderTest.java | 8 ++++---- .../builder/builders/AlleleBuilderTest.java | 4 ++-- .../builder/builders/BiosampleBuilderTest.java | 6 +++--- .../builder/builders/ComplexValueBuilderTest.java | 4 ++-- .../builder/builders/DiagnosisBuilderTest.java | 6 +++--- .../builder/builders/DiseaseBuilderTest.java | 6 +++--- .../builder/builders/TimeIntervalBuilderTest.java | 6 +++--- .../builder/builders/TimestampBuilderTest.java | 6 +++--- .../converter/PhenopacketConverterTest.java | 4 ++-- 9 files changed, 25 insertions(+), 25 deletions(-) diff --git a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AgeBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AgeBuilderTest.java index aa714128..8743c47a 100644 --- a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AgeBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AgeBuilderTest.java @@ -8,13 +8,13 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; -class AgeBuilderTest { +public class AgeBuilderTest { /** * https://phenopacket-schema.readthedocs.io/en/v2/age.html#example */ @Test - void testAge() { + public void testAge() { Age age = Ages.age("P25Y3M2D"); assertThat(age.getIso8601Duration(), equalTo("P25Y3M2D")); } @@ -23,7 +23,7 @@ void testAge() { * https://phenopacket-schema.readthedocs.io/en/v2/age.html#id3 */ @Test - void testAgeRange() { + public void testAgeRange() { AgeRange ageRange = Ages.ageRange("P45Y", "P49Y"); assertThat(ageRange.getStart(), equalTo(Ages.age("P45Y"))); assertThat(ageRange.getEnd(), equalTo(Ages.age("P49Y"))); @@ -33,7 +33,7 @@ void testAgeRange() { * https://phenopacket-schema.readthedocs.io/en/v2/gestational-age.html */ @Test - void testGestationalAge() { + public void testGestationalAge() { GestationalAge gestationalAge = Ages.gestationalAge(33, 2); assertThat(gestationalAge.getWeeks(), equalTo(33)); assertThat(gestationalAge.getDays(), equalTo(2)); diff --git a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilderTest.java index 3b918608..7235ab8a 100644 --- a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/AlleleBuilderTest.java @@ -7,10 +7,10 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; -class AlleleBuilderTest { +public class AlleleBuilderTest { @Test - void testBuild() { + public void testBuild() { Variation variation = AlleleBuilder.builder() .sequenceId("NC_000003.12") .startEnd(42686219, 42686220) diff --git a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilderTest.java index 17b3d3a4..2f8b52e1 100644 --- a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/BiosampleBuilderTest.java @@ -9,10 +9,10 @@ import static org.hamcrest.Matchers.equalTo; import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; -class BiosampleBuilderTest { +public class BiosampleBuilderTest { @Test - void biosampleTest() { + public void biosampleTest() { Biosample biosample = BiosampleBuilder.builder("sample1").build(); assertThat(biosample.getId(), equalTo("sample1")); } @@ -21,7 +21,7 @@ void biosampleTest() { * https://phenopacket-schema.readthedocs.io/en/v2/biosample.html#example */ @Test - void biosampleBuilderTest() { + public void biosampleBuilderTest() { Biosample biosample = BiosampleBuilder.builder("sample1") .individualId("patient1") .description("Additional information can go here") diff --git a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilderTest.java index 6c245dbd..31e4422a 100644 --- a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/ComplexValueBuilderTest.java @@ -11,13 +11,13 @@ import static org.hamcrest.Matchers.equalTo; import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; -class ComplexValueBuilderTest { +public class ComplexValueBuilderTest { /** * https://phenopacket-schema.readthedocs.io/en/v2/complex-value.html#example */ @Test - void testComplexValue() { + public void testComplexValue() { OntologyClass millimeterOfMercury = ontologyClass("NCIT:C49670", "Millimeter of Mercury"); TypedQuantity systolicBloodPressure = TypedQuantityBuilder.of(ontologyClass("NCIT:C25298", "Systolic Blood Pressure"), QuantityBuilder.of(millimeterOfMercury, 120)); TypedQuantity diastolicBloodPressure = TypedQuantityBuilder.of(ontologyClass("NCIT:C25299", "Diastolic Blood Pressure"), QuantityBuilder.of(millimeterOfMercury, 70)); diff --git a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiagnosisBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiagnosisBuilderTest.java index 755bb20d..7093b2f1 100644 --- a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiagnosisBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiagnosisBuilderTest.java @@ -10,10 +10,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; -class DiagnosisBuilderTest { +public class DiagnosisBuilderTest { @Test - void testDiagnosisBuilder() { + public void testDiagnosisBuilder() { var variationDescriptor = VariationDescriptorBuilder.builder("variant id") .heterozygous() @@ -36,7 +36,7 @@ void testDiagnosisBuilder() { } @Test - void testDiagnosisBuilderMinimalData() { + public void testDiagnosisBuilderMinimalData() { var thrombocytopenia2 = ontologyClass("OMIM:188000", "Thrombocytopenia 2"); Diagnosis diagnosis = DiagnosisBuilder.builder(thrombocytopenia2).build(); assertThat(diagnosis.getDisease(), equalTo(thrombocytopenia2)); diff --git a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilderTest.java index 6cefcf80..32949cfd 100644 --- a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/DiseaseBuilderTest.java @@ -7,16 +7,16 @@ import static org.hamcrest.Matchers.equalTo; import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; -class DiseaseBuilderTest { +public class DiseaseBuilderTest { @Test - void testMinimalData() { + public void testMinimalData() { Disease disease = DiseaseBuilder.of("MONDO:0004994", "cardiomyopathy"); assertThat(disease.getTerm(), equalTo(ontologyClass("MONDO:0004994", "cardiomyopathy"))); } @Test - void testBuilder() { + public void testBuilder() { Disease disease = DiseaseBuilder.builder("OMIM:164400", "Spinocerebellar ataxia 1") .onset(TimeElements.age("P38Y7M")) .build(); diff --git a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilderTest.java index 48c9b6b3..b49b1470 100644 --- a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimeIntervalBuilderTest.java @@ -7,20 +7,20 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; -class TimeIntervalBuilderTest { +public class TimeIntervalBuilderTest { /** * https://phenopacket-schema.readthedocs.io/en/v2/time-interval.html#example */ @Test - void timeIntervalFromStringTest() { + public void timeIntervalFromStringTest() { TimeInterval instance = TimeIntervalBuilder.of("2020-03-15T13:00:00Z", "2020-03-25T09:00:00Z"); assertThat(instance.getStart().getSeconds(), equalTo(1584277200L)); assertThat(instance.getEnd().getSeconds(), equalTo(1585126800L)); } @Test - void timeIntervalFromTimestampTest() { + public void timeIntervalFromTimestampTest() { Timestamp start = TimestampBuilder.fromISO8601("2020-03-15T13:00:00Z"); Timestamp end = TimestampBuilder.fromISO8601("2020-03-25T09:00:00Z"); TimeInterval instance = TimeIntervalBuilder.of(start, end); diff --git a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimestampBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimestampBuilderTest.java index 2002dcf5..31e9b567 100644 --- a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimestampBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/TimestampBuilderTest.java @@ -9,16 +9,16 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; -class TimestampBuilderTest { +public class TimestampBuilderTest { @Test - void testFromISO8601Timestamp() throws ParseException { + public void testFromISO8601Timestamp() throws ParseException { Timestamp instance = TimestampBuilder.fromISO8601("2021-11-05T12:38:00Z"); assertThat(instance, equalTo(Timestamps.parse("2021-11-05T12:38:00Z"))); } @Test - void testFromISO8601Date() throws ParseException { + public void testFromISO8601Date() throws ParseException { Timestamp instance = TimestampBuilder.fromISO8601("2021-11-05"); assertThat(instance, equalTo(Timestamps.parse("2021-11-05T00:00:00Z"))); } diff --git a/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java b/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java index d6b10593..7465a4a9 100644 --- a/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java +++ b/phenopacket-tools-converter/src/test/java/org/phenopackets/phenopackettools/converter/PhenopacketConverterTest.java @@ -5,12 +5,12 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; -class PhenopacketConverterTest { +public class PhenopacketConverterTest { /** * To output: System.out.println(JsonFormat.printer().print(v2Phenopacket)); */ @Test - void name() { + public void name() { org.phenopackets.schema.v1.Phenopacket v1Phenopacket = BethlemMyopathyV1.proband(); org.phenopackets.schema.v2.Phenopacket v2Phenopacket = PhenopacketConverter.toV2Phenopacket(v1Phenopacket); assertNotNull(v2Phenopacket); From e9383d26aaedf23db81ac59e80cde632553e47ec Mon Sep 17 00:00:00 2001 From: Daniel Danis Date: Thu, 19 May 2022 17:07:44 -0400 Subject: [PATCH 044/155] Add `module-info.java` files, clean up `pom.xml` files. --- phenopacket-tools-builder/pom.xml | 10 ++++++---- .../src/main/java/module-info.java | 11 +++++++++++ phenopacket-tools-cli/pom.xml | 5 ++++- phenopacket-tools-cli/src/main/java/module-info.java | 11 +++++++++++ phenopacket-tools-converter/pom.xml | 4 ---- .../src/main/java/module-info.java | 8 ++++++++ .../src/main/java/module-info.java | 6 ++++++ .../src/main/java/module-info.java | 9 +++++++++ pom.xml | 7 ++++++- 9 files changed, 61 insertions(+), 10 deletions(-) create mode 100644 phenopacket-tools-builder/src/main/java/module-info.java create mode 100644 phenopacket-tools-cli/src/main/java/module-info.java create mode 100644 phenopacket-tools-converter/src/main/java/module-info.java create mode 100644 phenopacket-tools-validator-core/src/main/java/module-info.java create mode 100644 phenopacket-tools-validator-jsonschema/src/main/java/module-info.java diff --git a/phenopacket-tools-builder/pom.xml b/phenopacket-tools-builder/pom.xml index ae71ee17..2fda2d89 100644 --- a/phenopacket-tools-builder/pom.xml +++ b/phenopacket-tools-builder/pom.xml @@ -17,13 +17,15 @@ com.google.protobuf protobuf-java - - com.google.protobuf - protobuf-java-util - org.phenopackets phenopacket-schema + + + com.google.protobuf + protobuf-java-util + test + \ No newline at end of file diff --git a/phenopacket-tools-builder/src/main/java/module-info.java b/phenopacket-tools-builder/src/main/java/module-info.java new file mode 100644 index 00000000..7ed36c34 --- /dev/null +++ b/phenopacket-tools-builder/src/main/java/module-info.java @@ -0,0 +1,11 @@ +module org.phenopacket.tools.builder { + // TODO - needs to be fixed after modular phenopacket schema is deployed to MC + requires transitive phenopacket.schema; + + requires com.google.protobuf; + + exports org.phenopackets.phenopackettools.builder; + exports org.phenopackets.phenopackettools.builder.builders; + exports org.phenopackets.phenopackettools.builder.constants; + exports org.phenopackets.phenopackettools.builder.exceptions; +} \ No newline at end of file diff --git a/phenopacket-tools-cli/pom.xml b/phenopacket-tools-cli/pom.xml index 7fe7c7fe..83c6f6d9 100644 --- a/phenopacket-tools-cli/pom.xml +++ b/phenopacket-tools-cli/pom.xml @@ -30,7 +30,6 @@ org.phenopackets.phenopackettools phenopacket-tools-validator-jsonschema ${project.parent.version} - compile info.picocli @@ -49,6 +48,10 @@ com.fasterxml.jackson.dataformat jackson-dataformat-yaml + + com.google.protobuf + protobuf-java-util + diff --git a/phenopacket-tools-cli/src/main/java/module-info.java b/phenopacket-tools-cli/src/main/java/module-info.java new file mode 100644 index 00000000..c5bc5ab2 --- /dev/null +++ b/phenopacket-tools-cli/src/main/java/module-info.java @@ -0,0 +1,11 @@ +module org.phenopacket.tools.cli { + requires org.phenopacket.tools.converter; + requires org.phenopacket.tools.builder; + requires org.phenopacket.tools.validator.jsonschema; + + requires com.google.protobuf; + requires com.google.protobuf.util; + requires com.fasterxml.jackson.databind; + requires com.fasterxml.jackson.dataformat.yaml; + requires info.picocli; +} \ No newline at end of file diff --git a/phenopacket-tools-converter/pom.xml b/phenopacket-tools-converter/pom.xml index bdc3f39b..be927d85 100644 --- a/phenopacket-tools-converter/pom.xml +++ b/phenopacket-tools-converter/pom.xml @@ -21,9 +21,5 @@ com.google.protobuf protobuf-java - - com.google.protobuf - protobuf-java-util - \ No newline at end of file diff --git a/phenopacket-tools-converter/src/main/java/module-info.java b/phenopacket-tools-converter/src/main/java/module-info.java new file mode 100644 index 00000000..3fa93b05 --- /dev/null +++ b/phenopacket-tools-converter/src/main/java/module-info.java @@ -0,0 +1,8 @@ +module org.phenopacket.tools.converter { + // TODO - needs to be fixed after modular phenopacket schema is deployed to MC + requires transitive phenopacket.schema; + requires com.google.protobuf; + + // TODO - do we want to export the `v2` package as well? + exports org.phenopackets.phenopackettools.converter.converters; +} \ No newline at end of file diff --git a/phenopacket-tools-validator-core/src/main/java/module-info.java b/phenopacket-tools-validator-core/src/main/java/module-info.java new file mode 100644 index 00000000..b570d14f --- /dev/null +++ b/phenopacket-tools-validator-core/src/main/java/module-info.java @@ -0,0 +1,6 @@ +module org.phenopacket.tools.validator.core { + requires org.slf4j; + + exports org.phenopackets.phenopackettools.validator.core; + exports org.phenopackets.phenopackettools.validator.core.except; +} \ No newline at end of file diff --git a/phenopacket-tools-validator-jsonschema/src/main/java/module-info.java b/phenopacket-tools-validator-jsonschema/src/main/java/module-info.java new file mode 100644 index 00000000..c051758a --- /dev/null +++ b/phenopacket-tools-validator-jsonschema/src/main/java/module-info.java @@ -0,0 +1,9 @@ +module org.phenopacket.tools.validator.jsonschema { + requires transitive org.phenopacket.tools.validator.core; + + requires com.fasterxml.jackson.databind; + requires json.schema.validator; + requires org.slf4j; + + exports org.phenopackets.phenopackettools.validator.jsonschema; +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index e963c532..f53c9c4e 100644 --- a/pom.xml +++ b/pom.xml @@ -109,7 +109,6 @@ org.phenopackets phenopacket-schema ${phenopacket-schema.version} - compile com.google.protobuf @@ -127,6 +126,12 @@ + + + info.picocli + picocli + 4.6.3 + From a536c4797a5101635b192d7e9abfb8689900099e Mon Sep 17 00:00:00 2001 From: Daniel Danis Date: Thu, 19 May 2022 17:08:01 -0400 Subject: [PATCH 045/155] Use `phenopacket-schema v2.0.1`. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f53c9c4e..eb003574 100644 --- a/pom.xml +++ b/pom.xml @@ -72,7 +72,7 @@ 11 3.14.0 - 2.0.0 + 2.0.1 5.7.1 From 83370f814448879dca53134fddb9a5acdd946cf1 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Wed, 1 Jun 2022 09:52:41 -0400 Subject: [PATCH 046/155] Lupus example --- .../src/main/java/module-info.java | 2 + .../command/ExamplesCommand.java | 23 ++++---- .../examples/BethlehamMyopathy.java | 4 +- .../phenopackettools/examples/Covid.java | 4 +- .../phenopackettools/examples/Marfan.java | 4 +- .../examples/NemalineMyopathyPrenatal.java | 4 +- .../examples/PhenopacketExamples.java | 54 ------------------- .../examples/SleKidneyTransplantation.java | 18 +++++-- .../examples/SquamousCellCancer.java | 4 +- .../examples/Thrombocytopenia2.java | 4 +- .../examples/UrothelialCancer.java | 4 +- 11 files changed, 42 insertions(+), 83 deletions(-) delete mode 100644 phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/PhenopacketExamples.java diff --git a/phenopacket-tools-cli/src/main/java/module-info.java b/phenopacket-tools-cli/src/main/java/module-info.java index c5bc5ab2..7afdbb9c 100644 --- a/phenopacket-tools-cli/src/main/java/module-info.java +++ b/phenopacket-tools-cli/src/main/java/module-info.java @@ -8,4 +8,6 @@ requires com.fasterxml.jackson.databind; requires com.fasterxml.jackson.dataformat.yaml; requires info.picocli; + + opens org.phenopackets.phenopackettools.command to info.picocli; } \ No newline at end of file diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java index 423534be..d640dfd1 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java @@ -11,9 +11,7 @@ import com.google.protobuf.util.JsonFormat; import org.phenopackets.phenopackettools.builder.exceptions.PhenotoolsRuntimeException; -import org.phenopackets.phenopackettools.examples.FamilyWithPedigree; -import org.phenopackets.phenopackettools.examples.PhenopacketExamples; -import org.phenopackets.phenopackettools.examples.WarburgMicroSyndrome; +import org.phenopackets.phenopackettools.examples.*; import picocli.CommandLine; import picocli.CommandLine.Command; @@ -116,15 +114,16 @@ private int outputAllPhenopackets() { Path outDir = Path.of(output); Path outDirectory = createOutdirectoryIfNeeded(outDir); try { - output(PhenopacketExamples.bethlemMyopathy(), outDirectory, "bethleham-myopathy"); - output(PhenopacketExamples.thrombocytopenia2(), outDirectory, "thrombocytopenia2"); - output(PhenopacketExamples.marfanSyndrome(), outDirectory, "marfan"); - output(PhenopacketExamples.acuteMyeloidLeukemia(), outDirectory, "nemalineMyopathy"); - output(PhenopacketExamples.GLAUCOMA, outDirectory, "glaucoma"); - output(PhenopacketExamples.squamousCellEsophagealCarcinoma(), outDirectory, "squamous-cell-esophageal-carcinoma"); - output(PhenopacketExamples.urothelialCarcinoma(), outDirectory, "urothelial-cancer"); - output(PhenopacketExamples.covid19(), outDirectory, "covid"); - output(PhenopacketExamples.retinoblastoma(), outDirectory, "retinoblastoma"); + output(new BethlehamMyopathy().getPhenopacket(), outDirectory, "bethleham-myopathy"); + output(new Thrombocytopenia2().getPhenopacket(), outDirectory, "thrombocytopenia2"); + output(new Marfan().getPhenopacket(), outDirectory, "marfan"); + output(new NemalineMyopathyPrenatal().getPhenopacket(), outDirectory, "nemalineMyopathy"); + output(new GlaucomaSurgery().getPhenopacket(), outDirectory,"glaucoma"); + output(new SleKidneyTransplantation().getPhenopacket(), outDirectory, "lupus"); + output(new SquamousCellCancer().getPhenopacket(), outDirectory, "squamous-cell-esophageal-carcinoma"); + output(new UrothelialCancer().getPhenopacket(), outDirectory, "urothelial-cancer"); + output(new Covid().getPhenopacket(), outDirectory, "covid"); + output(new Retinoblastoma().getPhenopacket(), outDirectory, "retinoblastoma"); output(new WarburgMicroSyndrome().getPhenopacket(), outDirectory, "warburg-micro-syndrome"); outputFamily(new FamilyWithPedigree().getFamily(), outDirectory, "family"); } catch (Exception e) { diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/BethlehamMyopathy.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/BethlehamMyopathy.java index 9d1c8796..d7bb1d11 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/BethlehamMyopathy.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/BethlehamMyopathy.java @@ -8,14 +8,14 @@ import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; -class BethlehamMyopathy implements PhenopacketExample { +public class BethlehamMyopathy implements PhenopacketExample { private static final String PHENOPACKET_ID = "arbitrary proband id"; private static final String INTERPRETATION_ID = "arbitrary interpretation id"; private static final String PROBAND_ID = "proband A"; private final Phenopacket phenopacket; - BethlehamMyopathy() { + public BethlehamMyopathy() { var authorAssertion = EvidenceBuilder.authorStatementEvidence("PMID:30808312", "COL6A1 mutation leading to Bethlem myopathy with recurrent hematuria: a case report"); var bethlehamMyopathy = ontologyClass("OMIM:158810", "Bethlem myopathy 1"); var individual = IndividualBuilder.builder(PROBAND_ID).male().ageAtLastEncounter("P6Y3M").build(); diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Covid.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Covid.java index df5ab395..ded05bbe 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Covid.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Covid.java @@ -10,7 +10,7 @@ import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; -class Covid implements PhenopacketExample { +public class Covid implements PhenopacketExample { private static final String ONSET_OF_COVID = "2021-02-01T05:00:00Z"; @@ -31,7 +31,7 @@ class Covid implements PhenopacketExample { private final Phenopacket phenopacket; - Covid() { + public Covid() { Individual patient = IndividualBuilder.builder("P123542") .male() .ageAtLastEncounter("P70Y") diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Marfan.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Marfan.java index ec6aaa41..ddd2aa4a 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Marfan.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Marfan.java @@ -6,14 +6,14 @@ import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; -class Marfan implements PhenopacketExample { +public class Marfan implements PhenopacketExample { private static final String PHENOPACKET_ID = "id-C"; private static final String PROBAND_ID = "proband C"; private final Phenopacket phenopacket; - Marfan() { + public Marfan() { var marfan = DiseaseBuilder.of("OMIM:154700 ", "Marfan syndrome"); var individual = IndividualBuilder.builder(PROBAND_ID).female().ageAtLastEncounter("P27Y").build(); var losartan = ontologyClass("DrugCentral:1610", "losartan"); diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/NemalineMyopathyPrenatal.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/NemalineMyopathyPrenatal.java index edcb8042..b99b61cd 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/NemalineMyopathyPrenatal.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/NemalineMyopathyPrenatal.java @@ -19,14 +19,14 @@ * doi: 10.31083/j.ceog.2020.06.209 * (Not in PubMed) */ -class NemalineMyopathyPrenatal implements PhenopacketExample { +public class NemalineMyopathyPrenatal implements PhenopacketExample { private static final String PHENOPACKET_ID = "arbitrary.id"; private static final String PROBAND_ID = "proband A"; private static final OntologyClass NEMALINE_MYOPATHY_8 = ontologyClass("MONDO:0014138", "nemaline myopathy 8"); private final Phenopacket phenopacket; - NemalineMyopathyPrenatal() { + public NemalineMyopathyPrenatal() { var metadata = MetaDataBuilder.builder("2021-05-14T10:35:00Z", "anonymous biocurator") .addResource(Resources.ncitVersion("21.05d")) diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/PhenopacketExamples.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/PhenopacketExamples.java deleted file mode 100644 index 9b17a3d8..00000000 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/PhenopacketExamples.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.phenopackets.phenopackettools.examples; - -import org.phenopackets.schema.v2.Phenopacket; - -public class PhenopacketExamples { - - public static final Phenopacket BETHLEM_MYOPATHY = new BethlehamMyopathy().getPhenopacket(); - public static final Phenopacket THROMBOCYTOPENIA = new Thrombocytopenia2().getPhenopacket(); - public static final Phenopacket MARFAN_SYNDROME = new Marfan().getPhenopacket(); - public static final Phenopacket AML = new NemalineMyopathyPrenatal().getPhenopacket(); - public static final Phenopacket SCC = new SquamousCellCancer().getPhenopacket(); - public static final Phenopacket UROTHELIAL_CARCINOMA = new UrothelialCancer().getPhenopacket(); - public static final Phenopacket COVID_19 = new Covid().getPhenopacket(); - public static final Phenopacket RETINOBLASTOMA = new Retinoblastoma().getPhenopacket(); - public static final Phenopacket NEMALINE_MYOPATHY = new NemalineMyopathyPrenatal().getPhenopacket(); - public static final Phenopacket GLAUCOMA = new GlaucomaSurgery().getPhenopacket(); - - - private PhenopacketExamples() { - } - - public static Phenopacket bethlemMyopathy() { - return BETHLEM_MYOPATHY; - } - - public static Phenopacket thrombocytopenia2() { - return THROMBOCYTOPENIA; - } - - public static Phenopacket marfanSyndrome() { - return MARFAN_SYNDROME; - - } - - public static Phenopacket acuteMyeloidLeukemia() { - return AML; - } - - public static Phenopacket squamousCellEsophagealCarcinoma() { - return SCC; - } - - public static Phenopacket urothelialCarcinoma() { - return UROTHELIAL_CARCINOMA; - } - - public static Phenopacket covid19() { - return COVID_19; - } - - public static Phenopacket retinoblastoma() { return RETINOBLASTOMA; } - - public static Phenopacket getNemalineMyopathy() { return NEMALINE_MYOPATHY; } -} diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SleKidneyTransplantation.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SleKidneyTransplantation.java index 2fbd60ae..21dc028d 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SleKidneyTransplantation.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SleKidneyTransplantation.java @@ -1,10 +1,9 @@ package org.phenopackets.phenopackettools.examples; import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; -import org.phenopackets.phenopackettools.builder.builders.IndividualBuilder; -import org.phenopackets.phenopackettools.builder.builders.MetaDataBuilder; -import org.phenopackets.phenopackettools.builder.builders.Resources; +import org.phenopackets.phenopackettools.builder.builders.*; import org.phenopackets.schema.v2.Phenopacket; +import org.phenopackets.schema.v2.core.Disease; import org.phenopackets.schema.v2.core.Individual; import org.phenopackets.schema.v2.core.OntologyClass; @@ -43,6 +42,19 @@ public SleKidneyTransplantation() { build(); phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metadata) .individual(proband) + .addDisease(sle()) + .build(); + } + + + /** + * A 39-year-old female patient was referred to our Nephrology Department during late 2009. + * She was newly diagnosed with SLE after a spontaneous miscarriage during the second trimester of pregnancy. + * @return + */ + Disease sle() { + return DiseaseBuilder.builder(SYSTEMIC_LUPUS) + .onset(TimeElements.age("P39Y")) .build(); } diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SquamousCellCancer.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SquamousCellCancer.java index 8626dc28..1a205f55 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SquamousCellCancer.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SquamousCellCancer.java @@ -8,14 +8,14 @@ import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; -class SquamousCellCancer implements PhenopacketExample { +public class SquamousCellCancer implements PhenopacketExample { private static final String PHENOPACKET_ID = "arbitrary.id"; private static final String PROBAND_ID = "proband A"; private static final OntologyClass BIOPSY = ontologyClass("NCIT:C15189", "Biopsy"); private final Phenopacket phenopacket; - SquamousCellCancer() { + public SquamousCellCancer() { Individual proband = IndividualBuilder.builder(PROBAND_ID).male().ageAtLastEncounter("P38Y").build(); var metadata = MetaDataBuilder.builder("2021-05-14T10:35:00Z", "anonymous biocurator") .addResource(Resources.ncitVersion("21.05d")) diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Thrombocytopenia2.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Thrombocytopenia2.java index 97d76747..234b1f6d 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Thrombocytopenia2.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Thrombocytopenia2.java @@ -7,14 +7,14 @@ import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; -class Thrombocytopenia2 implements PhenopacketExample { +public class Thrombocytopenia2 implements PhenopacketExample { private static final String PHENOPACKET_ID = "id-C"; private static final String INTERPRETATION_ID = "arbitrary interpretation id"; private static final String PROBAND_ID = "family 10 proband"; private final Phenopacket phenopacket; - Thrombocytopenia2() { + public Thrombocytopenia2() { var authorAssertion = EvidenceBuilder.authorStatementEvidence("PMID:21211618", "Mutations in the 5' UTR of ANKRD26, the ankirin repeat domain 26 gene, cause an autosomal-dominant form of inherited thrombocytopenia, THC2"); var thrombocytopenia2 = ontologyClass("OMIM:188000", "Thrombocytopenia 2"); var individual = IndividualBuilder.builder(PROBAND_ID).female().ageAtLastEncounter("P20Y").build(); diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/UrothelialCancer.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/UrothelialCancer.java index 72fe95ab..c8ed23b5 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/UrothelialCancer.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/UrothelialCancer.java @@ -9,7 +9,7 @@ import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; -class UrothelialCancer implements PhenopacketExample { +public class UrothelialCancer implements PhenopacketExample { private static final String PHENOPACKET_ID = "arbitrary.id"; private static final String PROBAND_ID = "patient1"; private static final TimeElement AGE_AT_BIOPSY = TimeElements.age("P52Y2M"); @@ -17,7 +17,7 @@ class UrothelialCancer implements PhenopacketExample { private final Phenopacket phenopacket; - UrothelialCancer() { + public UrothelialCancer() { var individual = IndividualBuilder.builder(PROBAND_ID).male().dateOfBirth("1964-03-15T00:00:00Z").build(); var hematuria = PhenotypicFeatureBuilder.of("HP:0000790","Hematuria"); var dsyuria = PhenotypicFeatureBuilder.builder("HP:0100518", "Dysuria") From 20e82d1bfa1495ced0bece13de74d821aea5b5d7 Mon Sep 17 00:00:00 2001 From: Daniel Danis Date: Wed, 1 Jun 2022 12:19:24 -0400 Subject: [PATCH 047/155] Update Java module names, use phenopacket schema `v2.0.2`. Signed-off-by: Daniel Danis --- phenopacket-tools-builder/src/main/java/module-info.java | 8 +++----- phenopacket-tools-cli/src/main/java/module-info.java | 9 ++++----- .../src/main/java/module-info.java | 7 ++----- .../src/main/java/module-info.java | 2 +- .../src/main/java/module-info.java | 4 ++-- pom.xml | 2 +- 6 files changed, 13 insertions(+), 19 deletions(-) diff --git a/phenopacket-tools-builder/src/main/java/module-info.java b/phenopacket-tools-builder/src/main/java/module-info.java index 7ed36c34..aeda4c19 100644 --- a/phenopacket-tools-builder/src/main/java/module-info.java +++ b/phenopacket-tools-builder/src/main/java/module-info.java @@ -1,8 +1,6 @@ -module org.phenopacket.tools.builder { - // TODO - needs to be fixed after modular phenopacket schema is deployed to MC - requires transitive phenopacket.schema; - - requires com.google.protobuf; +module org.phenopackets.phenopackettools.builder { + requires transitive org.phenopackets.schema; + requires transitive com.google.protobuf; // TODO - investigate exports org.phenopackets.phenopackettools.builder; exports org.phenopackets.phenopackettools.builder.builders; diff --git a/phenopacket-tools-cli/src/main/java/module-info.java b/phenopacket-tools-cli/src/main/java/module-info.java index c5bc5ab2..552b8a78 100644 --- a/phenopacket-tools-cli/src/main/java/module-info.java +++ b/phenopacket-tools-cli/src/main/java/module-info.java @@ -1,9 +1,8 @@ -module org.phenopacket.tools.cli { - requires org.phenopacket.tools.converter; - requires org.phenopacket.tools.builder; - requires org.phenopacket.tools.validator.jsonschema; +module org.phenopackets.phenopackettools.cli { + requires org.phenopackets.phenopackettools.converter; + requires org.phenopackets.phenopackettools.builder; + requires org.phenopackets.phenopackettools.validator.jsonschema; - requires com.google.protobuf; requires com.google.protobuf.util; requires com.fasterxml.jackson.databind; requires com.fasterxml.jackson.dataformat.yaml; diff --git a/phenopacket-tools-converter/src/main/java/module-info.java b/phenopacket-tools-converter/src/main/java/module-info.java index 3fa93b05..75dbea5a 100644 --- a/phenopacket-tools-converter/src/main/java/module-info.java +++ b/phenopacket-tools-converter/src/main/java/module-info.java @@ -1,8 +1,5 @@ -module org.phenopacket.tools.converter { - // TODO - needs to be fixed after modular phenopacket schema is deployed to MC - requires transitive phenopacket.schema; - requires com.google.protobuf; +module org.phenopackets.phenopackettools.converter { + requires transitive org.phenopackets.schema; - // TODO - do we want to export the `v2` package as well? exports org.phenopackets.phenopackettools.converter.converters; } \ No newline at end of file diff --git a/phenopacket-tools-validator-core/src/main/java/module-info.java b/phenopacket-tools-validator-core/src/main/java/module-info.java index b570d14f..d3531f92 100644 --- a/phenopacket-tools-validator-core/src/main/java/module-info.java +++ b/phenopacket-tools-validator-core/src/main/java/module-info.java @@ -1,4 +1,4 @@ -module org.phenopacket.tools.validator.core { +module org.phenopackets.phenopackettools.validator.core { requires org.slf4j; exports org.phenopackets.phenopackettools.validator.core; diff --git a/phenopacket-tools-validator-jsonschema/src/main/java/module-info.java b/phenopacket-tools-validator-jsonschema/src/main/java/module-info.java index c051758a..e245e9f2 100644 --- a/phenopacket-tools-validator-jsonschema/src/main/java/module-info.java +++ b/phenopacket-tools-validator-jsonschema/src/main/java/module-info.java @@ -1,5 +1,5 @@ -module org.phenopacket.tools.validator.jsonschema { - requires transitive org.phenopacket.tools.validator.core; +module org.phenopackets.phenopackettools.validator.jsonschema { + requires transitive org.phenopackets.phenopackettools.validator.core; requires com.fasterxml.jackson.databind; requires json.schema.validator; diff --git a/pom.xml b/pom.xml index eb003574..fd9cdb6e 100644 --- a/pom.xml +++ b/pom.xml @@ -72,7 +72,7 @@ 11 3.14.0 - 2.0.1 + 2.0.2 5.7.1 From 9c339624d4e87ad233df57e671381cbd26a2fb57 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Sun, 26 Jun 2022 10:52:56 -0400 Subject: [PATCH 048/155] glaucoma --- .../examples/GlaucomaSurgery.java | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/GlaucomaSurgery.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/GlaucomaSurgery.java index ee60564a..0fff5f42 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/GlaucomaSurgery.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/GlaucomaSurgery.java @@ -3,6 +3,7 @@ import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; import org.phenopackets.phenopackettools.builder.builders.MetaDataBuilder; import org.phenopackets.phenopackettools.builder.builders.Resources; +import org.phenopackets.phenopackettools.builder.constants.Onset; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.phenopackettools.builder.builders.*; import org.phenopackets.phenopackettools.builder.constants.Laterality; @@ -39,7 +40,7 @@ public GlaucomaSurgery() { .addResource(Resources.ncbiTaxonVersion("2021-06-10")) .build(); Individual proband = IndividualBuilder.builder(PROBAND_ID). - ageAtLastEncounter("P6M"). + ageAtLastEncounter("P70Y"). female(). XX(). build(); @@ -88,21 +89,16 @@ public Phenopacket getPhenopacket() { measured with the Perkins tonometer. */ List getMeasurements() { - OntologyClass iop = ontologyClass("56844-4","Intraocular pressure of Eye"); - ReferenceRange ref = ReferenceRangeBuilder.of(iop, 10, 21); - OntologyClass leftEyeIop = - OntologyClassBuilder.ontologyClass("LOINC:79893-4", "Left eye Intraocular pressure"); - Value leftEyeValue = ValueBuilder.of(Unit.mmHg(), 25, ref); - OntologyClass rightEyeIop = - OntologyClassBuilder.ontologyClass("LOINC:79892-6", "Right eye Intraocular pressure"); - Value rightEyeValue = ValueBuilder.of(Unit.mmHg(), 15, ref); - TimeElement age = TimeElements.age("P6M"); - - Measurement leftEyeMeasurement = MeasurementBuilder.builder(leftEyeIop, leftEyeValue).timeObserved(age).build(); - Measurement rightEyeMeasurement = MeasurementBuilder.builder(rightEyeIop, rightEyeValue).timeObserved(age).build(); - //33728-7 Size.maximum dimension in Tumor - //14 × 13 × 11 mm left eye tumor - return List.of(leftEyeMeasurement, rightEyeMeasurement); + OntologyClass visusPercent = ontologyClass("NCIT:C48570", "Percent Unit"); + // -0.25/-0.5/110 degreees + TypedQuantity visus100 = TypedQuantityBuilder.of(ontologyClass("NCIT:C87149", "Visual Acuity"), + QuantityBuilder.of(visusPercent, 100)); + var visionAssessment = ontologyClass("NCIT:C156778", "Vision Assessment"); + Measurement visusMeasurement = MeasurementBuilder + .builder(visionAssessment, ComplexValueBuilder.of(visus100)).build(); + // NCIT:C117889 Astigmatism Axis - A measurement of the location, in degrees, of the flatter principal meridian on a 180-degree scale, where 90 degrees designates the vertical meridian and 180 degrees designates the horizontal meridian. [ NCI ] + + return List.of(visusMeasurement); } List getPhenotypicFeatures() { @@ -124,13 +120,18 @@ List getPhenotypicFeatures() { .addModifier(Laterality.left()) .onset(age5months) .build(); + PhenotypicFeature excludedPhacodonesis = PhenotypicFeatureBuilder. + builder("HP:0012629", "Phakodonesis") + .excluded() + .build(); + TimeElement age6months = TimeElements.age("P6M"); PhenotypicFeature retinalDetachment = PhenotypicFeatureBuilder .builder("HP:0000541", "Retinal detachment") .addModifier(Laterality.left()) .onset(age6months) .build(); - return List.of(clinodactyly, leukocoria, strabismus, retinalDetachment); + return List.of(clinodactyly, leukocoria, strabismus, retinalDetachment, excludedPhacodonesis); } } From 624517b958b54e6ba2cd5d3386b67de846545807 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Sun, 26 Jun 2022 10:57:31 -0400 Subject: [PATCH 049/155] cleanup --- .../examples/GlaucomaSurgery.java | 67 ++++++++++++------- 1 file changed, 44 insertions(+), 23 deletions(-) diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/GlaucomaSurgery.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/GlaucomaSurgery.java index 0fff5f42..f16aec8c 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/GlaucomaSurgery.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/GlaucomaSurgery.java @@ -85,32 +85,58 @@ public Phenopacket getPhenopacket() { } /* - The intraocular pressure was 25 mmHg in the right eye and 15 mmHg in the left eye, - measured with the Perkins tonometer. - */ + The intraocular pressure was 25 mmHg in the right eye and 15 mmHg in the left eye, + measured with the Perkins tonometer. + */ List getMeasurements() { - OntologyClass visusPercent = ontologyClass("NCIT:C48570", "Percent Unit"); - // -0.25/-0.5/110 degreees - TypedQuantity visus100 = TypedQuantityBuilder.of(ontologyClass("NCIT:C87149", "Visual Acuity"), - QuantityBuilder.of(visusPercent, 100)); - var visionAssessment = ontologyClass("NCIT:C156778", "Vision Assessment"); - Measurement visusMeasurement = MeasurementBuilder - .builder(visionAssessment, ComplexValueBuilder.of(visus100)).build(); - // NCIT:C117889 Astigmatism Axis - A measurement of the location, in degrees, of the flatter principal meridian on a 180-degree scale, where 90 degrees designates the vertical meridian and 180 degrees designates the horizontal meridian. [ NCI ] - - return List.of(visusMeasurement); + OntologyClass iop = ontologyClass("56844-4","Intraocular pressure of Eye"); + ReferenceRange ref = ReferenceRangeBuilder.of(iop, 10, 21); + OntologyClass leftEyeIop = + OntologyClassBuilder.ontologyClass("LOINC:79893-4", "Left eye Intraocular pressure"); + Value leftEyeValue = ValueBuilder.of(Unit.mmHg(), 25, ref); + OntologyClass rightEyeIop = + OntologyClassBuilder.ontologyClass("LOINC:79892-6", "Right eye Intraocular pressure"); + Value rightEyeValue = ValueBuilder.of(Unit.mmHg(), 15, ref); + TimeElement age = TimeElements.age("P6M"); + + Measurement leftEyeMeasurement = MeasurementBuilder.builder(leftEyeIop, leftEyeValue).timeObserved(age).build(); + Measurement rightEyeMeasurement = MeasurementBuilder.builder(rightEyeIop, rightEyeValue).timeObserved(age).build(); + //33728-7 Size.maximum dimension in Tumor + //14 × 13 × 11 mm left eye tumor + return List.of(leftEyeMeasurement, rightEyeMeasurement); } + + /* +Pseudophakia HP:0500081 +Cataract HP:0000518 +Shallow anterior chamber HP:0000594 +Pseudophakia HP:0500081 +Asymmetry of intraocular pressure HP:0012633 +Ocular hypertension HP:0007906 +PseudoexfoliationHP:0012627 +GlaucomaOMIT:0007096 +Pseudoexfoliation glaucoma (disorder)111514006 +http://snomed.info/id/111514006 +Pseudoexfoliation glaucoma of left eye (disorder)338481000119100 +http://snomed.info/id/338481000119100 +Pseudoexfoliation glaucoma of bilateral eyes (disorder)344251000119103 +http://snomed.info/id/344251000119103 +Pseudoexfoliation glaucoma of right eye (disorder)332871000119103 +http://snomed.info/id/332871000119103 +*/ + + List getPhenotypicFeatures() { - TimeElement age3months = TimeElements.age("P3M"); + TimeElement age70years = TimeElements.age("P70J"); PhenotypicFeature clinodactyly = PhenotypicFeatureBuilder. - builder("HP:0030084", "Clinodactyly"). + builder("HP:0012108", "Open angle glaucoma "). addModifier(Laterality.right()). - onset(age3months). + onset(age70years). build(); TimeElement age4months = TimeElements.age("P4M"); PhenotypicFeature leukocoria = PhenotypicFeatureBuilder. - builder("HP:0000555", "Leukocoria") + builder("HP:0500081", "Pseudophakia") .addModifier(Laterality.left()) .onset(age4months) .build(); @@ -120,18 +146,13 @@ List getPhenotypicFeatures() { .addModifier(Laterality.left()) .onset(age5months) .build(); - PhenotypicFeature excludedPhacodonesis = PhenotypicFeatureBuilder. - builder("HP:0012629", "Phakodonesis") - .excluded() - .build(); - TimeElement age6months = TimeElements.age("P6M"); PhenotypicFeature retinalDetachment = PhenotypicFeatureBuilder .builder("HP:0000541", "Retinal detachment") .addModifier(Laterality.left()) .onset(age6months) .build(); - return List.of(clinodactyly, leukocoria, strabismus, retinalDetachment, excludedPhacodonesis); + return List.of(clinodactyly, leukocoria, strabismus, retinalDetachment); } } From 89825855a6e4c218628c10cab24625e8afe5e33b Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Sun, 26 Jun 2022 10:59:14 -0400 Subject: [PATCH 050/155] Changing name to OntologyClass exfoliationSyndrome = ontologyClass("MONDO:0008327", Pseudoexfoliation --- .../phenopackettools/command/ExamplesCommand.java | 2 +- .../{GlaucomaSurgery.java => Pseudoexfoliation.java} | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) rename phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/{GlaucomaSurgery.java => Pseudoexfoliation.java} (96%) diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java index d640dfd1..95287a34 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java @@ -118,7 +118,7 @@ private int outputAllPhenopackets() { output(new Thrombocytopenia2().getPhenopacket(), outDirectory, "thrombocytopenia2"); output(new Marfan().getPhenopacket(), outDirectory, "marfan"); output(new NemalineMyopathyPrenatal().getPhenopacket(), outDirectory, "nemalineMyopathy"); - output(new GlaucomaSurgery().getPhenopacket(), outDirectory,"glaucoma"); + output(new Pseudoexfoliation().getPhenopacket(), outDirectory,"glaucoma"); output(new SleKidneyTransplantation().getPhenopacket(), outDirectory, "lupus"); output(new SquamousCellCancer().getPhenopacket(), outDirectory, "squamous-cell-esophageal-carcinoma"); output(new UrothelialCancer().getPhenopacket(), outDirectory, "urothelial-cancer"); diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/GlaucomaSurgery.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Pseudoexfoliation.java similarity index 96% rename from phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/GlaucomaSurgery.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Pseudoexfoliation.java index f16aec8c..cf856577 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/GlaucomaSurgery.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Pseudoexfoliation.java @@ -3,12 +3,10 @@ import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; import org.phenopackets.phenopackettools.builder.builders.MetaDataBuilder; import org.phenopackets.phenopackettools.builder.builders.Resources; -import org.phenopackets.phenopackettools.builder.constants.Onset; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.phenopackettools.builder.builders.*; import org.phenopackets.phenopackettools.builder.constants.Laterality; import org.phenopackets.phenopackettools.builder.constants.Unit; -import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; import java.util.List; @@ -16,7 +14,7 @@ import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; -public class GlaucomaSurgery implements PhenopacketExample { +public class Pseudoexfoliation implements PhenopacketExample { private static final String PHENOPACKET_ID = "arbitrary.id"; private static final String PROBAND_ID = "proband A"; private static final String BIOSAMPLE_ID = "biosample.1"; @@ -31,7 +29,7 @@ public class GlaucomaSurgery implements PhenopacketExample { private final Phenopacket phenopacket; - public GlaucomaSurgery() { + public Pseudoexfoliation() { // hallo var metadata = MetaDataBuilder.builder("2021-05-14T10:35:00Z", "anonymous biocurator") .addResource(Resources.ncitVersion("21.05d")) From 09688074da4ffa878b1f42173b16d6f1aaf16fab Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Sun, 26 Jun 2022 11:07:32 -0400 Subject: [PATCH 051/155] adding back measurement --- .../examples/Pseudoexfoliation.java | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Pseudoexfoliation.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Pseudoexfoliation.java index cf856577..1e053701 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Pseudoexfoliation.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Pseudoexfoliation.java @@ -101,7 +101,18 @@ List getMeasurements() { Measurement rightEyeMeasurement = MeasurementBuilder.builder(rightEyeIop, rightEyeValue).timeObserved(age).build(); //33728-7 Size.maximum dimension in Tumor //14 × 13 × 11 mm left eye tumor - return List.of(leftEyeMeasurement, rightEyeMeasurement); + + OntologyClass visusPercent = ontologyClass("NCIT:C48570", "Percent Unit"); + // -0.25/-0.5/110 degreees + TypedQuantity visus100 = TypedQuantityBuilder.of(ontologyClass("NCIT:C87149", "Visual Acuity"), + QuantityBuilder.of(visusPercent, 100)); + var visionAssessment = ontologyClass("NCIT:C156778", "Vision Assessment"); + Measurement visusMeasurement = MeasurementBuilder + .builder(visionAssessment, ComplexValueBuilder.of(visus100)).build(); + // NCIT:C117889 Astigmatism Axis - A measurement of the location, in degrees, of the flatter principal meridian on a 180-degree scale, where 90 degrees designates the vertical meridian and 180 degrees designates the horizontal meridian. [ NCI ] + + + return List.of(leftEyeMeasurement, rightEyeMeasurement, visusMeasurement); } @@ -150,7 +161,11 @@ List getPhenotypicFeatures() { .addModifier(Laterality.left()) .onset(age6months) .build(); - return List.of(clinodactyly, leukocoria, strabismus, retinalDetachment); + PhenotypicFeature excludedPhacodonesis = PhenotypicFeatureBuilder. + builder("HP:0012629", "Phakodonesis") + .excluded() + .build(); + return List.of(clinodactyly, leukocoria, strabismus, retinalDetachment, excludedPhacodonesis); } } From c20c2616dedf17befc3d94a1588e9607f4ddda7c Mon Sep 17 00:00:00 2001 From: Markus <99075696+Sukramg@users.noreply.github.com> Date: Sun, 26 Jun 2022 17:10:00 +0200 Subject: [PATCH 052/155] Hallo Test Zeile 173 --- .../phenopackettools/examples/Pseudoexfoliation.java | 1 + 1 file changed, 1 insertion(+) diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Pseudoexfoliation.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Pseudoexfoliation.java index 1e053701..b101f1a7 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Pseudoexfoliation.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Pseudoexfoliation.java @@ -170,3 +170,4 @@ List getPhenotypicFeatures() { } +// Hallo Test \ No newline at end of file From 7a97596863f9f6be35e2b9613ded9382f2c9ee86 Mon Sep 17 00:00:00 2001 From: Markus <99075696+Sukramg@users.noreply.github.com> Date: Sun, 26 Jun 2022 17:17:33 +0200 Subject: [PATCH 053/155] Hallo Test Zeile 173 entfernt --- .../phenopackettools/examples/Pseudoexfoliation.java | 1 - 1 file changed, 1 deletion(-) diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Pseudoexfoliation.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Pseudoexfoliation.java index b101f1a7..1e053701 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Pseudoexfoliation.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Pseudoexfoliation.java @@ -170,4 +170,3 @@ List getPhenotypicFeatures() { } -// Hallo Test \ No newline at end of file From 780e89c58df4c19736e0b205dc3292a287d8818b Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Thu, 30 Jun 2022 13:03:25 -0400 Subject: [PATCH 054/155] hotfix --- .../phenopackettools/builder/constants/Organs.java | 12 ++++++++++++ .../phenopackettools/examples/Retinoblastoma.java | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Organs.java diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Organs.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Organs.java new file mode 100644 index 00000000..d96ae29a --- /dev/null +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Organs.java @@ -0,0 +1,12 @@ +package org.phenopackets.phenopackettools.builder.constants; + +import org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder; +import org.phenopackets.schema.v2.core.OntologyClass; + +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; + +public class Organs { + + + public static final OntologyClass KIDNEY = ontologyClass("UBERON:0002113", "Kidney"); +} diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java index b7dd471d..ba3faf54 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Retinoblastoma.java @@ -80,7 +80,7 @@ GenomicInterpretation somaticRb1Missense() { .genomic() .heterozygous() .label("RB1 c.958C>T (p.Arg320Ter)") - .transcript() + .genomic() .vcfHg38("NC_000013.11", 48367512, "C", "T") .alleleFrequency(25.0) .geneContext(GeneDescriptorBuilder.of("HGNC:9884", "RB1")) From f491722dfa85134184ccf75d881e7d34a1f1facd Mon Sep 17 00:00:00 2001 From: Markus <99075696+Sukramg@users.noreply.github.com> Date: Tue, 5 Jul 2022 14:15:46 +0200 Subject: [PATCH 055/155] Etwas angepasst dem Fall --- .../examples/Pseudoexfoliation.java | 134 ++++++++---------- 1 file changed, 60 insertions(+), 74 deletions(-) diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Pseudoexfoliation.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Pseudoexfoliation.java index 1e053701..18143d14 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Pseudoexfoliation.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Pseudoexfoliation.java @@ -13,67 +13,54 @@ import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; - -public class Pseudoexfoliation implements PhenopacketExample { +/* +RA: Cataract and PEX -> Cataractsurgery -> Emmetropia -> 1J1M Myopia + elevated eyeIop -> Brimonidine -> Yag-IT -> normal Iop +LA: Cataract -> Cataractsurgery -> Emmetropia +RA/LA: Monovision +*/ + public class Pseudoexfoliation implements PhenopacketExample { private static final String PHENOPACKET_ID = "arbitrary.id"; private static final String PROBAND_ID = "proband A"; private static final String BIOSAMPLE_ID = "biosample.1"; - + private static final OntologyClass Pseudoexfoliation = ontologyClass("HP:0012627", "Pseudoexfoliation"); + private static final OntologyClass Pseudophakia = ontologyClass("HP:0500081", "Pseudophakia"); // Organs private static final OntologyClass EYE = ontologyClass("UBERON:0000970", "eye"); - private static final OntologyClass CURE = ontologyClass("NCIT:C62220", "Cure"); private static final OntologyClass LEFT_EYE = ontologyClass("UBERON:0004548", "left eye"); - - + private static final OntologyClass RIGHT_EYE = ontologyClass("UBERON:0004549", "right eye"); + private static final OntologyClass Cataract = ontologyClass("HP:0000518", "cataract"); private final Phenopacket phenopacket; - public Pseudoexfoliation() { - // hallo + // Metadaten var metadata = MetaDataBuilder.builder("2021-05-14T10:35:00Z", "anonymous biocurator") - .addResource(Resources.ncitVersion("21.05d")) - .addResource(Resources.efoVersion("3.34.0")) .addResource(Resources.uberonVersion("2021-07-27")) - .addResource(Resources.ncbiTaxonVersion("2021-06-10")) + .addResource(Resources.hpoVersion("2021-08-02")) .build(); Individual proband = IndividualBuilder.builder(PROBAND_ID). ageAtLastEncounter("P70Y"). - female(). - XX(). + male(). + XY(). build(); - - - - PhenopacketBuilder builder = PhenopacketBuilder.create(PHENOPACKET_ID, metadata) + phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metadata) .individual(proband) .addAllMeasurements(getMeasurements()) .addAllPhenotypicFeatures(getPhenotypicFeatures()) - .addDisease(getDisease()); - // (Genom-Sequenz) .addInterpretation(interpretation()) - + .addDisease(getDisease()) + .addMedicalAction(Cataractsurgery()) + .addMedicalAction(brimonidine()) + .build(); - phenopacket = builder.build(); - } + } Disease getDisease() { - // NCIT:C27980 - // Stage E - // Group E = LOINC:LA24739-7 - // Retinoblastoma , NCIT:C7541 - // No metastasis is NCIT:C140678, Retinoblastoma cM0 TNM Finding v8 - // Retinoblastoma with no signs or symptoms of intracranial or distant metastasis. (from AJCC 8th Ed.) [ NCI ] - // OntologyClass stageE = ontologyClass("LOINC:LA24739-7", "Group E"); - // OntologyClass noMetastasis = ontologyClass("NCIT:C140678", "Retinoblastoma cM0 TNM Finding v8"); + OntologyClass exfoliationSyndrome = ontologyClass("MONDO:0008327", "exfoliation syndrome"); - // TimeElement age4m = TimeElements.age("P4M"); - TimeElement adult = TimeElements.adultOnset(); + TimeElement adult = TimeElements.adultOnset(); return DiseaseBuilder.builder(exfoliationSyndrome) .onset(adult) - // .addDiseaseStage(stageE) - // .addClinicalTnmFinding(noMetastasis) - - // .primarySite(LEFT_EYE) + .primarySite(RIGHT_EYE) .build(); } @@ -81,10 +68,30 @@ Disease getDisease() { public Phenopacket getPhenopacket() { return phenopacket; } + /* + uneventful clear-cornea phacoemulsification with PC/IOL +implantation in the right eye (OD) in January 2006. + */ + MedicalAction cataractsurgery = () { + ProcedureBuilder builder = ProcedureBuilder.builder("HP:0000518", "Cataractsurgery"); + TimeElement age = TimeElements.age("P70J"); + builder.bodySite(RIGHT_EYE).performed(age); + MedicalActionBuilder mabuilder = MedicalActionBuilder.builder(builder.build()) + .treatmentTarget(Cataract) + .treatmentIntent(Pseudophakia); + return mabuilder.build(); + } + MedicalAction cataractsurgery = () { + ProcedureBuilder builder = ProcedureBuilder.builder("HP:0000518", "Cataractsurgery"); + TimeElement age = TimeElements.age("P70J6W"); + builder.bodySite(LEFT_EYE).performed(age); + MedicalActionBuilder mabuilder = MedicalActionBuilder.builder(builder.build()) + .treatmentTarget(Cataract) + .treatmentIntent(Pseudophakia); + return mabuilder.build(); /* - The intraocular pressure was 25 mmHg in the right eye and 15 mmHg in the left eye, - measured with the Perkins tonometer. + The intraocular pressure was 29 mmHg in the right eye and 11 mmHg in the left eye */ List getMeasurements() { OntologyClass iop = ontologyClass("56844-4","Intraocular pressure of Eye"); @@ -99,8 +106,6 @@ List getMeasurements() { Measurement leftEyeMeasurement = MeasurementBuilder.builder(leftEyeIop, leftEyeValue).timeObserved(age).build(); Measurement rightEyeMeasurement = MeasurementBuilder.builder(rightEyeIop, rightEyeValue).timeObserved(age).build(); - //33728-7 Size.maximum dimension in Tumor - //14 × 13 × 11 mm left eye tumor OntologyClass visusPercent = ontologyClass("NCIT:C48570", "Percent Unit"); // -0.25/-0.5/110 degreees @@ -116,29 +121,21 @@ List getMeasurements() { } - /* -Pseudophakia HP:0500081 -Cataract HP:0000518 -Shallow anterior chamber HP:0000594 -Pseudophakia HP:0500081 -Asymmetry of intraocular pressure HP:0012633 -Ocular hypertension HP:0007906 -PseudoexfoliationHP:0012627 -GlaucomaOMIT:0007096 -Pseudoexfoliation glaucoma (disorder)111514006 -http://snomed.info/id/111514006 -Pseudoexfoliation glaucoma of left eye (disorder)338481000119100 -http://snomed.info/id/338481000119100 -Pseudoexfoliation glaucoma of bilateral eyes (disorder)344251000119103 -http://snomed.info/id/344251000119103 -Pseudoexfoliation glaucoma of right eye (disorder)332871000119103 -http://snomed.info/id/332871000119103 -*/ - - List getPhenotypicFeatures() { + TimeElement age70years = TimeElements.age("P70J"); + PhenotypicFeature emmetropia = PhenotypicFeatureBuilder. + builder("HP:0000539", "Abnormality of refraction"). // Verneinung, NO Abnormaility... + addModifier(Laterality.right()). + onset(age70years). + build(); + TimeElement age71years = TimeElements.age("P71J"); + PhenotypicFeature Myopia = PhenotypicFeatureBuilder. + builder("HP:0000545", "Myopia"). + addModifier(Laterality.right()). + onset(age71years). + build(); TimeElement age70years = TimeElements.age("P70J"); - PhenotypicFeature clinodactyly = PhenotypicFeatureBuilder. + PhenotypicFeature glaucoma = PhenotypicFeatureBuilder. builder("HP:0012108", "Open angle glaucoma "). addModifier(Laterality.right()). onset(age70years). @@ -146,21 +143,10 @@ List getPhenotypicFeatures() { TimeElement age4months = TimeElements.age("P4M"); PhenotypicFeature leukocoria = PhenotypicFeatureBuilder. builder("HP:0500081", "Pseudophakia") - .addModifier(Laterality.left()) + .addModifier(Laterality.right()) .onset(age4months) .build(); - TimeElement age5months = TimeElements.age("P5M15D"); - PhenotypicFeature strabismus = PhenotypicFeatureBuilder. - builder("HP:0000486", "Strabismus") - .addModifier(Laterality.left()) - .onset(age5months) - .build(); - TimeElement age6months = TimeElements.age("P6M"); - PhenotypicFeature retinalDetachment = PhenotypicFeatureBuilder - .builder("HP:0000541", "Retinal detachment") - .addModifier(Laterality.left()) - .onset(age6months) - .build(); + PhenotypicFeature excludedPhacodonesis = PhenotypicFeatureBuilder. builder("HP:0012629", "Phakodonesis") .excluded() From 3adbbcd563959c6b50bb455d97b8e92e5fd23f1f Mon Sep 17 00:00:00 2001 From: Daniel Danis Date: Wed, 6 Jul 2022 09:18:40 -0400 Subject: [PATCH 056/155] Add `SO` and `UO` into `Resources`. Signed-off-by: Daniel Danis --- .../builder/builders/Resources.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Resources.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Resources.java index 871edc75..aa686383 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Resources.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/Resources.java @@ -70,6 +70,20 @@ private Resources() { .setUrl("http://purl.obolibrary.org/obo/ncbitaxon.owl") .setIriPrefix("http://purl.obolibrary.org/obo/NCBITaxon_"); + private static final Resource.Builder SO_BUILDER = Resource.newBuilder() + .setId("so") + .setName("Sequence types and features ontology") + .setNamespacePrefix("SO") + .setUrl("http://purl.obolibrary.org/obo/so.owl") + .setIriPrefix("http://purl.obolibrary.org/obo/SO_"); + + private static final Resource.Builder UO_BUILDER = Resource.newBuilder() + .setId("uo") + .setName("Units of measurement ontology") + .setNamespacePrefix("UO") + .setUrl("http://purl.obolibrary.org/obo/uo.owl") + .setIriPrefix("http://purl.obolibrary.org/obo/UO_"); + public static Resource hpoVersion(String version) { return HPO_BUILDER.setVersion(version).build(); } @@ -106,4 +120,11 @@ public static Resource ncbiTaxonVersion(String version) { return NCBI_TAXON_BUILDER.setVersion(version).build(); } + public static Resource soVersion(String version) { + return SO_BUILDER.setVersion(version).build(); + } + + public static Resource uoVersion(String version) { + return UO_BUILDER.setVersion(version).build(); + } } From abbd3dd4b37a62e61b4319825a6130d5dc614669 Mon Sep 17 00:00:00 2001 From: Daniel Danis Date: Wed, 6 Jul 2022 09:25:15 -0400 Subject: [PATCH 057/155] Fix prefix in Homo sapiens constant in `IndividualBuilder`. Signed-off-by: Daniel Danis --- .../phenopackettools/builder/builders/IndividualBuilder.java | 2 +- .../builder/builders/IndividualBuilderTest.java | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilder.java index 6a54534d..d81badc9 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilder.java @@ -21,7 +21,7 @@ */ public class IndividualBuilder { - public static final OntologyClass HOMO_SAPIENS = OntologyClassBuilder.ontologyClass("NCBI:txid9606", "Homo sapiens"); + private static final OntologyClass HOMO_SAPIENS = OntologyClassBuilder.ontologyClass("NCBITaxon:9606", "Homo sapiens"); private final Individual.Builder builder; diff --git a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilderTest.java b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilderTest.java index 27c1034f..887e356d 100644 --- a/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilderTest.java +++ b/phenopacket-tools-builder/src/test/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilderTest.java @@ -7,7 +7,6 @@ import org.phenopackets.schema.v2.core.VitalStatus; import static org.junit.jupiter.api.Assertions.*; -import static org.phenopackets.phenopackettools.builder.builders.IndividualBuilder.HOMO_SAPIENS; import static org.phenopackets.phenopackettools.builder.builders.TimestampBuilder.fromISO8601; @@ -56,8 +55,8 @@ public void testTaxons() { assertEquals(musMusculus, individual.getTaxonomy()); Individual individual2 = IndividualBuilder.builder("human").homoSapiens().build(); - assertEquals(HOMO_SAPIENS, individual2.getTaxonomy()); - assertNotEquals(HOMO_SAPIENS, individual.getTaxonomy()); + assertEquals(OntologyClassBuilder.ontologyClass("NCBITaxon:9606", "Homo sapiens"), individual2.getTaxonomy()); + assertNotEquals(OntologyClassBuilder.ontologyClass("NCBITaxon:9606", "Homo sapiens"), individual.getTaxonomy()); } @Test From fa42758c42c8280ef1940ef939302923714c1d7b Mon Sep 17 00:00:00 2001 From: Daniel Danis Date: Wed, 6 Jul 2022 09:33:55 -0400 Subject: [PATCH 058/155] Ignore the entire `.idea` folder to simplify `.gitignore`. Signed-off-by: Daniel Danis --- .gitignore | 55 +++--------------------------------------------------- 1 file changed, 3 insertions(+), 52 deletions(-) diff --git a/.gitignore b/.gitignore index 0f6edc9d..da85ee72 100644 --- a/.gitignore +++ b/.gitignore @@ -26,28 +26,9 @@ hs_err_pid* # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 -# User-specific stuff -.idea/**/workspace.xml -.idea/**/tasks.xml -.idea/**/usage.statistics.xml -.idea/**/dictionaries -.idea/**/shelf - -# Generated files -.idea/**/contentModel.xml - -# Sensitive or high-churn files -.idea/**/dataSources/ -.idea/**/dataSources.ids -.idea/**/dataSources.local.xml -.idea/**/sqlDataSources.xml -.idea/**/dynamic.xml -.idea/**/uiDesigner.xml -.idea/**/dbnavigator.xml - -# Gradle -.idea/**/gradle.xml -.idea/**/libraries +.idea +*.iml +modules.xml # Maven target/ @@ -62,19 +43,9 @@ buildNumber.properties # https://github.com/takari/maven-wrapper#usage-without-binary-jar .mvn/wrapper/maven-wrapper.jar -# Gradle and Maven with auto-import -# When using Gradle or Maven with auto-import, you should exclude module files, -# since they will be recreated, and may cause churn. Uncomment if using -# auto-import. -.idea/modules.xml -.idea/*.iml -.idea/modules - # CMake cmake-build-*/ -# Mongo Explorer plugin -.idea/**/mongoSettings.xml # File-based project format *.iws @@ -88,32 +59,12 @@ out/ # JIRA plugin atlassian-ide-plugin.xml -# Cursive Clojure plugin -.idea/replstate.xml - # Crashlytics plugin (for Android Studio and IntelliJ) com_crashlytics_export_strings.xml crashlytics.properties crashlytics-build.properties fabric.properties -# Editor-based Rest Client -.idea/httpRequests - -# Android studio 3.1+ serialized cache file -.idea/caches/build_file_checksums.ser - -# JetBrains templates -**___jb_tmp___ - -*.iml -modules.xml -.idea/misc.xml -*.ipr - -# Sonarlint plugin -.idea/sonarlint - # Mac *.DS_Store /*.json From 124a40f0bf9d94e2e99b67f718c27933c8f944f7 Mon Sep 17 00:00:00 2001 From: Daniel Danis Date: Wed, 6 Jul 2022 09:45:33 -0400 Subject: [PATCH 059/155] Comment on transitive requirement of protobuf. Signed-off-by: Daniel Danis --- phenopacket-tools-builder/src/main/java/module-info.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/phenopacket-tools-builder/src/main/java/module-info.java b/phenopacket-tools-builder/src/main/java/module-info.java index aeda4c19..a23bf84f 100644 --- a/phenopacket-tools-builder/src/main/java/module-info.java +++ b/phenopacket-tools-builder/src/main/java/module-info.java @@ -1,6 +1,7 @@ module org.phenopackets.phenopackettools.builder { requires transitive org.phenopackets.schema; - requires transitive com.google.protobuf; // TODO - investigate + // Required due to `TimestampBuilder`. + requires transitive com.google.protobuf; exports org.phenopackets.phenopackettools.builder; exports org.phenopackets.phenopackettools.builder.builders; From 67ac3bb3398e4906daba5a3dbe72f16cba57cac1 Mon Sep 17 00:00:00 2001 From: Daniel Danis Date: Wed, 6 Jul 2022 10:16:06 -0400 Subject: [PATCH 060/155] Change version to `0.2.0-SNAPSHOT`, centralize dependency versions in the `dependencyManagement` section, use dependencies without known security vulnerabilities. Signed-off-by: Daniel Danis --- phenopacket-tools-builder/pom.xml | 2 +- phenopacket-tools-cli/pom.xml | 3 +- phenopacket-tools-converter/pom.xml | 2 +- phenopacket-tools-validator-core/pom.xml | 2 +- .../pom.xml | 3 +- pom.xml | 46 +++++++++++++------ 6 files changed, 38 insertions(+), 20 deletions(-) diff --git a/phenopacket-tools-builder/pom.xml b/phenopacket-tools-builder/pom.xml index 2fda2d89..2725f71d 100644 --- a/phenopacket-tools-builder/pom.xml +++ b/phenopacket-tools-builder/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenopackettools phenopacket-tools - 1.0.0 + 0.2.0-SNAPSHOT phenopacket-tools-builder diff --git a/phenopacket-tools-cli/pom.xml b/phenopacket-tools-cli/pom.xml index 83c6f6d9..bbc46f7a 100644 --- a/phenopacket-tools-cli/pom.xml +++ b/phenopacket-tools-cli/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenopackettools phenopacket-tools - 1.0.0 + 0.2.0-SNAPSHOT phenopacket-tools-cli @@ -34,7 +34,6 @@ info.picocli picocli - 4.6.3 ch.qos.logback diff --git a/phenopacket-tools-converter/pom.xml b/phenopacket-tools-converter/pom.xml index be927d85..0374ab8f 100644 --- a/phenopacket-tools-converter/pom.xml +++ b/phenopacket-tools-converter/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenopackettools phenopacket-tools - 1.0.0 + 0.2.0-SNAPSHOT phenopacket-tools-converter diff --git a/phenopacket-tools-validator-core/pom.xml b/phenopacket-tools-validator-core/pom.xml index 77457cb5..130aab52 100644 --- a/phenopacket-tools-validator-core/pom.xml +++ b/phenopacket-tools-validator-core/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenopackettools phenopacket-tools - 1.0.0 + 0.2.0-SNAPSHOT phenopacket-tools-validator-core diff --git a/phenopacket-tools-validator-jsonschema/pom.xml b/phenopacket-tools-validator-jsonschema/pom.xml index 9c40e153..f5bcbcad 100644 --- a/phenopacket-tools-validator-jsonschema/pom.xml +++ b/phenopacket-tools-validator-jsonschema/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenopackettools phenopacket-tools - 1.0.0 + 0.2.0-SNAPSHOT phenopacket-tools-validator-jsonschema @@ -25,7 +25,6 @@ com.networknt json-schema-validator - 1.0.42 diff --git a/pom.xml b/pom.xml index fd9cdb6e..c51a44a8 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.phenopackets.phenopackettools phenopacket-tools - 1.0.0 + 0.2.0-SNAPSHOT pom @@ -71,8 +71,9 @@ UTF-8 11 - 3.14.0 + 3.21.1 2.0.2 + 2.13.3 5.7.1 @@ -119,12 +120,36 @@ com.google.protobuf protobuf-java-util ${protobuf.version} - - - com.google.guava - guava - - + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + com.fasterxml.jackson.core + jackson-core + ${jackson.version} + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson.version} + + + com.google.guava + guava + 31.1-android + + + com.google.errorprone + error_prone_annotations + 2.11.0 + + + com.networknt + json-schema-validator + 1.0.42 @@ -151,10 +176,5 @@ hamcrest-core test - - org.slf4j - slf4j-simple - test - \ No newline at end of file From 7e0bab05d5dd4937271ab9826dc3c438dfa497ce Mon Sep 17 00:00:00 2001 From: Daniel Danis Date: Wed, 6 Jul 2022 10:20:17 -0400 Subject: [PATCH 061/155] Run CI tests on windows, macOS, and ubuntu. Signed-off-by: Daniel Danis --- .github/workflows/main.yaml | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index d371424b..e8404e0f 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -1,10 +1,22 @@ name: Java CI -on: [push] +on: + push: + branches: [ main, develop ] + pull_request: + branches: [ main, develop ] jobs: build: - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} + env: + JDK_VERSION: ${{ matrix.jdk }} + + strategy: + fail-fast: false + matrix: + os: [ windows-latest, macOS-latest, ubuntu-latest ] + jdk: [ 11 ] steps: - uses: actions/checkout@v2 From 68481c3646703930f0c0e99458b800710b3355e8 Mon Sep 17 00:00:00 2001 From: Daniel Danis Date: Wed, 6 Jul 2022 10:22:46 -0400 Subject: [PATCH 062/155] Add release and CI badges into the README.md. Signed-off-by: Daniel Danis --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 23bb96fe..5a81b0d7 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ # phenopacket-tools +[![GitHub release](https://img.shields.io/github/release/phenopackets/phenopacket-tools.svg)](https://github.com/phenopackets/phenopacket-tools/releases) +[![Java CI](https://github.com/phenopackets/phenopacket-tools/workflows/Java%20CI/badge.svg)](https://github.com/phenopackets/phenopacket-tools/actions/workflows/main.yml) + Multimodule Java library/app that contains a "streamlined builder" module, a v1 to v2 converter app, a validator API and a JSON validator. From 3db2f530e4072e26f1df7f65a3420a20248fe118 Mon Sep 17 00:00:00 2001 From: Daniel Danis Date: Wed, 6 Jul 2022 10:24:58 -0400 Subject: [PATCH 063/155] Revert `0.2.0-SNAPSHOT`, we may need to go with `1.0.1-SNAPSHOT`. Signed-off-by: Daniel Danis --- phenopacket-tools-builder/pom.xml | 2 +- phenopacket-tools-cli/pom.xml | 2 +- phenopacket-tools-converter/pom.xml | 2 +- phenopacket-tools-validator-core/pom.xml | 2 +- phenopacket-tools-validator-jsonschema/pom.xml | 2 +- pom.xml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/phenopacket-tools-builder/pom.xml b/phenopacket-tools-builder/pom.xml index 2725f71d..191e0a05 100644 --- a/phenopacket-tools-builder/pom.xml +++ b/phenopacket-tools-builder/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenopackettools phenopacket-tools - 0.2.0-SNAPSHOT + 1.0.1-SNAPSHOT phenopacket-tools-builder diff --git a/phenopacket-tools-cli/pom.xml b/phenopacket-tools-cli/pom.xml index bbc46f7a..a1b32491 100644 --- a/phenopacket-tools-cli/pom.xml +++ b/phenopacket-tools-cli/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenopackettools phenopacket-tools - 0.2.0-SNAPSHOT + 1.0.1-SNAPSHOT phenopacket-tools-cli diff --git a/phenopacket-tools-converter/pom.xml b/phenopacket-tools-converter/pom.xml index 0374ab8f..7d8ed829 100644 --- a/phenopacket-tools-converter/pom.xml +++ b/phenopacket-tools-converter/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenopackettools phenopacket-tools - 0.2.0-SNAPSHOT + 1.0.1-SNAPSHOT phenopacket-tools-converter diff --git a/phenopacket-tools-validator-core/pom.xml b/phenopacket-tools-validator-core/pom.xml index 130aab52..534acce4 100644 --- a/phenopacket-tools-validator-core/pom.xml +++ b/phenopacket-tools-validator-core/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenopackettools phenopacket-tools - 0.2.0-SNAPSHOT + 1.0.1-SNAPSHOT phenopacket-tools-validator-core diff --git a/phenopacket-tools-validator-jsonschema/pom.xml b/phenopacket-tools-validator-jsonschema/pom.xml index f5bcbcad..3871ed36 100644 --- a/phenopacket-tools-validator-jsonschema/pom.xml +++ b/phenopacket-tools-validator-jsonschema/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenopackettools phenopacket-tools - 0.2.0-SNAPSHOT + 1.0.1-SNAPSHOT phenopacket-tools-validator-jsonschema diff --git a/pom.xml b/pom.xml index c51a44a8..3426de86 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.phenopackets.phenopackettools phenopacket-tools - 0.2.0-SNAPSHOT + 1.0.1-SNAPSHOT pom From e586c384d6531aede5d057c5b4c4f20a2bf314c5 Mon Sep 17 00:00:00 2001 From: Daniel Danis Date: Wed, 6 Jul 2022 13:19:15 -0400 Subject: [PATCH 064/155] Add Maven wrapper. Signed-off-by: Daniel Danis --- .gitignore | 3 +- .mvn/wrapper/maven-wrapper.jar | Bin 0 -> 47610 bytes .mvn/wrapper/maven-wrapper.properties | 20 +++ README.md | 5 +- mvnw | 225 ++++++++++++++++++++++++++ mvnw.cmd | 143 ++++++++++++++++ 6 files changed, 392 insertions(+), 4 deletions(-) create mode 100644 .mvn/wrapper/maven-wrapper.jar create mode 100644 .mvn/wrapper/maven-wrapper.properties create mode 100755 mvnw create mode 100644 mvnw.cmd diff --git a/.gitignore b/.gitignore index da85ee72..0eb7ff1e 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ # Package Files # *.jar +!maven-wrapper.jar *.war *.nar *.ear @@ -40,8 +41,6 @@ release.properties dependency-reduced-pom.xml buildNumber.properties .mvn/timing.properties -# https://github.com/takari/maven-wrapper#usage-without-binary-jar -.mvn/wrapper/maven-wrapper.jar # CMake cmake-build-*/ diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..9cc84ea9b4d95453115d0c26488d6a78694e0bc6 GIT binary patch literal 47610 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 literal 0 HcmV?d00001 diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 00000000..39e8694b --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,20 @@ +# +# The Exomiser - A tool to annotate and prioritize genomic variants +# +# Copyright (c) 2016-2018 Queen Mary University of London. +# Copyright (c) 2012-2016 Charit� Universit�tsmedizin Berlin and Genome Research Ltd. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip \ No newline at end of file diff --git a/README.md b/README.md index 5a81b0d7..34e37c64 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,9 @@ Multimodule Java library/app that contains a "streamlined builder" module, a v1 The cli application works in a standard UNIX-like manner. ```shell -mvn package -alias pfx-tools='java -jar phenopacket-tools/phenopacket-tools-cli/target/phenopacket-tools-cli-1.0.0.jar' +cd phenopacket-tools +./mvnw package +alias pfx-tools='java -jar $(pwd)/phenopacket-tools-cli/target/phenopacket-tools-cli-*.jar' ``` ### Example Phenopackets diff --git a/mvnw b/mvnw new file mode 100755 index 00000000..5bf251c0 --- /dev/null +++ b/mvnw @@ -0,0 +1,225 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# 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 +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven2 Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# 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 +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# 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" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + 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 + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# 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"` +fi + +# For Migwn, 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)`" + # TODO classpath? +fi + +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 +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 + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +echo $MAVEN_PROJECTBASEDIR +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 + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 00000000..019bd74d --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,143 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@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 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 +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@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 key stroke 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 ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM enable echoing my 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 + +%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% From 8794cac73c27d005fb7b4ed801d3c24d018bb6c1 Mon Sep 17 00:00:00 2001 From: Daniel Danis Date: Wed, 6 Jul 2022 14:56:43 -0400 Subject: [PATCH 065/155] Update Maven wrapper properties. Signed-off-by: Daniel Danis --- .mvn/wrapper/maven-wrapper.properties | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 39e8694b..0061e751 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1,20 +1 @@ -# -# The Exomiser - A tool to annotate and prioritize genomic variants -# -# Copyright (c) 2016-2018 Queen Mary University of London. -# Copyright (c) 2012-2016 Charit� Universit�tsmedizin Berlin and Genome Research Ltd. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip \ No newline at end of file From 3cf32bae8dbb5f3b3db3ba0c5e3a707b953ac862 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Thu, 7 Jul 2022 09:34:42 -0400 Subject: [PATCH 066/155] adding back measurement --- phenopacket-tools-builder/pom.xml | 2 +- phenopacket-tools-cli/pom.xml | 2 +- phenopacket-tools-converter/pom.xml | 2 +- phenopacket-tools-validator-core/pom.xml | 2 +- phenopacket-tools-validator-jsonschema/pom.xml | 2 +- pom.xml | 18 +++++++++++++++++- 6 files changed, 22 insertions(+), 6 deletions(-) diff --git a/phenopacket-tools-builder/pom.xml b/phenopacket-tools-builder/pom.xml index 191e0a05..dea2c0ca 100644 --- a/phenopacket-tools-builder/pom.xml +++ b/phenopacket-tools-builder/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenopackettools phenopacket-tools - 1.0.1-SNAPSHOT + 0.4.0-SNAPSHOT phenopacket-tools-builder diff --git a/phenopacket-tools-cli/pom.xml b/phenopacket-tools-cli/pom.xml index a1b32491..751228a1 100644 --- a/phenopacket-tools-cli/pom.xml +++ b/phenopacket-tools-cli/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenopackettools phenopacket-tools - 1.0.1-SNAPSHOT + 0.4.0-SNAPSHOT phenopacket-tools-cli diff --git a/phenopacket-tools-converter/pom.xml b/phenopacket-tools-converter/pom.xml index 7d8ed829..5a63ff28 100644 --- a/phenopacket-tools-converter/pom.xml +++ b/phenopacket-tools-converter/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenopackettools phenopacket-tools - 1.0.1-SNAPSHOT + 0.4.0-SNAPSHOT phenopacket-tools-converter diff --git a/phenopacket-tools-validator-core/pom.xml b/phenopacket-tools-validator-core/pom.xml index 534acce4..a39d4ff1 100644 --- a/phenopacket-tools-validator-core/pom.xml +++ b/phenopacket-tools-validator-core/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenopackettools phenopacket-tools - 1.0.1-SNAPSHOT + 0.4.0-SNAPSHOT phenopacket-tools-validator-core diff --git a/phenopacket-tools-validator-jsonschema/pom.xml b/phenopacket-tools-validator-jsonschema/pom.xml index 3871ed36..3b459aef 100644 --- a/phenopacket-tools-validator-jsonschema/pom.xml +++ b/phenopacket-tools-validator-jsonschema/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenopackettools phenopacket-tools - 1.0.1-SNAPSHOT + 0.4.0-SNAPSHOT phenopacket-tools-validator-jsonschema diff --git a/pom.xml b/pom.xml index 3426de86..d08cc92e 100644 --- a/pom.xml +++ b/pom.xml @@ -6,10 +6,14 @@ org.phenopackets.phenopackettools phenopacket-tools - 1.0.1-SNAPSHOT + 0.4.0-SNAPSHOT pom + + 3.6.0 + + phenopacket-tools-builder phenopacket-tools-validator-core @@ -25,6 +29,8 @@ + + The 3-Clause BSD License @@ -101,6 +107,16 @@ + + + org.codehaus.mojo + versions-maven-plugin + 2.7 + + false + + + From 0a8136f0be26fed516982d2bfecc5ce11611c59f Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Thu, 7 Jul 2022 12:23:09 -0400 Subject: [PATCH 067/155] prototyped refactor --- .../command/ValidateCommand.java | 4 +- ...rvicofacialActinomycosisOfTheMandible.java | 92 +++++++++---------- ...ngSyndromeWithMultifocalOsteonecrosis.java | 86 ++++++++--------- .../PneumothoraxSecondaryToCOVID.java | 76 +++++++-------- ...SevereStatinInducedAutoimmuneMyopathy.java | 31 ++++--- phenopacket-tools-validator-core/pom.xml | 16 ++++ .../src/main/java/module-info.java | 4 + .../core/DefaultValidationRunner.java | 30 ++++++ .../{ErrorType.java => ErrorTypeOLD.java} | 6 +- .../core/JsonPhenopacketValidator.java | 11 +++ .../validator/core/OntologyError.java | 12 +++ .../core/PhenopacketMessageValidator.java | 21 +++++ .../core/PhenopacketValidatorFactory.java | 5 +- ...ator.java => PhenopacketValidatorOld.java} | 2 +- ...onAspect.java => ValidationAspectOLD.java} | 2 +- .../validator/core/ValidationErrorLevel.java | 5 + .../validator/core/ValidationErrorType.java | 8 ++ .../validator/core/ValidationItem.java | 2 +- .../core/ValidationWorkflowRunner.java | 26 ++++++ .../validator/core/ValidatorRunner.java | 64 +++++++++++-- .../validator/core/ValidatorRunnerTest.java | 16 ++++ .../ClasspathJsonSchemaValidatorFactory.java | 4 +- .../jsonschema/JsonSchemaValidator.java | 6 +- .../jsonschema/JsonValidationError.java | 8 +- .../JsonSchemaDiseaseValidatorTest.java | 10 +- .../jsonschema/JsonSchemaValidatorTest.java | 22 ++--- pom.xml | 2 +- 27 files changed, 385 insertions(+), 186 deletions(-) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/examples/CervicofacialActinomycosisOfTheMandible.java (55%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/examples/CushingSyndromeWithMultifocalOsteonecrosis.java (55%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/examples/PneumothoraxSecondaryToCOVID.java (79%) rename {phenotools-cli/src/main/java/org/phenopackets/phenotools => phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools}/examples/SevereStatinInducedAutoimmuneMyopathy.java (85%) create mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidationRunner.java rename phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/{ErrorType.java => ErrorTypeOLD.java} (91%) create mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/JsonPhenopacketValidator.java create mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/OntologyError.java create mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketMessageValidator.java rename phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/{PhenopacketValidator.java => PhenopacketValidatorOld.java} (96%) rename phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/{ValidationAspect.java => ValidationAspectOLD.java} (92%) create mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationErrorLevel.java create mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationErrorType.java create mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationWorkflowRunner.java create mode 100644 phenopacket-tools-validator-core/src/test/java/org/phenopackets/phenopackettools/validator/core/ValidatorRunnerTest.java diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ValidateCommand.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ValidateCommand.java index e82cd644..ff692212 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ValidateCommand.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ValidateCommand.java @@ -38,11 +38,11 @@ public Integer call() { } PhenopacketValidatorFactory phenopacketValidatorFactory = ClasspathJsonSchemaValidatorFactory.defaultValidators(); - ValidatorRunner validatorRunner = new ValidatorRunner(phenopacketValidatorFactory); + ValidatorRunner validatorRunner = new ValidatorRunner(List.of(), List.of()); for (Path phenopacket : phenopackets) { try (InputStream in = Files.newInputStream(phenopacket)) { - List validationItems = validatorRunner.validate(in, validationTypes); + List validationItems = validatorRunner.validate(in, List.of()); Path fileName = phenopacket.getFileName(); if (validationItems.isEmpty()) { System.out.printf("%s - OK%n", fileName); diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/CervicofacialActinomycosisOfTheMandible.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/CervicofacialActinomycosisOfTheMandible.java similarity index 55% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/CervicofacialActinomycosisOfTheMandible.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/CervicofacialActinomycosisOfTheMandible.java index 503f4e30..3fa04ad5 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/CervicofacialActinomycosisOfTheMandible.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/CervicofacialActinomycosisOfTheMandible.java @@ -1,7 +1,7 @@ -package org.phenopackets.phenotools.examples; +package org.phenopackets.phenopackettools.examples; -import org.phenopackets.phenotools.builder.PhenopacketBuilder; -import org.phenopackets.phenotools.builder.builders.*; +import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; +import org.phenopackets.phenopackettools.builder.builders.*; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.Individual; import org.phenopackets.schema.v2.core.Interpretation; @@ -10,7 +10,7 @@ import java.util.List; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; public class CervicofacialActinomycosisOfTheMandible { @@ -18,45 +18,45 @@ public class CervicofacialActinomycosisOfTheMandible { private static final String PHENOPACKET_ID = "arbitrary.id"; private static final String INDIVIDUAL = "individual A"; - private final Phenopacket phenopacket; +// private final Phenopacket phenopacket; public CervicofacialActinomycosisOfTheMandible() { - var externalRef = ExternalReferenceBuilder.builder() - .id("DOI:10.1136/bcr-2019-233681") - .builder("PMID:32467116") - .description("Cervicofacial actinomycosis of the mandible in a paediatric patient") - .build(); - - //TODO: Fix ontology versions - var metadata = MetaDataBuilder.builder("2022-04-21T10:35:00Z", "anonymous biocurator") - .resource(Resources.ncitVersion("21.05d")) - .resource(Resources.hpoVersion("2021-08-02")) - .resource(Resources.efoVersion("3.34.0")) - .resource(Resources.uberonVersion("2021-07-27")) - .resource(Resources.ncbiTaxonVersion("2021-06-10")) - .externalReference(externalRef) - .build(); - - Individual proband = IndividualBuilder.builder(INDIVIDUAL). - ageAtLastEncounter("P10Y"). - female(). - build(); - - phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metadata) - .individual(proband) - .addAllPhenotypicFeatures(getMedicalHistory()) - .addAllPhenotypicFeatures(getLast8Monthsistory()) - .addMedicalAction(neckCT()) - .addMedicalAction(mri()) - .addPhenotypicFeature(examination()) - .addInterpretation(interpretation()) - .addMedicalAction(biopsy()) - .addMedicalAction(frozenSection()) - .addMedicalAction(tissueCultures()) - .addMedicalAction(anaerobicCultures()) - .addMedicalAction(treatment()) - .build(); +// var externalRef = ExternalReferenceBuilder.builder() +// .id("DOI:10.1136/bcr-2019-233681") +// .builder("PMID:32467116") +// .description("Cervicofacial actinomycosis of the mandible in a paediatric patient") +// .build(); +// +// //TODO: Fix ontology versions +// var metadata = MetaDataBuilder.builder("2022-04-21T10:35:00Z", "anonymous biocurator") +// .resource(Resources.ncitVersion("21.05d")) +// .resource(Resources.hpoVersion("2021-08-02")) +// .resource(Resources.efoVersion("3.34.0")) +// .resource(Resources.uberonVersion("2021-07-27")) +// .resource(Resources.ncbiTaxonVersion("2021-06-10")) +// .externalReference(externalRef) +// .build(); +// +// Individual proband = IndividualBuilder.builder(INDIVIDUAL). +// ageAtLastEncounter("P10Y"). +// female(). +// build(); +// +// phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metadata) +// .individual(proband) +// .addAllPhenotypicFeatures(getMedicalHistory()) +// .addAllPhenotypicFeatures(getLast8Monthsistory()) +// .addMedicalAction(neckCT()) +// .addMedicalAction(mri()) +// .addPhenotypicFeature(examination()) +// .addInterpretation(interpretation()) +// .addMedicalAction(biopsy()) +// .addMedicalAction(frozenSection()) +// .addMedicalAction(tissueCultures()) +// .addMedicalAction(anaerobicCultures()) +// .addMedicalAction(treatment()) +// .build(); } /** @@ -161,10 +161,10 @@ private List getMedicalHistory() { /** * Diagnosis: cervicofacial actinomycosis */ - private Interpretation interpretation() { - InterpretationBuilder ibuilder = InterpretationBuilder.solved("interpretation.id"); - DiagnosisBuilder dbuilder = DiagnosisBuilder.builder(ontologyClass("???", "Cervicofacial actinomycosis")); - ibuilder.diagnosis(dbuilder.build()); - return ibuilder.build(); - } +// private Interpretation interpretation() { +// InterpretationBuilder ibuilder = InterpretationBuilder.solved("interpretation.id"); +// DiagnosisBuilder dbuilder = DiagnosisBuilder.builder(ontologyClass("???", "Cervicofacial actinomycosis")); +// ibuilder.diagnosis(dbuilder.build()); +// return ibuilder.build(); +// } } diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/CushingSyndromeWithMultifocalOsteonecrosis.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/CushingSyndromeWithMultifocalOsteonecrosis.java similarity index 55% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/CushingSyndromeWithMultifocalOsteonecrosis.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/CushingSyndromeWithMultifocalOsteonecrosis.java index f70ed7dc..801711ef 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/CushingSyndromeWithMultifocalOsteonecrosis.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/CushingSyndromeWithMultifocalOsteonecrosis.java @@ -1,13 +1,13 @@ -package org.phenopackets.phenotools.examples; +package org.phenopackets.phenopackettools.examples; -import org.phenopackets.phenotools.builder.PhenopacketBuilder; -import org.phenopackets.phenotools.builder.builders.*; +import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; +import org.phenopackets.phenopackettools.builder.builders.*; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; import java.util.List; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; public class CushingSyndromeWithMultifocalOsteonecrosis { @@ -15,41 +15,41 @@ public class CushingSyndromeWithMultifocalOsteonecrosis { private static final String PHENOPACKET_ID = "arbitrary.id"; private static final String INDIVIDUAL = "individual A"; - private final Phenopacket phenopacket; + // private final Phenopacket phenopacket; public CushingSyndromeWithMultifocalOsteonecrosis() { - var externalRef = ExternalReferenceBuilder.builder() - .id("DOI:10.1136/bcr-2019-233712") - .builder("PMID:32467117") - .description("Iatrogenic Cushing syndrome and multifocal osteonecrosis caused by the interaction between inhaled fluticasone and ritonavir") - .build(); - - //TODO: Fix ontology versions - var metadata = MetaDataBuilder.builder("2022-04-21T10:35:00Z", "anonymous biocurator") - .resource(Resources.ncitVersion("21.05d")) - .resource(Resources.hpoVersion("2021-08-02")) - .resource(Resources.efoVersion("3.34.0")) - .resource(Resources.uberonVersion("2021-07-27")) - .resource(Resources.ncbiTaxonVersion("2021-06-10")) - .externalReference(externalRef) - .build(); - - Individual proband = IndividualBuilder.builder(INDIVIDUAL). - ageAtLastEncounter("P40Y"). - male(). - build(); - - phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metadata) - .individual(proband) - .addAllPhenotypicFeatures(getMedicalHistory()) - .addAllPhenotypicFeatures(getMedicalBackground()) - .addMedicalAction(existingTreatment()) - .addAllPhenotypicFeatures(getSymptomsOnPresentation()) - .addAllMeasurements(getMeasurementsOnPresentation()) - .addInterpretation(interpretation()) - .addMedicalAction(treatment()) - .build(); +// var externalRef = ExternalReferenceBuilder.builder() +// .id("DOI:10.1136/bcr-2019-233712") +// .builder("PMID:32467117") +// .description("Iatrogenic Cushing syndrome and multifocal osteonecrosis caused by the interaction between inhaled fluticasone and ritonavir") +// .build(); +// +// //TODO: Fix ontology versions +// var metadata = MetaDataBuilder.builder("2022-04-21T10:35:00Z", "anonymous biocurator") +// .resource(Resources.ncitVersion("21.05d")) +// .resource(Resources.hpoVersion("2021-08-02")) +// .resource(Resources.efoVersion("3.34.0")) +// .resource(Resources.uberonVersion("2021-07-27")) +// .resource(Resources.ncbiTaxonVersion("2021-06-10")) +// .externalReference(externalRef) +// .build(); +// +// Individual proband = IndividualBuilder.builder(INDIVIDUAL). +// ageAtLastEncounter("P40Y"). +// male(). +// build(); +// +// phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metadata) +// .individual(proband) +// .addAllPhenotypicFeatures(getMedicalHistory()) +// .addAllPhenotypicFeatures(getMedicalBackground()) +// .addMedicalAction(existingTreatment()) +// .addAllPhenotypicFeatures(getSymptomsOnPresentation()) +// .addAllMeasurements(getMeasurementsOnPresentation()) +// .addInterpretation(interpretation()) +// .addMedicalAction(treatment()) +// .build(); } /** @@ -155,11 +155,11 @@ private List getSymptomsOnPresentation() { /** * Diagnosis: exogenous/iatrogenic Cushing syndrome secondary to inhaled fluticasone - */ - private Interpretation interpretation() { - InterpretationBuilder ibuilder = InterpretationBuilder.solved("interpretation.id"); - DiagnosisBuilder dbuilder = DiagnosisBuilder.builder(ontologyClass("???", "Exogenous/iatrogenic Cushing syndrome")); - ibuilder.diagnosis(dbuilder.build()); - return ibuilder.build(); - } +// */ +// private Interpretation interpretation() { +// InterpretationBuilder ibuilder = InterpretationBuilder.solved("interpretation.id"); +// DiagnosisBuilder dbuilder = DiagnosisBuilder.builder(ontologyClass("???", "Exogenous/iatrogenic Cushing syndrome")); +// ibuilder.diagnosis(dbuilder.build()); +// return ibuilder.build(); +// } } diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/PneumothoraxSecondaryToCOVID.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/PneumothoraxSecondaryToCOVID.java similarity index 79% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/PneumothoraxSecondaryToCOVID.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/PneumothoraxSecondaryToCOVID.java index 2dc58e14..21e99f28 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/PneumothoraxSecondaryToCOVID.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/PneumothoraxSecondaryToCOVID.java @@ -1,13 +1,16 @@ -package org.phenopackets.phenotools.examples; +package org.phenopackets.phenopackettools.examples; -import org.phenopackets.phenotools.builder.PhenopacketBuilder; -import org.phenopackets.phenotools.builder.builders.*; + +import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; +import org.phenopackets.phenopackettools.builder.builders.*; +import org.phenopackets.phenopackettools.builder.constants.Laterality; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; import java.util.List; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; + public class PneumothoraxSecondaryToCOVID { @@ -18,20 +21,20 @@ public class PneumothoraxSecondaryToCOVID { public PneumothoraxSecondaryToCOVID() { - var externalRef = ExternalReferenceBuilder.builder() + var externalRef = ExternalReferenceBuilder.reference() .id("DOI:10.1136/bcr-2020-235861") - .builder("PMID:32423911") + // .builder("PMID:32423911") .description("Tension pneumothorax in a patient with COVID-19") .build(); //TODO: Fix ontology versions var metadata = MetaDataBuilder.builder("2022-04-21T10:35:00Z", "anonymous biocurator") - .resource(Resources.ncitVersion("21.05d")) - .resource(Resources.hpoVersion("2021-08-02")) - .resource(Resources.efoVersion("3.34.0")) - .resource(Resources.uberonVersion("2021-07-27")) - .resource(Resources.ncbiTaxonVersion("2021-06-10")) - .externalReference(externalRef) + .addResource(Resources.ncitVersion("21.05d")) + .addResource(Resources.hpoVersion("2021-08-02")) + .addResource(Resources.efoVersion("3.34.0")) + .addResource(Resources.uberonVersion("2021-07-27")) + .addResource(Resources.ncbiTaxonVersion("2021-06-10")) + .addExternalReference(externalRef) .build(); Individual proband = IndividualBuilder.builder(INDIVIDUAL). @@ -92,10 +95,10 @@ private MedicalAction chestDrain() { * Diagnosis: tension pneumothorax, secondary to underlying COVID-19 */ private Interpretation interpretation() { - InterpretationBuilder ibuilder = InterpretationBuilder.solved("interpretation.id"); + // InterpretationBuilder ibuilder = InterpretationBuilder.solved("interpretation.id"); DiagnosisBuilder dbuilder = DiagnosisBuilder.builder(ontologyClass("SCTID:233645004", "Tension pneumothorax (disorder)")); - ibuilder.diagnosis(dbuilder.build()); - return ibuilder.build(); + //ibuilder.diagnosis(dbuilder.build()); + return null;//ibuilder.build(); } /** @@ -111,21 +114,21 @@ private Interpretation interpretation() { private List getChestRadiograph() { PhenotypicFeature pneumothorax = PhenotypicFeatureBuilder .builder("HP:0002107", "Pneumothorax") - .modifier(OntologyClassBuilder.ontologyClass("PATO:0000600", "increased width")) - .modifier(Laterality.left()) + .addModifier(ontologyClass("PATO:0000600", "increased width")) + .addModifier(Laterality.left()) .build(); PhenotypicFeature rightLungNormal = PhenotypicFeatureBuilder .builder("HP:0031983", "Abnormal pulmonary thoracic imaging finding") - .modifier(Laterality.right()) + .addModifier(Laterality.right()) .excluded() .build(); PhenotypicFeature rightLungConsolidated = PhenotypicFeatureBuilder .builder("SCTID:95436008", "Lung consolidation (disorder)") // Probably incorrect - .modifier(Laterality.right()) - .modifier(OntologyClassBuilder.ontologyClass("PATO:0001630", "dispersed")) - .modifier(OntologyClassBuilder.ontologyClass("PATO:0001608", "patchy")) + .addModifier(Laterality.right()) + .addModifier(ontologyClass("PATO:0001630", "dispersed")) + .addModifier(ontologyClass("PATO:0001608", "patchy")) .build(); return List.of(pneumothorax, rightLungNormal, rightLungConsolidated); @@ -142,41 +145,38 @@ private List getChestRadiograph() { * - blood pressure of 110/65 mm Hg */ private List getMeasurementsOnPresentation() { - OntologyClass respiratoryRate = OntologyClassBuilder.ontologyClass("LOINC:9279-1", "Respiratory rate"); - + OntologyClass respiratoryRate = ontologyClass("LOINC:9279-1", "Respiratory rate"); +/* // Couldn't find 'breaths per minute' as a measurement unit and UCUM has not been published. // This applies to all measurements below - Value respiratoryRateValue = ValueBuilder.value("UCUM:{breaths}/min", "Breaths/minute", 50); + Value respiratoryRateValue = ValueBuilder.of("UCUM:{breaths}/min", "Breaths/minute", 50); // Time observed: on presentation? This applies to all measurements below Measurement respiratoryRateMeasurement = MeasurementBuilder. - value(respiratoryRate, respiratoryRateValue). + of(respiratoryRate, respiratoryRateValue). build(); - OntologyClass heartRate = OntologyClassBuilder.ontologyClass("LOINC:8867-4", "Heart rate"); - Value heartRateValue = ValueBuilder.value("UCUM:{beats}/min", "Beats/minute", 150); + OntologyClass heartRate = ontologyClass("LOINC:8867-4", "Heart rate"); + Value heartRateValue = ValueBuilder.of("UCUM:{beats}/min", "Beats/minute", 150); Measurement heartRateMeasurement = MeasurementBuilder. - value(heartRate, heartRateValue). + of(heartRate, heartRateValue). build(); - OntologyClass systBloodPressure = OntologyClassBuilder.ontologyClass("LOINC:8480-6", "Systolic blood pressure"); - Value systBloodPressureValue = ValueBuilder.value("UCUM:mm[Hg]", "mm[Hg]", 110); + OntologyClass systBloodPressure = ontologyClass("LOINC:8480-6", "Systolic blood pressure"); + Value systBloodPressureValue = ValueBuilder.of("UCUM:mm[Hg]", "mm[Hg]", 110); Measurement systBloodPressureMeasurement = MeasurementBuilder. - value(systBloodPressure, systBloodPressureValue). + of(systBloodPressure, systBloodPressureValue). build(); - OntologyClass diastBloodPressure = OntologyClassBuilder.ontologyClass("LOINC:8480-6", "Systolic blood pressure"); + OntologyClass diastBloodPressure = ontologyClass("LOINC:8480-6", "Systolic blood pressure"); Value diastBloodPressureValue = ValueBuilder.value("UCUM:mm[Hg]", "mm[Hg]", 65); Measurement diastBloodPressureMeasurement = MeasurementBuilder. value(diastBloodPressure, diastBloodPressureValue). build(); - /** - * TODO: How to associate SpO2 of 88% on 15L/min oxygen with the 'intervention' 'non rebreather mask oxygen delivery'? - */ - OntologyClass spO2 = OntologyClassBuilder.ontologyClass("LOINC:20564-1", "Oxygen saturation in Blood"); + OntologyClass spO2 = ontologyClass("LOINC:20564-1", "Oxygen saturation in Blood"); Value spO2Value = ValueBuilder.value("UCUM:%", "%", 88); Measurement spO2Measurement = MeasurementBuilder. value(spO2, spO2Value). @@ -188,6 +188,8 @@ private List getMeasurementsOnPresentation() { systBloodPressureMeasurement, diastBloodPressureMeasurement, spO2Measurement); + */ + return null; } /** @@ -215,7 +217,7 @@ private List getSymptomsOnPresentation() { PhenotypicFeature chestPain = PhenotypicFeatureBuilder. builder("HP:0033771", "Pleuritic chest pain"). - modifier(Laterality.left()). + //modifier(Laterality.left()). build(); PhenotypicFeature trachea = PhenotypicFeatureBuilder. diff --git a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/SevereStatinInducedAutoimmuneMyopathy.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SevereStatinInducedAutoimmuneMyopathy.java similarity index 85% rename from phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/SevereStatinInducedAutoimmuneMyopathy.java rename to phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SevereStatinInducedAutoimmuneMyopathy.java index 1d7ddb39..55329652 100644 --- a/phenotools-cli/src/main/java/org/phenopackets/phenotools/examples/SevereStatinInducedAutoimmuneMyopathy.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SevereStatinInducedAutoimmuneMyopathy.java @@ -1,13 +1,14 @@ -package org.phenopackets.phenotools.examples; +package org.phenopackets.phenopackettools.examples; -import org.phenopackets.phenotools.builder.PhenopacketBuilder; -import org.phenopackets.phenotools.builder.builders.*; +import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; +import org.phenopackets.phenopackettools.builder.builders.*; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; import java.util.List; -import static org.phenopackets.phenotools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; + public class SevereStatinInducedAutoimmuneMyopathy { @@ -19,20 +20,20 @@ public class SevereStatinInducedAutoimmuneMyopathy { public SevereStatinInducedAutoimmuneMyopathy() { - var externalRef = ExternalReferenceBuilder.builder() + var externalRef = ExternalReferenceBuilder.reference() .id("DOI:10.1136/bcr-2020-234805") - .builder("PMID:32444443") + // .builder("PMID:32444443") .description("Severe statin-induced autoimmune myopathy successfully treated with intravenous immunoglobulin") .build(); //TODO: Fix ontology versions var metadata = MetaDataBuilder.builder("2022-04-21T10:35:00Z", "anonymous biocurator") - .resource(Resources.ncitVersion("21.05d")) - .resource(Resources.hpoVersion("2021-08-02")) - .resource(Resources.efoVersion("3.34.0")) - .resource(Resources.uberonVersion("2021-07-27")) - .resource(Resources.ncbiTaxonVersion("2021-06-10")) - .externalReference(externalRef) + .addResource(Resources.ncitVersion("21.05d")) + .addResource(Resources.hpoVersion("2021-08-02")) + .addResource(Resources.efoVersion("3.34.0")) + .addResource(Resources.uberonVersion("2021-07-27")) + .addResource(Resources.ncbiTaxonVersion("2021-06-10")) + .addExternalReference(externalRef) .build(); Individual proband = IndividualBuilder.builder(INDIVIDUAL). @@ -154,9 +155,9 @@ private MedicalAction existingTreatment() { * Diagnosis: statin-associated autoimmune myopathy */ private Interpretation interpretation() { - InterpretationBuilder ibuilder = InterpretationBuilder.solved("interpretation.id"); + InterpretationBuilder ibuilder = InterpretationBuilder.builder("interpretation.id"); DiagnosisBuilder dbuilder = DiagnosisBuilder.builder(ontologyClass("????", "Statin-associated autoimmune myopathy")); - ibuilder.diagnosis(dbuilder.build()); - return ibuilder.build(); + // ibuilder.(dbuilder.build()); + return null; //ibuilder. } } diff --git a/phenopacket-tools-validator-core/pom.xml b/phenopacket-tools-validator-core/pom.xml index a39d4ff1..a7ae9d05 100644 --- a/phenopacket-tools-validator-core/pom.xml +++ b/phenopacket-tools-validator-core/pom.xml @@ -15,4 +15,20 @@ phenopacket-tools-validator-core Validator utilities for phenopackets + + + org.phenopackets + phenopacket-schema + + + + com.google.protobuf + protobuf-java + + + com.google.protobuf + protobuf-java-util + + + \ No newline at end of file diff --git a/phenopacket-tools-validator-core/src/main/java/module-info.java b/phenopacket-tools-validator-core/src/main/java/module-info.java index d3531f92..a51e2edf 100644 --- a/phenopacket-tools-validator-core/src/main/java/module-info.java +++ b/phenopacket-tools-validator-core/src/main/java/module-info.java @@ -3,4 +3,8 @@ exports org.phenopackets.phenopackettools.validator.core; exports org.phenopackets.phenopackettools.validator.core.except; + + requires com.google.protobuf; + requires com.google.protobuf.util; + requires org.phenopackets.schema; } \ No newline at end of file diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidationRunner.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidationRunner.java new file mode 100644 index 00000000..f074e662 --- /dev/null +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidationRunner.java @@ -0,0 +1,30 @@ +package org.phenopackets.phenopackettools.validator.core; + + + +import java.util.List; + +public class DefaultValidationRunner implements ValidationWorkflowRunner { + + public DefaultValidationRunner(List sds, List v1) { + + } + + /** + * implementation: + * 1. get string as input + * 2. decide if JSON/YML/Protobuf ("sniff the input") + * 3. Parse into JSON string + * 4. Fail if the JSON is not Phenopacket (e.g., fail for Family or Cohort) (one interface, three impl) + * 5. Pass to list of JSON Schema Validators + * 6. Convert JSON to Phenopacket, Cohort, or Family + * 7. Run all PhenopacketMessageValidators + * 8. Return List + * @return + */ + @Override + public List run(String input) { + // + return null; + } +} diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ErrorType.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ErrorTypeOLD.java similarity index 91% rename from phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ErrorType.java rename to phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ErrorTypeOLD.java index bf87300c..2ba8b9ff 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ErrorType.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ErrorTypeOLD.java @@ -2,7 +2,7 @@ import org.phenopackets.phenopackettools.validator.core.except.PhenopacketValidatorRuntimeException; -public enum ErrorType { +public enum ErrorTypeOLD { /** JSON schema error meaning that the JSON code contained a property not present in the schema. */ JSON_ADDITIONAL_PROPERTIES("additionalProperties"), /** JSON schema error meaning that the JSON code failed to contain a property required by the schema. */ @@ -17,7 +17,7 @@ public enum ErrorType { private final String name; - ErrorType(String value) { + ErrorTypeOLD(String value) { this.name = value; } @@ -27,7 +27,7 @@ public String toString() { } - public static ErrorType stringToErrorType(String error) { + public static ErrorTypeOLD stringToErrorType(String error) { switch (error) { case "additionalProperties": return JSON_ADDITIONAL_PROPERTIES; case "required": return JSON_REQUIRED; diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/JsonPhenopacketValidator.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/JsonPhenopacketValidator.java new file mode 100644 index 00000000..44143ee3 --- /dev/null +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/JsonPhenopacketValidator.java @@ -0,0 +1,11 @@ +package org.phenopackets.phenopackettools.validator.core; + +import java.util.List; + +public interface JsonPhenopacketValidator { + + ValidatorInfo info(); + + List validate(String json); + +} diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/OntologyError.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/OntologyError.java new file mode 100644 index 00000000..3a31545a --- /dev/null +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/OntologyError.java @@ -0,0 +1,12 @@ +package org.phenopackets.phenopackettools.validator.core; + +public record OntologyError(String name, String message) implements ValidationErrorType{ + + + // + + public static OntologyError invalidOntology(String message) { + return new OntologyError("invalid ontology", message); + } + +} diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketMessageValidator.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketMessageValidator.java new file mode 100644 index 00000000..7ca99b40 --- /dev/null +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketMessageValidator.java @@ -0,0 +1,21 @@ +package org.phenopackets.phenopackettools.validator.core; + +import com.google.protobuf.Message; + + + +import java.util.List; + +public interface PhenopacketMessageValidator { + + + ValidatorInfo info(); + + List validate(T ga4ghPhenopacketMessage); + + + + +} + + diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidatorFactory.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidatorFactory.java index 1eb427e7..0ef71429 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidatorFactory.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidatorFactory.java @@ -9,7 +9,8 @@ * @author Peter N Robinson */ public interface PhenopacketValidatorFactory { - - Optional getValidatorForType(ValidatorInfo type); + // TODO probably simplify/delete + Optional getValidatorForType(ValidatorInfo type); + // ? List getValidators(); } diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidator.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidatorOld.java similarity index 96% rename from phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidator.java rename to phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidatorOld.java index 1b6fe42a..e619a82e 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidator.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidatorOld.java @@ -14,7 +14,7 @@ * @author Daniel Danis * @author Peter N Robinson */ -public interface PhenopacketValidator { +public interface PhenopacketValidatorOld { ValidatorInfo info(); diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationAspect.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationAspectOLD.java similarity index 92% rename from phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationAspect.java rename to phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationAspectOLD.java index 122594f7..c0f20a3b 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationAspect.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationAspectOLD.java @@ -1,7 +1,7 @@ package org.phenopackets.phenopackettools.validator.core; -public enum ValidationAspect { +public enum ValidationAspectOLD { // This enum is supposed to be used instead of the ErrorType // TODO - elaborate the categories diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationErrorLevel.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationErrorLevel.java new file mode 100644 index 00000000..165a2cae --- /dev/null +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationErrorLevel.java @@ -0,0 +1,5 @@ +package org.phenopackets.phenopackettools.validator.core; + +public enum ValidationErrorLevel { + ERROR, WARNING +} diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationErrorType.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationErrorType.java new file mode 100644 index 00000000..063af13b --- /dev/null +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationErrorType.java @@ -0,0 +1,8 @@ +package org.phenopackets.phenopackettools.validator.core; + +public interface ValidationErrorType { + + String name(); + String message(); + +} diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationItem.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationItem.java index b076eb8f..fb9caed1 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationItem.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationItem.java @@ -14,7 +14,7 @@ public interface ValidationItem { ValidatorInfo validatorInfo(); // TODO - decide which enum to use here - either ErrorType or ValidationAspect - ErrorType errorType(); + ErrorTypeOLD errorType(); /** * @return string with description of the issue intended for human consumption. diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationWorkflowRunner.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationWorkflowRunner.java new file mode 100644 index 00000000..b7d1916e --- /dev/null +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationWorkflowRunner.java @@ -0,0 +1,26 @@ +package org.phenopackets.phenopackettools.validator.core; + +import java.util.List; + +public interface ValidationWorkflowRunner { + + + /** + * implementation: + * 1. get string as input + * 2. decide if JSON/YML/Protobuf ("sniff the input") + * 3. Parse into JSON string + * 4. Fail if the JSON is not Phenopacket (e.g., fail for Family or Cohort) (one interface, three impl) + * 5. Pass to list of JSON Schema Validators + * 6. Convert JSON to Phenopacket, Cohort, or Family + * 7. Run all PhenopacketMessageValidators + * 8. Return List + * @return + */ + + List run(String input); + + + + +} diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorRunner.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorRunner.java index ed898d25..d23f5b5d 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorRunner.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorRunner.java @@ -1,5 +1,6 @@ package org.phenopackets.phenopackettools.validator.core; +import org.phenopackets.schema.v2.Phenopacket; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -14,21 +15,64 @@ public class ValidatorRunner { private static final Logger LOGGER = LoggerFactory.getLogger(ValidatorRunner.class); - private final PhenopacketValidatorFactory validatorFactory; + // private final PhenopacketValidatorFactory validatorFactory; + private final List messageValidators; + private final List jsonValidators; + + + // private final ValidationWorkflowRunner phenopacketValidationWorkflowRunner; + // private final ValidationWorkflowRunner cohortValidationWorkflowRunner; + // private final ValidationWorkflowRunner familyValidationWorkflowRunner; + +// private final List cohortValidators; +// +// private final List familyValidators; + + public ValidatorRunner(List validators, + List jsonPhenopacketValidators) { + this.messageValidators = validators; + this.jsonValidators = jsonPhenopacketValidators; + // cohortValidators = List.of(); - public ValidatorRunner(PhenopacketValidatorFactory validatorFactory) { - this.validatorFactory = validatorFactory; } - public List validate(InputStream inputStream, List validations) { + + + + + + public List validatePhenopacket(InputStream stream) { + // 1. Create json string + // phenopacketValidationWorkflowRunner.run() + + return List.of(); + } + + public List validateCohort(InputStream stream) { + /// 1. Create json string + // 2. cohortValidationWorkflowRunner.run() + + + return List.of(); + } + + + + public List validate(InputStream inputStream, List validations) { List items = new ArrayList<>(); + //JsonNode json = objectMapper.readTree(inputStream); + // loop 1 + //PhenopacketBuilder from google + // loop 2 try { byte[] content = inputStream.readAllBytes(); - for (ValidatorInfo validationType : validations) { - validatorFactory.getValidatorForType(validationType) - .map(validate(content)) - .ifPresent(items::addAll); - } + // items = validations.stream().flatMap(v -> v.validate(inputStream).stream()) + // .toList(); +// for (PhenopacketValidator validationType : validations) { +// // validatorFactory.getValidatorForType(validationType) +// validate(content). +// //.ifPresent(items::addAll); +// } return List.copyOf(items); } catch (IOException e) { @@ -37,7 +81,7 @@ public List validate(InputStream inputStream, List> validate(byte[] content) { + private static Function> validate(byte[] content) { return validator -> { try (InputStream is = new ByteArrayInputStream(content)) { return validator.validate(is); diff --git a/phenopacket-tools-validator-core/src/test/java/org/phenopackets/phenopackettools/validator/core/ValidatorRunnerTest.java b/phenopacket-tools-validator-core/src/test/java/org/phenopackets/phenopackettools/validator/core/ValidatorRunnerTest.java new file mode 100644 index 00000000..8ce5f68b --- /dev/null +++ b/phenopacket-tools-validator-core/src/test/java/org/phenopackets/phenopackettools/validator/core/ValidatorRunnerTest.java @@ -0,0 +1,16 @@ +package org.phenopackets.phenopackettools.validator.core; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class ValidatorRunnerTest { + + + @Test + public void testMe() { + //ValidatorRunner runner = new ValidatorRunner(); + } + + +} \ No newline at end of file diff --git a/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/ClasspathJsonSchemaValidatorFactory.java b/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/ClasspathJsonSchemaValidatorFactory.java index e9d3f21c..aca77ed7 100644 --- a/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/ClasspathJsonSchemaValidatorFactory.java +++ b/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/ClasspathJsonSchemaValidatorFactory.java @@ -1,6 +1,6 @@ package org.phenopackets.phenopackettools.validator.jsonschema; -import org.phenopackets.phenopackettools.validator.core.PhenopacketValidator; +import org.phenopackets.phenopackettools.validator.core.PhenopacketValidatorOld; import org.phenopackets.phenopackettools.validator.core.PhenopacketValidatorFactory; import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; import org.phenopackets.phenopackettools.validator.core.except.PhenopacketValidatorRuntimeException; @@ -46,7 +46,7 @@ private ClasspathJsonSchemaValidatorFactory(Map getValidatorForType(ValidatorInfo type) { + public Optional getValidatorForType(ValidatorInfo type) { return Optional.ofNullable(validatorMap.get(type)); } diff --git a/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidator.java b/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidator.java index 004e99e5..d8e46d87 100644 --- a/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidator.java +++ b/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidator.java @@ -6,7 +6,7 @@ import com.networknt.schema.JsonSchema; import com.networknt.schema.JsonSchemaFactory; import com.networknt.schema.SpecVersion; -import org.phenopackets.phenopackettools.validator.core.PhenopacketValidator; +import org.phenopackets.phenopackettools.validator.core.PhenopacketValidatorOld; import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; import org.phenopackets.phenopackettools.validator.core.except.PhenopacketValidatorRuntimeException; import org.phenopackets.phenopackettools.validator.core.ValidationItem; @@ -22,7 +22,7 @@ import java.util.stream.Collectors; -public class JsonSchemaValidator implements PhenopacketValidator { +public class JsonSchemaValidator implements PhenopacketValidatorOld { private static final Logger LOGGER = LoggerFactory.getLogger(JsonSchemaValidator.class); @@ -76,6 +76,8 @@ public ValidatorInfo info() { public List validate(InputStream inputStream) { try { JsonNode json = objectMapper.readTree(inputStream); + String s = "LL"; + // json = objectMapper.readTree(s); return jsonSchema.validate(json).stream() .map(e -> new JsonValidationError(validatorInfo, e)) .collect(Collectors.toUnmodifiableList()); diff --git a/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonValidationError.java b/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonValidationError.java index 82ad27da..745426fa 100644 --- a/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonValidationError.java +++ b/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonValidationError.java @@ -1,7 +1,7 @@ package org.phenopackets.phenopackettools.validator.jsonschema; import com.networknt.schema.ValidationMessage; -import org.phenopackets.phenopackettools.validator.core.ErrorType; +import org.phenopackets.phenopackettools.validator.core.ErrorTypeOLD; import org.phenopackets.phenopackettools.validator.core.ValidationItem; import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; @@ -15,12 +15,12 @@ public final class JsonValidationError implements ValidationItem { private final ValidatorInfo validatorInfo; - private final ErrorType errorType; + private final ErrorTypeOLD errorType; private final String message; public JsonValidationError(ValidatorInfo validatorInfo, ValidationMessage validationMessage) { this.validatorInfo = validatorInfo; - this.errorType = ErrorType.stringToErrorType(validationMessage.getType()); + this.errorType = ErrorTypeOLD.stringToErrorType(validationMessage.getType()); this.message = validationMessage.getMessage(); } @@ -30,7 +30,7 @@ public ValidatorInfo validatorInfo() { } @Override - public ErrorType errorType() { + public ErrorTypeOLD errorType() { return this.errorType; } diff --git a/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaDiseaseValidatorTest.java b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaDiseaseValidatorTest.java index 93fc037a..da204cca 100644 --- a/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaDiseaseValidatorTest.java +++ b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaDiseaseValidatorTest.java @@ -4,8 +4,8 @@ import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.util.JsonFormat; import org.junit.jupiter.api.Test; -import org.phenopackets.phenopackettools.validator.core.PhenopacketValidator; -import org.phenopackets.phenopackettools.validator.core.ErrorType; +import org.phenopackets.phenopackettools.validator.core.PhenopacketValidatorOld; +import org.phenopackets.phenopackettools.validator.core.ErrorTypeOLD; import org.phenopackets.phenopackettools.validator.core.ValidationItem; import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; import org.phenopackets.phenopackettools.validator.testdatagen.PhenopacketUtil; @@ -65,7 +65,7 @@ private static Phenopacket phenopacketWithDisease() { @Test public void testPhenopacketValidity() throws InvalidProtocolBufferException { - PhenopacketValidator validator = FACTORY.getValidatorForType(ValidatorInfo.generic()).get(); + PhenopacketValidatorOld validator = FACTORY.getValidatorForType(ValidatorInfo.generic()).get(); String json = JsonFormat.printer().print(phenopacket); List errors = validator.validate(json); assertTrue(errors.isEmpty()); @@ -73,7 +73,7 @@ public void testPhenopacketValidity() throws InvalidProtocolBufferException { @Test public void testLacksId() throws InvalidProtocolBufferException { - PhenopacketValidator validator = FACTORY.getValidatorForType(ValidatorInfo.generic()).get(); + PhenopacketValidatorOld validator = FACTORY.getValidatorForType(ValidatorInfo.generic()).get(); // the Phenopacket is not valid if we remove the id Phenopacket p1 = Phenopacket.newBuilder(phenopacket).clearId().build(); String json = JsonFormat.printer().print(p1); @@ -82,7 +82,7 @@ public void testLacksId() throws InvalidProtocolBufferException { // System.out.println(errors); assertEquals(1, errors.size()); ValidationItem error = errors.get(0); - assertEquals(ErrorType.JSON_REQUIRED, error.errorType()); + assertEquals(ErrorTypeOLD.JSON_REQUIRED, error.errorType()); assertEquals("$.id: is missing but it is required", error.message()); } diff --git a/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidatorTest.java b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidatorTest.java index 9ecbc547..9f0589a0 100644 --- a/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidatorTest.java +++ b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidatorTest.java @@ -2,8 +2,8 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import org.phenopackets.phenopackettools.validator.core.ErrorType; -import org.phenopackets.phenopackettools.validator.core.PhenopacketValidator; +import org.phenopackets.phenopackettools.validator.core.ErrorTypeOLD; +import org.phenopackets.phenopackettools.validator.core.PhenopacketValidatorOld; import org.phenopackets.phenopackettools.validator.core.ValidationItem; import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; import org.phenopackets.phenopackettools.validator.testdatagen.RareDiseasePhenopacket; @@ -29,7 +29,7 @@ public class JsonSchemaValidatorTest { @Test public void testValidationOfSimpleValidPhenopacket() throws Exception { - PhenopacketValidator validator = FACTORY.getValidatorForType(ValidatorInfo.generic()).get(); + PhenopacketValidatorOld validator = FACTORY.getValidatorForType(ValidatorInfo.generic()).get(); Phenopacket phenopacket = simplePhenopacket.getPhenopacket(); String json = JsonFormat.printer().print(phenopacket); List errors = validator.validate(json); @@ -40,7 +40,7 @@ public void testValidationOfSimpleValidPhenopacket() throws Exception { errors = validator.validate(json); assertEquals(1, errors.size()); ValidationItem error = errors.get(0); - assertEquals(ErrorType.JSON_REQUIRED, error.errorType()); + assertEquals(ErrorTypeOLD.JSON_REQUIRED, error.errorType()); assertEquals("$.id: is missing but it is required", error.message()); } @@ -50,7 +50,7 @@ public void testValidationOfSimpleValidPhenopacket() throws Exception { */ @Test public void testValidationOfSimpleInValidPhenopacket() { - PhenopacketValidator validator = FACTORY.getValidatorForType(ValidatorInfo.generic()).get(); + PhenopacketValidatorOld validator = FACTORY.getValidatorForType(ValidatorInfo.generic()).get(); String invalidPhenopacketJson = "{\"disney\" : \"donald\"}"; @@ -58,19 +58,19 @@ public void testValidationOfSimpleInValidPhenopacket() { assertEquals(3, errors.size()); ValidationItem error = errors.get(0); - assertEquals(ErrorType.JSON_REQUIRED, error.errorType()); + assertEquals(ErrorTypeOLD.JSON_REQUIRED, error.errorType()); assertEquals("$.id: is missing but it is required", error.message()); error = errors.get(1); - assertEquals(ErrorType.JSON_REQUIRED, error.errorType()); + assertEquals(ErrorTypeOLD.JSON_REQUIRED, error.errorType()); assertEquals("$.metaData: is missing but it is required", error.message()); error = errors.get(2); - assertEquals(ErrorType.JSON_ADDITIONAL_PROPERTIES, error.errorType()); + assertEquals(ErrorTypeOLD.JSON_ADDITIONAL_PROPERTIES, error.errorType()); assertEquals("$.disney: is not defined in the schema and the schema does not allow additional properties", error.message()); } @Test public void testRareDiseaseBethlemahmValidPhenopacket() throws Exception { - PhenopacketValidator validator = FACTORY.getValidatorForType(ValidatorInfo.rareDiseaseValidation()).get(); + PhenopacketValidatorOld validator = FACTORY.getValidatorForType(ValidatorInfo.rareDiseaseValidation()).get(); Phenopacket bethlehamMyopathy = rareDiseasePhenopacket.getPhenopacket(); String json = JsonFormat.printer().print(bethlehamMyopathy); @@ -82,7 +82,7 @@ public void testRareDiseaseBethlemahmValidPhenopacket() throws Exception { @Test @Disabled // TODO - we should rework the testing strategy to invalidate a valid phenopacket and check that it raises the expected error public void testRareDiseaseBethlemahmInvalidValidPhenopacket() throws IOException { - PhenopacketValidator validator = FACTORY.getValidatorForType(ValidatorInfo.rareDiseaseValidation()).get(); + PhenopacketValidatorOld validator = FACTORY.getValidatorForType(ValidatorInfo.rareDiseaseValidation()).get(); File invalidMyopathyPhenopacket = Path.of("src/test/resources/json/bethlehamMyopathyInvalidExample.json").toFile(); List validationItems = validator.validate(invalidMyopathyPhenopacket); @@ -91,7 +91,7 @@ public void testRareDiseaseBethlemahmInvalidValidPhenopacket() throws IOExceptio } assertEquals(1, validationItems.size()); ValidationItem validationItem = validationItems.get(0); - assertEquals(ErrorType.JSON_REQUIRED, validationItem.errorType()); + assertEquals(ErrorTypeOLD.JSON_REQUIRED, validationItem.errorType()); assertEquals("$.phenotypicFeatures: is missing but it is required", validationItem.message()); } diff --git a/pom.xml b/pom.xml index d08cc92e..dd5daa00 100644 --- a/pom.xml +++ b/pom.xml @@ -75,7 +75,7 @@ UTF-8 - 11 + 17 3.21.1 2.0.2 From f7306cf19204904db104cb74e158db97c06edbcd Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Thu, 7 Jul 2022 09:34:42 -0400 Subject: [PATCH 068/155] Set artifact versions to `0.4.0-SNAPSHOT`. --- phenopacket-tools-builder/pom.xml | 2 +- phenopacket-tools-cli/pom.xml | 2 +- phenopacket-tools-converter/pom.xml | 2 +- phenopacket-tools-validator-core/pom.xml | 2 +- phenopacket-tools-validator-jsonschema/pom.xml | 2 +- pom.xml | 18 +++++++++++++++++- 6 files changed, 22 insertions(+), 6 deletions(-) diff --git a/phenopacket-tools-builder/pom.xml b/phenopacket-tools-builder/pom.xml index 191e0a05..dea2c0ca 100644 --- a/phenopacket-tools-builder/pom.xml +++ b/phenopacket-tools-builder/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenopackettools phenopacket-tools - 1.0.1-SNAPSHOT + 0.4.0-SNAPSHOT phenopacket-tools-builder diff --git a/phenopacket-tools-cli/pom.xml b/phenopacket-tools-cli/pom.xml index a1b32491..751228a1 100644 --- a/phenopacket-tools-cli/pom.xml +++ b/phenopacket-tools-cli/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenopackettools phenopacket-tools - 1.0.1-SNAPSHOT + 0.4.0-SNAPSHOT phenopacket-tools-cli diff --git a/phenopacket-tools-converter/pom.xml b/phenopacket-tools-converter/pom.xml index 7d8ed829..5a63ff28 100644 --- a/phenopacket-tools-converter/pom.xml +++ b/phenopacket-tools-converter/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenopackettools phenopacket-tools - 1.0.1-SNAPSHOT + 0.4.0-SNAPSHOT phenopacket-tools-converter diff --git a/phenopacket-tools-validator-core/pom.xml b/phenopacket-tools-validator-core/pom.xml index 534acce4..a39d4ff1 100644 --- a/phenopacket-tools-validator-core/pom.xml +++ b/phenopacket-tools-validator-core/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenopackettools phenopacket-tools - 1.0.1-SNAPSHOT + 0.4.0-SNAPSHOT phenopacket-tools-validator-core diff --git a/phenopacket-tools-validator-jsonschema/pom.xml b/phenopacket-tools-validator-jsonschema/pom.xml index 3871ed36..3b459aef 100644 --- a/phenopacket-tools-validator-jsonschema/pom.xml +++ b/phenopacket-tools-validator-jsonschema/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenopackettools phenopacket-tools - 1.0.1-SNAPSHOT + 0.4.0-SNAPSHOT phenopacket-tools-validator-jsonschema diff --git a/pom.xml b/pom.xml index 3426de86..d08cc92e 100644 --- a/pom.xml +++ b/pom.xml @@ -6,10 +6,14 @@ org.phenopackets.phenopackettools phenopacket-tools - 1.0.1-SNAPSHOT + 0.4.0-SNAPSHOT pom + + 3.6.0 + + phenopacket-tools-builder phenopacket-tools-validator-core @@ -25,6 +29,8 @@ + + The 3-Clause BSD License @@ -101,6 +107,16 @@ + + + org.codehaus.mojo + versions-maven-plugin + 2.7 + + false + + + From 7e2928e8d9ca0eb59e35ca298437c9435510edb3 Mon Sep 17 00:00:00 2001 From: Daniel Danis Date: Thu, 7 Jul 2022 13:03:38 -0400 Subject: [PATCH 069/155] Use Java 17. Signed-off-by: Daniel Danis --- pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d08cc92e..c0ddf023 100644 --- a/pom.xml +++ b/pom.xml @@ -75,7 +75,8 @@ UTF-8 - 11 + UTF-8 + 17 3.21.1 2.0.2 From 3935e25aba1e6a14bd953b322ced1709e2e58a7d Mon Sep 17 00:00:00 2001 From: Daniel Danis Date: Thu, 7 Jul 2022 13:11:07 -0400 Subject: [PATCH 070/155] Require Java 17 in README.ms, run CI on Java 17. Signed-off-by: Daniel Danis --- .github/workflows/main.yaml | 6 +++--- README.md | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index e8404e0f..aa7a8e36 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -16,14 +16,14 @@ jobs: fail-fast: false matrix: os: [ windows-latest, macOS-latest, ubuntu-latest ] - jdk: [ 11 ] + jdk: [ 17 ] steps: - uses: actions/checkout@v2 - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@v2 with: - java-version: '11' + java-version: '17' distribution: 'adopt' - name: Build with Maven run: mvn --batch-mode --update-snapshots verify diff --git a/README.md b/README.md index 34e37c64..9cb8b4ae 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ Multimodule Java library/app that contains a "streamlined builder" module, a v1 to v2 converter app, a validator API and a JSON validator. +Both library and app requires Java 17 or better to run. ## Phenopacket tools CLI From 101e00758836ec7bdd7c595b61539fae26069184 Mon Sep 17 00:00:00 2001 From: Markus <99075696+Sukramg@users.noreply.github.com> Date: Sun, 10 Jul 2022 16:04:00 +0200 Subject: [PATCH 071/155] Hi! --- .../builder/constants/Unit.java | 4 + .../examples/Pseudoexfoliation.java | 210 ++++++++++++++---- 2 files changed, 172 insertions(+), 42 deletions(-) diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Unit.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Unit.java index 28337117..0473888b 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Unit.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Unit.java @@ -9,6 +9,7 @@ public class Unit { private static final OntologyClass MILLIMETRES_OF_MERCURY = ontologyClass("UO:0000272", "millimetres of mercury"); private static final OntologyClass MILLIMETER = ontologyClass("UO:0000016", "millimeter"); private static final OntologyClass MILLIGRAM_PER_KILOGRAM = ontologyClass("UO:0000308", "milligram per kilogram"); + private static final OntologyClass DIOPTER = ontologyClass("NCIT:C100899", "Diopter"); private Unit() { } @@ -27,4 +28,7 @@ public static OntologyClass mm() { public static OntologyClass mgPerKg() { return MILLIGRAM_PER_KILOGRAM; } + + //A unit of measurement of the optical power of a curved mirror or lens represented by the inverse of the focal length in meters. + public static OntologyClass diop() {return DIOPTER; } } diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Pseudoexfoliation.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Pseudoexfoliation.java index 18143d14..b2c56c35 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Pseudoexfoliation.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Pseudoexfoliation.java @@ -11,29 +11,36 @@ import java.util.List; +import static javax.management.MBeanServerFactory.builder; import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; /* +Late-Onset Anterior Dislocation of a Posterior Chamber +Intraocular Lens in a Patient with Pseudoexfoliation +Syndrome Case Rep Ophthalmol 2011;2:1–4 DOI: 10.1159/000323861 RA: Cataract and PEX -> Cataractsurgery -> Emmetropia -> 1J1M Myopia + elevated eyeIop -> Brimonidine -> Yag-IT -> normal Iop LA: Cataract -> Cataractsurgery -> Emmetropia -RA/LA: Monovision -*/ +Result: RA/LA: Monovision +Vorderkammertiefe!!!!!!!!!! + */ public class Pseudoexfoliation implements PhenopacketExample { private static final String PHENOPACKET_ID = "arbitrary.id"; private static final String PROBAND_ID = "proband A"; - private static final String BIOSAMPLE_ID = "biosample.1"; + private static final OntologyClass Pseudoexfoliation = ontologyClass("HP:0012627", "Pseudoexfoliation"); private static final OntologyClass Pseudophakia = ontologyClass("HP:0500081", "Pseudophakia"); + // Organs private static final OntologyClass EYE = ontologyClass("UBERON:0000970", "eye"); private static final OntologyClass LEFT_EYE = ontologyClass("UBERON:0004548", "left eye"); private static final OntologyClass RIGHT_EYE = ontologyClass("UBERON:0004549", "right eye"); private static final OntologyClass Cataract = ontologyClass("HP:0000518", "cataract"); - private final Phenopacket phenopacket; + private Phenopacket phenopacket; public Pseudoexfoliation() { // Metadaten + var authorAssertion = EvidenceBuilder.authorStatementEvidence("PMID:21532993", "Late-Onset Anterior Dislocation of a Posterior Chamber Intraocular Lens in a Patient Pseudoexfoliation Syndrome"); var metadata = MetaDataBuilder.builder("2021-05-14T10:35:00Z", "anonymous biocurator") .addResource(Resources.uberonVersion("2021-07-27")) .addResource(Resources.hpoVersion("2021-08-02")) @@ -47,13 +54,15 @@ public Pseudoexfoliation() { phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metadata) .individual(proband) .addAllMeasurements(getMeasurements()) - .addAllPhenotypicFeatures(getPhenotypicFeatures()) + // .addAllPhenotypicFeatures(getPhenotypicFeatures()) .addDisease(getDisease()) - .addMedicalAction(Cataractsurgery()) - .addMedicalAction(brimonidine()) + .addMedicalAction(cataractsurgery()) + //.addMedicalAction(brimonidine()) + //.addMedicalAction(nd_yag_iridotomy) .build(); } + Disease getDisease() { OntologyClass exfoliationSyndrome = ontologyClass("MONDO:0008327", "exfoliation syndrome"); @@ -81,7 +90,11 @@ implantation in the right eye (OD) in January 2006. .treatmentIntent(Pseudophakia); return mabuilder.build(); } - MedicalAction cataractsurgery = () { + /* + "Six weeks later (Feb./Marc 2006, the patient was subjected to an uncomplicated cataract surgery OS." + No other event on the left eye + */ + MedicalAction cataractsurgery = () { ProcedureBuilder builder = ProcedureBuilder.builder("HP:0000518", "Cataractsurgery"); TimeElement age = TimeElements.age("P70J6W"); builder.bodySite(LEFT_EYE).performed(age); @@ -90,68 +103,181 @@ implantation in the right eye (OD) in January 2006. .treatmentIntent(Pseudophakia); return mabuilder.build(); + + // visual acuity 1,0 right eye one week after Cataractsurgery + + TypedQuantity visus100 = TypedQuantityBuilder.of(ontologyClass("NCIT:C87149", "Visual Acuity"), + QuantityBuilder.of(visusPercent, 100)); + TimeElement age = TimeElements.age("P70J7W");// One week added to the patient's age. Is that how it works? + var visionAssessment = ontologyClass("NCIT:C156778", "Vision Assessment"); + Measurement visusMeasurement = MeasurementBuilder + .builder(visionAssessment, ComplexValueBuilder.of(visus100)).build(); + + // Refraction after 1 week right eye -0.25/-0.5/110 degrees + + OntologyClass sphericalrefraction = ontologyClass("LOINC:79895-9","Subjective refraction method"); + ReferenceRange ref = ReferenceRangeBuilder.of(sphericalrefraction, -30, 30); + OntologyClass rightEyesphericalrefraction = + OntologyClassBuilder.ontologyClass("LOINC:79850-4", "Right eye spharical refraction"); + Value rightEyeValue = ValueBuilder.of(Unit.diop(), -0.25, ref); + OntologyClass rightEyecylindricalrefraction = + OntologyClassBuilder.ontologyClass("LOINC:79846-2", "Right eye cylindrical refraction"); + Value rightEyeValue = ValueBuilder.of(Unit.diop(), -0.5, ref); + // Right eye Axis: LOINC 9829-8 + TimeElement age = TimeElements.age("P70J"); //Druckerhöhung 1J1M nach Cataractsurgery + + return List.of(leftEyeMeasurement, rightEyeMeasurement, visusMeasurement); + } + /* + ONE YEAR AFTER: Refraction after 1 year right eye –3.75/–0.5/110°. degrees + */ + OntologyClass sphericalrefraction = ontologyClass("LOINC:79895-9","Subjective refraction method"); + ReferenceRange ref = ReferenceRangeBuilder.of(sphericalrefraction, -30, 30); + OntologyClass rightEyesphericalrefraction = + OntologyClassBuilder.ontologyClass("LOINC:79850-4", "Right eye spharical refraction"); + Value rightEyeValue = ValueBuilder.of(Unit.diop(), -3.75, ref); + OntologyClass rightEyecylindricalrefraction = + OntologyClassBuilder.ontologyClass("LOINC:79846-2", "Right eye cylindrical refraction"); + Value rightEyeValue = ValueBuilder.of(Unit.diop(), -0.5, ref); + // Right eye Axis: LOINC 9829-8 + TimeElement age = TimeElements.age("P71J1M"); + /* - The intraocular pressure was 29 mmHg in the right eye and 11 mmHg in the left eye - */ + ONE YEAR AFTER: The intraocular pressure was 29 mmHg in the right eye and 11 mmHg in the left eye one + */ List getMeasurements() { - OntologyClass iop = ontologyClass("56844-4","Intraocular pressure of Eye"); + OntologyClass iop = ontologyClass("LOINC:56844-4","Intraocular pressure of Eye"); ReferenceRange ref = ReferenceRangeBuilder.of(iop, 10, 21); OntologyClass leftEyeIop = OntologyClassBuilder.ontologyClass("LOINC:79893-4", "Left eye Intraocular pressure"); - Value leftEyeValue = ValueBuilder.of(Unit.mmHg(), 25, ref); + Value leftEyeValue = ValueBuilder.of(Unit.mmHg(), 11, ref); OntologyClass rightEyeIop = OntologyClassBuilder.ontologyClass("LOINC:79892-6", "Right eye Intraocular pressure"); - Value rightEyeValue = ValueBuilder.of(Unit.mmHg(), 15, ref); - TimeElement age = TimeElements.age("P6M"); + Value rightEyeValue = ValueBuilder.of(Unit.mmHg(), 29, ref); + TimeElement age = TimeElements.age("P71J1M"); //Druckerhöhung 1J1M nach Cataractsurgery Measurement leftEyeMeasurement = MeasurementBuilder.builder(leftEyeIop, leftEyeValue).timeObserved(age).build(); Measurement rightEyeMeasurement = MeasurementBuilder.builder(rightEyeIop, rightEyeValue).timeObserved(age).build(); OntologyClass visusPercent = ontologyClass("NCIT:C48570", "Percent Unit"); - // -0.25/-0.5/110 degreees - TypedQuantity visus100 = TypedQuantityBuilder.of(ontologyClass("NCIT:C87149", "Visual Acuity"), - QuantityBuilder.of(visusPercent, 100)); - var visionAssessment = ontologyClass("NCIT:C156778", "Vision Assessment"); - Measurement visusMeasurement = MeasurementBuilder - .builder(visionAssessment, ComplexValueBuilder.of(visus100)).build(); - // NCIT:C117889 Astigmatism Axis - A measurement of the location, in degrees, of the flatter principal meridian on a 180-degree scale, where 90 degrees designates the vertical meridian and 180 degrees designates the horizontal meridian. [ NCI ] + /* Medical action brimonidine: IOP elevation resisted to topical therapy with α-2 receptors agonists (brimonidine eye drops) */ + /*Product containing precisely brimonidine tartrate 2 milligram/1 milliliter conventional release eye drops (clinical drug) + SCTID: 330731001*/ - return List.of(leftEyeMeasurement, rightEyeMeasurement, visusMeasurement); - } + + MedicalAction brimonidine() { + OntologyClass brimonidine = ontologyClass("DrugCentral:395", "brimonidine"); + OntologyClass administration = ontologyClass("NCIT:C29302", "Ophthalmic Solution"); //Eye drop + Quantity quantity = QuantityBuilder.of(Unit.mgPerKg(), 0.002);// quantity of eye drop? + TimeInterval interval = TimeIntervalBuilder.of("2022-07-07", "2022-07-07"); //omit? + TimeElement age = TimeElements.age("P71J1M"); + OntologyClass once = ontologyClass("NCIT:C64576", "Once"); + + DoseInterval doseInterval = DoseIntervalBuilder.of(quantity, once, interval); + + Treatment treatment = TreatmentBuilder.builder(brimonidine) + .routeOfAdministration(administration) + .addDoseInterval(doseInterval).build(); + + return MedicalActionBuilder.builder(treatment) + .addAdverseEvent(ontologyClass("HP:0025637", "Vasospasm")) + .treatmentTarget() + .treatmentIntent() + .treatmentTerminationReason(ontologyClass("NCIT:C41331", "Adverse Event")) + .build(); + } + + /* Medical action Nd:YAG iridotomy (one year after initial Cataractsurgery)*/ + + MedicalAction nd_yag_iridotomy = () { + ProcedureBuilder builder = ProcedureBuilder.builder("LOINC:29031-2", "Right eye YAG mode"); + TimeElement age = TimeElements.age("P71J1M"); + builder.bodySite(RIGHT_EYE).performed(age); + MedicalActionBuilder mabuilder = MedicalActionBuilder.builder(builder.build()) + .treatmentTarget(Cataract) + .treatmentIntent(Pseudophakia); + return mabuilder.build(); + + + // IOP was successfully regulated OD after Nd:YAG iridotomy (direct postoperative IOP: 14 mm Hg). + + List getMeasurements() { + OntologyClass iop = ontologyClass("LOINC:56844-4", "Intraocular pressure of Eye"); + ReferenceRange ref = ReferenceRangeBuilder.of(iop, 10, 21); + + OntologyClass rightEyeIop = + OntologyClassBuilder.ontologyClass("LOINC:79892-6", "Right eye Intraocular pressure"); + Value rightEyeValue = ValueBuilder.of(Unit.mmHg(), 14, ref);// after Nd:YAG iridotomy + TimeElement age = TimeElements.age("P71J1M"); + +// Anterior chamber depth was 3.93 mm. The PC/IOL was sitting in the capsular bag OS, and the anterior chamber depth was 5.21 mm + OntologyClass acdod = ontologyClass("SCTID: 397312009", "Intraocular lens anterior chamber depth"); + ReferenceRange ref = ReferenceRangeBuilder.of(acdod, 0, 10); + + OntologyClass rightEyeacdod = + OntologyClassBuilder.ontologyClass("SCTID: 397312009", "Intraocular lens anterior chamber depth"); + Value rightEyeValue = ValueBuilder.of(Unit.mm(), 3.93, ref);// + TimeElement age = TimeElements.age("P71J1M"); + Measurement leftEyeMeasurement = MeasurementBuilder.builder(leftEyeIop, leftEyeValue).timeObserved(age).build(); + Measurement rightEyeMeasurement = MeasurementBuilder.builder(rightEyeIop, rightEyeValue).timeObserved(age).build(); + + + // ONE YEAR AFTER: visual acuity 1,0 right eye + + TypedQuantity visus100 = TypedQuantityBuilder.of(ontologyClass("NCIT:C87149", "Visual Acuity"), + QuantityBuilder.of(visusPercent, 100)); + var visionAssessment = ontologyClass("NCIT:C156778", "Vision Assessment"); + Measurement visusMeasurement = MeasurementBuilder + .builder(visionAssessment, ComplexValueBuilder.of(visus100)).build(); + TimeElement age = TimeElements.age("P71J1M"); //Visual acuity 1J1M after Cataractsurgery + } + +/* Result: Monovision Although the myopic shift OD was not eliminated, the patient was satisfied with the monovision, +which was achieved unintentionally and, therefore, we did not proceed to an exchange surgery of the PC/IOL. + */ List getPhenotypicFeatures() { - TimeElement age70years = TimeElements.age("P70J"); - PhenotypicFeature emmetropia = PhenotypicFeatureBuilder. - builder("HP:0000539", "Abnormality of refraction"). // Verneinung, NO Abnormaility... - addModifier(Laterality.right()). - onset(age70years). - build(); - TimeElement age71years = TimeElements.age("P71J"); - PhenotypicFeature Myopia = PhenotypicFeatureBuilder. - builder("HP:0000545", "Myopia"). - addModifier(Laterality.right()). - onset(age71years). - build(); TimeElement age70years = TimeElements.age("P70J"); - PhenotypicFeature glaucoma = PhenotypicFeatureBuilder. - builder("HP:0012108", "Open angle glaucoma "). + PhenotypicFeature emmetropia = PhenotypicFeatureBuilder. + builder("HP:0000539", "Abnormality of refraction"). // Verneinung, NO Abnormaility... addModifier(Laterality.right()). onset(age70years). build(); - TimeElement age4months = TimeElements.age("P4M"); - PhenotypicFeature leukocoria = PhenotypicFeatureBuilder. - builder("HP:0500081", "Pseudophakia") + TimeElement age71years = TimeElements.age("P71J"); + PhenotypicFeature myopia = PhenotypicFeatureBuilder. + builder("HP:0000545", "Myopia") .addModifier(Laterality.right()) - .onset(age4months) + .onset(age71years) .build(); + TimeElement age71years = TimeElements.age("P71J"); + PhenotypicFeature iopi= PhenotypicFeatureBuilder. // iopi = Intraocular Pressure Increased + builder("NCIT:C50618", "Intraocular Pressure Increased") + .addModifier(Laterality.right()) + .onset(age71years) + .build(); + // Anterior chamber depth was 3.93 mm. The PC/IOL was sitting in the capsular bag OS, and the anterior chamber depth was 5.21 mm + TimeElement age71years = TimeElements.age("P71J"); + PhenotypicFeature acdod= PhenotypicFeatureBuilder. //acdod: anterior chamber depth oculus dexter + builder("SCTID:397312009", "Intraocular lens anterior chamber depth")//NCIT:C12667 Anterior Chamber of the Eye + .addModifier(Laterality.right()) + .onset(age71years) + .build(); PhenotypicFeature excludedPhacodonesis = PhenotypicFeatureBuilder. builder("HP:0012629", "Phakodonesis") .excluded() .build(); - return List.of(clinodactyly, leukocoria, strabismus, retinalDetachment, excludedPhacodonesis); + PhenotypicFeature excludedpupilabnormality = PhenotypicFeatureBuilder. + builder(" HP:0007686", "Abnormal pupillary function") + .excluded() + .build(); + PhenotypicFeature monovision = PhenotypicFeatureBuilder. + builder(" SCTID: 414775001", "monovision")// alternative to snomed? + .excluded() + .build(); + return List.of(emmetropia, myopia, iopi, excludedpupilabnormality, excludedPhacodonesis); } } From dd63033670803174339de532f94ce006d79db75e Mon Sep 17 00:00:00 2001 From: pnrobinson Date: Sun, 10 Jul 2022 10:53:30 -0400 Subject: [PATCH 072/155] Pseudoexfoliation --- .../command/ExamplesCommand.java | 2 +- .../examples/Pseudoexfoliation.java | 207 ++++++++++-------- 2 files changed, 111 insertions(+), 98 deletions(-) diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java index 95287a34..c522d1a9 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java @@ -118,7 +118,7 @@ private int outputAllPhenopackets() { output(new Thrombocytopenia2().getPhenopacket(), outDirectory, "thrombocytopenia2"); output(new Marfan().getPhenopacket(), outDirectory, "marfan"); output(new NemalineMyopathyPrenatal().getPhenopacket(), outDirectory, "nemalineMyopathy"); - output(new Pseudoexfoliation().getPhenopacket(), outDirectory,"glaucoma"); + output(new Pseudoexfoliation().getPhenopacket(), outDirectory,"pseudoexfoliation"); output(new SleKidneyTransplantation().getPhenopacket(), outDirectory, "lupus"); output(new SquamousCellCancer().getPhenopacket(), outDirectory, "squamous-cell-esophageal-carcinoma"); output(new UrothelialCancer().getPhenopacket(), outDirectory, "urothelial-cancer"); diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Pseudoexfoliation.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Pseudoexfoliation.java index b2c56c35..b28c39a4 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Pseudoexfoliation.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Pseudoexfoliation.java @@ -11,7 +11,6 @@ import java.util.List; -import static javax.management.MBeanServerFactory.builder; import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; /* @@ -23,7 +22,7 @@ Result: RA/LA: Monovision Vorderkammertiefe!!!!!!!!!! */ - public class Pseudoexfoliation implements PhenopacketExample { +public class Pseudoexfoliation implements PhenopacketExample { private static final String PHENOPACKET_ID = "arbitrary.id"; private static final String PROBAND_ID = "proband A"; @@ -35,7 +34,12 @@ public class Pseudoexfoliation implements PhenopacketExample { private static final OntologyClass LEFT_EYE = ontologyClass("UBERON:0004548", "left eye"); private static final OntologyClass RIGHT_EYE = ontologyClass("UBERON:0004549", "right eye"); private static final OntologyClass Cataract = ontologyClass("HP:0000518", "cataract"); + private static final OntologyClass visusPercent = ontologyClass("NCIT:C48570", "Percent Unit"); + ; + private static final OntologyClass ocularHypertension = ontologyClass("HP:0007906", "Ocular hypertension"); + + // private Phenopacket phenopacket; public Pseudoexfoliation() { @@ -54,19 +58,20 @@ public Pseudoexfoliation() { phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metadata) .individual(proband) .addAllMeasurements(getMeasurements()) - // .addAllPhenotypicFeatures(getPhenotypicFeatures()) + .addAllPhenotypicFeatures(getPhenotypicFeatures()) .addDisease(getDisease()) - .addMedicalAction(cataractsurgery()) + .addMedicalAction(cataractsurgeryRight()) + .addMedicalAction(cataractsurgeryLeft()) //.addMedicalAction(brimonidine()) //.addMedicalAction(nd_yag_iridotomy) .build(); - } + } Disease getDisease() { OntologyClass exfoliationSyndrome = ontologyClass("MONDO:0008327", "exfoliation syndrome"); - TimeElement adult = TimeElements.adultOnset(); + TimeElement adult = TimeElements.adultOnset(); return DiseaseBuilder.builder(exfoliationSyndrome) .onset(adult) .primarySite(RIGHT_EYE) @@ -77,60 +82,66 @@ Disease getDisease() { public Phenopacket getPhenopacket() { return phenopacket; } + /* uneventful clear-cornea phacoemulsification with PC/IOL implantation in the right eye (OD) in January 2006. +// TODO find code for cat op */ - MedicalAction cataractsurgery = () { - ProcedureBuilder builder = ProcedureBuilder.builder("HP:0000518", "Cataractsurgery"); - TimeElement age = TimeElements.age("P70J"); + MedicalAction cataractsurgeryRight() { + ProcedureBuilder builder = ProcedureBuilder.builder("NCIT:C157809", "Cataract Surgery"); + TimeElement age = TimeElements.age("P70Y"); builder.bodySite(RIGHT_EYE).performed(age); MedicalActionBuilder mabuilder = MedicalActionBuilder.builder(builder.build()) .treatmentTarget(Cataract) .treatmentIntent(Pseudophakia); return mabuilder.build(); } + /* "Six weeks later (Feb./Marc 2006, the patient was subjected to an uncomplicated cataract surgery OS." No other event on the left eye */ - MedicalAction cataractsurgery = () { - ProcedureBuilder builder = ProcedureBuilder.builder("HP:0000518", "Cataractsurgery"); - TimeElement age = TimeElements.age("P70J6W"); + MedicalAction cataractsurgeryLeft() { + ProcedureBuilder builder = ProcedureBuilder.builder("NCIT:C157809", "Cataract Surgery"); + TimeElement age = TimeElements.age("P70Y6W"); builder.bodySite(LEFT_EYE).performed(age); MedicalActionBuilder mabuilder = MedicalActionBuilder.builder(builder.build()) .treatmentTarget(Cataract) .treatmentIntent(Pseudophakia); return mabuilder.build(); + } + List getMeasurements2() { + // visual acuity 1,0 right eye one week after Cataractsurgery - TypedQuantity visus100 = TypedQuantityBuilder.of(ontologyClass("NCIT:C87149", "Visual Acuity"), + TypedQuantity visus100 = TypedQuantityBuilder.of(ontologyClass("NCIT:C87149", "Visual Acuity"), QuantityBuilder.of(visusPercent, 100)); - TimeElement age = TimeElements.age("P70J7W");// One week added to the patient's age. Is that how it works? + TimeElement age = TimeElements.age("P70Y7W");// One week added to the patient's age. Is that how it works? var visionAssessment = ontologyClass("NCIT:C156778", "Vision Assessment"); Measurement visusMeasurement = MeasurementBuilder .builder(visionAssessment, ComplexValueBuilder.of(visus100)).build(); // Refraction after 1 week right eye -0.25/-0.5/110 degrees - OntologyClass sphericalrefraction = ontologyClass("LOINC:79895-9","Subjective refraction method"); - ReferenceRange ref = ReferenceRangeBuilder.of(sphericalrefraction, -30, 30); - OntologyClass rightEyesphericalrefraction = - OntologyClassBuilder.ontologyClass("LOINC:79850-4", "Right eye spharical refraction"); - Value rightEyeValue = ValueBuilder.of(Unit.diop(), -0.25, ref); - OntologyClass rightEyecylindricalrefraction = - OntologyClassBuilder.ontologyClass("LOINC:79846-2", "Right eye cylindrical refraction"); - Value rightEyeValue = ValueBuilder.of(Unit.diop(), -0.5, ref); - // Right eye Axis: LOINC 9829-8 - TimeElement age = TimeElements.age("P70J"); //Druckerhöhung 1J1M nach Cataractsurgery - - return List.of(leftEyeMeasurement, rightEyeMeasurement, visusMeasurement); + OntologyClass sphericalrefraction = ontologyClass("LOINC:79895-9", "Subjective refraction method"); + ReferenceRange ref = ReferenceRangeBuilder.of(sphericalrefraction, -30, 30); + OntologyClass rightEyesphericalrefraction = + OntologyClassBuilder.ontologyClass("LOINC:79850-4", "Right eye spharical refraction"); + Value rightEyeValue = ValueBuilder.of(Unit.diop(), -0.25, ref); + OntologyClass rightEyecylindricalrefraction = + OntologyClassBuilder.ontologyClass("LOINC:79846-2", "Right eye cylindrical refraction"); + Value rightEyeValueCylinder = ValueBuilder.of(Unit.diop(), -0.5, ref); + // Right eye Axis: LOINC 9829-8 + TimeElement age70years = TimeElements.age("P70Y"); //Druckerhöhung 1J1M nach Cataractsurgery +//leftEyeMeasurement, rightEyeMeasurement, TODO -- add to list of returned items + return List.of(visusMeasurement); } /* ONE YEAR AFTER: Refraction after 1 year right eye –3.75/–0.5/110°. degrees - */ + OntologyClass sphericalrefraction = ontologyClass("LOINC:79895-9","Subjective refraction method"); ReferenceRange ref = ReferenceRangeBuilder.of(sphericalrefraction, -30, 30); OntologyClass rightEyesphericalrefraction = @@ -138,15 +149,17 @@ implantation in the right eye (OD) in January 2006. Value rightEyeValue = ValueBuilder.of(Unit.diop(), -3.75, ref); OntologyClass rightEyecylindricalrefraction = OntologyClassBuilder.ontologyClass("LOINC:79846-2", "Right eye cylindrical refraction"); - Value rightEyeValue = ValueBuilder.of(Unit.diop(), -0.5, ref); + Value rightEyeValueCylinder = ValueBuilder.of(Unit.diop(), -0.5, ref); // Right eye Axis: LOINC 9829-8 TimeElement age = TimeElements.age("P71J1M"); + */ + /* ONE YEAR AFTER: The intraocular pressure was 29 mmHg in the right eye and 11 mmHg in the left eye one */ - List getMeasurements() { - OntologyClass iop = ontologyClass("LOINC:56844-4","Intraocular pressure of Eye"); + List getMeasurementsYeasr2() { + OntologyClass iop = ontologyClass("LOINC:56844-4", "Intraocular pressure of Eye"); ReferenceRange ref = ReferenceRangeBuilder.of(iop, 10, 21); OntologyClass leftEyeIop = OntologyClassBuilder.ontologyClass("LOINC:79893-4", "Left eye Intraocular pressure"); @@ -154,84 +167,85 @@ List getMeasurements() { OntologyClass rightEyeIop = OntologyClassBuilder.ontologyClass("LOINC:79892-6", "Right eye Intraocular pressure"); Value rightEyeValue = ValueBuilder.of(Unit.mmHg(), 29, ref); - TimeElement age = TimeElements.age("P71J1M"); //Druckerhöhung 1J1M nach Cataractsurgery + TimeElement age = TimeElements.age("P71Y1M"); //Druckerhöhung 1J1M nach Cataractsurgery Measurement leftEyeMeasurement = MeasurementBuilder.builder(leftEyeIop, leftEyeValue).timeObserved(age).build(); Measurement rightEyeMeasurement = MeasurementBuilder.builder(rightEyeIop, rightEyeValue).timeObserved(age).build(); - OntologyClass visusPercent = ontologyClass("NCIT:C48570", "Percent Unit"); /* Medical action brimonidine: IOP elevation resisted to topical therapy with α-2 receptors agonists (brimonidine eye drops) */ /*Product containing precisely brimonidine tartrate 2 milligram/1 milliliter conventional release eye drops (clinical drug) SCTID: 330731001*/ + return List.of(leftEyeMeasurement, rightEyeMeasurement); + } - MedicalAction brimonidine() { - OntologyClass brimonidine = ontologyClass("DrugCentral:395", "brimonidine"); - OntologyClass administration = ontologyClass("NCIT:C29302", "Ophthalmic Solution"); //Eye drop - Quantity quantity = QuantityBuilder.of(Unit.mgPerKg(), 0.002);// quantity of eye drop? - TimeInterval interval = TimeIntervalBuilder.of("2022-07-07", "2022-07-07"); //omit? - TimeElement age = TimeElements.age("P71J1M"); - OntologyClass once = ontologyClass("NCIT:C64576", "Once"); + MedicalAction brimonidine() { + OntologyClass brimonidine = ontologyClass("DrugCentral:395", "brimonidine"); + OntologyClass administration = ontologyClass("NCIT:C29302", "Ophthalmic Solution"); //Eye drop + Quantity quantity = QuantityBuilder.of(Unit.mgPerKg(), 0.002);// quantity of eye drop? + TimeInterval interval = TimeIntervalBuilder.of("2022-07-07", "2022-07-07"); //omit? + TimeElement age = TimeElements.age("P71Y1M"); + OntologyClass once = ontologyClass("NCIT:C64576", "Once"); - DoseInterval doseInterval = DoseIntervalBuilder.of(quantity, once, interval); + DoseInterval doseInterval = DoseIntervalBuilder.of(quantity, once, interval); - Treatment treatment = TreatmentBuilder.builder(brimonidine) - .routeOfAdministration(administration) - .addDoseInterval(doseInterval).build(); + Treatment treatment = TreatmentBuilder.builder(brimonidine) + .routeOfAdministration(administration) + .addDoseInterval(doseInterval).build(); - return MedicalActionBuilder.builder(treatment) - .addAdverseEvent(ontologyClass("HP:0025637", "Vasospasm")) - .treatmentTarget() - .treatmentIntent() - .treatmentTerminationReason(ontologyClass("NCIT:C41331", "Adverse Event")) - .build(); - } + return MedicalActionBuilder.builder(treatment) + .addAdverseEvent(ontologyClass("HP:0025637", "Vasospasm")) + .treatmentTarget(ocularHypertension) + .treatmentTerminationReason(ontologyClass("NCIT:C41331", "Adverse Event")) + .build(); + } - /* Medical action Nd:YAG iridotomy (one year after initial Cataractsurgery)*/ + /* Medical action Nd:YAG iridotomy (one year after initial Cataractsurgery)*/ - MedicalAction nd_yag_iridotomy = () { - ProcedureBuilder builder = ProcedureBuilder.builder("LOINC:29031-2", "Right eye YAG mode"); - TimeElement age = TimeElements.age("P71J1M"); - builder.bodySite(RIGHT_EYE).performed(age); - MedicalActionBuilder mabuilder = MedicalActionBuilder.builder(builder.build()) - .treatmentTarget(Cataract) - .treatmentIntent(Pseudophakia); - return mabuilder.build(); + MedicalAction nd_yag_iridotomy() { + ProcedureBuilder builder = ProcedureBuilder.builder("LOINC:29031-2", "Right eye YAG mode"); + TimeElement age = TimeElements.age("P71Y1M"); + builder.bodySite(RIGHT_EYE).performed(age); + MedicalActionBuilder mabuilder = MedicalActionBuilder.builder(builder.build()) + .treatmentTarget(Cataract) + .treatmentIntent(Pseudophakia); + return mabuilder.build(); + } // IOP was successfully regulated OD after Nd:YAG iridotomy (direct postoperative IOP: 14 mm Hg). - List getMeasurements() { - OntologyClass iop = ontologyClass("LOINC:56844-4", "Intraocular pressure of Eye"); - ReferenceRange ref = ReferenceRangeBuilder.of(iop, 10, 21); + List getMeasurements() { + OntologyClass iop = ontologyClass("LOINC:56844-4", "Intraocular pressure of Eye"); + ReferenceRange ref = ReferenceRangeBuilder.of(iop, 10, 21); - OntologyClass rightEyeIop = - OntologyClassBuilder.ontologyClass("LOINC:79892-6", "Right eye Intraocular pressure"); - Value rightEyeValue = ValueBuilder.of(Unit.mmHg(), 14, ref);// after Nd:YAG iridotomy - TimeElement age = TimeElements.age("P71J1M"); + OntologyClass rightEyeIop = + OntologyClassBuilder.ontologyClass("LOINC:79892-6", "Right eye Intraocular pressure"); + Value rightEyeValue = ValueBuilder.of(Unit.mmHg(), 14, ref);// after Nd:YAG iridotomy + TimeElement age = TimeElements.age("P71Y1M"); // Anterior chamber depth was 3.93 mm. The PC/IOL was sitting in the capsular bag OS, and the anterior chamber depth was 5.21 mm - OntologyClass acdod = ontologyClass("SCTID: 397312009", "Intraocular lens anterior chamber depth"); - ReferenceRange ref = ReferenceRangeBuilder.of(acdod, 0, 10); + OntologyClass acdod = ontologyClass("SCTID: 397312009", "Intraocular lens anterior chamber depth"); + ReferenceRange ref2 = ReferenceRangeBuilder.of(acdod, 0, 10); - OntologyClass rightEyeacdod = - OntologyClassBuilder.ontologyClass("SCTID: 397312009", "Intraocular lens anterior chamber depth"); - Value rightEyeValue = ValueBuilder.of(Unit.mm(), 3.93, ref);// - TimeElement age = TimeElements.age("P71J1M"); - Measurement leftEyeMeasurement = MeasurementBuilder.builder(leftEyeIop, leftEyeValue).timeObserved(age).build(); - Measurement rightEyeMeasurement = MeasurementBuilder.builder(rightEyeIop, rightEyeValue).timeObserved(age).build(); + OntologyClass rightEyeacdod = + OntologyClassBuilder.ontologyClass("SCTID: 397312009", "Intraocular lens anterior chamber depth"); + Value rightEyeValue2 = ValueBuilder.of(Unit.mm(), 3.93, ref);// + // Measurement leftEyeMeasurement = MeasurementBuilder.builder(leftEyeIop, leftEyeValue).timeObserved(age).build(); + Measurement rightEyeMeasurement = MeasurementBuilder.builder(rightEyeIop, rightEyeValue).timeObserved(age).build(); - // ONE YEAR AFTER: visual acuity 1,0 right eye - TypedQuantity visus100 = TypedQuantityBuilder.of(ontologyClass("NCIT:C87149", "Visual Acuity"), - QuantityBuilder.of(visusPercent, 100)); - var visionAssessment = ontologyClass("NCIT:C156778", "Vision Assessment"); - Measurement visusMeasurement = MeasurementBuilder - .builder(visionAssessment, ComplexValueBuilder.of(visus100)).build(); - TimeElement age = TimeElements.age("P71J1M"); //Visual acuity 1J1M after Cataractsurgery - } + // ONE YEAR AFTER: visual acuity 1,0 right eye + + TypedQuantity visus100 = TypedQuantityBuilder.of(ontologyClass("NCIT:C87149", "Visual Acuity"), + QuantityBuilder.of(visusPercent, 100)); + var visionAssessment = ontologyClass("NCIT:C156778", "Vision Assessment"); + Measurement visusMeasurement = MeasurementBuilder + .builder(visionAssessment, ComplexValueBuilder.of(visus100)).build(); + return List.of(rightEyeMeasurement); + } /* Result: Monovision Although the myopic shift OD was not eliminated, the patient was satisfied with the monovision, which was achieved unintentionally and, therefore, we did not proceed to an exchange surgery of the PC/IOL. @@ -239,41 +253,40 @@ List getMeasurements() { List getPhenotypicFeatures() { - TimeElement age70years = TimeElements.age("P70J"); - PhenotypicFeature emmetropia = PhenotypicFeatureBuilder. + TimeElement age70years = TimeElements.age("P70Y"); + PhenotypicFeature emmetropia = PhenotypicFeatureBuilder. builder("HP:0000539", "Abnormality of refraction"). // Verneinung, NO Abnormaility... - addModifier(Laterality.right()). + addModifier(Laterality.right()). onset(age70years). build(); - TimeElement age71years = TimeElements.age("P71J"); - PhenotypicFeature myopia = PhenotypicFeatureBuilder. + TimeElement age71years = TimeElements.age("P71Y"); + PhenotypicFeature myopia = PhenotypicFeatureBuilder. builder("HP:0000545", "Myopia") .addModifier(Laterality.right()) .onset(age71years) .build(); - TimeElement age71years = TimeElements.age("P71J"); - PhenotypicFeature iopi= PhenotypicFeatureBuilder. // iopi = Intraocular Pressure Increased + + PhenotypicFeature iopi = PhenotypicFeatureBuilder. // iopi = Intraocular Pressure Increased builder("NCIT:C50618", "Intraocular Pressure Increased") .addModifier(Laterality.right()) .onset(age71years) .build(); // Anterior chamber depth was 3.93 mm. The PC/IOL was sitting in the capsular bag OS, and the anterior chamber depth was 5.21 mm - TimeElement age71years = TimeElements.age("P71J"); - PhenotypicFeature acdod= PhenotypicFeatureBuilder. //acdod: anterior chamber depth oculus dexter - builder("SCTID:397312009", "Intraocular lens anterior chamber depth")//NCIT:C12667 Anterior Chamber of the Eye - .addModifier(Laterality.right()) - .onset(age71years) - .build(); + PhenotypicFeature acdod = PhenotypicFeatureBuilder. //acdod: anterior chamber depth oculus dexter + builder("SCTID:397312009", "Intraocular lens anterior chamber depth")//NCIT:C12667 Anterior Chamber of the Eye + .addModifier(Laterality.right()) + .onset(age71years) + .build(); PhenotypicFeature excludedPhacodonesis = PhenotypicFeatureBuilder. builder("HP:0012629", "Phakodonesis") .excluded() .build(); - PhenotypicFeature excludedpupilabnormality = PhenotypicFeatureBuilder. + PhenotypicFeature excludedpupilabnormality = PhenotypicFeatureBuilder. builder(" HP:0007686", "Abnormal pupillary function") .excluded() .build(); - PhenotypicFeature monovision = PhenotypicFeatureBuilder. + PhenotypicFeature monovision = PhenotypicFeatureBuilder. builder(" SCTID: 414775001", "monovision")// alternative to snomed? .excluded() .build(); From 2b2738a2fee3f066d393e3834600298f9682a7cf Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Sun, 17 Jul 2022 09:49:00 -0400 Subject: [PATCH 073/155] adding false to simplify testing --- .../src/main/java/module-info.java | 2 ++ pom.xml | 3 +++ 2 files changed, 5 insertions(+) diff --git a/phenopacket-tools-validator-core/src/main/java/module-info.java b/phenopacket-tools-validator-core/src/main/java/module-info.java index a51e2edf..c9181b92 100644 --- a/phenopacket-tools-validator-core/src/main/java/module-info.java +++ b/phenopacket-tools-validator-core/src/main/java/module-info.java @@ -7,4 +7,6 @@ requires com.google.protobuf; requires com.google.protobuf.util; requires org.phenopackets.schema; + + opens org.phenopackets.phenopackettools.validator.core; } \ No newline at end of file diff --git a/pom.xml b/pom.xml index dd5daa00..40c37432 100644 --- a/pom.xml +++ b/pom.xml @@ -100,6 +100,9 @@ org.apache.maven.plugins maven-surefire-plugin 3.0.0-M5 + + false + org.springframework.boot From b62e19ac556ffa2a174a2f0c1028c660c78571ea Mon Sep 17 00:00:00 2001 From: Daniel Danis Date: Fri, 22 Jul 2022 10:19:55 -0400 Subject: [PATCH 074/155] Add `release` profile, remove obsolete CI POM section, add Sonatype repositories. Signed-off-by: Daniel Danis --- pom.xml | 122 +++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 107 insertions(+), 15 deletions(-) diff --git a/pom.xml b/pom.xml index c0ddf023..c196d784 100644 --- a/pom.xml +++ b/pom.xml @@ -61,17 +61,22 @@ - scm:git:https://github.com/phenopackets/phenopacket-validator.git - scm:git:ssh://github.com:phenopackets/phenopackets/phenopacket-tools.git - + scm:git:https://github.com/phenopackets/phenopacket-tools.git + scm:git:ssh://github.com:phenopackets/phenopacket-tools.git https://github.com/phenopackets/phenopacket-tools - HEAD + v${project.version} - - Travis CI - https://travis-ci.org/phenopackets/phenopacket-tools - + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + UTF-8 @@ -188,10 +193,97 @@ junit-jupiter test - - org.hamcrest - hamcrest-core - test - - - \ No newline at end of file + + org.hamcrest + hamcrest-core + test + + + + + + + + + release + + + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.3.1 + + ${java.home}/bin/javadoc + none + true + + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-release-plugin + 3.0.0-M5 + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + + sign-artifacts + verify + + sign + + + + + + org.apache.maven.plugins + maven-deploy-plugin + 3.0.0-M2 + + + + + + org.apache.maven.plugins + maven-gpg-plugin + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + + + + + \ No newline at end of file From bb357f94bfaf1ca2774d3d410900075418647389 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Tue, 9 Aug 2022 21:17:36 -0400 Subject: [PATCH 075/155] refactoring --- .../builder/constants/Organs.java | 1 - .../command/ValidateCommand.java | 2 +- ...rvicofacialActinomycosisOfTheMandible.java | 7 --- ...ngSyndromeWithMultifocalOsteonecrosis.java | 5 -- .../examples/Pseudoexfoliation.java | 2 - .../src/main/java/module-info.java | 2 + .../validator/core/ErrorTypeOLD.java | 1 + .../validator/core/OntologyError.java | 12 ---- .../core/PhenopacketMessageValidator.java | 8 ++- .../core/PhenopacketValidatorFactory.java | 1 + .../core/PhenopacketValidatorOld.java | 2 + .../validator/core/ValidationAspectOLD.java | 18 ------ .../validator/core/ValidationErrorLevel.java | 5 -- .../validator/core/ValidationErrorType.java | 10 +++- .../validator/core/ValidationItem.java | 9 +-- .../validator/core/ValidatorRunner.java | 1 - .../validator/core/errors/JsonError.java | 56 +++++++++++++++++++ .../validator/core/errors/OntologyError.java | 17 ++++++ .../validator/core/ValidatorRunnerTest.java | 2 - .../pom.xml | 6 +- .../src/main/java/module-info.java | 2 +- .../jsonschema/JsonValidationError.java | 30 +++++----- .../JsonSchemaDiseaseValidatorTest.java | 6 +- .../jsonschema/JsonSchemaValidatorTest.java | 29 ++++++---- 24 files changed, 137 insertions(+), 97 deletions(-) delete mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/OntologyError.java delete mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationAspectOLD.java delete mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationErrorLevel.java create mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/JsonError.java create mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/OntologyError.java diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Organs.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Organs.java index d96ae29a..0535521f 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Organs.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/Organs.java @@ -1,6 +1,5 @@ package org.phenopackets.phenopackettools.builder.constants; -import org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder; import org.phenopackets.schema.v2.core.OntologyClass; import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ValidateCommand.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ValidateCommand.java index ff692212..532ffe18 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ValidateCommand.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ValidateCommand.java @@ -49,7 +49,7 @@ public Integer call() { printSeparator(); } else { for (ValidationItem item : validationItems) { - System.out.printf("%s - (%s) %s%n", fileName, item.errorType(), item.message()); + System.out.printf("%s - (%s) %n", fileName, item.errorType()); } printSeparator(); } diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/CervicofacialActinomycosisOfTheMandible.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/CervicofacialActinomycosisOfTheMandible.java index 3fa04ad5..91e039e3 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/CervicofacialActinomycosisOfTheMandible.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/CervicofacialActinomycosisOfTheMandible.java @@ -1,17 +1,10 @@ package org.phenopackets.phenopackettools.examples; -import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; -import org.phenopackets.phenopackettools.builder.builders.*; -import org.phenopackets.schema.v2.Phenopacket; -import org.phenopackets.schema.v2.core.Individual; -import org.phenopackets.schema.v2.core.Interpretation; import org.phenopackets.schema.v2.core.MedicalAction; import org.phenopackets.schema.v2.core.PhenotypicFeature; import java.util.List; -import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; - public class CervicofacialActinomycosisOfTheMandible { diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/CushingSyndromeWithMultifocalOsteonecrosis.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/CushingSyndromeWithMultifocalOsteonecrosis.java index 801711ef..ef49ea57 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/CushingSyndromeWithMultifocalOsteonecrosis.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/CushingSyndromeWithMultifocalOsteonecrosis.java @@ -1,14 +1,9 @@ package org.phenopackets.phenopackettools.examples; -import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; -import org.phenopackets.phenopackettools.builder.builders.*; -import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.*; import java.util.List; -import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; - public class CushingSyndromeWithMultifocalOsteonecrosis { diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Pseudoexfoliation.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Pseudoexfoliation.java index 1e053701..872f1967 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Pseudoexfoliation.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Pseudoexfoliation.java @@ -1,8 +1,6 @@ package org.phenopackets.phenopackettools.examples; import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; -import org.phenopackets.phenopackettools.builder.builders.MetaDataBuilder; -import org.phenopackets.phenopackettools.builder.builders.Resources; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.phenopackettools.builder.builders.*; import org.phenopackets.phenopackettools.builder.constants.Laterality; diff --git a/phenopacket-tools-validator-core/src/main/java/module-info.java b/phenopacket-tools-validator-core/src/main/java/module-info.java index c9181b92..ab0b46eb 100644 --- a/phenopacket-tools-validator-core/src/main/java/module-info.java +++ b/phenopacket-tools-validator-core/src/main/java/module-info.java @@ -9,4 +9,6 @@ requires org.phenopackets.schema; opens org.phenopackets.phenopackettools.validator.core; + exports org.phenopackets.phenopackettools.validator.core.errors; + opens org.phenopackets.phenopackettools.validator.core.errors; } \ No newline at end of file diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ErrorTypeOLD.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ErrorTypeOLD.java index 2ba8b9ff..aeb84c7a 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ErrorTypeOLD.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ErrorTypeOLD.java @@ -2,6 +2,7 @@ import org.phenopackets.phenopackettools.validator.core.except.PhenopacketValidatorRuntimeException; +@Deprecated(forRemoval = true) public enum ErrorTypeOLD { /** JSON schema error meaning that the JSON code contained a property not present in the schema. */ JSON_ADDITIONAL_PROPERTIES("additionalProperties"), diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/OntologyError.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/OntologyError.java deleted file mode 100644 index 3a31545a..00000000 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/OntologyError.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.phenopackets.phenopackettools.validator.core; - -public record OntologyError(String name, String message) implements ValidationErrorType{ - - - // - - public static OntologyError invalidOntology(String message) { - return new OntologyError("invalid ontology", message); - } - -} diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketMessageValidator.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketMessageValidator.java index 7ca99b40..c5a97d55 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketMessageValidator.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketMessageValidator.java @@ -6,6 +6,11 @@ import java.util.List; +/** + * Interface for validator classes that do not use JSON Schema, for instance, + * classes that use Ontology logic. + * @param A Message that can be a Phenopacket, Family, Cohort, or components of these messages + */ public interface PhenopacketMessageValidator { @@ -13,9 +18,6 @@ public interface PhenopacketMessageValidator { List validate(T ga4ghPhenopacketMessage); - - - } diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidatorFactory.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidatorFactory.java index 0ef71429..78b63a48 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidatorFactory.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidatorFactory.java @@ -8,6 +8,7 @@ * @author Daniel Danis * @author Peter N Robinson */ +@Deprecated(forRemoval = true) public interface PhenopacketValidatorFactory { // TODO probably simplify/delete Optional getValidatorForType(ValidatorInfo type); diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidatorOld.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidatorOld.java index e619a82e..25303614 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidatorOld.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidatorOld.java @@ -11,9 +11,11 @@ /** * Phenopacket validator applies rules to check that the provided data meets the requirements for a valid Phenopacket. *

+ * REPLACED BY ValidatorRunner ... * @author Daniel Danis * @author Peter N Robinson */ +@Deprecated(forRemoval = true) public interface PhenopacketValidatorOld { ValidatorInfo info(); diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationAspectOLD.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationAspectOLD.java deleted file mode 100644 index c0f20a3b..00000000 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationAspectOLD.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.phenopackets.phenopackettools.validator.core; - - -public enum ValidationAspectOLD { - - // This enum is supposed to be used instead of the ErrorType - // TODO - elaborate the categories - - // general syntax inconsistency, e.g. bad JSON format - GENERAL, - - // e.g. missing at least one phenotypic feature, age, etc. - MISSING_PROPERTY, - - // e.g. invalid ontology used to represent an info - INVALID_VALUE, - -} diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationErrorLevel.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationErrorLevel.java deleted file mode 100644 index 165a2cae..00000000 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationErrorLevel.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.phenopackets.phenopackettools.validator.core; - -public enum ValidationErrorLevel { - ERROR, WARNING -} diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationErrorType.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationErrorType.java index 063af13b..6f3c6290 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationErrorType.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationErrorType.java @@ -1,8 +1,16 @@ package org.phenopackets.phenopackettools.validator.core; +import org.phenopackets.phenopackettools.validator.core.errors.OntologyError; + public interface ValidationErrorType { - String name(); + String category(); + String subcategory(); String message(); + + static ValidationErrorType ontologyError(String message) { + return OntologyError.of(message); + } + } diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationItem.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationItem.java index fb9caed1..1818e8ad 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationItem.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationItem.java @@ -7,18 +7,15 @@ * @author Peter N Robinson */ public interface ValidationItem { - /** * @return basic description of the validator that produced this issue. */ ValidatorInfo validatorInfo(); - // TODO - decide which enum to use here - either ErrorType or ValidationAspect - ErrorTypeOLD errorType(); - /** - * @return string with description of the issue intended for human consumption. + * @return the error or warning produce by a validator */ - String message(); + ValidationErrorType errorType(); + } diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorRunner.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorRunner.java index d23f5b5d..65fa0425 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorRunner.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorRunner.java @@ -1,6 +1,5 @@ package org.phenopackets.phenopackettools.validator.core; -import org.phenopackets.schema.v2.Phenopacket; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/JsonError.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/JsonError.java new file mode 100644 index 00000000..0c2e4811 --- /dev/null +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/JsonError.java @@ -0,0 +1,56 @@ +package org.phenopackets.phenopackettools.validator.core.errors; + +import org.phenopackets.phenopackettools.validator.core.ValidationErrorType; + +public class JsonError implements ValidationErrorType { + + public static final String CATEGORY = "JSON"; + /** JSON schema error meaning that the JSON code contained a property not present in the schema. */ + public static final String ADDITIONAL_PROPERTIES = "additionalProperties"; + /** JSON schema error meaning that the JSON code failed to contain a property required by the schema. */ + public static final String REQUIRED = "required"; + /** Another kind of JSON error. */ + public static final String UNKNOWN = "unknown"; + + + + private final String category; + private final String subcategory; + private final String message; + + + public JsonError(String subcategory, String message) { + this.category = CATEGORY; + this.subcategory = subcategory; + this.message = message; + } + + @Override + public String category() { + return this.category; + } + + @Override + public String subcategory() { + return this.subcategory; + } + + @Override + public String message() { + return this.message; + } + + + + public static JsonError additionalProperties(String message) { + return new JsonError(ADDITIONAL_PROPERTIES, message); + } + + public static JsonError required(String message) { + return new JsonError(REQUIRED, message); + } + + public static JsonError unknown(String message) { + return new JsonError(UNKNOWN, message); + } +} diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/OntologyError.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/OntologyError.java new file mode 100644 index 00000000..f66ec5e8 --- /dev/null +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/OntologyError.java @@ -0,0 +1,17 @@ +package org.phenopackets.phenopackettools.validator.core.errors; + +import org.phenopackets.phenopackettools.validator.core.ValidationErrorType; + +public record OntologyError(String category, + String subcategory, + String message) implements ValidationErrorType { + + + // + + public static OntologyError of(String message) { + return new OntologyError("invalid ontology", "todo-subcat", message); + } + + +} diff --git a/phenopacket-tools-validator-core/src/test/java/org/phenopackets/phenopackettools/validator/core/ValidatorRunnerTest.java b/phenopacket-tools-validator-core/src/test/java/org/phenopackets/phenopackettools/validator/core/ValidatorRunnerTest.java index 8ce5f68b..141c97bf 100644 --- a/phenopacket-tools-validator-core/src/test/java/org/phenopackets/phenopackettools/validator/core/ValidatorRunnerTest.java +++ b/phenopacket-tools-validator-core/src/test/java/org/phenopackets/phenopackettools/validator/core/ValidatorRunnerTest.java @@ -2,8 +2,6 @@ import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; - class ValidatorRunnerTest { diff --git a/phenopacket-tools-validator-jsonschema/pom.xml b/phenopacket-tools-validator-jsonschema/pom.xml index 3b459aef..5aef5a0c 100644 --- a/phenopacket-tools-validator-jsonschema/pom.xml +++ b/phenopacket-tools-validator-jsonschema/pom.xml @@ -26,17 +26,15 @@ com.networknt json-schema-validator - - org.phenopackets phenopacket-schema - test + com.google.protobuf protobuf-java - test + com.google.protobuf diff --git a/phenopacket-tools-validator-jsonschema/src/main/java/module-info.java b/phenopacket-tools-validator-jsonschema/src/main/java/module-info.java index e245e9f2..87455f9c 100644 --- a/phenopacket-tools-validator-jsonschema/src/main/java/module-info.java +++ b/phenopacket-tools-validator-jsonschema/src/main/java/module-info.java @@ -1,6 +1,6 @@ module org.phenopackets.phenopackettools.validator.jsonschema { requires transitive org.phenopackets.phenopackettools.validator.core; - + requires org.phenopackets.schema; requires com.fasterxml.jackson.databind; requires json.schema.validator; requires org.slf4j; diff --git a/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonValidationError.java b/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonValidationError.java index 745426fa..12dd6151 100644 --- a/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonValidationError.java +++ b/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonValidationError.java @@ -1,9 +1,10 @@ package org.phenopackets.phenopackettools.validator.jsonschema; import com.networknt.schema.ValidationMessage; -import org.phenopackets.phenopackettools.validator.core.ErrorTypeOLD; +import org.phenopackets.phenopackettools.validator.core.ValidationErrorType; import org.phenopackets.phenopackettools.validator.core.ValidationItem; import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; +import org.phenopackets.phenopackettools.validator.core.errors.JsonError; import java.util.Objects; @@ -14,42 +15,46 @@ */ public final class JsonValidationError implements ValidationItem { + String CATEGORY = "JSON"; + private final ValidatorInfo validatorInfo; - private final ErrorTypeOLD errorType; - private final String message; + private final ValidationErrorType errorType; public JsonValidationError(ValidatorInfo validatorInfo, ValidationMessage validationMessage) { this.validatorInfo = validatorInfo; - this.errorType = ErrorTypeOLD.stringToErrorType(validationMessage.getType()); - this.message = validationMessage.getMessage(); + String subcat = validationMessage.getType(); + switch (subcat) { + case JsonError.REQUIRED -> errorType = JsonError.required(validationMessage.getMessage()); + case JsonError.ADDITIONAL_PROPERTIES -> errorType = JsonError.additionalProperties(validationMessage.getMessage()); + default -> errorType = JsonError.unknown(validationMessage.getType()); + } + } + @Override public ValidatorInfo validatorInfo() { return validatorInfo; } @Override - public ErrorTypeOLD errorType() { + public ValidationErrorType errorType() { return this.errorType; } - @Override - public String message() { - return message; - } + @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; JsonValidationError that = (JsonValidationError) o; - return Objects.equals(validatorInfo, that.validatorInfo) && errorType == that.errorType && Objects.equals(message, that.message); + return Objects.equals(validatorInfo, that.validatorInfo) && errorType == that.errorType; } @Override public int hashCode() { - return Objects.hash(validatorInfo, errorType, message); + return Objects.hash(validatorInfo, errorType); } @Override @@ -57,7 +62,6 @@ public String toString() { return "JsonValidationError{" + "validatorInfo='" + validatorInfo + '\'' + ", errorType=" + errorType + - ", message='" + message + '\'' + '}'; } } diff --git a/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaDiseaseValidatorTest.java b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaDiseaseValidatorTest.java index da204cca..2d92bb0a 100644 --- a/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaDiseaseValidatorTest.java +++ b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaDiseaseValidatorTest.java @@ -5,9 +5,9 @@ import com.google.protobuf.util.JsonFormat; import org.junit.jupiter.api.Test; import org.phenopackets.phenopackettools.validator.core.PhenopacketValidatorOld; -import org.phenopackets.phenopackettools.validator.core.ErrorTypeOLD; import org.phenopackets.phenopackettools.validator.core.ValidationItem; import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; +import org.phenopackets.phenopackettools.validator.core.errors.JsonError; import org.phenopackets.phenopackettools.validator.testdatagen.PhenopacketUtil; import org.phenopackets.schema.v2.Phenopacket; import org.phenopackets.schema.v2.core.Disease; @@ -82,8 +82,8 @@ public void testLacksId() throws InvalidProtocolBufferException { // System.out.println(errors); assertEquals(1, errors.size()); ValidationItem error = errors.get(0); - assertEquals(ErrorTypeOLD.JSON_REQUIRED, error.errorType()); - assertEquals("$.id: is missing but it is required", error.message()); + assertEquals(JsonError.REQUIRED, error.errorType().subcategory()); + assertEquals("$.id: is missing but it is required", error.errorType().message()); } diff --git a/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidatorTest.java b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidatorTest.java index 9f0589a0..7c97ee3b 100644 --- a/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidatorTest.java +++ b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidatorTest.java @@ -6,6 +6,7 @@ import org.phenopackets.phenopackettools.validator.core.PhenopacketValidatorOld; import org.phenopackets.phenopackettools.validator.core.ValidationItem; import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; +import org.phenopackets.phenopackettools.validator.core.errors.JsonError; import org.phenopackets.phenopackettools.validator.testdatagen.RareDiseasePhenopacket; import org.phenopackets.phenopackettools.validator.testdatagen.SimplePhenopacket; import org.phenopackets.schema.v2.Phenopacket; @@ -31,17 +32,17 @@ public class JsonSchemaValidatorTest { public void testValidationOfSimpleValidPhenopacket() throws Exception { PhenopacketValidatorOld validator = FACTORY.getValidatorForType(ValidatorInfo.generic()).get(); Phenopacket phenopacket = simplePhenopacket.getPhenopacket(); - String json = JsonFormat.printer().print(phenopacket); + String json = JsonFormat.printer().print(phenopacket); List errors = validator.validate(json); assertTrue(errors.isEmpty()); // the Phenopacket is not valid if we remove the id phenopacket = Phenopacket.newBuilder(phenopacket).clearId().build(); - json = JsonFormat.printer().print(phenopacket); + json = JsonFormat.printer().print(phenopacket); errors = validator.validate(json); assertEquals(1, errors.size()); ValidationItem error = errors.get(0); - assertEquals(ErrorTypeOLD.JSON_REQUIRED, error.errorType()); - assertEquals("$.id: is missing but it is required", error.message()); + assertEquals(JsonError.REQUIRED, error.errorType().subcategory()); + assertEquals("$.id: is missing but it is required", error.errorType().message()); } /** @@ -55,17 +56,21 @@ public void testValidationOfSimpleInValidPhenopacket() { String invalidPhenopacketJson = "{\"disney\" : \"donald\"}"; List errors = validator.validate(invalidPhenopacketJson); - assertEquals(3, errors.size()); ValidationItem error = errors.get(0); - assertEquals(ErrorTypeOLD.JSON_REQUIRED, error.errorType()); - assertEquals("$.id: is missing but it is required", error.message()); + // JsonError.CATEGORY is "JSON" + assertEquals(JsonError.CATEGORY, error.errorType().category()); + assertEquals(JsonError.REQUIRED, error.errorType().subcategory()); + assertEquals("$.id: is missing but it is required", error.errorType().message()); error = errors.get(1); - assertEquals(ErrorTypeOLD.JSON_REQUIRED, error.errorType()); - assertEquals("$.metaData: is missing but it is required", error.message()); + assertEquals(JsonError.CATEGORY, error.errorType().category()); + assertEquals(JsonError.REQUIRED, error.errorType().subcategory()); + assertEquals("$.metaData: is missing but it is required", error.errorType().message()); error = errors.get(2); - assertEquals(ErrorTypeOLD.JSON_ADDITIONAL_PROPERTIES, error.errorType()); - assertEquals("$.disney: is not defined in the schema and the schema does not allow additional properties", error.message()); + + assertEquals(JsonError.CATEGORY, error.errorType().category()); + assertEquals(JsonError.ADDITIONAL_PROPERTIES, error.errorType().subcategory()); + assertEquals("$.disney: is not defined in the schema and the schema does not allow additional properties", error.errorType().message()); } @Test @@ -92,7 +97,7 @@ public void testRareDiseaseBethlemahmInvalidValidPhenopacket() throws IOExceptio assertEquals(1, validationItems.size()); ValidationItem validationItem = validationItems.get(0); assertEquals(ErrorTypeOLD.JSON_REQUIRED, validationItem.errorType()); - assertEquals("$.phenotypicFeatures: is missing but it is required", validationItem.message()); + // assertEquals("$.phenotypicFeatures: is missing but it is required", validationItem.message()); } From 666b4b21cc69523488bb3c8405de8c0d46d2e03b Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Wed, 10 Aug 2022 10:07:09 -0400 Subject: [PATCH 076/155] deleting old file --- .../validator/core/ValidationAspectOLD.java | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationAspectOLD.java diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationAspectOLD.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationAspectOLD.java deleted file mode 100644 index c0f20a3b..00000000 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationAspectOLD.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.phenopackets.phenopackettools.validator.core; - - -public enum ValidationAspectOLD { - - // This enum is supposed to be used instead of the ErrorType - // TODO - elaborate the categories - - // general syntax inconsistency, e.g. bad JSON format - GENERAL, - - // e.g. missing at least one phenotypic feature, age, etc. - MISSING_PROPERTY, - - // e.g. invalid ontology used to represent an info - INVALID_VALUE, - -} From 4dc4df5d2e94459d87539da9ceecd86fbfb8c85e Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Thu, 11 Aug 2022 08:35:45 -0400 Subject: [PATCH 077/155] merged, bumped to 0.4.5 --- phenopacket-tools-builder/pom.xml | 2 +- phenopacket-tools-cli/pom.xml | 2 +- phenopacket-tools-converter/pom.xml | 2 +- phenopacket-tools-validator-core/pom.xml | 2 +- phenopacket-tools-validator-jsonschema/pom.xml | 2 +- pom.xml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/phenopacket-tools-builder/pom.xml b/phenopacket-tools-builder/pom.xml index dea2c0ca..28d406b8 100644 --- a/phenopacket-tools-builder/pom.xml +++ b/phenopacket-tools-builder/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenopackettools phenopacket-tools - 0.4.0-SNAPSHOT + 0.4.5-SNAPSHOT phenopacket-tools-builder diff --git a/phenopacket-tools-cli/pom.xml b/phenopacket-tools-cli/pom.xml index 751228a1..7d9fb65c 100644 --- a/phenopacket-tools-cli/pom.xml +++ b/phenopacket-tools-cli/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenopackettools phenopacket-tools - 0.4.0-SNAPSHOT + 0.4.5-SNAPSHOT phenopacket-tools-cli diff --git a/phenopacket-tools-converter/pom.xml b/phenopacket-tools-converter/pom.xml index 5a63ff28..43014817 100644 --- a/phenopacket-tools-converter/pom.xml +++ b/phenopacket-tools-converter/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenopackettools phenopacket-tools - 0.4.0-SNAPSHOT + 0.4.5-SNAPSHOT phenopacket-tools-converter diff --git a/phenopacket-tools-validator-core/pom.xml b/phenopacket-tools-validator-core/pom.xml index a7ae9d05..5faa7167 100644 --- a/phenopacket-tools-validator-core/pom.xml +++ b/phenopacket-tools-validator-core/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenopackettools phenopacket-tools - 0.4.0-SNAPSHOT + 0.4.5-SNAPSHOT phenopacket-tools-validator-core diff --git a/phenopacket-tools-validator-jsonschema/pom.xml b/phenopacket-tools-validator-jsonschema/pom.xml index 5aef5a0c..c366d5d4 100644 --- a/phenopacket-tools-validator-jsonschema/pom.xml +++ b/phenopacket-tools-validator-jsonschema/pom.xml @@ -7,7 +7,7 @@ org.phenopackets.phenopackettools phenopacket-tools - 0.4.0-SNAPSHOT + 0.4.5-SNAPSHOT phenopacket-tools-validator-jsonschema diff --git a/pom.xml b/pom.xml index 5ce2c647..f06de4ea 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.phenopackets.phenopackettools phenopacket-tools - 0.4.0-SNAPSHOT + 0.4.5-SNAPSHOT pom From 91955169ca4aa9b186becfa7b0606de1e75841e9 Mon Sep 17 00:00:00 2001 From: Daniel Danis Date: Thu, 11 Aug 2022 09:37:42 -0400 Subject: [PATCH 078/155] Enable to submit date of birth as `LocalDate` and age at last encounter as `TimeElement`. Signed-off-by: Daniel Danis --- .../builder/builders/IndividualBuilder.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilder.java index d81badc9..22fdbc64 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/IndividualBuilder.java @@ -3,6 +3,7 @@ import com.google.protobuf.Timestamp; import org.phenopackets.schema.v2.core.*; +import java.time.LocalDate; import java.util.List; /** @@ -47,6 +48,12 @@ public IndividualBuilder addAllAlternateIds(List altIdList) { return this; } + public IndividualBuilder dateOfBirth(LocalDate localDate) { + Timestamp timestamp = TimestampBuilder.timestamp(localDate.getYear(), localDate.getMonthValue(), localDate.getDayOfMonth()); + builder.setDateOfBirth(timestamp); + return this; + } + public IndividualBuilder dateOfBirth(String dobirth) { Timestamp dob = TimestampBuilder.fromISO8601(dobirth); builder.setDateOfBirth(dob); @@ -58,6 +65,12 @@ public IndividualBuilder timestampAtLastEncounter(String timestamp) { builder.setTimeAtLastEncounter(t); return this; } + + public IndividualBuilder ageAtLastEncounter(TimeElement timeElement) { + builder.setTimeAtLastEncounter(timeElement); + return this; + } + public IndividualBuilder ageAtLastEncounter(String iso8601) { TimeElement t = TimeElements.age(iso8601); builder.setTimeAtLastEncounter(t); From 132447008e8d91f0af2b5fc2d63afe74f31adca2 Mon Sep 17 00:00:00 2001 From: Daniel Danis Date: Thu, 11 Aug 2022 09:38:19 -0400 Subject: [PATCH 079/155] Enable setting of resolution and description to `PhenotypicFeatureBuilder`. Signed-off-by: Daniel Danis --- .../builder/builders/PhenotypicFeatureBuilder.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/PhenotypicFeatureBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/PhenotypicFeatureBuilder.java index 3901df93..5a5d850e 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/PhenotypicFeatureBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/PhenotypicFeatureBuilder.java @@ -80,6 +80,11 @@ public PhenotypicFeatureBuilder adultOnset() { return this; } + public PhenotypicFeatureBuilder resolution(TimeElement time) { + builder.setResolution(time); + return this; + } + public PhenotypicFeatureBuilder severity(String id, String label) { OntologyClass severity = OntologyClassBuilder.ontologyClass(id, label); return severity(severity); @@ -116,6 +121,11 @@ public PhenotypicFeatureBuilder addAllModifiers(List modifiers) { return this; } + public PhenotypicFeatureBuilder description(String text) { + builder.setDescription(text); + return this; + } + public PhenotypicFeature build() { return builder.build(); } From dc989f818b2f85d6d7e3bef3a53d8527a806db22 Mon Sep 17 00:00:00 2001 From: Daniel Danis Date: Thu, 11 Aug 2022 09:39:05 -0400 Subject: [PATCH 080/155] Allow adding `ExternalReference` to `TherapeuticRegimenBuilder`. Signed-off-by: Daniel Danis --- .../builders/TherapeuticRegimenBuilder.java | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TherapeuticRegimenBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TherapeuticRegimenBuilder.java index 583bf529..b81b3571 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TherapeuticRegimenBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/TherapeuticRegimenBuilder.java @@ -1,5 +1,6 @@ package org.phenopackets.phenopackettools.builder.builders; +import org.phenopackets.schema.v2.core.ExternalReference; import org.phenopackets.schema.v2.core.OntologyClass; import org.phenopackets.schema.v2.core.TherapeuticRegimen; import org.phenopackets.schema.v2.core.TimeElement; @@ -11,15 +12,23 @@ public class TherapeuticRegimenBuilder { private final TherapeuticRegimen.Builder builder; - public TherapeuticRegimenBuilder() { - builder = TherapeuticRegimen.newBuilder(); + private TherapeuticRegimenBuilder(OntologyClass clazz) { + builder = TherapeuticRegimen.newBuilder() + .setOntologyClass(clazz); + } + + private TherapeuticRegimenBuilder(ExternalReference externalReference) { + builder = TherapeuticRegimen.newBuilder() + .setExternalReference(externalReference); } public static TherapeuticRegimenBuilder builder(String id, String label) { OntologyClass clazz = OntologyClassBuilder.ontologyClass(id, label); - TherapeuticRegimenBuilder builder = new TherapeuticRegimenBuilder(); - builder.ontologyClass(clazz); - return builder; + return new TherapeuticRegimenBuilder(clazz); + } + + public static TherapeuticRegimenBuilder builder(ExternalReference reference) { + return new TherapeuticRegimenBuilder(reference); } public TherapeuticRegimenBuilder ontologyClass(OntologyClass clz) { From ad308ae57589a72f1acfb25fd7796c9a4a975acf Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Thu, 11 Aug 2022 15:35:18 -0400 Subject: [PATCH 081/155] refactoring --- .../command/ValidateCommand.java | 22 ++-- phenopacket-tools-validator-core/pom.xml | 11 ++ .../src/main/java/module-info.java | 1 + .../validator/core/DefaultValidationInfo.java | 5 + .../core/DefaultValidationRunner.java | 23 +++- .../core/DefaultValidatorRunner.java | 92 +++++++++++++++ .../validator/core/ErrorTypeOLD.java | 41 ------- .../core/JsonPhenopacketValidator.java | 11 -- .../core/PhenopacketMessageValidator.java | 23 ---- .../validator/core/PhenopacketValidator.java | 13 +++ .../core/PhenopacketValidatorFactory.java | 17 --- .../core/PhenopacketValidatorOld.java | 37 ------ .../validator/core/ValidationErrorType.java | 16 --- .../validator/core/ValidationItem.java | 21 ---- .../validator/core/ValidationLevel.java | 5 + .../validator/core/ValidationResult.java | 26 +++++ .../core/ValidationWorkflowRunner.java | 7 +- .../validator/core/ValidatorInfo.java | 6 +- .../validator/core/ValidatorRunner.java | 95 --------------- .../validator/core/errors/InputError.java | 38 ++++++ .../validator/core/errors/JsonError.java | 22 +++- .../validator/core/errors/OntologyError.java | 15 ++- .../except/PhenopacketValidatorException.java | 11 ++ .../PhenopacketValidatorInputException.java | 11 ++ .../core/impl/DefaultPhenopacketIngestor.java | 109 ++++++++++++++++++ .../validator/core/impl/Ingestor.java | 11 ++ .../ClasspathJsonSchemaValidatorFactory.java | 17 ++- .../jsonschema/JsonSchemaValidator.java | 60 +++++----- .../jsonschema/JsonValidationError.java | 59 ++++++---- .../JsonSchemaDiseaseValidatorTest.java | 31 ++--- .../jsonschema/JsonSchemaValidatorTest.java | 72 ++++++------ 31 files changed, 535 insertions(+), 393 deletions(-) create mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidatorRunner.java delete mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ErrorTypeOLD.java delete mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/JsonPhenopacketValidator.java delete mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketMessageValidator.java create mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidator.java delete mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidatorFactory.java delete mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidatorOld.java delete mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationErrorType.java delete mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationItem.java create mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationLevel.java create mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationResult.java delete mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorRunner.java create mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/InputError.java create mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/except/PhenopacketValidatorException.java create mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/except/PhenopacketValidatorInputException.java create mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/DefaultPhenopacketIngestor.java create mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/Ingestor.java diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ValidateCommand.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ValidateCommand.java index 532ffe18..0848857f 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ValidateCommand.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ValidateCommand.java @@ -1,11 +1,10 @@ package org.phenopackets.phenopackettools.command; -import org.phenopackets.phenopackettools.validator.core.PhenopacketValidatorFactory; -import org.phenopackets.phenopackettools.validator.core.ValidationItem; +import org.phenopackets.phenopackettools.validator.core.ValidationResult; +import org.phenopackets.phenopackettools.validator.core.ValidationWorkflowRunner; import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; -import org.phenopackets.phenopackettools.validator.core.ValidatorRunner; -import org.phenopackets.phenopackettools.validator.jsonschema.ClasspathJsonSchemaValidatorFactory; +import org.phenopackets.phenopackettools.validator.core.DefaultValidatorRunner; import picocli.CommandLine.Command; import picocli.CommandLine.Option; import picocli.CommandLine.Parameters; @@ -18,6 +17,8 @@ import java.util.List; import java.util.concurrent.Callable; +import static org.phenopackets.phenopackettools.validator.jsonschema.JsonSchemaValidator.makeGenericJsonValidator; + @Command(name = "validate", mixinStandardHelpOptions = true) public class ValidateCommand implements Callable { @@ -32,24 +33,23 @@ public class ValidateCommand implements Callable { public Integer call() { // What type of validation do we run? List validationTypes = new ArrayList<>(); - validationTypes.add(ValidatorInfo.generic()); // we run this by default + validationTypes.add(ValidatorInfo.genericJsonSchema()); // we run this by default if (rareHpoConstraints) { validationTypes.add(ValidatorInfo.rareDiseaseValidation()); } - - PhenopacketValidatorFactory phenopacketValidatorFactory = ClasspathJsonSchemaValidatorFactory.defaultValidators(); - ValidatorRunner validatorRunner = new ValidatorRunner(List.of(), List.of()); + var messageValidators = List.of(makeGenericJsonValidator()); + DefaultValidatorRunner validatorRunner = new DefaultValidatorRunner(messageValidators, List.of()); for (Path phenopacket : phenopackets) { try (InputStream in = Files.newInputStream(phenopacket)) { - List validationItems = validatorRunner.validate(in, List.of()); + List validationItems = validatorRunner.validate(in); Path fileName = phenopacket.getFileName(); if (validationItems.isEmpty()) { System.out.printf("%s - OK%n", fileName); printSeparator(); } else { - for (ValidationItem item : validationItems) { - System.out.printf("%s - (%s) %n", fileName, item.errorType()); + for (ValidationResult item : validationItems) { + System.out.printf("%s - (%s) %n", fileName, item.category()); } printSeparator(); } diff --git a/phenopacket-tools-validator-core/pom.xml b/phenopacket-tools-validator-core/pom.xml index 5faa7167..02cb5dfc 100644 --- a/phenopacket-tools-validator-core/pom.xml +++ b/phenopacket-tools-validator-core/pom.xml @@ -29,6 +29,17 @@ com.google.protobuf protobuf-java-util + + com.fasterxml.jackson.core + jackson-core + ${jackson.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + \ No newline at end of file diff --git a/phenopacket-tools-validator-core/src/main/java/module-info.java b/phenopacket-tools-validator-core/src/main/java/module-info.java index ab0b46eb..617d1171 100644 --- a/phenopacket-tools-validator-core/src/main/java/module-info.java +++ b/phenopacket-tools-validator-core/src/main/java/module-info.java @@ -7,6 +7,7 @@ requires com.google.protobuf; requires com.google.protobuf.util; requires org.phenopackets.schema; + requires com.fasterxml.jackson.databind; opens org.phenopackets.phenopackettools.validator.core; exports org.phenopackets.phenopackettools.validator.core.errors; diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidationInfo.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidationInfo.java index 6ca82b34..71428dcb 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidationInfo.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidationInfo.java @@ -7,6 +7,9 @@ class DefaultValidationInfo implements ValidatorInfo { private static final DefaultValidationInfo GENERIC = of("GENERIC", "Validation of a generic Phenopacket"); private static final DefaultValidationInfo RARE_DISEASE_VALIDATOR = of("RARE_DISEASE_VALIDATOR", "Validation of rare disease Phenopacket constraints"); + private static final DefaultValidationInfo INPUT_VALIDATOR = of("Input", "Input of phenopacket data"); + + static ValidatorInfo generic() { return GENERIC; } @@ -15,6 +18,8 @@ static ValidatorInfo rareDiseaseValidator() { return RARE_DISEASE_VALIDATOR; } + static ValidatorInfo inputValidator() { return INPUT_VALIDATOR; } + private final String validatorId; private final String validatorName; diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidationRunner.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidationRunner.java index f074e662..9f0d7914 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidationRunner.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidationRunner.java @@ -2,14 +2,31 @@ +import java.io.InputStream; +import java.nio.charset.Charset; import java.util.List; public class DefaultValidationRunner implements ValidationWorkflowRunner { - public DefaultValidationRunner(List sds, List v1) { + public DefaultValidationRunner(List sds) { } + @Override + public List validate(InputStream io) { + return null; + } + + @Override + public List validate(byte[] content) { + return null; + } + + @Override + public List validate(byte[] content, Charset charset) { + return null; + } + /** * implementation: * 1. get string as input @@ -23,8 +40,10 @@ public DefaultValidationRunner(List sds, List run(String input) { + public List validate(String input) { // return null; } + + } diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidatorRunner.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidatorRunner.java new file mode 100644 index 00000000..ad3f8094 --- /dev/null +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidatorRunner.java @@ -0,0 +1,92 @@ +package org.phenopackets.phenopackettools.validator.core; + +import com.fasterxml.jackson.databind.JsonNode; +import com.google.protobuf.Message; +import org.phenopackets.phenopackettools.validator.core.except.PhenopacketValidatorException; +import org.phenopackets.phenopackettools.validator.core.except.PhenopacketValidatorRuntimeException; +import org.phenopackets.phenopackettools.validator.core.impl.DefaultPhenopacketIngestor; +import org.phenopackets.phenopackettools.validator.core.impl.Ingestor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; + +public class DefaultValidatorRunner implements ValidationWorkflowRunner{ + + private static final Logger LOGGER = LoggerFactory.getLogger(DefaultValidatorRunner.class); + + private final List jsonValidators; + private final List messageValidators; + + + public DefaultValidatorRunner(List jsonValidators, + List messageValidators) { + this.messageValidators = jsonValidators; + this.jsonValidators = messageValidators; + } + + + public List validate(InputStream stream) { + try { + Ingestor ingestor = new DefaultPhenopacketIngestor(stream); + JsonNode jsonNode = ingestor.jsonNode(); + Message message = ingestor.message(); + return validateImpl(jsonNode, message); + } catch (PhenopacketValidatorException e) { + return List.of(ValidationResult.inputError(e.getMessage())); + } + } + + @Override + public List validate(byte[] content) { + try { + Ingestor ingestor = new DefaultPhenopacketIngestor(content); + JsonNode jsonNode = ingestor.jsonNode(); + Message message = ingestor.message(); + return validateImpl(jsonNode, message); + } catch (PhenopacketValidatorException e) { + return List.of(ValidationResult.inputError(e.getMessage())); + } + } + + @Override + public List validate(byte[] content, Charset charset) { + try { + Ingestor ingestor = new DefaultPhenopacketIngestor(content, charset); + JsonNode jsonNode = ingestor.jsonNode(); + Message message = ingestor.message(); + return validateImpl(jsonNode, message); + } catch (PhenopacketValidatorException e) { + return List.of(ValidationResult.inputError(e.getMessage())); + } + } + + @Override + public List validate(String content) { + try { + Ingestor ingestor = new DefaultPhenopacketIngestor(content); + JsonNode jsonNode = ingestor.jsonNode(); + Message message = ingestor.message(); + return validateImpl(jsonNode, message); + } catch (PhenopacketValidatorException e) { + return List.of(ValidationResult.inputError(e.getMessage())); + } + } + + + private List validateImpl(JsonNode jsonNode, Message message) { + List results = new ArrayList<>(); + for (var validator : jsonValidators) { + results.addAll(validator.validateJson(jsonNode)); + } + for (var validator : messageValidators) { + results.addAll(validator.validateMessage(message)); + } + return results; + } + +} diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ErrorTypeOLD.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ErrorTypeOLD.java deleted file mode 100644 index aeb84c7a..00000000 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ErrorTypeOLD.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.phenopackets.phenopackettools.validator.core; - -import org.phenopackets.phenopackettools.validator.core.except.PhenopacketValidatorRuntimeException; - -@Deprecated(forRemoval = true) -public enum ErrorTypeOLD { - /** JSON schema error meaning that the JSON code contained a property not present in the schema. */ - JSON_ADDITIONAL_PROPERTIES("additionalProperties"), - /** JSON schema error meaning that the JSON code failed to contain a property required by the schema. */ - JSON_REQUIRED("required"), - /** The type of an object is not as required by the schema, e.g., we get a string instead of an array. */ - JSON_TYPE("type"), - SUBJECT_MISSING_AGE("subject missing age"), - MISSING_SUBJECT("missing subject"), - INVALID_ONTOLOGY("invalid ontology"), - MISSING_PHENOTYPIC_FEATURE("missing phenotypic feature"); - - private final String name; - - - ErrorTypeOLD(String value) { - this.name = value; - } - - @Override - public String toString() { - return this.name; - } - - - public static ErrorTypeOLD stringToErrorType(String error) { - switch (error) { - case "additionalProperties": return JSON_ADDITIONAL_PROPERTIES; - case "required": return JSON_REQUIRED; - case "type": return JSON_TYPE; - - default: - throw new PhenopacketValidatorRuntimeException("Did not recognize error type: \"" + error + "\""); - } - } -} diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/JsonPhenopacketValidator.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/JsonPhenopacketValidator.java deleted file mode 100644 index 44143ee3..00000000 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/JsonPhenopacketValidator.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.phenopackets.phenopackettools.validator.core; - -import java.util.List; - -public interface JsonPhenopacketValidator { - - ValidatorInfo info(); - - List validate(String json); - -} diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketMessageValidator.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketMessageValidator.java deleted file mode 100644 index c5a97d55..00000000 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketMessageValidator.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.phenopackets.phenopackettools.validator.core; - -import com.google.protobuf.Message; - - - -import java.util.List; - -/** - * Interface for validator classes that do not use JSON Schema, for instance, - * classes that use Ontology logic. - * @param A Message that can be a Phenopacket, Family, Cohort, or components of these messages - */ -public interface PhenopacketMessageValidator { - - - ValidatorInfo info(); - - List validate(T ga4ghPhenopacketMessage); - -} - - diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidator.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidator.java new file mode 100644 index 00000000..e681920b --- /dev/null +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidator.java @@ -0,0 +1,13 @@ +package org.phenopackets.phenopackettools.validator.core; + +import com.google.protobuf.Message; +import com.fasterxml.jackson.databind.JsonNode; + +import java.util.List; + +public interface PhenopacketValidator { + + List validateJson(JsonNode jsonNode); + List validateMessage(Message message); + +} diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidatorFactory.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidatorFactory.java deleted file mode 100644 index 78b63a48..00000000 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidatorFactory.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.phenopackets.phenopackettools.validator.core; - -import java.util.Optional; - -/** - * The phenopacket validator factory provides phenopacket validators designed to perform specific {@link ValidatorInfo}. - *

- * @author Daniel Danis - * @author Peter N Robinson - */ -@Deprecated(forRemoval = true) -public interface PhenopacketValidatorFactory { - // TODO probably simplify/delete - Optional getValidatorForType(ValidatorInfo type); - // ? List getValidators(); - -} diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidatorOld.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidatorOld.java deleted file mode 100644 index 25303614..00000000 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidatorOld.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.phenopackets.phenopackettools.validator.core; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.util.List; - -/** - * Phenopacket validator applies rules to check that the provided data meets the requirements for a valid Phenopacket. - *

- * REPLACED BY ValidatorRunner ... - * @author Daniel Danis - * @author Peter N Robinson - */ -@Deprecated(forRemoval = true) -public interface PhenopacketValidatorOld { - - ValidatorInfo info(); - - List validate(InputStream inputStream); - - // ----------------------------------------------------------------------------------------------------------------- - - default List validate(File phenopacket) throws IOException { - try (InputStream inputStream = Files.newInputStream(phenopacket.toPath())) { - return validate(inputStream); - } - } - - default List validate(String content) { - return validate(new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8))); - } - -} diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationErrorType.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationErrorType.java deleted file mode 100644 index 6f3c6290..00000000 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationErrorType.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.phenopackets.phenopackettools.validator.core; - -import org.phenopackets.phenopackettools.validator.core.errors.OntologyError; - -public interface ValidationErrorType { - - String category(); - String subcategory(); - String message(); - - - static ValidationErrorType ontologyError(String message) { - return OntologyError.of(message); - } - -} diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationItem.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationItem.java deleted file mode 100644 index 1818e8ad..00000000 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationItem.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.phenopackets.phenopackettools.validator.core; - -/** - * The interface represents a single issue found during validation. - *

- * @author Daniel Danis - * @author Peter N Robinson - */ -public interface ValidationItem { - /** - * @return basic description of the validator that produced this issue. - */ - ValidatorInfo validatorInfo(); - - /** - * @return the error or warning produce by a validator - */ - ValidationErrorType errorType(); - - -} diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationLevel.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationLevel.java new file mode 100644 index 00000000..9b55b182 --- /dev/null +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationLevel.java @@ -0,0 +1,5 @@ +package org.phenopackets.phenopackettools.validator.core; + +public enum ValidationLevel { + VALIDATION_ERROR, VALIDATION_WARNING +} diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationResult.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationResult.java new file mode 100644 index 00000000..0656217a --- /dev/null +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationResult.java @@ -0,0 +1,26 @@ +package org.phenopackets.phenopackettools.validator.core; + +import org.phenopackets.phenopackettools.validator.core.errors.InputError; +import org.phenopackets.phenopackettools.validator.core.errors.OntologyError; + +public interface ValidationResult { + + + ValidatorInfo validationInfo(); + + ValidationLevel level(); + + //String category(); + String category(); + String message(); + + + static ValidationResult ontologyError(String message) { + return OntologyError.of(message); + } + + static ValidationResult inputError(String message) { + return new InputError(message); + } + +} diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationWorkflowRunner.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationWorkflowRunner.java index b7d1916e..9cd5d7fd 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationWorkflowRunner.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationWorkflowRunner.java @@ -1,5 +1,7 @@ package org.phenopackets.phenopackettools.validator.core; +import java.io.InputStream; +import java.nio.charset.Charset; import java.util.List; public interface ValidationWorkflowRunner { @@ -18,8 +20,11 @@ public interface ValidationWorkflowRunner { * @return */ - List run(String input); + public List validate(InputStream io); + public List validate(byte[] content); + public List validate(byte[] content, Charset charset); + public List validate(String content); diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorInfo.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorInfo.java index 9beb6b00..7b28724f 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorInfo.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorInfo.java @@ -2,20 +2,22 @@ public interface ValidatorInfo { - static ValidatorInfo generic() { + static ValidatorInfo genericJsonSchema() { return DefaultValidationInfo.generic(); } /** * This class implements additional validation of a phenopacket that is intended to be used * for HPO rare disease phenotyping. By assumption, the phenopacket will have been first - * checked against the {@link ValidatorInfo#generic()} specification. This class performs validation with the + * checked against the {@link ValidatorInfo#genericJsonSchema()} specification. This class performs validation with the * file {@code hpo-rare-disease-schema.json}. */ static ValidatorInfo rareDiseaseValidation() { return DefaultValidationInfo.rareDiseaseValidator(); } + static ValidatorInfo inputValidator() { return DefaultValidationInfo.inputValidator(); } + static ValidatorInfo of(String validatorId, String validatorName) { return DefaultValidationInfo.of(validatorId, validatorName); } diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorRunner.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorRunner.java deleted file mode 100644 index 65fa0425..00000000 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorRunner.java +++ /dev/null @@ -1,95 +0,0 @@ -package org.phenopackets.phenopackettools.validator.core; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; -import java.util.function.Function; - -public class ValidatorRunner { - - private static final Logger LOGGER = LoggerFactory.getLogger(ValidatorRunner.class); - - // private final PhenopacketValidatorFactory validatorFactory; - private final List messageValidators; - private final List jsonValidators; - - - // private final ValidationWorkflowRunner phenopacketValidationWorkflowRunner; - // private final ValidationWorkflowRunner cohortValidationWorkflowRunner; - // private final ValidationWorkflowRunner familyValidationWorkflowRunner; - -// private final List cohortValidators; -// -// private final List familyValidators; - - public ValidatorRunner(List validators, - List jsonPhenopacketValidators) { - this.messageValidators = validators; - this.jsonValidators = jsonPhenopacketValidators; - // cohortValidators = List.of(); - - } - - - - - - - public List validatePhenopacket(InputStream stream) { - // 1. Create json string - // phenopacketValidationWorkflowRunner.run() - - return List.of(); - } - - public List validateCohort(InputStream stream) { - /// 1. Create json string - // 2. cohortValidationWorkflowRunner.run() - - - return List.of(); - } - - - - public List validate(InputStream inputStream, List validations) { - List items = new ArrayList<>(); - //JsonNode json = objectMapper.readTree(inputStream); - // loop 1 - //PhenopacketBuilder from google - // loop 2 - try { - byte[] content = inputStream.readAllBytes(); - // items = validations.stream().flatMap(v -> v.validate(inputStream).stream()) - // .toList(); -// for (PhenopacketValidator validationType : validations) { -// // validatorFactory.getValidatorForType(validationType) -// validate(content). -// //.ifPresent(items::addAll); -// } - return List.copyOf(items); - - } catch (IOException e) { - LOGGER.error("Error occurred during validation {}", e.getMessage(), e); - } - return List.of(); - } - - private static Function> validate(byte[] content) { - return validator -> { - try (InputStream is = new ByteArrayInputStream(content)) { - return validator.validate(is); - } catch (IOException e) { - LOGGER.error("Error occurred during validation {}", e.getMessage(), e); - } - return List.of(); - }; - } - - -} diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/InputError.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/InputError.java new file mode 100644 index 00000000..d48bad02 --- /dev/null +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/InputError.java @@ -0,0 +1,38 @@ +package org.phenopackets.phenopackettools.validator.core.errors; + +import org.phenopackets.phenopackettools.validator.core.ValidationLevel; +import org.phenopackets.phenopackettools.validator.core.ValidationResult; +import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; + +public class InputError implements ValidationResult { + + private static final String VALIDATION_CATEGORY = "input"; + + private final String message; + + public InputError(String message) { + this.message = message; + } + + + @Override + public ValidatorInfo validationInfo() { + return ValidatorInfo.inputValidator(); + } + + @Override + public ValidationLevel level() { + return ValidationLevel.VALIDATION_ERROR; + } + + @Override + public String category() { + return VALIDATION_CATEGORY; + } + + @Override + public String message() { + return this.message; + } + +} diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/JsonError.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/JsonError.java index 0c2e4811..ddc507a3 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/JsonError.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/JsonError.java @@ -1,8 +1,10 @@ package org.phenopackets.phenopackettools.validator.core.errors; -import org.phenopackets.phenopackettools.validator.core.ValidationErrorType; +import org.phenopackets.phenopackettools.validator.core.ValidationLevel; +import org.phenopackets.phenopackettools.validator.core.ValidationResult; +import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; -public class JsonError implements ValidationErrorType { +public class JsonError implements ValidationResult { public static final String CATEGORY = "JSON"; /** JSON schema error meaning that the JSON code contained a property not present in the schema. */ @@ -25,13 +27,23 @@ public JsonError(String subcategory, String message) { this.message = message; } +// @Override +// public String category() { +// return this.category; +// } + @Override - public String category() { - return this.category; + public ValidatorInfo validationInfo() { + return null; + } + + @Override + public ValidationLevel level() { + return null; } @Override - public String subcategory() { + public String category() { return this.subcategory; } diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/OntologyError.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/OntologyError.java index f66ec5e8..d7b5358c 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/OntologyError.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/OntologyError.java @@ -1,10 +1,12 @@ package org.phenopackets.phenopackettools.validator.core.errors; -import org.phenopackets.phenopackettools.validator.core.ValidationErrorType; +import org.phenopackets.phenopackettools.validator.core.ValidationLevel; +import org.phenopackets.phenopackettools.validator.core.ValidationResult; +import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; public record OntologyError(String category, String subcategory, - String message) implements ValidationErrorType { + String message) implements ValidationResult { // @@ -14,4 +16,13 @@ public static OntologyError of(String message) { } + @Override + public ValidatorInfo validationInfo() { + return null; + } + + @Override + public ValidationLevel level() { + return null; + } } diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/except/PhenopacketValidatorException.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/except/PhenopacketValidatorException.java new file mode 100644 index 00000000..c55bc234 --- /dev/null +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/except/PhenopacketValidatorException.java @@ -0,0 +1,11 @@ +package org.phenopackets.phenopackettools.validator.core.except; + +public class PhenopacketValidatorException extends Exception { + public PhenopacketValidatorException() { + super(); + } + + public PhenopacketValidatorException(String message) { + super(message); + } +} diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/except/PhenopacketValidatorInputException.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/except/PhenopacketValidatorInputException.java new file mode 100644 index 00000000..8d0b48a3 --- /dev/null +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/except/PhenopacketValidatorInputException.java @@ -0,0 +1,11 @@ +package org.phenopackets.phenopackettools.validator.core.except; + +public class PhenopacketValidatorInputException extends PhenopacketValidatorException { + public PhenopacketValidatorInputException() { + super(); + } + + public PhenopacketValidatorInputException(String message) { + super(message); + } +} diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/DefaultPhenopacketIngestor.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/DefaultPhenopacketIngestor.java new file mode 100644 index 00000000..ff1d47c0 --- /dev/null +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/DefaultPhenopacketIngestor.java @@ -0,0 +1,109 @@ +package org.phenopackets.phenopackettools.validator.core.impl; + +import com.fasterxml.jackson.core.JsonEncoding; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.Message; +import org.phenopackets.phenopackettools.validator.core.except.PhenopacketValidatorInputException; +import org.phenopackets.phenopackettools.validator.core.except.PhenopacketValidatorRuntimeException; +import org.phenopackets.schema.v2.Phenopacket; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.Charset; + +/** + * To do, add Default Cohort Ingestor etc + */ +public class DefaultPhenopacketIngestor implements Ingestor { + + private final JsonNode jsonNode; + + private final Message message; + + + + public DefaultPhenopacketIngestor(InputStream stream) throws PhenopacketValidatorInputException { + byte[] content = null; + try { + content = stream.readAllBytes(); + ObjectMapper mapper = new ObjectMapper(); + this.jsonNode = mapper.readTree(content); + } catch (IOException e) { + throw new PhenopacketValidatorInputException("Could not read input stream: " + e.getMessage()); + } + // read the protobuf message if possible + // if we get here, content is not null; + try { + message = Phenopacket.parseFrom(content); + } catch (InvalidProtocolBufferException e) { + throw new PhenopacketValidatorInputException("Invalid Phenopacket Message: " + e.getMessage()); + } + } + + public DefaultPhenopacketIngestor(byte[] content) throws PhenopacketValidatorInputException { + if (content == null) { + throw new PhenopacketValidatorInputException("input (\"byte[] content\" was null"); + } + try { + ObjectMapper mapper = new ObjectMapper(); + this.jsonNode = mapper.readTree(content); + } catch (IOException e) { + throw new PhenopacketValidatorInputException("Could not read input stream: " + e.getMessage()); + } + try { + message = Phenopacket.parseFrom(content); + } catch (InvalidProtocolBufferException e) { + throw new PhenopacketValidatorInputException("Invalid Phenopacket Message: " + e.getMessage()); + } + } + + public DefaultPhenopacketIngestor(byte[] content, Charset charset) throws PhenopacketValidatorInputException { + if (content == null) { + throw new PhenopacketValidatorInputException("input (\"byte[] content\" was null"); + } + // decode the bytes according to the provided charset + String jsonString = new String(content, charset); + try { + ObjectMapper mapper = new ObjectMapper(); + this.jsonNode = mapper.readTree(jsonString); + } catch (IOException e) { + throw new PhenopacketValidatorInputException("Could not read input stream: " + e.getMessage()); + } + try { + message = Phenopacket.parseFrom(content); + } catch (InvalidProtocolBufferException e) { + throw new PhenopacketValidatorInputException("Invalid Phenopacket Message: " + e.getMessage()); + } + } + + public DefaultPhenopacketIngestor(String jsonString) throws PhenopacketValidatorInputException { + if (jsonString == null) { + throw new PhenopacketValidatorInputException("input (\"String jsonString\" was null"); + } + try { + ObjectMapper mapper = new ObjectMapper(); + this.jsonNode = mapper.readTree(jsonString); + } catch (IOException e) { + throw new PhenopacketValidatorInputException("Could not read input stream: " + e.getMessage()); + } + try { + message = Phenopacket.parseFrom(jsonString.getBytes()); + } catch (InvalidProtocolBufferException e) { + throw new PhenopacketValidatorInputException("Invalid Phenopacket Message: " + e.getMessage()); + } + } + + + @Override + public JsonNode jsonNode() { + return this.jsonNode; + } + + @Override + public Message message() { + return this.message; + } + +} diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/Ingestor.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/Ingestor.java new file mode 100644 index 00000000..d122e1f7 --- /dev/null +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/Ingestor.java @@ -0,0 +1,11 @@ +package org.phenopackets.phenopackettools.validator.core.impl; + +import com.fasterxml.jackson.databind.JsonNode; +import com.google.protobuf.Message; + +public interface Ingestor { + + JsonNode jsonNode(); + Message message(); + +} diff --git a/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/ClasspathJsonSchemaValidatorFactory.java b/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/ClasspathJsonSchemaValidatorFactory.java index aca77ed7..fa5bc426 100644 --- a/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/ClasspathJsonSchemaValidatorFactory.java +++ b/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/ClasspathJsonSchemaValidatorFactory.java @@ -1,14 +1,11 @@ package org.phenopackets.phenopackettools.validator.jsonschema; -import org.phenopackets.phenopackettools.validator.core.PhenopacketValidatorOld; -import org.phenopackets.phenopackettools.validator.core.PhenopacketValidatorFactory; import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; import org.phenopackets.phenopackettools.validator.core.except.PhenopacketValidatorRuntimeException; import java.io.InputStream; import java.util.Map; import java.util.Objects; -import java.util.Optional; /** * Validator factory that uses JSON schema definitions that are bundled within the application (on classpath). @@ -16,8 +13,10 @@ * * @author Daniel Danis * @author Peter N Robinson + * /// implements PhenopacketValidatorFactory */ -public class ClasspathJsonSchemaValidatorFactory implements PhenopacketValidatorFactory { +@Deprecated(forRemoval = true) +public class ClasspathJsonSchemaValidatorFactory { private final Map validatorMap; @@ -28,7 +27,7 @@ public static ClasspathJsonSchemaValidatorFactory defaultValidators() { private static Map makeValidatorMap() { return Map.of( - ValidatorInfo.generic(), makeJsonValidator("/schema/phenopacket-schema-2-0.json", ValidatorInfo.generic()), + ValidatorInfo.genericJsonSchema(), makeJsonValidator("/schema/phenopacket-schema-2-0.json", ValidatorInfo.genericJsonSchema()), ValidatorInfo.rareDiseaseValidation(), makeJsonValidator("/schema/hpo-rare-disease-schema.json", ValidatorInfo.rareDiseaseValidation()) ); } @@ -45,10 +44,10 @@ private ClasspathJsonSchemaValidatorFactory(Map getValidatorForType(ValidatorInfo type) { - return Optional.ofNullable(validatorMap.get(type)); - } +// @Override +// public Optional getValidatorForType(ValidatorInfo type) { +// return Optional.ofNullable(validatorMap.get(type)); +// } @Override public boolean equals(Object o) { diff --git a/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidator.java b/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidator.java index d8e46d87..04fcea50 100644 --- a/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidator.java +++ b/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidator.java @@ -3,26 +3,29 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.protobuf.Message; import com.networknt.schema.JsonSchema; import com.networknt.schema.JsonSchemaFactory; import com.networknt.schema.SpecVersion; -import org.phenopackets.phenopackettools.validator.core.PhenopacketValidatorOld; +import org.phenopackets.phenopackettools.validator.core.PhenopacketValidator; +import org.phenopackets.phenopackettools.validator.core.ValidationResult; +import org.phenopackets.phenopackettools.validator.core.ValidationWorkflowRunner; import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; import org.phenopackets.phenopackettools.validator.core.except.PhenopacketValidatorRuntimeException; -import org.phenopackets.phenopackettools.validator.core.ValidationItem; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.nio.charset.Charset; import java.nio.file.Files; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; -public class JsonSchemaValidator implements PhenopacketValidatorOld { +public class JsonSchemaValidator implements PhenopacketValidator { private static final Logger LOGGER = LoggerFactory.getLogger(JsonSchemaValidator.class); @@ -35,6 +38,14 @@ public class JsonSchemaValidator implements PhenopacketValidatorOld { private final ValidatorInfo validatorInfo; + public static JsonSchemaValidator makeGenericJsonValidator() { + String schemaPath = "/schema/phenopacket-schema-2-0.json"; + InputStream inputStream = JsonSchemaValidator.class.getResourceAsStream(schemaPath); + if (inputStream == null) + throw new PhenopacketValidatorRuntimeException("Invalid JSON schema path `" + schemaPath + '`'); + return JsonSchemaValidator.of(inputStream, ValidatorInfo.genericJsonSchema()); + } + /** * @param jsonSchema path to JSON schema specification file * @throws PhenopacketValidatorRuntimeException if jsonSchema is not a valid file or if the file is @@ -62,32 +73,8 @@ private JsonSchemaValidator(JsonSchema jsonSchema, ValidatorInfo validatorInfo) this.validatorInfo = validatorInfo; } - @Override - public ValidatorInfo info() { - return validatorInfo; - } - /** - * Validate the {@code inputStream} content (assumed to be a Phenopacket formated in JSON) - * - * @return List of {@link ValidationItem} objects (empty list if there were no errors) - */ - @Override - public List validate(InputStream inputStream) { - try { - JsonNode json = objectMapper.readTree(inputStream); - String s = "LL"; - // json = objectMapper.readTree(s); - return jsonSchema.validate(json).stream() - .map(e -> new JsonValidationError(validatorInfo, e)) - .collect(Collectors.toUnmodifiableList()); - } catch (IOException e) { - LOGGER.warn("Error while decoding JSON content: {}", e.getMessage(), e); - } catch (RuntimeException e) { - LOGGER.warn("Error while validating: {}", e.getMessage()); - } - return List.of(); - } + @Override public boolean equals(Object o) { @@ -101,4 +88,21 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(jsonSchema, objectMapper, validatorInfo); } + + + @Override + public List validateJson(JsonNode jsonNode) { + return jsonSchema.validate(jsonNode).stream() + .map(e -> new JsonValidationError(validatorInfo, e)).toList(); + } + + /** + * This validator does not work on protobuf messages + * @param message + * @return empty list + */ + @Override + public List validateMessage(Message message) { + return List.of(); + } } diff --git a/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonValidationError.java b/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonValidationError.java index 12dd6151..0f8a4517 100644 --- a/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonValidationError.java +++ b/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonValidationError.java @@ -1,10 +1,9 @@ package org.phenopackets.phenopackettools.validator.jsonschema; import com.networknt.schema.ValidationMessage; -import org.phenopackets.phenopackettools.validator.core.ValidationErrorType; -import org.phenopackets.phenopackettools.validator.core.ValidationItem; +import org.phenopackets.phenopackettools.validator.core.ValidationLevel; +import org.phenopackets.phenopackettools.validator.core.ValidationResult; import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; -import org.phenopackets.phenopackettools.validator.core.errors.JsonError; import java.util.Objects; @@ -13,34 +12,28 @@ * * @author Peter N Robinson */ -public final class JsonValidationError implements ValidationItem { - - String CATEGORY = "JSON"; +public final class JsonValidationError implements ValidationResult { private final ValidatorInfo validatorInfo; - private final ValidationErrorType errorType; + private final ValidationLevel level; + private final String category; + private final String message; + public JsonValidationError(ValidatorInfo validatorInfo, ValidationMessage validationMessage) { this.validatorInfo = validatorInfo; - String subcat = validationMessage.getType(); - switch (subcat) { - case JsonError.REQUIRED -> errorType = JsonError.required(validationMessage.getMessage()); - case JsonError.ADDITIONAL_PROPERTIES -> errorType = JsonError.additionalProperties(validationMessage.getMessage()); - default -> errorType = JsonError.unknown(validationMessage.getType()); - } - + this.category = validationMessage.getType(); + this.message = validationMessage.getMessage(); + this.level = ValidationLevel.VALIDATION_ERROR; } @Override - public ValidatorInfo validatorInfo() { + public ValidatorInfo validationInfo() { return validatorInfo; } - @Override - public ValidationErrorType errorType() { - return this.errorType; - } + @@ -49,19 +42,41 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; JsonValidationError that = (JsonValidationError) o; - return Objects.equals(validatorInfo, that.validatorInfo) && errorType == that.errorType; + return Objects.equals(validatorInfo, that.validatorInfo) && + this.level.equals(that.level) && + this.category.equals(that.category) && + this.message.equals(that.message); } @Override public int hashCode() { - return Objects.hash(validatorInfo, errorType); + return Objects.hash(validatorInfo, level, category, message); } @Override public String toString() { return "JsonValidationError{" + "validatorInfo='" + validatorInfo + '\'' + - ", errorType=" + errorType + + "category='" + category + '\'' + + "message='" + message + '\'' + + ", level=" + level + '}'; } + + + + @Override + public ValidationLevel level() { + return ValidationLevel.VALIDATION_ERROR; + } + + @Override + public String category() { + return this.category; + } + + @Override + public String message() { + return this.message; + } } diff --git a/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaDiseaseValidatorTest.java b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaDiseaseValidatorTest.java index 2d92bb0a..49919310 100644 --- a/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaDiseaseValidatorTest.java +++ b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaDiseaseValidatorTest.java @@ -1,12 +1,13 @@ package org.phenopackets.phenopackettools.validator.jsonschema; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.util.JsonFormat; import org.junit.jupiter.api.Test; -import org.phenopackets.phenopackettools.validator.core.PhenopacketValidatorOld; -import org.phenopackets.phenopackettools.validator.core.ValidationItem; -import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; +import org.phenopackets.phenopackettools.validator.core.ValidationResult; import org.phenopackets.phenopackettools.validator.core.errors.JsonError; import org.phenopackets.phenopackettools.validator.testdatagen.PhenopacketUtil; import org.phenopackets.schema.v2.Phenopacket; @@ -29,7 +30,7 @@ */ public class JsonSchemaDiseaseValidatorTest { - private static final ClasspathJsonSchemaValidatorFactory FACTORY = ClasspathJsonSchemaValidatorFactory.defaultValidators(); + private static final JsonSchemaValidator validator = JsonSchemaValidator.makeGenericJsonValidator(); private static Disease mondoDisease() { @@ -64,26 +65,26 @@ private static Phenopacket phenopacketWithDisease() { private static final Phenopacket phenopacket = phenopacketWithDisease(); @Test - public void testPhenopacketValidity() throws InvalidProtocolBufferException { - PhenopacketValidatorOld validator = FACTORY.getValidatorForType(ValidatorInfo.generic()).get(); + public void testPhenopacketValidity() throws InvalidProtocolBufferException, JsonProcessingException { String json = JsonFormat.printer().print(phenopacket); - List errors = validator.validate(json); + ObjectMapper mapper = new ObjectMapper(); + JsonNode jsonNode = mapper.readTree(json); + List errors = validator.validateJson(jsonNode); assertTrue(errors.isEmpty()); } @Test - public void testLacksId() throws InvalidProtocolBufferException { - PhenopacketValidatorOld validator = FACTORY.getValidatorForType(ValidatorInfo.generic()).get(); + public void testLacksId() throws InvalidProtocolBufferException, JsonProcessingException { // the Phenopacket is not valid if we remove the id Phenopacket p1 = Phenopacket.newBuilder(phenopacket).clearId().build(); String json = JsonFormat.printer().print(p1); -// System.out.println(json); - List errors = validator.validate(json); -// System.out.println(errors); + ObjectMapper mapper = new ObjectMapper(); + JsonNode jsonNode = mapper.readTree(json); + List errors = validator.validateJson(jsonNode); assertEquals(1, errors.size()); - ValidationItem error = errors.get(0); - assertEquals(JsonError.REQUIRED, error.errorType().subcategory()); - assertEquals("$.id: is missing but it is required", error.errorType().message()); + ValidationResult error = errors.get(0); + assertEquals(JsonError.REQUIRED, error.category()); + assertEquals("$.id: is missing but it is required", error.message()); } diff --git a/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidatorTest.java b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidatorTest.java index 7c97ee3b..4b09b57f 100644 --- a/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidatorTest.java +++ b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidatorTest.java @@ -1,11 +1,11 @@ package org.phenopackets.phenopackettools.validator.jsonschema; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import org.phenopackets.phenopackettools.validator.core.ErrorTypeOLD; -import org.phenopackets.phenopackettools.validator.core.PhenopacketValidatorOld; -import org.phenopackets.phenopackettools.validator.core.ValidationItem; -import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; +import org.phenopackets.phenopackettools.validator.core.ValidationResult; import org.phenopackets.phenopackettools.validator.core.errors.JsonError; import org.phenopackets.phenopackettools.validator.testdatagen.RareDiseasePhenopacket; import org.phenopackets.phenopackettools.validator.testdatagen.SimplePhenopacket; @@ -13,6 +13,7 @@ import java.io.File; import java.io.IOException; +import java.nio.file.Files; import java.nio.file.Path; import java.util.List; @@ -21,8 +22,7 @@ import static org.junit.jupiter.api.Assertions.*; public class JsonSchemaValidatorTest { - - private static final ClasspathJsonSchemaValidatorFactory FACTORY = ClasspathJsonSchemaValidatorFactory.defaultValidators(); + private static final JsonSchemaValidator validator = JsonSchemaValidator.makeGenericJsonValidator(); private static final SimplePhenopacket simplePhenopacket = new SimplePhenopacket(); @@ -30,19 +30,22 @@ public class JsonSchemaValidatorTest { @Test public void testValidationOfSimpleValidPhenopacket() throws Exception { - PhenopacketValidatorOld validator = FACTORY.getValidatorForType(ValidatorInfo.generic()).get(); + // PhenopacketValidatorOld validator = FACTORY.getValidatorForType(ValidatorInfo.generic()).get(); Phenopacket phenopacket = simplePhenopacket.getPhenopacket(); String json = JsonFormat.printer().print(phenopacket); - List errors = validator.validate(json); + ObjectMapper mapper = new ObjectMapper(); + JsonNode jsonNode = mapper.readTree(json); + List errors = validator.validateJson(jsonNode); assertTrue(errors.isEmpty()); // the Phenopacket is not valid if we remove the id phenopacket = Phenopacket.newBuilder(phenopacket).clearId().build(); json = JsonFormat.printer().print(phenopacket); - errors = validator.validate(json); + jsonNode = mapper.readTree(json); + errors = validator.validateJson(jsonNode); assertEquals(1, errors.size()); - ValidationItem error = errors.get(0); - assertEquals(JsonError.REQUIRED, error.errorType().subcategory()); - assertEquals("$.id: is missing but it is required", error.errorType().message()); + ValidationResult error = errors.get(0); + assertEquals(JsonError.REQUIRED, error.category()); + assertEquals("$.id: is missing but it is required", error.message()); } /** @@ -50,54 +53,53 @@ public void testValidationOfSimpleValidPhenopacket() throws Exception { * It does not contain an id or a metaData element and thus should fail. */ @Test - public void testValidationOfSimpleInValidPhenopacket() { - PhenopacketValidatorOld validator = FACTORY.getValidatorForType(ValidatorInfo.generic()).get(); + public void testValidationOfSimpleInValidPhenopacket() throws JsonProcessingException { String invalidPhenopacketJson = "{\"disney\" : \"donald\"}"; - List errors = validator.validate(invalidPhenopacketJson); + ObjectMapper mapper = new ObjectMapper(); + JsonNode jsonNode = mapper.readTree(invalidPhenopacketJson); + List errors = validator.validateJson(jsonNode); assertEquals(3, errors.size()); - ValidationItem error = errors.get(0); + ValidationResult error = errors.get(0); // JsonError.CATEGORY is "JSON" - assertEquals(JsonError.CATEGORY, error.errorType().category()); - assertEquals(JsonError.REQUIRED, error.errorType().subcategory()); - assertEquals("$.id: is missing but it is required", error.errorType().message()); + assertEquals(JsonError.REQUIRED, error.category()); + assertEquals("$.id: is missing but it is required", error.message()); error = errors.get(1); - assertEquals(JsonError.CATEGORY, error.errorType().category()); - assertEquals(JsonError.REQUIRED, error.errorType().subcategory()); - assertEquals("$.metaData: is missing but it is required", error.errorType().message()); + assertEquals(JsonError.REQUIRED, error.category()); + assertEquals("$.metaData: is missing but it is required", error.message()); error = errors.get(2); - assertEquals(JsonError.CATEGORY, error.errorType().category()); - assertEquals(JsonError.ADDITIONAL_PROPERTIES, error.errorType().subcategory()); - assertEquals("$.disney: is not defined in the schema and the schema does not allow additional properties", error.errorType().message()); + assertEquals(JsonError.ADDITIONAL_PROPERTIES, error.category()); + assertEquals("$.disney: is not defined in the schema and the schema does not allow additional properties", error.message()); } @Test public void testRareDiseaseBethlemahmValidPhenopacket() throws Exception { - PhenopacketValidatorOld validator = FACTORY.getValidatorForType(ValidatorInfo.rareDiseaseValidation()).get(); - Phenopacket bethlehamMyopathy = rareDiseasePhenopacket.getPhenopacket(); String json = JsonFormat.printer().print(bethlehamMyopathy); - List errors = validator.validate(json); - + ObjectMapper mapper = new ObjectMapper(); + JsonNode jsonNode = mapper.readTree(json); + List errors = validator.validateJson(jsonNode); assertTrue(errors.isEmpty()); } @Test @Disabled // TODO - we should rework the testing strategy to invalidate a valid phenopacket and check that it raises the expected error public void testRareDiseaseBethlemahmInvalidValidPhenopacket() throws IOException { - PhenopacketValidatorOld validator = FACTORY.getValidatorForType(ValidatorInfo.rareDiseaseValidation()).get(); File invalidMyopathyPhenopacket = Path.of("src/test/resources/json/bethlehamMyopathyInvalidExample.json").toFile(); - List validationItems = validator.validate(invalidMyopathyPhenopacket); - for (ValidationItem ve : validationItems) { + String payload = Files.readString(invalidMyopathyPhenopacket.toPath()); + ObjectMapper mapper = new ObjectMapper(); + JsonNode jsonNode = mapper.readTree(payload); + List validationItems = validator.validateJson(jsonNode); + for (ValidationResult ve : validationItems) { System.out.println(ve); } assertEquals(1, validationItems.size()); - ValidationItem validationItem = validationItems.get(0); - assertEquals(ErrorTypeOLD.JSON_REQUIRED, validationItem.errorType()); - // assertEquals("$.phenotypicFeatures: is missing but it is required", validationItem.message()); + ValidationResult validationResult = validationItems.get(0); + assertEquals(JsonError.REQUIRED, validationResult.category()); + assertEquals("$.phenotypicFeatures: is missing but it is required", validationResult.message()); } From 7adffc2fa105fd6b5dc92a823cacc39d596f2152 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Thu, 11 Aug 2022 15:37:17 -0400 Subject: [PATCH 082/155] cleanup --- .../src/main/java/module-info.java | 1 + .../command/ValidateCommand.java | 1 - .../phenopackettools/html/HtmlUtil.java | 392 +++++++++--------- .../core/DefaultValidatorRunner.java | 2 - .../validator/core/errors/JsonError.java | 13 +- .../core/impl/DefaultPhenopacketIngestor.java | 2 - .../jsonschema/JsonSchemaValidator.java | 4 - 7 files changed, 201 insertions(+), 214 deletions(-) diff --git a/phenopacket-tools-builder/src/main/java/module-info.java b/phenopacket-tools-builder/src/main/java/module-info.java index a23bf84f..9ca32aca 100644 --- a/phenopacket-tools-builder/src/main/java/module-info.java +++ b/phenopacket-tools-builder/src/main/java/module-info.java @@ -1,6 +1,7 @@ module org.phenopackets.phenopackettools.builder { requires transitive org.phenopackets.schema; // Required due to `TimestampBuilder`. + //noinspection requires-transitive-automatic requires transitive com.google.protobuf; exports org.phenopackets.phenopackettools.builder; diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ValidateCommand.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ValidateCommand.java index 0848857f..cfddc488 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ValidateCommand.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ValidateCommand.java @@ -2,7 +2,6 @@ import org.phenopackets.phenopackettools.validator.core.ValidationResult; -import org.phenopackets.phenopackettools.validator.core.ValidationWorkflowRunner; import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; import org.phenopackets.phenopackettools.validator.core.DefaultValidatorRunner; import picocli.CommandLine.Command; diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlUtil.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlUtil.java index 213b45d1..ed9c5506 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlUtil.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlUtil.java @@ -22,207 +22,211 @@ public static String header(String phenopacketId) { private static String css() { - return "\n"; + return """ + + """; } public static String htmlTop() { - return "\n" + - "

\n" + - "

Phenopacket-Tools

\n" + - "
\n" + - "
\n"; + return """ + + +
+ """; } public static String htmlBottom() { - return " \n" + - "
\n" + - "\n" + - ""; + return """ + +
+ + """; } diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidatorRunner.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidatorRunner.java index ad3f8094..4e0aa842 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidatorRunner.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidatorRunner.java @@ -3,13 +3,11 @@ import com.fasterxml.jackson.databind.JsonNode; import com.google.protobuf.Message; import org.phenopackets.phenopackettools.validator.core.except.PhenopacketValidatorException; -import org.phenopackets.phenopackettools.validator.core.except.PhenopacketValidatorRuntimeException; import org.phenopackets.phenopackettools.validator.core.impl.DefaultPhenopacketIngestor; import org.phenopackets.phenopackettools.validator.core.impl.Ingestor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; import java.util.ArrayList; diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/JsonError.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/JsonError.java index ddc507a3..ef8ba7ec 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/JsonError.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/JsonError.java @@ -14,24 +14,15 @@ public class JsonError implements ValidationResult { /** Another kind of JSON error. */ public static final String UNKNOWN = "unknown"; - - private final String category; - private final String subcategory; private final String message; public JsonError(String subcategory, String message) { - this.category = CATEGORY; - this.subcategory = subcategory; + this.category = subcategory; this.message = message; } -// @Override -// public String category() { -// return this.category; -// } - @Override public ValidatorInfo validationInfo() { return null; @@ -44,7 +35,7 @@ public ValidationLevel level() { @Override public String category() { - return this.subcategory; + return this.category; } @Override diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/DefaultPhenopacketIngestor.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/DefaultPhenopacketIngestor.java index ff1d47c0..1f2db1a7 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/DefaultPhenopacketIngestor.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/DefaultPhenopacketIngestor.java @@ -1,12 +1,10 @@ package org.phenopackets.phenopackettools.validator.core.impl; -import com.fasterxml.jackson.core.JsonEncoding; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Message; import org.phenopackets.phenopackettools.validator.core.except.PhenopacketValidatorInputException; -import org.phenopackets.phenopackettools.validator.core.except.PhenopacketValidatorRuntimeException; import org.phenopackets.schema.v2.Phenopacket; import java.io.IOException; diff --git a/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidator.java b/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidator.java index 04fcea50..0c3770f5 100644 --- a/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidator.java +++ b/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidator.java @@ -9,20 +9,16 @@ import com.networknt.schema.SpecVersion; import org.phenopackets.phenopackettools.validator.core.PhenopacketValidator; import org.phenopackets.phenopackettools.validator.core.ValidationResult; -import org.phenopackets.phenopackettools.validator.core.ValidationWorkflowRunner; import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; import org.phenopackets.phenopackettools.validator.core.except.PhenopacketValidatorRuntimeException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; -import java.io.IOException; import java.io.InputStream; -import java.nio.charset.Charset; import java.nio.file.Files; import java.util.List; import java.util.Objects; -import java.util.stream.Collectors; public class JsonSchemaValidator implements PhenopacketValidator { From e7a1ab799acd8008bc27a7fe4cf6856468ccd2d7 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Thu, 11 Aug 2022 16:00:18 -0400 Subject: [PATCH 083/155] adding File ingest --- .../core/DefaultValidationRunner.java | 6 ++++++ .../core/DefaultValidatorRunner.java | 19 +++++++++++++++++++ .../core/ValidationWorkflowRunner.java | 3 +++ .../core/impl/DefaultPhenopacketIngestor.java | 5 ++--- 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidationRunner.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidationRunner.java index 9f0d7914..f3d98ae5 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidationRunner.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidationRunner.java @@ -2,6 +2,7 @@ +import java.io.File; import java.io.InputStream; import java.nio.charset.Charset; import java.util.List; @@ -45,5 +46,10 @@ public List validate(String input) { return null; } + @Override + public List validate(File file) { + return null; + } + } diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidatorRunner.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidatorRunner.java index 4e0aa842..573853bc 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidatorRunner.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidatorRunner.java @@ -8,8 +8,11 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.File; +import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; +import java.nio.file.Files; import java.util.ArrayList; import java.util.List; @@ -75,6 +78,22 @@ public List validate(String content) { } } + @Override + public List validate(File file) { + if (file == null) { + return List.of(ValidationResult.inputError("Null file pointer passed")); + } else if (! file.isFile()) { + String msg = String.format("%s (%s) is not a valid File", file.getName(), file.getAbsolutePath()); + return List.of(ValidationResult.inputError(msg)); + } + try { + String payload = Files.readString(file.toPath()); + return validate(payload); + } catch (IOException e) { + return List.of(ValidationResult.inputError(e.getMessage())); + } + } + private List validateImpl(JsonNode jsonNode, Message message) { List results = new ArrayList<>(); diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationWorkflowRunner.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationWorkflowRunner.java index 9cd5d7fd..276f199f 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationWorkflowRunner.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationWorkflowRunner.java @@ -1,5 +1,6 @@ package org.phenopackets.phenopackettools.validator.core; +import java.io.File; import java.io.InputStream; import java.nio.charset.Charset; import java.util.List; @@ -26,6 +27,8 @@ public interface ValidationWorkflowRunner { public List validate(String content); + public List validate(File file); + } diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/DefaultPhenopacketIngestor.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/DefaultPhenopacketIngestor.java index 1f2db1a7..c4a79130 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/DefaultPhenopacketIngestor.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/DefaultPhenopacketIngestor.java @@ -21,11 +21,10 @@ public class DefaultPhenopacketIngestor implements Ingestor { private final Message message; - public DefaultPhenopacketIngestor(InputStream stream) throws PhenopacketValidatorInputException { - byte[] content = null; + byte[] content; try { - content = stream.readAllBytes(); + content = stream.readAllBytes(); ObjectMapper mapper = new ObjectMapper(); this.jsonNode = mapper.readTree(content); } catch (IOException e) { From c43819f131b28b533b95738e28378ba629b54a2a Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Thu, 11 Aug 2022 18:55:46 -0400 Subject: [PATCH 084/155] cleanup --- .../command/ValidateCommand.java | 15 ++--- .../phenopackettools/html/HtmlUtil.java | 21 +++--- .../src/main/java/module-info.java | 1 + .../core/DefaultValidatorRunner.java | 1 + .../ClasspathJsonSchemaValidatorFactory.java | 65 ------------------- 5 files changed, 17 insertions(+), 86 deletions(-) delete mode 100644 phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/ClasspathJsonSchemaValidatorFactory.java diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ValidateCommand.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ValidateCommand.java index cfddc488..8961cdb1 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ValidateCommand.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ValidateCommand.java @@ -1,8 +1,8 @@ package org.phenopackets.phenopackettools.command; +import org.phenopackets.phenopackettools.validator.core.PhenopacketValidator; import org.phenopackets.phenopackettools.validator.core.ValidationResult; -import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; import org.phenopackets.phenopackettools.validator.core.DefaultValidatorRunner; import picocli.CommandLine.Command; import picocli.CommandLine.Option; @@ -12,7 +12,6 @@ import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; -import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; @@ -30,14 +29,12 @@ public class ValidateCommand implements Callable { @Override public Integer call() { - // What type of validation do we run? - List validationTypes = new ArrayList<>(); - validationTypes.add(ValidatorInfo.genericJsonSchema()); // we run this by default + var jsonValidators = List.of(makeGenericJsonValidator()); + DefaultValidatorRunner validatorRunner = new DefaultValidatorRunner(jsonValidators, List.of()); + List messageValidators = List.of(); if (rareHpoConstraints) { - validationTypes.add(ValidatorInfo.rareDiseaseValidation()); + // add HPO validator } - var messageValidators = List.of(makeGenericJsonValidator()); - DefaultValidatorRunner validatorRunner = new DefaultValidatorRunner(messageValidators, List.of()); for (Path phenopacket : phenopackets) { try (InputStream in = Files.newInputStream(phenopacket)) { @@ -48,7 +45,7 @@ public Integer call() { printSeparator(); } else { for (ValidationResult item : validationItems) { - System.out.printf("%s - (%s) %n", fileName, item.category()); + System.out.printf("%s - %s:%s%n ", fileName, item.category(), item.message()); } printSeparator(); } diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlUtil.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlUtil.java index ed9c5506..04865d64 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlUtil.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlUtil.java @@ -212,21 +212,18 @@ private static String css() { public static String htmlTop() { - return """ - - -
- """; + return "\n" + + "
\n" + + "

Phenopacket-Tools

\n" + + "
\n" + + "
\n"; } public static String htmlBottom() { - return """ - -
- - """; + return " \n" + + "
\n" + + "\n" + + ""; } diff --git a/phenopacket-tools-validator-core/src/main/java/module-info.java b/phenopacket-tools-validator-core/src/main/java/module-info.java index 617d1171..11891178 100644 --- a/phenopacket-tools-validator-core/src/main/java/module-info.java +++ b/phenopacket-tools-validator-core/src/main/java/module-info.java @@ -9,6 +9,7 @@ requires org.phenopackets.schema; requires com.fasterxml.jackson.databind; + opens org.phenopackets.phenopackettools.validator.core; exports org.phenopackets.phenopackettools.validator.core.errors; opens org.phenopackets.phenopackettools.validator.core.errors; diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidatorRunner.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidatorRunner.java index 573853bc..6067f2ea 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidatorRunner.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidatorRunner.java @@ -5,6 +5,7 @@ import org.phenopackets.phenopackettools.validator.core.except.PhenopacketValidatorException; import org.phenopackets.phenopackettools.validator.core.impl.DefaultPhenopacketIngestor; import org.phenopackets.phenopackettools.validator.core.impl.Ingestor; +import org.phenopackets.phenopackettools.validator.core.PhenopacketValidator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/ClasspathJsonSchemaValidatorFactory.java b/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/ClasspathJsonSchemaValidatorFactory.java deleted file mode 100644 index fa5bc426..00000000 --- a/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/ClasspathJsonSchemaValidatorFactory.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.phenopackets.phenopackettools.validator.jsonschema; - -import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; -import org.phenopackets.phenopackettools.validator.core.except.PhenopacketValidatorRuntimeException; - -import java.io.InputStream; -import java.util.Map; -import java.util.Objects; - -/** - * Validator factory that uses JSON schema definitions that are bundled within the application (on classpath). - *

- * - * @author Daniel Danis - * @author Peter N Robinson - * /// implements PhenopacketValidatorFactory - */ -@Deprecated(forRemoval = true) -public class ClasspathJsonSchemaValidatorFactory { - - private final Map validatorMap; - - public static ClasspathJsonSchemaValidatorFactory defaultValidators() { - Map validatorMap = makeValidatorMap(); - return new ClasspathJsonSchemaValidatorFactory(validatorMap); - } - - private static Map makeValidatorMap() { - return Map.of( - ValidatorInfo.genericJsonSchema(), makeJsonValidator("/schema/phenopacket-schema-2-0.json", ValidatorInfo.genericJsonSchema()), - ValidatorInfo.rareDiseaseValidation(), makeJsonValidator("/schema/hpo-rare-disease-schema.json", ValidatorInfo.rareDiseaseValidation()) - ); - } - - private static JsonSchemaValidator makeJsonValidator(String schemaPath, ValidatorInfo validationName) { - InputStream inputStream = ClasspathJsonSchemaValidatorFactory.class.getResourceAsStream(schemaPath); - if (inputStream == null) - throw new PhenopacketValidatorRuntimeException("Invalid JSON schema path `" + schemaPath + '`'); - - return JsonSchemaValidator.of(inputStream, validationName); - } - - private ClasspathJsonSchemaValidatorFactory(Map validatorMap) { - this.validatorMap = validatorMap; - } - -// @Override -// public Optional getValidatorForType(ValidatorInfo type) { -// return Optional.ofNullable(validatorMap.get(type)); -// } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - ClasspathJsonSchemaValidatorFactory that = (ClasspathJsonSchemaValidatorFactory) o; - return Objects.equals(validatorMap, that.validatorMap); - } - - @Override - public int hashCode() { - return Objects.hash(validatorMap); - } - -} From b6af12d390280e42d85da1c8d93c12f1d34f08c3 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Thu, 11 Aug 2022 19:31:37 -0400 Subject: [PATCH 085/155] refactoring --- .../command/ValidateCommand.java | 2 +- .../core/impl/DefaultPhenopacketIngestor.java | 20 ++++++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ValidateCommand.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ValidateCommand.java index 8961cdb1..dc94ce3e 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ValidateCommand.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ValidateCommand.java @@ -38,7 +38,7 @@ public Integer call() { for (Path phenopacket : phenopackets) { try (InputStream in = Files.newInputStream(phenopacket)) { - List validationItems = validatorRunner.validate(in); + List validationItems = validatorRunner.validate(phenopacket.toFile()); Path fileName = phenopacket.getFileName(); if (validationItems.isEmpty()) { System.out.printf("%s - OK%n", fileName); diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/DefaultPhenopacketIngestor.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/DefaultPhenopacketIngestor.java index c4a79130..675c99e9 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/DefaultPhenopacketIngestor.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/DefaultPhenopacketIngestor.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Message; +import com.google.protobuf.TextFormat; import org.phenopackets.phenopackettools.validator.core.except.PhenopacketValidatorInputException; import org.phenopackets.schema.v2.Phenopacket; @@ -75,6 +76,17 @@ public DefaultPhenopacketIngestor(byte[] content, Charset charset) throws Phenop } } + public Message fromString(String msg) throws PhenopacketValidatorInputException { + try { + Phenopacket.Builder builder = Phenopacket.newBuilder(); + TextFormat.Parser parser = TextFormat.Parser.newBuilder().build(); + parser.merge(msg, builder); + return builder.build(); + } catch (TextFormat.ParseException e ) { + throw new PhenopacketValidatorInputException("Could not decode Message: " + e.getMessage()); + } + } + public DefaultPhenopacketIngestor(String jsonString) throws PhenopacketValidatorInputException { if (jsonString == null) { throw new PhenopacketValidatorInputException("input (\"String jsonString\" was null"); @@ -85,11 +97,9 @@ public DefaultPhenopacketIngestor(String jsonString) throws PhenopacketValidator } catch (IOException e) { throw new PhenopacketValidatorInputException("Could not read input stream: " + e.getMessage()); } - try { - message = Phenopacket.parseFrom(jsonString.getBytes()); - } catch (InvalidProtocolBufferException e) { - throw new PhenopacketValidatorInputException("Invalid Phenopacket Message: " + e.getMessage()); - } + + message = fromString(jsonString); + } From 343ddf6fab2d93590013eb52fda0add0f4373474 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Fri, 12 Aug 2022 08:25:23 -0400 Subject: [PATCH 086/155] fixing protobuf message import --- .../phenopackettools/html/HtmlOutputter.java | 4 +- .../phenopackettools/html/HtmlUtil.java | 21 +++--- .../converters/v2/IndividualConverter.java | 61 ++++++----------- .../converters/v2/PedigreeConverter.java | 17 ++--- .../validator/core/errors/InputError.java | 13 +--- .../core/impl/DefaultPhenopacketIngestor.java | 64 +++++++++++++++--- .../core/DefaultPhenopacketIngestorTest.java | 67 +++++++++++++++++++ 7 files changed, 165 insertions(+), 82 deletions(-) create mode 100644 phenopacket-tools-validator-core/src/test/java/org/phenopackets/phenopackettools/validator/core/DefaultPhenopacketIngestorTest.java diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlOutputter.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlOutputter.java index b8b6862b..51468c64 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlOutputter.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlOutputter.java @@ -51,8 +51,8 @@ private void endSection(Writer writer) throws IOException { private void wrap(Section section,Writer writer) throws IOException { startSection(writer); switch (section) { - case PROBAND: outputProband(writer); break; - case PHENOTYPICFEATURE: outputPhenotypicFeatures(writer); + case PROBAND -> outputProband(writer); + case PHENOTYPICFEATURE -> outputPhenotypicFeatures(writer); } endSection(writer); } diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlUtil.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlUtil.java index 04865d64..ed9c5506 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlUtil.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/html/HtmlUtil.java @@ -212,18 +212,21 @@ private static String css() { public static String htmlTop() { - return "\n" + - "

\n" + - "

Phenopacket-Tools

\n" + - "
\n" + - "
\n"; + return """ + + +
+ """; } public static String htmlBottom() { - return " \n" + - "
\n" + - "\n" + - ""; + return """ + +
+ + """; } diff --git a/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/IndividualConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/IndividualConverter.java index b78595e3..3a2a9ec2 100644 --- a/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/IndividualConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/IndividualConverter.java @@ -28,49 +28,30 @@ public static Individual toIndividual(org.phenopackets.schema.v1.core.Individual } public static KaryotypicSex toKaryotypicSex(org.phenopackets.schema.v1.core.KaryotypicSex karyotypicSex) { - switch (karyotypicSex) { - case XX: - return KaryotypicSex.XX; - case XY: - return KaryotypicSex.XY; - case XO: - return KaryotypicSex.XO; - case XXY: - return KaryotypicSex.XXY; - case XXX: - return KaryotypicSex.XXX; - case XXYY: - return KaryotypicSex.XXYY; - case XXXY: - return KaryotypicSex.XXXY; - case XXXX: - return KaryotypicSex.XXXX; - case XYY: - return KaryotypicSex.XYY; - case OTHER_KARYOTYPE: - return KaryotypicSex.OTHER_KARYOTYPE; - case UNRECOGNIZED: - return KaryotypicSex.UNRECOGNIZED; - case UNKNOWN_KARYOTYPE: - default: - return KaryotypicSex.UNKNOWN_KARYOTYPE; - } + return switch (karyotypicSex) { + case XX -> KaryotypicSex.XX; + case XY -> KaryotypicSex.XY; + case XO -> KaryotypicSex.XO; + case XXY -> KaryotypicSex.XXY; + case XXX -> KaryotypicSex.XXX; + case XXYY -> KaryotypicSex.XXYY; + case XXXY -> KaryotypicSex.XXXY; + case XXXX -> KaryotypicSex.XXXX; + case XYY -> KaryotypicSex.XYY; + case OTHER_KARYOTYPE -> KaryotypicSex.OTHER_KARYOTYPE; + case UNRECOGNIZED -> KaryotypicSex.UNRECOGNIZED; + case UNKNOWN_KARYOTYPE -> KaryotypicSex.UNKNOWN_KARYOTYPE; + }; } public static Sex toSex(org.phenopackets.schema.v1.core.Sex sex) { - switch (sex) { - case FEMALE: - return Sex.FEMALE; - case MALE: - return Sex.MALE; - case OTHER_SEX: - return Sex.OTHER_SEX; - case UNRECOGNIZED: - return Sex.UNRECOGNIZED; - case UNKNOWN_SEX: - default: - return Sex.UNKNOWN_SEX; - } + return switch (sex) { + case FEMALE -> Sex.FEMALE; + case MALE -> Sex.MALE; + case OTHER_SEX -> Sex.OTHER_SEX; + case UNRECOGNIZED -> Sex.UNRECOGNIZED; + case UNKNOWN_SEX -> Sex.UNKNOWN_SEX; + }; } public static TimeElement toIndividualTimeAtLastEncounter(org.phenopackets.schema.v1.core.Individual v1Individual) { diff --git a/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/PedigreeConverter.java b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/PedigreeConverter.java index fefc12fa..35bf0d2b 100644 --- a/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/PedigreeConverter.java +++ b/phenopacket-tools-converter/src/main/java/org/phenopackets/phenopackettools/converter/converters/v2/PedigreeConverter.java @@ -47,16 +47,11 @@ private static Pedigree.Person toPerson(org.phenopackets.schema.v1.core.Pedigree } private static Pedigree.Person.AffectedStatus toAffectedStatus(org.phenopackets.schema.v1.core.Pedigree.Person.AffectedStatus v1AffectedStatus) { - switch (v1AffectedStatus) { - case UNAFFECTED: - return Pedigree.Person.AffectedStatus.UNAFFECTED; - case AFFECTED: - return Pedigree.Person.AffectedStatus.AFFECTED; - case UNRECOGNIZED: - return Pedigree.Person.AffectedStatus.UNRECOGNIZED; - case MISSING: - default: - return Pedigree.Person.AffectedStatus.MISSING; - } + return switch (v1AffectedStatus) { + case UNAFFECTED -> Pedigree.Person.AffectedStatus.UNAFFECTED; + case AFFECTED -> Pedigree.Person.AffectedStatus.AFFECTED; + case UNRECOGNIZED -> Pedigree.Person.AffectedStatus.UNRECOGNIZED; + case MISSING -> Pedigree.Person.AffectedStatus.MISSING; + }; } } diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/InputError.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/InputError.java index d48bad02..be7686ed 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/InputError.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/InputError.java @@ -4,16 +4,10 @@ import org.phenopackets.phenopackettools.validator.core.ValidationResult; import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; -public class InputError implements ValidationResult { +public record InputError(String message) implements ValidationResult { private static final String VALIDATION_CATEGORY = "input"; - private final String message; - - public InputError(String message) { - this.message = message; - } - @Override public ValidatorInfo validationInfo() { @@ -30,9 +24,4 @@ public String category() { return VALIDATION_CATEGORY; } - @Override - public String message() { - return this.message; - } - } diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/DefaultPhenopacketIngestor.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/DefaultPhenopacketIngestor.java index c4a79130..6494cf82 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/DefaultPhenopacketIngestor.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/DefaultPhenopacketIngestor.java @@ -4,15 +4,22 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Message; +import com.google.protobuf.util.JsonFormat; import org.phenopackets.phenopackettools.validator.core.except.PhenopacketValidatorInputException; import org.phenopackets.schema.v2.Phenopacket; +import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.Arrays; /** - * To do, add Default Cohort Ingestor etc + * Parse a JsonNode object and a Message object from various input formats. This results in + * two standard objects for the actual validation code. + * @author peter.robinson@jax.org */ public class DefaultPhenopacketIngestor implements Ingestor { @@ -23,17 +30,21 @@ public class DefaultPhenopacketIngestor implements Ingestor { public DefaultPhenopacketIngestor(InputStream stream) throws PhenopacketValidatorInputException { byte[] content; + String jsonString; try { - content = stream.readAllBytes(); + jsonString = new String(stream.readAllBytes(), StandardCharsets.UTF_8); + // content = stream.readAllBytes(); ObjectMapper mapper = new ObjectMapper(); - this.jsonNode = mapper.readTree(content); + this.jsonNode = mapper.readTree(jsonString); } catch (IOException e) { throw new PhenopacketValidatorInputException("Could not read input stream: " + e.getMessage()); } // read the protobuf message if possible // if we get here, content is not null; try { - message = Phenopacket.parseFrom(content); + Phenopacket.Builder builder = Phenopacket.newBuilder(); + JsonFormat.parser().merge(jsonString, builder); + message = builder.build(); } catch (InvalidProtocolBufferException e) { throw new PhenopacketValidatorInputException("Invalid Phenopacket Message: " + e.getMessage()); } @@ -43,14 +54,17 @@ public DefaultPhenopacketIngestor(byte[] content) throws PhenopacketValidatorInp if (content == null) { throw new PhenopacketValidatorInputException("input (\"byte[] content\" was null"); } + String jsonText = new String(content); try { ObjectMapper mapper = new ObjectMapper(); - this.jsonNode = mapper.readTree(content); + this.jsonNode = mapper.readTree(jsonText); } catch (IOException e) { throw new PhenopacketValidatorInputException("Could not read input stream: " + e.getMessage()); } try { - message = Phenopacket.parseFrom(content); + Phenopacket.Builder builder = Phenopacket.newBuilder(); + JsonFormat.parser().merge(jsonText, builder); + message = builder.build(); } catch (InvalidProtocolBufferException e) { throw new PhenopacketValidatorInputException("Invalid Phenopacket Message: " + e.getMessage()); } @@ -69,7 +83,9 @@ public DefaultPhenopacketIngestor(byte[] content, Charset charset) throws Phenop throw new PhenopacketValidatorInputException("Could not read input stream: " + e.getMessage()); } try { - message = Phenopacket.parseFrom(content); + Phenopacket.Builder builder = Phenopacket.newBuilder(); + JsonFormat.parser().merge(Arrays.toString(content), builder); + message = builder.build(); } catch (InvalidProtocolBufferException e) { throw new PhenopacketValidatorInputException("Invalid Phenopacket Message: " + e.getMessage()); } @@ -86,7 +102,39 @@ public DefaultPhenopacketIngestor(String jsonString) throws PhenopacketValidator throw new PhenopacketValidatorInputException("Could not read input stream: " + e.getMessage()); } try { - message = Phenopacket.parseFrom(jsonString.getBytes()); + Phenopacket.Builder builder = Phenopacket.newBuilder(); + JsonFormat.parser().merge(jsonString, builder); + message = builder.build(); + } catch (InvalidProtocolBufferException e) { + throw new PhenopacketValidatorInputException("Invalid Phenopacket Message: " + e.getMessage()); + } + } + + public DefaultPhenopacketIngestor(File file) throws PhenopacketValidatorInputException { + if (file == null) { + throw new PhenopacketValidatorInputException("Null file handle passed."); + } else if (! file.isFile()) { + throw new PhenopacketValidatorInputException(String.format("Invalid file path (%s) passed.", + file.getAbsolutePath())); + } + String jsonString; + try { + jsonString = Files.readString(file.toPath()); + + } catch (IOException e) { + throw new PhenopacketValidatorInputException("I/O error while reading " + + file.getName() +": " + e.getMessage()); + } + try { + ObjectMapper mapper = new ObjectMapper(); + this.jsonNode = mapper.readTree(jsonString); + } catch (IOException e) { + throw new PhenopacketValidatorInputException("Could not read input stream: " + e.getMessage()); + } + try { + Phenopacket.Builder builder = Phenopacket.newBuilder(); + JsonFormat.parser().merge(jsonString, builder); + message = builder.build(); } catch (InvalidProtocolBufferException e) { throw new PhenopacketValidatorInputException("Invalid Phenopacket Message: " + e.getMessage()); } diff --git a/phenopacket-tools-validator-core/src/test/java/org/phenopackets/phenopackettools/validator/core/DefaultPhenopacketIngestorTest.java b/phenopacket-tools-validator-core/src/test/java/org/phenopackets/phenopackettools/validator/core/DefaultPhenopacketIngestorTest.java new file mode 100644 index 00000000..3718c6ba --- /dev/null +++ b/phenopacket-tools-validator-core/src/test/java/org/phenopackets/phenopackettools/validator/core/DefaultPhenopacketIngestorTest.java @@ -0,0 +1,67 @@ +package org.phenopackets.phenopackettools.validator.core; + +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.util.JsonFormat; +import org.junit.jupiter.api.Test; +import org.phenopackets.phenopackettools.validator.core.except.PhenopacketValidatorInputException; +import org.phenopackets.schema.v2.Phenopacket; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class DefaultPhenopacketIngestorTest { + + private static final String minimalPhenopacket = """ + { + "id": "arbitrary.id", + "subject": { + "id": "proband A", + "timeAtLastEncounter": { + "age": { + "iso8601duration": "P39Y" + } + }, + "sex": "FEMALE" + }, + "diseases": [{ + "term": { + "id": "MONDO:0007915", + "label": "systemic lupus erythematosus" + }, + "onset": { + "age": { + "iso8601duration": "P39Y" + } + } + }], + "metaData": { + "created": "2021-05-14T10:35:00Z", + "createdBy": "anonymous biocurator", + "resources": [{ + "id": "uberon", + "name": "Uber-anatomy ontology", + "url": "http://purl.obolibrary.org/obo/uberon.owl", + "version": "2021-07-27", + "namespacePrefix": "UBERON", + "iriPrefix": "http://purl.obolibrary.org/obo/UBERON_" + }, { + "id": "ncbitaxon", + "name": "NCBI organismal classification", + "url": "http://purl.obolibrary.org/obo/ncbitaxon.owl", + "version": "2021-06-10", + "namespacePrefix": "NCBITaxon", + "iriPrefix": "http://purl.obolibrary.org/obo/NCBITaxon_" + }], + "phenopacketSchemaVersion": "2.0" + } + }"""; + + + @Test + public void testCtor() throws PhenopacketValidatorInputException, InvalidProtocolBufferException { + var builder = Phenopacket.newBuilder(); + JsonFormat.parser().merge(minimalPhenopacket, builder); + var pp = builder.build(); + assertEquals("arbitrary.id", pp.getId()); + } + +} From c7cf590ce539e4e40235b9e22872986c0acd0953 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Fri, 12 Aug 2022 08:41:55 -0400 Subject: [PATCH 087/155] adding allelic state constants --- .../builders/VariationDescriptorBuilder.java | 10 ++++---- .../builder/constants/AllelicState.java | 24 +++++++++++++++++++ 2 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/AllelicState.java diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariationDescriptorBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariationDescriptorBuilder.java index fe7c631a..4d1379ac 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariationDescriptorBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariationDescriptorBuilder.java @@ -2,6 +2,7 @@ import org.ga4gh.vrs.v1.Variation; import org.ga4gh.vrsatile.v1.*; +import org.phenopackets.phenopackettools.builder.constants.AllelicState; import org.phenopackets.schema.v2.core.OntologyClass; import java.util.List; @@ -99,20 +100,17 @@ public VariationDescriptorBuilder structuralType(OntologyClass structuralType) { } public VariationDescriptorBuilder heterozygous() { - OntologyClass heterozygous = OntologyClassBuilder.ontologyClass("GENO:0000135", "heterozygous"); - builder.setAllelicState(heterozygous); + builder.setAllelicState(AllelicState.heterozygous()); return this; } public VariationDescriptorBuilder homozygous() { - OntologyClass heterozygous = OntologyClassBuilder.ontologyClass("GENO:0000136", "homozygous"); - builder.setAllelicState(heterozygous); + builder.setAllelicState(AllelicState.homozygous()); return this; } public VariationDescriptorBuilder hemizygous() { - OntologyClass heterozygous = OntologyClassBuilder.ontologyClass("GENO:0000134", "hemizygous"); - builder.setAllelicState(heterozygous); + builder.setAllelicState(AllelicState.hemizygous()); return this; } diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/AllelicState.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/AllelicState.java new file mode 100644 index 00000000..68d1845d --- /dev/null +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/constants/AllelicState.java @@ -0,0 +1,24 @@ +package org.phenopackets.phenopackettools.builder.constants; + +import org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder; +import org.phenopackets.schema.v2.core.OntologyClass; + +public class AllelicState { + + private static final OntologyClass HETEROZYGOUS = OntologyClassBuilder.ontologyClass("GENO:0000135", "heterozygous"); + private static final OntologyClass HOMOZYGOUS = OntologyClassBuilder.ontologyClass("GENO:0000136", "homozygous"); + private static final OntologyClass HEMIZYGOUS = OntologyClassBuilder.ontologyClass("GENO:0000134", "hemizygous"); + + + public static OntologyClass heterozygous() { + return HETEROZYGOUS; + } + public static OntologyClass homozygous() { + return HOMOZYGOUS; + } + + public static OntologyClass hemizygous() { + return HEMIZYGOUS; + } + +} From 05d5edfd86f85b660c461fb70a406344a8997dbb Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Fri, 12 Aug 2022 08:51:39 -0400 Subject: [PATCH 088/155] unit test for bad enum --- .../validator/core/errors/JsonError.java | 3 +- .../jsonschema/JsonSchemaValidatorTest.java | 43 +++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/JsonError.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/JsonError.java index ef8ba7ec..465856f7 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/JsonError.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/JsonError.java @@ -6,11 +6,12 @@ public class JsonError implements ValidationResult { - public static final String CATEGORY = "JSON"; /** JSON schema error meaning that the JSON code contained a property not present in the schema. */ public static final String ADDITIONAL_PROPERTIES = "additionalProperties"; /** JSON schema error meaning that the JSON code failed to contain a property required by the schema. */ public static final String REQUIRED = "required"; + /** JSON schema error meaning that a field is used that is not defined in the corresponding enum. */ + public static final String ENUM = "enum"; /** Another kind of JSON error. */ public static final String UNKNOWN = "unknown"; diff --git a/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidatorTest.java b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidatorTest.java index 4b09b57f..295528ca 100644 --- a/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidatorTest.java +++ b/phenopacket-tools-validator-jsonschema/src/test/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidatorTest.java @@ -5,6 +5,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import org.phenopackets.phenopackettools.validator.core.ValidationLevel; import org.phenopackets.phenopackettools.validator.core.ValidationResult; import org.phenopackets.phenopackettools.validator.core.errors.JsonError; import org.phenopackets.phenopackettools.validator.testdatagen.RareDiseasePhenopacket; @@ -84,6 +85,48 @@ public void testRareDiseaseBethlemahmValidPhenopacket() throws Exception { assertTrue(errors.isEmpty()); } + /** + * This line is erroneous because it does not correspond to the enumeration + * "sex": "random text here" + */ + @Test + public void invalidEnum() throws JsonProcessingException { + String invalidJson = """ + { + "id": "id-C", + "subject": { + "id": "proband C", + "timeAtLastEncounter": { + "age": { + "iso8601duration": "P27Y" + } + }, + "sex": "random text here" + }, + "metaData": { + "created": "2021-05-14T10:35:00Z", + "createdBy": "anonymous biocurator", + "resources": [{ + "id": "hp", + "name": "human phenotype ontology", + "url": "http://purl.obolibrary.org/obo/hp.owl", + "version": "2021-08-02", + "namespacePrefix": "HP", + "iriPrefix": "http://purl.obolibrary.org/obo/HP_" + }], + "phenopacketSchemaVersion": "2.0" + } + }"""; + ObjectMapper mapper = new ObjectMapper(); + JsonNode jsonNode = mapper.readTree(invalidJson); + List errors = validator.validateJson(jsonNode); + assertEquals(1, errors.size()); + ValidationResult error = errors.get(0); + assertEquals(JsonError.ENUM, error.category()); + assertEquals("$.subject.sex: does not have a value in the enumeration [UNKNOWN_SEX, FEMALE, MALE]", error.message()); + assertEquals(ValidationLevel.VALIDATION_ERROR, error.level()); + } + @Test @Disabled // TODO - we should rework the testing strategy to invalidate a valid phenopacket and check that it raises the expected error public void testRareDiseaseBethlemahmInvalidValidPhenopacket() throws IOException { From 6fcb9ac3c66213d999a7088dafffd4087e5445ab Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Fri, 12 Aug 2022 08:58:42 -0400 Subject: [PATCH 089/155] Fixing #59 --- .../builder/builders/VariantInterpretationBuilder.java | 2 +- .../builder/builders/VariationDescriptorBuilder.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariantInterpretationBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariantInterpretationBuilder.java index 88ad8da9..335f88e1 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariantInterpretationBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariantInterpretationBuilder.java @@ -7,7 +7,7 @@ public class VariantInterpretationBuilder { - final VariantInterpretation.Builder builder; + final private VariantInterpretation.Builder builder; private VariantInterpretationBuilder(VariationDescriptor descriptor) { builder = VariantInterpretation.newBuilder().setVariationDescriptor(descriptor); diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariationDescriptorBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariationDescriptorBuilder.java index 4d1379ac..869bb098 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariationDescriptorBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/VariationDescriptorBuilder.java @@ -9,7 +9,7 @@ public class VariationDescriptorBuilder { - final VariationDescriptor.Builder builder; + final private VariationDescriptor.Builder builder; /** * Constructor if no identifier is to be used From a0d0c258c67d1abc9569861d58d3731420c96fe6 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Fri, 12 Aug 2022 10:56:58 -0400 Subject: [PATCH 090/155] adding holoprosecephaly example --- .../command/ExamplesCommand.java | 2 +- .../examples/Holoprosencephaly5.java | 112 ++++++++++++++++++ .../examples/Thrombocytopenia2.java | 60 ---------- 3 files changed, 113 insertions(+), 61 deletions(-) create mode 100644 phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Holoprosencephaly5.java delete mode 100644 phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Thrombocytopenia2.java diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java index c522d1a9..a5052787 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java @@ -115,7 +115,7 @@ private int outputAllPhenopackets() { Path outDirectory = createOutdirectoryIfNeeded(outDir); try { output(new BethlehamMyopathy().getPhenopacket(), outDirectory, "bethleham-myopathy"); - output(new Thrombocytopenia2().getPhenopacket(), outDirectory, "thrombocytopenia2"); + output(new Holoprosencephaly5().getPhenopacket(), outDirectory, "holoprosencephaly5"); output(new Marfan().getPhenopacket(), outDirectory, "marfan"); output(new NemalineMyopathyPrenatal().getPhenopacket(), outDirectory, "nemalineMyopathy"); output(new Pseudoexfoliation().getPhenopacket(), outDirectory,"pseudoexfoliation"); diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Holoprosencephaly5.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Holoprosencephaly5.java new file mode 100644 index 00000000..2b41fdf9 --- /dev/null +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Holoprosencephaly5.java @@ -0,0 +1,112 @@ +package org.phenopackets.phenopackettools.examples; + +import org.ga4gh.vrsatile.v1.GeneDescriptor; +import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; +import org.phenopackets.phenopackettools.builder.builders.*; +import org.phenopackets.phenopackettools.builder.constants.Status; +import org.phenopackets.schema.v2.Phenopacket; +import org.phenopackets.schema.v2.core.OntologyClass; +import org.phenopackets.schema.v2.core.TimeElement; + +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; + +/** + * Case report based on Xiong J, et al. + * Case report: a novel mutation in ZIC2 in an infant with microcephaly, holoprosencephaly, and arachnoid cyst. + * Medicine (Baltimore). 2019 Mar;98(10):e14780. + * doi: 10.1097/MD.0000000000014780. PMID: 30855487; PMCID: PMC6417543. + * Note that we add single ventricle and semilobar HPE as congenital because these are only congenital defects + * even if the observation age was the MRI at 9 months + * @author peter.robinson@jax.org + */ +public class Holoprosencephaly5 implements PhenopacketExample { + private static final String PHENOPACKET_ID = "1"; + private static final String INTERPRETATION_ID = "arbitrary interpretation id"; + private static final String PROBAND_ID = "nine-month old infant"; + + private static final TimeElement nineMonths = TimeElements.age("P9M"); + + private static final TimeElement gestationalAge40w = TimeElements.gestationalAge(40); + + private static final OntologyClass holoprosencephaly5 = ontologyClass("OMIM:609637", "Holoprosencephaly 5"); + + private final Phenopacket phenopacket; + + public Holoprosencephaly5() { + var authorAssertion = EvidenceBuilder.authorStatementEvidence("PMID:30855487", "Xiong J, et al., 2019"); + var individual = IndividualBuilder.builder(PROBAND_ID).female().ageAtLastEncounter("P9M").build(); + var metaData = MetaDataBuilder.builder("2021-05-14T10:35:00Z", "anonymous biocurator") + .addResource(Resources.hpoVersion("2021-08-02")) + .addResource(Resources.genoVersion("2020-03-08")) + .addExternalReference(authorAssertion.getReference()) + .build(); + var vcfRecord = VcfRecordBuilder.of("GRCh38", + "NC_000013.11", + 99983133, + "C", + "G"); + var variationDescriptor = + VariationDescriptorBuilder.builder("variant id") + .heterozygous() + .hgvs("NM_007129.3:c.1069C>G") + .geneContext(GeneDescriptor.newBuilder().setSymbol("ZIC2").setValueId("HGNC:12873 ").build()) + .vcfRecord(vcfRecord) + .build(); + var zic2VariantInterpretation = VariantInterpretationBuilder.of(variationDescriptor, Status.pathogenic()); + var genomicInterpretation = + GenomicInterpretationBuilder.builder("genomic interpretation id") + .causative() + .variantInterpretation(zic2VariantInterpretation) + .build(); + var diagnosis = DiagnosisBuilder.builder(holoprosencephaly5).addGenomicInterpretation(genomicInterpretation).build(); + var interpretation = InterpretationBuilder.builder(INTERPRETATION_ID).completed(diagnosis); + var arachnoidCyst = + PhenotypicFeatureBuilder.builder("HP:0100702", "Arachnoid cyst") + .onset(nineMonths) + .addEvidence(authorAssertion) + .build(); + var cerebellarAtrophy = + PhenotypicFeatureBuilder.builder("HP:0001272", "Cerebellar atrophy") + .onset(nineMonths) + .addEvidence(authorAssertion) + .build(); + var gdd = PhenotypicFeatureBuilder.builder("HP:0001263", "Global developmental delay") + .infantileOnset() + .addEvidence(authorAssertion) + .build(); + var hydrocephalus = PhenotypicFeatureBuilder.builder("HP:0000238", "Hydrocephalus") + .onset(gestationalAge40w) + .addEvidence(authorAssertion) + .build(); + var hyperreflexia = PhenotypicFeatureBuilder.builder("HP:0001347", "Hyperreflexia") + .onset(gestationalAge40w) + .addEvidence(authorAssertion) + .build(); + var semilobarHPE = PhenotypicFeatureBuilder.builder("HP:0002507", "Semilobar holoprosencephaly") + .congenitalOnset() + .addEvidence(authorAssertion) + .build(); + var singleVentricle = PhenotypicFeatureBuilder.builder("HP:0001750", "Single ventricle") + .onset(gestationalAge40w) + .addEvidence(authorAssertion) + .build(); + + phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metaData) + .individual(individual) + .addPhenotypicFeature(hydrocephalus) + .addPhenotypicFeature(semilobarHPE) + .addPhenotypicFeature(singleVentricle) + .addPhenotypicFeature(cerebellarAtrophy) + .addPhenotypicFeature(arachnoidCyst) + .addPhenotypicFeature(cerebellarAtrophy) + .addPhenotypicFeature(gdd) + .addPhenotypicFeature(hyperreflexia) + .addInterpretation(interpretation) + .build(); + } + + @Override + public Phenopacket getPhenopacket() { + return phenopacket; + } +} diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Thrombocytopenia2.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Thrombocytopenia2.java deleted file mode 100644 index 234b1f6d..00000000 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Thrombocytopenia2.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.phenopackets.phenopackettools.examples; - -import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; -import org.phenopackets.phenopackettools.builder.builders.*; -import org.phenopackets.phenopackettools.builder.constants.Status; -import org.phenopackets.schema.v2.Phenopacket; - -import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; - -public class Thrombocytopenia2 implements PhenopacketExample { - private static final String PHENOPACKET_ID = "id-C"; - private static final String INTERPRETATION_ID = "arbitrary interpretation id"; - private static final String PROBAND_ID = "family 10 proband"; - - private final Phenopacket phenopacket; - - public Thrombocytopenia2() { - var authorAssertion = EvidenceBuilder.authorStatementEvidence("PMID:21211618", "Mutations in the 5' UTR of ANKRD26, the ankirin repeat domain 26 gene, cause an autosomal-dominant form of inherited thrombocytopenia, THC2"); - var thrombocytopenia2 = ontologyClass("OMIM:188000", "Thrombocytopenia 2"); - var individual = IndividualBuilder.builder(PROBAND_ID).female().ageAtLastEncounter("P20Y").build(); - var metaData = MetaDataBuilder.builder("2021-05-14T10:35:00Z", "anonymous biocurator") - .addResource(Resources.hpoVersion("2021-08-02")) - .addResource(Resources.genoVersion("2020-03-08")) - .addExternalReference(authorAssertion.getReference()) - .build(); - var variationDescriptor = - VariationDescriptorBuilder.builder("variant id") - .heterozygous() - .hgvs("NM_014915.2:c.-128G>A") - .build(); - var col6a1VariantInterpretation = VariantInterpretationBuilder.of(variationDescriptor, Status.pathogenic()); - var genomicInterpretation = - GenomicInterpretationBuilder.builder("genomic interpretation id") - .causative() - .variantInterpretation(col6a1VariantInterpretation) - .build(); - var diagnosis = DiagnosisBuilder.builder(thrombocytopenia2).addGenomicInterpretation(genomicInterpretation).build(); - var interpretation = InterpretationBuilder.builder(INTERPRETATION_ID).completed(diagnosis); - var excludedAbnormalPlateletSize = - PhenotypicFeatureBuilder.builder("HP:0011876", "Abnormal platelet volume") - .excluded() - .addEvidence(authorAssertion) - .build(); - var brusing = - PhenotypicFeatureBuilder.builder("HP:0000978", "Bruising susceptibility") - .addEvidence(authorAssertion) - .build(); - phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metaData) - .individual(individual) - .addPhenotypicFeature(excludedAbnormalPlateletSize) - .addPhenotypicFeature(brusing) - .addInterpretation(interpretation) - .build(); - } - - @Override - public Phenopacket getPhenopacket() { - return phenopacket; - } -} From 88ebd0e2e20a2bf542b7344b52ed4c20826bcc69 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Fri, 12 Aug 2022 11:01:37 -0400 Subject: [PATCH 091/155] fixing Marfan example --- .../java/org/phenopackets/phenopackettools/examples/Marfan.java | 1 + 1 file changed, 1 insertion(+) diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Marfan.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Marfan.java index ddd2aa4a..728aa8f4 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Marfan.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/Marfan.java @@ -37,6 +37,7 @@ public Marfan() { phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metaData) .individual(individual) .addDisease(marfan) + .addPhenotypicFeature(aorticAneurysm) .addMedicalAction(medicalAction) .build(); } From aee0eb79e6756874c29d04ca2cfc0c4b4ec46c31 Mon Sep 17 00:00:00 2001 From: Justin Reese Date: Fri, 12 Aug 2022 11:07:42 -0400 Subject: [PATCH 092/155] Added docs according to Harshad's walkthrough --- docs/_sources/index.rst.txt | 22 + docs/_sources/modules.rst.txt | 6 + .../_sphinx_javascript_frameworks_compat.js | 134 + docs/_static/alabaster.css | 701 + docs/_static/basic.css | 899 ++ docs/_static/custom.css | 1 + docs/_static/doctools.js | 264 + docs/_static/documentation_options.js | 14 + docs/_static/file.png | Bin 0 -> 286 bytes docs/_static/jquery-3.6.0.js | 10881 ++++++++++++++++ docs/_static/jquery.js | 2 + docs/_static/language_data.js | 199 + docs/_static/minus.png | Bin 0 -> 90 bytes docs/_static/plus.png | Bin 0 -> 90 bytes docs/_static/pygments.css | 82 + docs/_static/searchtools.js | 530 + docs/_static/underscore-1.13.1.js | 2042 +++ docs/_static/underscore.js | 6 + docs/genindex.html | 105 + docs/index.html | 124 + docs/modules.html | 112 + docs/objects.inv | Bin 0 -> 285 bytes docs/search.html | 124 + docs/searchindex.js | 1 + sphinx/Makefile | 20 + sphinx/_build/doctrees/environment.pickle | Bin 0 -> 12659 bytes sphinx/_build/doctrees/index.doctree | Bin 0 -> 5060 bytes sphinx/_build/doctrees/modules.doctree | Bin 0 -> 2735 bytes sphinx/_build/html/.buildinfo | 4 + sphinx/_build/html/_sources/index.rst.txt | 22 + sphinx/_build/html/_sources/modules.rst.txt | 6 + .../_sphinx_javascript_frameworks_compat.js | 134 + sphinx/_build/html/_static/alabaster.css | 701 + sphinx/_build/html/_static/basic.css | 899 ++ sphinx/_build/html/_static/custom.css | 1 + sphinx/_build/html/_static/doctools.js | 264 + .../html/_static/documentation_options.js | 14 + sphinx/_build/html/_static/file.png | Bin 0 -> 286 bytes sphinx/_build/html/_static/jquery-3.6.0.js | 10881 ++++++++++++++++ sphinx/_build/html/_static/jquery.js | 2 + sphinx/_build/html/_static/language_data.js | 199 + sphinx/_build/html/_static/minus.png | Bin 0 -> 90 bytes sphinx/_build/html/_static/plus.png | Bin 0 -> 90 bytes sphinx/_build/html/_static/pygments.css | 82 + sphinx/_build/html/_static/searchtools.js | 530 + .../_build/html/_static/underscore-1.13.1.js | 2042 +++ sphinx/_build/html/_static/underscore.js | 6 + sphinx/_build/html/genindex.html | 105 + sphinx/_build/html/index.html | 124 + sphinx/_build/html/modules.html | 112 + sphinx/_build/html/objects.inv | Bin 0 -> 285 bytes sphinx/_build/html/search.html | 124 + sphinx/_build/html/searchindex.js | 1 + sphinx/conf.py | 43 + sphinx/conf.py~ | 41 + sphinx/index.rst | 22 + sphinx/index.rst~ | 20 + sphinx/make.bat | 35 + sphinx/modules.rst | 6 + 59 files changed, 32689 insertions(+) create mode 100644 docs/_sources/index.rst.txt create mode 100644 docs/_sources/modules.rst.txt create mode 100644 docs/_static/_sphinx_javascript_frameworks_compat.js create mode 100644 docs/_static/alabaster.css create mode 100644 docs/_static/basic.css create mode 100644 docs/_static/custom.css create mode 100644 docs/_static/doctools.js create mode 100644 docs/_static/documentation_options.js create mode 100644 docs/_static/file.png create mode 100644 docs/_static/jquery-3.6.0.js create mode 100644 docs/_static/jquery.js create mode 100644 docs/_static/language_data.js create mode 100644 docs/_static/minus.png create mode 100644 docs/_static/plus.png create mode 100644 docs/_static/pygments.css create mode 100644 docs/_static/searchtools.js create mode 100644 docs/_static/underscore-1.13.1.js create mode 100644 docs/_static/underscore.js create mode 100644 docs/genindex.html create mode 100644 docs/index.html create mode 100644 docs/modules.html create mode 100644 docs/objects.inv create mode 100644 docs/search.html create mode 100644 docs/searchindex.js create mode 100644 sphinx/Makefile create mode 100644 sphinx/_build/doctrees/environment.pickle create mode 100644 sphinx/_build/doctrees/index.doctree create mode 100644 sphinx/_build/doctrees/modules.doctree create mode 100644 sphinx/_build/html/.buildinfo create mode 100644 sphinx/_build/html/_sources/index.rst.txt create mode 100644 sphinx/_build/html/_sources/modules.rst.txt create mode 100644 sphinx/_build/html/_static/_sphinx_javascript_frameworks_compat.js create mode 100644 sphinx/_build/html/_static/alabaster.css create mode 100644 sphinx/_build/html/_static/basic.css create mode 100644 sphinx/_build/html/_static/custom.css create mode 100644 sphinx/_build/html/_static/doctools.js create mode 100644 sphinx/_build/html/_static/documentation_options.js create mode 100644 sphinx/_build/html/_static/file.png create mode 100644 sphinx/_build/html/_static/jquery-3.6.0.js create mode 100644 sphinx/_build/html/_static/jquery.js create mode 100644 sphinx/_build/html/_static/language_data.js create mode 100644 sphinx/_build/html/_static/minus.png create mode 100644 sphinx/_build/html/_static/plus.png create mode 100644 sphinx/_build/html/_static/pygments.css create mode 100644 sphinx/_build/html/_static/searchtools.js create mode 100644 sphinx/_build/html/_static/underscore-1.13.1.js create mode 100644 sphinx/_build/html/_static/underscore.js create mode 100644 sphinx/_build/html/genindex.html create mode 100644 sphinx/_build/html/index.html create mode 100644 sphinx/_build/html/modules.html create mode 100644 sphinx/_build/html/objects.inv create mode 100644 sphinx/_build/html/search.html create mode 100644 sphinx/_build/html/searchindex.js create mode 100644 sphinx/conf.py create mode 100644 sphinx/conf.py~ create mode 100644 sphinx/index.rst create mode 100644 sphinx/index.rst~ create mode 100644 sphinx/make.bat create mode 100644 sphinx/modules.rst diff --git a/docs/_sources/index.rst.txt b/docs/_sources/index.rst.txt new file mode 100644 index 00000000..bf2187bd --- /dev/null +++ b/docs/_sources/index.rst.txt @@ -0,0 +1,22 @@ +.. phenopacket-tools documentation master file, created by + sphinx-quickstart on Fri Aug 12 11:03:28 2022. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to phenopacket-tools's documentation! +============================================= + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + static/intro.md + + modules + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/_sources/modules.rst.txt b/docs/_sources/modules.rst.txt new file mode 100644 index 00000000..80f38119 --- /dev/null +++ b/docs/_sources/modules.rst.txt @@ -0,0 +1,6 @@ +phenopacket-tools +================= + +.. toctree:: + :maxdepth: 4 + diff --git a/docs/_static/_sphinx_javascript_frameworks_compat.js b/docs/_static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 00000000..8549469d --- /dev/null +++ b/docs/_static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,134 @@ +/* + * _sphinx_javascript_frameworks_compat.js + * ~~~~~~~~~~ + * + * Compatability shim for jQuery and underscores.js. + * + * WILL BE REMOVED IN Sphinx 6.0 + * xref RemovedInSphinx60Warning + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/docs/_static/alabaster.css b/docs/_static/alabaster.css new file mode 100644 index 00000000..0eddaeb0 --- /dev/null +++ b/docs/_static/alabaster.css @@ -0,0 +1,701 @@ +@import url("basic.css"); + +/* -- page layout ----------------------------------------------------------- */ + +body { + font-family: Georgia, serif; + font-size: 17px; + background-color: #fff; + color: #000; + margin: 0; + padding: 0; +} + + +div.document { + width: 940px; + margin: 30px auto 0 auto; +} + +div.documentwrapper { + float: left; + width: 100%; +} + +div.bodywrapper { + margin: 0 0 0 220px; +} + +div.sphinxsidebar { + width: 220px; + font-size: 14px; + line-height: 1.5; +} + +hr { + border: 1px solid #B1B4B6; +} + +div.body { + background-color: #fff; + color: #3E4349; + padding: 0 30px 0 30px; +} + +div.body > .section { + text-align: left; +} + +div.footer { + width: 940px; + margin: 20px auto 30px auto; + font-size: 14px; + color: #888; + text-align: right; +} + +div.footer a { + color: #888; +} + +p.caption { + font-family: inherit; + font-size: inherit; +} + + +div.relations { + display: none; +} + + +div.sphinxsidebar a { + color: #444; + text-decoration: none; + border-bottom: 1px dotted #999; +} + +div.sphinxsidebar a:hover { + border-bottom: 1px solid #999; +} + +div.sphinxsidebarwrapper { + padding: 18px 10px; +} + +div.sphinxsidebarwrapper p.logo { + padding: 0; + margin: -10px 0 0 0px; + text-align: center; +} + +div.sphinxsidebarwrapper h1.logo { + margin-top: -10px; + text-align: center; + margin-bottom: 5px; + text-align: left; +} + +div.sphinxsidebarwrapper h1.logo-name { + margin-top: 0px; +} + +div.sphinxsidebarwrapper p.blurb { + margin-top: 0; + font-style: normal; +} + +div.sphinxsidebar h3, +div.sphinxsidebar h4 { + font-family: Georgia, serif; + color: #444; + font-size: 24px; + font-weight: normal; + margin: 0 0 5px 0; + padding: 0; +} + +div.sphinxsidebar h4 { + font-size: 20px; +} + +div.sphinxsidebar h3 a { + color: #444; +} + +div.sphinxsidebar p.logo a, +div.sphinxsidebar h3 a, +div.sphinxsidebar p.logo a:hover, +div.sphinxsidebar h3 a:hover { + border: none; +} + +div.sphinxsidebar p { + color: #555; + margin: 10px 0; +} + +div.sphinxsidebar ul { + margin: 10px 0; + padding: 0; + color: #000; +} + +div.sphinxsidebar ul li.toctree-l1 > a { + font-size: 120%; +} + +div.sphinxsidebar ul li.toctree-l2 > a { + font-size: 110%; +} + +div.sphinxsidebar input { + border: 1px solid #CCC; + font-family: Georgia, serif; + font-size: 1em; +} + +div.sphinxsidebar hr { + border: none; + height: 1px; + color: #AAA; + background: #AAA; + + text-align: left; + margin-left: 0; + width: 50%; +} + +div.sphinxsidebar .badge { + border-bottom: none; +} + +div.sphinxsidebar .badge:hover { + border-bottom: none; +} + +/* To address an issue with donation coming after search */ +div.sphinxsidebar h3.donation { + margin-top: 10px; +} + +/* -- body styles ----------------------------------------------------------- */ + +a { + color: #004B6B; + text-decoration: underline; +} + +a:hover { + color: #6D4100; + text-decoration: underline; +} + +div.body h1, +div.body h2, +div.body h3, +div.body h4, +div.body h5, +div.body h6 { + font-family: Georgia, serif; + font-weight: normal; + margin: 30px 0px 10px 0px; + padding: 0; +} + +div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; } +div.body h2 { font-size: 180%; } +div.body h3 { font-size: 150%; } +div.body h4 { font-size: 130%; } +div.body h5 { font-size: 100%; } +div.body h6 { font-size: 100%; } + +a.headerlink { + color: #DDD; + padding: 0 4px; + text-decoration: none; +} + +a.headerlink:hover { + color: #444; + background: #EAEAEA; +} + +div.body p, div.body dd, div.body li { + line-height: 1.4em; +} + +div.admonition { + margin: 20px 0px; + padding: 10px 30px; + background-color: #EEE; + border: 1px solid #CCC; +} + +div.admonition tt.xref, div.admonition code.xref, div.admonition a tt { + background-color: #FBFBFB; + border-bottom: 1px solid #fafafa; +} + +div.admonition p.admonition-title { + font-family: Georgia, serif; + font-weight: normal; + font-size: 24px; + margin: 0 0 10px 0; + padding: 0; + line-height: 1; +} + +div.admonition p.last { + margin-bottom: 0; +} + +div.highlight { + background-color: #fff; +} + +dt:target, .highlight { + background: #FAF3E8; +} + +div.warning { + background-color: #FCC; + border: 1px solid #FAA; +} + +div.danger { + background-color: #FCC; + border: 1px solid #FAA; + -moz-box-shadow: 2px 2px 4px #D52C2C; + -webkit-box-shadow: 2px 2px 4px #D52C2C; + box-shadow: 2px 2px 4px #D52C2C; +} + +div.error { + background-color: #FCC; + border: 1px solid #FAA; + -moz-box-shadow: 2px 2px 4px #D52C2C; + -webkit-box-shadow: 2px 2px 4px #D52C2C; + box-shadow: 2px 2px 4px #D52C2C; +} + +div.caution { + background-color: #FCC; + border: 1px solid #FAA; +} + +div.attention { + background-color: #FCC; + border: 1px solid #FAA; +} + +div.important { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.note { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.tip { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.hint { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.seealso { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.topic { + background-color: #EEE; +} + +p.admonition-title { + display: inline; +} + +p.admonition-title:after { + content: ":"; +} + +pre, tt, code { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; + font-size: 0.9em; +} + +.hll { + background-color: #FFC; + margin: 0 -12px; + padding: 0 12px; + display: block; +} + +img.screenshot { +} + +tt.descname, tt.descclassname, code.descname, code.descclassname { + font-size: 0.95em; +} + +tt.descname, code.descname { + padding-right: 0.08em; +} + +img.screenshot { + -moz-box-shadow: 2px 2px 4px #EEE; + -webkit-box-shadow: 2px 2px 4px #EEE; + box-shadow: 2px 2px 4px #EEE; +} + +table.docutils { + border: 1px solid #888; + -moz-box-shadow: 2px 2px 4px #EEE; + -webkit-box-shadow: 2px 2px 4px #EEE; + box-shadow: 2px 2px 4px #EEE; +} + +table.docutils td, table.docutils th { + border: 1px solid #888; + padding: 0.25em 0.7em; +} + +table.field-list, table.footnote { + border: none; + -moz-box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; +} + +table.footnote { + margin: 15px 0; + width: 100%; + border: 1px solid #EEE; + background: #FDFDFD; + font-size: 0.9em; +} + +table.footnote + table.footnote { + margin-top: -15px; + border-top: none; +} + +table.field-list th { + padding: 0 0.8em 0 0; +} + +table.field-list td { + padding: 0; +} + +table.field-list p { + margin-bottom: 0.8em; +} + +/* Cloned from + * https://github.com/sphinx-doc/sphinx/commit/ef60dbfce09286b20b7385333d63a60321784e68 + */ +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +table.footnote td.label { + width: .1px; + padding: 0.3em 0 0.3em 0.5em; +} + +table.footnote td { + padding: 0.3em 0.5em; +} + +dl { + margin: 0; + padding: 0; +} + +dl dd { + margin-left: 30px; +} + +blockquote { + margin: 0 0 0 30px; + padding: 0; +} + +ul, ol { + /* Matches the 30px from the narrow-screen "li > ul" selector below */ + margin: 10px 0 10px 30px; + padding: 0; +} + +pre { + background: #EEE; + padding: 7px 30px; + margin: 15px 0px; + line-height: 1.3em; +} + +div.viewcode-block:target { + background: #ffd; +} + +dl pre, blockquote pre, li pre { + margin-left: 0; + padding-left: 30px; +} + +tt, code { + background-color: #ecf0f3; + color: #222; + /* padding: 1px 2px; */ +} + +tt.xref, code.xref, a tt { + background-color: #FBFBFB; + border-bottom: 1px solid #fff; +} + +a.reference { + text-decoration: none; + border-bottom: 1px dotted #004B6B; +} + +/* Don't put an underline on images */ +a.image-reference, a.image-reference:hover { + border-bottom: none; +} + +a.reference:hover { + border-bottom: 1px solid #6D4100; +} + +a.footnote-reference { + text-decoration: none; + font-size: 0.7em; + vertical-align: top; + border-bottom: 1px dotted #004B6B; +} + +a.footnote-reference:hover { + border-bottom: 1px solid #6D4100; +} + +a:hover tt, a:hover code { + background: #EEE; +} + + +@media screen and (max-width: 870px) { + + div.sphinxsidebar { + display: none; + } + + div.document { + width: 100%; + + } + + div.documentwrapper { + margin-left: 0; + margin-top: 0; + margin-right: 0; + margin-bottom: 0; + } + + div.bodywrapper { + margin-top: 0; + margin-right: 0; + margin-bottom: 0; + margin-left: 0; + } + + ul { + margin-left: 0; + } + + li > ul { + /* Matches the 30px from the "ul, ol" selector above */ + margin-left: 30px; + } + + .document { + width: auto; + } + + .footer { + width: auto; + } + + .bodywrapper { + margin: 0; + } + + .footer { + width: auto; + } + + .github { + display: none; + } + + + +} + + + +@media screen and (max-width: 875px) { + + body { + margin: 0; + padding: 20px 30px; + } + + div.documentwrapper { + float: none; + background: #fff; + } + + div.sphinxsidebar { + display: block; + float: none; + width: 102.5%; + margin: 50px -30px -20px -30px; + padding: 10px 20px; + background: #333; + color: #FFF; + } + + div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p, + div.sphinxsidebar h3 a { + color: #fff; + } + + div.sphinxsidebar a { + color: #AAA; + } + + div.sphinxsidebar p.logo { + display: none; + } + + div.document { + width: 100%; + margin: 0; + } + + div.footer { + display: none; + } + + div.bodywrapper { + margin: 0; + } + + div.body { + min-height: 0; + padding: 0; + } + + .rtd_doc_footer { + display: none; + } + + .document { + width: auto; + } + + .footer { + width: auto; + } + + .footer { + width: auto; + } + + .github { + display: none; + } +} + + +/* misc. */ + +.revsys-inline { + display: none!important; +} + +/* Make nested-list/multi-paragraph items look better in Releases changelog + * pages. Without this, docutils' magical list fuckery causes inconsistent + * formatting between different release sub-lists. + */ +div#changelog > div.section > ul > li > p:only-child { + margin-bottom: 0; +} + +/* Hide fugly table cell borders in ..bibliography:: directive output */ +table.docutils.citation, table.docutils.citation td, table.docutils.citation th { + border: none; + /* Below needed in some edge cases; if not applied, bottom shadows appear */ + -moz-box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; +} + + +/* relbar */ + +.related { + line-height: 30px; + width: 100%; + font-size: 0.9rem; +} + +.related.top { + border-bottom: 1px solid #EEE; + margin-bottom: 20px; +} + +.related.bottom { + border-top: 1px solid #EEE; +} + +.related ul { + padding: 0; + margin: 0; + list-style: none; +} + +.related li { + display: inline; +} + +nav#rellinks { + float: right; +} + +nav#rellinks li+li:before { + content: "|"; +} + +nav#breadcrumbs li+li:before { + content: "\00BB"; +} + +/* Hide certain items when printing */ +@media print { + div.related { + display: none; + } +} \ No newline at end of file diff --git a/docs/_static/basic.css b/docs/_static/basic.css new file mode 100644 index 00000000..eeb0519a --- /dev/null +++ b/docs/_static/basic.css @@ -0,0 +1,899 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} +a.brackets:before, +span.brackets > a:before{ + content: "["; +} + +a.brackets:after, +span.brackets > a:after { + content: "]"; +} + + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} +dl.footnote > dt, +dl.citation > dt { + float: left; + margin-right: 0.5em; +} + +dl.footnote > dd, +dl.citation > dd { + margin-bottom: 0em; +} + +dl.footnote > dd:after, +dl.citation > dd:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} +dl.field-list > dt:after { + content: ":"; +} + + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/docs/_static/custom.css b/docs/_static/custom.css new file mode 100644 index 00000000..2a924f1d --- /dev/null +++ b/docs/_static/custom.css @@ -0,0 +1 @@ +/* This file intentionally left blank. */ diff --git a/docs/_static/doctools.js b/docs/_static/doctools.js new file mode 100644 index 00000000..c3db08d1 --- /dev/null +++ b/docs/_static/doctools.js @@ -0,0 +1,264 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + parent.insertBefore( + span, + parent.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.highlightSearchWords(); + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords: () => { + const highlight = + new URLSearchParams(window.location.search).get("highlight") || ""; + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + const url = new URL(window.location); + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + const blacklistedElements = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", + ]); + document.addEventListener("keydown", (event) => { + if (blacklistedElements.has(document.activeElement.tagName)) return; // bail for input elements + if (event.altKey || event.ctrlKey || event.metaKey) return; // bail with special keys + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + case "Escape": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.hideSearchWords(); + event.preventDefault(); + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/docs/_static/documentation_options.js b/docs/_static/documentation_options.js new file mode 100644 index 00000000..b57ae3b8 --- /dev/null +++ b/docs/_static/documentation_options.js @@ -0,0 +1,14 @@ +var DOCUMENTATION_OPTIONS = { + URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), + VERSION: '', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/docs/_static/file.png b/docs/_static/file.png new file mode 100644 index 0000000000000000000000000000000000000000..a858a410e4faa62ce324d814e4b816fff83a6fb3 GIT binary patch literal 286 zcmV+(0pb3MP)s`hMrGg#P~ix$^RISR_I47Y|r1 z_CyJOe}D1){SET-^Amu_i71Lt6eYfZjRyw@I6OQAIXXHDfiX^GbOlHe=Ae4>0m)d(f|Me07*qoM6N<$f}vM^LjV8( literal 0 HcmV?d00001 diff --git a/docs/_static/jquery-3.6.0.js b/docs/_static/jquery-3.6.0.js new file mode 100644 index 00000000..fc6c299b --- /dev/null +++ b/docs/_static/jquery-3.6.0.js @@ -0,0 +1,10881 @@ +/*! + * jQuery JavaScript Library v3.6.0 + * https://jquery.com/ + * + * Includes Sizzle.js + * https://sizzlejs.com/ + * + * Copyright OpenJS Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2021-03-02T17:08Z + */ +( function( global, factory ) { + + "use strict"; + + if ( typeof module === "object" && typeof module.exports === "object" ) { + + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common +// enough that all such attempts are guarded in a try block. +"use strict"; + +var arr = []; + +var getProto = Object.getPrototypeOf; + +var slice = arr.slice; + +var flat = arr.flat ? function( array ) { + return arr.flat.call( array ); +} : function( array ) { + return arr.concat.apply( [], array ); +}; + + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var fnToString = hasOwn.toString; + +var ObjectFunctionString = fnToString.call( Object ); + +var support = {}; + +var isFunction = function isFunction( obj ) { + + // Support: Chrome <=57, Firefox <=52 + // In some browsers, typeof returns "function" for HTML elements + // (i.e., `typeof document.createElement( "object" ) === "function"`). + // We don't want to classify *any* DOM node as a function. + // Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5 + // Plus for old WebKit, typeof returns "function" for HTML collections + // (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756) + return typeof obj === "function" && typeof obj.nodeType !== "number" && + typeof obj.item !== "function"; + }; + + +var isWindow = function isWindow( obj ) { + return obj != null && obj === obj.window; + }; + + +var document = window.document; + + + + var preservedScriptAttributes = { + type: true, + src: true, + nonce: true, + noModule: true + }; + + function DOMEval( code, node, doc ) { + doc = doc || document; + + var i, val, + script = doc.createElement( "script" ); + + script.text = code; + if ( node ) { + for ( i in preservedScriptAttributes ) { + + // Support: Firefox 64+, Edge 18+ + // Some browsers don't support the "nonce" property on scripts. + // On the other hand, just using `getAttribute` is not enough as + // the `nonce` attribute is reset to an empty string whenever it + // becomes browsing-context connected. + // See https://github.com/whatwg/html/issues/2369 + // See https://html.spec.whatwg.org/#nonce-attributes + // The `node.getAttribute` check was added for the sake of + // `jQuery.globalEval` so that it can fake a nonce-containing node + // via an object. + val = node[ i ] || node.getAttribute && node.getAttribute( i ); + if ( val ) { + script.setAttribute( i, val ); + } + } + } + doc.head.appendChild( script ).parentNode.removeChild( script ); + } + + +function toType( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; +} +/* global Symbol */ +// Defining this global in .eslintrc.json would create a danger of using the global +// unguarded in another place, it seems safer to define global only for this module + + + +var + version = "3.6.0", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }; + +jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + + // Return all the elements in a clean array + if ( num == null ) { + return slice.call( this ); + } + + // Return just the one element from the set + return num < 0 ? this[ num + this.length ] : this[ num ]; + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + even: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return ( i + 1 ) % 2; + } ) ); + }, + + odd: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return i % 2; + } ) ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + copy = options[ name ]; + + // Prevent Object.prototype pollution + // Prevent never-ending loop + if ( name === "__proto__" || target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = Array.isArray( copy ) ) ) ) { + src = target[ name ]; + + // Ensure proper type for the source value + if ( copyIsArray && !Array.isArray( src ) ) { + clone = []; + } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { + clone = {}; + } else { + clone = src; + } + copyIsArray = false; + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend( { + + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isPlainObject: function( obj ) { + var proto, Ctor; + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if ( !obj || toString.call( obj ) !== "[object Object]" ) { + return false; + } + + proto = getProto( obj ); + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if ( !proto ) { + return true; + } + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; + }, + + isEmptyObject: function( obj ) { + var name; + + for ( name in obj ) { + return false; + } + return true; + }, + + // Evaluates a script in a provided context; falls back to the global one + // if not specified. + globalEval: function( code, options, doc ) { + DOMEval( code, { nonce: options && options.nonce }, doc ); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return flat( ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), + function( _i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); + } ); + +function isArrayLike( obj ) { + + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = toType( obj ); + + if ( isFunction( obj ) || isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.3.6 + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://js.foundation/ + * + * Date: 2021-02-16 + */ +( function( window ) { +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + nonnativeSelectorCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // Instance methods + hasOwn = ( {} ).hasOwnProperty, + arr = [], + pop = arr.pop, + pushNative = arr.push, + push = arr.push, + slice = arr.slice, + + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[ i ] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + + "ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram + identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + + "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + + // "Attribute values must be CSS identifiers [capture 5] + // or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + + whitespace + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + + "*" ), + rdescend = new RegExp( whitespace + "|>" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rhtml = /HTML$/i, + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), + funescape = function( escape, nonHex ) { + var high = "0x" + escape.slice( 1 ) - 0x10000; + + return nonHex ? + + // Strip the backslash prefix from a non-hex escape sequence + nonHex : + + // Replace a hexadecimal escape sequence with the encoded Unicode code point + // Support: IE <=11+ + // For values outside the Basic Multilingual Plane (BMP), manually construct a + // surrogate pair + high < 0 ? + String.fromCharCode( high + 0x10000 ) : + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, + fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }, + + inDisabledFieldset = addCombinator( + function( elem ) { + return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; + }, + { dir: "parentNode", next: "legend" } + ); + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + ( arr = slice.call( preferredDoc.childNodes ) ), + preferredDoc.childNodes + ); + + // Support: Android<4.0 + // Detect silently failing push.apply + // eslint-disable-next-line no-unused-expressions + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + pushNative.apply( target, slice.call( els ) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + + // Can't trust NodeList.length + while ( ( target[ j++ ] = els[ i++ ] ) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + setDocument( context ); + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { + + // ID selector + if ( ( m = match[ 1 ] ) ) { + + // Document context + if ( nodeType === 9 ) { + if ( ( elem = context.getElementById( m ) ) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && ( elem = newContext.getElementById( m ) ) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[ 2 ] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !nonnativeSelectorCache[ selector + " " ] && + ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && + + // Support: IE 8 only + // Exclude object elements + ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { + + newSelector = selector; + newContext = context; + + // qSA considers elements outside a scoping root when evaluating child or + // descendant combinators, which is not what we want. + // In such cases, we work around the behavior by prefixing every selector in the + // list with an ID selector referencing the scope context. + // The technique has to be used as well when a leading combinator is used + // as such selectors are not recognized by querySelectorAll. + // Thanks to Andrew Dupont for this technique. + if ( nodeType === 1 && + ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + + // We can use :scope instead of the ID hack if the browser + // supports it & if we're not changing the context. + if ( newContext !== context || !support.scope ) { + + // Capture the context ID, setting it first if necessary + if ( ( nid = context.getAttribute( "id" ) ) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", ( nid = expando ) ); + } + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + while ( i-- ) { + groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + + toSelector( groups[ i ] ); + } + newSelector = groups.join( "," ); + } + + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + nonnativeSelectorCache( selector, true ); + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return ( cache[ key + " " ] = value ); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created element and returns a boolean result + */ +function assert( fn ) { + var el = document.createElement( "fieldset" ); + + try { + return !!fn( el ); + } catch ( e ) { + return false; + } finally { + + // Remove from its parent by default + if ( el.parentNode ) { + el.parentNode.removeChild( el ); + } + + // release memory in IE + el = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split( "|" ), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[ i ] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + a.sourceIndex - b.sourceIndex; + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( ( cur = cur.nextSibling ) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return ( name === "input" || name === "button" ) && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { + + // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { + + // Only certain elements can match :enabled or :disabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + if ( "form" in elem ) { + + // Check for inherited disabledness on relevant non-disabled elements: + // * listed form-associated elements in a disabled fieldset + // https://html.spec.whatwg.org/multipage/forms.html#category-listed + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled + // * option elements in a disabled optgroup + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled + // All such elements have a "form" property. + if ( elem.parentNode && elem.disabled === false ) { + + // Option elements defer to a parent optgroup if present + if ( "label" in elem ) { + if ( "label" in elem.parentNode ) { + return elem.parentNode.disabled === disabled; + } else { + return elem.disabled === disabled; + } + } + + // Support: IE 6 - 11 + // Use the isDisabled shortcut property to check for disabled fieldset ancestors + return elem.isDisabled === disabled || + + // Where there is no isDisabled, check manually + /* jshint -W018 */ + elem.isDisabled !== !disabled && + inDisabledFieldset( elem ) === disabled; + } + + return elem.disabled === disabled; + + // Try to winnow out elements that can't be disabled before trusting the disabled property. + // Some victims get caught in our net (label, legend, menu, track), but it shouldn't + // even exist on them, let alone have a boolean value. + } else if ( "label" in elem ) { + return elem.disabled === disabled; + } + + // Remaining elements are neither :enabled nor :disabled + return false; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction( function( argument ) { + argument = +argument; + return markFunction( function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ ( j = matchIndexes[ i ] ) ] ) { + seed[ j ] = !( matches[ j ] = seed[ j ] ); + } + } + } ); + } ); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + var namespace = elem && elem.namespaceURI, + docElem = elem && ( elem.ownerDocument || elem ).documentElement; + + // Support: IE <=8 + // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes + // https://bugs.jquery.com/ticket/4833 + return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, subWindow, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9 - 11+, Edge 12 - 18+ + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( preferredDoc != document && + ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { + + // Support: IE 11, Edge + if ( subWindow.addEventListener ) { + subWindow.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( subWindow.attachEvent ) { + subWindow.attachEvent( "onunload", unloadHandler ); + } + } + + // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, + // Safari 4 - 5 only, Opera <=11.6 - 12.x only + // IE/Edge & older browsers don't support the :scope pseudo-class. + // Support: Safari 6.0 only + // Safari 6.0 supports :scope but it's an alias of :root there. + support.scope = assert( function( el ) { + docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); + return typeof el.querySelectorAll !== "undefined" && + !el.querySelectorAll( ":scope fieldset div" ).length; + } ); + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert( function( el ) { + el.className = "i"; + return !el.getAttribute( "className" ); + } ); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert( function( el ) { + el.appendChild( document.createComment( "" ) ); + return !el.getElementsByTagName( "*" ).length; + } ); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programmatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert( function( el ) { + docElem.appendChild( el ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + } ); + + // ID filter and find + if ( support.getById ) { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute( "id" ) === attrId; + }; + }; + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var elem = context.getElementById( id ); + return elem ? [ elem ] : []; + } + }; + } else { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode( "id" ); + return node && node.value === attrId; + }; + }; + + // Support: IE 6 - 7 only + // getElementById is not reliable as a find shortcut + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var node, i, elems, + elem = context.getElementById( id ); + + if ( elem ) { + + // Verify the id attribute + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + + // Fall back on getElementsByName + elems = context.getElementsByName( id ); + i = 0; + while ( ( elem = elems[ i++ ] ) ) { + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + } + } + + return []; + } + }; + } + + // Tag + Expr.find[ "TAG" ] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See https://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { + + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert( function( el ) { + + var input; + + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // https://bugs.jquery.com/ticket/12359 + docElem.appendChild( el ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !el.querySelectorAll( "[selected]" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push( "~=" ); + } + + // Support: IE 11+, Edge 15 - 18+ + // IE 11/Edge don't find elements on a `[name='']` query in some cases. + // Adding a temporary attribute to the document before the selection works + // around the issue. + // Interestingly, IE 10 & older don't seem to have the issue. + input = document.createElement( "input" ); + input.setAttribute( "name", "" ); + el.appendChild( input ); + if ( !el.querySelectorAll( "[name='']" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + + whitespace + "*(?:''|\"\")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !el.querySelectorAll( ":checked" ).length ) { + rbuggyQSA.push( ":checked" ); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibling-combinator selector` fails + if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push( ".#.+[+~]" ); + } + + // Support: Firefox <=3.6 - 5 only + // Old Firefox doesn't throw on a badly-escaped identifier. + el.querySelectorAll( "\\\f" ); + rbuggyQSA.push( "[\\r\\n\\f]" ); + } ); + + assert( function( el ) { + el.innerHTML = "" + + ""; + + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement( "input" ); + input.setAttribute( "type", "hidden" ); + el.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( el.querySelectorAll( "[name=d]" ).length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: IE9-11+ + // IE's :disabled selector does not pick up the children of disabled fieldsets + docElem.appendChild( el ).disabled = true; + if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: Opera 10 - 11 only + // Opera 10-11 does not throw on post-comma invalid pseudos + el.querySelectorAll( "*,:x" ); + rbuggyQSA.push( ",.*:" ); + } ); + } + + if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector ) ) ) ) { + + assert( function( el ) { + + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( el, "*" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( el, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + } ); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + ) ); + } : + function( a, b ) { + if ( b ) { + while ( ( b = b.parentNode ) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { + + // Choose the first element that is related to our preferred document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( a == document || a.ownerDocument == preferredDoc && + contains( preferredDoc, a ) ) { + return -1; + } + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( b == document || b.ownerDocument == preferredDoc && + contains( preferredDoc, b ) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + return a == document ? -1 : + b == document ? 1 : + /* eslint-enable eqeqeq */ + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( ( cur = cur.parentNode ) ) { + ap.unshift( cur ); + } + cur = b; + while ( ( cur = cur.parentNode ) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[ i ] === bp[ i ] ) { + i++; + } + + return i ? + + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[ i ], bp[ i ] ) : + + // Otherwise nodes in our document sort first + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + ap[ i ] == preferredDoc ? -1 : + bp[ i ] == preferredDoc ? 1 : + /* eslint-enable eqeqeq */ + 0; + }; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + setDocument( elem ); + + if ( support.matchesSelector && documentIsHTML && + !nonnativeSelectorCache[ expr + " " ] && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch ( e ) { + nonnativeSelectorCache( expr, true ); + } + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( context.ownerDocument || context ) != document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( elem.ownerDocument || elem ) != document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; +}; + +Sizzle.escape = function( sel ) { + return ( sel + "" ).replace( rcssescape, fcssescape ); +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + + // If no nodeType, this is expected to be an array + while ( ( node = elem[ i++ ] ) ) { + + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[ 1 ] = match[ 1 ].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[ 3 ] = ( match[ 3 ] || match[ 4 ] || + match[ 5 ] || "" ).replace( runescape, funescape ); + + if ( match[ 2 ] === "~=" ) { + match[ 3 ] = " " + match[ 3 ] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[ 1 ] = match[ 1 ].toLowerCase(); + + if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { + + // nth-* requires argument + if ( !match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[ 4 ] = +( match[ 4 ] ? + match[ 5 ] + ( match[ 6 ] || 1 ) : + 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); + match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); + + // other types prohibit arguments + } else if ( match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[ 6 ] && match[ 2 ]; + + if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[ 3 ] ) { + match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + + // Get excess from tokenize (recursively) + ( excess = tokenize( unquoted, true ) ) && + + // advance to the next closing parenthesis + ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { + + // excess is a negative index + match[ 0 ] = match[ 0 ].slice( 0, excess ); + match[ 2 ] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { + return true; + } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + ( pattern = new RegExp( "(^|" + whitespace + + ")" + className + "(" + whitespace + "|$)" ) ) && classCache( + className, function( elem ) { + return pattern.test( + typeof elem.className === "string" && elem.className || + typeof elem.getAttribute !== "undefined" && + elem.getAttribute( "class" ) || + "" + ); + } ); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + /* eslint-disable max-len */ + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + /* eslint-enable max-len */ + + }; + }, + + "CHILD": function( type, what, _argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, _context, xml ) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( ( node = node[ dir ] ) ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + + return false; + } + } + + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + + // Seek `elem` from a previously-cached index + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( ( node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + + // Use previously-cached element index if available + if ( useCache ) { + + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + + // Use the same loop as above to seek `elem` from the start + while ( ( node = ++nodeIndex && node && node[ dir ] || + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || + ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction( function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[ i ] ); + seed[ idx ] = !( matches[ idx ] = matched[ i ] ); + } + } ) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + + // Potentially complex pseudos + "not": markFunction( function( selector ) { + + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction( function( seed, matches, _context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( ( elem = unmatched[ i ] ) ) { + seed[ i ] = !( matches[ i ] = elem ); + } + } + } ) : + function( elem, _context, xml ) { + input[ 0 ] = elem; + matcher( input, null, xml, results ); + + // Don't keep the element (issue #299) + input[ 0 ] = null; + return !results.pop(); + }; + } ), + + "has": markFunction( function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + } ), + + "contains": markFunction( function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; + }; + } ), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + + // lang value must be a valid identifier + if ( !ridentifier.test( lang || "" ) ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( ( elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); + return false; + }; + } ), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && + ( !document.hasFocus || document.hasFocus() ) && + !!( elem.type || elem.href || ~elem.tabIndex ); + }, + + // Boolean properties + "enabled": createDisabledPseudo( false ), + "disabled": createDisabledPseudo( true ), + + "checked": function( elem ) { + + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return ( nodeName === "input" && !!elem.checked ) || + ( nodeName === "option" && !!elem.selected ); + }, + + "selected": function( elem ) { + + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + // eslint-disable-next-line no-unused-expressions + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos[ "empty" ]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( ( attr = elem.getAttribute( "type" ) ) == null || + attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo( function() { + return [ 0 ]; + } ), + + "last": createPositionalPseudo( function( _matchIndexes, length ) { + return [ length - 1 ]; + } ), + + "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + } ), + + "even": createPositionalPseudo( function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "odd": createPositionalPseudo( function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "lt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? + argument + length : + argument > length ? + length : + argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "gt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ) + } +}; + +Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || ( match = rcomma.exec( soFar ) ) ) { + if ( match ) { + + // Don't consume trailing commas as valid + soFar = soFar.slice( match[ 0 ].length ) || soFar; + } + groups.push( ( tokens = [] ) ); + } + + matched = false; + + // Combinators + if ( ( match = rcombinators.exec( soFar ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + + // Cast descendant combinators to space + type: match[ 0 ].replace( rtrim, " " ) + } ); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || + ( match = preFilters[ type ]( match ) ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + type: type, + matches: match + } ); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[ i ].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + skip = combinator.next, + key = skip || dir, + checkNonElements = base && key === "parentNode", + doneName = done++; + + return combinator.first ? + + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + return false; + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, uniqueCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if ( xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || ( elem[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || + ( outerCache[ elem.uniqueID ] = {} ); + + if ( skip && skip === elem.nodeName.toLowerCase() ) { + elem = elem[ dir ] || elem; + } else if ( ( oldCache = uniqueCache[ key ] ) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return ( newCache[ 2 ] = oldCache[ 2 ] ); + } else { + + // Reuse newcache so results back-propagate to previous elements + uniqueCache[ key ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { + return true; + } + } + } + } + } + return false; + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[ i ]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[ 0 ]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[ i ], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( ( elem = unmatched[ i ] ) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction( function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( + selector || "*", + context.nodeType ? [ context ] : context, + [] + ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( ( elem = temp[ i ] ) ) { + matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) ) { + + // Restore matcherIn since elem is not yet a final match + temp.push( ( matcherIn[ i ] = elem ) ); + } + } + postFinder( null, ( matcherOut = [] ), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) && + ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) { + + seed[ temp ] = !( results[ temp ] = elem ); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + } ); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[ 0 ].type ], + implicitRelative = leadingRelative || Expr.relative[ " " ], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + ( checkContext = context ).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { + matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; + } else { + matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[ j ].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens + .slice( 0, i - 1 ) + .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ), + + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), + len = elems.length; + + if ( outermost ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + outermostContext = context == document || context || outermost; + } + + // Add elements passing elementMatchers directly to results + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( !context && elem.ownerDocument != document ) { + setDocument( elem ); + xml = !documentIsHTML; + } + while ( ( matcher = elementMatchers[ j++ ] ) ) { + if ( matcher( elem, context || document, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + + // They will have gone through all possible matchers + if ( ( elem = !matcher && elem ) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + if ( bySet && i !== matchedCount ) { + j = 0; + while ( ( matcher = setMatchers[ j++ ] ) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !( unmatched[ i ] || setMatched[ i ] ) ) { + setMatched[ i ] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[ i ] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( + selector, + matcherFromGroupMatchers( elementMatchers, setMatchers ) + ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( ( selector = compiled.selector || selector ) ); + + results = results || []; + + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) + if ( match.length === 1 ) { + + // Reduce context if the leading compound selector is an ID + tokens = match[ 0 ] = match[ 0 ].slice( 0 ); + if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && + context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { + + context = ( Expr.find[ "ID" ]( token.matches[ 0 ] + .replace( runescape, funescape ), context ) || [] )[ 0 ]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[ i ]; + + // Abort if we hit a combinator + if ( Expr.relative[ ( type = token.type ) ] ) { + break; + } + if ( ( find = Expr.find[ type ] ) ) { + + // Search, expanding context for leading sibling combinators + if ( ( seed = find( + token.matches[ 0 ].replace( runescape, funescape ), + rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || + context + ) ) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert( function( el ) { + + // Should return 1, but returns 4 (following) + return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; +} ); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert( function( el ) { + el.innerHTML = ""; + return el.firstChild.getAttribute( "href" ) === "#"; +} ) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + } ); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert( function( el ) { + el.innerHTML = ""; + el.firstChild.setAttribute( "value", "" ); + return el.firstChild.getAttribute( "value" ) === ""; +} ) ) { + addHandle( "value", function( elem, _name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + } ); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert( function( el ) { + return el.getAttribute( "disabled" ) == null; +} ) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; + } + } ); +} + +return Sizzle; + +} )( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; + +// Deprecated +jQuery.expr[ ":" ] = jQuery.expr.pseudos; +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; +jQuery.escapeSelector = Sizzle.escape; + + + + +var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; +}; + + +var siblings = function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; +}; + + +var rneedsContext = jQuery.expr.match.needsContext; + + + +function nodeName( elem, name ) { + + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + +} +var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); + + + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + return !!qualifier.call( elem, i, elem ) !== not; + } ); + } + + // Single element + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + } ); + } + + // Arraylike of elements (jQuery, arguments, Array) + if ( typeof qualifier !== "string" ) { + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) > -1 ) !== not; + } ); + } + + // Filtered directly for both simple and complex selectors + return jQuery.filter( qualifier, elements, not ); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + if ( elems.length === 1 && elem.nodeType === 1 ) { + return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; + } + + return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + } ) ); +}; + +jQuery.fn.extend( { + find: function( selector ) { + var i, ret, + len = this.length, + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + } ) ); + } + + ret = this.pushStack( [] ); + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + return len > 1 ? jQuery.uniqueSort( ret ) : ret; + }, + filter: function( selector ) { + return this.pushStack( winnow( this, selector || [], false ) ); + }, + not: function( selector ) { + return this.pushStack( winnow( this, selector || [], true ) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +} ); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + // Shortcut simple #id case for speed + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, + + init = jQuery.fn.init = function( selector, context, root ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[ 0 ] === "<" && + selector[ selector.length - 1 ] === ">" && + selector.length >= 3 ) { + + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && ( match[ 1 ] || !context ) ) { + + // HANDLE: $(html) -> $(array) + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; + + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[ 1 ], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + + // Properties of context are called as methods if possible + if ( isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[ 2 ] ); + + if ( elem ) { + + // Inject the element directly into the jQuery object + this[ 0 ] = elem; + this.length = 1; + } + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || root ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this[ 0 ] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( isFunction( selector ) ) { + return root.ready !== undefined ? + root.ready( selector ) : + + // Execute immediately if ready is not present + selector( jQuery ); + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend( { + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter( function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[ i ] ) ) { + return true; + } + } + } ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + targets = typeof selectors !== "string" && jQuery( selectors ); + + // Positional selectors never match, since there's no _selection_ context + if ( !rneedsContext.test( selectors ) ) { + for ( ; i < l; i++ ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + + // Always skip document fragments + if ( cur.nodeType < 11 && ( targets ? + targets.index( cur ) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector( cur, selectors ) ) ) { + + matched.push( cur ); + break; + } + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); + }, + + // Determine the position of an element within the set + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // Index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.uniqueSort( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + } +} ); + +function sibling( cur, dir ) { + while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} + return cur; +} + +jQuery.each( { + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, _i, until ) { + return dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, _i, until ) { + return dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, _i, until ) { + return dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return siblings( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return siblings( elem.firstChild ); + }, + contents: function( elem ) { + if ( elem.contentDocument != null && + + // Support: IE 11+ + // elements with no `data` attribute has an object + // `contentDocument` with a `null` prototype. + getProto( elem.contentDocument ) ) { + + return elem.contentDocument; + } + + // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only + // Treat the template element as a regular one in browsers that + // don't support it. + if ( nodeName( elem, "template" ) ) { + elem = elem.content || elem; + } + + return jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.uniqueSort( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +} ); +var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); + + + +// Convert String-formatted options into Object-formatted ones +function createOptions( options ) { + var object = {}; + jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { + object[ flag ] = true; + } ); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + createOptions( options ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + + // Last fire value for non-forgettable lists + memory, + + // Flag to know if list was already fired + fired, + + // Flag to prevent firing + locked, + + // Actual callback list + list = [], + + // Queue of execution data for repeatable lists + queue = [], + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + + // Fire callbacks + fire = function() { + + // Enforce single-firing + locked = locked || options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { + + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } + } + } + + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } + + firing = false; + + // Clean up if we're done firing for good + if ( locked ) { + + // Keep an empty list if we have data for future add calls + if ( memory ) { + list = []; + + // Otherwise, this object is spent + } else { + list = ""; + } + } + }, + + // Actual Callbacks object + self = { + + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } + + ( function add( args ) { + jQuery.each( args, function( _, arg ) { + if ( isFunction( arg ) ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && toType( arg ) !== "string" ) { + + // Inspect recursively + add( arg ); + } + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); + } + } + return this; + }, + + // Remove a callback from the list + remove: function() { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + + // Handle firing indexes + if ( index <= firingIndex ) { + firingIndex--; + } + } + } ); + return this; + }, + + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? + jQuery.inArray( fn, list ) > -1 : + list.length > 0; + }, + + // Remove all callbacks from the list + empty: function() { + if ( list ) { + list = []; + } + return this; + }, + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = []; + list = memory = ""; + return this; + }, + disabled: function() { + return !list; + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = queue = []; + if ( !memory && !firing ) { + list = memory = ""; + } + return this; + }, + locked: function() { + return !!locked; + }, + + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( !locked ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + queue.push( args ); + if ( !firing ) { + fire(); + } + } + return this; + }, + + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +function Identity( v ) { + return v; +} +function Thrower( ex ) { + throw ex; +} + +function adoptValue( value, resolve, reject, noValue ) { + var method; + + try { + + // Check for promise aspect first to privilege synchronous behavior + if ( value && isFunction( ( method = value.promise ) ) ) { + method.call( value ).done( resolve ).fail( reject ); + + // Other thenables + } else if ( value && isFunction( ( method = value.then ) ) ) { + method.call( value, resolve, reject ); + + // Other non-thenables + } else { + + // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: + // * false: [ value ].slice( 0 ) => resolve( value ) + // * true: [ value ].slice( 1 ) => resolve() + resolve.apply( undefined, [ value ].slice( noValue ) ); + } + + // For Promises/A+, convert exceptions into rejections + // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in + // Deferred#then to conditionally suppress rejection. + } catch ( value ) { + + // Support: Android 4.0 only + // Strict mode functions invoked without .call/.apply get global-object context + reject.apply( undefined, [ value ] ); + } +} + +jQuery.extend( { + + Deferred: function( func ) { + var tuples = [ + + // action, add listener, callbacks, + // ... .then handlers, argument index, [final state] + [ "notify", "progress", jQuery.Callbacks( "memory" ), + jQuery.Callbacks( "memory" ), 2 ], + [ "resolve", "done", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 0, "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 1, "rejected" ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + "catch": function( fn ) { + return promise.then( null, fn ); + }, + + // Keep pipe for back-compat + pipe: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( _i, tuple ) { + + // Map tuples (progress, done, fail) to arguments (done, fail, progress) + var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; + + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + // deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && isFunction( returned.promise ) ) { + returned.promise() + .progress( newDefer.notify ) + .done( newDefer.resolve ) + .fail( newDefer.reject ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + }, + then: function( onFulfilled, onRejected, onProgress ) { + var maxDepth = 0; + function resolve( depth, deferred, handler, special ) { + return function() { + var that = this, + args = arguments, + mightThrow = function() { + var returned, then; + + // Support: Promises/A+ section 2.3.3.3.3 + // https://promisesaplus.com/#point-59 + // Ignore double-resolution attempts + if ( depth < maxDepth ) { + return; + } + + returned = handler.apply( that, args ); + + // Support: Promises/A+ section 2.3.1 + // https://promisesaplus.com/#point-48 + if ( returned === deferred.promise() ) { + throw new TypeError( "Thenable self-resolution" ); + } + + // Support: Promises/A+ sections 2.3.3.1, 3.5 + // https://promisesaplus.com/#point-54 + // https://promisesaplus.com/#point-75 + // Retrieve `then` only once + then = returned && + + // Support: Promises/A+ section 2.3.4 + // https://promisesaplus.com/#point-64 + // Only check objects and functions for thenability + ( typeof returned === "object" || + typeof returned === "function" ) && + returned.then; + + // Handle a returned thenable + if ( isFunction( then ) ) { + + // Special processors (notify) just wait for resolution + if ( special ) { + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ) + ); + + // Normal processors (resolve) also hook into progress + } else { + + // ...and disregard older resolution values + maxDepth++; + + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ), + resolve( maxDepth, deferred, Identity, + deferred.notifyWith ) + ); + } + + // Handle all other returned values + } else { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Identity ) { + that = undefined; + args = [ returned ]; + } + + // Process the value(s) + // Default process is resolve + ( special || deferred.resolveWith )( that, args ); + } + }, + + // Only normal processors (resolve) catch and reject exceptions + process = special ? + mightThrow : + function() { + try { + mightThrow(); + } catch ( e ) { + + if ( jQuery.Deferred.exceptionHook ) { + jQuery.Deferred.exceptionHook( e, + process.stackTrace ); + } + + // Support: Promises/A+ section 2.3.3.3.4.1 + // https://promisesaplus.com/#point-61 + // Ignore post-resolution exceptions + if ( depth + 1 >= maxDepth ) { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Thrower ) { + that = undefined; + args = [ e ]; + } + + deferred.rejectWith( that, args ); + } + } + }; + + // Support: Promises/A+ section 2.3.3.3.1 + // https://promisesaplus.com/#point-57 + // Re-resolve promises immediately to dodge false rejection from + // subsequent errors + if ( depth ) { + process(); + } else { + + // Call an optional hook to record the stack, in case of exception + // since it's otherwise lost when execution goes async + if ( jQuery.Deferred.getStackHook ) { + process.stackTrace = jQuery.Deferred.getStackHook(); + } + window.setTimeout( process ); + } + }; + } + + return jQuery.Deferred( function( newDefer ) { + + // progress_handlers.add( ... ) + tuples[ 0 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onProgress ) ? + onProgress : + Identity, + newDefer.notifyWith + ) + ); + + // fulfilled_handlers.add( ... ) + tuples[ 1 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onFulfilled ) ? + onFulfilled : + Identity + ) + ); + + // rejected_handlers.add( ... ) + tuples[ 2 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onRejected ) ? + onRejected : + Thrower + ) + ); + } ).promise(); + }, + + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 5 ]; + + // promise.progress = list.add + // promise.done = list.add + // promise.fail = list.add + promise[ tuple[ 1 ] ] = list.add; + + // Handle state + if ( stateString ) { + list.add( + function() { + + // state = "resolved" (i.e., fulfilled) + // state = "rejected" + state = stateString; + }, + + // rejected_callbacks.disable + // fulfilled_callbacks.disable + tuples[ 3 - i ][ 2 ].disable, + + // rejected_handlers.disable + // fulfilled_handlers.disable + tuples[ 3 - i ][ 3 ].disable, + + // progress_callbacks.lock + tuples[ 0 ][ 2 ].lock, + + // progress_handlers.lock + tuples[ 0 ][ 3 ].lock + ); + } + + // progress_handlers.fire + // fulfilled_handlers.fire + // rejected_handlers.fire + list.add( tuple[ 3 ].fire ); + + // deferred.notify = function() { deferred.notifyWith(...) } + // deferred.resolve = function() { deferred.resolveWith(...) } + // deferred.reject = function() { deferred.rejectWith(...) } + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); + return this; + }; + + // deferred.notifyWith = list.fireWith + // deferred.resolveWith = list.fireWith + // deferred.rejectWith = list.fireWith + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( singleValue ) { + var + + // count of uncompleted subordinates + remaining = arguments.length, + + // count of unprocessed arguments + i = remaining, + + // subordinate fulfillment data + resolveContexts = Array( i ), + resolveValues = slice.call( arguments ), + + // the primary Deferred + primary = jQuery.Deferred(), + + // subordinate callback factory + updateFunc = function( i ) { + return function( value ) { + resolveContexts[ i ] = this; + resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( !( --remaining ) ) { + primary.resolveWith( resolveContexts, resolveValues ); + } + }; + }; + + // Single- and empty arguments are adopted like Promise.resolve + if ( remaining <= 1 ) { + adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject, + !remaining ); + + // Use .then() to unwrap secondary thenables (cf. gh-3000) + if ( primary.state() === "pending" || + isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { + + return primary.then(); + } + } + + // Multiple arguments are aggregated like Promise.all array elements + while ( i-- ) { + adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject ); + } + + return primary.promise(); + } +} ); + + +// These usually indicate a programmer mistake during development, +// warn about them ASAP rather than swallowing them by default. +var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; + +jQuery.Deferred.exceptionHook = function( error, stack ) { + + // Support: IE 8 - 9 only + // Console exists when dev tools are open, which can happen at any time + if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { + window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); + } +}; + + + + +jQuery.readyException = function( error ) { + window.setTimeout( function() { + throw error; + } ); +}; + + + + +// The deferred used on DOM ready +var readyList = jQuery.Deferred(); + +jQuery.fn.ready = function( fn ) { + + readyList + .then( fn ) + + // Wrap jQuery.readyException in a function so that the lookup + // happens at the time of error handling instead of callback + // registration. + .catch( function( error ) { + jQuery.readyException( error ); + } ); + + return this; +}; + +jQuery.extend( { + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + } +} ); + +jQuery.ready.then = readyList.then; + +// The ready event handler and self cleanup method +function completed() { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + jQuery.ready(); +} + +// Catch cases where $(document).ready() is called +// after the browser event has already occurred. +// Support: IE <=9 - 10 only +// Older IE sometimes signals "interactive" too soon +if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); + +} else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); +} + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( toType( key ) === "object" ) { + chainable = true; + for ( i in key ) { + access( elems, fn, i, key[ i ], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, _key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); + } + } + } + + if ( chainable ) { + return elems; + } + + // Gets + if ( bulk ) { + return fn.call( elems ); + } + + return len ? fn( elems[ 0 ], key ) : emptyGet; +}; + + +// Matches dashed string for camelizing +var rmsPrefix = /^-ms-/, + rdashAlpha = /-([a-z])/g; + +// Used by camelCase as callback to replace() +function fcamelCase( _all, letter ) { + return letter.toUpperCase(); +} + +// Convert dashed to camelCase; used by the css and data modules +// Support: IE <=9 - 11, Edge 12 - 15 +// Microsoft forgot to hump their vendor prefix (#9572) +function camelCase( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); +} +var acceptData = function( owner ) { + + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + + + +function Data() { + this.expando = jQuery.expando + Data.uid++; +} + +Data.uid = 1; + +Data.prototype = { + + cache: function( owner ) { + + // Check if the owner object already has a cache + var value = owner[ this.expando ]; + + // If not, create one + if ( !value ) { + value = {}; + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( acceptData( owner ) ) { + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty( owner, this.expando, { + value: value, + configurable: true + } ); + } + } + } + + return value; + }, + set: function( owner, data, value ) { + var prop, + cache = this.cache( owner ); + + // Handle: [ owner, key, value ] args + // Always use camelCase key (gh-2257) + if ( typeof data === "string" ) { + cache[ camelCase( data ) ] = value; + + // Handle: [ owner, { properties } ] args + } else { + + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ camelCase( prop ) ] = data[ prop ]; + } + } + return cache; + }, + get: function( owner, key ) { + return key === undefined ? + this.cache( owner ) : + + // Always use camelCase key (gh-2257) + owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; + }, + access: function( owner, key, value ) { + + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ( ( key && typeof key === "string" ) && value === undefined ) ) { + + return this.get( owner, key ); + } + + // When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, + cache = owner[ this.expando ]; + + if ( cache === undefined ) { + return; + } + + if ( key !== undefined ) { + + // Support array or space separated string of keys + if ( Array.isArray( key ) ) { + + // If key is an array of keys... + // We always set camelCase keys, so remove that. + key = key.map( camelCase ); + } else { + key = camelCase( key ); + + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + key = key in cache ? + [ key ] : + ( key.match( rnothtmlwhite ) || [] ); + } + + i = key.length; + + while ( i-- ) { + delete cache[ key[ i ] ]; + } + } + + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + + // Support: Chrome <=35 - 45 + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) + if ( owner.nodeType ) { + owner[ this.expando ] = undefined; + } else { + delete owner[ this.expando ]; + } + } + }, + hasData: function( owner ) { + var cache = owner[ this.expando ]; + return cache !== undefined && !jQuery.isEmptyObject( cache ); + } +}; +var dataPriv = new Data(); + +var dataUser = new Data(); + + + +// Implementation Summary +// +// 1. Enforce API surface and semantic compatibility with 1.9.x branch +// 2. Improve the module's maintainability by reducing the storage +// paths to a single mechanism. +// 3. Use the same single mechanism to support "private" and "user" data. +// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) +// 5. Avoid exposing implementation details on user objects (eg. expando properties) +// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /[A-Z]/g; + +function getData( data ) { + if ( data === "true" ) { + return true; + } + + if ( data === "false" ) { + return false; + } + + if ( data === "null" ) { + return null; + } + + // Only convert to a number if it doesn't change the string + if ( data === +data + "" ) { + return +data; + } + + if ( rbrace.test( data ) ) { + return JSON.parse( data ); + } + + return data; +} + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = getData( data ); + } catch ( e ) {} + + // Make sure we set the data so it isn't changed later + dataUser.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend( { + hasData: function( elem ) { + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return dataUser.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + dataUser.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to dataPriv methods, these can be deprecated. + _data: function( elem, name, data ) { + return dataPriv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + dataPriv.remove( elem, name ); + } +} ); + +jQuery.fn.extend( { + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = dataUser.get( elem ); + + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE 11 only + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = camelCase( name.slice( 5 ) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + dataPriv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + dataUser.set( this, key ); + } ); + } + + return access( this, function( value ) { + var data; + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + + // Attempt to get data from the cache + // The key will always be camelCased in Data + data = dataUser.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, key ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each( function() { + + // We always store the camelCased key + dataUser.set( this, key, value ); + } ); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each( function() { + dataUser.remove( this, key ); + } ); + } +} ); + + +jQuery.extend( { + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = dataPriv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || Array.isArray( data ) ) { + queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + dataPriv.remove( elem, [ type + "queue", key ] ); + } ) + } ); + } +} ); + +jQuery.fn.extend( { + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[ 0 ], type ); + } + + return data === undefined ? + this : + this.each( function() { + var queue = jQuery.queue( this, type, data ); + + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + } ); + }, + dequeue: function( type ) { + return this.each( function() { + jQuery.dequeue( this, type ); + } ); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +} ); +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var documentElement = document.documentElement; + + + + var isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ); + }, + composed = { composed: true }; + + // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only + // Check attachment across shadow DOM boundaries when possible (gh-3504) + // Support: iOS 10.0-10.2 only + // Early iOS 10 versions support `attachShadow` but not `getRootNode`, + // leading to errors. We need to check for `getRootNode`. + if ( documentElement.getRootNode ) { + isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ) || + elem.getRootNode( composed ) === elem.ownerDocument; + }; + } +var isHiddenWithinTree = function( elem, el ) { + + // isHiddenWithinTree might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + + // Inline style trumps all + return elem.style.display === "none" || + elem.style.display === "" && + + // Otherwise, check computed style + // Support: Firefox <=43 - 45 + // Disconnected elements can have computed display: none, so first confirm that elem is + // in the document. + isAttached( elem ) && + + jQuery.css( elem, "display" ) === "none"; + }; + + + +function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, scale, + maxIterations = 20, + currentValue = tween ? + function() { + return tween.cur(); + } : + function() { + return jQuery.css( elem, prop, "" ); + }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = elem.nodeType && + ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Support: Firefox <=54 + // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) + initial = initial / 2; + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + while ( maxIterations-- ) { + + // Evaluate and update our best guess (doubling guesses that zero out). + // Finish if the scale equals or crosses 1 (making the old*new product non-positive). + jQuery.style( elem, prop, initialInUnit + unit ); + if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { + maxIterations = 0; + } + initialInUnit = initialInUnit / scale; + + } + + initialInUnit = initialInUnit * 2; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; +} + + +var defaultDisplayMap = {}; + +function getDefaultDisplay( elem ) { + var temp, + doc = elem.ownerDocument, + nodeName = elem.nodeName, + display = defaultDisplayMap[ nodeName ]; + + if ( display ) { + return display; + } + + temp = doc.body.appendChild( doc.createElement( nodeName ) ); + display = jQuery.css( temp, "display" ); + + temp.parentNode.removeChild( temp ); + + if ( display === "none" ) { + display = "block"; + } + defaultDisplayMap[ nodeName ] = display; + + return display; +} + +function showHide( elements, show ) { + var display, elem, + values = [], + index = 0, + length = elements.length; + + // Determine new display value for elements that need to change + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + display = elem.style.display; + if ( show ) { + + // Since we force visibility upon cascade-hidden elements, an immediate (and slow) + // check is required in this first loop unless we have a nonempty display value (either + // inline or about-to-be-restored) + if ( display === "none" ) { + values[ index ] = dataPriv.get( elem, "display" ) || null; + if ( !values[ index ] ) { + elem.style.display = ""; + } + } + if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { + values[ index ] = getDefaultDisplay( elem ); + } + } else { + if ( display !== "none" ) { + values[ index ] = "none"; + + // Remember what we're overwriting + dataPriv.set( elem, "display", display ); + } + } + } + + // Set the display of the elements in a second loop to avoid constant reflow + for ( index = 0; index < length; index++ ) { + if ( values[ index ] != null ) { + elements[ index ].style.display = values[ index ]; + } + } + + return elements; +} + +jQuery.fn.extend( { + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each( function() { + if ( isHiddenWithinTree( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + } ); + } +} ); +var rcheckableType = ( /^(?:checkbox|radio)$/i ); + +var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); + +var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); + + + +( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Android 4.0 - 4.3 only + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Android <=4.1 only + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE <=11 only + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + + // Support: IE <=9 only + // IE <=9 replaces "; + support.option = !!div.lastChild; +} )(); + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting
or other required elements. + thead: [ 1, "
").append(head).append("
", "
" ], + col: [ 2, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + _default: [ 0, "", "" ] +}; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// Support: IE <=9 only +if ( !support.option ) { + wrapMap.optgroup = wrapMap.option = [ 1, "" ]; +} + + +function getAll( context, tag ) { + + // Support: IE <=9 - 11 only + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret; + + if ( typeof context.getElementsByTagName !== "undefined" ) { + ret = context.getElementsByTagName( tag || "*" ); + + } else if ( typeof context.querySelectorAll !== "undefined" ) { + ret = context.querySelectorAll( tag || "*" ); + + } else { + ret = []; + } + + if ( tag === undefined || tag && nodeName( context, tag ) ) { + return jQuery.merge( [ context ], ret ); + } + + return ret; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|&#?\w+;/; + +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, attached, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( toType( elem ) === "object" ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + attached = isAttached( elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( attached ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; +} + + +var rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +// Support: IE <=9 - 11+ +// focus() and blur() are asynchronous, except when they are no-op. +// So expect focus to be synchronous when the element is already active, +// and blur to be synchronous when the element is not already active. +// (focus and blur are always synchronous in other supported browsers, +// this just defines when we can count on it). +function expectSync( elem, type ) { + return ( elem === safeActiveElement() ) === ( type === "focus" ); +} + +// Support: IE <=9 only +// Accessing document.activeElement can throw unexpectedly +// https://bugs.jquery.com/ticket/13393 +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( elem ); + + // Only attach events to objects that accept data + if ( !acceptData( elem ) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Ensure that invalid selectors throw exceptions at attach time + // Evaluate against documentElement in case elem is a non-element node (e.g., document) + if ( selector ) { + jQuery.find.matchesSelector( documentElement, selector ); + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = Object.create( null ); + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); + } + }, + + dispatch: function( nativeEvent ) { + + var i, j, ret, matched, handleObj, handlerQueue, + args = new Array( arguments.length ), + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( nativeEvent ), + + handlers = ( + dataPriv.get( this, "events" ) || Object.create( null ) + )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + + for ( i = 1; i < arguments.length; i++ ) { + args[ i ] = arguments[ i ]; + } + + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // If the event is namespaced, then each handler is only invoked if it is + // specially universal or its namespaces are a superset of the event's. + if ( !event.rnamespace || handleObj.namespace === false || + event.rnamespace.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, handleObj, sel, matchedHandlers, matchedSelectors, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + if ( delegateCount && + + // Support: IE <=9 + // Black-hole SVG instance trees (trac-13180) + cur.nodeType && + + // Support: Firefox <=42 + // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) + // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click + // Support: IE 11 only + // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) + !( event.type === "click" && event.button >= 1 ) ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { + matchedHandlers = []; + matchedSelectors = {}; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matchedSelectors[ sel ] === undefined ) { + matchedSelectors[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) > -1 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matchedSelectors[ sel ] ) { + matchedHandlers.push( handleObj ); + } + } + if ( matchedHandlers.length ) { + handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); + } + } + } + } + + // Add the remaining (directly-bound) handlers + cur = this; + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); + } + + return handlerQueue; + }, + + addProp: function( name, hook ) { + Object.defineProperty( jQuery.Event.prototype, name, { + enumerable: true, + configurable: true, + + get: isFunction( hook ) ? + function() { + if ( this.originalEvent ) { + return hook( this.originalEvent ); + } + } : + function() { + if ( this.originalEvent ) { + return this.originalEvent[ name ]; + } + }, + + set: function( value ) { + Object.defineProperty( this, name, { + enumerable: true, + configurable: true, + writable: true, + value: value + } ); + } + } ); + }, + + fix: function( originalEvent ) { + return originalEvent[ jQuery.expando ] ? + originalEvent : + new jQuery.Event( originalEvent ); + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + click: { + + // Utilize native event to ensure correct state for checkable inputs + setup: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Claim the first handler + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + // dataPriv.set( el, "click", ... ) + leverageNative( el, "click", returnTrue ); + } + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Force setup before triggering a click + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + leverageNative( el, "click" ); + } + + // Return non-false to allow normal event-path propagation + return true; + }, + + // For cross-browser consistency, suppress native .click() on links + // Also prevent it if we're currently inside a leveraged native-event stack + _default: function( event ) { + var target = event.target; + return rcheckableType.test( target.type ) && + target.click && nodeName( target, "input" ) && + dataPriv.get( target, "click" ) || + nodeName( target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + } +}; + +// Ensure the presence of an event listener that handles manually-triggered +// synthetic events by interrupting progress until reinvoked in response to +// *native* events that it fires directly, ensuring that state changes have +// already occurred before other listeners are invoked. +function leverageNative( el, type, expectSync ) { + + // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add + if ( !expectSync ) { + if ( dataPriv.get( el, type ) === undefined ) { + jQuery.event.add( el, type, returnTrue ); + } + return; + } + + // Register the controller as a special universal handler for all event namespaces + dataPriv.set( el, type, false ); + jQuery.event.add( el, type, { + namespace: false, + handler: function( event ) { + var notAsync, result, + saved = dataPriv.get( this, type ); + + if ( ( event.isTrigger & 1 ) && this[ type ] ) { + + // Interrupt processing of the outer synthetic .trigger()ed event + // Saved data should be false in such cases, but might be a leftover capture object + // from an async native handler (gh-4350) + if ( !saved.length ) { + + // Store arguments for use when handling the inner native event + // There will always be at least one argument (an event object), so this array + // will not be confused with a leftover capture object. + saved = slice.call( arguments ); + dataPriv.set( this, type, saved ); + + // Trigger the native event and capture its result + // Support: IE <=9 - 11+ + // focus() and blur() are asynchronous + notAsync = expectSync( this, type ); + this[ type ](); + result = dataPriv.get( this, type ); + if ( saved !== result || notAsync ) { + dataPriv.set( this, type, false ); + } else { + result = {}; + } + if ( saved !== result ) { + + // Cancel the outer synthetic event + event.stopImmediatePropagation(); + event.preventDefault(); + + // Support: Chrome 86+ + // In Chrome, if an element having a focusout handler is blurred by + // clicking outside of it, it invokes the handler synchronously. If + // that handler calls `.remove()` on the element, the data is cleared, + // leaving `result` undefined. We need to guard against this. + return result && result.value; + } + + // If this is an inner synthetic event for an event with a bubbling surrogate + // (focus or blur), assume that the surrogate already propagated from triggering the + // native event and prevent that from happening again here. + // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the + // bubbling surrogate propagates *after* the non-bubbling base), but that seems + // less bad than duplication. + } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { + event.stopPropagation(); + } + + // If this is a native event triggered above, everything is now in order + // Fire an inner synthetic event with the original arguments + } else if ( saved.length ) { + + // ...and capture the result + dataPriv.set( this, type, { + value: jQuery.event.trigger( + + // Support: IE <=9 - 11+ + // Extend with the prototype to reset the above stopImmediatePropagation() + jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), + saved.slice( 1 ), + this + ) + } ); + + // Abort handling of the native event + event.stopImmediatePropagation(); + } + } + } ); +} + +jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } +}; + +jQuery.Event = function( src, props ) { + + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: Android <=2.3 only + src.returnValue === false ? + returnTrue : + returnFalse; + + // Create target properties + // Support: Safari <=6 - 7 only + // Target should not be a text node (#504, #13143) + this.target = ( src.target && src.target.nodeType === 3 ) ? + src.target.parentNode : + src.target; + + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || Date.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + isSimulated: false, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && !this.isSimulated ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Includes all common event props including KeyEvent and MouseEvent specific props +jQuery.each( { + altKey: true, + bubbles: true, + cancelable: true, + changedTouches: true, + ctrlKey: true, + detail: true, + eventPhase: true, + metaKey: true, + pageX: true, + pageY: true, + shiftKey: true, + view: true, + "char": true, + code: true, + charCode: true, + key: true, + keyCode: true, + button: true, + buttons: true, + clientX: true, + clientY: true, + offsetX: true, + offsetY: true, + pointerId: true, + pointerType: true, + screenX: true, + screenY: true, + targetTouches: true, + toElement: true, + touches: true, + which: true +}, jQuery.event.addProp ); + +jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { + jQuery.event.special[ type ] = { + + // Utilize native event if possible so blur/focus sequence is correct + setup: function() { + + // Claim the first handler + // dataPriv.set( this, "focus", ... ) + // dataPriv.set( this, "blur", ... ) + leverageNative( this, type, expectSync ); + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function() { + + // Force setup before trigger + leverageNative( this, type ); + + // Return non-false to allow normal event-path propagation + return true; + }, + + // Suppress native focus or blur as it's already being fired + // in leverageNative. + _default: function() { + return true; + }, + + delegateType: delegateType + }; +} ); + +// Create mouseenter/leave events using mouseover/out and event-time checks +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +} ); + +jQuery.fn.extend( { + + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + } +} ); + + +var + + // Support: IE <=10 - 11, Edge 12 - 13 only + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /\s*$/g; + +// Prefer a tbody over its parent table for containing new rows +function manipulationTarget( elem, content ) { + if ( nodeName( elem, "table" ) && + nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + + return jQuery( elem ).children( "tbody" )[ 0 ] || elem; + } + + return elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { + elem.type = elem.type.slice( 5 ); + } else { + elem.removeAttribute( "type" ); + } + + return elem; +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.get( src ); + events = pdataOld.events; + + if ( events ) { + dataPriv.remove( dest, "handle events" ); + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + dataUser.set( dest, udataCur ); + } +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = flat( args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + valueIsFunction = isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( valueIsFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( valueIsFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl && !node.noModule ) { + jQuery._evalUrl( node.src, { + nonce: node.nonce || node.getAttribute( "nonce" ) + }, doc ); + } + } else { + DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); + } + } + } + } + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && isAttached( node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html; + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = isAttached( elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; + + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } + } + } + } +} ); + +jQuery.fn.extend( { + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } +} ); + +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: Android <=4.0 only, PhantomJS 1 only + // .get() because push.apply(_, arraylike) throws on ancient WebKit + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +} ); +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + +var getStyles = function( elem ) { + + // Support: IE <=11 only, Firefox <=30 (#15098, #14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + var view = elem.ownerDocument.defaultView; + + if ( !view || !view.opener ) { + view = window; + } + + return view.getComputedStyle( elem ); + }; + +var swap = function( elem, options, callback ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.call( elem ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + +var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); + + + +( function() { + + // Executing both pixelPosition & boxSizingReliable tests require only one layout + // so they're executed at the same time to save the second computation. + function computeStyleTests() { + + // This is a singleton, we need to execute it only once + if ( !div ) { + return; + } + + container.style.cssText = "position:absolute;left:-11111px;width:60px;" + + "margin-top:1px;padding:0;border:0"; + div.style.cssText = + "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + + "margin:auto;border:1px;padding:1px;" + + "width:60%;top:1%"; + documentElement.appendChild( container ).appendChild( div ); + + var divStyle = window.getComputedStyle( div ); + pixelPositionVal = divStyle.top !== "1%"; + + // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 + reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; + + // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 + // Some styles come back with percentage values, even though they shouldn't + div.style.right = "60%"; + pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; + + // Support: IE 9 - 11 only + // Detect misreporting of content dimensions for box-sizing:border-box elements + boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; + + // Support: IE 9 only + // Detect overflow:scroll screwiness (gh-3699) + // Support: Chrome <=64 + // Don't get tricked when zoom affects offsetWidth (gh-4029) + div.style.position = "absolute"; + scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; + + documentElement.removeChild( container ); + + // Nullify the div so it wouldn't be stored in the memory and + // it will also be a sign that checks already performed + div = null; + } + + function roundPixelMeasures( measure ) { + return Math.round( parseFloat( measure ) ); + } + + var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, + reliableTrDimensionsVal, reliableMarginLeftVal, + container = document.createElement( "div" ), + div = document.createElement( "div" ); + + // Finish early in limited (non-browser) environments + if ( !div.style ) { + return; + } + + // Support: IE <=9 - 11 only + // Style of cloned element affects source element cloned (#8908) + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + jQuery.extend( support, { + boxSizingReliable: function() { + computeStyleTests(); + return boxSizingReliableVal; + }, + pixelBoxStyles: function() { + computeStyleTests(); + return pixelBoxStylesVal; + }, + pixelPosition: function() { + computeStyleTests(); + return pixelPositionVal; + }, + reliableMarginLeft: function() { + computeStyleTests(); + return reliableMarginLeftVal; + }, + scrollboxSize: function() { + computeStyleTests(); + return scrollboxSizeVal; + }, + + // Support: IE 9 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Behavior in IE 9 is more subtle than in newer versions & it passes + // some versions of this test; make sure not to make it pass there! + // + // Support: Firefox 70+ + // Only Firefox includes border widths + // in computed dimensions. (gh-4529) + reliableTrDimensions: function() { + var table, tr, trChild, trStyle; + if ( reliableTrDimensionsVal == null ) { + table = document.createElement( "table" ); + tr = document.createElement( "tr" ); + trChild = document.createElement( "div" ); + + table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate"; + tr.style.cssText = "border:1px solid"; + + // Support: Chrome 86+ + // Height set through cssText does not get applied. + // Computed height then comes back as 0. + tr.style.height = "1px"; + trChild.style.height = "9px"; + + // Support: Android 8 Chrome 86+ + // In our bodyBackground.html iframe, + // display for all div elements is set to "inline", + // which causes a problem only in Android 8 Chrome 86. + // Ensuring the div is display: block + // gets around this issue. + trChild.style.display = "block"; + + documentElement + .appendChild( table ) + .appendChild( tr ) + .appendChild( trChild ); + + trStyle = window.getComputedStyle( tr ); + reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) + + parseInt( trStyle.borderTopWidth, 10 ) + + parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight; + + documentElement.removeChild( table ); + } + return reliableTrDimensionsVal; + } + } ); +} )(); + + +function curCSS( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + + // Support: Firefox 51+ + // Retrieving style before computed somehow + // fixes an issue with getting wrong values + // on detached elements + style = elem.style; + + computed = computed || getStyles( elem ); + + // getPropertyValue is needed for: + // .css('filter') (IE 9 only, #12537) + // .css('--customProperty) (#3144) + if ( computed ) { + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !isAttached( elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Android Browser returns percentage for some values, + // but width seems to be reliably pixels. + // This is against the CSSOM draft spec: + // https://drafts.csswg.org/cssom/#resolved-values + if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret !== undefined ? + + // Support: IE <=9 - 11 only + // IE returns zIndex value as an integer. + ret + "" : + ret; +} + + +function addGetHookIf( conditionFn, hookFn ) { + + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + if ( conditionFn() ) { + + // Hook not needed (or it's not possible to use it due + // to missing dependency), remove it. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + return ( this.get = hookFn ).apply( this, arguments ); + } + }; +} + + +var cssPrefixes = [ "Webkit", "Moz", "ms" ], + emptyStyle = document.createElement( "div" ).style, + vendorProps = {}; + +// Return a vendor-prefixed property or undefined +function vendorPropName( name ) { + + // Check for vendor prefixed names + var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in emptyStyle ) { + return name; + } + } +} + +// Return a potentially-mapped jQuery.cssProps or vendor prefixed property +function finalPropName( name ) { + var final = jQuery.cssProps[ name ] || vendorProps[ name ]; + + if ( final ) { + return final; + } + if ( name in emptyStyle ) { + return name; + } + return vendorProps[ name ] = vendorPropName( name ) || name; +} + + +var + + // Swappable if display is none or starts with table + // except "table", "table-cell", or "table-caption" + // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rcustomProp = /^--/, + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }; + +function setPositiveNumber( _elem, value, subtract ) { + + // Any relative (+/-) values have already been + // normalized at this point + var matches = rcssNum.exec( value ); + return matches ? + + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : + value; +} + +function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { + var i = dimension === "width" ? 1 : 0, + extra = 0, + delta = 0; + + // Adjustment may not be necessary + if ( box === ( isBorderBox ? "border" : "content" ) ) { + return 0; + } + + for ( ; i < 4; i += 2 ) { + + // Both box models exclude margin + if ( box === "margin" ) { + delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); + } + + // If we get here with a content-box, we're seeking "padding" or "border" or "margin" + if ( !isBorderBox ) { + + // Add padding + delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // For "border" or "margin", add border + if ( box !== "padding" ) { + delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + + // But still keep track of it otherwise + } else { + extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + + // If we get here with a border-box (content + padding + border), we're seeking "content" or + // "padding" or "margin" + } else { + + // For "content", subtract padding + if ( box === "content" ) { + delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // For "content" or "padding", subtract border + if ( box !== "margin" ) { + delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + // Account for positive content-box scroll gutter when requested by providing computedVal + if ( !isBorderBox && computedVal >= 0 ) { + + // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border + // Assuming integer scroll gutter, subtract the rest and round down + delta += Math.max( 0, Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + computedVal - + delta - + extra - + 0.5 + + // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter + // Use an explicit zero to avoid NaN (gh-3964) + ) ) || 0; + } + + return delta; +} + +function getWidthOrHeight( elem, dimension, extra ) { + + // Start with computed style + var styles = getStyles( elem ), + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). + // Fake content-box until we know it's needed to know the true value. + boxSizingNeeded = !support.boxSizingReliable() || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + valueIsBorderBox = isBorderBox, + + val = curCSS( elem, dimension, styles ), + offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); + + // Support: Firefox <=54 + // Return a confounding non-pixel value or feign ignorance, as appropriate. + if ( rnumnonpx.test( val ) ) { + if ( !extra ) { + return val; + } + val = "auto"; + } + + + // Support: IE 9 - 11 only + // Use offsetWidth/offsetHeight for when box sizing is unreliable. + // In those cases, the computed value can be trusted to be border-box. + if ( ( !support.boxSizingReliable() && isBorderBox || + + // Support: IE 10 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Interestingly, in some cases IE 9 doesn't suffer from this issue. + !support.reliableTrDimensions() && nodeName( elem, "tr" ) || + + // Fall back to offsetWidth/offsetHeight when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + val === "auto" || + + // Support: Android <=4.1 - 4.3 only + // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) + !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && + + // Make sure the element is visible & connected + elem.getClientRects().length ) { + + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // Where available, offsetWidth/offsetHeight approximate border box dimensions. + // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the + // retrieved value as a content box dimension. + valueIsBorderBox = offsetProp in elem; + if ( valueIsBorderBox ) { + val = elem[ offsetProp ]; + } + } + + // Normalize "" and auto + val = parseFloat( val ) || 0; + + // Adjust for the element's box model + return ( val + + boxModelAdjustment( + elem, + dimension, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles, + + // Provide the current computed size to request scroll gutter calculation (gh-3589) + val + ) + ) + "px"; +} + +jQuery.extend( { + + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "animationIterationCount": true, + "columnCount": true, + "fillOpacity": true, + "flexGrow": true, + "flexShrink": true, + "fontWeight": true, + "gridArea": true, + "gridColumn": true, + "gridColumnEnd": true, + "gridColumnStart": true, + "gridRow": true, + "gridRowEnd": true, + "gridRowStart": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: {}, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ), + style = elem.style; + + // Make sure that we're working with the right name. We don't + // want to query the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Gets hook for the prefixed version, then unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // Convert "+=" or "-=" to relative numbers (#7345) + if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { + value = adjustCSS( elem, name, ret ); + + // Fixes bug #9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set (#7116) + if ( value == null || value !== value ) { + return; + } + + // If a number was passed in, add the unit (except for certain CSS properties) + // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append + // "px" to a few hardcoded values. + if ( type === "number" && !isCustomProp ) { + value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); + } + + // background-* props affect original clone's values + if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !( "set" in hooks ) || + ( value = hooks.set( elem, value, extra ) ) !== undefined ) { + + if ( isCustomProp ) { + style.setProperty( name, value ); + } else { + style[ name ] = value; + } + } + + } else { + + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && + ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { + + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var val, num, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ); + + // Make sure that we're working with the right name. We don't + // want to modify the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Try prefixed name followed by the unprefixed name + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + // Convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Make numeric if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || isFinite( num ) ? num || 0 : val; + } + + return val; + } +} ); + +jQuery.each( [ "height", "width" ], function( _i, dimension ) { + jQuery.cssHooks[ dimension ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + + // Certain elements can have dimension info if we invisibly show them + // but it must have a current display style that would benefit + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && + + // Support: Safari 8+ + // Table columns in Safari have non-zero offsetWidth & zero + // getBoundingClientRect().width unless display is changed. + // Support: IE <=11 only + // Running getBoundingClientRect on a disconnected node + // in IE throws an error. + ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? + swap( elem, cssShow, function() { + return getWidthOrHeight( elem, dimension, extra ); + } ) : + getWidthOrHeight( elem, dimension, extra ); + } + }, + + set: function( elem, value, extra ) { + var matches, + styles = getStyles( elem ), + + // Only read styles.position if the test has a chance to fail + // to avoid forcing a reflow. + scrollboxSizeBuggy = !support.scrollboxSize() && + styles.position === "absolute", + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) + boxSizingNeeded = scrollboxSizeBuggy || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + subtract = extra ? + boxModelAdjustment( + elem, + dimension, + extra, + isBorderBox, + styles + ) : + 0; + + // Account for unreliable border-box dimensions by comparing offset* to computed and + // faking a content-box to get border and padding (gh-3699) + if ( isBorderBox && scrollboxSizeBuggy ) { + subtract -= Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + parseFloat( styles[ dimension ] ) - + boxModelAdjustment( elem, dimension, "border", false, styles ) - + 0.5 + ); + } + + // Convert to pixels if value adjustment is needed + if ( subtract && ( matches = rcssNum.exec( value ) ) && + ( matches[ 3 ] || "px" ) !== "px" ) { + + elem.style[ dimension ] = value; + value = jQuery.css( elem, dimension ); + } + + return setPositiveNumber( elem, value, subtract ); + } + }; +} ); + +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, + function( elem, computed ) { + if ( computed ) { + return ( parseFloat( curCSS( elem, "marginLeft" ) ) || + elem.getBoundingClientRect().left - + swap( elem, { marginLeft: 0 }, function() { + return elem.getBoundingClientRect().left; + } ) + ) + "px"; + } + } +); + +// These hooks are used by animate to expand properties +jQuery.each( { + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, + + // Assumes a single number if not a string + parts = typeof value === "string" ? value.split( " " ) : [ value ]; + + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( prefix !== "margin" ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +} ); + +jQuery.fn.extend( { + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( Array.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + } +} ); + + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || jQuery.easing._default; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + // Use a property on the element directly when it is not a DOM element, + // or when there is no matching style property that exists. + if ( tween.elem.nodeType !== 1 || + tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { + return tween.elem[ tween.prop ]; + } + + // Passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails. + // Simple values such as "10px" are parsed to Float; + // complex values such as "rotate(1rad)" are returned as-is. + result = jQuery.css( tween.elem, tween.prop, "" ); + + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + + // Use step hook for back compat. + // Use cssHook if its there. + // Use .style if available and use plain properties where available. + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.nodeType === 1 && ( + jQuery.cssHooks[ tween.prop ] || + tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Support: IE <=9 only +// Panic based approach to setting things on disconnected nodes +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + }, + _default: "swing" +}; + +jQuery.fx = Tween.prototype.init; + +// Back compat <1.8 extension point +jQuery.fx.step = {}; + + + + +var + fxNow, inProgress, + rfxtypes = /^(?:toggle|show|hide)$/, + rrun = /queueHooks$/; + +function schedule() { + if ( inProgress ) { + if ( document.hidden === false && window.requestAnimationFrame ) { + window.requestAnimationFrame( schedule ); + } else { + window.setTimeout( schedule, jQuery.fx.interval ); + } + + jQuery.fx.tick(); + } +} + +// Animations created synchronously will run synchronously +function createFxNow() { + window.setTimeout( function() { + fxNow = undefined; + } ); + return ( fxNow = Date.now() ); +} + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + i = 0, + attrs = { height: type }; + + // If we include width, step value is 1 to do all cssExpand values, + // otherwise step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +function createTween( value, prop, animation ) { + var tween, + collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { + + // We're done with this property + return tween; + } + } +} + +function defaultPrefilter( elem, props, opts ) { + var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, + isBox = "width" in props || "height" in props, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHiddenWithinTree( elem ), + dataShow = dataPriv.get( elem, "fxshow" ); + + // Queue-skipping animations hijack the fx hooks + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always( function() { + + // Ensure the complete handler is called before this completes + anim.always( function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + } ); + } ); + } + + // Detect show/hide animations + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.test( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + + // Pretend to be hidden if this is a "show" and + // there is still data from a stopped show/hide + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; + + // Ignore all other no-op show/hide data + } else { + continue; + } + } + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); + } + } + + // Bail out if this is a no-op like .hide().hide() + propTween = !jQuery.isEmptyObject( props ); + if ( !propTween && jQuery.isEmptyObject( orig ) ) { + return; + } + + // Restrict "overflow" and "display" styles during box animations + if ( isBox && elem.nodeType === 1 ) { + + // Support: IE <=9 - 11, Edge 12 - 15 + // Record all 3 overflow attributes because IE does not infer the shorthand + // from identically-valued overflowX and overflowY and Edge just mirrors + // the overflowX value there. + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Identify a display type, preferring old show/hide data over the CSS cascade + restoreDisplay = dataShow && dataShow.display; + if ( restoreDisplay == null ) { + restoreDisplay = dataPriv.get( elem, "display" ); + } + display = jQuery.css( elem, "display" ); + if ( display === "none" ) { + if ( restoreDisplay ) { + display = restoreDisplay; + } else { + + // Get nonempty value(s) by temporarily forcing visibility + showHide( [ elem ], true ); + restoreDisplay = elem.style.display || restoreDisplay; + display = jQuery.css( elem, "display" ); + showHide( [ elem ] ); + } + } + + // Animate inline elements as inline-block + if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { + if ( jQuery.css( elem, "float" ) === "none" ) { + + // Restore the original display value at the end of pure show/hide animations + if ( !propTween ) { + anim.done( function() { + style.display = restoreDisplay; + } ); + if ( restoreDisplay == null ) { + display = style.display; + restoreDisplay = display === "none" ? "" : display; + } + } + style.display = "inline-block"; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + anim.always( function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + } ); + } + + // Implement show/hide animations + propTween = false; + for ( prop in orig ) { + + // General show/hide setup for this element animation + if ( !propTween ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); + } + + // Store hidden/visible for toggle so `.stop().toggle()` "reverses" + if ( toggle ) { + dataShow.hidden = !hidden; + } + + // Show elements before animating them + if ( hidden ) { + showHide( [ elem ], true ); + } + + /* eslint-disable no-loop-func */ + + anim.done( function() { + + /* eslint-enable no-loop-func */ + + // The final step of a "hide" animation is actually hiding the element + if ( !hidden ) { + showHide( [ elem ] ); + } + dataPriv.remove( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + } ); + } + + // Per-property setup + propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = propTween.start; + if ( hidden ) { + propTween.end = propTween.start; + propTween.start = 0; + } + } + } +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( Array.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // Not quite $.extend, this won't overwrite existing keys. + // Reusing 'index' because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = Animation.prefilters.length, + deferred = jQuery.Deferred().always( function() { + + // Don't match elem in the :animated selector + delete tick.elem; + } ), + tick = function() { + if ( stopped ) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + + // Support: Android 2.3 only + // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ] ); + + // If there's more to do, yield + if ( percent < 1 && length ) { + return remaining; + } + + // If this was an empty animation, synthesize a final progress notification + if ( !length ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + } + + // Resolve the animation and report its conclusion + deferred.resolveWith( elem, [ animation ] ); + return false; + }, + animation = deferred.promise( { + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + + // If we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // Resolve when we played the last frame; otherwise, reject + if ( gotoEnd ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + } ), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length; index++ ) { + result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + if ( isFunction( result.stop ) ) { + jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = + result.stop.bind( result ); + } + return result; + } + } + + jQuery.map( props, createTween, animation ); + + if ( isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + // Attach callbacks from options + animation + .progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); + + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + } ) + ); + + return animation; +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweeners: { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ); + adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); + return tween; + } ] + }, + + tweener: function( props, callback ) { + if ( isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.match( rnothtmlwhite ); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length; index++ ) { + prop = props[ index ]; + Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; + Animation.tweeners[ prop ].unshift( callback ); + } + }, + + prefilters: [ defaultPrefilter ], + + prefilter: function( callback, prepend ) { + if ( prepend ) { + Animation.prefilters.unshift( callback ); + } else { + Animation.prefilters.push( callback ); + } + } +} ); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !isFunction( easing ) && easing + }; + + // Go to the end state if fx are off + if ( jQuery.fx.off ) { + opt.duration = 0; + + } else { + if ( typeof opt.duration !== "number" ) { + if ( opt.duration in jQuery.fx.speeds ) { + opt.duration = jQuery.fx.speeds[ opt.duration ]; + + } else { + opt.duration = jQuery.fx.speeds._default; + } + } + } + + // Normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.fn.extend( { + fadeTo: function( speed, to, easing, callback ) { + + // Show any hidden elements after setting opacity to 0 + return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() + + // Animate to the value specified + .end().animate( { opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations, or finishing resolves immediately + if ( empty || dataPriv.get( this, "finish" ) ) { + anim.stop( true ); + } + }; + + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue ) { + this.queue( type || "fx", [] ); + } + + return this.each( function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = dataPriv.get( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && + ( type == null || timers[ index ].queue === type ) ) { + + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // Start the next in the queue if the last step wasn't forced. + // Timers currently will call their complete callbacks, which + // will dequeue but only if they were gotoEnd. + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + } ); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each( function() { + var index, + data = dataPriv.get( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // Enable finishing flag on private data + data.finish = true; + + // Empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // Look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // Look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // Turn off finishing flag + delete data.finish; + } ); + } +} ); + +jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +} ); + +// Generate shortcuts for custom animations +jQuery.each( { + slideDown: genFx( "show" ), + slideUp: genFx( "hide" ), + slideToggle: genFx( "toggle" ), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +} ); + +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + i = 0, + timers = jQuery.timers; + + fxNow = Date.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + + // Run the timer and safely remove it when done (allowing for external removal) + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + jQuery.fx.start(); +}; + +jQuery.fx.interval = 13; +jQuery.fx.start = function() { + if ( inProgress ) { + return; + } + + inProgress = true; + schedule(); +}; + +jQuery.fx.stop = function() { + inProgress = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + + // Default speed + _default: 400 +}; + + +// Based off of the plugin by Clint Helfers, with permission. +// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = window.setTimeout( next, time ); + hooks.stop = function() { + window.clearTimeout( timeout ); + }; + } ); +}; + + +( function() { + var input = document.createElement( "input" ), + select = document.createElement( "select" ), + opt = select.appendChild( document.createElement( "option" ) ); + + input.type = "checkbox"; + + // Support: Android <=4.3 only + // Default value for a checkbox should be "on" + support.checkOn = input.value !== ""; + + // Support: IE <=11 only + // Must access selectedIndex to make default options select + support.optSelected = opt.selected; + + // Support: IE <=11 only + // An input loses its value after becoming a radio + input = document.createElement( "input" ); + input.value = "t"; + input.type = "radio"; + support.radioValue = input.value === "t"; +} )(); + + +var boolHook, + attrHandle = jQuery.expr.attrHandle; + +jQuery.fn.extend( { + attr: function( name, value ) { + return access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each( function() { + jQuery.removeAttr( this, name ); + } ); + } +} ); + +jQuery.extend( { + attr: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set attributes on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + // Attribute hooks are determined by the lowercase version + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + hooks = jQuery.attrHooks[ name.toLowerCase() ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); + } + + if ( value !== undefined ) { + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + } + + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + elem.setAttribute( name, value + "" ); + return value; + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? undefined : ret; + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && + nodeName( elem, "input" ) ) { + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + removeAttr: function( elem, value ) { + var name, + i = 0, + + // Attribute names can contain non-HTML whitespace characters + // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 + attrNames = value && value.match( rnothtmlwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( ( name = attrNames[ i++ ] ) ) { + elem.removeAttribute( name ); + } + } + } +} ); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + elem.setAttribute( name, name ); + } + return name; + } +}; + +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { + var getter = attrHandle[ name ] || jQuery.find.attr; + + attrHandle[ name ] = function( elem, name, isXML ) { + var ret, handle, + lowercaseName = name.toLowerCase(); + + if ( !isXML ) { + + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[ lowercaseName ]; + attrHandle[ lowercaseName ] = ret; + ret = getter( elem, name, isXML ) != null ? + lowercaseName : + null; + attrHandle[ lowercaseName ] = handle; + } + return ret; + }; +} ); + + + + +var rfocusable = /^(?:input|select|textarea|button)$/i, + rclickable = /^(?:a|area)$/i; + +jQuery.fn.extend( { + prop: function( name, value ) { + return access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + return this.each( function() { + delete this[ jQuery.propFix[ name ] || name ]; + } ); + } +} ); + +jQuery.extend( { + prop: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set properties on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + return ( elem[ name ] = value ); + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + return elem[ name ]; + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + + // Support: IE <=9 - 11 only + // elem.tabIndex doesn't always return the + // correct value when it hasn't been explicitly set + // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + if ( tabindex ) { + return parseInt( tabindex, 10 ); + } + + if ( + rfocusable.test( elem.nodeName ) || + rclickable.test( elem.nodeName ) && + elem.href + ) { + return 0; + } + + return -1; + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + } +} ); + +// Support: IE <=11 only +// Accessing the selectedIndex property +// forces the browser to respect setting selected +// on the option +// The getter ensures a default option is selected +// when in an optgroup +// eslint rule "no-unused-expressions" is disabled for this code +// since it considers such accessions noop +if ( !support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent && parent.parentNode ) { + parent.parentNode.selectedIndex; + } + return null; + }, + set: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent ) { + parent.selectedIndex; + + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + }; +} + +jQuery.each( [ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +} ); + + + + + // Strip and collapse whitespace according to HTML spec + // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace + function stripAndCollapse( value ) { + var tokens = value.match( rnothtmlwhite ) || []; + return tokens.join( " " ); + } + + +function getClass( elem ) { + return elem.getAttribute && elem.getAttribute( "class" ) || ""; +} + +function classesToArray( value ) { + if ( Array.isArray( value ) ) { + return value; + } + if ( typeof value === "string" ) { + return value.match( rnothtmlwhite ) || []; + } + return []; +} + +jQuery.fn.extend( { + addClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + if ( !arguments.length ) { + return this.attr( "class", "" ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) > -1 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isValidValue = type === "string" || Array.isArray( value ); + + if ( typeof stateVal === "boolean" && isValidValue ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( isFunction( value ) ) { + return this.each( function( i ) { + jQuery( this ).toggleClass( + value.call( this, i, getClass( this ), stateVal ), + stateVal + ); + } ); + } + + return this.each( function() { + var className, i, self, classNames; + + if ( isValidValue ) { + + // Toggle individual class names + i = 0; + self = jQuery( this ); + classNames = classesToArray( value ); + + while ( ( className = classNames[ i++ ] ) ) { + + // Check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( value === undefined || type === "boolean" ) { + className = getClass( this ); + if ( className ) { + + // Store className if set + dataPriv.set( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || value === false ? + "" : + dataPriv.get( this, "__className__" ) || "" + ); + } + } + } ); + }, + + hasClass: function( selector ) { + var className, elem, + i = 0; + + className = " " + selector + " "; + while ( ( elem = this[ i++ ] ) ) { + if ( elem.nodeType === 1 && + ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { + return true; + } + } + + return false; + } +} ); + + + + +var rreturn = /\r/g; + +jQuery.fn.extend( { + val: function( value ) { + var hooks, ret, valueIsFunction, + elem = this[ 0 ]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || + jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && + "get" in hooks && + ( ret = hooks.get( elem, "value" ) ) !== undefined + ) { + return ret; + } + + ret = elem.value; + + // Handle most common string cases + if ( typeof ret === "string" ) { + return ret.replace( rreturn, "" ); + } + + // Handle cases where value is null/undef or number + return ret == null ? "" : ret; + } + + return; + } + + valueIsFunction = isFunction( value ); + + return this.each( function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( valueIsFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + + } else if ( typeof val === "number" ) { + val += ""; + + } else if ( Array.isArray( val ) ) { + val = jQuery.map( val, function( value ) { + return value == null ? "" : value + ""; + } ); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + } ); + } +} ); + +jQuery.extend( { + valHooks: { + option: { + get: function( elem ) { + + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + + // Support: IE <=10 - 11 only + // option.text throws exceptions (#14686, #14858) + // Strip and collapse whitespace + // https://html.spec.whatwg.org/#strip-and-collapse-whitespace + stripAndCollapse( jQuery.text( elem ) ); + } + }, + select: { + get: function( elem ) { + var value, option, i, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one", + values = one ? null : [], + max = one ? index + 1 : options.length; + + if ( index < 0 ) { + i = max; + + } else { + i = one ? index : 0; + } + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Support: IE <=9 only + // IE8-9 doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + + // Don't return options that are disabled or in a disabled optgroup + !option.disabled && + ( !option.parentNode.disabled || + !nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + + /* eslint-disable no-cond-assign */ + + if ( option.selected = + jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 + ) { + optionSet = true; + } + + /* eslint-enable no-cond-assign */ + } + + // Force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + } +} ); + +// Radios and checkboxes getter/setter +jQuery.each( [ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( Array.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); + } + } + }; + if ( !support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + return elem.getAttribute( "value" ) === null ? "on" : elem.value; + }; + } +} ); + + + + +// Return jQuery for attributes-only inclusion + + +support.focusin = "onfocusin" in window; + + +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + stopPropagationCallback = function( e ) { + e.stopPropagation(); + }; + +jQuery.extend( jQuery.event, { + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; + + cur = lastElement = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "." ) > -1 ) { + + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split( "." ); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf( ":" ) < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join( "." ); + event.rnamespace = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === ( elem.ownerDocument || document ) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { + lastElement = cur; + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] && + dataPriv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( ( !special._default || + special._default.apply( eventPath.pop(), data ) === false ) && + acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + + if ( event.isPropagationStopped() ) { + lastElement.addEventListener( type, stopPropagationCallback ); + } + + elem[ type ](); + + if ( event.isPropagationStopped() ) { + lastElement.removeEventListener( type, stopPropagationCallback ); + } + + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + // Piggyback on a donor event to simulate a different one + // Used only for `focus(in | out)` events + simulate: function( type, elem, event ) { + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true + } + ); + + jQuery.event.trigger( e, null, elem ); + } + +} ); + +jQuery.fn.extend( { + + trigger: function( type, data ) { + return this.each( function() { + jQuery.event.trigger( type, data, this ); + } ); + }, + triggerHandler: function( type, data ) { + var elem = this[ 0 ]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +} ); + + +// Support: Firefox <=44 +// Firefox doesn't have focus(in | out) events +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 +// +// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 +// focus(in | out) events fire after focus & blur events, +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order +// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 +if ( !support.focusin ) { + jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + + // Handle: regular nodes (via `this.ownerDocument`), window + // (via `this.document`) & document (via `this`). + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + dataPriv.remove( doc, fix ); + + } else { + dataPriv.access( doc, fix, attaches ); + } + } + }; + } ); +} +var location = window.location; + +var nonce = { guid: Date.now() }; + +var rquery = ( /\?/ ); + + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml, parserErrorElem; + if ( !data || typeof data !== "string" ) { + return null; + } + + // Support: IE 9 - 11 only + // IE throws on parseFromString with invalid input. + try { + xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); + } catch ( e ) {} + + parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ]; + if ( !xml || parserErrorElem ) { + jQuery.error( "Invalid XML: " + ( + parserErrorElem ? + jQuery.map( parserErrorElem.childNodes, function( el ) { + return el.textContent; + } ).join( "\n" ) : + data + ) ); + } + return xml; +}; + + +var + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( Array.isArray( obj ) ) { + + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + + // Item is non-scalar (array or object), encode its numeric index. + buildParams( + prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", + v, + traditional, + add + ); + } + } ); + + } else if ( !traditional && toType( obj ) === "object" ) { + + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + + // Serialize scalar item. + add( prefix, obj ); + } +} + +// Serialize an array of form elements or a set of +// key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, valueOrFunction ) { + + // If value is a function, invoke it and use its return value + var value = isFunction( valueOrFunction ) ? + valueOrFunction() : + valueOrFunction; + + s[ s.length ] = encodeURIComponent( key ) + "=" + + encodeURIComponent( value == null ? "" : value ); + }; + + if ( a == null ) { + return ""; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + } ); + + } else { + + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ); +}; + +jQuery.fn.extend( { + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map( function() { + + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop( this, "elements" ); + return elements ? jQuery.makeArray( elements ) : this; + } ).filter( function() { + var type = this.type; + + // Use .is( ":disabled" ) so that fieldset[disabled] works + return this.name && !jQuery( this ).is( ":disabled" ) && + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && + ( this.checked || !rcheckableType.test( type ) ); + } ).map( function( _i, elem ) { + var val = jQuery( this ).val(); + + if ( val == null ) { + return null; + } + + if ( Array.isArray( val ) ) { + return jQuery.map( val, function( val ) { + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ); + } + + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ).get(); + } +} ); + + +var + r20 = /%20/g, + rhash = /#.*$/, + rantiCache = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, + + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = "*/".concat( "*" ), + + // Anchor tag for parsing the document origin + originAnchor = document.createElement( "a" ); + +originAnchor.href = location.href; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; + + if ( isFunction( func ) ) { + + // For each dataType in the dataTypeExpression + while ( ( dataType = dataTypes[ i++ ] ) ) { + + // Prepend if requested + if ( dataType[ 0 ] === "+" ) { + dataType = dataType.slice( 1 ) || "*"; + ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); + + // Otherwise append + } else { + ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); + } + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { + + var inspected = {}, + seekingTransport = ( structure === transports ); + + function inspect( dataType ) { + var selected; + inspected[ dataType ] = true; + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); + if ( typeof dataTypeOrTransport === "string" && + !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + + options.dataTypes.unshift( dataTypeOrTransport ); + inspect( dataTypeOrTransport ); + return false; + } else if ( seekingTransport ) { + return !( selected = dataTypeOrTransport ); + } + } ); + return selected; + } + + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } + + return target; +} + +/* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while ( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, + converters = {}, + + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while ( current ) { + + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + current = dataTypes.shift(); + + if ( current ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split( " " ); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.unshift( tmp[ 1 ] ); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s.throws ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { + state: "parsererror", + error: conv ? e : "No conversion from " + prev + " to " + current + }; + } + } + } + } + } + } + + return { state: "success", data: response }; +} + +jQuery.extend( { + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: location.href, + type: "GET", + isLocal: rlocalProtocol.test( location.protocol ), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /\bxml\b/, + html: /\bhtml/, + json: /\bjson\b/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": JSON.parse, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + return settings ? + + // Building a settings object + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : + + // Extending ajaxSettings + ajaxExtend( jQuery.ajaxSettings, target ); + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var transport, + + // URL without anti-cache param + cacheURL, + + // Response headers + responseHeadersString, + responseHeaders, + + // timeout handle + timeoutTimer, + + // Url cleanup var + urlAnchor, + + // Request state (becomes false upon send and true upon completion) + completed, + + // To know if global events are to be dispatched + fireGlobals, + + // Loop variable + i, + + // uncached part of the url + uncached, + + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + + // Callbacks context + callbackContext = s.context || s, + + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && + ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + + // Status-dependent callbacks + statusCode = s.statusCode || {}, + + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + + // Default abort message + strAbort = "canceled", + + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( completed ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while ( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[ 1 ].toLowerCase() + " " ] = + ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) + .concat( match[ 2 ] ); + } + } + match = responseHeaders[ key.toLowerCase() + " " ]; + } + return match == null ? null : match.join( ", " ); + }, + + // Raw string + getAllResponseHeaders: function() { + return completed ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( completed == null ) { + name = requestHeadersNames[ name.toLowerCase() ] = + requestHeadersNames[ name.toLowerCase() ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( completed == null ) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function( map ) { + var code; + if ( map ) { + if ( completed ) { + + // Execute the appropriate callbacks + jqXHR.always( map[ jqXHR.status ] ); + } else { + + // Lazy-add the new callbacks in a way that preserves old ones + for ( code in map ) { + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } + } + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + var finalText = statusText || strAbort; + if ( transport ) { + transport.abort( finalText ); + } + done( 0, finalText ); + return this; + } + }; + + // Attach deferreds + deferred.promise( jqXHR ); + + // Add protocol if not provided (prefilters might expect it) + // Handle falsy url in the settings object (#10093: consistency with old signature) + // We also use the url parameter if available + s.url = ( ( url || s.url || location.href ) + "" ) + .replace( rprotocol, location.protocol + "//" ); + + // Alias method option to type as per ticket #12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; + + // A cross-domain request is in order when the origin doesn't match the current origin. + if ( s.crossDomain == null ) { + urlAnchor = document.createElement( "a" ); + + // Support: IE <=8 - 11, Edge 12 - 15 + // IE throws exception on accessing the href property if url is malformed, + // e.g. http://example.com:80x/ + try { + urlAnchor.href = s.url; + + // Support: IE <=8 - 11 only + // Anchor's host property isn't correctly set when s.url is relative + urlAnchor.href = urlAnchor.href; + s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== + urlAnchor.protocol + "//" + urlAnchor.host; + } catch ( e ) { + + // If there is an error parsing the URL, assume it is crossDomain, + // it can be rejected by the transport if it is invalid + s.crossDomain = true; + } + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( completed ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + // Remove hash to simplify url manipulation + cacheURL = s.url.replace( rhash, "" ); + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // Remember the hash so we can put it back + uncached = s.url.slice( cacheURL.length ); + + // If data is available and should be processed, append data to url + if ( s.data && ( s.processData || typeof s.data === "string" ) ) { + cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; + + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add or update anti-cache param if needed + if ( s.cache === false ) { + cacheURL = cacheURL.replace( rantiCache, "$1" ); + uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + + uncached; + } + + // Put hash and anti-cache on the URL that will be requested (gh-1732) + s.url = cacheURL + uncached; + + // Change '%20' to '+' if this is encoded form body content (gh-2658) + } else if ( s.data && s.processData && + ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { + s.data = s.data.replace( r20, "+" ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery.lastModified[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); + } + if ( jQuery.etag[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? + s.accepts[ s.dataTypes[ 0 ] ] + + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && + ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { + + // Abort if not done already and return + return jqXHR.abort(); + } + + // Aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + completeDeferred.add( s.complete ); + jqXHR.done( s.success ); + jqXHR.fail( s.error ); + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + + // If request was aborted inside ajaxSend, stop there + if ( completed ) { + return jqXHR; + } + + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = window.setTimeout( function() { + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + completed = false; + transport.send( requestHeaders, done ); + } catch ( e ) { + + // Rethrow post-completion exceptions + if ( completed ) { + throw e; + } + + // Propagate others as results + done( -1, e ); + } + } + + // Callback for when everything is done + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Ignore repeat invocations + if ( completed ) { + return; + } + + completed = true; + + // Clear timeout if it exists + if ( timeoutTimer ) { + window.clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // Use a noop converter for missing script but not if jsonp + if ( !isSuccess && + jQuery.inArray( "script", s.dataTypes ) > -1 && + jQuery.inArray( "json", s.dataTypes ) < 0 ) { + s.converters[ "text script" ] = function() {}; + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + + // If successful, handle type chaining + if ( isSuccess ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + modified = jqXHR.getResponseHeader( "Last-Modified" ); + if ( modified ) { + jQuery.lastModified[ cacheURL ] = modified; + } + modified = jqXHR.getResponseHeader( "etag" ); + if ( modified ) { + jQuery.etag[ cacheURL ] = modified; + } + } + + // if no content + if ( status === 204 || s.type === "HEAD" ) { + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + + // Extract error from statusText and normalize for non-aborts + error = statusText; + if ( status || !statusText ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + return jqXHR; + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + } +} ); + +jQuery.each( [ "get", "post" ], function( _i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + + // Shift arguments if data argument was omitted + if ( isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + // The url can be an options object (which then must have .url) + return jQuery.ajax( jQuery.extend( { + url: url, + type: method, + dataType: type, + data: data, + success: callback + }, jQuery.isPlainObject( url ) && url ) ); + }; +} ); + +jQuery.ajaxPrefilter( function( s ) { + var i; + for ( i in s.headers ) { + if ( i.toLowerCase() === "content-type" ) { + s.contentType = s.headers[ i ] || ""; + } + } +} ); + + +jQuery._evalUrl = function( url, options, doc ) { + return jQuery.ajax( { + url: url, + + // Make this explicit, since user can override this through ajaxSetup (#11264) + type: "GET", + dataType: "script", + cache: true, + async: false, + global: false, + + // Only evaluate the response if it is successful (gh-4126) + // dataFilter is not invoked for failure responses, so using it instead + // of the default converter is kludgy but it works. + converters: { + "text script": function() {} + }, + dataFilter: function( response ) { + jQuery.globalEval( response, options, doc ); + } + } ); +}; + + +jQuery.fn.extend( { + wrapAll: function( html ) { + var wrap; + + if ( this[ 0 ] ) { + if ( isFunction( html ) ) { + html = html.call( this[ 0 ] ); + } + + // The elements to wrap the target around + wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); + + if ( this[ 0 ].parentNode ) { + wrap.insertBefore( this[ 0 ] ); + } + + wrap.map( function() { + var elem = this; + + while ( elem.firstElementChild ) { + elem = elem.firstElementChild; + } + + return elem; + } ).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( isFunction( html ) ) { + return this.each( function( i ) { + jQuery( this ).wrapInner( html.call( this, i ) ); + } ); + } + + return this.each( function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + } ); + }, + + wrap: function( html ) { + var htmlIsFunction = isFunction( html ); + + return this.each( function( i ) { + jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); + } ); + }, + + unwrap: function( selector ) { + this.parent( selector ).not( "body" ).each( function() { + jQuery( this ).replaceWith( this.childNodes ); + } ); + return this; + } +} ); + + +jQuery.expr.pseudos.hidden = function( elem ) { + return !jQuery.expr.pseudos.visible( elem ); +}; +jQuery.expr.pseudos.visible = function( elem ) { + return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); +}; + + + + +jQuery.ajaxSettings.xhr = function() { + try { + return new window.XMLHttpRequest(); + } catch ( e ) {} +}; + +var xhrSuccessStatus = { + + // File protocol always yields status code 0, assume 200 + 0: 200, + + // Support: IE <=9 only + // #1450: sometimes IE returns 1223 when it should be 204 + 1223: 204 + }, + xhrSupported = jQuery.ajaxSettings.xhr(); + +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); +support.ajax = xhrSupported = !!xhrSupported; + +jQuery.ajaxTransport( function( options ) { + var callback, errorCallback; + + // Cross domain only allowed if supported through XMLHttpRequest + if ( support.cors || xhrSupported && !options.crossDomain ) { + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(); + + xhr.open( + options.type, + options.url, + options.async, + options.username, + options.password + ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Set headers + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + + // Callback + callback = function( type ) { + return function() { + if ( callback ) { + callback = errorCallback = xhr.onload = + xhr.onerror = xhr.onabort = xhr.ontimeout = + xhr.onreadystatechange = null; + + if ( type === "abort" ) { + xhr.abort(); + } else if ( type === "error" ) { + + // Support: IE <=9 only + // On a manual native abort, IE9 throws + // errors on any property access that is not readyState + if ( typeof xhr.status !== "number" ) { + complete( 0, "error" ); + } else { + complete( + + // File: protocol always yields status 0; see #8605, #14207 + xhr.status, + xhr.statusText + ); + } + } else { + complete( + xhrSuccessStatus[ xhr.status ] || xhr.status, + xhr.statusText, + + // Support: IE <=9 only + // IE9 has no XHR2 but throws on binary (trac-11426) + // For XHR2 non-text, let the caller handle it (gh-2498) + ( xhr.responseType || "text" ) !== "text" || + typeof xhr.responseText !== "string" ? + { binary: xhr.response } : + { text: xhr.responseText }, + xhr.getAllResponseHeaders() + ); + } + } + }; + }; + + // Listen to events + xhr.onload = callback(); + errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); + + // Support: IE 9 only + // Use onreadystatechange to replace onabort + // to handle uncaught aborts + if ( xhr.onabort !== undefined ) { + xhr.onabort = errorCallback; + } else { + xhr.onreadystatechange = function() { + + // Check readyState before timeout as it changes + if ( xhr.readyState === 4 ) { + + // Allow onerror to be called first, + // but that will not handle a native abort + // Also, save errorCallback to a variable + // as xhr.onerror cannot be accessed + window.setTimeout( function() { + if ( callback ) { + errorCallback(); + } + } ); + } + }; + } + + // Create the abort callback + callback = callback( "abort" ); + + try { + + // Do send the request (this may raise an exception) + xhr.send( options.hasContent && options.data || null ); + } catch ( e ) { + + // #14683: Only rethrow if this hasn't been notified as an error yet + if ( callback ) { + throw e; + } + } + }, + + abort: function() { + if ( callback ) { + callback(); + } + } + }; + } +} ); + + + + +// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) +jQuery.ajaxPrefilter( function( s ) { + if ( s.crossDomain ) { + s.contents.script = false; + } +} ); + +// Install script dataType +jQuery.ajaxSetup( { + accepts: { + script: "text/javascript, application/javascript, " + + "application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /\b(?:java|ecma)script\b/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +} ); + +// Handle cache's special case and crossDomain +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + } +} ); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function( s ) { + + // This transport only deals with cross domain or forced-by-attrs requests + if ( s.crossDomain || s.scriptAttrs ) { + var script, callback; + return { + send: function( _, complete ) { + script = jQuery( " + + + + + + + + + + + + + + + +
+
+
+ + +
+ + +

Index

+ +
+ +
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 00000000..5d5bd868 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,124 @@ + + + + + + + + + Welcome to phenopacket-tools’s documentation! — phenopacket-tools documentation + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

Welcome to phenopacket-tools’s documentation!

+
+

Contents:

+ +
+
+
+

Indices and tables

+ +
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/docs/modules.html b/docs/modules.html new file mode 100644 index 00000000..0ce3b5de --- /dev/null +++ b/docs/modules.html @@ -0,0 +1,112 @@ + + + + + + + + + phenopacket-tools — phenopacket-tools documentation + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

phenopacket-tools

+
+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/docs/objects.inv b/docs/objects.inv new file mode 100644 index 0000000000000000000000000000000000000000..3e1dfc15f0272ecbc63a4e1178a67bd3a90fc415 GIT binary patch literal 285 zcmY#Z2rkIT%&Sny%qvUHE6FdaR47X=D$dN$Q!wIERtPA{&q_@$u~I0=NX^SHNKDR7 zEzvE>&(A3aN`^rcS}6e8AsML(MX9-onRzLxMGE<83MCnt#R_SeIjIUjIypbLpeVJt zI5kC~v^X;_U7;!`Gf9uD;#O;)Hy@KCPuur7i{u!Dx8FO^dQwF%M%lzbP-CLsqc_i_ z;?7Tg!QrMhYe)8f_x({lwI&ss7bQhpcSbe_+wh g@9bB4-)QJnN?vu{ow_k&X|YD#a-A-AmD6QP0A2@oA^-pY literal 0 HcmV?d00001 diff --git a/docs/search.html b/docs/search.html new file mode 100644 index 00000000..1768ff1d --- /dev/null +++ b/docs/search.html @@ -0,0 +1,124 @@ + + + + + + + + Search — phenopacket-tools documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +

Search

+ + + + +

+ Searching for multiple words only shows matches that contain + all words. +

+ + +
+ + + +
+ + + +
+ +
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/docs/searchindex.js b/docs/searchindex.js new file mode 100644 index 00000000..158f9dac --- /dev/null +++ b/docs/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"docnames": ["index", "modules"], "filenames": ["index.rst", "modules.rst"], "titles": ["Welcome to phenopacket-tools\u2019s documentation!", "phenopacket-tools"], "terms": {"index": 0, "modul": 0, "search": 0, "page": 0}, "objects": {}, "objtypes": {}, "objnames": {}, "titleterms": {"welcom": 0, "phenopacket": [0, 1], "tool": [0, 1], "": 0, "document": 0, "content": 0, "indic": 0, "tabl": 0}, "envversion": {"sphinx.domains.c": 2, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 6, "sphinx.domains.index": 1, "sphinx.domains.javascript": 2, "sphinx.domains.math": 2, "sphinx.domains.python": 3, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx": 56}}) \ No newline at end of file diff --git a/sphinx/Makefile b/sphinx/Makefile new file mode 100644 index 00000000..d4bb2cbb --- /dev/null +++ b/sphinx/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/sphinx/_build/doctrees/environment.pickle b/sphinx/_build/doctrees/environment.pickle new file mode 100644 index 0000000000000000000000000000000000000000..99fbf230ad0a6e7769a757a22f230fd25fc85897 GIT binary patch literal 12659 zcmb_iYm6kT*WR(QW<6f*+TsUZit6e+T~$+E z)mx9*8CymPQXG$TrC6l+f%pr`AAScAAP@o*p#UKu6!8=BkN}B?6!MqvoO5qg^*lm$ z!~B@;KIh(Z&pr3N@BPBWulmnj;6J^R4gDZK+*0vDkS6g!#d)chUM_;Dx7`4JwS4-E z<@@D^9(RYsa#zpv5-(4c>IG@3w>xiVD$P1!o__kEbL+_S-E?p(O+w}6S!d|0I2pR$ zzREZAB#E+)EZK3ov`WWN%1S+%r5+P}@u3KUfS1I3LBG`VW>@z2)k$nCmWuCU{&q3o{I%cr)7kzO)9 zN`t-+QLa7z6VE^YZ2OkNy!P#+8^l=>gHyN2{REU2PGS~vH5f*2t}zik>1gh%%=edQzl`#ozLaK{wm#b@6@c#vSKQo}{W&dWkoa8Z_blz97?e>2GPAnp^U(31ylRPga{_*eaPJq`;f zcfVZvkNS`K*YO2MD~Iefj`IT8CkgP#YyKntt2A;7%0x<2`r9&fDpiqkGgSd5@}%b; zRX?Zsr?WT6%Uzk#irlzgxP9mmfl&gGMfUDDPo z@1;qSzrXdK#l8O?MEt%X-0myr&SCDjQIyb}5KY zX|*1E<{7)yxt`i{izs)}1ZQl7w(jbQ3J8(pQXwAC z(_jEKOY%6$m6NJHC}~Vu3{R!XW0^je`H+s7YG#28!=paA$qc4*#JsQ$toShah>X5E z4k(7<+Q@3T9+M13&gMk?$NeWnmlmz9J6-rE=)EIeQ2gZPKr0N2e)dR3mgi*IXyLmd)>Ln>-jJG zKPd|@!twYH26R>W|pQp+II{9XaItR%hCfH^K}d#T6o-GF~#aj!M;COlAJ+tAb2{Mmnug)SU@ zi{mal7UYD04(Y?Gu>)3x(0g38(?KNi-7LruYa%f2ClP#krF-)nFc1gV>3`VvRf|w z+X9xzhSj4W^AW!7a1-&WU=4T9WEPn=l7l!8_5zOgMZ6y;_u-cti)S7u2L5*h*y345 z&?^DqV-dbRN;S%-o1i{MDGM^(rK*a%GE}%2CS-OdATz?>@Sm0yMP@b~7#XBR6nWwq zH6ItEA~pge-!XPv4b2efAmO9t`tTSItQ^*94PlMKrx-1JfhwV za;o5640a<~(7)_oF@BX37gjo({Rm>EfoN#ntE81C0c6e7?Ng~s=TLWA5p~+S$ zqERMd58^Qv9aR!sNYD&av^M?ozb8AARXG(vCP_6{$izq0(9?R$z3q%r-nCjO=v_~pb?WS@!1(b3g z2~=0@n27wJt$nB@zxL|eH*dCgufMU~{@nH(*I&Q+()AlRZg1bY^E0Kae7T+~H5=-4 zcK}az^ZM>#x4rhMib7=d`DkC z6>+v`%9%}vQ;md4Bz6VjU|zbc`!lkJL=uK92?QM-C@ec_lQ=&r2y#sFZGg%Pel#iu zvB}2`$28;+Zr-Np*JOO23?p@*BKR84R;l=tDqu|poD2}mkD=K}9>!usJyMNTnZ_sz zILN}0kT7aNP$;;$Duah&@D%|!0+mgW7(FX!NkYS4xp?71a~(+&YCB?_5!Xlx!3e_v zPS1lfQ7km$;aZR*di!_a=7JWd!eR8xiD!r z!>`rwRNX_LBX@k|a`ui$%|n)(Ly%n|PNNt)iOPe4f|rM>pTyix(tWB1b|y}t+}K0* zL(ZNjt=B6VOf3*S_6tv<#^-U5)#Fmw1|01G!Ps)}+DqvlaVa5#r=i{^_kcfxv7FV3 zTRCMwZ4%LA?#@M+g%Fx2Lbc8v3-l3!4%~eNUr}Ld!r)tih-rqbW>D)$Nno{UQuqW^ zNnGkOY&D4Y5^9ccl4#BP3{FwjJQn^Vrs_|;8LKt~q1ugfxSi~^tCr*Z8$sr&2xSgV zCL{Y6mRIb0BL*$FC5vmAiD0f+%t@0JbhU|ELb_%9CPtGkTM{w$s&Y4oV2Onl)4Iia zX@WjQ)oQ8KgOVD9PuM|5B?K9tAA} zv`KP5g$X;{14Kk-_7{NX79O_X9J~OTGkD$OevpH%kM$j9fQgV-z2Q*O+|%75rm)Nd z&J@EMp}vnGfJLfQ^ucMek22Gm3r!OQ>k?fbSll&qf`g%hzF_Q9KiKKwz5u<*%(pvw za(IM>dF)WYDdKwwY*d=}ocw5LTYF~jm!bZ!N)-)}6vRE#`9tFX9ej)7HpFW6(+)&( zu^T=+hFE}*vsR;f>VP^+l#%EO6>q}os$uK(FteO(edvqN)x#F*VN$kL1RCq?ccF^t zR-)3;r(M@(O>L>BhB@3eJBwbb2Grdg#b2%GN_)_H>*I>VwR*@Ph>_i-11Cc2f&f#? zry;%!@m`ePzg-b&@F;C-^kXXIV!eVXk*}O~)jx|ftoQtAJ%w^{(iPY#^=M$aHCv7I zsD??~@@`G*N==JpfC@y?@WoD%r5)VTbo`*mgQ%X;5L-o8<}6opETW#(t`|aL&GjtY z1a56mIP+y#SxbEhY9?x1x74VE%s|%IWr{VUL-g7yxgp#b$ILYpk3XY~tdSIUZ3Sji z`g=%o$bxECB&aPJ1b5T9S8is^8H8k1dLl-1;K0^$P29=yq$s+2UJ3`kjDm6PT-2*0 z5b>?pm7YXeiQYT%k*j*abPlS>ICaZh%h`KAzvWNUeS~g7C~^Vt6%;>HawPz_Y_2js zD!Tsb)Gu8!BqbPTTVA;{rq@pbecaXHnjt4fubxB(rWpjByD~6DrCg9kMhC;WHDNw4)2Nxb73chyz zJAd%&kItoc!=nE6wcjc>YNNUo_6$7*Y7B)_H^40Q7C2oFO z=8~^hhQ9%d;n(nw5%cJlP;TQ!_uZqcgpD!-AL-Tr`6L~Snem&Lp)Z+bc- zPp&)LiYZLM#(9MF4oN4cQ}@2<_|Nz_QwRS82n?MVHU|51<&H{Ezd~Jcq$8h2S=Wz}E}Z?OAN1fE z@onDFssJsiLgBx6F6bFi@g$DWP|!2*Ni|da)2d!yaGpP=z z8}bH+0XkvhxniK5Nv2G zuS<`!?Z&+}-z;UL{`#x|vZ;++vgv6{Zsb#xrZfj z@?0L`Xh}P8pp-+LZ}8_G_eS`T=Y2+iY6h_I?};6Doyh~s=IrC84gO!QGkV~)P90^y zB+i%QGVo^_&cnD%-c!R}o^p^)*LbORjl2J^{;=Ww!cA;XUw=5yXUabIePIWLb}oqu ze2HcH5J^kz`Q%t0!aQmV+xua-D7uASM8Kq{OQ;hhzEJ{35pQRV&2Q&op%-XOqf?5K zjX}82lkh}YmtHcV7d=9LmRF}@$mKXDGC|5NmpE3Un}N!R@9;67hg4ZS-gQ!N#1MWn zO!>WDwy|&oif6_2l#CO8N_j7OTt&|E8^i2q&_(AoJS01tyd%GCrO)Sx$}S7=$|vq$ z@8Z=Bg1i0wvcfw@{GQ;B5x$^eK^l!~25Rad2{8QuG?GX!cJ*SA-B!&p$9mdnlnQ#@ zana&d^UIJIG0@}`$`B~vxp6wO@O;a$#K=>Hu?Juf22~y~B zv{6YY;h%xe@ICTk-@vy~IfUP&O@x2JTbbrPznQ*CFPsTFlf%1u90FFSA5Z)VYZIy^$Ex)IJ` zv|hy3Y2#6?0w(-rFi-DlW0m4!R!<-$!398$sxe%^9L9%>^lb_MzFdA#cF~A#*@v8X zTRlA5tbU?C{w!1GAX-r=Vf?OV8dJ(J&0G$@WR z89v2i_3AC|-?vA2`!e(ywFYwFO6n|XBkvE&@Cs&!SD6HU5sQXT{36PR{0Ai~14@0g zs@YEPz}xgd^sFi6xSy++Ud4+Vs%+klgL^lmUx9G>l@jLLizM$4p95(= literal 0 HcmV?d00001 diff --git a/sphinx/_build/doctrees/index.doctree b/sphinx/_build/doctrees/index.doctree new file mode 100644 index 0000000000000000000000000000000000000000..fc0635ab2d23981ea35dbd661d52264f7e8768f7 GIT binary patch literal 5060 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 SQniLG&AMhRr2Ds=o&E= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/sphinx/_build/html/_static/alabaster.css b/sphinx/_build/html/_static/alabaster.css new file mode 100644 index 00000000..0eddaeb0 --- /dev/null +++ b/sphinx/_build/html/_static/alabaster.css @@ -0,0 +1,701 @@ +@import url("basic.css"); + +/* -- page layout ----------------------------------------------------------- */ + +body { + font-family: Georgia, serif; + font-size: 17px; + background-color: #fff; + color: #000; + margin: 0; + padding: 0; +} + + +div.document { + width: 940px; + margin: 30px auto 0 auto; +} + +div.documentwrapper { + float: left; + width: 100%; +} + +div.bodywrapper { + margin: 0 0 0 220px; +} + +div.sphinxsidebar { + width: 220px; + font-size: 14px; + line-height: 1.5; +} + +hr { + border: 1px solid #B1B4B6; +} + +div.body { + background-color: #fff; + color: #3E4349; + padding: 0 30px 0 30px; +} + +div.body > .section { + text-align: left; +} + +div.footer { + width: 940px; + margin: 20px auto 30px auto; + font-size: 14px; + color: #888; + text-align: right; +} + +div.footer a { + color: #888; +} + +p.caption { + font-family: inherit; + font-size: inherit; +} + + +div.relations { + display: none; +} + + +div.sphinxsidebar a { + color: #444; + text-decoration: none; + border-bottom: 1px dotted #999; +} + +div.sphinxsidebar a:hover { + border-bottom: 1px solid #999; +} + +div.sphinxsidebarwrapper { + padding: 18px 10px; +} + +div.sphinxsidebarwrapper p.logo { + padding: 0; + margin: -10px 0 0 0px; + text-align: center; +} + +div.sphinxsidebarwrapper h1.logo { + margin-top: -10px; + text-align: center; + margin-bottom: 5px; + text-align: left; +} + +div.sphinxsidebarwrapper h1.logo-name { + margin-top: 0px; +} + +div.sphinxsidebarwrapper p.blurb { + margin-top: 0; + font-style: normal; +} + +div.sphinxsidebar h3, +div.sphinxsidebar h4 { + font-family: Georgia, serif; + color: #444; + font-size: 24px; + font-weight: normal; + margin: 0 0 5px 0; + padding: 0; +} + +div.sphinxsidebar h4 { + font-size: 20px; +} + +div.sphinxsidebar h3 a { + color: #444; +} + +div.sphinxsidebar p.logo a, +div.sphinxsidebar h3 a, +div.sphinxsidebar p.logo a:hover, +div.sphinxsidebar h3 a:hover { + border: none; +} + +div.sphinxsidebar p { + color: #555; + margin: 10px 0; +} + +div.sphinxsidebar ul { + margin: 10px 0; + padding: 0; + color: #000; +} + +div.sphinxsidebar ul li.toctree-l1 > a { + font-size: 120%; +} + +div.sphinxsidebar ul li.toctree-l2 > a { + font-size: 110%; +} + +div.sphinxsidebar input { + border: 1px solid #CCC; + font-family: Georgia, serif; + font-size: 1em; +} + +div.sphinxsidebar hr { + border: none; + height: 1px; + color: #AAA; + background: #AAA; + + text-align: left; + margin-left: 0; + width: 50%; +} + +div.sphinxsidebar .badge { + border-bottom: none; +} + +div.sphinxsidebar .badge:hover { + border-bottom: none; +} + +/* To address an issue with donation coming after search */ +div.sphinxsidebar h3.donation { + margin-top: 10px; +} + +/* -- body styles ----------------------------------------------------------- */ + +a { + color: #004B6B; + text-decoration: underline; +} + +a:hover { + color: #6D4100; + text-decoration: underline; +} + +div.body h1, +div.body h2, +div.body h3, +div.body h4, +div.body h5, +div.body h6 { + font-family: Georgia, serif; + font-weight: normal; + margin: 30px 0px 10px 0px; + padding: 0; +} + +div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; } +div.body h2 { font-size: 180%; } +div.body h3 { font-size: 150%; } +div.body h4 { font-size: 130%; } +div.body h5 { font-size: 100%; } +div.body h6 { font-size: 100%; } + +a.headerlink { + color: #DDD; + padding: 0 4px; + text-decoration: none; +} + +a.headerlink:hover { + color: #444; + background: #EAEAEA; +} + +div.body p, div.body dd, div.body li { + line-height: 1.4em; +} + +div.admonition { + margin: 20px 0px; + padding: 10px 30px; + background-color: #EEE; + border: 1px solid #CCC; +} + +div.admonition tt.xref, div.admonition code.xref, div.admonition a tt { + background-color: #FBFBFB; + border-bottom: 1px solid #fafafa; +} + +div.admonition p.admonition-title { + font-family: Georgia, serif; + font-weight: normal; + font-size: 24px; + margin: 0 0 10px 0; + padding: 0; + line-height: 1; +} + +div.admonition p.last { + margin-bottom: 0; +} + +div.highlight { + background-color: #fff; +} + +dt:target, .highlight { + background: #FAF3E8; +} + +div.warning { + background-color: #FCC; + border: 1px solid #FAA; +} + +div.danger { + background-color: #FCC; + border: 1px solid #FAA; + -moz-box-shadow: 2px 2px 4px #D52C2C; + -webkit-box-shadow: 2px 2px 4px #D52C2C; + box-shadow: 2px 2px 4px #D52C2C; +} + +div.error { + background-color: #FCC; + border: 1px solid #FAA; + -moz-box-shadow: 2px 2px 4px #D52C2C; + -webkit-box-shadow: 2px 2px 4px #D52C2C; + box-shadow: 2px 2px 4px #D52C2C; +} + +div.caution { + background-color: #FCC; + border: 1px solid #FAA; +} + +div.attention { + background-color: #FCC; + border: 1px solid #FAA; +} + +div.important { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.note { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.tip { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.hint { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.seealso { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.topic { + background-color: #EEE; +} + +p.admonition-title { + display: inline; +} + +p.admonition-title:after { + content: ":"; +} + +pre, tt, code { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; + font-size: 0.9em; +} + +.hll { + background-color: #FFC; + margin: 0 -12px; + padding: 0 12px; + display: block; +} + +img.screenshot { +} + +tt.descname, tt.descclassname, code.descname, code.descclassname { + font-size: 0.95em; +} + +tt.descname, code.descname { + padding-right: 0.08em; +} + +img.screenshot { + -moz-box-shadow: 2px 2px 4px #EEE; + -webkit-box-shadow: 2px 2px 4px #EEE; + box-shadow: 2px 2px 4px #EEE; +} + +table.docutils { + border: 1px solid #888; + -moz-box-shadow: 2px 2px 4px #EEE; + -webkit-box-shadow: 2px 2px 4px #EEE; + box-shadow: 2px 2px 4px #EEE; +} + +table.docutils td, table.docutils th { + border: 1px solid #888; + padding: 0.25em 0.7em; +} + +table.field-list, table.footnote { + border: none; + -moz-box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; +} + +table.footnote { + margin: 15px 0; + width: 100%; + border: 1px solid #EEE; + background: #FDFDFD; + font-size: 0.9em; +} + +table.footnote + table.footnote { + margin-top: -15px; + border-top: none; +} + +table.field-list th { + padding: 0 0.8em 0 0; +} + +table.field-list td { + padding: 0; +} + +table.field-list p { + margin-bottom: 0.8em; +} + +/* Cloned from + * https://github.com/sphinx-doc/sphinx/commit/ef60dbfce09286b20b7385333d63a60321784e68 + */ +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +table.footnote td.label { + width: .1px; + padding: 0.3em 0 0.3em 0.5em; +} + +table.footnote td { + padding: 0.3em 0.5em; +} + +dl { + margin: 0; + padding: 0; +} + +dl dd { + margin-left: 30px; +} + +blockquote { + margin: 0 0 0 30px; + padding: 0; +} + +ul, ol { + /* Matches the 30px from the narrow-screen "li > ul" selector below */ + margin: 10px 0 10px 30px; + padding: 0; +} + +pre { + background: #EEE; + padding: 7px 30px; + margin: 15px 0px; + line-height: 1.3em; +} + +div.viewcode-block:target { + background: #ffd; +} + +dl pre, blockquote pre, li pre { + margin-left: 0; + padding-left: 30px; +} + +tt, code { + background-color: #ecf0f3; + color: #222; + /* padding: 1px 2px; */ +} + +tt.xref, code.xref, a tt { + background-color: #FBFBFB; + border-bottom: 1px solid #fff; +} + +a.reference { + text-decoration: none; + border-bottom: 1px dotted #004B6B; +} + +/* Don't put an underline on images */ +a.image-reference, a.image-reference:hover { + border-bottom: none; +} + +a.reference:hover { + border-bottom: 1px solid #6D4100; +} + +a.footnote-reference { + text-decoration: none; + font-size: 0.7em; + vertical-align: top; + border-bottom: 1px dotted #004B6B; +} + +a.footnote-reference:hover { + border-bottom: 1px solid #6D4100; +} + +a:hover tt, a:hover code { + background: #EEE; +} + + +@media screen and (max-width: 870px) { + + div.sphinxsidebar { + display: none; + } + + div.document { + width: 100%; + + } + + div.documentwrapper { + margin-left: 0; + margin-top: 0; + margin-right: 0; + margin-bottom: 0; + } + + div.bodywrapper { + margin-top: 0; + margin-right: 0; + margin-bottom: 0; + margin-left: 0; + } + + ul { + margin-left: 0; + } + + li > ul { + /* Matches the 30px from the "ul, ol" selector above */ + margin-left: 30px; + } + + .document { + width: auto; + } + + .footer { + width: auto; + } + + .bodywrapper { + margin: 0; + } + + .footer { + width: auto; + } + + .github { + display: none; + } + + + +} + + + +@media screen and (max-width: 875px) { + + body { + margin: 0; + padding: 20px 30px; + } + + div.documentwrapper { + float: none; + background: #fff; + } + + div.sphinxsidebar { + display: block; + float: none; + width: 102.5%; + margin: 50px -30px -20px -30px; + padding: 10px 20px; + background: #333; + color: #FFF; + } + + div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p, + div.sphinxsidebar h3 a { + color: #fff; + } + + div.sphinxsidebar a { + color: #AAA; + } + + div.sphinxsidebar p.logo { + display: none; + } + + div.document { + width: 100%; + margin: 0; + } + + div.footer { + display: none; + } + + div.bodywrapper { + margin: 0; + } + + div.body { + min-height: 0; + padding: 0; + } + + .rtd_doc_footer { + display: none; + } + + .document { + width: auto; + } + + .footer { + width: auto; + } + + .footer { + width: auto; + } + + .github { + display: none; + } +} + + +/* misc. */ + +.revsys-inline { + display: none!important; +} + +/* Make nested-list/multi-paragraph items look better in Releases changelog + * pages. Without this, docutils' magical list fuckery causes inconsistent + * formatting between different release sub-lists. + */ +div#changelog > div.section > ul > li > p:only-child { + margin-bottom: 0; +} + +/* Hide fugly table cell borders in ..bibliography:: directive output */ +table.docutils.citation, table.docutils.citation td, table.docutils.citation th { + border: none; + /* Below needed in some edge cases; if not applied, bottom shadows appear */ + -moz-box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; +} + + +/* relbar */ + +.related { + line-height: 30px; + width: 100%; + font-size: 0.9rem; +} + +.related.top { + border-bottom: 1px solid #EEE; + margin-bottom: 20px; +} + +.related.bottom { + border-top: 1px solid #EEE; +} + +.related ul { + padding: 0; + margin: 0; + list-style: none; +} + +.related li { + display: inline; +} + +nav#rellinks { + float: right; +} + +nav#rellinks li+li:before { + content: "|"; +} + +nav#breadcrumbs li+li:before { + content: "\00BB"; +} + +/* Hide certain items when printing */ +@media print { + div.related { + display: none; + } +} \ No newline at end of file diff --git a/sphinx/_build/html/_static/basic.css b/sphinx/_build/html/_static/basic.css new file mode 100644 index 00000000..eeb0519a --- /dev/null +++ b/sphinx/_build/html/_static/basic.css @@ -0,0 +1,899 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} +a.brackets:before, +span.brackets > a:before{ + content: "["; +} + +a.brackets:after, +span.brackets > a:after { + content: "]"; +} + + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} +dl.footnote > dt, +dl.citation > dt { + float: left; + margin-right: 0.5em; +} + +dl.footnote > dd, +dl.citation > dd { + margin-bottom: 0em; +} + +dl.footnote > dd:after, +dl.citation > dd:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} +dl.field-list > dt:after { + content: ":"; +} + + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/sphinx/_build/html/_static/custom.css b/sphinx/_build/html/_static/custom.css new file mode 100644 index 00000000..2a924f1d --- /dev/null +++ b/sphinx/_build/html/_static/custom.css @@ -0,0 +1 @@ +/* This file intentionally left blank. */ diff --git a/sphinx/_build/html/_static/doctools.js b/sphinx/_build/html/_static/doctools.js new file mode 100644 index 00000000..c3db08d1 --- /dev/null +++ b/sphinx/_build/html/_static/doctools.js @@ -0,0 +1,264 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + parent.insertBefore( + span, + parent.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.highlightSearchWords(); + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords: () => { + const highlight = + new URLSearchParams(window.location.search).get("highlight") || ""; + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + const url = new URL(window.location); + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + const blacklistedElements = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", + ]); + document.addEventListener("keydown", (event) => { + if (blacklistedElements.has(document.activeElement.tagName)) return; // bail for input elements + if (event.altKey || event.ctrlKey || event.metaKey) return; // bail with special keys + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + case "Escape": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.hideSearchWords(); + event.preventDefault(); + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/sphinx/_build/html/_static/documentation_options.js b/sphinx/_build/html/_static/documentation_options.js new file mode 100644 index 00000000..b57ae3b8 --- /dev/null +++ b/sphinx/_build/html/_static/documentation_options.js @@ -0,0 +1,14 @@ +var DOCUMENTATION_OPTIONS = { + URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), + VERSION: '', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/sphinx/_build/html/_static/file.png b/sphinx/_build/html/_static/file.png new file mode 100644 index 0000000000000000000000000000000000000000..a858a410e4faa62ce324d814e4b816fff83a6fb3 GIT binary patch literal 286 zcmV+(0pb3MP)s`hMrGg#P~ix$^RISR_I47Y|r1 z_CyJOe}D1){SET-^Amu_i71Lt6eYfZjRyw@I6OQAIXXHDfiX^GbOlHe=Ae4>0m)d(f|Me07*qoM6N<$f}vM^LjV8( literal 0 HcmV?d00001 diff --git a/sphinx/_build/html/_static/jquery-3.6.0.js b/sphinx/_build/html/_static/jquery-3.6.0.js new file mode 100644 index 00000000..fc6c299b --- /dev/null +++ b/sphinx/_build/html/_static/jquery-3.6.0.js @@ -0,0 +1,10881 @@ +/*! + * jQuery JavaScript Library v3.6.0 + * https://jquery.com/ + * + * Includes Sizzle.js + * https://sizzlejs.com/ + * + * Copyright OpenJS Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2021-03-02T17:08Z + */ +( function( global, factory ) { + + "use strict"; + + if ( typeof module === "object" && typeof module.exports === "object" ) { + + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common +// enough that all such attempts are guarded in a try block. +"use strict"; + +var arr = []; + +var getProto = Object.getPrototypeOf; + +var slice = arr.slice; + +var flat = arr.flat ? function( array ) { + return arr.flat.call( array ); +} : function( array ) { + return arr.concat.apply( [], array ); +}; + + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var fnToString = hasOwn.toString; + +var ObjectFunctionString = fnToString.call( Object ); + +var support = {}; + +var isFunction = function isFunction( obj ) { + + // Support: Chrome <=57, Firefox <=52 + // In some browsers, typeof returns "function" for HTML elements + // (i.e., `typeof document.createElement( "object" ) === "function"`). + // We don't want to classify *any* DOM node as a function. + // Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5 + // Plus for old WebKit, typeof returns "function" for HTML collections + // (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756) + return typeof obj === "function" && typeof obj.nodeType !== "number" && + typeof obj.item !== "function"; + }; + + +var isWindow = function isWindow( obj ) { + return obj != null && obj === obj.window; + }; + + +var document = window.document; + + + + var preservedScriptAttributes = { + type: true, + src: true, + nonce: true, + noModule: true + }; + + function DOMEval( code, node, doc ) { + doc = doc || document; + + var i, val, + script = doc.createElement( "script" ); + + script.text = code; + if ( node ) { + for ( i in preservedScriptAttributes ) { + + // Support: Firefox 64+, Edge 18+ + // Some browsers don't support the "nonce" property on scripts. + // On the other hand, just using `getAttribute` is not enough as + // the `nonce` attribute is reset to an empty string whenever it + // becomes browsing-context connected. + // See https://github.com/whatwg/html/issues/2369 + // See https://html.spec.whatwg.org/#nonce-attributes + // The `node.getAttribute` check was added for the sake of + // `jQuery.globalEval` so that it can fake a nonce-containing node + // via an object. + val = node[ i ] || node.getAttribute && node.getAttribute( i ); + if ( val ) { + script.setAttribute( i, val ); + } + } + } + doc.head.appendChild( script ).parentNode.removeChild( script ); + } + + +function toType( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; +} +/* global Symbol */ +// Defining this global in .eslintrc.json would create a danger of using the global +// unguarded in another place, it seems safer to define global only for this module + + + +var + version = "3.6.0", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }; + +jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + + // Return all the elements in a clean array + if ( num == null ) { + return slice.call( this ); + } + + // Return just the one element from the set + return num < 0 ? this[ num + this.length ] : this[ num ]; + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + even: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return ( i + 1 ) % 2; + } ) ); + }, + + odd: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return i % 2; + } ) ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + copy = options[ name ]; + + // Prevent Object.prototype pollution + // Prevent never-ending loop + if ( name === "__proto__" || target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = Array.isArray( copy ) ) ) ) { + src = target[ name ]; + + // Ensure proper type for the source value + if ( copyIsArray && !Array.isArray( src ) ) { + clone = []; + } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { + clone = {}; + } else { + clone = src; + } + copyIsArray = false; + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend( { + + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isPlainObject: function( obj ) { + var proto, Ctor; + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if ( !obj || toString.call( obj ) !== "[object Object]" ) { + return false; + } + + proto = getProto( obj ); + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if ( !proto ) { + return true; + } + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; + }, + + isEmptyObject: function( obj ) { + var name; + + for ( name in obj ) { + return false; + } + return true; + }, + + // Evaluates a script in a provided context; falls back to the global one + // if not specified. + globalEval: function( code, options, doc ) { + DOMEval( code, { nonce: options && options.nonce }, doc ); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return flat( ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), + function( _i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); + } ); + +function isArrayLike( obj ) { + + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = toType( obj ); + + if ( isFunction( obj ) || isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.3.6 + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://js.foundation/ + * + * Date: 2021-02-16 + */ +( function( window ) { +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + nonnativeSelectorCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // Instance methods + hasOwn = ( {} ).hasOwnProperty, + arr = [], + pop = arr.pop, + pushNative = arr.push, + push = arr.push, + slice = arr.slice, + + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[ i ] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + + "ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram + identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + + "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + + // "Attribute values must be CSS identifiers [capture 5] + // or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + + whitespace + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + + "*" ), + rdescend = new RegExp( whitespace + "|>" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rhtml = /HTML$/i, + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), + funescape = function( escape, nonHex ) { + var high = "0x" + escape.slice( 1 ) - 0x10000; + + return nonHex ? + + // Strip the backslash prefix from a non-hex escape sequence + nonHex : + + // Replace a hexadecimal escape sequence with the encoded Unicode code point + // Support: IE <=11+ + // For values outside the Basic Multilingual Plane (BMP), manually construct a + // surrogate pair + high < 0 ? + String.fromCharCode( high + 0x10000 ) : + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, + fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }, + + inDisabledFieldset = addCombinator( + function( elem ) { + return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; + }, + { dir: "parentNode", next: "legend" } + ); + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + ( arr = slice.call( preferredDoc.childNodes ) ), + preferredDoc.childNodes + ); + + // Support: Android<4.0 + // Detect silently failing push.apply + // eslint-disable-next-line no-unused-expressions + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + pushNative.apply( target, slice.call( els ) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + + // Can't trust NodeList.length + while ( ( target[ j++ ] = els[ i++ ] ) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + setDocument( context ); + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { + + // ID selector + if ( ( m = match[ 1 ] ) ) { + + // Document context + if ( nodeType === 9 ) { + if ( ( elem = context.getElementById( m ) ) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && ( elem = newContext.getElementById( m ) ) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[ 2 ] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !nonnativeSelectorCache[ selector + " " ] && + ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && + + // Support: IE 8 only + // Exclude object elements + ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { + + newSelector = selector; + newContext = context; + + // qSA considers elements outside a scoping root when evaluating child or + // descendant combinators, which is not what we want. + // In such cases, we work around the behavior by prefixing every selector in the + // list with an ID selector referencing the scope context. + // The technique has to be used as well when a leading combinator is used + // as such selectors are not recognized by querySelectorAll. + // Thanks to Andrew Dupont for this technique. + if ( nodeType === 1 && + ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + + // We can use :scope instead of the ID hack if the browser + // supports it & if we're not changing the context. + if ( newContext !== context || !support.scope ) { + + // Capture the context ID, setting it first if necessary + if ( ( nid = context.getAttribute( "id" ) ) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", ( nid = expando ) ); + } + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + while ( i-- ) { + groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + + toSelector( groups[ i ] ); + } + newSelector = groups.join( "," ); + } + + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + nonnativeSelectorCache( selector, true ); + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return ( cache[ key + " " ] = value ); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created element and returns a boolean result + */ +function assert( fn ) { + var el = document.createElement( "fieldset" ); + + try { + return !!fn( el ); + } catch ( e ) { + return false; + } finally { + + // Remove from its parent by default + if ( el.parentNode ) { + el.parentNode.removeChild( el ); + } + + // release memory in IE + el = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split( "|" ), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[ i ] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + a.sourceIndex - b.sourceIndex; + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( ( cur = cur.nextSibling ) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return ( name === "input" || name === "button" ) && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { + + // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { + + // Only certain elements can match :enabled or :disabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + if ( "form" in elem ) { + + // Check for inherited disabledness on relevant non-disabled elements: + // * listed form-associated elements in a disabled fieldset + // https://html.spec.whatwg.org/multipage/forms.html#category-listed + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled + // * option elements in a disabled optgroup + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled + // All such elements have a "form" property. + if ( elem.parentNode && elem.disabled === false ) { + + // Option elements defer to a parent optgroup if present + if ( "label" in elem ) { + if ( "label" in elem.parentNode ) { + return elem.parentNode.disabled === disabled; + } else { + return elem.disabled === disabled; + } + } + + // Support: IE 6 - 11 + // Use the isDisabled shortcut property to check for disabled fieldset ancestors + return elem.isDisabled === disabled || + + // Where there is no isDisabled, check manually + /* jshint -W018 */ + elem.isDisabled !== !disabled && + inDisabledFieldset( elem ) === disabled; + } + + return elem.disabled === disabled; + + // Try to winnow out elements that can't be disabled before trusting the disabled property. + // Some victims get caught in our net (label, legend, menu, track), but it shouldn't + // even exist on them, let alone have a boolean value. + } else if ( "label" in elem ) { + return elem.disabled === disabled; + } + + // Remaining elements are neither :enabled nor :disabled + return false; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction( function( argument ) { + argument = +argument; + return markFunction( function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ ( j = matchIndexes[ i ] ) ] ) { + seed[ j ] = !( matches[ j ] = seed[ j ] ); + } + } + } ); + } ); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + var namespace = elem && elem.namespaceURI, + docElem = elem && ( elem.ownerDocument || elem ).documentElement; + + // Support: IE <=8 + // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes + // https://bugs.jquery.com/ticket/4833 + return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, subWindow, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9 - 11+, Edge 12 - 18+ + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( preferredDoc != document && + ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { + + // Support: IE 11, Edge + if ( subWindow.addEventListener ) { + subWindow.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( subWindow.attachEvent ) { + subWindow.attachEvent( "onunload", unloadHandler ); + } + } + + // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, + // Safari 4 - 5 only, Opera <=11.6 - 12.x only + // IE/Edge & older browsers don't support the :scope pseudo-class. + // Support: Safari 6.0 only + // Safari 6.0 supports :scope but it's an alias of :root there. + support.scope = assert( function( el ) { + docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); + return typeof el.querySelectorAll !== "undefined" && + !el.querySelectorAll( ":scope fieldset div" ).length; + } ); + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert( function( el ) { + el.className = "i"; + return !el.getAttribute( "className" ); + } ); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert( function( el ) { + el.appendChild( document.createComment( "" ) ); + return !el.getElementsByTagName( "*" ).length; + } ); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programmatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert( function( el ) { + docElem.appendChild( el ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + } ); + + // ID filter and find + if ( support.getById ) { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute( "id" ) === attrId; + }; + }; + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var elem = context.getElementById( id ); + return elem ? [ elem ] : []; + } + }; + } else { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode( "id" ); + return node && node.value === attrId; + }; + }; + + // Support: IE 6 - 7 only + // getElementById is not reliable as a find shortcut + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var node, i, elems, + elem = context.getElementById( id ); + + if ( elem ) { + + // Verify the id attribute + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + + // Fall back on getElementsByName + elems = context.getElementsByName( id ); + i = 0; + while ( ( elem = elems[ i++ ] ) ) { + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + } + } + + return []; + } + }; + } + + // Tag + Expr.find[ "TAG" ] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See https://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { + + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert( function( el ) { + + var input; + + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // https://bugs.jquery.com/ticket/12359 + docElem.appendChild( el ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !el.querySelectorAll( "[selected]" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push( "~=" ); + } + + // Support: IE 11+, Edge 15 - 18+ + // IE 11/Edge don't find elements on a `[name='']` query in some cases. + // Adding a temporary attribute to the document before the selection works + // around the issue. + // Interestingly, IE 10 & older don't seem to have the issue. + input = document.createElement( "input" ); + input.setAttribute( "name", "" ); + el.appendChild( input ); + if ( !el.querySelectorAll( "[name='']" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + + whitespace + "*(?:''|\"\")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !el.querySelectorAll( ":checked" ).length ) { + rbuggyQSA.push( ":checked" ); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibling-combinator selector` fails + if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push( ".#.+[+~]" ); + } + + // Support: Firefox <=3.6 - 5 only + // Old Firefox doesn't throw on a badly-escaped identifier. + el.querySelectorAll( "\\\f" ); + rbuggyQSA.push( "[\\r\\n\\f]" ); + } ); + + assert( function( el ) { + el.innerHTML = "" + + ""; + + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement( "input" ); + input.setAttribute( "type", "hidden" ); + el.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( el.querySelectorAll( "[name=d]" ).length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: IE9-11+ + // IE's :disabled selector does not pick up the children of disabled fieldsets + docElem.appendChild( el ).disabled = true; + if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: Opera 10 - 11 only + // Opera 10-11 does not throw on post-comma invalid pseudos + el.querySelectorAll( "*,:x" ); + rbuggyQSA.push( ",.*:" ); + } ); + } + + if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector ) ) ) ) { + + assert( function( el ) { + + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( el, "*" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( el, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + } ); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + ) ); + } : + function( a, b ) { + if ( b ) { + while ( ( b = b.parentNode ) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { + + // Choose the first element that is related to our preferred document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( a == document || a.ownerDocument == preferredDoc && + contains( preferredDoc, a ) ) { + return -1; + } + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( b == document || b.ownerDocument == preferredDoc && + contains( preferredDoc, b ) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + return a == document ? -1 : + b == document ? 1 : + /* eslint-enable eqeqeq */ + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( ( cur = cur.parentNode ) ) { + ap.unshift( cur ); + } + cur = b; + while ( ( cur = cur.parentNode ) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[ i ] === bp[ i ] ) { + i++; + } + + return i ? + + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[ i ], bp[ i ] ) : + + // Otherwise nodes in our document sort first + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + ap[ i ] == preferredDoc ? -1 : + bp[ i ] == preferredDoc ? 1 : + /* eslint-enable eqeqeq */ + 0; + }; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + setDocument( elem ); + + if ( support.matchesSelector && documentIsHTML && + !nonnativeSelectorCache[ expr + " " ] && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch ( e ) { + nonnativeSelectorCache( expr, true ); + } + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( context.ownerDocument || context ) != document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( elem.ownerDocument || elem ) != document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; +}; + +Sizzle.escape = function( sel ) { + return ( sel + "" ).replace( rcssescape, fcssescape ); +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + + // If no nodeType, this is expected to be an array + while ( ( node = elem[ i++ ] ) ) { + + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[ 1 ] = match[ 1 ].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[ 3 ] = ( match[ 3 ] || match[ 4 ] || + match[ 5 ] || "" ).replace( runescape, funescape ); + + if ( match[ 2 ] === "~=" ) { + match[ 3 ] = " " + match[ 3 ] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[ 1 ] = match[ 1 ].toLowerCase(); + + if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { + + // nth-* requires argument + if ( !match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[ 4 ] = +( match[ 4 ] ? + match[ 5 ] + ( match[ 6 ] || 1 ) : + 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); + match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); + + // other types prohibit arguments + } else if ( match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[ 6 ] && match[ 2 ]; + + if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[ 3 ] ) { + match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + + // Get excess from tokenize (recursively) + ( excess = tokenize( unquoted, true ) ) && + + // advance to the next closing parenthesis + ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { + + // excess is a negative index + match[ 0 ] = match[ 0 ].slice( 0, excess ); + match[ 2 ] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { + return true; + } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + ( pattern = new RegExp( "(^|" + whitespace + + ")" + className + "(" + whitespace + "|$)" ) ) && classCache( + className, function( elem ) { + return pattern.test( + typeof elem.className === "string" && elem.className || + typeof elem.getAttribute !== "undefined" && + elem.getAttribute( "class" ) || + "" + ); + } ); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + /* eslint-disable max-len */ + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + /* eslint-enable max-len */ + + }; + }, + + "CHILD": function( type, what, _argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, _context, xml ) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( ( node = node[ dir ] ) ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + + return false; + } + } + + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + + // Seek `elem` from a previously-cached index + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( ( node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + + // Use previously-cached element index if available + if ( useCache ) { + + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + + // Use the same loop as above to seek `elem` from the start + while ( ( node = ++nodeIndex && node && node[ dir ] || + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || + ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction( function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[ i ] ); + seed[ idx ] = !( matches[ idx ] = matched[ i ] ); + } + } ) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + + // Potentially complex pseudos + "not": markFunction( function( selector ) { + + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction( function( seed, matches, _context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( ( elem = unmatched[ i ] ) ) { + seed[ i ] = !( matches[ i ] = elem ); + } + } + } ) : + function( elem, _context, xml ) { + input[ 0 ] = elem; + matcher( input, null, xml, results ); + + // Don't keep the element (issue #299) + input[ 0 ] = null; + return !results.pop(); + }; + } ), + + "has": markFunction( function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + } ), + + "contains": markFunction( function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; + }; + } ), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + + // lang value must be a valid identifier + if ( !ridentifier.test( lang || "" ) ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( ( elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); + return false; + }; + } ), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && + ( !document.hasFocus || document.hasFocus() ) && + !!( elem.type || elem.href || ~elem.tabIndex ); + }, + + // Boolean properties + "enabled": createDisabledPseudo( false ), + "disabled": createDisabledPseudo( true ), + + "checked": function( elem ) { + + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return ( nodeName === "input" && !!elem.checked ) || + ( nodeName === "option" && !!elem.selected ); + }, + + "selected": function( elem ) { + + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + // eslint-disable-next-line no-unused-expressions + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos[ "empty" ]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( ( attr = elem.getAttribute( "type" ) ) == null || + attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo( function() { + return [ 0 ]; + } ), + + "last": createPositionalPseudo( function( _matchIndexes, length ) { + return [ length - 1 ]; + } ), + + "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + } ), + + "even": createPositionalPseudo( function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "odd": createPositionalPseudo( function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "lt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? + argument + length : + argument > length ? + length : + argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "gt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ) + } +}; + +Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || ( match = rcomma.exec( soFar ) ) ) { + if ( match ) { + + // Don't consume trailing commas as valid + soFar = soFar.slice( match[ 0 ].length ) || soFar; + } + groups.push( ( tokens = [] ) ); + } + + matched = false; + + // Combinators + if ( ( match = rcombinators.exec( soFar ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + + // Cast descendant combinators to space + type: match[ 0 ].replace( rtrim, " " ) + } ); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || + ( match = preFilters[ type ]( match ) ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + type: type, + matches: match + } ); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[ i ].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + skip = combinator.next, + key = skip || dir, + checkNonElements = base && key === "parentNode", + doneName = done++; + + return combinator.first ? + + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + return false; + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, uniqueCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if ( xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || ( elem[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || + ( outerCache[ elem.uniqueID ] = {} ); + + if ( skip && skip === elem.nodeName.toLowerCase() ) { + elem = elem[ dir ] || elem; + } else if ( ( oldCache = uniqueCache[ key ] ) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return ( newCache[ 2 ] = oldCache[ 2 ] ); + } else { + + // Reuse newcache so results back-propagate to previous elements + uniqueCache[ key ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { + return true; + } + } + } + } + } + return false; + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[ i ]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[ 0 ]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[ i ], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( ( elem = unmatched[ i ] ) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction( function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( + selector || "*", + context.nodeType ? [ context ] : context, + [] + ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( ( elem = temp[ i ] ) ) { + matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) ) { + + // Restore matcherIn since elem is not yet a final match + temp.push( ( matcherIn[ i ] = elem ) ); + } + } + postFinder( null, ( matcherOut = [] ), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) && + ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) { + + seed[ temp ] = !( results[ temp ] = elem ); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + } ); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[ 0 ].type ], + implicitRelative = leadingRelative || Expr.relative[ " " ], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + ( checkContext = context ).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { + matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; + } else { + matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[ j ].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens + .slice( 0, i - 1 ) + .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ), + + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), + len = elems.length; + + if ( outermost ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + outermostContext = context == document || context || outermost; + } + + // Add elements passing elementMatchers directly to results + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( !context && elem.ownerDocument != document ) { + setDocument( elem ); + xml = !documentIsHTML; + } + while ( ( matcher = elementMatchers[ j++ ] ) ) { + if ( matcher( elem, context || document, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + + // They will have gone through all possible matchers + if ( ( elem = !matcher && elem ) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + if ( bySet && i !== matchedCount ) { + j = 0; + while ( ( matcher = setMatchers[ j++ ] ) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !( unmatched[ i ] || setMatched[ i ] ) ) { + setMatched[ i ] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[ i ] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( + selector, + matcherFromGroupMatchers( elementMatchers, setMatchers ) + ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( ( selector = compiled.selector || selector ) ); + + results = results || []; + + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) + if ( match.length === 1 ) { + + // Reduce context if the leading compound selector is an ID + tokens = match[ 0 ] = match[ 0 ].slice( 0 ); + if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && + context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { + + context = ( Expr.find[ "ID" ]( token.matches[ 0 ] + .replace( runescape, funescape ), context ) || [] )[ 0 ]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[ i ]; + + // Abort if we hit a combinator + if ( Expr.relative[ ( type = token.type ) ] ) { + break; + } + if ( ( find = Expr.find[ type ] ) ) { + + // Search, expanding context for leading sibling combinators + if ( ( seed = find( + token.matches[ 0 ].replace( runescape, funescape ), + rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || + context + ) ) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert( function( el ) { + + // Should return 1, but returns 4 (following) + return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; +} ); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert( function( el ) { + el.innerHTML = ""; + return el.firstChild.getAttribute( "href" ) === "#"; +} ) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + } ); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert( function( el ) { + el.innerHTML = ""; + el.firstChild.setAttribute( "value", "" ); + return el.firstChild.getAttribute( "value" ) === ""; +} ) ) { + addHandle( "value", function( elem, _name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + } ); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert( function( el ) { + return el.getAttribute( "disabled" ) == null; +} ) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; + } + } ); +} + +return Sizzle; + +} )( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; + +// Deprecated +jQuery.expr[ ":" ] = jQuery.expr.pseudos; +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; +jQuery.escapeSelector = Sizzle.escape; + + + + +var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; +}; + + +var siblings = function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; +}; + + +var rneedsContext = jQuery.expr.match.needsContext; + + + +function nodeName( elem, name ) { + + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + +} +var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); + + + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + return !!qualifier.call( elem, i, elem ) !== not; + } ); + } + + // Single element + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + } ); + } + + // Arraylike of elements (jQuery, arguments, Array) + if ( typeof qualifier !== "string" ) { + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) > -1 ) !== not; + } ); + } + + // Filtered directly for both simple and complex selectors + return jQuery.filter( qualifier, elements, not ); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + if ( elems.length === 1 && elem.nodeType === 1 ) { + return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; + } + + return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + } ) ); +}; + +jQuery.fn.extend( { + find: function( selector ) { + var i, ret, + len = this.length, + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + } ) ); + } + + ret = this.pushStack( [] ); + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + return len > 1 ? jQuery.uniqueSort( ret ) : ret; + }, + filter: function( selector ) { + return this.pushStack( winnow( this, selector || [], false ) ); + }, + not: function( selector ) { + return this.pushStack( winnow( this, selector || [], true ) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +} ); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + // Shortcut simple #id case for speed + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, + + init = jQuery.fn.init = function( selector, context, root ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[ 0 ] === "<" && + selector[ selector.length - 1 ] === ">" && + selector.length >= 3 ) { + + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && ( match[ 1 ] || !context ) ) { + + // HANDLE: $(html) -> $(array) + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; + + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[ 1 ], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + + // Properties of context are called as methods if possible + if ( isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[ 2 ] ); + + if ( elem ) { + + // Inject the element directly into the jQuery object + this[ 0 ] = elem; + this.length = 1; + } + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || root ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this[ 0 ] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( isFunction( selector ) ) { + return root.ready !== undefined ? + root.ready( selector ) : + + // Execute immediately if ready is not present + selector( jQuery ); + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend( { + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter( function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[ i ] ) ) { + return true; + } + } + } ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + targets = typeof selectors !== "string" && jQuery( selectors ); + + // Positional selectors never match, since there's no _selection_ context + if ( !rneedsContext.test( selectors ) ) { + for ( ; i < l; i++ ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + + // Always skip document fragments + if ( cur.nodeType < 11 && ( targets ? + targets.index( cur ) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector( cur, selectors ) ) ) { + + matched.push( cur ); + break; + } + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); + }, + + // Determine the position of an element within the set + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // Index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.uniqueSort( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + } +} ); + +function sibling( cur, dir ) { + while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} + return cur; +} + +jQuery.each( { + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, _i, until ) { + return dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, _i, until ) { + return dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, _i, until ) { + return dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return siblings( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return siblings( elem.firstChild ); + }, + contents: function( elem ) { + if ( elem.contentDocument != null && + + // Support: IE 11+ + // elements with no `data` attribute has an object + // `contentDocument` with a `null` prototype. + getProto( elem.contentDocument ) ) { + + return elem.contentDocument; + } + + // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only + // Treat the template element as a regular one in browsers that + // don't support it. + if ( nodeName( elem, "template" ) ) { + elem = elem.content || elem; + } + + return jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.uniqueSort( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +} ); +var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); + + + +// Convert String-formatted options into Object-formatted ones +function createOptions( options ) { + var object = {}; + jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { + object[ flag ] = true; + } ); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + createOptions( options ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + + // Last fire value for non-forgettable lists + memory, + + // Flag to know if list was already fired + fired, + + // Flag to prevent firing + locked, + + // Actual callback list + list = [], + + // Queue of execution data for repeatable lists + queue = [], + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + + // Fire callbacks + fire = function() { + + // Enforce single-firing + locked = locked || options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { + + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } + } + } + + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } + + firing = false; + + // Clean up if we're done firing for good + if ( locked ) { + + // Keep an empty list if we have data for future add calls + if ( memory ) { + list = []; + + // Otherwise, this object is spent + } else { + list = ""; + } + } + }, + + // Actual Callbacks object + self = { + + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } + + ( function add( args ) { + jQuery.each( args, function( _, arg ) { + if ( isFunction( arg ) ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && toType( arg ) !== "string" ) { + + // Inspect recursively + add( arg ); + } + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); + } + } + return this; + }, + + // Remove a callback from the list + remove: function() { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + + // Handle firing indexes + if ( index <= firingIndex ) { + firingIndex--; + } + } + } ); + return this; + }, + + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? + jQuery.inArray( fn, list ) > -1 : + list.length > 0; + }, + + // Remove all callbacks from the list + empty: function() { + if ( list ) { + list = []; + } + return this; + }, + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = []; + list = memory = ""; + return this; + }, + disabled: function() { + return !list; + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = queue = []; + if ( !memory && !firing ) { + list = memory = ""; + } + return this; + }, + locked: function() { + return !!locked; + }, + + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( !locked ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + queue.push( args ); + if ( !firing ) { + fire(); + } + } + return this; + }, + + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +function Identity( v ) { + return v; +} +function Thrower( ex ) { + throw ex; +} + +function adoptValue( value, resolve, reject, noValue ) { + var method; + + try { + + // Check for promise aspect first to privilege synchronous behavior + if ( value && isFunction( ( method = value.promise ) ) ) { + method.call( value ).done( resolve ).fail( reject ); + + // Other thenables + } else if ( value && isFunction( ( method = value.then ) ) ) { + method.call( value, resolve, reject ); + + // Other non-thenables + } else { + + // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: + // * false: [ value ].slice( 0 ) => resolve( value ) + // * true: [ value ].slice( 1 ) => resolve() + resolve.apply( undefined, [ value ].slice( noValue ) ); + } + + // For Promises/A+, convert exceptions into rejections + // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in + // Deferred#then to conditionally suppress rejection. + } catch ( value ) { + + // Support: Android 4.0 only + // Strict mode functions invoked without .call/.apply get global-object context + reject.apply( undefined, [ value ] ); + } +} + +jQuery.extend( { + + Deferred: function( func ) { + var tuples = [ + + // action, add listener, callbacks, + // ... .then handlers, argument index, [final state] + [ "notify", "progress", jQuery.Callbacks( "memory" ), + jQuery.Callbacks( "memory" ), 2 ], + [ "resolve", "done", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 0, "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 1, "rejected" ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + "catch": function( fn ) { + return promise.then( null, fn ); + }, + + // Keep pipe for back-compat + pipe: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( _i, tuple ) { + + // Map tuples (progress, done, fail) to arguments (done, fail, progress) + var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; + + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + // deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && isFunction( returned.promise ) ) { + returned.promise() + .progress( newDefer.notify ) + .done( newDefer.resolve ) + .fail( newDefer.reject ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + }, + then: function( onFulfilled, onRejected, onProgress ) { + var maxDepth = 0; + function resolve( depth, deferred, handler, special ) { + return function() { + var that = this, + args = arguments, + mightThrow = function() { + var returned, then; + + // Support: Promises/A+ section 2.3.3.3.3 + // https://promisesaplus.com/#point-59 + // Ignore double-resolution attempts + if ( depth < maxDepth ) { + return; + } + + returned = handler.apply( that, args ); + + // Support: Promises/A+ section 2.3.1 + // https://promisesaplus.com/#point-48 + if ( returned === deferred.promise() ) { + throw new TypeError( "Thenable self-resolution" ); + } + + // Support: Promises/A+ sections 2.3.3.1, 3.5 + // https://promisesaplus.com/#point-54 + // https://promisesaplus.com/#point-75 + // Retrieve `then` only once + then = returned && + + // Support: Promises/A+ section 2.3.4 + // https://promisesaplus.com/#point-64 + // Only check objects and functions for thenability + ( typeof returned === "object" || + typeof returned === "function" ) && + returned.then; + + // Handle a returned thenable + if ( isFunction( then ) ) { + + // Special processors (notify) just wait for resolution + if ( special ) { + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ) + ); + + // Normal processors (resolve) also hook into progress + } else { + + // ...and disregard older resolution values + maxDepth++; + + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ), + resolve( maxDepth, deferred, Identity, + deferred.notifyWith ) + ); + } + + // Handle all other returned values + } else { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Identity ) { + that = undefined; + args = [ returned ]; + } + + // Process the value(s) + // Default process is resolve + ( special || deferred.resolveWith )( that, args ); + } + }, + + // Only normal processors (resolve) catch and reject exceptions + process = special ? + mightThrow : + function() { + try { + mightThrow(); + } catch ( e ) { + + if ( jQuery.Deferred.exceptionHook ) { + jQuery.Deferred.exceptionHook( e, + process.stackTrace ); + } + + // Support: Promises/A+ section 2.3.3.3.4.1 + // https://promisesaplus.com/#point-61 + // Ignore post-resolution exceptions + if ( depth + 1 >= maxDepth ) { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Thrower ) { + that = undefined; + args = [ e ]; + } + + deferred.rejectWith( that, args ); + } + } + }; + + // Support: Promises/A+ section 2.3.3.3.1 + // https://promisesaplus.com/#point-57 + // Re-resolve promises immediately to dodge false rejection from + // subsequent errors + if ( depth ) { + process(); + } else { + + // Call an optional hook to record the stack, in case of exception + // since it's otherwise lost when execution goes async + if ( jQuery.Deferred.getStackHook ) { + process.stackTrace = jQuery.Deferred.getStackHook(); + } + window.setTimeout( process ); + } + }; + } + + return jQuery.Deferred( function( newDefer ) { + + // progress_handlers.add( ... ) + tuples[ 0 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onProgress ) ? + onProgress : + Identity, + newDefer.notifyWith + ) + ); + + // fulfilled_handlers.add( ... ) + tuples[ 1 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onFulfilled ) ? + onFulfilled : + Identity + ) + ); + + // rejected_handlers.add( ... ) + tuples[ 2 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onRejected ) ? + onRejected : + Thrower + ) + ); + } ).promise(); + }, + + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 5 ]; + + // promise.progress = list.add + // promise.done = list.add + // promise.fail = list.add + promise[ tuple[ 1 ] ] = list.add; + + // Handle state + if ( stateString ) { + list.add( + function() { + + // state = "resolved" (i.e., fulfilled) + // state = "rejected" + state = stateString; + }, + + // rejected_callbacks.disable + // fulfilled_callbacks.disable + tuples[ 3 - i ][ 2 ].disable, + + // rejected_handlers.disable + // fulfilled_handlers.disable + tuples[ 3 - i ][ 3 ].disable, + + // progress_callbacks.lock + tuples[ 0 ][ 2 ].lock, + + // progress_handlers.lock + tuples[ 0 ][ 3 ].lock + ); + } + + // progress_handlers.fire + // fulfilled_handlers.fire + // rejected_handlers.fire + list.add( tuple[ 3 ].fire ); + + // deferred.notify = function() { deferred.notifyWith(...) } + // deferred.resolve = function() { deferred.resolveWith(...) } + // deferred.reject = function() { deferred.rejectWith(...) } + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); + return this; + }; + + // deferred.notifyWith = list.fireWith + // deferred.resolveWith = list.fireWith + // deferred.rejectWith = list.fireWith + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( singleValue ) { + var + + // count of uncompleted subordinates + remaining = arguments.length, + + // count of unprocessed arguments + i = remaining, + + // subordinate fulfillment data + resolveContexts = Array( i ), + resolveValues = slice.call( arguments ), + + // the primary Deferred + primary = jQuery.Deferred(), + + // subordinate callback factory + updateFunc = function( i ) { + return function( value ) { + resolveContexts[ i ] = this; + resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( !( --remaining ) ) { + primary.resolveWith( resolveContexts, resolveValues ); + } + }; + }; + + // Single- and empty arguments are adopted like Promise.resolve + if ( remaining <= 1 ) { + adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject, + !remaining ); + + // Use .then() to unwrap secondary thenables (cf. gh-3000) + if ( primary.state() === "pending" || + isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { + + return primary.then(); + } + } + + // Multiple arguments are aggregated like Promise.all array elements + while ( i-- ) { + adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject ); + } + + return primary.promise(); + } +} ); + + +// These usually indicate a programmer mistake during development, +// warn about them ASAP rather than swallowing them by default. +var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; + +jQuery.Deferred.exceptionHook = function( error, stack ) { + + // Support: IE 8 - 9 only + // Console exists when dev tools are open, which can happen at any time + if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { + window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); + } +}; + + + + +jQuery.readyException = function( error ) { + window.setTimeout( function() { + throw error; + } ); +}; + + + + +// The deferred used on DOM ready +var readyList = jQuery.Deferred(); + +jQuery.fn.ready = function( fn ) { + + readyList + .then( fn ) + + // Wrap jQuery.readyException in a function so that the lookup + // happens at the time of error handling instead of callback + // registration. + .catch( function( error ) { + jQuery.readyException( error ); + } ); + + return this; +}; + +jQuery.extend( { + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + } +} ); + +jQuery.ready.then = readyList.then; + +// The ready event handler and self cleanup method +function completed() { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + jQuery.ready(); +} + +// Catch cases where $(document).ready() is called +// after the browser event has already occurred. +// Support: IE <=9 - 10 only +// Older IE sometimes signals "interactive" too soon +if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); + +} else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); +} + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( toType( key ) === "object" ) { + chainable = true; + for ( i in key ) { + access( elems, fn, i, key[ i ], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, _key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); + } + } + } + + if ( chainable ) { + return elems; + } + + // Gets + if ( bulk ) { + return fn.call( elems ); + } + + return len ? fn( elems[ 0 ], key ) : emptyGet; +}; + + +// Matches dashed string for camelizing +var rmsPrefix = /^-ms-/, + rdashAlpha = /-([a-z])/g; + +// Used by camelCase as callback to replace() +function fcamelCase( _all, letter ) { + return letter.toUpperCase(); +} + +// Convert dashed to camelCase; used by the css and data modules +// Support: IE <=9 - 11, Edge 12 - 15 +// Microsoft forgot to hump their vendor prefix (#9572) +function camelCase( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); +} +var acceptData = function( owner ) { + + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + + + +function Data() { + this.expando = jQuery.expando + Data.uid++; +} + +Data.uid = 1; + +Data.prototype = { + + cache: function( owner ) { + + // Check if the owner object already has a cache + var value = owner[ this.expando ]; + + // If not, create one + if ( !value ) { + value = {}; + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( acceptData( owner ) ) { + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty( owner, this.expando, { + value: value, + configurable: true + } ); + } + } + } + + return value; + }, + set: function( owner, data, value ) { + var prop, + cache = this.cache( owner ); + + // Handle: [ owner, key, value ] args + // Always use camelCase key (gh-2257) + if ( typeof data === "string" ) { + cache[ camelCase( data ) ] = value; + + // Handle: [ owner, { properties } ] args + } else { + + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ camelCase( prop ) ] = data[ prop ]; + } + } + return cache; + }, + get: function( owner, key ) { + return key === undefined ? + this.cache( owner ) : + + // Always use camelCase key (gh-2257) + owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; + }, + access: function( owner, key, value ) { + + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ( ( key && typeof key === "string" ) && value === undefined ) ) { + + return this.get( owner, key ); + } + + // When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, + cache = owner[ this.expando ]; + + if ( cache === undefined ) { + return; + } + + if ( key !== undefined ) { + + // Support array or space separated string of keys + if ( Array.isArray( key ) ) { + + // If key is an array of keys... + // We always set camelCase keys, so remove that. + key = key.map( camelCase ); + } else { + key = camelCase( key ); + + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + key = key in cache ? + [ key ] : + ( key.match( rnothtmlwhite ) || [] ); + } + + i = key.length; + + while ( i-- ) { + delete cache[ key[ i ] ]; + } + } + + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + + // Support: Chrome <=35 - 45 + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) + if ( owner.nodeType ) { + owner[ this.expando ] = undefined; + } else { + delete owner[ this.expando ]; + } + } + }, + hasData: function( owner ) { + var cache = owner[ this.expando ]; + return cache !== undefined && !jQuery.isEmptyObject( cache ); + } +}; +var dataPriv = new Data(); + +var dataUser = new Data(); + + + +// Implementation Summary +// +// 1. Enforce API surface and semantic compatibility with 1.9.x branch +// 2. Improve the module's maintainability by reducing the storage +// paths to a single mechanism. +// 3. Use the same single mechanism to support "private" and "user" data. +// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) +// 5. Avoid exposing implementation details on user objects (eg. expando properties) +// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /[A-Z]/g; + +function getData( data ) { + if ( data === "true" ) { + return true; + } + + if ( data === "false" ) { + return false; + } + + if ( data === "null" ) { + return null; + } + + // Only convert to a number if it doesn't change the string + if ( data === +data + "" ) { + return +data; + } + + if ( rbrace.test( data ) ) { + return JSON.parse( data ); + } + + return data; +} + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = getData( data ); + } catch ( e ) {} + + // Make sure we set the data so it isn't changed later + dataUser.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend( { + hasData: function( elem ) { + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return dataUser.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + dataUser.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to dataPriv methods, these can be deprecated. + _data: function( elem, name, data ) { + return dataPriv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + dataPriv.remove( elem, name ); + } +} ); + +jQuery.fn.extend( { + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = dataUser.get( elem ); + + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE 11 only + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = camelCase( name.slice( 5 ) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + dataPriv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + dataUser.set( this, key ); + } ); + } + + return access( this, function( value ) { + var data; + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + + // Attempt to get data from the cache + // The key will always be camelCased in Data + data = dataUser.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, key ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each( function() { + + // We always store the camelCased key + dataUser.set( this, key, value ); + } ); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each( function() { + dataUser.remove( this, key ); + } ); + } +} ); + + +jQuery.extend( { + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = dataPriv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || Array.isArray( data ) ) { + queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + dataPriv.remove( elem, [ type + "queue", key ] ); + } ) + } ); + } +} ); + +jQuery.fn.extend( { + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[ 0 ], type ); + } + + return data === undefined ? + this : + this.each( function() { + var queue = jQuery.queue( this, type, data ); + + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + } ); + }, + dequeue: function( type ) { + return this.each( function() { + jQuery.dequeue( this, type ); + } ); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +} ); +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var documentElement = document.documentElement; + + + + var isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ); + }, + composed = { composed: true }; + + // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only + // Check attachment across shadow DOM boundaries when possible (gh-3504) + // Support: iOS 10.0-10.2 only + // Early iOS 10 versions support `attachShadow` but not `getRootNode`, + // leading to errors. We need to check for `getRootNode`. + if ( documentElement.getRootNode ) { + isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ) || + elem.getRootNode( composed ) === elem.ownerDocument; + }; + } +var isHiddenWithinTree = function( elem, el ) { + + // isHiddenWithinTree might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + + // Inline style trumps all + return elem.style.display === "none" || + elem.style.display === "" && + + // Otherwise, check computed style + // Support: Firefox <=43 - 45 + // Disconnected elements can have computed display: none, so first confirm that elem is + // in the document. + isAttached( elem ) && + + jQuery.css( elem, "display" ) === "none"; + }; + + + +function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, scale, + maxIterations = 20, + currentValue = tween ? + function() { + return tween.cur(); + } : + function() { + return jQuery.css( elem, prop, "" ); + }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = elem.nodeType && + ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Support: Firefox <=54 + // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) + initial = initial / 2; + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + while ( maxIterations-- ) { + + // Evaluate and update our best guess (doubling guesses that zero out). + // Finish if the scale equals or crosses 1 (making the old*new product non-positive). + jQuery.style( elem, prop, initialInUnit + unit ); + if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { + maxIterations = 0; + } + initialInUnit = initialInUnit / scale; + + } + + initialInUnit = initialInUnit * 2; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; +} + + +var defaultDisplayMap = {}; + +function getDefaultDisplay( elem ) { + var temp, + doc = elem.ownerDocument, + nodeName = elem.nodeName, + display = defaultDisplayMap[ nodeName ]; + + if ( display ) { + return display; + } + + temp = doc.body.appendChild( doc.createElement( nodeName ) ); + display = jQuery.css( temp, "display" ); + + temp.parentNode.removeChild( temp ); + + if ( display === "none" ) { + display = "block"; + } + defaultDisplayMap[ nodeName ] = display; + + return display; +} + +function showHide( elements, show ) { + var display, elem, + values = [], + index = 0, + length = elements.length; + + // Determine new display value for elements that need to change + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + display = elem.style.display; + if ( show ) { + + // Since we force visibility upon cascade-hidden elements, an immediate (and slow) + // check is required in this first loop unless we have a nonempty display value (either + // inline or about-to-be-restored) + if ( display === "none" ) { + values[ index ] = dataPriv.get( elem, "display" ) || null; + if ( !values[ index ] ) { + elem.style.display = ""; + } + } + if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { + values[ index ] = getDefaultDisplay( elem ); + } + } else { + if ( display !== "none" ) { + values[ index ] = "none"; + + // Remember what we're overwriting + dataPriv.set( elem, "display", display ); + } + } + } + + // Set the display of the elements in a second loop to avoid constant reflow + for ( index = 0; index < length; index++ ) { + if ( values[ index ] != null ) { + elements[ index ].style.display = values[ index ]; + } + } + + return elements; +} + +jQuery.fn.extend( { + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each( function() { + if ( isHiddenWithinTree( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + } ); + } +} ); +var rcheckableType = ( /^(?:checkbox|radio)$/i ); + +var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); + +var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); + + + +( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Android 4.0 - 4.3 only + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Android <=4.1 only + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE <=11 only + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + + // Support: IE <=9 only + // IE <=9 replaces "; + support.option = !!div.lastChild; +} )(); + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting or other required elements. + thead: [ 1, "", "
" ], + col: [ 2, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + _default: [ 0, "", "" ] +}; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// Support: IE <=9 only +if ( !support.option ) { + wrapMap.optgroup = wrapMap.option = [ 1, "" ]; +} + + +function getAll( context, tag ) { + + // Support: IE <=9 - 11 only + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret; + + if ( typeof context.getElementsByTagName !== "undefined" ) { + ret = context.getElementsByTagName( tag || "*" ); + + } else if ( typeof context.querySelectorAll !== "undefined" ) { + ret = context.querySelectorAll( tag || "*" ); + + } else { + ret = []; + } + + if ( tag === undefined || tag && nodeName( context, tag ) ) { + return jQuery.merge( [ context ], ret ); + } + + return ret; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|&#?\w+;/; + +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, attached, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( toType( elem ) === "object" ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + attached = isAttached( elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( attached ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; +} + + +var rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +// Support: IE <=9 - 11+ +// focus() and blur() are asynchronous, except when they are no-op. +// So expect focus to be synchronous when the element is already active, +// and blur to be synchronous when the element is not already active. +// (focus and blur are always synchronous in other supported browsers, +// this just defines when we can count on it). +function expectSync( elem, type ) { + return ( elem === safeActiveElement() ) === ( type === "focus" ); +} + +// Support: IE <=9 only +// Accessing document.activeElement can throw unexpectedly +// https://bugs.jquery.com/ticket/13393 +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( elem ); + + // Only attach events to objects that accept data + if ( !acceptData( elem ) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Ensure that invalid selectors throw exceptions at attach time + // Evaluate against documentElement in case elem is a non-element node (e.g., document) + if ( selector ) { + jQuery.find.matchesSelector( documentElement, selector ); + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = Object.create( null ); + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); + } + }, + + dispatch: function( nativeEvent ) { + + var i, j, ret, matched, handleObj, handlerQueue, + args = new Array( arguments.length ), + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( nativeEvent ), + + handlers = ( + dataPriv.get( this, "events" ) || Object.create( null ) + )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + + for ( i = 1; i < arguments.length; i++ ) { + args[ i ] = arguments[ i ]; + } + + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // If the event is namespaced, then each handler is only invoked if it is + // specially universal or its namespaces are a superset of the event's. + if ( !event.rnamespace || handleObj.namespace === false || + event.rnamespace.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, handleObj, sel, matchedHandlers, matchedSelectors, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + if ( delegateCount && + + // Support: IE <=9 + // Black-hole SVG instance trees (trac-13180) + cur.nodeType && + + // Support: Firefox <=42 + // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) + // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click + // Support: IE 11 only + // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) + !( event.type === "click" && event.button >= 1 ) ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { + matchedHandlers = []; + matchedSelectors = {}; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matchedSelectors[ sel ] === undefined ) { + matchedSelectors[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) > -1 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matchedSelectors[ sel ] ) { + matchedHandlers.push( handleObj ); + } + } + if ( matchedHandlers.length ) { + handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); + } + } + } + } + + // Add the remaining (directly-bound) handlers + cur = this; + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); + } + + return handlerQueue; + }, + + addProp: function( name, hook ) { + Object.defineProperty( jQuery.Event.prototype, name, { + enumerable: true, + configurable: true, + + get: isFunction( hook ) ? + function() { + if ( this.originalEvent ) { + return hook( this.originalEvent ); + } + } : + function() { + if ( this.originalEvent ) { + return this.originalEvent[ name ]; + } + }, + + set: function( value ) { + Object.defineProperty( this, name, { + enumerable: true, + configurable: true, + writable: true, + value: value + } ); + } + } ); + }, + + fix: function( originalEvent ) { + return originalEvent[ jQuery.expando ] ? + originalEvent : + new jQuery.Event( originalEvent ); + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + click: { + + // Utilize native event to ensure correct state for checkable inputs + setup: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Claim the first handler + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + // dataPriv.set( el, "click", ... ) + leverageNative( el, "click", returnTrue ); + } + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Force setup before triggering a click + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + leverageNative( el, "click" ); + } + + // Return non-false to allow normal event-path propagation + return true; + }, + + // For cross-browser consistency, suppress native .click() on links + // Also prevent it if we're currently inside a leveraged native-event stack + _default: function( event ) { + var target = event.target; + return rcheckableType.test( target.type ) && + target.click && nodeName( target, "input" ) && + dataPriv.get( target, "click" ) || + nodeName( target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + } +}; + +// Ensure the presence of an event listener that handles manually-triggered +// synthetic events by interrupting progress until reinvoked in response to +// *native* events that it fires directly, ensuring that state changes have +// already occurred before other listeners are invoked. +function leverageNative( el, type, expectSync ) { + + // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add + if ( !expectSync ) { + if ( dataPriv.get( el, type ) === undefined ) { + jQuery.event.add( el, type, returnTrue ); + } + return; + } + + // Register the controller as a special universal handler for all event namespaces + dataPriv.set( el, type, false ); + jQuery.event.add( el, type, { + namespace: false, + handler: function( event ) { + var notAsync, result, + saved = dataPriv.get( this, type ); + + if ( ( event.isTrigger & 1 ) && this[ type ] ) { + + // Interrupt processing of the outer synthetic .trigger()ed event + // Saved data should be false in such cases, but might be a leftover capture object + // from an async native handler (gh-4350) + if ( !saved.length ) { + + // Store arguments for use when handling the inner native event + // There will always be at least one argument (an event object), so this array + // will not be confused with a leftover capture object. + saved = slice.call( arguments ); + dataPriv.set( this, type, saved ); + + // Trigger the native event and capture its result + // Support: IE <=9 - 11+ + // focus() and blur() are asynchronous + notAsync = expectSync( this, type ); + this[ type ](); + result = dataPriv.get( this, type ); + if ( saved !== result || notAsync ) { + dataPriv.set( this, type, false ); + } else { + result = {}; + } + if ( saved !== result ) { + + // Cancel the outer synthetic event + event.stopImmediatePropagation(); + event.preventDefault(); + + // Support: Chrome 86+ + // In Chrome, if an element having a focusout handler is blurred by + // clicking outside of it, it invokes the handler synchronously. If + // that handler calls `.remove()` on the element, the data is cleared, + // leaving `result` undefined. We need to guard against this. + return result && result.value; + } + + // If this is an inner synthetic event for an event with a bubbling surrogate + // (focus or blur), assume that the surrogate already propagated from triggering the + // native event and prevent that from happening again here. + // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the + // bubbling surrogate propagates *after* the non-bubbling base), but that seems + // less bad than duplication. + } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { + event.stopPropagation(); + } + + // If this is a native event triggered above, everything is now in order + // Fire an inner synthetic event with the original arguments + } else if ( saved.length ) { + + // ...and capture the result + dataPriv.set( this, type, { + value: jQuery.event.trigger( + + // Support: IE <=9 - 11+ + // Extend with the prototype to reset the above stopImmediatePropagation() + jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), + saved.slice( 1 ), + this + ) + } ); + + // Abort handling of the native event + event.stopImmediatePropagation(); + } + } + } ); +} + +jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } +}; + +jQuery.Event = function( src, props ) { + + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: Android <=2.3 only + src.returnValue === false ? + returnTrue : + returnFalse; + + // Create target properties + // Support: Safari <=6 - 7 only + // Target should not be a text node (#504, #13143) + this.target = ( src.target && src.target.nodeType === 3 ) ? + src.target.parentNode : + src.target; + + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || Date.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + isSimulated: false, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && !this.isSimulated ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Includes all common event props including KeyEvent and MouseEvent specific props +jQuery.each( { + altKey: true, + bubbles: true, + cancelable: true, + changedTouches: true, + ctrlKey: true, + detail: true, + eventPhase: true, + metaKey: true, + pageX: true, + pageY: true, + shiftKey: true, + view: true, + "char": true, + code: true, + charCode: true, + key: true, + keyCode: true, + button: true, + buttons: true, + clientX: true, + clientY: true, + offsetX: true, + offsetY: true, + pointerId: true, + pointerType: true, + screenX: true, + screenY: true, + targetTouches: true, + toElement: true, + touches: true, + which: true +}, jQuery.event.addProp ); + +jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { + jQuery.event.special[ type ] = { + + // Utilize native event if possible so blur/focus sequence is correct + setup: function() { + + // Claim the first handler + // dataPriv.set( this, "focus", ... ) + // dataPriv.set( this, "blur", ... ) + leverageNative( this, type, expectSync ); + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function() { + + // Force setup before trigger + leverageNative( this, type ); + + // Return non-false to allow normal event-path propagation + return true; + }, + + // Suppress native focus or blur as it's already being fired + // in leverageNative. + _default: function() { + return true; + }, + + delegateType: delegateType + }; +} ); + +// Create mouseenter/leave events using mouseover/out and event-time checks +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +} ); + +jQuery.fn.extend( { + + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + } +} ); + + +var + + // Support: IE <=10 - 11, Edge 12 - 13 only + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /\s*$/g; + +// Prefer a tbody over its parent table for containing new rows +function manipulationTarget( elem, content ) { + if ( nodeName( elem, "table" ) && + nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + + return jQuery( elem ).children( "tbody" )[ 0 ] || elem; + } + + return elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { + elem.type = elem.type.slice( 5 ); + } else { + elem.removeAttribute( "type" ); + } + + return elem; +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.get( src ); + events = pdataOld.events; + + if ( events ) { + dataPriv.remove( dest, "handle events" ); + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + dataUser.set( dest, udataCur ); + } +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = flat( args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + valueIsFunction = isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( valueIsFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( valueIsFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl && !node.noModule ) { + jQuery._evalUrl( node.src, { + nonce: node.nonce || node.getAttribute( "nonce" ) + }, doc ); + } + } else { + DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); + } + } + } + } + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && isAttached( node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html; + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = isAttached( elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; + + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } + } + } + } +} ); + +jQuery.fn.extend( { + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } +} ); + +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: Android <=4.0 only, PhantomJS 1 only + // .get() because push.apply(_, arraylike) throws on ancient WebKit + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +} ); +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + +var getStyles = function( elem ) { + + // Support: IE <=11 only, Firefox <=30 (#15098, #14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + var view = elem.ownerDocument.defaultView; + + if ( !view || !view.opener ) { + view = window; + } + + return view.getComputedStyle( elem ); + }; + +var swap = function( elem, options, callback ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.call( elem ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + +var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); + + + +( function() { + + // Executing both pixelPosition & boxSizingReliable tests require only one layout + // so they're executed at the same time to save the second computation. + function computeStyleTests() { + + // This is a singleton, we need to execute it only once + if ( !div ) { + return; + } + + container.style.cssText = "position:absolute;left:-11111px;width:60px;" + + "margin-top:1px;padding:0;border:0"; + div.style.cssText = + "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + + "margin:auto;border:1px;padding:1px;" + + "width:60%;top:1%"; + documentElement.appendChild( container ).appendChild( div ); + + var divStyle = window.getComputedStyle( div ); + pixelPositionVal = divStyle.top !== "1%"; + + // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 + reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; + + // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 + // Some styles come back with percentage values, even though they shouldn't + div.style.right = "60%"; + pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; + + // Support: IE 9 - 11 only + // Detect misreporting of content dimensions for box-sizing:border-box elements + boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; + + // Support: IE 9 only + // Detect overflow:scroll screwiness (gh-3699) + // Support: Chrome <=64 + // Don't get tricked when zoom affects offsetWidth (gh-4029) + div.style.position = "absolute"; + scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; + + documentElement.removeChild( container ); + + // Nullify the div so it wouldn't be stored in the memory and + // it will also be a sign that checks already performed + div = null; + } + + function roundPixelMeasures( measure ) { + return Math.round( parseFloat( measure ) ); + } + + var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, + reliableTrDimensionsVal, reliableMarginLeftVal, + container = document.createElement( "div" ), + div = document.createElement( "div" ); + + // Finish early in limited (non-browser) environments + if ( !div.style ) { + return; + } + + // Support: IE <=9 - 11 only + // Style of cloned element affects source element cloned (#8908) + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + jQuery.extend( support, { + boxSizingReliable: function() { + computeStyleTests(); + return boxSizingReliableVal; + }, + pixelBoxStyles: function() { + computeStyleTests(); + return pixelBoxStylesVal; + }, + pixelPosition: function() { + computeStyleTests(); + return pixelPositionVal; + }, + reliableMarginLeft: function() { + computeStyleTests(); + return reliableMarginLeftVal; + }, + scrollboxSize: function() { + computeStyleTests(); + return scrollboxSizeVal; + }, + + // Support: IE 9 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Behavior in IE 9 is more subtle than in newer versions & it passes + // some versions of this test; make sure not to make it pass there! + // + // Support: Firefox 70+ + // Only Firefox includes border widths + // in computed dimensions. (gh-4529) + reliableTrDimensions: function() { + var table, tr, trChild, trStyle; + if ( reliableTrDimensionsVal == null ) { + table = document.createElement( "table" ); + tr = document.createElement( "tr" ); + trChild = document.createElement( "div" ); + + table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate"; + tr.style.cssText = "border:1px solid"; + + // Support: Chrome 86+ + // Height set through cssText does not get applied. + // Computed height then comes back as 0. + tr.style.height = "1px"; + trChild.style.height = "9px"; + + // Support: Android 8 Chrome 86+ + // In our bodyBackground.html iframe, + // display for all div elements is set to "inline", + // which causes a problem only in Android 8 Chrome 86. + // Ensuring the div is display: block + // gets around this issue. + trChild.style.display = "block"; + + documentElement + .appendChild( table ) + .appendChild( tr ) + .appendChild( trChild ); + + trStyle = window.getComputedStyle( tr ); + reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) + + parseInt( trStyle.borderTopWidth, 10 ) + + parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight; + + documentElement.removeChild( table ); + } + return reliableTrDimensionsVal; + } + } ); +} )(); + + +function curCSS( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + + // Support: Firefox 51+ + // Retrieving style before computed somehow + // fixes an issue with getting wrong values + // on detached elements + style = elem.style; + + computed = computed || getStyles( elem ); + + // getPropertyValue is needed for: + // .css('filter') (IE 9 only, #12537) + // .css('--customProperty) (#3144) + if ( computed ) { + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !isAttached( elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Android Browser returns percentage for some values, + // but width seems to be reliably pixels. + // This is against the CSSOM draft spec: + // https://drafts.csswg.org/cssom/#resolved-values + if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret !== undefined ? + + // Support: IE <=9 - 11 only + // IE returns zIndex value as an integer. + ret + "" : + ret; +} + + +function addGetHookIf( conditionFn, hookFn ) { + + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + if ( conditionFn() ) { + + // Hook not needed (or it's not possible to use it due + // to missing dependency), remove it. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + return ( this.get = hookFn ).apply( this, arguments ); + } + }; +} + + +var cssPrefixes = [ "Webkit", "Moz", "ms" ], + emptyStyle = document.createElement( "div" ).style, + vendorProps = {}; + +// Return a vendor-prefixed property or undefined +function vendorPropName( name ) { + + // Check for vendor prefixed names + var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in emptyStyle ) { + return name; + } + } +} + +// Return a potentially-mapped jQuery.cssProps or vendor prefixed property +function finalPropName( name ) { + var final = jQuery.cssProps[ name ] || vendorProps[ name ]; + + if ( final ) { + return final; + } + if ( name in emptyStyle ) { + return name; + } + return vendorProps[ name ] = vendorPropName( name ) || name; +} + + +var + + // Swappable if display is none or starts with table + // except "table", "table-cell", or "table-caption" + // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rcustomProp = /^--/, + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }; + +function setPositiveNumber( _elem, value, subtract ) { + + // Any relative (+/-) values have already been + // normalized at this point + var matches = rcssNum.exec( value ); + return matches ? + + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : + value; +} + +function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { + var i = dimension === "width" ? 1 : 0, + extra = 0, + delta = 0; + + // Adjustment may not be necessary + if ( box === ( isBorderBox ? "border" : "content" ) ) { + return 0; + } + + for ( ; i < 4; i += 2 ) { + + // Both box models exclude margin + if ( box === "margin" ) { + delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); + } + + // If we get here with a content-box, we're seeking "padding" or "border" or "margin" + if ( !isBorderBox ) { + + // Add padding + delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // For "border" or "margin", add border + if ( box !== "padding" ) { + delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + + // But still keep track of it otherwise + } else { + extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + + // If we get here with a border-box (content + padding + border), we're seeking "content" or + // "padding" or "margin" + } else { + + // For "content", subtract padding + if ( box === "content" ) { + delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // For "content" or "padding", subtract border + if ( box !== "margin" ) { + delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + // Account for positive content-box scroll gutter when requested by providing computedVal + if ( !isBorderBox && computedVal >= 0 ) { + + // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border + // Assuming integer scroll gutter, subtract the rest and round down + delta += Math.max( 0, Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + computedVal - + delta - + extra - + 0.5 + + // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter + // Use an explicit zero to avoid NaN (gh-3964) + ) ) || 0; + } + + return delta; +} + +function getWidthOrHeight( elem, dimension, extra ) { + + // Start with computed style + var styles = getStyles( elem ), + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). + // Fake content-box until we know it's needed to know the true value. + boxSizingNeeded = !support.boxSizingReliable() || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + valueIsBorderBox = isBorderBox, + + val = curCSS( elem, dimension, styles ), + offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); + + // Support: Firefox <=54 + // Return a confounding non-pixel value or feign ignorance, as appropriate. + if ( rnumnonpx.test( val ) ) { + if ( !extra ) { + return val; + } + val = "auto"; + } + + + // Support: IE 9 - 11 only + // Use offsetWidth/offsetHeight for when box sizing is unreliable. + // In those cases, the computed value can be trusted to be border-box. + if ( ( !support.boxSizingReliable() && isBorderBox || + + // Support: IE 10 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Interestingly, in some cases IE 9 doesn't suffer from this issue. + !support.reliableTrDimensions() && nodeName( elem, "tr" ) || + + // Fall back to offsetWidth/offsetHeight when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + val === "auto" || + + // Support: Android <=4.1 - 4.3 only + // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) + !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && + + // Make sure the element is visible & connected + elem.getClientRects().length ) { + + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // Where available, offsetWidth/offsetHeight approximate border box dimensions. + // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the + // retrieved value as a content box dimension. + valueIsBorderBox = offsetProp in elem; + if ( valueIsBorderBox ) { + val = elem[ offsetProp ]; + } + } + + // Normalize "" and auto + val = parseFloat( val ) || 0; + + // Adjust for the element's box model + return ( val + + boxModelAdjustment( + elem, + dimension, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles, + + // Provide the current computed size to request scroll gutter calculation (gh-3589) + val + ) + ) + "px"; +} + +jQuery.extend( { + + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "animationIterationCount": true, + "columnCount": true, + "fillOpacity": true, + "flexGrow": true, + "flexShrink": true, + "fontWeight": true, + "gridArea": true, + "gridColumn": true, + "gridColumnEnd": true, + "gridColumnStart": true, + "gridRow": true, + "gridRowEnd": true, + "gridRowStart": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: {}, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ), + style = elem.style; + + // Make sure that we're working with the right name. We don't + // want to query the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Gets hook for the prefixed version, then unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // Convert "+=" or "-=" to relative numbers (#7345) + if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { + value = adjustCSS( elem, name, ret ); + + // Fixes bug #9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set (#7116) + if ( value == null || value !== value ) { + return; + } + + // If a number was passed in, add the unit (except for certain CSS properties) + // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append + // "px" to a few hardcoded values. + if ( type === "number" && !isCustomProp ) { + value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); + } + + // background-* props affect original clone's values + if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !( "set" in hooks ) || + ( value = hooks.set( elem, value, extra ) ) !== undefined ) { + + if ( isCustomProp ) { + style.setProperty( name, value ); + } else { + style[ name ] = value; + } + } + + } else { + + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && + ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { + + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var val, num, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ); + + // Make sure that we're working with the right name. We don't + // want to modify the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Try prefixed name followed by the unprefixed name + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + // Convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Make numeric if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || isFinite( num ) ? num || 0 : val; + } + + return val; + } +} ); + +jQuery.each( [ "height", "width" ], function( _i, dimension ) { + jQuery.cssHooks[ dimension ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + + // Certain elements can have dimension info if we invisibly show them + // but it must have a current display style that would benefit + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && + + // Support: Safari 8+ + // Table columns in Safari have non-zero offsetWidth & zero + // getBoundingClientRect().width unless display is changed. + // Support: IE <=11 only + // Running getBoundingClientRect on a disconnected node + // in IE throws an error. + ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? + swap( elem, cssShow, function() { + return getWidthOrHeight( elem, dimension, extra ); + } ) : + getWidthOrHeight( elem, dimension, extra ); + } + }, + + set: function( elem, value, extra ) { + var matches, + styles = getStyles( elem ), + + // Only read styles.position if the test has a chance to fail + // to avoid forcing a reflow. + scrollboxSizeBuggy = !support.scrollboxSize() && + styles.position === "absolute", + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) + boxSizingNeeded = scrollboxSizeBuggy || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + subtract = extra ? + boxModelAdjustment( + elem, + dimension, + extra, + isBorderBox, + styles + ) : + 0; + + // Account for unreliable border-box dimensions by comparing offset* to computed and + // faking a content-box to get border and padding (gh-3699) + if ( isBorderBox && scrollboxSizeBuggy ) { + subtract -= Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + parseFloat( styles[ dimension ] ) - + boxModelAdjustment( elem, dimension, "border", false, styles ) - + 0.5 + ); + } + + // Convert to pixels if value adjustment is needed + if ( subtract && ( matches = rcssNum.exec( value ) ) && + ( matches[ 3 ] || "px" ) !== "px" ) { + + elem.style[ dimension ] = value; + value = jQuery.css( elem, dimension ); + } + + return setPositiveNumber( elem, value, subtract ); + } + }; +} ); + +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, + function( elem, computed ) { + if ( computed ) { + return ( parseFloat( curCSS( elem, "marginLeft" ) ) || + elem.getBoundingClientRect().left - + swap( elem, { marginLeft: 0 }, function() { + return elem.getBoundingClientRect().left; + } ) + ) + "px"; + } + } +); + +// These hooks are used by animate to expand properties +jQuery.each( { + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, + + // Assumes a single number if not a string + parts = typeof value === "string" ? value.split( " " ) : [ value ]; + + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( prefix !== "margin" ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +} ); + +jQuery.fn.extend( { + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( Array.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + } +} ); + + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || jQuery.easing._default; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + // Use a property on the element directly when it is not a DOM element, + // or when there is no matching style property that exists. + if ( tween.elem.nodeType !== 1 || + tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { + return tween.elem[ tween.prop ]; + } + + // Passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails. + // Simple values such as "10px" are parsed to Float; + // complex values such as "rotate(1rad)" are returned as-is. + result = jQuery.css( tween.elem, tween.prop, "" ); + + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + + // Use step hook for back compat. + // Use cssHook if its there. + // Use .style if available and use plain properties where available. + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.nodeType === 1 && ( + jQuery.cssHooks[ tween.prop ] || + tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Support: IE <=9 only +// Panic based approach to setting things on disconnected nodes +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + }, + _default: "swing" +}; + +jQuery.fx = Tween.prototype.init; + +// Back compat <1.8 extension point +jQuery.fx.step = {}; + + + + +var + fxNow, inProgress, + rfxtypes = /^(?:toggle|show|hide)$/, + rrun = /queueHooks$/; + +function schedule() { + if ( inProgress ) { + if ( document.hidden === false && window.requestAnimationFrame ) { + window.requestAnimationFrame( schedule ); + } else { + window.setTimeout( schedule, jQuery.fx.interval ); + } + + jQuery.fx.tick(); + } +} + +// Animations created synchronously will run synchronously +function createFxNow() { + window.setTimeout( function() { + fxNow = undefined; + } ); + return ( fxNow = Date.now() ); +} + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + i = 0, + attrs = { height: type }; + + // If we include width, step value is 1 to do all cssExpand values, + // otherwise step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +function createTween( value, prop, animation ) { + var tween, + collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { + + // We're done with this property + return tween; + } + } +} + +function defaultPrefilter( elem, props, opts ) { + var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, + isBox = "width" in props || "height" in props, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHiddenWithinTree( elem ), + dataShow = dataPriv.get( elem, "fxshow" ); + + // Queue-skipping animations hijack the fx hooks + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always( function() { + + // Ensure the complete handler is called before this completes + anim.always( function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + } ); + } ); + } + + // Detect show/hide animations + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.test( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + + // Pretend to be hidden if this is a "show" and + // there is still data from a stopped show/hide + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; + + // Ignore all other no-op show/hide data + } else { + continue; + } + } + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); + } + } + + // Bail out if this is a no-op like .hide().hide() + propTween = !jQuery.isEmptyObject( props ); + if ( !propTween && jQuery.isEmptyObject( orig ) ) { + return; + } + + // Restrict "overflow" and "display" styles during box animations + if ( isBox && elem.nodeType === 1 ) { + + // Support: IE <=9 - 11, Edge 12 - 15 + // Record all 3 overflow attributes because IE does not infer the shorthand + // from identically-valued overflowX and overflowY and Edge just mirrors + // the overflowX value there. + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Identify a display type, preferring old show/hide data over the CSS cascade + restoreDisplay = dataShow && dataShow.display; + if ( restoreDisplay == null ) { + restoreDisplay = dataPriv.get( elem, "display" ); + } + display = jQuery.css( elem, "display" ); + if ( display === "none" ) { + if ( restoreDisplay ) { + display = restoreDisplay; + } else { + + // Get nonempty value(s) by temporarily forcing visibility + showHide( [ elem ], true ); + restoreDisplay = elem.style.display || restoreDisplay; + display = jQuery.css( elem, "display" ); + showHide( [ elem ] ); + } + } + + // Animate inline elements as inline-block + if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { + if ( jQuery.css( elem, "float" ) === "none" ) { + + // Restore the original display value at the end of pure show/hide animations + if ( !propTween ) { + anim.done( function() { + style.display = restoreDisplay; + } ); + if ( restoreDisplay == null ) { + display = style.display; + restoreDisplay = display === "none" ? "" : display; + } + } + style.display = "inline-block"; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + anim.always( function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + } ); + } + + // Implement show/hide animations + propTween = false; + for ( prop in orig ) { + + // General show/hide setup for this element animation + if ( !propTween ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); + } + + // Store hidden/visible for toggle so `.stop().toggle()` "reverses" + if ( toggle ) { + dataShow.hidden = !hidden; + } + + // Show elements before animating them + if ( hidden ) { + showHide( [ elem ], true ); + } + + /* eslint-disable no-loop-func */ + + anim.done( function() { + + /* eslint-enable no-loop-func */ + + // The final step of a "hide" animation is actually hiding the element + if ( !hidden ) { + showHide( [ elem ] ); + } + dataPriv.remove( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + } ); + } + + // Per-property setup + propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = propTween.start; + if ( hidden ) { + propTween.end = propTween.start; + propTween.start = 0; + } + } + } +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( Array.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // Not quite $.extend, this won't overwrite existing keys. + // Reusing 'index' because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = Animation.prefilters.length, + deferred = jQuery.Deferred().always( function() { + + // Don't match elem in the :animated selector + delete tick.elem; + } ), + tick = function() { + if ( stopped ) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + + // Support: Android 2.3 only + // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ] ); + + // If there's more to do, yield + if ( percent < 1 && length ) { + return remaining; + } + + // If this was an empty animation, synthesize a final progress notification + if ( !length ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + } + + // Resolve the animation and report its conclusion + deferred.resolveWith( elem, [ animation ] ); + return false; + }, + animation = deferred.promise( { + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + + // If we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // Resolve when we played the last frame; otherwise, reject + if ( gotoEnd ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + } ), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length; index++ ) { + result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + if ( isFunction( result.stop ) ) { + jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = + result.stop.bind( result ); + } + return result; + } + } + + jQuery.map( props, createTween, animation ); + + if ( isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + // Attach callbacks from options + animation + .progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); + + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + } ) + ); + + return animation; +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweeners: { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ); + adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); + return tween; + } ] + }, + + tweener: function( props, callback ) { + if ( isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.match( rnothtmlwhite ); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length; index++ ) { + prop = props[ index ]; + Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; + Animation.tweeners[ prop ].unshift( callback ); + } + }, + + prefilters: [ defaultPrefilter ], + + prefilter: function( callback, prepend ) { + if ( prepend ) { + Animation.prefilters.unshift( callback ); + } else { + Animation.prefilters.push( callback ); + } + } +} ); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !isFunction( easing ) && easing + }; + + // Go to the end state if fx are off + if ( jQuery.fx.off ) { + opt.duration = 0; + + } else { + if ( typeof opt.duration !== "number" ) { + if ( opt.duration in jQuery.fx.speeds ) { + opt.duration = jQuery.fx.speeds[ opt.duration ]; + + } else { + opt.duration = jQuery.fx.speeds._default; + } + } + } + + // Normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.fn.extend( { + fadeTo: function( speed, to, easing, callback ) { + + // Show any hidden elements after setting opacity to 0 + return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() + + // Animate to the value specified + .end().animate( { opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations, or finishing resolves immediately + if ( empty || dataPriv.get( this, "finish" ) ) { + anim.stop( true ); + } + }; + + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue ) { + this.queue( type || "fx", [] ); + } + + return this.each( function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = dataPriv.get( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && + ( type == null || timers[ index ].queue === type ) ) { + + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // Start the next in the queue if the last step wasn't forced. + // Timers currently will call their complete callbacks, which + // will dequeue but only if they were gotoEnd. + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + } ); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each( function() { + var index, + data = dataPriv.get( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // Enable finishing flag on private data + data.finish = true; + + // Empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // Look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // Look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // Turn off finishing flag + delete data.finish; + } ); + } +} ); + +jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +} ); + +// Generate shortcuts for custom animations +jQuery.each( { + slideDown: genFx( "show" ), + slideUp: genFx( "hide" ), + slideToggle: genFx( "toggle" ), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +} ); + +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + i = 0, + timers = jQuery.timers; + + fxNow = Date.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + + // Run the timer and safely remove it when done (allowing for external removal) + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + jQuery.fx.start(); +}; + +jQuery.fx.interval = 13; +jQuery.fx.start = function() { + if ( inProgress ) { + return; + } + + inProgress = true; + schedule(); +}; + +jQuery.fx.stop = function() { + inProgress = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + + // Default speed + _default: 400 +}; + + +// Based off of the plugin by Clint Helfers, with permission. +// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = window.setTimeout( next, time ); + hooks.stop = function() { + window.clearTimeout( timeout ); + }; + } ); +}; + + +( function() { + var input = document.createElement( "input" ), + select = document.createElement( "select" ), + opt = select.appendChild( document.createElement( "option" ) ); + + input.type = "checkbox"; + + // Support: Android <=4.3 only + // Default value for a checkbox should be "on" + support.checkOn = input.value !== ""; + + // Support: IE <=11 only + // Must access selectedIndex to make default options select + support.optSelected = opt.selected; + + // Support: IE <=11 only + // An input loses its value after becoming a radio + input = document.createElement( "input" ); + input.value = "t"; + input.type = "radio"; + support.radioValue = input.value === "t"; +} )(); + + +var boolHook, + attrHandle = jQuery.expr.attrHandle; + +jQuery.fn.extend( { + attr: function( name, value ) { + return access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each( function() { + jQuery.removeAttr( this, name ); + } ); + } +} ); + +jQuery.extend( { + attr: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set attributes on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + // Attribute hooks are determined by the lowercase version + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + hooks = jQuery.attrHooks[ name.toLowerCase() ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); + } + + if ( value !== undefined ) { + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + } + + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + elem.setAttribute( name, value + "" ); + return value; + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? undefined : ret; + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && + nodeName( elem, "input" ) ) { + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + removeAttr: function( elem, value ) { + var name, + i = 0, + + // Attribute names can contain non-HTML whitespace characters + // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 + attrNames = value && value.match( rnothtmlwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( ( name = attrNames[ i++ ] ) ) { + elem.removeAttribute( name ); + } + } + } +} ); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + elem.setAttribute( name, name ); + } + return name; + } +}; + +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { + var getter = attrHandle[ name ] || jQuery.find.attr; + + attrHandle[ name ] = function( elem, name, isXML ) { + var ret, handle, + lowercaseName = name.toLowerCase(); + + if ( !isXML ) { + + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[ lowercaseName ]; + attrHandle[ lowercaseName ] = ret; + ret = getter( elem, name, isXML ) != null ? + lowercaseName : + null; + attrHandle[ lowercaseName ] = handle; + } + return ret; + }; +} ); + + + + +var rfocusable = /^(?:input|select|textarea|button)$/i, + rclickable = /^(?:a|area)$/i; + +jQuery.fn.extend( { + prop: function( name, value ) { + return access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + return this.each( function() { + delete this[ jQuery.propFix[ name ] || name ]; + } ); + } +} ); + +jQuery.extend( { + prop: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set properties on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + return ( elem[ name ] = value ); + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + return elem[ name ]; + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + + // Support: IE <=9 - 11 only + // elem.tabIndex doesn't always return the + // correct value when it hasn't been explicitly set + // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + if ( tabindex ) { + return parseInt( tabindex, 10 ); + } + + if ( + rfocusable.test( elem.nodeName ) || + rclickable.test( elem.nodeName ) && + elem.href + ) { + return 0; + } + + return -1; + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + } +} ); + +// Support: IE <=11 only +// Accessing the selectedIndex property +// forces the browser to respect setting selected +// on the option +// The getter ensures a default option is selected +// when in an optgroup +// eslint rule "no-unused-expressions" is disabled for this code +// since it considers such accessions noop +if ( !support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent && parent.parentNode ) { + parent.parentNode.selectedIndex; + } + return null; + }, + set: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent ) { + parent.selectedIndex; + + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + }; +} + +jQuery.each( [ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +} ); + + + + + // Strip and collapse whitespace according to HTML spec + // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace + function stripAndCollapse( value ) { + var tokens = value.match( rnothtmlwhite ) || []; + return tokens.join( " " ); + } + + +function getClass( elem ) { + return elem.getAttribute && elem.getAttribute( "class" ) || ""; +} + +function classesToArray( value ) { + if ( Array.isArray( value ) ) { + return value; + } + if ( typeof value === "string" ) { + return value.match( rnothtmlwhite ) || []; + } + return []; +} + +jQuery.fn.extend( { + addClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + if ( !arguments.length ) { + return this.attr( "class", "" ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) > -1 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isValidValue = type === "string" || Array.isArray( value ); + + if ( typeof stateVal === "boolean" && isValidValue ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( isFunction( value ) ) { + return this.each( function( i ) { + jQuery( this ).toggleClass( + value.call( this, i, getClass( this ), stateVal ), + stateVal + ); + } ); + } + + return this.each( function() { + var className, i, self, classNames; + + if ( isValidValue ) { + + // Toggle individual class names + i = 0; + self = jQuery( this ); + classNames = classesToArray( value ); + + while ( ( className = classNames[ i++ ] ) ) { + + // Check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( value === undefined || type === "boolean" ) { + className = getClass( this ); + if ( className ) { + + // Store className if set + dataPriv.set( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || value === false ? + "" : + dataPriv.get( this, "__className__" ) || "" + ); + } + } + } ); + }, + + hasClass: function( selector ) { + var className, elem, + i = 0; + + className = " " + selector + " "; + while ( ( elem = this[ i++ ] ) ) { + if ( elem.nodeType === 1 && + ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { + return true; + } + } + + return false; + } +} ); + + + + +var rreturn = /\r/g; + +jQuery.fn.extend( { + val: function( value ) { + var hooks, ret, valueIsFunction, + elem = this[ 0 ]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || + jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && + "get" in hooks && + ( ret = hooks.get( elem, "value" ) ) !== undefined + ) { + return ret; + } + + ret = elem.value; + + // Handle most common string cases + if ( typeof ret === "string" ) { + return ret.replace( rreturn, "" ); + } + + // Handle cases where value is null/undef or number + return ret == null ? "" : ret; + } + + return; + } + + valueIsFunction = isFunction( value ); + + return this.each( function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( valueIsFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + + } else if ( typeof val === "number" ) { + val += ""; + + } else if ( Array.isArray( val ) ) { + val = jQuery.map( val, function( value ) { + return value == null ? "" : value + ""; + } ); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + } ); + } +} ); + +jQuery.extend( { + valHooks: { + option: { + get: function( elem ) { + + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + + // Support: IE <=10 - 11 only + // option.text throws exceptions (#14686, #14858) + // Strip and collapse whitespace + // https://html.spec.whatwg.org/#strip-and-collapse-whitespace + stripAndCollapse( jQuery.text( elem ) ); + } + }, + select: { + get: function( elem ) { + var value, option, i, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one", + values = one ? null : [], + max = one ? index + 1 : options.length; + + if ( index < 0 ) { + i = max; + + } else { + i = one ? index : 0; + } + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Support: IE <=9 only + // IE8-9 doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + + // Don't return options that are disabled or in a disabled optgroup + !option.disabled && + ( !option.parentNode.disabled || + !nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + + /* eslint-disable no-cond-assign */ + + if ( option.selected = + jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 + ) { + optionSet = true; + } + + /* eslint-enable no-cond-assign */ + } + + // Force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + } +} ); + +// Radios and checkboxes getter/setter +jQuery.each( [ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( Array.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); + } + } + }; + if ( !support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + return elem.getAttribute( "value" ) === null ? "on" : elem.value; + }; + } +} ); + + + + +// Return jQuery for attributes-only inclusion + + +support.focusin = "onfocusin" in window; + + +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + stopPropagationCallback = function( e ) { + e.stopPropagation(); + }; + +jQuery.extend( jQuery.event, { + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; + + cur = lastElement = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "." ) > -1 ) { + + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split( "." ); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf( ":" ) < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join( "." ); + event.rnamespace = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === ( elem.ownerDocument || document ) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { + lastElement = cur; + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] && + dataPriv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( ( !special._default || + special._default.apply( eventPath.pop(), data ) === false ) && + acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + + if ( event.isPropagationStopped() ) { + lastElement.addEventListener( type, stopPropagationCallback ); + } + + elem[ type ](); + + if ( event.isPropagationStopped() ) { + lastElement.removeEventListener( type, stopPropagationCallback ); + } + + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + // Piggyback on a donor event to simulate a different one + // Used only for `focus(in | out)` events + simulate: function( type, elem, event ) { + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true + } + ); + + jQuery.event.trigger( e, null, elem ); + } + +} ); + +jQuery.fn.extend( { + + trigger: function( type, data ) { + return this.each( function() { + jQuery.event.trigger( type, data, this ); + } ); + }, + triggerHandler: function( type, data ) { + var elem = this[ 0 ]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +} ); + + +// Support: Firefox <=44 +// Firefox doesn't have focus(in | out) events +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 +// +// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 +// focus(in | out) events fire after focus & blur events, +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order +// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 +if ( !support.focusin ) { + jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + + // Handle: regular nodes (via `this.ownerDocument`), window + // (via `this.document`) & document (via `this`). + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + dataPriv.remove( doc, fix ); + + } else { + dataPriv.access( doc, fix, attaches ); + } + } + }; + } ); +} +var location = window.location; + +var nonce = { guid: Date.now() }; + +var rquery = ( /\?/ ); + + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml, parserErrorElem; + if ( !data || typeof data !== "string" ) { + return null; + } + + // Support: IE 9 - 11 only + // IE throws on parseFromString with invalid input. + try { + xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); + } catch ( e ) {} + + parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ]; + if ( !xml || parserErrorElem ) { + jQuery.error( "Invalid XML: " + ( + parserErrorElem ? + jQuery.map( parserErrorElem.childNodes, function( el ) { + return el.textContent; + } ).join( "\n" ) : + data + ) ); + } + return xml; +}; + + +var + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( Array.isArray( obj ) ) { + + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + + // Item is non-scalar (array or object), encode its numeric index. + buildParams( + prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", + v, + traditional, + add + ); + } + } ); + + } else if ( !traditional && toType( obj ) === "object" ) { + + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + + // Serialize scalar item. + add( prefix, obj ); + } +} + +// Serialize an array of form elements or a set of +// key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, valueOrFunction ) { + + // If value is a function, invoke it and use its return value + var value = isFunction( valueOrFunction ) ? + valueOrFunction() : + valueOrFunction; + + s[ s.length ] = encodeURIComponent( key ) + "=" + + encodeURIComponent( value == null ? "" : value ); + }; + + if ( a == null ) { + return ""; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + } ); + + } else { + + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ); +}; + +jQuery.fn.extend( { + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map( function() { + + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop( this, "elements" ); + return elements ? jQuery.makeArray( elements ) : this; + } ).filter( function() { + var type = this.type; + + // Use .is( ":disabled" ) so that fieldset[disabled] works + return this.name && !jQuery( this ).is( ":disabled" ) && + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && + ( this.checked || !rcheckableType.test( type ) ); + } ).map( function( _i, elem ) { + var val = jQuery( this ).val(); + + if ( val == null ) { + return null; + } + + if ( Array.isArray( val ) ) { + return jQuery.map( val, function( val ) { + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ); + } + + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ).get(); + } +} ); + + +var + r20 = /%20/g, + rhash = /#.*$/, + rantiCache = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, + + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = "*/".concat( "*" ), + + // Anchor tag for parsing the document origin + originAnchor = document.createElement( "a" ); + +originAnchor.href = location.href; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; + + if ( isFunction( func ) ) { + + // For each dataType in the dataTypeExpression + while ( ( dataType = dataTypes[ i++ ] ) ) { + + // Prepend if requested + if ( dataType[ 0 ] === "+" ) { + dataType = dataType.slice( 1 ) || "*"; + ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); + + // Otherwise append + } else { + ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); + } + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { + + var inspected = {}, + seekingTransport = ( structure === transports ); + + function inspect( dataType ) { + var selected; + inspected[ dataType ] = true; + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); + if ( typeof dataTypeOrTransport === "string" && + !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + + options.dataTypes.unshift( dataTypeOrTransport ); + inspect( dataTypeOrTransport ); + return false; + } else if ( seekingTransport ) { + return !( selected = dataTypeOrTransport ); + } + } ); + return selected; + } + + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } + + return target; +} + +/* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while ( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, + converters = {}, + + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while ( current ) { + + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + current = dataTypes.shift(); + + if ( current ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split( " " ); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.unshift( tmp[ 1 ] ); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s.throws ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { + state: "parsererror", + error: conv ? e : "No conversion from " + prev + " to " + current + }; + } + } + } + } + } + } + + return { state: "success", data: response }; +} + +jQuery.extend( { + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: location.href, + type: "GET", + isLocal: rlocalProtocol.test( location.protocol ), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /\bxml\b/, + html: /\bhtml/, + json: /\bjson\b/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": JSON.parse, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + return settings ? + + // Building a settings object + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : + + // Extending ajaxSettings + ajaxExtend( jQuery.ajaxSettings, target ); + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var transport, + + // URL without anti-cache param + cacheURL, + + // Response headers + responseHeadersString, + responseHeaders, + + // timeout handle + timeoutTimer, + + // Url cleanup var + urlAnchor, + + // Request state (becomes false upon send and true upon completion) + completed, + + // To know if global events are to be dispatched + fireGlobals, + + // Loop variable + i, + + // uncached part of the url + uncached, + + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + + // Callbacks context + callbackContext = s.context || s, + + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && + ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + + // Status-dependent callbacks + statusCode = s.statusCode || {}, + + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + + // Default abort message + strAbort = "canceled", + + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( completed ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while ( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[ 1 ].toLowerCase() + " " ] = + ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) + .concat( match[ 2 ] ); + } + } + match = responseHeaders[ key.toLowerCase() + " " ]; + } + return match == null ? null : match.join( ", " ); + }, + + // Raw string + getAllResponseHeaders: function() { + return completed ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( completed == null ) { + name = requestHeadersNames[ name.toLowerCase() ] = + requestHeadersNames[ name.toLowerCase() ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( completed == null ) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function( map ) { + var code; + if ( map ) { + if ( completed ) { + + // Execute the appropriate callbacks + jqXHR.always( map[ jqXHR.status ] ); + } else { + + // Lazy-add the new callbacks in a way that preserves old ones + for ( code in map ) { + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } + } + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + var finalText = statusText || strAbort; + if ( transport ) { + transport.abort( finalText ); + } + done( 0, finalText ); + return this; + } + }; + + // Attach deferreds + deferred.promise( jqXHR ); + + // Add protocol if not provided (prefilters might expect it) + // Handle falsy url in the settings object (#10093: consistency with old signature) + // We also use the url parameter if available + s.url = ( ( url || s.url || location.href ) + "" ) + .replace( rprotocol, location.protocol + "//" ); + + // Alias method option to type as per ticket #12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; + + // A cross-domain request is in order when the origin doesn't match the current origin. + if ( s.crossDomain == null ) { + urlAnchor = document.createElement( "a" ); + + // Support: IE <=8 - 11, Edge 12 - 15 + // IE throws exception on accessing the href property if url is malformed, + // e.g. http://example.com:80x/ + try { + urlAnchor.href = s.url; + + // Support: IE <=8 - 11 only + // Anchor's host property isn't correctly set when s.url is relative + urlAnchor.href = urlAnchor.href; + s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== + urlAnchor.protocol + "//" + urlAnchor.host; + } catch ( e ) { + + // If there is an error parsing the URL, assume it is crossDomain, + // it can be rejected by the transport if it is invalid + s.crossDomain = true; + } + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( completed ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + // Remove hash to simplify url manipulation + cacheURL = s.url.replace( rhash, "" ); + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // Remember the hash so we can put it back + uncached = s.url.slice( cacheURL.length ); + + // If data is available and should be processed, append data to url + if ( s.data && ( s.processData || typeof s.data === "string" ) ) { + cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; + + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add or update anti-cache param if needed + if ( s.cache === false ) { + cacheURL = cacheURL.replace( rantiCache, "$1" ); + uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + + uncached; + } + + // Put hash and anti-cache on the URL that will be requested (gh-1732) + s.url = cacheURL + uncached; + + // Change '%20' to '+' if this is encoded form body content (gh-2658) + } else if ( s.data && s.processData && + ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { + s.data = s.data.replace( r20, "+" ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery.lastModified[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); + } + if ( jQuery.etag[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? + s.accepts[ s.dataTypes[ 0 ] ] + + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && + ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { + + // Abort if not done already and return + return jqXHR.abort(); + } + + // Aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + completeDeferred.add( s.complete ); + jqXHR.done( s.success ); + jqXHR.fail( s.error ); + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + + // If request was aborted inside ajaxSend, stop there + if ( completed ) { + return jqXHR; + } + + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = window.setTimeout( function() { + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + completed = false; + transport.send( requestHeaders, done ); + } catch ( e ) { + + // Rethrow post-completion exceptions + if ( completed ) { + throw e; + } + + // Propagate others as results + done( -1, e ); + } + } + + // Callback for when everything is done + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Ignore repeat invocations + if ( completed ) { + return; + } + + completed = true; + + // Clear timeout if it exists + if ( timeoutTimer ) { + window.clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // Use a noop converter for missing script but not if jsonp + if ( !isSuccess && + jQuery.inArray( "script", s.dataTypes ) > -1 && + jQuery.inArray( "json", s.dataTypes ) < 0 ) { + s.converters[ "text script" ] = function() {}; + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + + // If successful, handle type chaining + if ( isSuccess ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + modified = jqXHR.getResponseHeader( "Last-Modified" ); + if ( modified ) { + jQuery.lastModified[ cacheURL ] = modified; + } + modified = jqXHR.getResponseHeader( "etag" ); + if ( modified ) { + jQuery.etag[ cacheURL ] = modified; + } + } + + // if no content + if ( status === 204 || s.type === "HEAD" ) { + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + + // Extract error from statusText and normalize for non-aborts + error = statusText; + if ( status || !statusText ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + return jqXHR; + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + } +} ); + +jQuery.each( [ "get", "post" ], function( _i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + + // Shift arguments if data argument was omitted + if ( isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + // The url can be an options object (which then must have .url) + return jQuery.ajax( jQuery.extend( { + url: url, + type: method, + dataType: type, + data: data, + success: callback + }, jQuery.isPlainObject( url ) && url ) ); + }; +} ); + +jQuery.ajaxPrefilter( function( s ) { + var i; + for ( i in s.headers ) { + if ( i.toLowerCase() === "content-type" ) { + s.contentType = s.headers[ i ] || ""; + } + } +} ); + + +jQuery._evalUrl = function( url, options, doc ) { + return jQuery.ajax( { + url: url, + + // Make this explicit, since user can override this through ajaxSetup (#11264) + type: "GET", + dataType: "script", + cache: true, + async: false, + global: false, + + // Only evaluate the response if it is successful (gh-4126) + // dataFilter is not invoked for failure responses, so using it instead + // of the default converter is kludgy but it works. + converters: { + "text script": function() {} + }, + dataFilter: function( response ) { + jQuery.globalEval( response, options, doc ); + } + } ); +}; + + +jQuery.fn.extend( { + wrapAll: function( html ) { + var wrap; + + if ( this[ 0 ] ) { + if ( isFunction( html ) ) { + html = html.call( this[ 0 ] ); + } + + // The elements to wrap the target around + wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); + + if ( this[ 0 ].parentNode ) { + wrap.insertBefore( this[ 0 ] ); + } + + wrap.map( function() { + var elem = this; + + while ( elem.firstElementChild ) { + elem = elem.firstElementChild; + } + + return elem; + } ).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( isFunction( html ) ) { + return this.each( function( i ) { + jQuery( this ).wrapInner( html.call( this, i ) ); + } ); + } + + return this.each( function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + } ); + }, + + wrap: function( html ) { + var htmlIsFunction = isFunction( html ); + + return this.each( function( i ) { + jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); + } ); + }, + + unwrap: function( selector ) { + this.parent( selector ).not( "body" ).each( function() { + jQuery( this ).replaceWith( this.childNodes ); + } ); + return this; + } +} ); + + +jQuery.expr.pseudos.hidden = function( elem ) { + return !jQuery.expr.pseudos.visible( elem ); +}; +jQuery.expr.pseudos.visible = function( elem ) { + return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); +}; + + + + +jQuery.ajaxSettings.xhr = function() { + try { + return new window.XMLHttpRequest(); + } catch ( e ) {} +}; + +var xhrSuccessStatus = { + + // File protocol always yields status code 0, assume 200 + 0: 200, + + // Support: IE <=9 only + // #1450: sometimes IE returns 1223 when it should be 204 + 1223: 204 + }, + xhrSupported = jQuery.ajaxSettings.xhr(); + +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); +support.ajax = xhrSupported = !!xhrSupported; + +jQuery.ajaxTransport( function( options ) { + var callback, errorCallback; + + // Cross domain only allowed if supported through XMLHttpRequest + if ( support.cors || xhrSupported && !options.crossDomain ) { + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(); + + xhr.open( + options.type, + options.url, + options.async, + options.username, + options.password + ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Set headers + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + + // Callback + callback = function( type ) { + return function() { + if ( callback ) { + callback = errorCallback = xhr.onload = + xhr.onerror = xhr.onabort = xhr.ontimeout = + xhr.onreadystatechange = null; + + if ( type === "abort" ) { + xhr.abort(); + } else if ( type === "error" ) { + + // Support: IE <=9 only + // On a manual native abort, IE9 throws + // errors on any property access that is not readyState + if ( typeof xhr.status !== "number" ) { + complete( 0, "error" ); + } else { + complete( + + // File: protocol always yields status 0; see #8605, #14207 + xhr.status, + xhr.statusText + ); + } + } else { + complete( + xhrSuccessStatus[ xhr.status ] || xhr.status, + xhr.statusText, + + // Support: IE <=9 only + // IE9 has no XHR2 but throws on binary (trac-11426) + // For XHR2 non-text, let the caller handle it (gh-2498) + ( xhr.responseType || "text" ) !== "text" || + typeof xhr.responseText !== "string" ? + { binary: xhr.response } : + { text: xhr.responseText }, + xhr.getAllResponseHeaders() + ); + } + } + }; + }; + + // Listen to events + xhr.onload = callback(); + errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); + + // Support: IE 9 only + // Use onreadystatechange to replace onabort + // to handle uncaught aborts + if ( xhr.onabort !== undefined ) { + xhr.onabort = errorCallback; + } else { + xhr.onreadystatechange = function() { + + // Check readyState before timeout as it changes + if ( xhr.readyState === 4 ) { + + // Allow onerror to be called first, + // but that will not handle a native abort + // Also, save errorCallback to a variable + // as xhr.onerror cannot be accessed + window.setTimeout( function() { + if ( callback ) { + errorCallback(); + } + } ); + } + }; + } + + // Create the abort callback + callback = callback( "abort" ); + + try { + + // Do send the request (this may raise an exception) + xhr.send( options.hasContent && options.data || null ); + } catch ( e ) { + + // #14683: Only rethrow if this hasn't been notified as an error yet + if ( callback ) { + throw e; + } + } + }, + + abort: function() { + if ( callback ) { + callback(); + } + } + }; + } +} ); + + + + +// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) +jQuery.ajaxPrefilter( function( s ) { + if ( s.crossDomain ) { + s.contents.script = false; + } +} ); + +// Install script dataType +jQuery.ajaxSetup( { + accepts: { + script: "text/javascript, application/javascript, " + + "application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /\b(?:java|ecma)script\b/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +} ); + +// Handle cache's special case and crossDomain +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + } +} ); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function( s ) { + + // This transport only deals with cross domain or forced-by-attrs requests + if ( s.crossDomain || s.scriptAttrs ) { + var script, callback; + return { + send: function( _, complete ) { + script = jQuery( " + + + + + + + + + + + + + + + +
+
+
+ + +
+ + +

Index

+ +
+ +
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/sphinx/_build/html/index.html b/sphinx/_build/html/index.html new file mode 100644 index 00000000..5d5bd868 --- /dev/null +++ b/sphinx/_build/html/index.html @@ -0,0 +1,124 @@ + + + + + + + + + Welcome to phenopacket-tools’s documentation! — phenopacket-tools documentation + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

Welcome to phenopacket-tools’s documentation!

+
+

Contents:

+ +
+
+
+

Indices and tables

+ +
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/sphinx/_build/html/modules.html b/sphinx/_build/html/modules.html new file mode 100644 index 00000000..0ce3b5de --- /dev/null +++ b/sphinx/_build/html/modules.html @@ -0,0 +1,112 @@ + + + + + + + + + phenopacket-tools — phenopacket-tools documentation + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

phenopacket-tools

+
+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/sphinx/_build/html/objects.inv b/sphinx/_build/html/objects.inv new file mode 100644 index 0000000000000000000000000000000000000000..3e1dfc15f0272ecbc63a4e1178a67bd3a90fc415 GIT binary patch literal 285 zcmY#Z2rkIT%&Sny%qvUHE6FdaR47X=D$dN$Q!wIERtPA{&q_@$u~I0=NX^SHNKDR7 zEzvE>&(A3aN`^rcS}6e8AsML(MX9-onRzLxMGE<83MCnt#R_SeIjIUjIypbLpeVJt zI5kC~v^X;_U7;!`Gf9uD;#O;)Hy@KCPuur7i{u!Dx8FO^dQwF%M%lzbP-CLsqc_i_ z;?7Tg!QrMhYe)8f_x({lwI&ss7bQhpcSbe_+wh g@9bB4-)QJnN?vu{ow_k&X|YD#a-A-AmD6QP0A2@oA^-pY literal 0 HcmV?d00001 diff --git a/sphinx/_build/html/search.html b/sphinx/_build/html/search.html new file mode 100644 index 00000000..1768ff1d --- /dev/null +++ b/sphinx/_build/html/search.html @@ -0,0 +1,124 @@ + + + + + + + + Search — phenopacket-tools documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +

Search

+ + + + +

+ Searching for multiple words only shows matches that contain + all words. +

+ + +
+ + + +
+ + + +
+ +
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/sphinx/_build/html/searchindex.js b/sphinx/_build/html/searchindex.js new file mode 100644 index 00000000..158f9dac --- /dev/null +++ b/sphinx/_build/html/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"docnames": ["index", "modules"], "filenames": ["index.rst", "modules.rst"], "titles": ["Welcome to phenopacket-tools\u2019s documentation!", "phenopacket-tools"], "terms": {"index": 0, "modul": 0, "search": 0, "page": 0}, "objects": {}, "objtypes": {}, "objnames": {}, "titleterms": {"welcom": 0, "phenopacket": [0, 1], "tool": [0, 1], "": 0, "document": 0, "content": 0, "indic": 0, "tabl": 0}, "envversion": {"sphinx.domains.c": 2, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 6, "sphinx.domains.index": 1, "sphinx.domains.javascript": 2, "sphinx.domains.math": 2, "sphinx.domains.python": 3, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx": 56}}) \ No newline at end of file diff --git a/sphinx/conf.py b/sphinx/conf.py new file mode 100644 index 00000000..e8c28f3f --- /dev/null +++ b/sphinx/conf.py @@ -0,0 +1,43 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +############# +# JR added: +import os +import sys + +sys.path.insert(0, os.path.abspath('../../')) +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.githubpages', + 'sphinx_rtd_theme', + 'recommonmark' +] + +html_theme = 'sphinx_rtd_theme' +############## + +project = 'phenopacket-tools' +copyright = '2022, Peter Robinson' +author = 'Peter Robinson' + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [] + +templates_path = ['_templates'] +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + + + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = 'alabaster' +html_static_path = ['_static'] diff --git a/sphinx/conf.py~ b/sphinx/conf.py~ new file mode 100644 index 00000000..f065bbd0 --- /dev/null +++ b/sphinx/conf.py~ @@ -0,0 +1,41 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +############# +# JR added: +import os +import sys + +sys.path.insert(0, os.path.abspath('../../')) +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.githubpages', + 'sphinx_rtd_theme', + 'recommonmark' +] +############## + +project = 'phenopacket-tools' +copyright = '2022, Peter Robinson' +author = 'Peter Robinson' + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [] + +templates_path = ['_templates'] +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + + + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = 'alabaster' +html_static_path = ['_static'] diff --git a/sphinx/index.rst b/sphinx/index.rst new file mode 100644 index 00000000..bf2187bd --- /dev/null +++ b/sphinx/index.rst @@ -0,0 +1,22 @@ +.. phenopacket-tools documentation master file, created by + sphinx-quickstart on Fri Aug 12 11:03:28 2022. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to phenopacket-tools's documentation! +============================================= + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + static/intro.md + + modules + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/sphinx/index.rst~ b/sphinx/index.rst~ new file mode 100644 index 00000000..1bff6fd4 --- /dev/null +++ b/sphinx/index.rst~ @@ -0,0 +1,20 @@ +.. phenopacket-tools documentation master file, created by + sphinx-quickstart on Fri Aug 12 11:03:28 2022. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to phenopacket-tools's documentation! +============================================= + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/sphinx/make.bat b/sphinx/make.bat new file mode 100644 index 00000000..32bb2452 --- /dev/null +++ b/sphinx/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/sphinx/modules.rst b/sphinx/modules.rst new file mode 100644 index 00000000..80f38119 --- /dev/null +++ b/sphinx/modules.rst @@ -0,0 +1,6 @@ +phenopacket-tools +================= + +.. toctree:: + :maxdepth: 4 + From f8ab69777b2700187a05a1699711655260829e79 Mon Sep 17 00:00:00 2001 From: Justin Reese Date: Fri, 12 Aug 2022 11:17:04 -0400 Subject: [PATCH 093/155] Create pages.yml --- .github/workflows/pages.yml | 42 +++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 .github/workflows/pages.yml diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml new file mode 100644 index 00000000..e9285990 --- /dev/null +++ b/.github/workflows/pages.yml @@ -0,0 +1,42 @@ +# Simple workflow for deploying static content to GitHub Pages +name: Deploy static content to Pages + +on: + # Runs on pushes targeting the default branch + push: + branches: ["main"] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow one concurrent deployment +concurrency: + group: "pages" + cancel-in-progress: true + +jobs: + # Single deploy job since we're just deploying + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Setup Pages + uses: actions/configure-pages@v1 + - name: Upload artifact + uses: actions/upload-pages-artifact@v1 + with: + # Upload entire repository + path: '.' + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@main From 67a3568f6f0836676ed310b2f4897eefdcdf1b2b Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Fri, 12 Aug 2022 11:40:30 -0400 Subject: [PATCH 094/155] adding HPO Ontology validator --- phenopacket-tools-validator-core/pom.xml | 7 +- .../src/main/java/module-info.java | 1 + .../core/DefaultValidatorRunner.java | 11 +-- .../validator/core/HpoPhenotypeValidator.java | 67 +++++++++++++++++++ .../validator/core/PhenopacketValidator.java | 3 +- .../validator/core/ValidationResult.java | 5 +- .../validator/core/ValidatorInfo.java | 3 + .../validator/core/errors/JsonError.java | 4 +- .../validator/core/errors/OntologyError.java | 28 -------- .../core/errors/OntologyValidationResult.java | 58 ++++++++++++++++ .../core/impl/DefaultPhenopacketIngestor.java | 4 +- .../{ => impl}/DefaultValidationInfo.java | 14 ++-- .../validator/core/impl/Ingestor.java | 4 +- .../jsonschema/JsonSchemaValidator.java | 3 +- pom.xml | 8 ++- 15 files changed, 164 insertions(+), 56 deletions(-) create mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/HpoPhenotypeValidator.java delete mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/OntologyError.java create mode 100644 phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/OntologyValidationResult.java rename phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/{ => impl}/DefaultValidationInfo.java (78%) diff --git a/phenopacket-tools-validator-core/pom.xml b/phenopacket-tools-validator-core/pom.xml index 02cb5dfc..5094252d 100644 --- a/phenopacket-tools-validator-core/pom.xml +++ b/phenopacket-tools-validator-core/pom.xml @@ -32,14 +32,15 @@ com.fasterxml.jackson.core jackson-core - ${jackson.version} com.fasterxml.jackson.core jackson-databind - ${jackson.version} - + + org.monarchinitiative.phenol + phenol-core + \ No newline at end of file diff --git a/phenopacket-tools-validator-core/src/main/java/module-info.java b/phenopacket-tools-validator-core/src/main/java/module-info.java index 11891178..3b940cf4 100644 --- a/phenopacket-tools-validator-core/src/main/java/module-info.java +++ b/phenopacket-tools-validator-core/src/main/java/module-info.java @@ -8,6 +8,7 @@ requires com.google.protobuf.util; requires org.phenopackets.schema; requires com.fasterxml.jackson.databind; + requires org.monarchinitiative.phenol.core; opens org.phenopackets.phenopackettools.validator.core; diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidatorRunner.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidatorRunner.java index 6067f2ea..5a45fdf2 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidatorRunner.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidatorRunner.java @@ -6,6 +6,7 @@ import org.phenopackets.phenopackettools.validator.core.impl.DefaultPhenopacketIngestor; import org.phenopackets.phenopackettools.validator.core.impl.Ingestor; import org.phenopackets.phenopackettools.validator.core.PhenopacketValidator; +import org.phenopackets.schema.v2.Phenopacket; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,7 +37,7 @@ public List validate(InputStream stream) { try { Ingestor ingestor = new DefaultPhenopacketIngestor(stream); JsonNode jsonNode = ingestor.jsonNode(); - Message message = ingestor.message(); + Phenopacket message = ingestor.message(); return validateImpl(jsonNode, message); } catch (PhenopacketValidatorException e) { return List.of(ValidationResult.inputError(e.getMessage())); @@ -48,7 +49,7 @@ public List validate(byte[] content) { try { Ingestor ingestor = new DefaultPhenopacketIngestor(content); JsonNode jsonNode = ingestor.jsonNode(); - Message message = ingestor.message(); + Phenopacket message = ingestor.message(); return validateImpl(jsonNode, message); } catch (PhenopacketValidatorException e) { return List.of(ValidationResult.inputError(e.getMessage())); @@ -60,7 +61,7 @@ public List validate(byte[] content, Charset charset) { try { Ingestor ingestor = new DefaultPhenopacketIngestor(content, charset); JsonNode jsonNode = ingestor.jsonNode(); - Message message = ingestor.message(); + Phenopacket message = ingestor.message(); return validateImpl(jsonNode, message); } catch (PhenopacketValidatorException e) { return List.of(ValidationResult.inputError(e.getMessage())); @@ -72,7 +73,7 @@ public List validate(String content) { try { Ingestor ingestor = new DefaultPhenopacketIngestor(content); JsonNode jsonNode = ingestor.jsonNode(); - Message message = ingestor.message(); + Phenopacket message = ingestor.message(); return validateImpl(jsonNode, message); } catch (PhenopacketValidatorException e) { return List.of(ValidationResult.inputError(e.getMessage())); @@ -96,7 +97,7 @@ public List validate(File file) { } - private List validateImpl(JsonNode jsonNode, Message message) { + private List validateImpl(JsonNode jsonNode, Phenopacket message) { List results = new ArrayList<>(); for (var validator : jsonValidators) { results.addAll(validator.validateJson(jsonNode)); diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/HpoPhenotypeValidator.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/HpoPhenotypeValidator.java new file mode 100644 index 00000000..90ea189d --- /dev/null +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/HpoPhenotypeValidator.java @@ -0,0 +1,67 @@ +package org.phenopackets.phenopackettools.validator.core; + +import com.fasterxml.jackson.databind.JsonNode; +import org.monarchinitiative.phenol.ontology.data.Ontology; +import org.monarchinitiative.phenol.ontology.data.TermId; +import org.phenopackets.phenopackettools.validator.core.errors.OntologyValidationResult; +import org.phenopackets.phenopackettools.validator.core.impl.DefaultValidationInfo; +import org.phenopackets.schema.v2.core.OntologyClass; +import org.phenopackets.schema.v2.core.PhenotypicFeature; +import org.phenopackets.schema.v2.Phenopacket; + +import java.util.ArrayList; +import java.util.List; + +public class HpoPhenotypeValidator implements PhenopacketValidator { + + + private static final ValidatorInfo hpoValidatorInfo = + DefaultValidationInfo.of("HpoPhenotypeValidator", "HPO Phenotypic feature validator"); + + + private final Ontology hpo; + + private final String hpoVersion; + + + HpoPhenotypeValidator(Ontology ontology) { + this.hpo = ontology; + this.hpoVersion = this.hpo.getMetaInfo().getOrDefault("data-version", "HPO"); + } + + + /** + * This validator expects to get a Phenopacket message as input and should only be called + * via the other function + */ + @Override + public List validateJson(JsonNode jsonNode) { + return List.of(); + } + + @Override + public List validateMessage(Phenopacket phenopacket) { + List features = phenopacket.getPhenotypicFeaturesList(); + List errors = new ArrayList<>(); + // check that all terms have the current primary ID + for (var feature: features) { + OntologyClass clz = feature.getType(); + TermId tid = TermId.of(clz.getId()); + if (! hpo.containsTerm(tid)) { + String msg = String.format("%s not found in %s", tid.getValue(), this.hpoVersion); + OntologyValidationResult res = OntologyValidationResult.invalidTermId(hpoValidatorInfo,msg); + errors.add(res); + } + // check if we are using the current primary id + // this is a warning + TermId primaryId = hpo.getPrimaryTermId(tid); + if (! primaryId.equals(tid)) { + String msg = String.format("Using obsoleted id (%s) instead of current primary id (%s)", + tid.getValue(), primaryId.getValue()); + OntologyValidationResult res = OntologyValidationResult.obsoletedTermId(hpoValidatorInfo,msg); + errors.add(res); + } + } + return errors; + } +} diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidator.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidator.java index e681920b..1a2ddbf8 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidator.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/PhenopacketValidator.java @@ -2,12 +2,13 @@ import com.google.protobuf.Message; import com.fasterxml.jackson.databind.JsonNode; +import org.phenopackets.schema.v2.Phenopacket; import java.util.List; public interface PhenopacketValidator { List validateJson(JsonNode jsonNode); - List validateMessage(Message message); + List validateMessage(Phenopacket phenopacket); } diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationResult.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationResult.java index 0656217a..41b532f0 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationResult.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidationResult.java @@ -1,7 +1,7 @@ package org.phenopackets.phenopackettools.validator.core; import org.phenopackets.phenopackettools.validator.core.errors.InputError; -import org.phenopackets.phenopackettools.validator.core.errors.OntologyError; +import org.phenopackets.phenopackettools.validator.core.errors.OntologyValidationResult; public interface ValidationResult { @@ -15,9 +15,6 @@ public interface ValidationResult { String message(); - static ValidationResult ontologyError(String message) { - return OntologyError.of(message); - } static ValidationResult inputError(String message) { return new InputError(message); diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorInfo.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorInfo.java index 7b28724f..463fae98 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorInfo.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/ValidatorInfo.java @@ -1,5 +1,7 @@ package org.phenopackets.phenopackettools.validator.core; +import org.phenopackets.phenopackettools.validator.core.impl.DefaultValidationInfo; + public interface ValidatorInfo { static ValidatorInfo genericJsonSchema() { @@ -18,6 +20,7 @@ static ValidatorInfo rareDiseaseValidation() { static ValidatorInfo inputValidator() { return DefaultValidationInfo.inputValidator(); } + static ValidatorInfo of(String validatorId, String validatorName) { return DefaultValidationInfo.of(validatorId, validatorName); } diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/JsonError.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/JsonError.java index 465856f7..9c63e2be 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/JsonError.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/JsonError.java @@ -19,8 +19,8 @@ public class JsonError implements ValidationResult { private final String message; - public JsonError(String subcategory, String message) { - this.category = subcategory; + public JsonError(String category, String message) { + this.category = category; this.message = message; } diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/OntologyError.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/OntologyError.java deleted file mode 100644 index d7b5358c..00000000 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/OntologyError.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.phenopackets.phenopackettools.validator.core.errors; - -import org.phenopackets.phenopackettools.validator.core.ValidationLevel; -import org.phenopackets.phenopackettools.validator.core.ValidationResult; -import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; - -public record OntologyError(String category, - String subcategory, - String message) implements ValidationResult { - - - // - - public static OntologyError of(String message) { - return new OntologyError("invalid ontology", "todo-subcat", message); - } - - - @Override - public ValidatorInfo validationInfo() { - return null; - } - - @Override - public ValidationLevel level() { - return null; - } -} diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/OntologyValidationResult.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/OntologyValidationResult.java new file mode 100644 index 00000000..00a64c01 --- /dev/null +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/errors/OntologyValidationResult.java @@ -0,0 +1,58 @@ +package org.phenopackets.phenopackettools.validator.core.errors; + +import org.phenopackets.phenopackettools.validator.core.ValidationLevel; +import org.phenopackets.phenopackettools.validator.core.ValidationResult; +import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; + +public class OntologyValidationResult implements ValidationResult { + + + private final ValidatorInfo info; + private final String message; + + private final String category; + private final ValidationLevel level; + + + private OntologyValidationResult(ValidatorInfo info,String category, ValidationLevel level, String message) { + this.info = info; + this.category = category; + this.level = level; + this.message = message; + } + + + @Override + public ValidatorInfo validationInfo() { + return this.info; + } + + @Override + public ValidationLevel level() { + return this.level; + } + + @Override + public String category() { + return this.category; + } + + @Override + public String message() { + return this.message; + } + + + public static OntologyValidationResult invalidTermId(ValidatorInfo info, String msg) { + return new OntologyValidationResult(info, "invalid TermId", + ValidationLevel.VALIDATION_ERROR, msg); + } + + public static OntologyValidationResult obsoletedTermId(ValidatorInfo info, String msg) { + return new OntologyValidationResult(info, "obsoleted TermId", + ValidationLevel.VALIDATION_WARNING, msg); + } + + + +} diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/DefaultPhenopacketIngestor.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/DefaultPhenopacketIngestor.java index 6494cf82..120a5904 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/DefaultPhenopacketIngestor.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/DefaultPhenopacketIngestor.java @@ -25,7 +25,7 @@ public class DefaultPhenopacketIngestor implements Ingestor { private final JsonNode jsonNode; - private final Message message; + private final Phenopacket message; public DefaultPhenopacketIngestor(InputStream stream) throws PhenopacketValidatorInputException { @@ -147,7 +147,7 @@ public JsonNode jsonNode() { } @Override - public Message message() { + public Phenopacket message() { return this.message; } diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidationInfo.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/DefaultValidationInfo.java similarity index 78% rename from phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidationInfo.java rename to phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/DefaultValidationInfo.java index 71428dcb..66f1decb 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/DefaultValidationInfo.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/DefaultValidationInfo.java @@ -1,8 +1,10 @@ -package org.phenopackets.phenopackettools.validator.core; +package org.phenopackets.phenopackettools.validator.core.impl; + +import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; import java.util.Objects; -class DefaultValidationInfo implements ValidatorInfo { +public class DefaultValidationInfo implements ValidatorInfo { private static final DefaultValidationInfo GENERIC = of("GENERIC", "Validation of a generic Phenopacket"); private static final DefaultValidationInfo RARE_DISEASE_VALIDATOR = of("RARE_DISEASE_VALIDATOR", "Validation of rare disease Phenopacket constraints"); @@ -10,20 +12,20 @@ class DefaultValidationInfo implements ValidatorInfo { private static final DefaultValidationInfo INPUT_VALIDATOR = of("Input", "Input of phenopacket data"); - static ValidatorInfo generic() { + public static ValidatorInfo generic() { return GENERIC; } - static ValidatorInfo rareDiseaseValidator() { + public static ValidatorInfo rareDiseaseValidator() { return RARE_DISEASE_VALIDATOR; } - static ValidatorInfo inputValidator() { return INPUT_VALIDATOR; } + public static ValidatorInfo inputValidator() { return INPUT_VALIDATOR; } private final String validatorId; private final String validatorName; - static DefaultValidationInfo of(String validatorId, String validatorName) { + public static DefaultValidationInfo of(String validatorId, String validatorName) { return new DefaultValidationInfo(validatorId, validatorName); } diff --git a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/Ingestor.java b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/Ingestor.java index d122e1f7..f0202238 100644 --- a/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/Ingestor.java +++ b/phenopacket-tools-validator-core/src/main/java/org/phenopackets/phenopackettools/validator/core/impl/Ingestor.java @@ -1,11 +1,11 @@ package org.phenopackets.phenopackettools.validator.core.impl; import com.fasterxml.jackson.databind.JsonNode; -import com.google.protobuf.Message; +import org.phenopackets.schema.v2.Phenopacket; public interface Ingestor { JsonNode jsonNode(); - Message message(); + Phenopacket message(); } diff --git a/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidator.java b/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidator.java index 0c3770f5..92cffe29 100644 --- a/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidator.java +++ b/phenopacket-tools-validator-jsonschema/src/main/java/org/phenopackets/phenopackettools/validator/jsonschema/JsonSchemaValidator.java @@ -11,6 +11,7 @@ import org.phenopackets.phenopackettools.validator.core.ValidationResult; import org.phenopackets.phenopackettools.validator.core.ValidatorInfo; import org.phenopackets.phenopackettools.validator.core.except.PhenopacketValidatorRuntimeException; +import org.phenopackets.schema.v2.Phenopacket; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -98,7 +99,7 @@ public List validateJson(JsonNode jsonNode) { * @return empty list */ @Override - public List validateMessage(Message message) { + public List validateMessage(Phenopacket message) { return List.of(); } } diff --git a/pom.xml b/pom.xml index f06de4ea..98f8f098 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ 3.21.1 2.0.2 2.13.3 - + 2.0.0-RC3 5.7.1 @@ -175,7 +175,11 @@ json-schema-validator 1.0.42 - + + org.monarchinitiative.phenol + phenol-core + ${phenol.version} + info.picocli picocli From b109f822b06d53ed46e4ee2a605e078691c34f25 Mon Sep 17 00:00:00 2001 From: pnrobinson Date: Tue, 6 Sep 2022 10:59:07 -0400 Subject: [PATCH 095/155] JSON Schema for vrsatile --- .../src/main/resources/schema/versatile.json | 200 ++++++++++++++++++ 1 file changed, 200 insertions(+) create mode 100644 phenopacket-tools-validator-jsonschema/src/main/resources/schema/versatile.json diff --git a/phenopacket-tools-validator-jsonschema/src/main/resources/schema/versatile.json b/phenopacket-tools-validator-jsonschema/src/main/resources/schema/versatile.json new file mode 100644 index 00000000..49d4dd18 --- /dev/null +++ b/phenopacket-tools-validator-jsonschema/src/main/resources/schema/versatile.json @@ -0,0 +1,200 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema#", + "$id": "https://www.ga4gh.org/phenopackets", + "title": "Phenopacket", + "description": "Schema for Global Alliance for Genomics and Health (GA4GH) Phenopacket", + "type": "object", + "definitions": { + "extension": { + "type": "object", + "properties": { + "name": { + "description": "Name of an Extension attribute", + "type": "string" + }, + "value": { + "description": "Value of the attribute", + "type": "string" + } + }, + "required": [ + "name", + "value" + ], + "additionalProperties": false + }, + "expression": { + "type": "object", + "properties": { + "syntax" : { + "description": "Name of an nomenclature/syntax (e.g., HGVS or ISCN)", + "type": "string" + }, + "value": { + "description": "An expression in the indicated syntax, e.g., an HGVS string", + "type": "string" + }, + "version": { + "description": "Version of the nomenclature/syntax ", + "type": "string" + } + }, + "required": [ + "syntax", + "value" + ], + "additionalProperties": false + }, + "vcfRecord": { + "type": "object", + "properties": { + "genomeAssembly": { + "description": "genome version, e.g. hg19, GRCh38", + "type": "string" + }, + "chrom" : { + "description": "chromosome", + "type": "string" + }, + "pos" : { + "description": "position on the chromosome (VCF convention)", + "type": "integer" + }, + "id" : { + "description": "identifier as used in VCF line", + "type": "string" + }, + "ref" : { + "description": "reference sequence", + "type": "string" + }, + "alt" : { + "description": "alternate sequence", + "type": "string" + }, + "qual" : { + "description": "PHRED quality of the variant", + "type": "string" + }, + "filter" : { + "description": "filter (as per VCF specification)", + "type": "string" + }, + "info" : { + "description": "information field of VCF line", + "type": "string" + } + }, + "required": [ + "genomeAssembly", "chrom", "pos", "ref", "alt" + ], + "additionalProperties": false + }, + "variationDescriptor": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "variation": { + "type": "object", + "description": "TODO IMPORT THIS" + }, + "label": { + "type": "string" + }, + "expressions": { + "type": "array", + "items": { + "$ref": "#/definitions/expression" + }, + "minItems": 0 + }, + "vcfRecord": { + "type": { + "$ref": "#/definitions/vcfRecord" + } + }, + "xrefs": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 0 + }, + "alternateLabels": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 0 + }, + "extensions": { + "type": "array", + "items": { + "$ref": "#/definitions/extension" + }, + "minItems": 0 + }, + "moleculeContext": { + "enum": [ + "unspecified_molecule_context", + "genomic", + "transcript", + "protein" + ] + }, + "structuralType" : { + "type": "object", + "description": "TODO IMPORT THIS OntologyClass" + }, + "vrs_ref_allele_seq": { + "type": "string", + "description": "A Sequence corresponding to a “ref allele”, describing the sequence expected at a SequenceLocation reference" + }, + "allelicState" : { + "type": "object", + "description": "TODO IMPORT THIS OntologyClass" + } + } + }, + "geneDescriptor" : { + "type": "object", + "properties": { + "valueId": { + "type": "string", + "description": "The official gene identifier as designated by the organism gene nomenclature committee e.g. HGNC:3477 or MGI:2385071" + }, + "symbol": { + "type": "string", + "description": "The primary gene symbol" + }, + "description": { + "type": "string", + "description": "Free-text description" + }, + "alternateIds" : { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 0 + }, + "alternateSymbols" : { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 0 + }, + "xrefs" : { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 0 + } + } + } + } +} \ No newline at end of file From b79d670fc99889d9b2c598bdaf8384782e95875e Mon Sep 17 00:00:00 2001 From: pnrobinson Date: Tue, 6 Sep 2022 11:27:58 -0400 Subject: [PATCH 096/155] finalizing JSON Schema --- .../schema/phenopacket-schema-2-0.json | 57 +- .../src/main/resources/schema/versatile.json | 11 +- .../src/main/resources/schema/vrs.json | 980 ++++++++++++++++++ 3 files changed, 1028 insertions(+), 20 deletions(-) create mode 100644 phenopacket-tools-validator-jsonschema/src/main/resources/schema/vrs.json diff --git a/phenopacket-tools-validator-jsonschema/src/main/resources/schema/phenopacket-schema-2-0.json b/phenopacket-tools-validator-jsonschema/src/main/resources/schema/phenopacket-schema-2-0.json index 2fb9b737..2e514501 100644 --- a/phenopacket-tools-validator-jsonschema/src/main/resources/schema/phenopacket-schema-2-0.json +++ b/phenopacket-tools-validator-jsonschema/src/main/resources/schema/phenopacket-schema-2-0.json @@ -300,8 +300,24 @@ } ] }, + "typedQuantity": { + "type": "object", + "properties": { + "type": { + "$ref": "#/definitions/ontologyClass" + }, + "quantity": { + "$ref": "#/definitions/quantity" + } + } + }, "complexValue": { - "type": "null" + "type": "array", + "items": { + "$ref": "#/definitions/typedQuantity" + }, + "minItems": 1, + "uniqueItems": true }, "measurement": { }, @@ -373,7 +389,29 @@ "additionalProperties": false }, "variantInterpretation": { - "type": "null" + "type": "object", + "properties": { + "acmgPathogenicityClassification": { + "enum": [ + "NOT_PROVIDED", + "BENIGN", + "LIKELY_BENIGN", + "UNCERTAIN_SIGNIFICANCE", + "LIKELY_PATHOGENIC", + "PATHOGENIC" + ] + }, + "therapeuticActionability": { + "enum": [ + "UNKNOWN_ACTIONABILITY", + "NOT_ACTIONABLE", + "ACTIONABLE" + ] + }, + "variationdescriptor": { + "$ref" : "versatile.json#/definitions/variationDescriptor" + } + } }, "geneDescriptor": { "type": "object", @@ -428,7 +466,7 @@ "$ref": "#/definitions/geneDescriptor" }, { - "$ref": "#/definitions/geneDescriptor" + "$ref": "#/definitions/variantInterpretation" } ] } @@ -507,6 +545,9 @@ }, "diagnosis": { "$ref": "#/definitions/diagnosis" + }, + "summary" : { + "type": "string" } }, "required": [ @@ -514,16 +555,6 @@ "progressStatus" ] }, - "variationInterpretation": { - "oneOf": [ - { - "$ref": "#/definitions/geneDescriptor" - }, - { - "$ref": "#/definitions/geneDescriptor" - } - ] - }, "procedure": { "type": "object", "properties": { diff --git a/phenopacket-tools-validator-jsonschema/src/main/resources/schema/versatile.json b/phenopacket-tools-validator-jsonschema/src/main/resources/schema/versatile.json index 49d4dd18..2f4a6996 100644 --- a/phenopacket-tools-validator-jsonschema/src/main/resources/schema/versatile.json +++ b/phenopacket-tools-validator-jsonschema/src/main/resources/schema/versatile.json @@ -97,8 +97,7 @@ "type": "string" }, "variation": { - "type": "object", - "description": "TODO IMPORT THIS" + "$ref": "vrs.json#/definitions/Variation" }, "label": { "type": "string" @@ -145,16 +144,14 @@ ] }, "structuralType" : { - "type": "object", - "description": "TODO IMPORT THIS OntologyClass" + "$ref":"phenopacket-schema-2-0.json#/definitions/ontologyClass" }, "vrs_ref_allele_seq": { "type": "string", "description": "A Sequence corresponding to a “ref allele”, describing the sequence expected at a SequenceLocation reference" }, - "allelicState" : { - "type": "object", - "description": "TODO IMPORT THIS OntologyClass" + "allelicState" : { + "$ref":"phenopacket-schema-2-0.json#/definitions/ontologyClass" } } }, diff --git a/phenopacket-tools-validator-jsonschema/src/main/resources/schema/vrs.json b/phenopacket-tools-validator-jsonschema/src/main/resources/schema/vrs.json new file mode 100644 index 00000000..ca2366be --- /dev/null +++ b/phenopacket-tools-validator-jsonschema/src/main/resources/schema/vrs.json @@ -0,0 +1,980 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "title": "GA4GH-VRS-Definitions", + "type": "object", + "definitions": { + "Variation": { + "description": "The root class of all Variation types", + "oneOf": [ + { + "$ref": "#/definitions/MolecularVariation" + }, + { + "$ref": "#/definitions/SystemicVariation" + }, + { + "$ref": "#/definitions/UtilityVariation" + } + ], + "discriminator": { + "propertyName": "type" + } + }, + "MolecularVariation": { + "description": "A variation on a contiguous molecule.", + "oneOf": [ + { + "$ref": "#/definitions/Allele" + }, + { + "$ref": "#/definitions/Haplotype" + } + ], + "discriminator": { + "propertyName": "type" + } + }, + "UtilityVariation": { + "description": "Utility variation classes that cannot be constrained to a specific biological class of variation.", + "oneOf": [ + { + "$ref": "#/definitions/Text" + }, + { + "$ref": "#/definitions/VariationSet" + } + ], + "discriminator": { + "propertyName": "type" + } + }, + "SystemicVariation": { + "description": "A Variation of multiple molecules in the context of a system, e.g. a genome, sample, or homologous chromosomes.", + "oneOf": [ + { + "$ref": "#/definitions/Abundance" + } + ], + "discriminator": { + "propertyName": "type" + } + }, + "Allele": { + "description": "The sequence state at a Location.", + "additionalProperties": false, + "type": "object", + "properties": { + "_id": { + "$ref": "#/definitions/CURIE" + }, + "type": { + "type": "string", + "enum": [ + "Allele" + ], + "default": "Allele" + }, + "location": { + "oneOf": [ + { + "$ref": "#/definitions/CURIE" + }, + { + "$ref": "#/definitions/Location" + } + ] + }, + "state": { + "oneOf": [ + { + "$ref": "#/definitions/SequenceState" + }, + { + "$ref": "#/definitions/SequenceExpression" + } + ] + } + }, + "required": [ + "type", + "location", + "state" + ] + }, + "Haplotype": { + "description": "A set of zero or more Alleles", + "additionalProperties": false, + "type": "object", + "properties": { + "_id": { + "$ref": "#/definitions/CURIE" + }, + "type": { + "type": "string", + "enum": [ + "Haplotype" + ], + "default": "Haplotype" + }, + "members": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { + "oneOf": [ + { + "$ref": "#/definitions/Allele" + }, + { + "$ref": "#/definitions/CURIE" + } + ] + } + } + }, + "required": [ + "type", + "members" + ] + }, + "Text": { + "description": "A textual description of variation, typically not parseable but understood by humans.", + "additionalProperties": false, + "type": "object", + "properties": { + "_id": { + "$ref": "#/definitions/CURIE" + }, + "type": { + "type": "string", + "enum": [ + "Text" + ], + "default": "Text" + }, + "definition": { + "type": "string", + "description": "An textual representation of variation intended to capture variation descriptions that cannot be parsed, but still treated as variation." + } + }, + "required": [ + "type", + "definition" + ] + }, + "VariationSet": { + "description": "A set of Variation objects.\nMembers may be specified inline or by reference (with CURIEs)", + "type": "object", + "additionalProperties": false, + "properties": { + "_id": { + "$ref": "#/definitions/CURIE" + }, + "type": { + "type": "string", + "enum": [ + "VariationSet" + ], + "default": "VariationSet" + }, + "members": { + "type": "array", + "uniqueItems": true, + "items": { + "oneOf": [ + { + "$ref": "#/definitions/CURIE" + }, + { + "$ref": "#/definitions/Variation" + } + ] + } + } + }, + "required": [ + "type", + "members" + ] + }, + "Abundance": { + "description": "The quantity of a feature, variation, molecule or part thereof in a system.", + "oneOf": [ + { + "$ref": "#/definitions/CopyNumber" + } + ], + "discriminator": { + "propertyName": "type" + } + }, + "CopyNumber": { + "additionalProperties": false, + "type": "object", + "description": "The count of copies of a Feature, Location, or Molecular Variation subject within a genome.", + "properties": { + "_id": { + "$ref": "#/definitions/CURIE" + }, + "type": { + "type": "string", + "enum": [ + "CopyNumber" + ], + "default": "CopyNumber" + }, + "subject": { + "oneOf": [ + { + "$ref": "#/definitions/MolecularVariation" + }, + { + "$ref": "#/definitions/Feature" + }, + { + "$ref": "#/definitions/SequenceExpression" + }, + { + "$ref": "#/definitions/CURIE" + } + ] + }, + "copies": { + "oneOf": [ + { + "$ref": "#/definitions/Number" + }, + { + "$ref": "#/definitions/IndefiniteRange" + }, + { + "$ref": "#/definitions/DefiniteRange" + } + ] + } + }, + "allOf": [ + { + "if": { + "properties": { + "copies": { + "$ref": "#/definitions/Number" + } + } + }, + "then": { + "properties": { + "copies": { + "properties": { + "value": { + "minimum": 0, + "type": "integer" + } + } + } + } + } + }, + { + "if": { + "properties": { + "copies": { + "$ref": "#/definitions/IndefiniteRange" + } + } + }, + "then": { + "properties": { + "copies": { + "properties": { + "value": { + "minimum": 0, + "type": "integer" + } + } + } + } + } + }, + { + "if": { + "properties": { + "copies": { + "$ref": "#/definitions/DefiniteRange" + } + } + }, + "then": { + "properties": { + "copies": { + "properties": { + "min": { + "minimum": 0, + "type": "integer" + }, + "max": { + "minimum": 0, + "type": "integer" + } + } + } + } + } + } + ], + "required": [ + "type", + "subject", + "copies" + ] + }, + "Location": { + "description": "A Location represents a span on a specific sequence.", + "oneOf": [ + { + "$ref": "#/definitions/ChromosomeLocation" + }, + { + "$ref": "#/definitions/SequenceLocation" + } + ], + "discriminator": { + "propertyName": "type" + } + }, + "ChromosomeLocation": { + "additionalProperties": false, + "description": "A region of a chromosomed specified by species and name using cytogenetic naming conventions", + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "ChromosomeLocation" + ], + "default": "ChromosomeLocation" + }, + "_id": { + "$ref": "#/definitions/CURIE" + }, + "species_id": { + "$ref": "#/definitions/CURIE", + "default": "taxonomy:9606" + }, + "chr": { + "type": "string" + }, + "interval": { + "$ref": "#/definitions/CytobandInterval" + } + }, + "required": [ + "type", + "species_id", + "chr", + "interval" + ] + }, + "SequenceLocation": { + "additionalProperties": false, + "description": "A specified subsequence within another sequence that is used as a reference sequence.", + "type": "object", + "properties": { + "_id": { + "$ref": "#/definitions/CURIE" + }, + "type": { + "type": "string", + "enum": [ + "SequenceLocation" + ], + "default": "SequenceLocation" + }, + "sequence_id": { + "$ref": "#/definitions/CURIE" + }, + "interval": { + "oneOf": [ + { + "$ref": "#/definitions/SequenceInterval" + }, + { + "$ref": "#/definitions/SimpleInterval" + } + ] + } + }, + "required": [ + "type", + "sequence_id", + "interval" + ] + }, + "SequenceInterval": { + "description": "A SequenceInterval represents a span of sequence. Positions are always represented by contiguous spans using interbase coordinates.\nSequenceInterval is intended to be compatible with that in Sequence Ontology ([SO:0000001](http://www.sequenceontology.org/browser/current_svn/term/SO:0000001)), with the exception that the GA4GH VRS SequenceInterval may be zero-width. The SO definition is for an \"extent greater than zero\".", + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "type": "string", + "enum": [ + "SequenceInterval" + ], + "default": "SequenceInterval" + }, + "start": { + "oneOf": [ + { + "$ref": "#/definitions/Number" + }, + { + "$ref": "#/definitions/IndefiniteRange" + }, + { + "$ref": "#/definitions/DefiniteRange" + } + ] + }, + "end": { + "oneOf": [ + { + "$ref": "#/definitions/Number" + }, + { + "$ref": "#/definitions/IndefiniteRange" + }, + { + "$ref": "#/definitions/DefiniteRange" + } + ] + } + }, + "allOf": [ + { + "if": { + "properties": { + "start": { + "$ref": "#/definitions/Number" + } + } + }, + "then": { + "properties": { + "start": { + "properties": { + "value": { + "minimum": 0, + "type": "integer" + } + } + } + } + } + }, + { + "if": { + "properties": { + "start": { + "$ref": "#/definitions/IndefiniteRange" + } + } + }, + "then": { + "properties": { + "start": { + "properties": { + "value": { + "minimum": 0, + "type": "integer" + } + } + } + } + } + }, + { + "if": { + "properties": { + "start": { + "$ref": "#/definitions/DefiniteRange" + } + } + }, + "then": { + "properties": { + "start": { + "properties": { + "min": { + "minimum": 0, + "type": "integer" + }, + "max": { + "minimum": 0, + "type": "integer" + } + } + } + } + } + }, + { + "if": { + "properties": { + "end": { + "$ref": "#/definitions/Number" + } + } + }, + "then": { + "properties": { + "end": { + "properties": { + "value": { + "minimum": 0, + "type": "integer" + } + } + } + } + } + }, + { + "if": { + "properties": { + "end": { + "$ref": "#/definitions/IndefiniteRange" + } + } + }, + "then": { + "properties": { + "end": { + "properties": { + "value": { + "minimum": 0, + "type": "integer" + } + } + } + } + } + }, + { + "if": { + "properties": { + "end": { + "$ref": "#/definitions/DefiniteRange" + } + } + }, + "then": { + "properties": { + "end": { + "properties": { + "min": { + "minimum": 0, + "type": "integer" + }, + "max": { + "minimum": 0, + "type": "integer" + } + } + } + } + } + } + ], + "required": [ + "type", + "start", + "end" + ] + }, + "CytobandInterval": { + "description": "A contiguous region specified by chromosomal bands features.", + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "type": "string", + "enum": [ + "CytobandInterval" + ], + "default": "CytobandInterval" + }, + "start": { + "$ref": "#/definitions/HumanCytoband" + }, + "end": { + "$ref": "#/definitions/HumanCytoband" + } + }, + "example": { + "type": "CytobandInterval", + "start": "q22.2", + "end": "q22.3" + }, + "required": [ + "type", + "start", + "end" + ] + }, + "SequenceExpression": { + "description": "One of a set of sequence representation syntaxes.", + "oneOf": [ + { + "$ref": "#/definitions/LiteralSequenceExpression" + }, + { + "$ref": "#/definitions/DerivedSequenceExpression" + }, + { + "$ref": "#/definitions/RepeatedSequenceExpression" + } + ], + "discriminator": { + "propertyName": "type" + } + }, + "LiteralSequenceExpression": { + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "type": "string", + "enum": [ + "LiteralSequenceExpression" + ], + "default": "LiteralSequenceExpression" + }, + "sequence": { + "$ref": "#/definitions/Sequence" + } + }, + "required": [ + "type", + "sequence" + ] + }, + "DerivedSequenceExpression": { + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "type": "string", + "enum": [ + "DerivedSequenceExpression" + ], + "default": "DerivedSequenceExpression" + }, + "location": { + "$ref": "#/definitions/SequenceLocation" + }, + "reverse_complement": { + "type": "boolean" + } + }, + "required": [ + "type", + "location", + "reverse_complement" + ] + }, + "RepeatedSequenceExpression": { + "additionalProperties": false, + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "RepeatedSequenceExpression" + ], + "default": "RepeatedSequenceExpression" + }, + "seq_expr": { + "oneOf": [ + { + "$ref": "#/definitions/LiteralSequenceExpression" + }, + { + "$ref": "#/definitions/DerivedSequenceExpression" + } + ] + }, + "count": { + "oneOf": [ + { + "$ref": "#/definitions/Number" + }, + { + "$ref": "#/definitions/IndefiniteRange" + }, + { + "$ref": "#/definitions/DefiniteRange" + } + ] + } + }, + "allOf": [ + { + "if": { + "properties": { + "count": { + "$ref": "#/definitions/Number" + } + } + }, + "then": { + "properties": { + "count": { + "properties": { + "value": { + "minimum": 0, + "type": "integer" + } + } + } + } + } + }, + { + "if": { + "properties": { + "count": { + "$ref": "#/definitions/IndefiniteRange" + } + } + }, + "then": { + "properties": { + "count": { + "properties": { + "value": { + "minimum": 0, + "type": "integer" + } + } + } + } + } + }, + { + "if": { + "properties": { + "count": { + "$ref": "#/definitions/DefiniteRange" + } + } + }, + "then": { + "properties": { + "count": { + "properties": { + "min": { + "minimum": 0, + "type": "integer" + }, + "max": { + "minimum": 0, + "type": "integer" + } + } + } + } + } + } + ], + "required": [ + "type", + "seq_expr", + "count" + ] + }, + "Feature": { + "description": "A named entity that can be mapped to a Location. Genes, protein domains, exons, and chromosomes are some examples of common biological entities that may be Features.", + "oneOf": [ + { + "$ref": "#/definitions/Gene" + } + ], + "discriminator": { + "propertyName": "type" + } + }, + "Gene": { + "description": "A reference to an external gene system, used as a location for variation. Currently, the `ncbigene` namespace is required. See https://registry.identifiers.org/registry/ncbigene.", + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "type": "string", + "enum": [ + "Gene" + ], + "default": "Gene" + }, + "gene_id": { + "$ref": "#/definitions/CURIE" + } + }, + "required": [ + "type", + "gene_id" + ] + }, + "Number": { + "description": "A simple number value as a VRS class.", + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "type": "string", + "enum": [ + "Number" + ], + "default": "Number" + }, + "value": { + "type": "number" + } + }, + "required": [ + "type", + "value" + ] + }, + "IndefiniteRange": { + "description": "An indefinite range represented as a number and associated comparator. The bound operator is interpreted as follows: '>=' are all values greater than and including the value, '<=' are all numbers less than and including the value.", + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "type": "string", + "enum": [ + "IndefiniteRange" + ], + "default": "IndefiniteRange" + }, + "value": { + "type": "number" + }, + "comparator": { + "type": "string", + "enum": [ + "<=", + ">=" + ] + } + }, + "required": [ + "type", + "value", + "comparator" + ] + }, + "DefiniteRange": { + "description": "A bounded, inclusive range of numbers.", + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "type": "string", + "enum": [ + "DefiniteRange" + ], + "default": "DefiniteRange" + }, + "min": { + "type": "number" + }, + "max": { + "type": "number" + } + }, + "required": [ + "type", + "min", + "max" + ] + }, + "Sequence": { + "additionalProperties": false, + "description": "A character string of residues that represents a biological sequence using the conventional sequence order (5\u2019-to-3\u2019 for nucleic acid sequences, and amino-to-carboxyl for amino acid sequences). IUPAC ambiguity codes are permitted in Sequences.", + "type": "string", + "pattern": "^[A-Z*\\-]*$" + }, + "CURIE": { + "additionalProperties": false, + "description": "A string that refers to an object uniquely. The lifetime and scope of an id is defined by the sender.\nVRS does not impose any contraints on strings used as ids in messages. However, to maximize sharability of data, VRS RECOMMENDS that implementations use [W3C Compact URI (CURIE)](https://www.w3.org/TR/curie/) syntax.\nString CURIEs are represented as `prefix`:`reference` (W3C terminology), but often referred to as `namespace`:`accession` or `namespace`:`local id` colloquially.\nVRS also RECOMMENDS that `prefix` be defined in identifiers.org.\nThe `reference` component is an unconstrained string.\nA CURIE is a URI. URIs may *locate* objects (i.e., specify where to retrieve them) or *name* objects conceptually. VRS uses CURIEs primarily as a naming mechanism.\nImplementations MAY provide CURIE resolution mechanisms for prefixes to make these objects locatable.\nUsing internal ids in public messages is strongly discouraged.", + "type": "string", + "pattern": "^\\w[^:]*:.+$", + "example": "ensembl:ENSG00000139618" + }, + "HumanCytoband": { + "additionalProperties": false, + "description": "A interval on a stained metaphase chromosome specified by cytobands. CytobandIntervals include the regions described by the start and end cytobands.", + "type": "string", + "pattern": "^cen|[pq](ter|([1-9][0-9]*(\\.[1-9][0-9]*)?))$", + "example": "q22.3" + }, + "SequenceState": { + "deprecated": true, + "description": "DEPRECATED: An assertion of the state of a sequence, typically at a Sequence Location within an Allele.\nThis class is deprecated. Use LiteralSequenceExpression instead.", + "additionalProperties": false, + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "SequenceState" + ], + "default": "SequenceState" + }, + "sequence": { + "$ref": "#/definitions/Sequence" + } + }, + "example": { + "type": "SequenceState", + "sequence": "C" + }, + "required": [ + "type", + "sequence" + ] + }, + "SimpleInterval": { + "deprecated": true, + "description": "DEPRECATED: A SimpleInterval represents a span of sequence. Positions are always represented by contiguous spans using interbase coordinates.\nThis class is deprecated. Use SequenceInterval instead.", + "additionalProperties": false, + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "SimpleInterval" + ], + "default": "SimpleInterval" + }, + "start": { + "type": "integer" + }, + "end": { + "type": "integer" + } + }, + "example": { + "type": "SimpleInterval", + "start": 11, + "end": 22 + }, + "required": [ + "type", + "start", + "end" + ] + } + } +} \ No newline at end of file From 55f9525d03a04a4598232c27fa01c92aaed0c402 Mon Sep 17 00:00:00 2001 From: pnrobinson Date: Tue, 6 Sep 2022 12:00:01 -0400 Subject: [PATCH 097/155] curation --- .../builder/builders/DiagnosisBuilder.java | 4 ++ ...rvicofacialActinomycosisOfTheMandible.java | 58 ++++++++++--------- ...SevereStatinInducedAutoimmuneMyopathy.java | 22 +++++-- 3 files changed, 52 insertions(+), 32 deletions(-) diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DiagnosisBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DiagnosisBuilder.java index 138669d4..1aabcf46 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DiagnosisBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/builders/DiagnosisBuilder.java @@ -20,6 +20,10 @@ public DiagnosisBuilder addGenomicInterpretation(GenomicInterpretation interpret public static DiagnosisBuilder builder(OntologyClass disease) { return new DiagnosisBuilder(disease); } + public static DiagnosisBuilder builder(String id, String label) { + OntologyClass dx = OntologyClass.newBuilder().setId(id).setLabel(label).build(); + return new DiagnosisBuilder(dx); + } public Diagnosis build() { return builder.build(); diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/CervicofacialActinomycosisOfTheMandible.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/CervicofacialActinomycosisOfTheMandible.java index 91e039e3..66633e61 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/CervicofacialActinomycosisOfTheMandible.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/CervicofacialActinomycosisOfTheMandible.java @@ -1,43 +1,44 @@ package org.phenopackets.phenopackettools.examples; +import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; +import org.phenopackets.phenopackettools.builder.builders.*; +import org.phenopackets.schema.v2.Phenopacket; +import org.phenopackets.schema.v2.core.Individual; import org.phenopackets.schema.v2.core.MedicalAction; import org.phenopackets.schema.v2.core.PhenotypicFeature; import java.util.List; +import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; + public class CervicofacialActinomycosisOfTheMandible { private static final String PHENOPACKET_ID = "arbitrary.id"; private static final String INDIVIDUAL = "individual A"; -// private final Phenopacket phenopacket; + private final Phenopacket phenopacket; public CervicofacialActinomycosisOfTheMandible() { -// var externalRef = ExternalReferenceBuilder.builder() -// .id("DOI:10.1136/bcr-2019-233681") -// .builder("PMID:32467116") -// .description("Cervicofacial actinomycosis of the mandible in a paediatric patient") -// .build(); -// -// //TODO: Fix ontology versions -// var metadata = MetaDataBuilder.builder("2022-04-21T10:35:00Z", "anonymous biocurator") -// .resource(Resources.ncitVersion("21.05d")) -// .resource(Resources.hpoVersion("2021-08-02")) -// .resource(Resources.efoVersion("3.34.0")) -// .resource(Resources.uberonVersion("2021-07-27")) -// .resource(Resources.ncbiTaxonVersion("2021-06-10")) -// .externalReference(externalRef) -// .build(); -// -// Individual proband = IndividualBuilder.builder(INDIVIDUAL). -// ageAtLastEncounter("P10Y"). -// female(). -// build(); -// -// phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metadata) -// .individual(proband) + var externalRef = ExternalReferenceBuilder.of("PMID:32467116", + "Cervicofacial actinomycosis of the mandible in a paediatric patient"); + + var metadata = MetaDataBuilder.builder("2022-04-21T10:35:00Z", "anonymous biocurator") + .addResource(Resources.ncitVersion("21.05d")) + .addResource(Resources.hpoVersion("2022-06-11")) + .addResource(Resources.efoVersion("3.34.0")) + .addResource(Resources.uberonVersion("2021-07-27")) + .addExternalReference(externalRef) + .build(); + + Individual proband = IndividualBuilder.builder(INDIVIDUAL). + ageAtLastEncounter("P10Y"). + female(). + build(); + + phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metadata) + .individual(proband) // .addAllPhenotypicFeatures(getMedicalHistory()) // .addAllPhenotypicFeatures(getLast8Monthsistory()) // .addMedicalAction(neckCT()) @@ -49,7 +50,7 @@ public CervicofacialActinomycosisOfTheMandible() { // .addMedicalAction(tissueCultures()) // .addMedicalAction(anaerobicCultures()) // .addMedicalAction(treatment()) -// .build(); + .build(); } /** @@ -148,7 +149,12 @@ private MedicalAction treatment() { * - no significant medical history */ private List getMedicalHistory() { - return null; + var age9y4m = TimeElements.age("P9Y4M"); + var mandiblePain = PhenotypicFeatureBuilder.builder("HP:0200025", "Mandibular pain") + .onset(age9y4m).build(); + var fever = PhenotypicFeatureBuilder.builder("HP:0001954", "Recurrent fever") + .onset(age9y4m).build(); + return List.of(mandiblePain, fever); } /** diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SevereStatinInducedAutoimmuneMyopathy.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SevereStatinInducedAutoimmuneMyopathy.java index 55329652..9ca3e23d 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SevereStatinInducedAutoimmuneMyopathy.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SevereStatinInducedAutoimmuneMyopathy.java @@ -20,11 +20,8 @@ public class SevereStatinInducedAutoimmuneMyopathy { public SevereStatinInducedAutoimmuneMyopathy() { - var externalRef = ExternalReferenceBuilder.reference() - .id("DOI:10.1136/bcr-2020-234805") - // .builder("PMID:32444443") - .description("Severe statin-induced autoimmune myopathy successfully treated with intravenous immunoglobulin") - .build(); + var externalRef = ExternalReferenceBuilder.of("PMID:32444443", + "Severe statin-induced autoimmune myopathy successfully treated with intravenous immunoglobulin"); //TODO: Fix ontology versions var metadata = MetaDataBuilder.builder("2022-04-21T10:35:00Z", "anonymous biocurator") @@ -54,6 +51,14 @@ public SevereStatinInducedAutoimmuneMyopathy() { .build(); } + + List getDiseases() { + var niddm = DiseaseBuilder.builder("MONDO:0005148", "type 2 diabetes mellitus").build(); + var htn = DiseaseBuilder.builder("MONDO:0001134", "essential hypertension").build(); + + return List.of(niddm, htn); + } + /** * Outcome: * @@ -138,7 +143,12 @@ private List getLastMonthHistory() { * - type 2 diabetes mellitus diagnosed 10 years back */ private List getMedicalHistory() { - return null; + var age65y = TimeElements.age("P65Y"); + var proxLegWeakness = PhenotypicFeatureBuilder.builder("HP:0008994", + "Proximal muscle weakness in lower limbs").onset(age65y).build(); + return List.of(proxLegWeakness); + + } /** From 22cb004c48105b8e3fc0583299ec6f1a4313e8eb Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Tue, 6 Sep 2022 12:21:14 -0400 Subject: [PATCH 098/155] gh pages setup --- .github/workflows/pages.yml | 48 +++++++++--- README.md | 4 + {sphinx => docs}/Makefile | 0 .../_build/doctrees/environment.pickle | Bin .../_build/doctrees/index.doctree | Bin .../_build/doctrees/modules.doctree | Bin {sphinx => docs}/_build/html/.buildinfo | 0 docs/{ => _build/html}/_sources/index.rst.txt | 0 .../html}/_sources/modules.rst.txt | 0 .../_sphinx_javascript_frameworks_compat.js | 0 docs/{ => _build/html}/_static/alabaster.css | 0 docs/{ => _build/html}/_static/basic.css | 0 docs/{ => _build/html}/_static/custom.css | 0 docs/{ => _build/html}/_static/doctools.js | 0 .../html}/_static/documentation_options.js | 0 docs/{ => _build/html}/_static/file.png | Bin .../{ => _build/html}/_static/jquery-3.6.0.js | 0 docs/{ => _build/html}/_static/jquery.js | 0 .../html}/_static/language_data.js | 0 docs/{ => _build/html}/_static/minus.png | Bin docs/{ => _build/html}/_static/plus.png | Bin docs/{ => _build/html}/_static/pygments.css | 0 docs/{ => _build/html}/_static/searchtools.js | 0 .../html}/_static/underscore-1.13.1.js | 0 docs/{ => _build/html}/_static/underscore.js | 0 docs/{ => _build/html}/genindex.html | 0 docs/{ => _build/html}/index.html | 0 docs/{ => _build/html}/modules.html | 0 docs/{ => _build/html}/objects.inv | Bin docs/{ => _build/html}/search.html | 0 docs/{ => _build/html}/searchindex.js | 0 {sphinx => docs}/conf.py | 0 {sphinx => docs}/index.rst | 0 {sphinx => docs}/make.bat | 70 +++++++++--------- {sphinx => docs}/modules.rst | 0 .../_sources/index.rst.txt | 0 .../_sources/modules.rst.txt | 0 .../_sphinx_javascript_frameworks_compat.js | 0 .../_static/alabaster.css | 0 .../html => obsolete_docs}/_static/basic.css | 0 .../html => obsolete_docs}/_static/custom.css | 0 .../_static/doctools.js | 0 .../_static/documentation_options.js | 0 .../html => obsolete_docs}/_static/file.png | Bin .../_static/jquery-3.6.0.js | 0 .../html => obsolete_docs}/_static/jquery.js | 0 .../_static/language_data.js | 0 .../html => obsolete_docs}/_static/minus.png | Bin .../html => obsolete_docs}/_static/plus.png | Bin .../_static/pygments.css | 0 .../_static/searchtools.js | 0 .../_static/underscore-1.13.1.js | 0 .../_static/underscore.js | 0 .../html => obsolete_docs}/genindex.html | 0 .../_build/html => obsolete_docs}/index.html | 0 .../html => obsolete_docs}/modules.html | 0 .../_build/html => obsolete_docs}/objects.inv | Bin .../_build/html => obsolete_docs}/search.html | 0 .../html => obsolete_docs}/searchindex.js | 0 .../src/main/resources/schema/vrsatile.json | 3 + 60 files changed, 78 insertions(+), 47 deletions(-) rename {sphinx => docs}/Makefile (100%) rename {sphinx => docs}/_build/doctrees/environment.pickle (100%) rename {sphinx => docs}/_build/doctrees/index.doctree (100%) rename {sphinx => docs}/_build/doctrees/modules.doctree (100%) rename {sphinx => docs}/_build/html/.buildinfo (100%) rename docs/{ => _build/html}/_sources/index.rst.txt (100%) rename docs/{ => _build/html}/_sources/modules.rst.txt (100%) rename docs/{ => _build/html}/_static/_sphinx_javascript_frameworks_compat.js (100%) rename docs/{ => _build/html}/_static/alabaster.css (100%) rename docs/{ => _build/html}/_static/basic.css (100%) rename docs/{ => _build/html}/_static/custom.css (100%) rename docs/{ => _build/html}/_static/doctools.js (100%) rename docs/{ => _build/html}/_static/documentation_options.js (100%) rename docs/{ => _build/html}/_static/file.png (100%) rename docs/{ => _build/html}/_static/jquery-3.6.0.js (100%) rename docs/{ => _build/html}/_static/jquery.js (100%) rename docs/{ => _build/html}/_static/language_data.js (100%) rename docs/{ => _build/html}/_static/minus.png (100%) rename docs/{ => _build/html}/_static/plus.png (100%) rename docs/{ => _build/html}/_static/pygments.css (100%) rename docs/{ => _build/html}/_static/searchtools.js (100%) rename docs/{ => _build/html}/_static/underscore-1.13.1.js (100%) rename docs/{ => _build/html}/_static/underscore.js (100%) rename docs/{ => _build/html}/genindex.html (100%) rename docs/{ => _build/html}/index.html (100%) rename docs/{ => _build/html}/modules.html (100%) rename docs/{ => _build/html}/objects.inv (100%) rename docs/{ => _build/html}/search.html (100%) rename docs/{ => _build/html}/searchindex.js (100%) rename {sphinx => docs}/conf.py (100%) rename {sphinx => docs}/index.rst (100%) rename {sphinx => docs}/make.bat (95%) rename {sphinx => docs}/modules.rst (100%) rename {sphinx/_build/html => obsolete_docs}/_sources/index.rst.txt (100%) rename {sphinx/_build/html => obsolete_docs}/_sources/modules.rst.txt (100%) rename {sphinx/_build/html => obsolete_docs}/_static/_sphinx_javascript_frameworks_compat.js (100%) rename {sphinx/_build/html => obsolete_docs}/_static/alabaster.css (100%) rename {sphinx/_build/html => obsolete_docs}/_static/basic.css (100%) rename {sphinx/_build/html => obsolete_docs}/_static/custom.css (100%) rename {sphinx/_build/html => obsolete_docs}/_static/doctools.js (100%) rename {sphinx/_build/html => obsolete_docs}/_static/documentation_options.js (100%) rename {sphinx/_build/html => obsolete_docs}/_static/file.png (100%) rename {sphinx/_build/html => obsolete_docs}/_static/jquery-3.6.0.js (100%) rename {sphinx/_build/html => obsolete_docs}/_static/jquery.js (100%) rename {sphinx/_build/html => obsolete_docs}/_static/language_data.js (100%) rename {sphinx/_build/html => obsolete_docs}/_static/minus.png (100%) rename {sphinx/_build/html => obsolete_docs}/_static/plus.png (100%) rename {sphinx/_build/html => obsolete_docs}/_static/pygments.css (100%) rename {sphinx/_build/html => obsolete_docs}/_static/searchtools.js (100%) rename {sphinx/_build/html => obsolete_docs}/_static/underscore-1.13.1.js (100%) rename {sphinx/_build/html => obsolete_docs}/_static/underscore.js (100%) rename {sphinx/_build/html => obsolete_docs}/genindex.html (100%) rename {sphinx/_build/html => obsolete_docs}/index.html (100%) rename {sphinx/_build/html => obsolete_docs}/modules.html (100%) rename {sphinx/_build/html => obsolete_docs}/objects.inv (100%) rename {sphinx/_build/html => obsolete_docs}/search.html (100%) rename {sphinx/_build/html => obsolete_docs}/searchindex.js (100%) create mode 100644 phenopacket-tools-validator-jsonschema/src/main/resources/schema/vrsatile.json diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index e9285990..2f698203 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -3,8 +3,11 @@ name: Deploy static content to Pages on: # Runs on pushes targeting the default branch - push: - branches: ["main"] + #push: + # branches: ["main"] + + pull_request: + branches: [ "main"] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: @@ -24,19 +27,40 @@ jobs: # Single deploy job since we're just deploying deploy: environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} + # name: github-pages + # url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v3 - - name: Setup Pages - uses: actions/configure-pages@v1 - - name: Upload artifact - uses: actions/upload-pages-artifact@v1 with: + fetch-depth: 0 + - name: Set up Python 3. + uses: actions/setup-python@v3 + with: + python-version: 3.9 + - name: Install dependencies + run: pip install sphinx + - name: Build documentation + run: | + mkdir gh-pages + touch gh-pages/.nojekyll + cd docs/ + sphinx-build -b html . _build + cp -r _build/* ../gh-pages/ + #- name: Setup Pages + # uses: actions/configure-pages@v1 + #- name: Upload artifact + # uses: actions/upload-pages-artifact@v1 + # with: # Upload entire repository - path: '.' - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@main + # path: '.' + - name: Deploy documentation. + if: ${{ github.event_name == 'pull_request' }} + uses: JamesIves/github-pages-deploy-action@v4.3.0 + with: + branch: gh-pages + force: true + folder: gh-pages + + diff --git a/README.md b/README.md index 9cb8b4ae..b9d5dd95 100644 --- a/README.md +++ b/README.md @@ -42,3 +42,7 @@ pfx-tools validate ~/phenopacket-examples/covid.json # or all the json files in a directory pfx-tools validate ~/phenopacket-examples/*.json ``` + + +see this for VRS -- https://github.com/ga4gh/vrs/blob/76542a903b913110e67811885a8958625bbc3aae/schema/vrs.json +import it like vrsatile \ No newline at end of file diff --git a/sphinx/Makefile b/docs/Makefile similarity index 100% rename from sphinx/Makefile rename to docs/Makefile diff --git a/sphinx/_build/doctrees/environment.pickle b/docs/_build/doctrees/environment.pickle similarity index 100% rename from sphinx/_build/doctrees/environment.pickle rename to docs/_build/doctrees/environment.pickle diff --git a/sphinx/_build/doctrees/index.doctree b/docs/_build/doctrees/index.doctree similarity index 100% rename from sphinx/_build/doctrees/index.doctree rename to docs/_build/doctrees/index.doctree diff --git a/sphinx/_build/doctrees/modules.doctree b/docs/_build/doctrees/modules.doctree similarity index 100% rename from sphinx/_build/doctrees/modules.doctree rename to docs/_build/doctrees/modules.doctree diff --git a/sphinx/_build/html/.buildinfo b/docs/_build/html/.buildinfo similarity index 100% rename from sphinx/_build/html/.buildinfo rename to docs/_build/html/.buildinfo diff --git a/docs/_sources/index.rst.txt b/docs/_build/html/_sources/index.rst.txt similarity index 100% rename from docs/_sources/index.rst.txt rename to docs/_build/html/_sources/index.rst.txt diff --git a/docs/_sources/modules.rst.txt b/docs/_build/html/_sources/modules.rst.txt similarity index 100% rename from docs/_sources/modules.rst.txt rename to docs/_build/html/_sources/modules.rst.txt diff --git a/docs/_static/_sphinx_javascript_frameworks_compat.js b/docs/_build/html/_static/_sphinx_javascript_frameworks_compat.js similarity index 100% rename from docs/_static/_sphinx_javascript_frameworks_compat.js rename to docs/_build/html/_static/_sphinx_javascript_frameworks_compat.js diff --git a/docs/_static/alabaster.css b/docs/_build/html/_static/alabaster.css similarity index 100% rename from docs/_static/alabaster.css rename to docs/_build/html/_static/alabaster.css diff --git a/docs/_static/basic.css b/docs/_build/html/_static/basic.css similarity index 100% rename from docs/_static/basic.css rename to docs/_build/html/_static/basic.css diff --git a/docs/_static/custom.css b/docs/_build/html/_static/custom.css similarity index 100% rename from docs/_static/custom.css rename to docs/_build/html/_static/custom.css diff --git a/docs/_static/doctools.js b/docs/_build/html/_static/doctools.js similarity index 100% rename from docs/_static/doctools.js rename to docs/_build/html/_static/doctools.js diff --git a/docs/_static/documentation_options.js b/docs/_build/html/_static/documentation_options.js similarity index 100% rename from docs/_static/documentation_options.js rename to docs/_build/html/_static/documentation_options.js diff --git a/docs/_static/file.png b/docs/_build/html/_static/file.png similarity index 100% rename from docs/_static/file.png rename to docs/_build/html/_static/file.png diff --git a/docs/_static/jquery-3.6.0.js b/docs/_build/html/_static/jquery-3.6.0.js similarity index 100% rename from docs/_static/jquery-3.6.0.js rename to docs/_build/html/_static/jquery-3.6.0.js diff --git a/docs/_static/jquery.js b/docs/_build/html/_static/jquery.js similarity index 100% rename from docs/_static/jquery.js rename to docs/_build/html/_static/jquery.js diff --git a/docs/_static/language_data.js b/docs/_build/html/_static/language_data.js similarity index 100% rename from docs/_static/language_data.js rename to docs/_build/html/_static/language_data.js diff --git a/docs/_static/minus.png b/docs/_build/html/_static/minus.png similarity index 100% rename from docs/_static/minus.png rename to docs/_build/html/_static/minus.png diff --git a/docs/_static/plus.png b/docs/_build/html/_static/plus.png similarity index 100% rename from docs/_static/plus.png rename to docs/_build/html/_static/plus.png diff --git a/docs/_static/pygments.css b/docs/_build/html/_static/pygments.css similarity index 100% rename from docs/_static/pygments.css rename to docs/_build/html/_static/pygments.css diff --git a/docs/_static/searchtools.js b/docs/_build/html/_static/searchtools.js similarity index 100% rename from docs/_static/searchtools.js rename to docs/_build/html/_static/searchtools.js diff --git a/docs/_static/underscore-1.13.1.js b/docs/_build/html/_static/underscore-1.13.1.js similarity index 100% rename from docs/_static/underscore-1.13.1.js rename to docs/_build/html/_static/underscore-1.13.1.js diff --git a/docs/_static/underscore.js b/docs/_build/html/_static/underscore.js similarity index 100% rename from docs/_static/underscore.js rename to docs/_build/html/_static/underscore.js diff --git a/docs/genindex.html b/docs/_build/html/genindex.html similarity index 100% rename from docs/genindex.html rename to docs/_build/html/genindex.html diff --git a/docs/index.html b/docs/_build/html/index.html similarity index 100% rename from docs/index.html rename to docs/_build/html/index.html diff --git a/docs/modules.html b/docs/_build/html/modules.html similarity index 100% rename from docs/modules.html rename to docs/_build/html/modules.html diff --git a/docs/objects.inv b/docs/_build/html/objects.inv similarity index 100% rename from docs/objects.inv rename to docs/_build/html/objects.inv diff --git a/docs/search.html b/docs/_build/html/search.html similarity index 100% rename from docs/search.html rename to docs/_build/html/search.html diff --git a/docs/searchindex.js b/docs/_build/html/searchindex.js similarity index 100% rename from docs/searchindex.js rename to docs/_build/html/searchindex.js diff --git a/sphinx/conf.py b/docs/conf.py similarity index 100% rename from sphinx/conf.py rename to docs/conf.py diff --git a/sphinx/index.rst b/docs/index.rst similarity index 100% rename from sphinx/index.rst rename to docs/index.rst diff --git a/sphinx/make.bat b/docs/make.bat similarity index 95% rename from sphinx/make.bat rename to docs/make.bat index 32bb2452..954237b9 100644 --- a/sphinx/make.bat +++ b/docs/make.bat @@ -1,35 +1,35 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=. -set BUILDDIR=_build - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.https://www.sphinx-doc.org/ - exit /b 1 -) - -if "%1" == "" goto help - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% - -:end -popd +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/sphinx/modules.rst b/docs/modules.rst similarity index 100% rename from sphinx/modules.rst rename to docs/modules.rst diff --git a/sphinx/_build/html/_sources/index.rst.txt b/obsolete_docs/_sources/index.rst.txt similarity index 100% rename from sphinx/_build/html/_sources/index.rst.txt rename to obsolete_docs/_sources/index.rst.txt diff --git a/sphinx/_build/html/_sources/modules.rst.txt b/obsolete_docs/_sources/modules.rst.txt similarity index 100% rename from sphinx/_build/html/_sources/modules.rst.txt rename to obsolete_docs/_sources/modules.rst.txt diff --git a/sphinx/_build/html/_static/_sphinx_javascript_frameworks_compat.js b/obsolete_docs/_static/_sphinx_javascript_frameworks_compat.js similarity index 100% rename from sphinx/_build/html/_static/_sphinx_javascript_frameworks_compat.js rename to obsolete_docs/_static/_sphinx_javascript_frameworks_compat.js diff --git a/sphinx/_build/html/_static/alabaster.css b/obsolete_docs/_static/alabaster.css similarity index 100% rename from sphinx/_build/html/_static/alabaster.css rename to obsolete_docs/_static/alabaster.css diff --git a/sphinx/_build/html/_static/basic.css b/obsolete_docs/_static/basic.css similarity index 100% rename from sphinx/_build/html/_static/basic.css rename to obsolete_docs/_static/basic.css diff --git a/sphinx/_build/html/_static/custom.css b/obsolete_docs/_static/custom.css similarity index 100% rename from sphinx/_build/html/_static/custom.css rename to obsolete_docs/_static/custom.css diff --git a/sphinx/_build/html/_static/doctools.js b/obsolete_docs/_static/doctools.js similarity index 100% rename from sphinx/_build/html/_static/doctools.js rename to obsolete_docs/_static/doctools.js diff --git a/sphinx/_build/html/_static/documentation_options.js b/obsolete_docs/_static/documentation_options.js similarity index 100% rename from sphinx/_build/html/_static/documentation_options.js rename to obsolete_docs/_static/documentation_options.js diff --git a/sphinx/_build/html/_static/file.png b/obsolete_docs/_static/file.png similarity index 100% rename from sphinx/_build/html/_static/file.png rename to obsolete_docs/_static/file.png diff --git a/sphinx/_build/html/_static/jquery-3.6.0.js b/obsolete_docs/_static/jquery-3.6.0.js similarity index 100% rename from sphinx/_build/html/_static/jquery-3.6.0.js rename to obsolete_docs/_static/jquery-3.6.0.js diff --git a/sphinx/_build/html/_static/jquery.js b/obsolete_docs/_static/jquery.js similarity index 100% rename from sphinx/_build/html/_static/jquery.js rename to obsolete_docs/_static/jquery.js diff --git a/sphinx/_build/html/_static/language_data.js b/obsolete_docs/_static/language_data.js similarity index 100% rename from sphinx/_build/html/_static/language_data.js rename to obsolete_docs/_static/language_data.js diff --git a/sphinx/_build/html/_static/minus.png b/obsolete_docs/_static/minus.png similarity index 100% rename from sphinx/_build/html/_static/minus.png rename to obsolete_docs/_static/minus.png diff --git a/sphinx/_build/html/_static/plus.png b/obsolete_docs/_static/plus.png similarity index 100% rename from sphinx/_build/html/_static/plus.png rename to obsolete_docs/_static/plus.png diff --git a/sphinx/_build/html/_static/pygments.css b/obsolete_docs/_static/pygments.css similarity index 100% rename from sphinx/_build/html/_static/pygments.css rename to obsolete_docs/_static/pygments.css diff --git a/sphinx/_build/html/_static/searchtools.js b/obsolete_docs/_static/searchtools.js similarity index 100% rename from sphinx/_build/html/_static/searchtools.js rename to obsolete_docs/_static/searchtools.js diff --git a/sphinx/_build/html/_static/underscore-1.13.1.js b/obsolete_docs/_static/underscore-1.13.1.js similarity index 100% rename from sphinx/_build/html/_static/underscore-1.13.1.js rename to obsolete_docs/_static/underscore-1.13.1.js diff --git a/sphinx/_build/html/_static/underscore.js b/obsolete_docs/_static/underscore.js similarity index 100% rename from sphinx/_build/html/_static/underscore.js rename to obsolete_docs/_static/underscore.js diff --git a/sphinx/_build/html/genindex.html b/obsolete_docs/genindex.html similarity index 100% rename from sphinx/_build/html/genindex.html rename to obsolete_docs/genindex.html diff --git a/sphinx/_build/html/index.html b/obsolete_docs/index.html similarity index 100% rename from sphinx/_build/html/index.html rename to obsolete_docs/index.html diff --git a/sphinx/_build/html/modules.html b/obsolete_docs/modules.html similarity index 100% rename from sphinx/_build/html/modules.html rename to obsolete_docs/modules.html diff --git a/sphinx/_build/html/objects.inv b/obsolete_docs/objects.inv similarity index 100% rename from sphinx/_build/html/objects.inv rename to obsolete_docs/objects.inv diff --git a/sphinx/_build/html/search.html b/obsolete_docs/search.html similarity index 100% rename from sphinx/_build/html/search.html rename to obsolete_docs/search.html diff --git a/sphinx/_build/html/searchindex.js b/obsolete_docs/searchindex.js similarity index 100% rename from sphinx/_build/html/searchindex.js rename to obsolete_docs/searchindex.js diff --git a/phenopacket-tools-validator-jsonschema/src/main/resources/schema/vrsatile.json b/phenopacket-tools-validator-jsonschema/src/main/resources/schema/vrsatile.json new file mode 100644 index 00000000..c0c128a5 --- /dev/null +++ b/phenopacket-tools-validator-jsonschema/src/main/resources/schema/vrsatile.json @@ -0,0 +1,3 @@ +"definitions" : { + +} \ No newline at end of file From edf466f7ed217b8e9b825489071518c9684b0cb9 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Tue, 6 Sep 2022 12:23:08 -0400 Subject: [PATCH 099/155] gh pages setup - fixed c/p error --- .github/workflows/pages.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 2f698203..35a45643 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -56,11 +56,11 @@ jobs: # Upload entire repository # path: '.' - name: Deploy documentation. - if: ${{ github.event_name == 'pull_request' }} - uses: JamesIves/github-pages-deploy-action@v4.3.0 - with: - branch: gh-pages - force: true - folder: gh-pages + if: ${{ github.event_name == 'pull_request' }} + uses: JamesIves/github-pages-deploy-action@v4.3.0 + with: + branch: gh-pages + force: true + folder: gh-pages From 49a34e4303c4553daa741469d205e9edd7f14ec3 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Tue, 6 Sep 2022 12:26:13 -0400 Subject: [PATCH 100/155] gh pages setup - fixed indent --- .github/workflows/pages.yml | 63 +++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 35 deletions(-) diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 35a45643..a3ce24b1 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -25,42 +25,35 @@ concurrency: jobs: # Single deploy job since we're just deploying - deploy: - environment: + #deploy: + # environment: # name: github-pages # url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - name: Set up Python 3. - uses: actions/setup-python@v3 - with: - python-version: 3.9 - - name: Install dependencies - run: pip install sphinx - - name: Build documentation - run: | - mkdir gh-pages - touch gh-pages/.nojekyll - cd docs/ - sphinx-build -b html . _build - cp -r _build/* ../gh-pages/ - #- name: Setup Pages - # uses: actions/configure-pages@v1 - #- name: Upload artifact - # uses: actions/upload-pages-artifact@v1 - # with: - # Upload entire repository - # path: '.' - - name: Deploy documentation. - if: ${{ github.event_name == 'pull_request' }} - uses: JamesIves/github-pages-deploy-action@v4.3.0 - with: - branch: gh-pages - force: true - folder: gh-pages + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Set up Python 3. + uses: actions/setup-python@v3 + with: + python-version: 3.9 + - name: Install dependencies + run: pip install sphinx + - name: Build documentation + run: | + mkdir gh-pages + touch gh-pages/.nojekyll + cd docs/ + sphinx-build -b html . _build + cp -r _build/* ../gh-pages/ + - name: Deploy documentation. + if: ${{ github.event_name == 'pull_request' }} + uses: JamesIves/github-pages-deploy-action@v4.3.0 + with: + branch: gh-pages + force: true + folder: gh-pages From a7070e71739d4eb3e9035fd598e0c5737055d39e Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Tue, 6 Sep 2022 12:27:31 -0400 Subject: [PATCH 101/155] indent again --- .github/workflows/pages.yml | 53 +++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index a3ce24b1..10bdc766 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -24,36 +24,37 @@ concurrency: cancel-in-progress: true jobs: + build-docs: # Single deploy job since we're just deploying #deploy: # environment: # name: github-pages # url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - name: Set up Python 3. - uses: actions/setup-python@v3 - with: - python-version: 3.9 - - name: Install dependencies - run: pip install sphinx - - name: Build documentation - run: | - mkdir gh-pages - touch gh-pages/.nojekyll - cd docs/ - sphinx-build -b html . _build - cp -r _build/* ../gh-pages/ - - name: Deploy documentation. - if: ${{ github.event_name == 'pull_request' }} - uses: JamesIves/github-pages-deploy-action@v4.3.0 - with: - branch: gh-pages - force: true - folder: gh-pages + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Set up Python 3. + uses: actions/setup-python@v3 + with: + python-version: 3.9 + - name: Install dependencies + run: pip install sphinx + - name: Build documentation + run: | + mkdir gh-pages + touch gh-pages/.nojekyll + cd docs/ + sphinx-build -b html . _build + cp -r _build/* ../gh-pages/ + - name: Deploy documentation. + if: ${{ github.event_name == 'pull_request' }} + uses: JamesIves/github-pages-deploy-action@v4.3.0 + with: + branch: gh-pages + force: true + folder: gh-pages From 10c9a39c0ea669476bacf83b919595f858c70f7b Mon Sep 17 00:00:00 2001 From: Harshad Hegde Date: Tue, 6 Sep 2022 11:35:08 -0500 Subject: [PATCH 102/155] commented and erased few lines --- .github/workflows/pages.yml | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 10bdc766..55f74de2 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -3,9 +3,6 @@ name: Deploy static content to Pages on: # Runs on pushes targeting the default branch - #push: - # branches: ["main"] - pull_request: branches: [ "main"] @@ -13,35 +10,33 @@ on: workflow_dispatch: # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages -permissions: - contents: read - pages: write - id-token: write +# permissions: +# contents: read +# pages: write +# id-token: write # Allow one concurrent deployment -concurrency: - group: "pages" - cancel-in-progress: true +# concurrency: +# group: "pages" +# cancel-in-progress: true jobs: build-docs: - # Single deploy job since we're just deploying - #deploy: - # environment: - # name: github-pages - # url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v3 with: fetch-depth: 0 + - name: Set up Python 3. uses: actions/setup-python@v3 with: python-version: 3.9 + - name: Install dependencies run: pip install sphinx + - name: Build documentation run: | mkdir gh-pages @@ -49,6 +44,7 @@ jobs: cd docs/ sphinx-build -b html . _build cp -r _build/* ../gh-pages/ + - name: Deploy documentation. if: ${{ github.event_name == 'pull_request' }} uses: JamesIves/github-pages-deploy-action@v4.3.0 From f5cc00515594ee4c2fd89eb2a6bc82c61133ce59 Mon Sep 17 00:00:00 2001 From: Harshad Hegde Date: Tue, 6 Sep 2022 11:36:57 -0500 Subject: [PATCH 103/155] typo and rearrange lines --- .github/workflows/pages.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 55f74de2..a34a81b1 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -2,12 +2,11 @@ name: Deploy static content to Pages on: - # Runs on pushes targeting the default branch - pull_request: - branches: [ "main"] - # Allows you to run this workflow manually from the Actions tab workflow_dispatch: + # Runs on pushes targeting the default branch + pull_request: + branches: [ main ] # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages # permissions: @@ -44,7 +43,7 @@ jobs: cd docs/ sphinx-build -b html . _build cp -r _build/* ../gh-pages/ - + - name: Deploy documentation. if: ${{ github.event_name == 'pull_request' }} uses: JamesIves/github-pages-deploy-action@v4.3.0 From 0406208803ebec40ef68550e64b3c37290b7409b Mon Sep 17 00:00:00 2001 From: Harshad Hegde Date: Tue, 6 Sep 2022 11:43:36 -0500 Subject: [PATCH 104/155] testing v3 => master --- .github/workflows/pages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index a34a81b1..0bf6ac45 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@master with: fetch-depth: 0 From 2fad85078f3e7a9a4282521477d809e6194911e0 Mon Sep 17 00:00:00 2001 From: Harshad Hegde Date: Tue, 6 Sep 2022 11:49:25 -0500 Subject: [PATCH 105/155] extra indent --- .github/workflows/pages.yml | 67 ++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 39 deletions(-) diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 0bf6ac45..046bade3 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -8,48 +8,37 @@ on: pull_request: branches: [ main ] -# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages -# permissions: -# contents: read -# pages: write -# id-token: write - -# Allow one concurrent deployment -# concurrency: -# group: "pages" -# cancel-in-progress: true - jobs: build-docs: runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@master - with: - fetch-depth: 0 - - - name: Set up Python 3. - uses: actions/setup-python@v3 - with: - python-version: 3.9 - - - name: Install dependencies - run: pip install sphinx - - - name: Build documentation - run: | - mkdir gh-pages - touch gh-pages/.nojekyll - cd docs/ - sphinx-build -b html . _build - cp -r _build/* ../gh-pages/ - - - name: Deploy documentation. - if: ${{ github.event_name == 'pull_request' }} - uses: JamesIves/github-pages-deploy-action@v4.3.0 - with: - branch: gh-pages - force: true - folder: gh-pages + - name: Checkout + uses: actions/checkout@master + with: + fetch-depth: 0 + + - name: Set up Python 3. + uses: actions/setup-python@v3 + with: + python-version: 3.9 + + - name: Install dependencies + run: pip install sphinx + + - name: Build documentation + run: | + mkdir gh-pages + touch gh-pages/.nojekyll + cd docs/ + sphinx-build -b html . _build + cp -r _build/* ../gh-pages/ + + - name: Deploy documentation. + if: ${{ github.event_name == 'pull_request' }} + uses: JamesIves/github-pages-deploy-action@v4.3.0 + with: + branch: gh-pages + force: true + folder: gh-pages From 33394437a8e9d535efb3056224d987e3ddcaec68 Mon Sep 17 00:00:00 2001 From: Harshad Hegde Date: Tue, 6 Sep 2022 11:51:59 -0500 Subject: [PATCH 106/155] switched back version master=>v3 --- .github/workflows/pages.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 046bade3..2a01ea20 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -13,10 +13,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@master + uses: actions/checkout@v3 with: - fetch-depth: 0 - + fetch-depth: 0 # otherwise, you will failed to push refs to dest repo + - name: Set up Python 3. uses: actions/setup-python@v3 with: From f636fa2e0775fdfb27de900abe0c6f4ca2f723f7 Mon Sep 17 00:00:00 2001 From: Harshad Hegde Date: Tue, 6 Sep 2022 11:56:35 -0500 Subject: [PATCH 107/155] switched branch name --- .github/workflows/pages.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 2a01ea20..58d818b4 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -5,8 +5,8 @@ on: # Allows you to run this workflow manually from the Actions tab workflow_dispatch: # Runs on pushes targeting the default branch - pull_request: - branches: [ main ] + push: + branches: [ "0.4.5" ] jobs: build-docs: @@ -34,7 +34,7 @@ jobs: cp -r _build/* ../gh-pages/ - name: Deploy documentation. - if: ${{ github.event_name == 'pull_request' }} + if: ${{ github.event_name == 'push' }} uses: JamesIves/github-pages-deploy-action@v4.3.0 with: branch: gh-pages From dd55d69725176a6a3af3754a47b251ec0e5f37eb Mon Sep 17 00:00:00 2001 From: pnrobinson Date: Tue, 6 Sep 2022 14:02:54 -0400 Subject: [PATCH 108/155] introductory text --- docs/index.rst | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index bf2187bd..ec727e22 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -6,17 +6,44 @@ Welcome to phenopacket-tools's documentation! ============================================= +The `Phenopacket Schema `_ of the +`Global Alliance for Genomics and Health (GA4GH) `_ was +approved by the GA4GH in 2022 and additional certified by the International Standards + Organization (ISO) as `ISO 4454:2022 `_. +A description of the schema was published in +`Jacobsen JOB, et al. 2022 `_ and a detailed tutorial +appeared in `Ladewig et al., 2022 < https://onlinelibrary.wiley.com/doi/full/10.1002/ggn2.202200016>`_. + +A Phenopacket characterizes an individual person or biosample, linking that individual to detailed phenotypic descriptions, +genetic information, diagnoses, and treatments. The Phenopacket schema supports the FAIR principles +(findable, accessible, interoperable, and reusable), and computability. Specifically, +Phenopackets are designed to be both human and machine-interpretable, enabling computing operations and validation on +the basis of defined relationships between diagnoses, lab measurements, and genotypic information. + +The phenopacket-tools library was written as a modular Java 17 library and has three main goals. + +- To provide a simplified interface for creating GA4GH phenopackets with Java code +- To provide an extensible validation framework that can be used to check phenopackets for syntactical and semantic correctness. +- To enable developers to extend the validation framework to encode the specific requirements of consortia or projects using either JSON schema or programmatic tools. + +Additionally, phenopacket-tools provides code to convert version 1 to the version 2 (the current version) of the Schema. + +

+ The Phenopacket provides a standardized way of reporting HPO terms and providing additional context. The image and some of the text on this page were adapted from this article. +

+ + + + + .. toctree:: :maxdepth: 2 :caption: Contents: static/intro.md - modules -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` +I
+ GA4GH Phenopacket +
Phenopacket Schema overview. The GA4GH Phenopacket Schema is a hierarchical structure that consists of two required fields, id and MetaData, as well as eight optional fields, Individual, Disease, Interpretation, Biosample, PhenotypicFeature, Measurement, MedicalAction, and files. Figure and text from LAdewig et al.,
+
\ No newline at end of file From 761644d61d33afd15b7987dbedf36e6b6180180c Mon Sep 17 00:00:00 2001 From: pnrobinson Date: Tue, 6 Sep 2022 15:12:10 -0400 Subject: [PATCH 109/155] adding text on building phenopackets --- docs/_static/creating.rst | 81 +++++++++++++++++++ docs/index.rst | 15 +--- .../builder/PhenopacketBuilder.java | 5 ++ .../command/ExamplesCommand.java | 1 + ...rvicofacialActinomycosisOfTheMandible.java | 54 +++++++++++-- ...SevereStatinInducedAutoimmuneMyopathy.java | 11 ++- 6 files changed, 149 insertions(+), 18 deletions(-) create mode 100644 docs/_static/creating.rst diff --git a/docs/_static/creating.rst b/docs/_static/creating.rst new file mode 100644 index 00000000..6807592a --- /dev/null +++ b/docs/_static/creating.rst @@ -0,0 +1,81 @@ +.. _rstcreating: + + +===================== +Creating Phenopackets +===================== + +Google's `Protocol Buffer (protobuf) `_ framework automatically generates +Java code for building and working with Phenopackets. However, the code can be unwieldly. Additionally, many users +of the phenopacket framework will want to use a recommeded set of ontology terms for specific kinds of data, and thus +the phenopacket-tools library provides constants that are more convenient to use than manually creating the equilavent message. + + +Phenopacket-tools builder pattern +================================= + +In this example, let's imagine we want to create a PhenotypicFeature element to denote that severe weakness of the +left triceps muscle was observed in a patient at the age of 11 years and 4 months. First, let us code this using +the Phenopacket code that is automatically generated by the protobuf framework. + + +.. code-block:: java + + OntologyClass tricepsWeakenss = OntologyClass.newBuilder() + .setId("HP:0031108") + .setLabel("Triceps weakness") + .build(); + OntologyClass left = OntologyClass.newBuilder() + .setId("HP:0012835") + .setLabel("Left") + .build(); + OntologyClass severe = OntologyClass.newBuilder() + .setId("HP:0012828") + .setLabel("Severe") + .build(); + Age iso8601duration = Age.newBuilder().setIso8601Duration("P11Y4M").build(); + TimeElement ageElement = TimeElement.newBuilder().setAge(iso8601duration) + .setAge(iso8601duration) + .build(); + PhenotypicFeature pfeature = PhenotypicFeature.newBuilder() + .setType(tricepsWeakenss) + .setOnset(ageElement) + .setSeverity(severe) + .addModifiers(left) + .build(); + +The following code block uses functions from the phenopacket-tools library to simplify the creation of this PhenotypicFeature element. + +.. code-block:: java + + PhenotypicFeature pfeature2 = PhenotypicFeatureBuilder.builder("HP:0031108","Triceps weakness") + .addModifier(severe()) + .addModifier(left()) + .onset(TimeElements.age("P11Y4M")) + .build(); + +Both code snippets generate identical phenopacket code. + +.. code-block:: json + + { + "type": { + "id": "HP:0031108", + "label": "Triceps weakness" + }, + "severity": { + "id": "HP:0012828", + "label": "Severe" + }, + "modifiers": [{ + "id": "HP:0012835", + "label": "Left" + }], + "onset": { + "age": { + "iso8601duration": "P11Y4M" + } + } + } + +Several detailed examples are available in the phenopackets-tools-cli module in the ``examples`` package. \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index ec727e22..ac662f99 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -28,22 +28,15 @@ The phenopacket-tools library was written as a modular Java 17 library and has t Additionally, phenopacket-tools provides code to convert version 1 to the version 2 (the current version) of the Schema. -

- The Phenopacket provides a standardized way of reporting HPO terms and providing additional context. The image and some of the text on this page were adapted from this article. -

- - - .. toctree:: :maxdepth: 2 :caption: Contents: - static/intro.md + _static/creating modules -I
- GA4GH Phenopacket -
Phenopacket Schema overview. The GA4GH Phenopacket Schema is a hierarchical structure that consists of two required fields, id and MetaData, as well as eight optional fields, Individual, Disease, Interpretation, Biosample, PhenotypicFeature, Measurement, MedicalAction, and files. Figure and text from LAdewig et al.,
-
\ No newline at end of file + +.. image:: https://onlinelibrary.wiley.com/cms/asset/1cc0a141-da65-45a3-b7b0-6316b7b02069/ggn2202200016-fig-0002-m.jpg + :alt: GA4GH Phenopacket diff --git a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/PhenopacketBuilder.java b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/PhenopacketBuilder.java index b06ef364..17334e04 100644 --- a/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/PhenopacketBuilder.java +++ b/phenopacket-tools-builder/src/main/java/org/phenopackets/phenopackettools/builder/PhenopacketBuilder.java @@ -68,6 +68,11 @@ public PhenopacketBuilder addDisease(Disease disease) { return this; } + public PhenopacketBuilder addAllDiseases(List diseaseList) { + builder.addAllDiseases(diseaseList); + return this; + } + public PhenopacketBuilder addMedicalAction(MedicalAction medicalAction) { builder.addMedicalActions(medicalAction); return this; diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java index a5052787..18bc86ad 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/command/ExamplesCommand.java @@ -125,6 +125,7 @@ private int outputAllPhenopackets() { output(new Covid().getPhenopacket(), outDirectory, "covid"); output(new Retinoblastoma().getPhenopacket(), outDirectory, "retinoblastoma"); output(new WarburgMicroSyndrome().getPhenopacket(), outDirectory, "warburg-micro-syndrome"); + output(new CervicofacialActinomycosisOfTheMandible().getPhenopacket(), outDirectory, "warburg-micro-syndrome"); outputFamily(new FamilyWithPedigree().getFamily(), outDirectory, "family"); } catch (Exception e) { System.err.println(e.getMessage()); diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/CervicofacialActinomycosisOfTheMandible.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/CervicofacialActinomycosisOfTheMandible.java index 66633e61..0ae6cb82 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/CervicofacialActinomycosisOfTheMandible.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/CervicofacialActinomycosisOfTheMandible.java @@ -1,17 +1,19 @@ package org.phenopackets.phenopackettools.examples; +import com.google.protobuf.util.JsonFormat; import org.phenopackets.phenopackettools.builder.PhenopacketBuilder; import org.phenopackets.phenopackettools.builder.builders.*; +import org.phenopackets.schema.v2.core.Age; import org.phenopackets.schema.v2.Phenopacket; -import org.phenopackets.schema.v2.core.Individual; -import org.phenopackets.schema.v2.core.MedicalAction; -import org.phenopackets.schema.v2.core.PhenotypicFeature; +import org.phenopackets.schema.v2.core.*; import java.util.List; import static org.phenopackets.phenopackettools.builder.builders.OntologyClassBuilder.ontologyClass; +import static org.phenopackets.phenopackettools.builder.constants.Laterality.left; +import static org.phenopackets.phenopackettools.builder.constants.Severity.severe; -public class CervicofacialActinomycosisOfTheMandible { +public class CervicofacialActinomycosisOfTheMandible implements PhenopacketExample { private static final String PHENOPACKET_ID = "arbitrary.id"; @@ -49,7 +51,7 @@ public CervicofacialActinomycosisOfTheMandible() { // .addMedicalAction(frozenSection()) // .addMedicalAction(tissueCultures()) // .addMedicalAction(anaerobicCultures()) -// .addMedicalAction(treatment()) + .addMedicalAction(treatment()) .build(); } @@ -131,6 +133,43 @@ private List getLast8Monthsistory() { * - 6-month course of oral amoxicillin 1000mg two times per day */ private MedicalAction treatment() { + + //automatically generated + OntologyClass tricepsWeakenss = OntologyClass.newBuilder() + .setId("HP:0031108") + .setLabel("Triceps weakness") + .build(); + OntologyClass left = OntologyClass.newBuilder() + .setId("HP:0012835") + .setLabel("Left") + .build(); + OntologyClass severe = OntologyClass.newBuilder() + .setId("HP:0012828") + .setLabel("Severe") + .build(); + Age iso8601duration = Age.newBuilder().setIso8601Duration("P11Y4M").build(); + var ageElement = TimeElement.newBuilder().setAge(iso8601duration) + .setAge(iso8601duration) + .build(); + PhenotypicFeature pfeature = PhenotypicFeature.newBuilder() + .setType(tricepsWeakenss) + .setOnset(ageElement) + .setSeverity(severe) + .addModifiers(left) + .build(); + + PhenotypicFeature pfeature2 = PhenotypicFeatureBuilder.builder("HP:0031108","Triceps weakness") + .severity(severe()) + .addModifier(left()) + .onset(TimeElements.age("P11Y4M")) + .build(); + try { + System.out.println(JsonFormat.printer().print(pfeature)); + System.out.println(JsonFormat.printer().print(pfeature2)); + } catch (Exception e) { + e.printStackTrace(); + } + return null; } @@ -157,6 +196,11 @@ private List getMedicalHistory() { return List.of(mandiblePain, fever); } + @Override + public Phenopacket getPhenopacket() { + return phenopacket; + } + /** * Diagnosis: cervicofacial actinomycosis */ diff --git a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SevereStatinInducedAutoimmuneMyopathy.java b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SevereStatinInducedAutoimmuneMyopathy.java index 9ca3e23d..27aa0597 100644 --- a/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SevereStatinInducedAutoimmuneMyopathy.java +++ b/phenopacket-tools-cli/src/main/java/org/phenopackets/phenopackettools/examples/SevereStatinInducedAutoimmuneMyopathy.java @@ -40,6 +40,7 @@ public SevereStatinInducedAutoimmuneMyopathy() { phenopacket = PhenopacketBuilder.create(PHENOPACKET_ID, metadata) .individual(proband) + .addAllDiseases(getDiseases()) .addAllPhenotypicFeatures(getMedicalHistory()) .addMedicalAction(existingTreatment()) .addAllPhenotypicFeatures(getLastMonthHistory()) @@ -52,9 +53,15 @@ public SevereStatinInducedAutoimmuneMyopathy() { } + /** + * Returns the disease diagnoses that form the past medical history of our patient -- type 2 Disbetes mellitus and + * hypertension. + * @return + */ List getDiseases() { - var niddm = DiseaseBuilder.builder("MONDO:0005148", "type 2 diabetes mellitus").build(); - var htn = DiseaseBuilder.builder("MONDO:0001134", "essential hypertension").build(); + var age55y = TimeElements.age("P55Y"); + var niddm = DiseaseBuilder.builder("MONDO:0005148", "type 2 diabetes mellitus").onset(age55y).build(); + var htn = DiseaseBuilder.builder("MONDO:0001134", "essential hypertension").onset(age55y).build(); return List.of(niddm, htn); } From a67a9473bde54059dbc04eaca2eba2ac2daea7e1 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Tue, 6 Sep 2022 16:04:42 -0400 Subject: [PATCH 110/155] more documentation --- docs/_build/doctrees/environment.pickle | Bin 12659 -> 17993 bytes docs/_build/doctrees/index.doctree | Bin 5060 -> 10928 bytes docs/_build/doctrees/modules.doctree | Bin 2735 -> 2731 bytes docs/_build/html/_sources/index.rst.txt | 34 ++++++++++++++---- docs/_build/html/_static/pygments.css | 1 + docs/_build/html/genindex.html | 1 + docs/_build/html/index.html | 37 ++++++++++++++------ docs/_build/html/objects.inv | Bin 285 -> 545 bytes docs/_build/html/search.html | 1 + docs/_build/html/searchindex.js | 2 +- docs/{_static => }/creating.rst | 0 docs/index.rst | 8 ++--- docs/modules.rst | 6 ---- docs/validation.rst | 44 ++++++++++++++++++++++++ 14 files changed, 106 insertions(+), 28 deletions(-) rename docs/{_static => }/creating.rst (100%) delete mode 100644 docs/modules.rst create mode 100644 docs/validation.rst diff --git a/docs/_build/doctrees/environment.pickle b/docs/_build/doctrees/environment.pickle index 99fbf230ad0a6e7769a757a22f230fd25fc85897..376259a4cf7b4a6820d26d2d2f8829db8349e68a 100644 GIT binary patch literal 17993 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 aHX9}zVQKpef#4H(-0Y&e^}uG$`u_vK^78rs delta 3129 zcmbtWUuYaf7{A zAyML4p$UNjBQrh;_C+a(6-20(Dt&2flxk`%L3~rtf{K5sf-m~b>^7HN_Ns|5^Udze z_nYtk_kBz&eot4vQ2C0|^KxZ!Ya;e|9-H|XvCMswvEk{Ag3KJ7=xIBUA6Ha;Dwayy zs+Nsqjf`btoaZ!@H#1q)I){w*c&eBh9ex-$7Zr>SI!b-K$t?Z#;0MbzofL`Je zT9q@hwkA+3RXvNR_=25Q2H$;T$8~>5i7NrcWDniDr=3jteZHgdFF$;>t{N7bEe(w$6YCZy=h*SclLhh~T(r~jaq>Rw?>oU~c!ZpXt&$)g z02$%r0uZ`oT*10Ajxx_+D{2{rmggsV@wV4Fxde>l3s~$lA|C-2*o!~`^b;UY1HIyW ze&&#?lGx-LP**sc)@X)4W~r92sX!2hBj>~-jOIK*gO-t5b$ph+)_u?JHF`vdG)uLn z=B<=!;T+heL|=BJd;ftoOfHX!M==;KgV*zb2*O4TMGy4~R&r4+QuRM!S4Q>qnzJ*p zHgI3#zB>z2`yCXWk_T8B4c84;@m>Dd~j zXB5K})sNHWonUzJeiYu1y6?LNEQWL6MqUDaJ;J#cAPSrEW2q0k{dik9ickRO6=d-# zn^EO_8zGx?ZfOBNT2g_@S0I<;OJgGzmUYMWsyo_7V7wirN{I4xXA7LKWI%j%)7ea| zvDt;)bDgq!ih@C+u+aFw6$`gr%W^?tz>*9)W;_Y|O$Ax8SUCE72ibou7Nh@13_ESp z2B_;P-OixtKh!b>%rtatI+r%IV(YlXF7`iM5o7i7gkKqCPsF!xRR)tjn}##0g)G(3MKgz! zg?Mz=Wk4m*i2z=N-AZ2;U37?CfnP)9(*XM>zPGR>Kd#DEIBSS}4(mL*1}kWAT@px7 zF;~oR`J$4N4<%Rip<81FaELSpZEfl&&it?p5Hq~krd$*n%pps8N=_i|m3jr`Q+UFb z+7yS6d5Jl1JC84jw;Tp?Q$jmt2#EGnJOe{a3~ci+2iU?uyT3Zf-X6GrxF!geZAfY8 z+3A#JB0aAmON=1oMG%@+jbR;|NP|HW$~p|177S$M4&agJq(ST&VVUEzJUz#0n0YgxLH899UNz8I`m-uRt81N-zl#4tQ V&@TQg2d}U*iKM?L$o@(^_76k<<5d6v diff --git a/docs/_build/doctrees/index.doctree b/docs/_build/doctrees/index.doctree index fc0635ab2d23981ea35dbd661d52264f7e8768f7..8d3f77ee8f3fd416a2ed6490e24437a3e9faaf4f 100644 GIT binary patch literal 10928 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 E3+&}}1MO+ho*<3 zMXXiEg3hS-7Cc+(#j6ydpokX_{te#zKoE;Fo2=bNi}kR>ypMVB&2Qhl=VNPq!CS${ zFFRL)@0w2y<;E;zTDg*Kp1htLosmH@%cEwcgk;;w8G!VPA<5Io&f1lVX5}mcRJ}?> zVS`*wpi~}*$`!@YkVWUIgxgeI)*J;*s$5f`a8V*(6SJLg#erTp4}Fk^%y1aG;T%~^ z9&d&rGMri-ha;IeI!n_K1Q9|7wi)mgIC?=>R2f-GNmr7#ROErV4@CZIxjYb zlu)mzx0$` zwWhO>WXe!$IUlEQ4V-H7Ca0Pl!D8)v1Emf3_mF2DT{|ZAgOe(5L#osoXlnW|SYBOz zRNV~B_bsTn<_p&Z-KHWVsTlbvbWC8e=x7>m&p^N1|8u@Bbl|!v>>2&G`o;!%o9bzavKZvO5MOOQ^fM5+x+?a57EVJMN~II*wxt2K iI5@0JWyD{V}T_fpzMFjVuw2!nXRM#i>Qb`bGIknRx~Jo++t`lM5N8SyJ+oi#JbVl;s2f DdLR#W delta 51 zcmZ22x?Yr}fpzMVjVuw2qK^8Z#i>Qb`dKAKCT02omB|^2MY)sn8Kv2Z3o`_ of the +`Global Alliance for Genomics and Health (GA4GH) `_ was +approved by the GA4GH in 2022 and additional certified by the International Standards +Organization (ISO) as `ISO 4454:2022 `_. +A description of the schema was published in +`Jacobsen JOB, et al. 2022 `_ and a detailed tutorial +appeared in `Ladewig et al., 2022 `_. + +A Phenopacket characterizes an individual person or biosample, linking that individual to detailed phenotypic descriptions, +genetic information, diagnoses, and treatments. The Phenopacket schema supports the FAIR principles +(findable, accessible, interoperable, and reusable), and computability. Specifically, +Phenopackets are designed to be both human and machine-interpretable, enabling computing operations and validation on +the basis of defined relationships between diagnoses, lab measurements, and genotypic information. + +The phenopacket-tools library was written as a modular Java 17 library and has three main goals. + +- To provide a simplified interface for creating GA4GH phenopackets with Java code +- To provide an extensible validation framework that can be used to check phenopackets for syntactical and semantic correctness. +- To enable developers to extend the validation framework to encode the specific requirements of consortia or projects using either JSON schema or programmatic tools. + +Additionally, phenopacket-tools provides code to convert version 1 to the version 2 (the current version) of the Schema. + + + .. toctree:: :maxdepth: 2 :caption: Contents: - static/intro.md - + creating modules -Indices and tables -================== -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` +.. image:: https://onlinelibrary.wiley.com/cms/asset/1cc0a141-da65-45a3-b7b0-6316b7b02069/ggn2202200016-fig-0002-m.jpg + :alt: GA4GH Phenopacket diff --git a/docs/_build/html/_static/pygments.css b/docs/_build/html/_static/pygments.css index 87f8bd12..9abe04ba 100644 --- a/docs/_build/html/_static/pygments.css +++ b/docs/_build/html/_static/pygments.css @@ -54,6 +54,7 @@ span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: .highlight .nt { color: #004461; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #000000 } /* Name.Variable */ .highlight .ow { color: #004461; font-weight: bold } /* Operator.Word */ +.highlight .pm { color: #000000; font-weight: bold } /* Punctuation.Marker */ .highlight .w { color: #f8f8f8; text-decoration: underline } /* Text.Whitespace */ .highlight .mb { color: #990000 } /* Literal.Number.Bin */ .highlight .mf { color: #990000 } /* Literal.Number.Float */ diff --git a/docs/_build/html/genindex.html b/docs/_build/html/genindex.html index f1c497bb..3fc1d217 100644 --- a/docs/_build/html/genindex.html +++ b/docs/_build/html/genindex.html @@ -57,6 +57,7 @@

phenopacket-tools

Navigation

Contents:

diff --git a/docs/_build/html/index.html b/docs/_build/html/index.html index 5d5bd868..39808881 100644 --- a/docs/_build/html/index.html +++ b/docs/_build/html/index.html @@ -16,7 +16,7 @@ - + @@ -35,22 +35,38 @@

Welcome to phenopacket-tools’s documentation!

+

The Phenopacket Schema of the +Global Alliance for Genomics and Health (GA4GH) was +approved by the GA4GH in 2022 and additional certified by the International Standards +Organization (ISO) as ISO 4454:2022. +A description of the schema was published in +Jacobsen JOB, et al. 2022 and a detailed tutorial +appeared in Ladewig et al., 2022.

+

A Phenopacket characterizes an individual person or biosample, linking that individual to detailed phenotypic descriptions, +genetic information, diagnoses, and treatments. The Phenopacket schema supports the FAIR principles +(findable, accessible, interoperable, and reusable), and computability. Specifically, +Phenopackets are designed to be both human and machine-interpretable, enabling computing operations and validation on +the basis of defined relationships between diagnoses, lab measurements, and genotypic information.

+

The phenopacket-tools library was written as a modular Java 17 library and has three main goals.

+
    +
  • To provide a simplified interface for creating GA4GH phenopackets with Java code

  • +
  • To provide an extensible validation framework that can be used to check phenopackets for syntactical and semantic correctness.

  • +
  • To enable developers to extend the validation framework to encode the specific requirements of consortia or projects using either JSON schema or programmatic tools.

  • +
+

Additionally, phenopacket-tools provides code to convert version 1 to the version 2 (the current version) of the Schema.

-
-
-

Indices and tables

- +GA4GH Phenopacket
@@ -72,6 +88,7 @@

phenopacket-tools

Navigation

Contents:

@@ -79,7 +96,7 @@

Navigation

Related Topics

diff --git a/docs/_build/html/objects.inv b/docs/_build/html/objects.inv index 3e1dfc15f0272ecbc63a4e1178a67bd3a90fc415..ad50d850e73a3ff66608038e0cbe163d02e440e3 100644 GIT binary patch delta 428 zcmV;d0aN~+0-*$ue}A=9&2F1O5We#i8>NTlun_D@RjMda<@!Knr&evL=gl%P+w2cw zhRE)zuaVcwlLWjt#&Rl(ET3R!=KGnCA6bAPWtR*o{gOJ#c+6x|3o|mBjkXiB46MtA zd<4Q^30Bz@RvVla_n>R!w(5~deH-k?8v546FVNB%VB}c7V}Ix5oW_^G&&VoBX~0tD zz}d6Fxbz*>e9gBFPdjyKsiDy~n*+8TG$lWLARM&#I)r9x%ADQTE0AP6)Hn2Atmhy8 z5iEizWVVm=H7_~${h3%o@C5cL(&|3SH$H~pRfLLw*IZQ}qwmW876U#E<8TnB3W+QG z;G#(~8sE*w?SDv)r1IXbtz)D}!%erfsVE-Hd@de<4=T?1NPFFM{Vj^>0SF{0_+|Jx zjN5B}8_!2Sli4Eqao5Y{|4}v{M<$3VWM8+K+iuIs)ED&!cpQE@I@C@!Z*-9Xn(vQ8$PL)4t{n#tyLl9!m?1rfn#2*krhvc%$zi0V^ch() zk