diff --git a/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/qicore/v600/BaseTest.java b/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/qicore/v600/BaseTest.java new file mode 100644 index 000000000..7eae5420a --- /dev/null +++ b/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/qicore/v600/BaseTest.java @@ -0,0 +1,168 @@ +package org.cqframework.cql.cql2elm.qicore.v600; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import org.cqframework.cql.cql2elm.CqlTranslator; +import org.cqframework.cql.cql2elm.TestUtils; +import org.hl7.elm.r1.*; +import org.testng.annotations.Test; + +public class BaseTest { + @Test + public void testQICore() throws IOException { + CqlTranslator translator = TestUtils.runSemanticTest("qicore/v600/TestQICore.cql", 0); + + Library library = translator.toELM(); + Map defs = new HashMap<>(); + + if (library.getStatements() != null) { + for (ExpressionDef def : library.getStatements().getDef()) { + defs.put(def.getName(), def); + } + } + + ExpressionDef def = null; + Retrieve retrieve = null; + Union union = null; + Query query = null; + + def = defs.get("TestAge"); + assertThat(def.getExpression(), instanceOf(CalculateAge.class)); + CalculateAge age = (CalculateAge) def.getExpression(); + assertThat(age.getOperand(), instanceOf(Property.class)); + Property p = (Property) age.getOperand(); + assertThat(p.getPath(), is("value")); + assertThat(p.getSource(), instanceOf(Property.class)); + p = (Property) p.getSource(); + assertThat(p.getPath(), is("birthDate")); + + def = defs.get("TestAgeAt"); + assertThat(def.getExpression(), instanceOf(CalculateAgeAt.class)); + CalculateAgeAt ageAt = (CalculateAgeAt) def.getExpression(); + assertThat(ageAt.getOperand().size(), is(2)); + assertThat(ageAt.getOperand().get(0), instanceOf(Property.class)); + p = (Property) ageAt.getOperand().get(0); + assertThat(p.getPath(), is("value")); + assertThat(p.getSource(), instanceOf(Property.class)); + p = (Property) p.getSource(); + assertThat(p.getPath(), is("birthDate")); + + def = defs.get("TestAdverseEvent"); + assertThat(def.getExpression(), instanceOf(Retrieve.class)); + retrieve = (Retrieve) def.getExpression(); + assertThat( + retrieve.getTemplateId(), is("http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-adverseevent")); + + def = defs.get("TestSpecificCommunicationNotDone"); + assertThat(def.getExpression(), instanceOf(Union.class)); + union = (Union) def.getExpression(); + assertThat(union.getOperand().size(), is(2)); + assertThat(union.getOperand().get(0), instanceOf(Retrieve.class)); + retrieve = (Retrieve) union.getOperand().get(0); + assertThat( + retrieve.getTemplateId(), + is("http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-communicationnotdone")); + assertThat(retrieve.getCodeComparator(), is("~")); + assertThat(union.getOperand().get(1), instanceOf(Retrieve.class)); + retrieve = (Retrieve) union.getOperand().get(1); + assertThat( + retrieve.getTemplateId(), + is("http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-communicationnotdone")); + assertThat(retrieve.getCodeComparator(), is("contains")); + + def = defs.get("TestSpecificCommunicationNotDoneExplicit"); + assertThat(def.getExpression(), instanceOf(Query.class)); + query = (Query) def.getExpression(); + assertThat(query.getSource().size(), is(1)); + assertThat(query.getSource().get(0).getExpression(), instanceOf(Retrieve.class)); + retrieve = (Retrieve) query.getSource().get(0).getExpression(); + assertThat( + retrieve.getTemplateId(), + is("http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-communicationnotdone")); + Expression whereClause = query.getWhere(); + assertThat(whereClause, instanceOf(Or.class)); + Expression left = ((Or) whereClause).getOperand().get(0); + Expression right = ((Or) whereClause).getOperand().get(1); + assertThat(left, instanceOf(Equivalent.class)); + assertThat(right, instanceOf(InValueSet.class)); + + def = defs.get("TestGeneralCommunicationNotDone"); + assertThat(def.getExpression(), instanceOf(Union.class)); + union = (Union) def.getExpression(); + assertThat(union.getOperand().size(), is(2)); + assertThat(union.getOperand().get(0), instanceOf(Retrieve.class)); + retrieve = (Retrieve) union.getOperand().get(0); + assertThat( + retrieve.getTemplateId(), + is("http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-communicationnotdone")); + assertThat(retrieve.getCodeComparator(), is("in")); + assertThat(union.getOperand().get(1), instanceOf(Retrieve.class)); + retrieve = (Retrieve) union.getOperand().get(1); + assertThat( + retrieve.getTemplateId(), + is("http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-communicationnotdone")); + assertThat(retrieve.getCodeComparator(), is("~")); + assertThat(retrieve.getCodes(), instanceOf(ValueSetRef.class)); + + def = defs.get("TestGeneralDeviceNotRequested"); + assertThat(def.getExpression(), instanceOf(Union.class)); + union = (Union) def.getExpression(); + assertThat(union.getOperand().size(), is(2)); + assertThat(union.getOperand().get(0), instanceOf(Retrieve.class)); + retrieve = (Retrieve) union.getOperand().get(0); + assertThat( + retrieve.getTemplateId(), + is("http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-devicenotrequested")); + assertThat(retrieve.getCodeComparator(), is("in")); + assertThat(union.getOperand().get(1), instanceOf(Retrieve.class)); + retrieve = (Retrieve) union.getOperand().get(1); + assertThat( + retrieve.getTemplateId(), + is("http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-devicenotrequested")); + assertThat(retrieve.getCodeComparator(), is("~")); + assertThat(retrieve.getCodes(), instanceOf(ValueSetRef.class)); + + def = defs.get("TestGeneralDeviceNotRequestedCode"); + assertThat(def.getExpression(), instanceOf(Retrieve.class)); + retrieve = (Retrieve) def.getExpression(); + assertThat( + retrieve.getTemplateId(), + is("http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-devicenotrequested")); + assertThat(retrieve.getCodeComparator(), is("in")); + assertThat(retrieve.getCodes(), instanceOf(ValueSetRef.class)); + + def = defs.get("TestGeneralDeviceNotRequestedValueSet"); + assertThat(def.getExpression(), instanceOf(Retrieve.class)); + retrieve = (Retrieve) def.getExpression(); + assertThat( + retrieve.getTemplateId(), + is("http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-devicenotrequested")); + assertThat(retrieve.getCodeComparator(), is("~")); + assertThat(retrieve.getCodes(), instanceOf(ValueSetRef.class)); + + def = defs.get("TestGeneralDeviceNotRequestedCodeExplicit"); + assertThat(def.getExpression(), instanceOf(Query.class)); + query = (Query) def.getExpression(); + assertThat(query.getWhere(), instanceOf(InValueSet.class)); + InValueSet inValueSet = (InValueSet) query.getWhere(); + assertThat(inValueSet.getCode(), instanceOf(FunctionRef.class)); + FunctionRef fr = (FunctionRef) inValueSet.getCode(); + assertThat(fr.getLibraryName(), is("FHIRHelpers")); + assertThat(fr.getName(), is("ToConcept")); + + def = defs.get("TestGeneralDeviceNotRequestedValueSetExplicit"); + assertThat(def.getExpression(), instanceOf(Query.class)); + query = (Query) def.getExpression(); + assertThat(query.getWhere(), instanceOf(Equivalent.class)); + Equivalent eq = (Equivalent) query.getWhere(); + assertThat(eq.getOperand().get(0), instanceOf(FunctionRef.class)); + fr = (FunctionRef) eq.getOperand().get(0); + assertThat(fr.getLibraryName(), is("FHIRHelpers")); + assertThat(fr.getName(), is("ToValueSet")); + } +} diff --git a/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/uscore/v610/BaseTest.java b/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/uscore/v610/BaseTest.java new file mode 100644 index 000000000..6c2190857 --- /dev/null +++ b/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/uscore/v610/BaseTest.java @@ -0,0 +1,401 @@ +package org.cqframework.cql.cql2elm.uscore.v610; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import org.cqframework.cql.cql2elm.CqlTranslator; +import org.cqframework.cql.cql2elm.TestUtils; +import org.hl7.elm.r1.*; +import org.testng.annotations.Test; + +public class BaseTest { + + @Test + public void testUSCore() throws IOException { + CqlTranslator translator = TestUtils.runSemanticTest("uscore/v610/TestUSCore.cql", 0); + Library library = translator.toELM(); + Map defs = new HashMap<>(); + + if (library.getStatements() != null) { + for (ExpressionDef def : library.getStatements().getDef()) { + defs.put(def.getName(), def); + } + } + + /* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + */ + + ExpressionDef def = defs.get("TestPrimitives"); + assertThat(def.getExpression(), instanceOf(Query.class)); + Query query = (Query) def.getExpression(); + assertThat(query.getWhere(), instanceOf(And.class)); + And and1 = (And) query.getWhere(); + assertThat(and1.getOperand().get(0), instanceOf(And.class)); + And and2 = (And) and1.getOperand().get(0); + assertThat(and2.getOperand().get(0), instanceOf(And.class)); + And and3 = (And) and2.getOperand().get(0); + assertThat(and3.getOperand().get(0), instanceOf(And.class)); + And and4 = (And) and3.getOperand().get(0); + assertThat(and4.getOperand().get(0), instanceOf(Equal.class)); + Equal equal = (Equal) and4.getOperand().get(0); + assertThat(equal.getOperand().get(0), instanceOf(Property.class)); + Property property = (Property) equal.getOperand().get(0); + assertThat(property.getPath(), is("value")); + assertThat(property.getSource(), instanceOf(Property.class)); + property = (Property) property.getSource(); + assertThat(property.getPath(), is("gender")); + + assertThat(and4.getOperand().get(1), instanceOf(IsTrue.class)); + IsTrue isTrue = (IsTrue) and4.getOperand().get(1); + assertThat(isTrue.getOperand(), instanceOf(Property.class)); + property = (Property) isTrue.getOperand(); + assertThat(property.getPath(), is("value")); + assertThat(property.getSource(), instanceOf(Property.class)); + property = (Property) property.getSource(); + assertThat(property.getPath(), is("active")); + + assertThat(and3.getOperand().get(1), instanceOf(Before.class)); + Before before = (Before) and3.getOperand().get(1); + assertThat(before.getOperand().get(0), instanceOf(Property.class)); + property = (Property) before.getOperand().get(0); + assertThat(property.getPath(), is("value")); + assertThat(property.getSource(), instanceOf(Property.class)); + property = (Property) property.getSource(); + assertThat(property.getPath(), is("birthDate")); + + assertThat(and2.getOperand().get(1), instanceOf(InValueSet.class)); + InValueSet inValueSet = (InValueSet) and2.getOperand().get(1); + assertThat(inValueSet.getCode(), instanceOf(FunctionRef.class)); + FunctionRef functionRef = (FunctionRef) inValueSet.getCode(); + assertThat(functionRef.getLibraryName(), is("FHIRHelpers")); + assertThat(functionRef.getName(), is("ToConcept")); + assertThat(functionRef.getOperand().get(0), instanceOf(Property.class)); + property = (Property) functionRef.getOperand().get(0); + assertThat(property.getPath(), is("maritalStatus")); + + assertThat(and1.getOperand().get(1), instanceOf(Equivalent.class)); + Equivalent equivalent = (Equivalent) and1.getOperand().get(1); + assertThat(equivalent.getOperand().get(0), instanceOf(FunctionRef.class)); + functionRef = (FunctionRef) equivalent.getOperand().get(0); + assertThat(functionRef.getLibraryName(), is("FHIRHelpers")); + assertThat(functionRef.getName(), is("ToConcept")); + assertThat(functionRef.getOperand().get(0), instanceOf(Property.class)); + property = (Property) functionRef.getOperand().get(0); + assertThat(property.getPath(), is("maritalStatus")); + + /* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + */ + def = defs.get("TestPluralPrimitive"); + assertThat(def.getExpression(), instanceOf(Indexer.class)); + Indexer i = (Indexer) def.getExpression(); + assertThat(i.getOperand().size(), is(2)); + assertThat(i.getOperand().get(0), instanceOf(Flatten.class)); + Flatten f = (Flatten) i.getOperand().get(0); + assertThat(f.getOperand(), instanceOf(Query.class)); + Query q = (Query) f.getOperand(); + assertThat(q.getSource().size(), is(1)); + AliasedQuerySource aqs = q.getSource().get(0); + assertThat(aqs.getAlias(), is("$this")); + assertThat(aqs.getExpression(), instanceOf(Property.class)); + Property p = (Property) aqs.getExpression(); + assertThat(p.getPath(), is("name")); + ReturnClause r = q.getReturn(); + assertThat(r.isDistinct(), is(false)); + assertThat(r.getExpression(), instanceOf(Query.class)); + q = (Query) r.getExpression(); + assertThat(q.getSource().size(), is(1)); + aqs = q.getSource().get(0); + assertThat(aqs.getAlias(), is("$this")); + assertThat(aqs.getExpression(), instanceOf(Property.class)); + p = (Property) aqs.getExpression(); + assertThat(p.getSource(), instanceOf(AliasRef.class)); + AliasRef ar = (AliasRef) p.getSource(); + assertThat(ar.getName(), is("$this")); + assertThat(p.getPath(), is("given")); + r = q.getReturn(); + assertThat(r.isDistinct(), is(false)); + assertThat(r.getExpression(), instanceOf(Property.class)); + p = (Property) r.getExpression(); + assertThat(p.getPath(), is("value")); + assertThat(p.getScope(), is("$this")); + assertThat(i.getOperand().get(1), instanceOf(Literal.class)); + Literal l = (Literal) i.getOperand().get(1); + assertThat(l.getValue(), is("0")); + + /* + + + + + + + + + + + + + + + + + + + */ + + def = defs.get("TestSpecificPluralPrimitive"); + assertThat(def.getExpression(), instanceOf(Indexer.class)); + i = (Indexer) def.getExpression(); + assertThat(i.getOperand().size(), is(2)); + assertThat(i.getOperand().get(0), instanceOf(Query.class)); + q = (Query) i.getOperand().get(0); + assertThat(q.getSource().size(), is(1)); + aqs = q.getSource().get(0); + assertThat(aqs.getAlias(), is("$this")); + assertThat(aqs.getExpression(), instanceOf(Property.class)); + p = (Property) aqs.getExpression(); + assertThat(p.getPath(), is("given")); + assertThat(p.getSource(), instanceOf(Indexer.class)); + Indexer i2 = (Indexer) p.getSource(); + assertThat(i2.getOperand().size(), is(2)); + assertThat(i2.getOperand().get(0), instanceOf(Property.class)); + p = (Property) i2.getOperand().get(0); + assertThat(p.getPath(), is("name")); + assertThat(i2.getOperand().get(1), instanceOf(Literal.class)); + l = (Literal) i2.getOperand().get(1); + assertThat(l.getValue(), is("0")); + r = q.getReturn(); + assertThat(r.isDistinct(), is(false)); + assertThat(r.getExpression(), instanceOf(Property.class)); + p = (Property) r.getExpression(); + assertThat(p.getPath(), is("value")); + assertThat(p.getScope(), is("$this")); + assertThat(i.getOperand().get(1), instanceOf(Literal.class)); + l = (Literal) i.getOperand().get(1); + assertThat(l.getValue(), is("0")); + + /* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + */ + + // TODO: Consider using a Coalesce here rather than a type-tested case like this... + def = defs.get("TestChoice"); + assertThat(def.getExpression(), instanceOf(Query.class)); + query = (Query) def.getExpression(); + assertThat(query.getWhere(), instanceOf(Or.class)); + Or or = (Or) query.getWhere(); + assertThat(or.getOperand().get(0), instanceOf(IsFalse.class)); + IsFalse isFalse = (IsFalse) or.getOperand().get(0); + assertThat(isFalse.getOperand(), instanceOf(As.class)); + As as = (As) isFalse.getOperand(); + assertThat(as.getOperand(), instanceOf(FunctionRef.class)); + FunctionRef fr = (FunctionRef) as.getOperand(); + assertThat(fr.getLibraryName(), is("FHIRHelpers")); + assertThat(fr.getName(), is("ToValue")); + + /* + Handling a target with a complex argument to a function call. + target="FHIRHelpers.ToConcept(%parent.category[coding.system='http://terminology.hl7.org/CodeSystem/observation-category',coding.code='vital-signs'])" + */ + def = defs.get("TestComplexFHIRHelpers"); + assertThat(def.getExpression(), instanceOf(Query.class)); + query = (Query) def.getExpression(); + ReturnClause returnClause = query.getReturn(); + assertThat(returnClause.getExpression(), instanceOf(FunctionRef.class)); + // Verify FHIRHelpers function in use + functionRef = (FunctionRef) returnClause.getExpression(); + assertThat(functionRef.getName(), is("ToConcept")); + assertThat(functionRef.getLibraryName(), is("FHIRHelpers")); + // Verify that return expression contains complex logic from the modelinfo + assertThat(functionRef.getOperand().get(0), instanceOf(SingletonFrom.class)); + SingletonFrom sf = (SingletonFrom) functionRef.getOperand().get(0); + and1 = (And) ((Query) sf.getOperand()).getWhere(); + assertThat(and1.getOperand().get(0), instanceOf(Equal.class)); + assertThat(and1.getOperand().get(1), instanceOf(Equal.class)); + equal = (Equal) and1.getOperand().get(0); + assertThat(equal.getOperand().get(0), instanceOf(Property.class)); + property = (Property) equal.getOperand().get(0); + assertThat(property.getPath(), is("system")); + assertThat(equal.getOperand().get(1), instanceOf(Literal.class)); + Literal literal = (Literal) equal.getOperand().get(1); + assertThat(literal.getValue(), is("http://terminology.hl7.org/CodeSystem/observation-category")); + equal = (Equal) and1.getOperand().get(1); + assertThat(equal.getOperand().get(0), instanceOf(Property.class)); + property = (Property) equal.getOperand().get(0); + assertThat(property.getPath(), is("code")); + assertThat(equal.getOperand().get(1), instanceOf(Literal.class)); + literal = (Literal) equal.getOperand().get(1); + assertThat(literal.getValue(), is("vital-signs")); + } +} diff --git a/Src/java/cql-to-elm/src/test/resources/org/cqframework/cql/cql2elm/qicore/v600/TestQICore.cql b/Src/java/cql-to-elm/src/test/resources/org/cqframework/cql/cql2elm/qicore/v600/TestQICore.cql new file mode 100644 index 000000000..c7fdd8338 --- /dev/null +++ b/Src/java/cql-to-elm/src/test/resources/org/cqframework/cql/cql2elm/qicore/v600/TestQICore.cql @@ -0,0 +1,462 @@ +library TestQICore + +using QICore version '6.0.0' + +include FHIRHelpers version '4.0.1' + +codesystem "Marital Status Codes": 'http://terminology.hl7.org/CodeSystem/v3-MaritalStatus' +codesystem "CDC Race and Ethnicity Codes": 'urn:oid:2.16.840.1.113883.6.238' +codesystem "CommunicationCategoryCodeSystem": 'http://terminology.hl7.org/CodeSystem/communication-category' +codesystem "SNOMED-CT": 'http://snomed.info/sct' +codesystem "CVX": 'http://hl7.org/fhir/sid/cvx' +codesystem "LOINC": 'http://loinc.org' +codesystem "TaskCodeSystem": 'http://hl7.org/fhir/CodeSystem/task-code' + +valueset "Marital Status": 'http://hl7.org/fhir/ValueSet/marital-status' +valueset "CommunicationCodes": 'http://hl7.org/fhir/ValueSet/communication-category' +valueset "DeviceCodes": 'http://example.org/fhir/ValueSet/device-codes' // Random set of device codes from 'http://hl7.org/fhir/ValueSet/device-type' +valueset "ImmunizationCodes": 'http://example.org/fhir/ValueSet/immunization-codes' // Random set of immunization codes from 'http://hl7.org/fhir/us/core/ValueSet/us-core-vaccines-cvx' +valueset "MedicationCodes": 'http://example.org/fhir/ValueSet/medication-codes' // Random set of medication codes from 'http://hl7.org/fhir/ValueSet/medication-codes' +valueset "ObservationCodes": 'http://example.org/fhir/ValueSet/observation-codes' // Random set of observation codes from 'http://hl7.org/fhir/ValueSet/observation-codes' +valueset "ProcedureCodes": 'http://example.org/fhir/ValueSet/procedure-codes' // Random set of procedure codes from 'http://hl7.org/fhir/us/core/ValueSet/us-core-procedure-code' +valueset "TaskCodes": 'http://hl7.org/fhir/ValueSet/task-code' +valueset "NegationReasonCodes": 'http://hl7.org/fhir/us/qicore/ValueSet/qicore-negation-reason' + +code "Marital Status - Married": 'M' from "Marital Status Codes" +code "American Indian or Alaska Native": '1002-5' from "CDC Race and Ethnicity Codes" +code "Alaska Native": '1735-0' from "CDC Race and Ethnicity Codes" +code "CommunicationCode": 'alert' from "CommunicationCategoryCodeSystem" display 'Alert' +code "DeviceCode": '156009' from "SNOMED-CT" display 'Spine board' +code "ImmunizationCode": '01' from "CVX" display 'diphtheria, tetanus toxoids and pertussis vaccine' +code "MedicationCode": '26100' from "SNOMED-CT" display 'Codeine phosphate' +code "ObservationCode": '1-8' from "LOINC" display 'Acyclovir [Susceptibility]' +code "ProcedureCode": '7138802' from "SNOMED-CT" display 'Procedure' +code "TaskCode": 'approve' from "TaskCodeSystem" display 'Activate/approve the focal resource' + +context Patient + +define TestAdverseEvent: ["AdverseEvent"] +define TestAllergyIntolerance: ["AllergyIntolerance"] +define TestBodyStructure: ["BodyStructure"] +define TestCarePlan: ["CarePlan"] +define TestCareTeam: ["CareTeam"] +define TestClaim: ["Claim"] +define TestClaimResponse: ["ClaimResponse"] +define TestCommunication: ["Communication"] +define TestCommunicationNotDone: ["CommunicationNotDone"] +define TestCommunicationRequest: ["CommunicationRequest"] +define TestConditionEncounterDiagnosis: ["ConditionEncounterDiagnosis"] +define TestConditionProblemsHealthConcerns: ["ConditionProblemsHealthConcerns"] +define TestCoverage: ["Coverage"] +define TestDevice: ["Device"] +define TestUSCoreImplantableDevice: ["USCoreImplantableDeviceProfile"] +define TestDeviceNotRequested: ["DeviceNotRequested"] +define TestDeviceRequest: ["DeviceRequest"] +define TestDeviceUseStatement: ["DeviceUseStatement"] +define TestDiagnosticReportLab: ["DiagnosticReportLab"] +define TestDiagnosticReportNote: ["DiagnosticReportNote"] +define TestEncounter: ["Encounter"] +define TestFamilyMemberHistory: ["FamilyMemberHistory"] +define TestFlag: ["Flag"] +define TestGoal: ["Goal"] +define TestImagingStudy: ["ImagingStudy"] +define TestImmunization: ["Immunization"] +define TestImmunizationEvaluation: ["ImmunizationEvaluation"] +define TestImmunizationNotDone: ["ImmunizationNotDone"] +define TestImmunizationRecommendation: ["ImmunizationRecommendation"] +define TestLaboratoryResultObservation: ["LaboratoryResultObservation"] +define TestLocation: ["Location"] +define TestMedication: ["Medication"] +define TestMedicationAdministration: ["MedicationAdministration"] +define TestMedicationAdministrationNotDone: ["MedicationAdministrationNotDone"] +define TestMedicationDispense: ["MedicationDispense"] +define TestMedicationDispenseDeclined: ["MedicationDispenseDeclined"] +define TestMedicationNotRequested: ["MedicationNotRequested"] +define TestMedicationRequest: ["MedicationRequest"] +define TestMedicationStatement: ["MedicationStatement"] +define TestNutritionOrder: ["NutritionOrder"] +define TestSimpleObservation: ["SimpleObservation"] +define TestNonPatientObservation: ["NonPatientObservation"] +define TestObservationCancelled: ["ObservationCancelled"] +define TestObservationClinicalResult: ["ObservationClinicalResult"] +define TestObservationLaboratoryResult: ["LaboratoryResultObservation"] +define TestObservationScreeningAssessment: ["ObservationScreeningAssessment"] +define TestVitalSignsProfile: ["USCoreVitalSignsProfile"] +define TestBloodPressureProfile: ["USCoreBloodPressureProfile"] +define TestBMIProfile: ["USCoreBMIProfile"] +define TestBodyHeightProfile: ["USCoreBodyHeightProfile"] +define TestBodyTemperatureProfile: ["USCoreBodyTemperatureProfile"] +define TestBodyWeightProfile: ["USCoreBodyWeightProfile"] +define TestHeadCircumferenceProfile: ["USCoreHeadCircumferenceProfile"] +define TestHeartRateProfile: ["USCoreHeartRateProfile"] +define TestPediatricBMIForAge: ["USCorePediatricBMIforAgeObservationProfile"] +define TestPediatricHeadOccipitalFrontalCircumferencePercentileProfile: ["USCorePediatricHeadOccipitalFrontalCircumferencePercentileProfile"] +define TestPediatricWeightForHeight: ["USCorePediatricWeightForHeightObservationProfile"] +define TestPulseOximetryProfile: ["USCorePulseOximetryProfile"] +define TestRespiratoryRateProfile: ["USCoreRespiratoryRateProfile"] +define TestSmokingStatus: ["USCoreSmokingStatusProfile"] +define TestObservationOccupationProfile: ["USCoreObservationOccupationProfile"] +define TestObservationPregnancyIntentProfile: ["USCoreObservationPregnancyIntentProfile"] +define TestObservationPregnancyStatusProfile: ["USCoreObservationPregnancyStatusProfile"] +define TestObservationSexualOrientationProfile: ["USCoreObservationSexualOrientationProfile"] +define TestOrganization: ["Organization"] +define TestPatient: ["Patient"] +define TestPractitioner: ["Practitioner"] +define TestPractitionerRole: ["PractitionerRole"] +define TestProcedure: ["Procedure"] +define TestProcedureNotDone: ["ProcedureNotDone"] +define TestRelatedPerson: ["RelatedPerson"] +define TestServiceNotRequested: ["ServiceNotRequested"] +define TestServiceRequest: ["ServiceRequest"] +define TestSpecimen: ["USCoreSpecimenProfile"] +define TestSubstance: ["Substance"] +define TestTask: ["Task"] +define TestTaskRejected: ["TaskRejected"] + +define TestAge: + AgeInYears() + +define TestAgeAt: + AgeInYearsAt(@2022-10-14) + +define TestPrimitives: + Patient P + where P.gender = 'male' + and P.active is true + and P.birthDate before Today() + and P.maritalStatus in "Marital Status" + and P.maritalStatus ~ "Marital Status - Married" + +define TestChoice: + Patient P + where P.deceased is false + or P.deceased before Today() + +define TestSlices: + ["USCoreBloodPressureProfile"] BP + where BP.systolic.value < 140 'mm[Hg]' + and BP.diastolic.value < 90 'mm[Hg]' + +define TestSimpleExtensions: + Patient P + where P.birthsex = 'M' + +define TestComplexExtensions: + Patient P + where P.race.ombCategory contains "American Indian or Alaska Native" + and P.race.detailed contains "Alaska Native" + +// Validate Encounter.diagnosis cardinality +define TestEncounterDiagnosisCardinality: + exists (First([Encounter]).diagnosis) + +// Validate ProcedureNotDone elements +define TestProcedureNotDoneElements: + [ProcedureNotDone] P + where P.recorded on or before day of Today() + and exists (P.identifier) + and P.status = 'not-done' + and P.statusReason is not null + and P.category is not null + and P.code is not null + and P.performed is null + +// Validate NotDone... + +// CommunicationNotDone +define TestSpecificCommunicationNotDone: + ["CommunicationNotDone": CommunicationCode] + +// TODO: Support this case, need to introduce a terminology contains operator +//define TestSpecificCommunicationNotDoneActual: +// ["CommunicationNotDone": topic ~ CommunicationCode] +// union ["CommunicationNotDone": topic contains CommunicationCode] + +define TestSpecificCommunicationNotDoneExplicit: + ["CommunicationNotDone"] C + where C.topic ~ CommunicationCode + or CommunicationCode in C.topic + +// NOTE: Consider using topic rather than reasonCode as the negation focus? +//define TestSpecificCommunicationNotDoneExplicit: +// [Communication] C +// where (C.topic ~ CommunicationCode +// or CommunicationCode in ValueSet { id: C.topic.extension("http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-notDoneValueSet").value as String } +// ) +// and C.status = 'not-done' +// and C.recorded on or before day of Today() +// and C.statusReason in NegationReasonCodes + +define TestGeneralCommunicationNotDone: + ["CommunicationNotDone": CommunicationCodes] + +//define TestGeneralCommunicationNotDoneActual: +// ["CommunicationNotDone": topic in CommunicationCodes] +// union ["CommunicationNotDone": topic ~ CommunicationCodes] + +define TestGeneralCommunicationNotDoneExplicit: + ["CommunicationNotDone"] C + where C.topic in CommunicationCodes + or C.topic ~ CommunicationCodes + +//define TestGeneralCommunicationNotDoneExplicit: +// [Communication] C +// where (C.topic in CommunicationCodes +// or CommunicationCodes ~ ValueSet { id: C.topic.extension("http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-notDoneValueSet").value as String } +// ) +// and C.status = 'not-done' +// and C.recorded on or before day of Today() +// and C.statusReason in NegationReasonCodes + +// DeviceNotRequested +define TestSpecificDeviceNotRequested: + ["DeviceNotRequested": DeviceCode] + +// TODO: Support this use case +//define TestSpecificDeviceNotRequestedActual: +// ["DeviceNotRequested": code ~ DeviceCode] +// union ["DeviceNotRequested": code contains DeviceCode] + +define TestSpecificDeviceNotRequestedExplicit: + [DeviceNotRequested] D + where D.code ~ DeviceCode + or DeviceCode in D.code + +define TestGeneralDeviceNotRequested: + ["DeviceNotRequested": DeviceCodes] + +define TestGeneralDeviceNotRequestedCode: + ["DeviceNotRequested": code in DeviceCodes] + +define TestGeneralDeviceNotRequestedValueSet: + ["DeviceNotRequested": code ~ DeviceCodes] + +define TestGeneralDeviceNotRequestedActual: + ["DeviceNotRequested": code in DeviceCodes] + union ["DeviceNotRequested": code ~ DeviceCodes] + +define TestGeneralDeviceNotRequestedExplicit: + ["DeviceNotRequested"] D + where D.code in DeviceCodes + or D.code ~ DeviceCodes + +define TestGeneralDeviceNotRequestedCodeExplicit: + ["DeviceNotRequested"] D + where D.code in DeviceCodes + +define TestGeneralDeviceNotRequestedValueSetExplicit: + ["DeviceNotRequested"] D + where D.code ~ DeviceCodes + +// ImmunizationNotDone +define TestSpecificImmunizationNotDone: + ["ImmunizationNotDone": ImmunizationCode] + +// TODO: Support this use case +//define TestSpecificImmunizationNotDoneActual: +// ["ImmunizationNotDone": vaccineCode ~ ImmunizationCode] +// union ["ImmunizationNotDone": vaccineCode contains ImmunizationCode] + +define TestSpecificImmunizationNotDoneExplicit: + ["ImmunizationNotDone"] I + where I.vaccineCode ~ ImmunizationCode + or ImmunizationCode in I.vaccineCode + +define TestGeneralImmunizationNotDone: + ["ImmunizationNotDone": ImmunizationCodes] + +define TestGeneralImmunizationNotDoneActual: + ["ImmunizationNotDone": vaccineCode in ImmunizationCodes] + union ["ImmunizationNotDone": vaccineCode ~ ImmunizationCodes] + +define TestGeneralImmunizationNotDoneExplicit: + ["ImmunizationNotDone"] I + where I.vaccineCode in ImmunizationCodes + or I.vaccineCode ~ ImmunizationCodes + +// MedicationAdministrationNotDone +define TestSpecificMedicationAdministrationNotDone: + ["MedicationAdministrationNotDone": MedicationCode] + +// TODO: Support this use case +//define TestSpecificMedicationAdministrationNotDoneActual: +// ["MedicationAdministrationNotDone": medication ~ MedicationCode] +// union ["MedicationAdministrationNotDone": medication contains MedicationCode] + +define TestSpecificMedicationAdministrationNotDoneExplicit: + ["MedicationAdministrationNotDone"] I + where I.medication ~ MedicationCode + or MedicationCode in I.medication + +define TestGeneralMedicationAdministrationNotDone: + ["MedicationAdministrationNotDone": MedicationCodes] + +define TestGeneralMedicationAdministrationNotDoneActual: + ["MedicationAdministrationNotDone": medication in MedicationCodes] + union ["MedicationAdministrationNotDone": medication ~ MedicationCodes] + +define TestGeneralMedicationAdministrationNotDoneExplicit: + ["MedicationAdministrationNotDone"] I + where I.medication in MedicationCodes + or I.medication ~ MedicationCodes + +// MedicationDispenseDeclined +define TestSpecificMedicationDispenseDeclined: + ["MedicationDispenseDeclined": MedicationCode] + +// TODO: Support this use case +//define TestSpecificMedicationDispenseDeclinedActual: +// ["MedicationDispenseDeclined": medication ~ MedicationCode] +// union ["MedicationDispenseDeclined": medication contains MedicationCode] + +define TestSpecificMedicationDispenseDeclinedExplicit: + ["MedicationDispenseDeclined"] I + where I.medication ~ MedicationCode + or MedicationCode in I.medication + +define TestGeneralMedicationDispenseDeclined: + ["MedicationDispenseDeclined": MedicationCodes] + +define TestGeneralMedicationDispenseDeclinedActual: + ["MedicationDispenseDeclined": medication in MedicationCodes] + union ["MedicationDispenseDeclined": medication ~ MedicationCodes] + +/* +There is an issue with the QICoreMedicationDispenseDeclined profile in that it allows for Reference, instead of just the CodeableConcept, +not sure why, that is inconsistent with the other patterns for negation for medication profiles. Discussing with QICore project team, +but until then, this usage does not translate +define TestGeneralMedicationDispenseDeclinedExplicit: + ["MedicationDispenseDeclined"] I + where I.medication in MedicationCodes + or I.medication ~ MedicationCodes +*/ + +// MedicationNotRequested +define TestSpecificMedicationNotRequested: + ["MedicationNotRequested": MedicationCode] + +// TODO: Support this use case +//define TestSpecificMedicationNotRequestedActual: +// ["MedicationNotRequested": medication ~ MedicationCode] +// union ["MedicationNotRequested": medication contains MedicationCode] + +define TestSpecificMedicationNotRequestedExplicit: + ["MedicationNotRequested"] I + where I.medication ~ MedicationCode + or MedicationCode in I.medication + +define TestGeneralMedicationNotRequested: + ["MedicationNotRequested": MedicationCodes] + +define TestGeneralMedicationNotRequestedActual: + ["MedicationNotRequested": medication in MedicationCodes] + union ["MedicationNotRequested": medication ~ MedicationCodes] + +define TestGeneralMedicationNotRequestedExplicit: + ["MedicationNotRequested"] I + where I.medication in MedicationCodes + or I.medication ~ MedicationCodes + +// ObservationCancelled +define TestSpecificObservationCancelled: + ["ObservationCancelled": ObservationCode] + +// TODO: Support this use case +//define TestSpecificObservationCancelledActual: +// ["ObservationCancelled": code ~ ObservationCode] +// union ["ObservationCancelled": code contains ObservationCode] + +define TestSpecificObservationCancelledExplicit: + ["ObservationCancelled"] I + where I.code ~ ObservationCode + or ObservationCode in I.code + +define TestGeneralObservationCancelled: + ["ObservationCancelled": ObservationCodes] + +define TestGeneralObservationCancelledActual: + ["ObservationCancelled": code in ObservationCodes] + union ["ObservationCancelled": code ~ ObservationCodes] + +define TestGeneralObservationCancelledExplicit: + ["ObservationCancelled"] I + where I.code in ObservationCodes + or I.code ~ ObservationCodes + +// ProcedureNotDone +define TestSpecificProcedureNotDone: + ["ProcedureNotDone": ProcedureCode] + +// TODO: Support this use case +//define TestSpecificProcedureNotDoneActual: +// ["ProcedureNotDone": code ~ ProcedureCode] +// union ["ProcedureNotDone": code contains ProcedureCode] + +define TestSpecificProcedureNotDoneExplicit: + ["ProcedureNotDone"] I + where I.code ~ ProcedureCode + or ProcedureCode in I.code + +define TestGeneralProcedureNotDone: + ["ProcedureNotDone": ProcedureCodes] + +define TestGeneralProcedureNotDoneActual: + ["ProcedureNotDone": code in ProcedureCodes] + union ["ProcedureNotDone": code ~ ProcedureCodes] + +define TestGeneralProcedureNotDoneExplicit: + ["ProcedureNotDone"] I + where I.code in ProcedureCodes + or I.code ~ ProcedureCodes + +// ServiceNotRequested +define TestSpecificServiceNotRequested: + ["ServiceNotRequested": ProcedureCode] + +// TODO: Support this use case +//define TestSpecificServiceNotRequestedActual: +// ["ServiceNotRequested": code ~ ProcedureCode] +// union ["ServiceNotRequested": code contains ProcedureCode] + +define TestSpecificServiceNotRequestedExplicit: + ["ServiceNotRequested"] I + where I.code ~ ProcedureCode + or ProcedureCode in I.code + +define TestGeneralServiceNotRequested: + ["ServiceNotRequested": ProcedureCodes] + +define TestGeneralServiceNotRequestedActual: + ["ServiceNotRequested": code in ProcedureCodes] + union ["ServiceNotRequested": code ~ ProcedureCodes] + +define TestGeneralServiceNotRequestedExplicit: + ["ServiceNotRequested"] I + where I.code in ProcedureCodes + or I.code ~ ProcedureCodes + +// TaskRejected +define TestSpecificTaskRejected: + ["TaskRejected": TaskCode] + +// TODO: Support this use case +//define TestSpecificTaskRejectedActual: +// ["TaskRejected": code ~ TaskCode] +// union ["TaskRejected": code contains TaskCode] + +define TestSpecificTaskNotDoneExplicit: + ["TaskRejected"] I + where I.code ~ TaskCode + or TaskCode in I.code + +define TestGeneralTaskRejected: + ["TaskRejected": TaskCodes] + +define TestGeneralTaskRejectedActual: + ["TaskRejected": code in TaskCodes] + union ["TaskRejected": code ~ TaskCodes] + +define TestGeneralTaskRejectedExplicit: + ["TaskRejected"] I + where I.code in TaskCodes + or I.code ~ TaskCodes diff --git a/Src/java/cql-to-elm/src/test/resources/org/cqframework/cql/cql2elm/uscore/v610/TestUSCore.cql b/Src/java/cql-to-elm/src/test/resources/org/cqframework/cql/cql2elm/uscore/v610/TestUSCore.cql new file mode 100644 index 000000000..bb29e83f1 --- /dev/null +++ b/Src/java/cql-to-elm/src/test/resources/org/cqframework/cql/cql2elm/uscore/v610/TestUSCore.cql @@ -0,0 +1,103 @@ +library TestUSCore + +using USCore version '6.1.0' + +include FHIRHelpers version '4.0.1' + +codesystem "Marital Status Codes": 'http://terminology.hl7.org/CodeSystem/v3-MaritalStatus' +codesystem "CDC Race and Ethnicity Codes": 'urn:oid:2.16.840.1.113883.6.238' + +valueset "Marital Status": 'http://hl7.org/fhir/ValueSet/marital-status' + +code "Marital Status - Married": 'M' from "Marital Status Codes" +code "American Indian or Alaska Native": '1002-5' from "CDC Race and Ethnicity Codes" +code "Alaska Native": '1735-0' from "CDC Race and Ethnicity Codes" + +context Patient + +define TestAllergyIntolerance: ["AllergyIntolerance"] +define TestCarePlan: ["CarePlanProfile"] +define TestCareTeam: ["CareTeam"] +define TestConditionEncounterDiagnosisProfile: ["ConditionEncounterDiagnosisProfile"] +define TestConditionProblemsHealthConcernsProfile: ["ConditionProblemsHealthConcernsProfile"] +define TestCoverage: ["CoverageProfile"] +define TestImplantableDevice: ["ImplantableDeviceProfile"] +define TestDiagnosticReport: ["DiagnosticReportProfileLaboratoryReporting"] +define TestDiagnosticReportNote: ["DiagnosticReportProfileNoteExchange"] +define TestDocumentReference: ["DocumentReferenceProfile"] +define TestEncounter: ["EncounterProfile"] +define TestGoal: ["GoalProfile"] +define TestImmunization: ["ImmunizationProfile"] +define TestLocation: ["Location"] +define TestMedication: ["MedicationProfile"] +define TestMedicationDispense: ["MedicationDispenseProfile"] +define TestMedicationRequest: ["MedicationRequestProfile"] +define TestObservationClinicalResultProfile: ["ObservationClinicalResultProfile"] +define TestLaboratoryResultObservationProfile: ["LaboratoryResultObservationProfile"] +define TestObservationOccupationProfile: ["ObservationOccupationProfile"] +define TestObservationPregnancyIntentProfile: ["ObservationPregnancyIntentProfile"] +define TestObservationPregnancyStatusProfile: ["ObservationPregnancyStatusProfile"] +define TestObservationScreeningAssessmentProfile: ["ObservationScreeningAssessmentProfile"] +define TestObservationSexualOrientationProfile: ["ObservationSexualOrientationProfile"] +define TestSimpleObservationProfile: ["SimpleObservationProfile"] +define TestSmokingStatus: ["SmokingStatusProfile"] +define TestVitalSignsProfile: ["VitalSignsProfile"] +define TestPediatricHeadOccipitalFrontalCircumferencePercentileProfile: ["PediatricHeadOccipitalFrontalCircumferencePercentileProfile"] +define TestPediatricBMIForAge: ["PediatricBMIforAgeObservationProfile"] +define TestPediatricWeightForHeight: ["PediatricWeightForHeightObservationProfile"] +define TestBloodPressureProfile: ["BloodPressureProfile"] +define TestBMIProfile: ["BMIProfile"] +define TestBodyHeightProfile: ["BodyHeightProfile"] +define TestBodyTemperatureProfile: ["BodyTemperatureProfile"] +define TestBodyWeightProfile: ["BodyWeightProfile"] +define TestHeadCircumferenceProfile: ["HeadCircumferenceProfile"] +define TestHeartRateProfile: ["HeartRateProfile"] +define TestPulseOximetryProfile: ["PulseOximetryProfile"] +define TestRespiratoryRateProfile: ["RespiratoryRateProfile"] +define TestOrganization: ["OrganizationProfile"] +define TestPatient: ["PatientProfile"] +define TestPractitioner: ["PractitionerProfile"] +define TestPractitionerRole: ["PractitionerRoleProfile"] +define TestProcedure: ["ProcedureProfile"] +define TestProvenance: ["Provenance"] +define TestQuestionnaireResponseProfile: ["QuestionnaireResponseProfile"] +define TestRelatedPersonProfile: ["RelatedPersonProfile"] +define TestServiceRequestProfile: ["ServiceRequestProfile"] +define TestSpecimenProfile: ["SpecimenProfile"] + +define TestPrimitives: + Patient P + where P.gender = 'male' + and P.active is true + and P.birthDate before Today() + and P.maritalStatus in "Marital Status" + and P.maritalStatus ~ "Marital Status - Married" + +define TestPluralPrimitive: + Patient.name.given[0] + +define TestSpecificPluralPrimitive: + Patient.name[0].given[0] + +define TestChoice: + Patient P + where P.deceased is false + or P.deceased before Today() + +define TestSlices: + ["BloodPressureProfile"] BP + where BP.systolic.value < 140 'mm[Hg]' + and BP.diastolic.value < 90 'mm[Hg]' + +define TestSimpleExtensions: + Patient P + where P.birthsex = 'M' + +define TestComplexExtensions: + Patient P + where P.race.ombCategory contains "American Indian or Alaska Native" + and P.race.detailed contains "Alaska Native" + +define TestComplexFHIRHelpers: + ["PediatricBMIforAgeObservationProfile"] PB + return PB.VSCat \ No newline at end of file diff --git a/Src/java/quick/src/main/java/org/cqframework/cql/cql2elm/quick/QICoreModelInfoProvider.java b/Src/java/quick/src/main/java/org/cqframework/cql/cql2elm/quick/QICoreModelInfoProvider.java index 606daf2af..2a84a9615 100644 --- a/Src/java/quick/src/main/java/org/cqframework/cql/cql2elm/quick/QICoreModelInfoProvider.java +++ b/Src/java/quick/src/main/java/org/cqframework/cql/cql2elm/quick/QICoreModelInfoProvider.java @@ -42,10 +42,14 @@ public ModelInfo load(ModelIdentifier modelIdentifier) { .read(QICoreModelInfoProvider.class.getResourceAsStream( "/org/hl7/fhir/qicore-modelinfo-4.1.1.xml")); case "5.0.0": - default: return ModelInfoReaderFactory.getReader("application/xml") .read(QICoreModelInfoProvider.class.getResourceAsStream( "/org/hl7/fhir/qicore-modelinfo-5.0.0.xml")); + case "6.0.0": + default: + return ModelInfoReaderFactory.getReader("application/xml") + .read(QICoreModelInfoProvider.class.getResourceAsStream( + "/org/hl7/fhir/qicore-modelinfo-6.0.0.xml")); } } catch (IOException e) { // Do not throw, allow other providers to resolve diff --git a/Src/java/quick/src/main/java/org/cqframework/cql/cql2elm/quick/UsCoreModelInfoProvider.java b/Src/java/quick/src/main/java/org/cqframework/cql/cql2elm/quick/UsCoreModelInfoProvider.java index 4701a50cd..f3f6fb1bc 100644 --- a/Src/java/quick/src/main/java/org/cqframework/cql/cql2elm/quick/UsCoreModelInfoProvider.java +++ b/Src/java/quick/src/main/java/org/cqframework/cql/cql2elm/quick/UsCoreModelInfoProvider.java @@ -35,10 +35,14 @@ public ModelInfo load(ModelIdentifier modelIdentifier) { .read(QuickModelInfoProvider.class.getResourceAsStream( "/org/hl7/fhir/uscore-modelinfo-3.1.0.xml")); case "3.1.1": - default: return ModelInfoReaderFactory.getReader("application/xml") .read(QuickModelInfoProvider.class.getResourceAsStream( "/org/hl7/fhir/uscore-modelinfo-3.1.1.xml")); + case "6.1.0": + default: + return ModelInfoReaderFactory.getReader("application/xml") + .read(QuickModelInfoProvider.class.getResourceAsStream( + "/org/hl7/fhir/uscore-modelinfo-6.1.0.xml")); } } catch (IOException e) { // Do not throw, allow other providers to resolve diff --git a/Src/java/quick/src/main/resources/org/hl7/fhir/qicore-modelinfo-6.0.0.xml b/Src/java/quick/src/main/resources/org/hl7/fhir/qicore-modelinfo-6.0.0.xml new file mode 100644 index 000000000..35d7c63e9 --- /dev/null +++ b/Src/java/quick/src/main/resources/org/hl7/fhir/qicore-modelinfo-6.0.0.xml @@ -0,0 +1,7588 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Src/java/quick/src/main/resources/org/hl7/fhir/uscore-modelinfo-6.1.0.xml b/Src/java/quick/src/main/resources/org/hl7/fhir/uscore-modelinfo-6.1.0.xml new file mode 100644 index 000000000..b5a49b8b1 --- /dev/null +++ b/Src/java/quick/src/main/resources/org/hl7/fhir/uscore-modelinfo-6.1.0.xml @@ -0,0 +1,3736 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +