Clinical Practice Guidelines, published by HL7 International - Clinical Decision Support WG. This is not an authorized publication; it is the continuous build for version 1.0.0). This version is based on the current content of https://github.com/HL7/cqf-recommendations/ and changes regularly. See the Directory of published versions
Active as of 2018-03-25 |
<Library xmlns="http://hl7.org/fhir">
<id value="OpioidCDSR4Common"/>
<text>
<status value="generated"/>
<div xmlns="http://www.w3.org/1999/xhtml"><h2>Participants</h2><table class="grid"><tr><td>Author</td><td>Kensaku Kawamoto, MD, PhD, MHS</td></tr><tr><td>Author</td><td>Bryn Rhodes</td></tr><tr><td>Author</td><td>Floyd Eisenberg, MD, MPH</td></tr><tr><td>Author</td><td>Robert McClure, MD, MPH</td></tr></table><h2>Related Artifacts</h2><table class="grid"><tr><td>documentation</td><td>CDC guideline for prescribing opioids for chronic pain</td><td>https://www.cdc.gov/mmwr/volumes/65/rr/rr6501e1.htm?CDC_AA_refVal=https%3A%2F%2Fwww.cdc.gov%2Fmmwr%2Fvolumes%2F65%2Frr%2Frr6501e1er.htm</td></tr></table><h2>Contents</h2><p><code>text/cql</code></p><pre><code class="language-sql">library OpioidCDSR4Common version '0.1.0'
using FHIR version '4.0.0'
include FHIRHelpers version '4.0.0' called FHIRHelpers
include OMTKLogic version '0.0.0' called OMTKLogic
codesystem "SNOMED": 'http://snomed.info/sct'
codesystem "Medication Request Category Codes": 'http://terminology.hl7.org/CodeSystem/medicationrequest-category'
valueset "Active Condition": 'http://hl7.org/fhir/uv/cpg/ValueSet/cpg-active-condition'
valueset "Benzodiazepines": 'http://fhir.org/guides/cdc/opioid-cds/ValueSet/benzodiazepines'
// TODO: Fix this name
valueset "End of Life Conditions": 'http://fhir.org/guides/cdc/opioid-cds/ValueSet/end-of-life-conditions'
// Harvested from VSAC - OID: 2.16.840.1.113762.1.4.1108.15
// NOTE: This harvest note is incorrect, none of the following 3 value sets contain any of the codes in the above referenced valueset
// Rob will construct an appropriate hospice value set aligned with current eCQM program usage and we will use that when available
valueset "Hospice Disposition": 'http://fhir.org/guides/cdc/opioid-cds/ValueSet/hospice-disposition'
valueset "Hospice Finding Codes": 'http://fhir.org/guides/cdc/opioid-cds/ValueSet/hospice-finding'
valueset "Hospice Procedure Codes": 'http://fhir.org/guides/cdc/opioid-cds/ValueSet/hospice-procedure'
valueset "Illicit Drug Screening": 'http://fhir.org/guides/cdc/opioid-cds/ValueSet/illicit-drug-urine-screening'
// Harvested from VSAC - OID: 2.16.840.1.113883.3.526.3.1259
valueset "Limited Life Expectancy Conditions": 'http://fhir.org/guides/cdc/opioid-cds/ValueSet/limited-life-expectancy-conditions'
valueset "Long Acting Opioids": 'http://fhir.org/guides/cdc/opioid-cds/ValueSet/long-acting-opioids'
valueset "Naloxone": 'http://fhir.org/guides/cdc/opioid-cds/ValueSet/naloxone'
valueset "Risk Assessment": 'http://fhir.org/guides/cdc/opioid-cds/ValueSet/opioid-abuse-assessment'
valueset "Opioid Drug Screening": 'http://fhir.org/guides/cdc/opioid-cds/ValueSet/opioid-urine-screening'
valueset "Ambulatory Abuse Potential Opioids": 'http://fhir.org/guides/cdc/opioid-cds/ValueSet/opioids-abused-in-ambulatory-care'
valueset "Substance Abuse": 'http://fhir.org/guides/cdc/opioid-cds/ValueSet/substance-abuse'
// TODO: Turn this into a valueset
code "Referral to Hospice": '306205009' from "SNOMED"
// TODO: Turn this into a valueset
code "Outpatient": 'outpatient' from "Medication Request Category Codes"
// TODO: Capture process decisions for long-term opioid use
define IsForChronicPain: true
define "Active Ambulatory Opioid Rx":
[MedicationRequest: "Ambulatory Abuse Potential Opioids"] Rx
where Rx.status = 'active'
and ToCodes(Rx.category.coding) contains "Outpatient"
define "Active Ambulatory Benzodiazepine Rx":
[MedicationRequest: "Benzodiazepines"] Rx
where Rx.status = 'active'
and ToCodes(Rx.category.coding) contains "Outpatient"
define "Active Ambulatory Naloxone Rx":
[MedicationRequest: "Naloxone"] Rx
where Rx.status = 'active'
and ToCodes(Rx.category.coding) contains "Outpatient"
define "Ambulatory Opioid Rx":
[MedicationRequest: "Ambulatory Abuse Potential Opioids"] Rx
where ToCodes(Rx.category.coding) contains "Outpatient"
define "End of Life Assessment":
// 1. Conditions indicating end of life or with limited life expectancy
exists (
(
[Condition: "End of Life Conditions"] C
where C.clinicalStatus in "Active Condition"
)
union
(
[Condition: code in "Limited Life Expectancy Conditions"] C
where C.clinicalStatus in "Active Condition"
)
)
// 2. Admitted/referred/discharged to hospice care
or exists (
(
[ServiceRequest: code in "Referral to Hospice"] RR
where RR.status in { 'active', 'completed' }
)
union
(
[ServiceRequest: code in "Hospice Procedure Codes"] P
where P.status in { 'in-progress', 'completed' }
)
union
(
[ServiceRequest: code in "Hospice Procedure Codes"] E
where E.status in { 'planned', 'arrived', 'in-progress', 'finished', 'onleave' }
)
union
(
[Observation: code in "Hospice Finding Codes"] O
where not (O.status in { 'unknown', 'entered-in-error', 'cancelled' })
)
union
(
[Encounter] E
where
(
if E.hospitalization.dischargeDisposition.coding is null
or not exists (E.hospitalization.dischargeDisposition.coding)
then false
else E.hospitalization.dischargeDisposition in "Hospice Disposition"
)
and E.status in { 'planned', 'arrived', 'in-progress', 'finished', 'onleave' }
)
)
define function Prescriptions(Orders List<MedicationRequest>):
Orders O
let
// NOTE: Assuming medication is specified as a CodeableConcept with a single RxNorm code
rxNormCode: ToCode(O.medication.coding[0]),
medicationName: OMTKLogic.GetMedicationName(rxNormCode),
// NOTE: Assuming a single dosage instruction element
dosageInstruction: O.dosageInstruction[0],
repeat: dosageInstruction.timing.repeat,
frequency: Coalesce(repeat.frequencyMax.value, repeat.frequency.value),
period: System.Quantity { value: repeat.period.value, unit: repeat.periodUnit.value },
doseDescription:
Coalesce(
// There should be a conversion from FHIR.SimpleQuantity to System.Quantity
if dosageInstruction.doseAndRate[0].dose is FHIR.Range
then ToString(ToQuantity(dosageInstruction.doseAndRate[0].dose.low))
+ '-' + ToString(ToQuantity(dosageInstruction.doseAndRate[0].dose.high))
+ dosageInstruction.doseAndRate[0].dose.high.unit.value
else ToString(ToQuantity(dosageInstruction.doseAndRate[0].dose)),
''
),
frequencyDescription:
ToString(dosageInstruction.timing.repeat.frequency.value) +
Coalesce(
'-' + ToString(dosageInstruction.timing.repeat.frequencyMax.value),
''
)
return {
rxNormCode: rxNormCode,
isDraft: O.status.value = 'draft',
// NOTE: Assuming asNeeded is expressed as a boolean
isPRN: dosageInstruction.asNeeded.value,
prescription:
if dosageInstruction.text is not null then
medicationName + ' ' + dosageInstruction.text.value
else
// TODO: Shouldn't need the .value here on asNeededBoolean
medicationName + ' ' + doseDescription + ' q' + frequencyDescription + (if dosageInstruction.asNeeded.value then ' PRN' else ''),
// TODO: Shouldn't need the ToQuantity here...
dose: if dosageInstruction.doseAndRate[0].dose is FHIR.Range
then ToQuantity(dosageInstruction.doseAndRate[0].dose.high)
else ToQuantity(dosageInstruction.doseAndRate[0].dose),
dosesPerDay: Coalesce(OMTKLogic.ToDaily(frequency, period), 1.0)
}
define function MME(prescriptions List<MedicationRequest>):
(Prescriptions(prescriptions)) P
let mme: SingletonFrom(OMTKLogic.CalculateMMEs({ { rxNormCode: P.rxNormCode, doseQuantity: P.dose, dosesPerDay: P.dosesPerDay } }))
return {
rxNormCode: P.rxNormCode,
isDraft: P.isDraft,
isPRN: P.isPRN,
prescription: P.prescription,
dailyDose: mme.dailyDoseDescription,
conversionFactor: mme.conversionFactor,
mme: mme.mme
}
define function TotalMME(prescriptions List<MedicationRequest>):
System.Quantity {
value: Sum((MME(prescriptions)) M return M.mme.value),
unit: 'mg/d'
}
define function ProbableDaysInRange(Orders List<MedicationRequest>, daysPast Integer, numDaysInDaysPast Integer):
Orders orders
let
frequency: orders.dosageInstruction[0].timing.repeat.frequency.value,
period: orders.dosageInstruction[0].timing.repeat.period.value,
periodDays: GetPeriodDays(orders.dosageInstruction[0].timing.repeat.periodUnit.value),
dosesPerDay:
if (frequency / (period * periodDays)) >= 1.0
then 1.0
else frequency / (period * periodDays),
repeat: orders.dispenseRequest.numberOfRepeatsAllowed.value,
supplyDuration: GetDurationInDays(orders.dispenseRequest.expectedSupplyDuration),
validityPeriod: days between orders.dispenseRequest.validityPeriod."start".value and Today(),
endDifference:
if orders.dispenseRequest.validityPeriod."end".value < Today()
then days between orders.dispenseRequest.validityPeriod."end".value and Today()
else 0
return
if (repeat * supplyDuration) < numDaysInDaysPast then false
else
(dosesPerDay * ((repeat * supplyDuration) / validityPeriod) * (daysPast - endDifference)) >= numDaysInDaysPast
define function GetPeriodDays(value System.String):
case
when value = 'a' then 365.0
when value = 'mo' then 30.0
when value = 'h' then 1.0/24.0
when value = 'min' then 1.0/24.0*60.0
when value = 's' then 1.0/24.0*60.0*60.0
when value = 'ms' then 1.0/24.0*60.0*60.0*1000.0
else 1.0
end
define function GetDurationInDays(value FHIR.Duration):
case
when StartsWith(value.unit.value, 'a') then value.value.value * 365.0
when StartsWith(value.unit.value, 'mo') then value.value.value * 30.0
when StartsWith(value.unit.value, 'wk') then value.value.value * 7.0
when StartsWith(value.unit.value, 'd') then value.value.value
when StartsWith(value.unit.value, 'h') then value.value.value / 24.0
when StartsWith(value.unit.value, 'min') then value.value.value / 60.0 / 24.0
when StartsWith(value.unit.value, 's') then value.value.value / 60.0 / 60.0 / 24.0
when StartsWith(value.unit.value, 'ms') then value.value.value / 60.0 / 60.0 / 24.0 / 1000.0
else Message(1000, true, 'Undefined', 'Error', 'Unsupported duration unit')
end
define function GetIngredient(rxNormCode Code):
OMTKLogic.GetIngredients(rxNormCode).ingredientName
define function GetIngredients(rxNormCodes List<Code>):
rxNormCodes rnc return GetIngredient(rnc)
define function GetMedicationNames(medications List<MedicationRequest>):
medications M
return OMTKLogic.GetIngredients(ToRxNormCode(M.medication.coding)).rxNormCode.display
/*
* Conversion Functions
*/
define function ToCode(coding FHIR.Coding):
System.Code {
code: coding.code.value,
system: coding.system.value,
version: coding.version.value,
display: coding.display.value
}
define function ToCodes(coding List<FHIR.Coding>):
coding c return ToCode(c)
define function ToRxNormCode(coding List<FHIR.Coding>):
singleton from (
coding C where C.system = 'http://www.nlm.nih.gov/research/umls/rxnorm'
)
define function ToQuantity(quantity FHIR.Quantity):
System.Quantity { value: quantity.value.value, unit: quantity.unit.value }
</code></pre><p><code>No Content</code> (<code>application/elm+xml</code>)</p></div>
</text>
<url
value="http://fhir.org/guides/cdc/opioid-cds/Library/OpioidCDSR4Common"/>
<version value="1.0.0"/>
<name value="OpioidCDSR4Common"/>
<title value="Opioid CDS R4 Common Logic"/>
<status value="active"/>
<experimental value="true"/>
<type>
<coding>
<system value="http://terminology.hl7.org/CodeSystem/library-type"/>
<code value="logic-library"/>
<display value="Logic Library"/>
</coding>
</type>
<date value="2018-03-25T13:49:09-06:00"/>
<publisher value="HL7 International - Clinical Decision Support WG"/>
<contact>
<name value="HL7 International - Clinical Decision Support WG"/>
<telecom>
<system value="url"/>
<value value="http://www.hl7.org/Special/committees/dss/index.cfm"/>
</telecom>
</contact>
<description
value="Common Opioid Decision Support Logic for use in implementing CDC Opioid Prescribing Guidelines."/>
<useContext>
<code>
<system
value="http://terminology.hl7.org/CodeSystem/usage-context-type"/>
<code value="focus"/>
<display value="Clinical Focus"/>
</code>
<valueCodeableConcept>
<coding>
<system value="http://snomed.info/sct"/>
<code value="182888003"/>
<display value="Medication requested (situation)"/>
</coding>
</valueCodeableConcept>
</useContext>
<useContext>
<code>
<system
value="http://terminology.hl7.org/CodeSystem/usage-context-type"/>
<code value="focus"/>
<display value="Clinical Focus"/>
</code>
<valueCodeableConcept>
<coding>
<system value="http://snomed.info/sct"/>
<code value="82423001"/>
<display value="Chronic pain (finding)"/>
</coding>
</valueCodeableConcept>
</useContext>
<jurisdiction>
<coding>
<system value="http://unstats.un.org/unsd/methods/m49/m49.htm"/>
<code value="001"/>
<display value="World"/>
</coding>
</jurisdiction>
<purpose
value="This library contains common logic across recommendations including MME calculations, conversions, and looking up codes in valuesets."/>
<usage
value="This library is used for decision support for opioid guideline recommendations when applying PlanDefinitions."/>
<copyright value="© CDC 2016+."/>
<topic>
<text value="Opioid Prescribing"/>
</topic>
<author>
<name value="Kensaku Kawamoto, MD, PhD, MHS"/>
</author>
<author>
<name value="Bryn Rhodes"/>
</author>
<author>
<name value="Floyd Eisenberg, MD, MPH"/>
</author>
<author>
<name value="Robert McClure, MD, MPH"/>
</author>
<relatedArtifact>
<type value="documentation"/>
<display value="CDC guideline for prescribing opioids for chronic pain"/>
<url
value="https://www.cdc.gov/mmwr/volumes/65/rr/rr6501e1.htm?CDC_AA_refVal=https%3A%2F%2Fwww.cdc.gov%2Fmmwr%2Fvolumes%2F65%2Frr%2Frr6501e1er.htm"/>
<document>
<url
value="https://www.cdc.gov/mmwr/volumes/65/rr/rr6501e1.htm?CDC_AA_refVal=https%3A%2F%2Fwww.cdc.gov%2Fmmwr%2Fvolumes%2F65%2Frr%2Frr6501e1er.htm"/>
</document>
</relatedArtifact>
<content>
<contentType value="text/cql"/>
<data
value="bGlicmFyeSBPcGlvaWRDRFNSNENvbW1vbiB2ZXJzaW9uICcwLjEuMCcKCnVzaW5nIEZISVIgdmVyc2lvbiAnNC4wLjAnCgppbmNsdWRlIEZISVJIZWxwZXJzIHZlcnNpb24gJzQuMC4wJyBjYWxsZWQgRkhJUkhlbHBlcnMKaW5jbHVkZSBPTVRLTG9naWMgdmVyc2lvbiAnMC4wLjAnIGNhbGxlZCBPTVRLTG9naWMKCmNvZGVzeXN0ZW0gIlNOT01FRCI6ICdodHRwOi8vc25vbWVkLmluZm8vc2N0Jwpjb2Rlc3lzdGVtICJNZWRpY2F0aW9uIFJlcXVlc3QgQ2F0ZWdvcnkgQ29kZXMiOiAnaHR0cDovL3Rlcm1pbm9sb2d5LmhsNy5vcmcvQ29kZVN5c3RlbS9tZWRpY2F0aW9ucmVxdWVzdC1jYXRlZ29yeScKCnZhbHVlc2V0ICJBY3RpdmUgQ29uZGl0aW9uIjogJ2h0dHA6Ly9obDcub3JnL2ZoaXIvdXYvY3BnL1ZhbHVlU2V0L2NwZy1hY3RpdmUtY29uZGl0aW9uJwp2YWx1ZXNldCAiQmVuem9kaWF6ZXBpbmVzIjogJ2h0dHA6Ly9maGlyLm9yZy9ndWlkZXMvY2RjL29waW9pZC1jZHMvVmFsdWVTZXQvYmVuem9kaWF6ZXBpbmVzJwovLyBUT0RPOiBGaXggdGhpcyBuYW1lCnZhbHVlc2V0ICJFbmQgb2YgTGlmZSBDb25kaXRpb25zIjogJ2h0dHA6Ly9maGlyLm9yZy9ndWlkZXMvY2RjL29waW9pZC1jZHMvVmFsdWVTZXQvZW5kLW9mLWxpZmUtY29uZGl0aW9ucycKLy8gSGFydmVzdGVkIGZyb20gVlNBQyAtIE9JRDogMi4xNi44NDAuMS4xMTM3NjIuMS40LjExMDguMTUKLy8gTk9URTogVGhpcyBoYXJ2ZXN0IG5vdGUgaXMgaW5jb3JyZWN0LCBub25lIG9mIHRoZSBmb2xsb3dpbmcgMyB2YWx1ZSBzZXRzIGNvbnRhaW4gYW55IG9mIHRoZSBjb2RlcyBpbiB0aGUgYWJvdmUgcmVmZXJlbmNlZCB2YWx1ZXNldAovLyBSb2Igd2lsbCBjb25zdHJ1Y3QgYW4gYXBwcm9wcmlhdGUgaG9zcGljZSB2YWx1ZSBzZXQgYWxpZ25lZCB3aXRoIGN1cnJlbnQgZUNRTSBwcm9ncmFtIHVzYWdlIGFuZCB3ZSB3aWxsIHVzZSB0aGF0IHdoZW4gYXZhaWxhYmxlCnZhbHVlc2V0ICJIb3NwaWNlIERpc3Bvc2l0aW9uIjogJ2h0dHA6Ly9maGlyLm9yZy9ndWlkZXMvY2RjL29waW9pZC1jZHMvVmFsdWVTZXQvaG9zcGljZS1kaXNwb3NpdGlvbicKdmFsdWVzZXQgIkhvc3BpY2UgRmluZGluZyBDb2RlcyI6ICdodHRwOi8vZmhpci5vcmcvZ3VpZGVzL2NkYy9vcGlvaWQtY2RzL1ZhbHVlU2V0L2hvc3BpY2UtZmluZGluZycKdmFsdWVzZXQgIkhvc3BpY2UgUHJvY2VkdXJlIENvZGVzIjogJ2h0dHA6Ly9maGlyLm9yZy9ndWlkZXMvY2RjL29waW9pZC1jZHMvVmFsdWVTZXQvaG9zcGljZS1wcm9jZWR1cmUnCnZhbHVlc2V0ICJJbGxpY2l0IERydWcgU2NyZWVuaW5nIjogJ2h0dHA6Ly9maGlyLm9yZy9ndWlkZXMvY2RjL29waW9pZC1jZHMvVmFsdWVTZXQvaWxsaWNpdC1kcnVnLXVyaW5lLXNjcmVlbmluZycKLy8gSGFydmVzdGVkIGZyb20gVlNBQyAtIE9JRDogMi4xNi44NDAuMS4xMTM4ODMuMy41MjYuMy4xMjU5CnZhbHVlc2V0ICJMaW1pdGVkIExpZmUgRXhwZWN0YW5jeSBDb25kaXRpb25zIjogJ2h0dHA6Ly9maGlyLm9yZy9ndWlkZXMvY2RjL29waW9pZC1jZHMvVmFsdWVTZXQvbGltaXRlZC1saWZlLWV4cGVjdGFuY3ktY29uZGl0aW9ucycKdmFsdWVzZXQgIkxvbmcgQWN0aW5nIE9waW9pZHMiOiAnaHR0cDovL2ZoaXIub3JnL2d1aWRlcy9jZGMvb3Bpb2lkLWNkcy9WYWx1ZVNldC9sb25nLWFjdGluZy1vcGlvaWRzJwp2YWx1ZXNldCAiTmFsb3hvbmUiOiAnaHR0cDovL2ZoaXIub3JnL2d1aWRlcy9jZGMvb3Bpb2lkLWNkcy9WYWx1ZVNldC9uYWxveG9uZScKdmFsdWVzZXQgIlJpc2sgQXNzZXNzbWVudCI6ICdodHRwOi8vZmhpci5vcmcvZ3VpZGVzL2NkYy9vcGlvaWQtY2RzL1ZhbHVlU2V0L29waW9pZC1hYnVzZS1hc3Nlc3NtZW50Jwp2YWx1ZXNldCAiT3Bpb2lkIERydWcgU2NyZWVuaW5nIjogJ2h0dHA6Ly9maGlyLm9yZy9ndWlkZXMvY2RjL29waW9pZC1jZHMvVmFsdWVTZXQvb3Bpb2lkLXVyaW5lLXNjcmVlbmluZycKdmFsdWVzZXQgIkFtYnVsYXRvcnkgQWJ1c2UgUG90ZW50aWFsIE9waW9pZHMiOiAnaHR0cDovL2ZoaXIub3JnL2d1aWRlcy9jZGMvb3Bpb2lkLWNkcy9WYWx1ZVNldC9vcGlvaWRzLWFidXNlZC1pbi1hbWJ1bGF0b3J5LWNhcmUnCnZhbHVlc2V0ICJTdWJzdGFuY2UgQWJ1c2UiOiAnaHR0cDovL2ZoaXIub3JnL2d1aWRlcy9jZGMvb3Bpb2lkLWNkcy9WYWx1ZVNldC9zdWJzdGFuY2UtYWJ1c2UnCgovLyBUT0RPOiBUdXJuIHRoaXMgaW50byBhIHZhbHVlc2V0CmNvZGUgIlJlZmVycmFsIHRvIEhvc3BpY2UiOiAnMzA2MjA1MDA5JyBmcm9tICJTTk9NRUQiCi8vIFRPRE86IFR1cm4gdGhpcyBpbnRvIGEgdmFsdWVzZXQKY29kZSAiT3V0cGF0aWVudCI6ICdvdXRwYXRpZW50JyBmcm9tICJNZWRpY2F0aW9uIFJlcXVlc3QgQ2F0ZWdvcnkgQ29kZXMiCgovLyBUT0RPOiBDYXB0dXJlIHByb2Nlc3MgZGVjaXNpb25zIGZvciBsb25nLXRlcm0gb3Bpb2lkIHVzZQpkZWZpbmUgSXNGb3JDaHJvbmljUGFpbjogdHJ1ZQoKZGVmaW5lICJBY3RpdmUgQW1idWxhdG9yeSBPcGlvaWQgUngiOgogIFtNZWRpY2F0aW9uUmVxdWVzdDogIkFtYnVsYXRvcnkgQWJ1c2UgUG90ZW50aWFsIE9waW9pZHMiXSBSeAogICAgd2hlcmUgUnguc3RhdHVzID0gJ2FjdGl2ZScKICAgICAgYW5kIFRvQ29kZXMoUnguY2F0ZWdvcnkuY29kaW5nKSBjb250YWlucyAiT3V0cGF0aWVudCIKCmRlZmluZSAiQWN0aXZlIEFtYnVsYXRvcnkgQmVuem9kaWF6ZXBpbmUgUngiOgogIFtNZWRpY2F0aW9uUmVxdWVzdDogIkJlbnpvZGlhemVwaW5lcyJdIFJ4CiAgICB3aGVyZSBSeC5zdGF0dXMgPSAnYWN0aXZlJwogICAgICBhbmQgVG9Db2RlcyhSeC5jYXRlZ29yeS5jb2RpbmcpIGNvbnRhaW5zICJPdXRwYXRpZW50IgoKZGVmaW5lICJBY3RpdmUgQW1idWxhdG9yeSBOYWxveG9uZSBSeCI6CiAgW01lZGljYXRpb25SZXF1ZXN0OiAiTmFsb3hvbmUiXSBSeAogICAgd2hlcmUgUnguc3RhdHVzID0gJ2FjdGl2ZScKICAgICAgYW5kIFRvQ29kZXMoUnguY2F0ZWdvcnkuY29kaW5nKSBjb250YWlucyAiT3V0cGF0aWVudCIKCmRlZmluZSAiQW1idWxhdG9yeSBPcGlvaWQgUngiOgogIFtNZWRpY2F0aW9uUmVxdWVzdDogIkFtYnVsYXRvcnkgQWJ1c2UgUG90ZW50aWFsIE9waW9pZHMiXSBSeAogICAgICB3aGVyZSBUb0NvZGVzKFJ4LmNhdGVnb3J5LmNvZGluZykgY29udGFpbnMgIk91dHBhdGllbnQiCgpkZWZpbmUgIkVuZCBvZiBMaWZlIEFzc2Vzc21lbnQiOgogIC8vIDEuIENvbmRpdGlvbnMgaW5kaWNhdGluZyBlbmQgb2YgbGlmZSBvciB3aXRoIGxpbWl0ZWQgbGlmZSBleHBlY3RhbmN5CiAgZXhpc3RzICgKICAgICgKICAgICAgW0NvbmRpdGlvbjogIkVuZCBvZiBMaWZlIENvbmRpdGlvbnMiXSBDCiAgICAgICAgd2hlcmUgQy5jbGluaWNhbFN0YXR1cyBpbiAiQWN0aXZlIENvbmRpdGlvbiIKICAgICkKICAgIHVuaW9uCiAgICAoCiAgICAgIFtDb25kaXRpb246IGNvZGUgaW4gIkxpbWl0ZWQgTGlmZSBFeHBlY3RhbmN5IENvbmRpdGlvbnMiXSBDCiAgICAgICAgd2hlcmUgQy5jbGluaWNhbFN0YXR1cyBpbiAiQWN0aXZlIENvbmRpdGlvbiIKICAgICkKICApCiAgLy8gMi4gQWRtaXR0ZWQvcmVmZXJyZWQvZGlzY2hhcmdlZCB0byBob3NwaWNlIGNhcmUKICBvciBleGlzdHMgKAogICAgKAogICAgICBbU2VydmljZVJlcXVlc3Q6IGNvZGUgaW4gIlJlZmVycmFsIHRvIEhvc3BpY2UiXSBSUgogICAgICAgIHdoZXJlIFJSLnN0YXR1cyBpbiB7ICdhY3RpdmUnLCAnY29tcGxldGVkJyB9CiAgICApCiAgICB1bmlvbgogICAgKAogICAgICBbU2VydmljZVJlcXVlc3Q6IGNvZGUgaW4gIkhvc3BpY2UgUHJvY2VkdXJlIENvZGVzIl0gUAogICAgICAgIHdoZXJlIFAuc3RhdHVzIGluIHsgJ2luLXByb2dyZXNzJywgJ2NvbXBsZXRlZCcgfQogICAgKQogICAgdW5pb24KICAgICgKICAgICAgW1NlcnZpY2VSZXF1ZXN0OiBjb2RlIGluICJIb3NwaWNlIFByb2NlZHVyZSBDb2RlcyJdIEUKICAgICAgICB3aGVyZSBFLnN0YXR1cyBpbiB7ICdwbGFubmVkJywgJ2Fycml2ZWQnLCAnaW4tcHJvZ3Jlc3MnLCAnZmluaXNoZWQnLCAnb25sZWF2ZScgfQogICAgKQogICAgdW5pb24KICAgICgKICAgICAgW09ic2VydmF0aW9uOiBjb2RlIGluICJIb3NwaWNlIEZpbmRpbmcgQ29kZXMiXSBPCiAgICAgICAgd2hlcmUgbm90IChPLnN0YXR1cyBpbiB7ICd1bmtub3duJywgJ2VudGVyZWQtaW4tZXJyb3InLCAnY2FuY2VsbGVkJyB9KQogICAgKQogICAgdW5pb24KICAgICgKICAgICAgW0VuY291bnRlcl0gRQogICAgICAgIHdoZXJlCiAgICAgICAgICAoCiAgICAgICAgICAgIGlmIEUuaG9zcGl0YWxpemF0aW9uLmRpc2NoYXJnZURpc3Bvc2l0aW9uLmNvZGluZyBpcyBudWxsCiAgICAgICAgICAgICAgICBvciBub3QgZXhpc3RzIChFLmhvc3BpdGFsaXphdGlvbi5kaXNjaGFyZ2VEaXNwb3NpdGlvbi5jb2RpbmcpCiAgICAgICAgICAgICAgdGhlbiBmYWxzZQogICAgICAgICAgICBlbHNlIEUuaG9zcGl0YWxpemF0aW9uLmRpc2NoYXJnZURpc3Bvc2l0aW9uIGluICJIb3NwaWNlIERpc3Bvc2l0aW9uIgogICAgICAgICAgKQogICAgICAgICAgYW5kIEUuc3RhdHVzIGluIHsgJ3BsYW5uZWQnLCAnYXJyaXZlZCcsICdpbi1wcm9ncmVzcycsICdmaW5pc2hlZCcsICdvbmxlYXZlJyB9CiAgICApCiAgKQoKZGVmaW5lIGZ1bmN0aW9uIFByZXNjcmlwdGlvbnMoT3JkZXJzIExpc3Q8TWVkaWNhdGlvblJlcXVlc3Q+KToKICBPcmRlcnMgTwogICAgbGV0CiAgICAgIC8vIE5PVEU6IEFzc3VtaW5nIG1lZGljYXRpb24gaXMgc3BlY2lmaWVkIGFzIGEgQ29kZWFibGVDb25jZXB0IHdpdGggYSBzaW5nbGUgUnhOb3JtIGNvZGUKICAgICAgcnhOb3JtQ29kZTogVG9Db2RlKE8ubWVkaWNhdGlvbi5jb2RpbmdbMF0pLAogICAgICBtZWRpY2F0aW9uTmFtZTogT01US0xvZ2ljLkdldE1lZGljYXRpb25OYW1lKHJ4Tm9ybUNvZGUpLAogICAgICAvLyBOT1RFOiBBc3N1bWluZyBhIHNpbmdsZSBkb3NhZ2UgaW5zdHJ1Y3Rpb24gZWxlbWVudAogICAgICBkb3NhZ2VJbnN0cnVjdGlvbjogTy5kb3NhZ2VJbnN0cnVjdGlvblswXSwKICAgICAgcmVwZWF0OiBkb3NhZ2VJbnN0cnVjdGlvbi50aW1pbmcucmVwZWF0LAogICAgICBmcmVxdWVuY3k6IENvYWxlc2NlKHJlcGVhdC5mcmVxdWVuY3lNYXgudmFsdWUsIHJlcGVhdC5mcmVxdWVuY3kudmFsdWUpLAogICAgICBwZXJpb2Q6IFN5c3RlbS5RdWFudGl0eSB7IHZhbHVlOiByZXBlYXQucGVyaW9kLnZhbHVlLCB1bml0OiByZXBlYXQucGVyaW9kVW5pdC52YWx1ZSB9LAogICAgICBkb3NlRGVzY3JpcHRpb246CiAgICAgICAgQ29hbGVzY2UoCiAgICAgICAgICAvLyBUaGVyZSBzaG91bGQgYmUgYSBjb252ZXJzaW9uIGZyb20gRkhJUi5TaW1wbGVRdWFudGl0eSB0byBTeXN0ZW0uUXVhbnRpdHkKICAgICAgICAgIGlmIGRvc2FnZUluc3RydWN0aW9uLmRvc2VBbmRSYXRlWzBdLmRvc2UgaXMgRkhJUi5SYW5nZQogICAgICAgICAgICB0aGVuIFRvU3RyaW5nKFRvUXVhbnRpdHkoZG9zYWdlSW5zdHJ1Y3Rpb24uZG9zZUFuZFJhdGVbMF0uZG9zZS5sb3cpKQogICAgICAgICAgICAgICAgICAgICAgICAgICsgJy0nICsgVG9TdHJpbmcoVG9RdWFudGl0eShkb3NhZ2VJbnN0cnVjdGlvbi5kb3NlQW5kUmF0ZVswXS5kb3NlLmhpZ2gpKQogICAgICAgICAgICAgICAgICAgICAgICAgICsgZG9zYWdlSW5zdHJ1Y3Rpb24uZG9zZUFuZFJhdGVbMF0uZG9zZS5oaWdoLnVuaXQudmFsdWUKICAgICAgICAgICAgZWxzZSBUb1N0cmluZyhUb1F1YW50aXR5KGRvc2FnZUluc3RydWN0aW9uLmRvc2VBbmRSYXRlWzBdLmRvc2UpKSwKICAgICAgICAgICAgJycKICAgICAgICApLAogICAgICBmcmVxdWVuY3lEZXNjcmlwdGlvbjoKICAgICAgICBUb1N0cmluZyhkb3NhZ2VJbnN0cnVjdGlvbi50aW1pbmcucmVwZWF0LmZyZXF1ZW5jeS52YWx1ZSkgKwogICAgICAgICAgQ29hbGVzY2UoCiAgICAgICAgICAgICctJyArIFRvU3RyaW5nKGRvc2FnZUluc3RydWN0aW9uLnRpbWluZy5yZXBlYXQuZnJlcXVlbmN5TWF4LnZhbHVlKSwKICAgICAgICAgICAgJycKICAgICAgICAgICkKICAgIHJldHVybiB7CiAgICAgIHJ4Tm9ybUNvZGU6IHJ4Tm9ybUNvZGUsCiAgICAgIGlzRHJhZnQ6IE8uc3RhdHVzLnZhbHVlID0gJ2RyYWZ0JywKICAgICAgLy8gTk9URTogQXNzdW1pbmcgYXNOZWVkZWQgaXMgZXhwcmVzc2VkIGFzIGEgYm9vbGVhbgogICAgICBpc1BSTjogZG9zYWdlSW5zdHJ1Y3Rpb24uYXNOZWVkZWQudmFsdWUsCiAgICAgIHByZXNjcmlwdGlvbjoKICAgICAgICBpZiBkb3NhZ2VJbnN0cnVjdGlvbi50ZXh0IGlzIG5vdCBudWxsIHRoZW4KICAgICAgICAgIG1lZGljYXRpb25OYW1lICsgJyAnICsgZG9zYWdlSW5zdHJ1Y3Rpb24udGV4dC52YWx1ZQogICAgICAgIGVsc2UKICAgICAgICAgIC8vIFRPRE86IFNob3VsZG4ndCBuZWVkIHRoZSAudmFsdWUgaGVyZSBvbiBhc05lZWRlZEJvb2xlYW4KICAgICAgICAgIG1lZGljYXRpb25OYW1lICsgJyAnICsgZG9zZURlc2NyaXB0aW9uICsgJyBxJyArIGZyZXF1ZW5jeURlc2NyaXB0aW9uICsgKGlmIGRvc2FnZUluc3RydWN0aW9uLmFzTmVlZGVkLnZhbHVlIHRoZW4gJyBQUk4nIGVsc2UgJycpLAogICAgICAvLyBUT0RPOiBTaG91bGRuJ3QgbmVlZCB0aGUgVG9RdWFudGl0eSBoZXJlLi4uCiAgICAgIGRvc2U6IGlmIGRvc2FnZUluc3RydWN0aW9uLmRvc2VBbmRSYXRlWzBdLmRvc2UgaXMgRkhJUi5SYW5nZQogICAgICAgICAgICB0aGVuIFRvUXVhbnRpdHkoZG9zYWdlSW5zdHJ1Y3Rpb24uZG9zZUFuZFJhdGVbMF0uZG9zZS5oaWdoKQogICAgICAgICAgICBlbHNlIFRvUXVhbnRpdHkoZG9zYWdlSW5zdHJ1Y3Rpb24uZG9zZUFuZFJhdGVbMF0uZG9zZSksCiAgICAgIGRvc2VzUGVyRGF5OiBDb2FsZXNjZShPTVRLTG9naWMuVG9EYWlseShmcmVxdWVuY3ksIHBlcmlvZCksIDEuMCkKICAgIH0KCmRlZmluZSBmdW5jdGlvbiBNTUUocHJlc2NyaXB0aW9ucyBMaXN0PE1lZGljYXRpb25SZXF1ZXN0Pik6CiAgKFByZXNjcmlwdGlvbnMocHJlc2NyaXB0aW9ucykpIFAKICAgIGxldCBtbWU6IFNpbmdsZXRvbkZyb20oT01US0xvZ2ljLkNhbGN1bGF0ZU1NRXMoeyB7IHJ4Tm9ybUNvZGU6IFAucnhOb3JtQ29kZSwgZG9zZVF1YW50aXR5OiBQLmRvc2UsIGRvc2VzUGVyRGF5OiBQLmRvc2VzUGVyRGF5IH0gfSkpCiAgICByZXR1cm4gewogICAgICByeE5vcm1Db2RlOiBQLnJ4Tm9ybUNvZGUsCiAgICAgIGlzRHJhZnQ6IFAuaXNEcmFmdCwKICAgICAgaXNQUk46IFAuaXNQUk4sCiAgICAgIHByZXNjcmlwdGlvbjogUC5wcmVzY3JpcHRpb24sCiAgICAgIGRhaWx5RG9zZTogbW1lLmRhaWx5RG9zZURlc2NyaXB0aW9uLAogICAgICBjb252ZXJzaW9uRmFjdG9yOiBtbWUuY29udmVyc2lvbkZhY3RvciwKICAgICAgbW1lOiBtbWUubW1lCiAgICB9CgpkZWZpbmUgZnVuY3Rpb24gVG90YWxNTUUocHJlc2NyaXB0aW9ucyBMaXN0PE1lZGljYXRpb25SZXF1ZXN0Pik6CiAgU3lzdGVtLlF1YW50aXR5IHsKICAgIHZhbHVlOiBTdW0oKE1NRShwcmVzY3JpcHRpb25zKSkgTSByZXR1cm4gTS5tbWUudmFsdWUpLAogICAgdW5pdDogJ21nL2QnCiAgfQoKZGVmaW5lIGZ1bmN0aW9uIFByb2JhYmxlRGF5c0luUmFuZ2UoT3JkZXJzIExpc3Q8TWVkaWNhdGlvblJlcXVlc3Q+LCBkYXlzUGFzdCBJbnRlZ2VyLCBudW1EYXlzSW5EYXlzUGFzdCBJbnRlZ2VyKToKICBPcmRlcnMgb3JkZXJzCiAgICBsZXQKICAgICAgZnJlcXVlbmN5OiBvcmRlcnMuZG9zYWdlSW5zdHJ1Y3Rpb25bMF0udGltaW5nLnJlcGVhdC5mcmVxdWVuY3kudmFsdWUsCiAgICAgIHBlcmlvZDogb3JkZXJzLmRvc2FnZUluc3RydWN0aW9uWzBdLnRpbWluZy5yZXBlYXQucGVyaW9kLnZhbHVlLAogICAgICBwZXJpb2REYXlzOiBHZXRQZXJpb2REYXlzKG9yZGVycy5kb3NhZ2VJbnN0cnVjdGlvblswXS50aW1pbmcucmVwZWF0LnBlcmlvZFVuaXQudmFsdWUpLAogICAgICBkb3Nlc1BlckRheToKICAgICAgICBpZiAoZnJlcXVlbmN5IC8gKHBlcmlvZCAqIHBlcmlvZERheXMpKSA+PSAxLjAKICAgICAgICB0aGVuIDEuMAogICAgICAgIGVsc2UgZnJlcXVlbmN5IC8gKHBlcmlvZCAqIHBlcmlvZERheXMpLAogICAgICByZXBlYXQ6IG9yZGVycy5kaXNwZW5zZVJlcXVlc3QubnVtYmVyT2ZSZXBlYXRzQWxsb3dlZC52YWx1ZSwKICAgICAgc3VwcGx5RHVyYXRpb246IEdldER1cmF0aW9uSW5EYXlzKG9yZGVycy5kaXNwZW5zZVJlcXVlc3QuZXhwZWN0ZWRTdXBwbHlEdXJhdGlvbiksCiAgICAgIHZhbGlkaXR5UGVyaW9kOiBkYXlzIGJldHdlZW4gb3JkZXJzLmRpc3BlbnNlUmVxdWVzdC52YWxpZGl0eVBlcmlvZC4ic3RhcnQiLnZhbHVlIGFuZCBUb2RheSgpLAogICAgICBlbmREaWZmZXJlbmNlOgogICAgICAgIGlmIG9yZGVycy5kaXNwZW5zZVJlcXVlc3QudmFsaWRpdHlQZXJpb2QuImVuZCIudmFsdWUgPCBUb2RheSgpCiAgICAgICAgdGhlbiBkYXlzIGJldHdlZW4gb3JkZXJzLmRpc3BlbnNlUmVxdWVzdC52YWxpZGl0eVBlcmlvZC4iZW5kIi52YWx1ZSBhbmQgVG9kYXkoKQogICAgICAgIGVsc2UgMAogICAgcmV0dXJuCiAgICAgIGlmIChyZXBlYXQgKiBzdXBwbHlEdXJhdGlvbikgPCBudW1EYXlzSW5EYXlzUGFzdCB0aGVuIGZhbHNlCiAgICAgIGVsc2UKICAgICAgICAoZG9zZXNQZXJEYXkgKiAoKHJlcGVhdCAqIHN1cHBseUR1cmF0aW9uKSAvIHZhbGlkaXR5UGVyaW9kKSAqIChkYXlzUGFzdCAtIGVuZERpZmZlcmVuY2UpKSA+PSBudW1EYXlzSW5EYXlzUGFzdAoKZGVmaW5lIGZ1bmN0aW9uIEdldFBlcmlvZERheXModmFsdWUgU3lzdGVtLlN0cmluZyk6CiAgY2FzZQogICAgd2hlbiB2YWx1ZSA9ICdhJyB0aGVuIDM2NS4wCiAgICB3aGVuIHZhbHVlID0gJ21vJyB0aGVuIDMwLjAKICAgIHdoZW4gdmFsdWUgPSAnaCcgdGhlbiAxLjAvMjQuMAogICAgd2hlbiB2YWx1ZSA9ICdtaW4nIHRoZW4gMS4wLzI0LjAqNjAuMAogICAgd2hlbiB2YWx1ZSA9ICdzJyB0aGVuIDEuMC8yNC4wKjYwLjAqNjAuMAogICAgd2hlbiB2YWx1ZSA9ICdtcycgdGhlbiAxLjAvMjQuMCo2MC4wKjYwLjAqMTAwMC4wCiAgICBlbHNlIDEuMAogIGVuZAoKICBkZWZpbmUgZnVuY3Rpb24gR2V0RHVyYXRpb25JbkRheXModmFsdWUgRkhJUi5EdXJhdGlvbik6CiAgICBjYXNlCiAgICAgIHdoZW4gU3RhcnRzV2l0aCh2YWx1ZS51bml0LnZhbHVlLCAnYScpIHRoZW4gdmFsdWUudmFsdWUudmFsdWUgKiAzNjUuMAogICAgICB3aGVuIFN0YXJ0c1dpdGgodmFsdWUudW5pdC52YWx1ZSwgJ21vJykgdGhlbiB2YWx1ZS52YWx1ZS52YWx1ZSAqIDMwLjAKICAgICAgd2hlbiBTdGFydHNXaXRoKHZhbHVlLnVuaXQudmFsdWUsICd3aycpIHRoZW4gdmFsdWUudmFsdWUudmFsdWUgKiA3LjAKICAgICAgd2hlbiBTdGFydHNXaXRoKHZhbHVlLnVuaXQudmFsdWUsICdkJykgdGhlbiB2YWx1ZS52YWx1ZS52YWx1ZQogICAgICB3aGVuIFN0YXJ0c1dpdGgodmFsdWUudW5pdC52YWx1ZSwgJ2gnKSB0aGVuIHZhbHVlLnZhbHVlLnZhbHVlIC8gMjQuMAogICAgICB3aGVuIFN0YXJ0c1dpdGgodmFsdWUudW5pdC52YWx1ZSwgJ21pbicpIHRoZW4gdmFsdWUudmFsdWUudmFsdWUgLyA2MC4wIC8gMjQuMAogICAgICB3aGVuIFN0YXJ0c1dpdGgodmFsdWUudW5pdC52YWx1ZSwgJ3MnKSB0aGVuIHZhbHVlLnZhbHVlLnZhbHVlIC8gNjAuMCAvIDYwLjAgLyAyNC4wCiAgICAgIHdoZW4gU3RhcnRzV2l0aCh2YWx1ZS51bml0LnZhbHVlLCAnbXMnKSB0aGVuIHZhbHVlLnZhbHVlLnZhbHVlIC8gNjAuMCAvIDYwLjAgLyAyNC4wIC8gMTAwMC4wCiAgICAgIGVsc2UgTWVzc2FnZSgxMDAwLCB0cnVlLCAnVW5kZWZpbmVkJywgJ0Vycm9yJywgJ1Vuc3VwcG9ydGVkIGR1cmF0aW9uIHVuaXQnKQogICAgZW5kCgpkZWZpbmUgZnVuY3Rpb24gR2V0SW5ncmVkaWVudChyeE5vcm1Db2RlIENvZGUpOgogIE9NVEtMb2dpYy5HZXRJbmdyZWRpZW50cyhyeE5vcm1Db2RlKS5pbmdyZWRpZW50TmFtZQoKZGVmaW5lIGZ1bmN0aW9uIEdldEluZ3JlZGllbnRzKHJ4Tm9ybUNvZGVzIExpc3Q8Q29kZT4pOgogIHJ4Tm9ybUNvZGVzIHJuYyByZXR1cm4gR2V0SW5ncmVkaWVudChybmMpCgpkZWZpbmUgZnVuY3Rpb24gR2V0TWVkaWNhdGlvbk5hbWVzKG1lZGljYXRpb25zIExpc3Q8TWVkaWNhdGlvblJlcXVlc3Q+KToKICBtZWRpY2F0aW9ucyBNCiAgICByZXR1cm4gT01US0xvZ2ljLkdldEluZ3JlZGllbnRzKFRvUnhOb3JtQ29kZShNLm1lZGljYXRpb24uY29kaW5nKSkucnhOb3JtQ29kZS5kaXNwbGF5CgovKgoqICBDb252ZXJzaW9uIEZ1bmN0aW9ucwoqLwoKZGVmaW5lIGZ1bmN0aW9uIFRvQ29kZShjb2RpbmcgRkhJUi5Db2RpbmcpOgogIFN5c3RlbS5Db2RlIHsKICAgIGNvZGU6IGNvZGluZy5jb2RlLnZhbHVlLAogICAgc3lzdGVtOiBjb2Rpbmcuc3lzdGVtLnZhbHVlLAogICAgdmVyc2lvbjogY29kaW5nLnZlcnNpb24udmFsdWUsCiAgICBkaXNwbGF5OiBjb2RpbmcuZGlzcGxheS52YWx1ZQogIH0KCmRlZmluZSBmdW5jdGlvbiBUb0NvZGVzKGNvZGluZyBMaXN0PEZISVIuQ29kaW5nPik6CiAgY29kaW5nIGMgcmV0dXJuIFRvQ29kZShjKQoKZGVmaW5lIGZ1bmN0aW9uIFRvUnhOb3JtQ29kZShjb2RpbmcgTGlzdDxGSElSLkNvZGluZz4pOgogIHNpbmdsZXRvbiBmcm9tICgKICAgIGNvZGluZyBDIHdoZXJlIEMuc3lzdGVtID0gJ2h0dHA6Ly93d3cubmxtLm5paC5nb3YvcmVzZWFyY2gvdW1scy9yeG5vcm0nCiAgKQoKZGVmaW5lIGZ1bmN0aW9uIFRvUXVhbnRpdHkocXVhbnRpdHkgRkhJUi5RdWFudGl0eSk6CiAgU3lzdGVtLlF1YW50aXR5IHsgdmFsdWU6IHF1YW50aXR5LnZhbHVlLnZhbHVlLCB1bml0OiBxdWFudGl0eS51bml0LnZhbHVlIH0K"/>
</content>
<content>
<contentType value="application/elm+xml"/>
</content>
</Library>
IG © 2022+ HL7 International - Clinical Decision Support WG. Package hl7.fhir.uv.cpg#1.0.0 based on FHIR 4.0.1. Generated 2023-09-21
Links: Table of Contents |
QA Report
| Version History |
|
Propose a change