Quality Measure Implementation Guide (STU3 Ballot)
2.1.0 - ballot

This page is part of the Quality Measure STU2 for FHIR R4 Implementation Guide (v2.1.0: STU3 Ballot 1) based on FHIR R4. The current version which supercedes this version is 3.0.0. For a full list of available versions, see the Directory of published versions

Example Library: Example Library - TSCComponent

Id: TSCComponent
Url: http://ecqi.healthit.gov/ecqms/Library/TSCComponentLibrary
Version: 0.0.001
Name: TSCComponent
Status: draft
Experimental: true
Type:

system: http://terminology.hl7.org/CodeSystem/library-type

code: logic-library

Date: 2021-04-13T15:56:57+00:00
Publisher: Clinical Quality Information WG
Description: Preventive Care and Screening: Tobacco Use: Screening and Cessation Intervention
Jurisdiction: US
Related Artifacts:

Dependencies

  • http://fhir.org/guides/cqf/common/Library/FHIR-ModelInfo|4.0.1
  • http://fhir.org/guides/cqf/common/Library/FHIRHelpers|4.0.1
  • http://hl7.org/fhir/us/cqfmeasures/Library/SupplementalDataElements|2.0.000
  • http://hl7.org/fhir/us/cqfmeasures/Library/MATGlobalCommonFunctions|5.0.000
  • http://fhir.org/guides/cqf/common/Library/FHIRHelpers|4.0.1
  • http://loinc.org
  • http://www.ama-assn.org/go/cpt
  • http://terminology.hl7.org/CodeSystem/condition-clinical
  • http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1240
  • http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1048
  • http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1016
  • http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1259
  • http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1007
  • http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1011
  • http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1001
  • http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1285
  • http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1022
  • http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1025
  • http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1027
  • http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1030
  • http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1026
  • http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1023
  • http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1492
  • http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1496
  • http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1141
  • http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1530
  • http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1189
  • http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.509
  • http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1190
  • http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1278
  • http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1170
  • http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.4.11.3591
Parameters:
NameTypeMinMaxIn/Out
Measurement PeriodPeriod01in
PatientPatient01out
SDE EthnicityCoding0*out
SDE EthnicityCoding0*out
PatientPatient01out
SDE PayerAny0*out
SDE PayerAny0*out
SDE RaceCoding0*out
SDE RaceCoding0*out
SDE SexCoding01out
SDE SexCoding01out
Preventive Visit During Measurement PeriodEncounter0*out
Office Based Visit During Measurement PeriodEncounter0*out
Initial Populationboolean01out
Denominator 1boolean01out
Denominator 3boolean01out
Medical Reason for Not Screening for Tobacco UseObservation0*out
Medical Reason for Not Ordering Tobacco Cessation PharmacotherapyMedicationRequest0*out
Medical Reason for Not Counseling Tobacco UserProcedure0*out
Tobacco Cessation Pharmacotherapy OrderedMedicationRequest0*out
Tobacco Cessation Counseling GivenEncounter0*out
Numerator 2boolean01out
Has Limited Life Expectancyboolean01out
Denominator Exceptions 1boolean01out
Denominator Exceptions 2boolean01out
Denominator Exceptions 3boolean01out
Most Recent Tobacco Use Screening Indicates Tobacco Non UserObservation01out
Most Recent Tobacco Use Screening Indicates Tobacco UserObservation01out
Denominator 2boolean01out
Numerator 1boolean01out
Numerator 3boolean01out
Data Requirements:
TypeProfileMSCode Filter
Patient http://hl7.org/fhir/StructureDefinition/Patient
Patient http://hl7.org/fhir/StructureDefinition/Patient
Coverage http://hl7.org/fhir/StructureDefinition/Coverage code filter:
path: type
value set: http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.4.11.3591
Encounter http://hl7.org/fhir/StructureDefinition/Encounter code filter:
path: type
value set: http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1240
Encounter http://hl7.org/fhir/StructureDefinition/Encounter code filter:
path: type
value set: http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1025
Encounter http://hl7.org/fhir/StructureDefinition/Encounter code filter:
path: type
value set: http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1027
Encounter http://hl7.org/fhir/StructureDefinition/Encounter code filter:
path: type
value set: http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1030
Encounter http://hl7.org/fhir/StructureDefinition/Encounter code filter:
path: type
value set: http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1026
Encounter http://hl7.org/fhir/StructureDefinition/Encounter code filter:
path: type
value set: http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1023
Encounter http://hl7.org/fhir/StructureDefinition/Encounter code filter:
path: type

system: http://www.ama-assn.org/go/cpt

code: 96158

display: Health behavior intervention, individual, face-to-face; initial 30 minutes

Encounter http://hl7.org/fhir/StructureDefinition/Encounter code filter:
path: type

system: http://www.ama-assn.org/go/cpt

code: 96156

display: Health behavior assessment, or re-assessment (ie, health-focused clinical interview, behavioral observations, clinical decision making)

Encounter http://hl7.org/fhir/StructureDefinition/Encounter code filter:
path: type
value set: http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1016
Encounter http://hl7.org/fhir/StructureDefinition/Encounter code filter:
path: type
value set: http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1011
Encounter http://hl7.org/fhir/StructureDefinition/Encounter code filter:
path: type
value set: http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1001
Encounter http://hl7.org/fhir/StructureDefinition/Encounter code filter:
path: type
value set: http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1285
Encounter http://hl7.org/fhir/StructureDefinition/Encounter code filter:
path: type
value set: http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1022
Encounter http://hl7.org/fhir/StructureDefinition/Encounter code filter:
path: type
value set: http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1492
Encounter http://hl7.org/fhir/StructureDefinition/Encounter code filter:
path: type
value set: http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1496
Encounter http://hl7.org/fhir/StructureDefinition/Encounter code filter:
path: type
value set: http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1141
Encounter http://hl7.org/fhir/StructureDefinition/Encounter code filter:
path: type
value set: http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1530
Patient http://hl7.org/fhir/StructureDefinition/Patient
Observation http://hl7.org/fhir/StructureDefinition/Observation code filter:
path: code
value set: http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1278
MedicationRequest http://hl7.org/fhir/StructureDefinition/MedicationRequest code filter:
path: medication
value set: http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1190
Procedure http://hl7.org/fhir/StructureDefinition/Procedure code filter:
path: code
value set: http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.509
MedicationRequest http://hl7.org/fhir/StructureDefinition/MedicationRequest code filter:
path: medication
value set: http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1190
Encounter http://hl7.org/fhir/StructureDefinition/Encounter code filter:
path: type
value set: http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.509
Condition http://hl7.org/fhir/StructureDefinition/Condition
Observation http://hl7.org/fhir/StructureDefinition/Observation code filter:
path: code
value set: http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1278
Observation http://hl7.org/fhir/StructureDefinition/Observation code filter:
path: code
value set: http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1278
Content: text/cql
/*
This example is a work in progress and should not be considered a final specification
or recommendation for guidance. This example will help guide and direct the process
of finding conventions and usage patterns that meet the needs of the various stakeholders
in the measure development community.
*/
library TSCComponent version '0.0.001'

using FHIR version '4.0.1'

include FHIRHelpers version '4.0.1' called FHIRHelpers
include SupplementalDataElements version '2.0.000' called SDE
include MATGlobalCommonFunctions version '5.0.000' called Global

codesystem "LOINC": 'http://loinc.org'
codesystem "CPT": 'http://www.ama-assn.org/go/cpt'

valueset "Annual Wellness Visit": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1240'
valueset "Face-to-Face Interaction": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1048'
valueset "Home Healthcare Services": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1016'
valueset "Limited Life Expectancy": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1259'
valueset "Medical Reason": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1007'
valueset "Occupational Therapy Evaluation": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1011'
valueset "Office Visit": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1001'
valueset "Ophthalmological Services": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1285'
valueset "Physical Therapy Evaluation": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1022'
valueset "Preventive Care Services - Established Office Visit, 18 and Up": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1025'
valueset "Preventive Care Services - Group Counseling": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1027'
valueset "Preventive Care Services - Other": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1030'
valueset "Preventive Care Services-Individual Counseling": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1026'
valueset "Preventive Care Services-Initial Office Visit, 18 and Up": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1023'
valueset "Psych Visit - Diagnostic Evaluation": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1492'
valueset "Psych Visit - Psychotherapy": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1496'
valueset "Psychoanalysis": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1141'
valueset "Speech and Hearing Evaluation": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1530'
valueset "Tobacco Non-User": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1189'
valueset "Tobacco Use Cessation Counseling": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.509'
valueset "Tobacco Use Cessation Pharmacotherapy": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1190'
valueset "Tobacco Use Screening": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1278'
valueset "Tobacco User": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1170'

code "Birth date": '21112-8' from "LOINC" display 'Birth date'
code "Health behavior assessment, or re-assessment (ie, health-focused clinical interview, behavioral observations, clinical decision making)": '96156' from "CPT" display 'Health behavior assessment, or re-assessment (ie, health-focused clinical interview, behavioral observations, clinical decision making)'
code "Health behavior intervention, individual, face-to-face; initial 30 minutes": '96158' from "CPT" display 'Health behavior intervention, individual, face-to-face; initial 30 minutes'

parameter "Measurement Period" Interval<DateTime>

context Patient

define "SDE Ethnicity":
  SDE."SDE Ethnicity"

define "SDE Payer":
  SDE."SDE Payer"

define "SDE Race":
  SDE."SDE Race"

define "SDE Sex":
  SDE."SDE Sex"

define "Preventive Visit During Measurement Period":
  ( ["Encounter": "Annual Wellness Visit"]
      union ["Encounter": "Preventive Care Services - Established Office Visit, 18 and Up"]
      union ["Encounter": "Preventive Care Services - Group Counseling"]
      union ["Encounter": "Preventive Care Services - Other"]
      union ["Encounter": "Preventive Care Services-Individual Counseling"]
      union ["Encounter": "Preventive Care Services-Initial Office Visit, 18 and Up"] ) PreventiveEncounter
      where PreventiveEncounter.period during "Measurement Period"
        and PreventiveEncounter.status = 'finished'

define "Denominator 1":
  "Initial Population"

define "Denominator 3":
  "Initial Population"

define "Initial Population":
  exists ( ["Patient"] BirthDate
        where Global."CalendarAgeInYearsAt" ( FHIRHelpers.ToDate ( BirthDate.birthDate ), start of "Measurement Period" ) >= 18
    )
      and ( Count("Office Based Visit During Measurement Period")>= 2
          or exists "Preventive Visit During Measurement Period"
      )

define "Medical Reason for Not Screening for Tobacco Use":
  ["Observation": "Tobacco Use Screening"] NoTobaccoUseScreening
      where NoTobaccoUseScreening.issued during "Measurement Period"
        and "Not Done"(NoTobaccoUseScreening)
        and "Not Done Reason in Medical Reason"(NoTobaccoUseScreening)
        and NoTobaccoUseScreening.status = 'final'

define "Medical Reason for Not Ordering Tobacco Cessation Pharmacotherapy":
  ["MedicationRequest": "Tobacco Use Cessation Pharmacotherapy"] NoCessationPharmacotherapyOrdered
      where NoCessationPharmacotherapyOrdered.authoredOn during "Measurement Period"
        and NoCessationPharmacotherapyOrdered.status = 'completed'
        and ( ( "Not Done"(NoCessationPharmacotherapyOrdered)
              and "Not Done Reason in Medical Reason"(NoCessationPharmacotherapyOrdered)
          )
            or ( NoCessationPharmacotherapyOrdered.doNotPerform = true
                and NoCessationPharmacotherapyOrdered.statusReason in "Medical Reason"
            )
        )

define "Medical Reason for Not Counseling Tobacco User":
  ["Procedure": "Tobacco Use Cessation Counseling"] NoTobaccoCessationCounseling
      where Global."Normalize Interval" ( NoTobaccoCessationCounseling.performed ) starts during "Measurement Period"
        and ( ( NoTobaccoCessationCounseling.status = 'not-done'
              and NoTobaccoCessationCounseling.statusReason in "Medical Reason"
          )
            or ( "Not Done"(NoTobaccoCessationCounseling)
                and "Not Done Reason in Medical Reason"(NoTobaccoCessationCounseling)
            )
        )

define "Tobacco Cessation Pharmacotherapy Ordered":
  ["MedicationRequest": "Tobacco Use Cessation Pharmacotherapy"] CessationPharmacotherapyOrdered
      where CessationPharmacotherapyOrdered.authoredOn during "Measurement Period"
        and CessationPharmacotherapyOrdered.status = 'active'

// MedicationStatement is not available in R5, known publication issue
//define "Active Pharmacotherapy for Tobacco Cessation":
//  ["MedicationStatement": "Tobacco Use Cessation Pharmacotherapy"] TakingCessationPharmacotherapy
//      where Global."Normalize Interval" ( TakingCessationPharmacotherapy.effective ) overlaps after "Measurement Period"
//        and TakingCessationPharmacotherapy.status in { 'active', 'completed' }

define "Tobacco Cessation Counseling Given":
  ["Encounter": "Tobacco Use Cessation Counseling"] TobaccoCessationCounseling
      where TobaccoCessationCounseling.period during "Measurement Period"
        and TobaccoCessationCounseling.status = 'finished'

define "Numerator 2":
  exists "Tobacco Cessation Counseling Given"
      or exists "Tobacco Cessation Pharmacotherapy Ordered"
      //or exists "Active Pharmacotherapy for Tobacco Cessation"

define "Has Limited Life Expectancy":
  exists ( ["Condition"] LimitedLifeExpectancy
        where Global."Prevalence Period" ( LimitedLifeExpectancy ) overlaps after "Measurement Period"
          and LimitedLifeExpectancy.clinicalStatus ~ ToConcept(Global."active")
    )

define "Denominator Exceptions 1":
  exists "Medical Reason for Not Screening for Tobacco Use"
      or "Has Limited Life Expectancy"

define "Denominator Exceptions 2":
  exists "Medical Reason for Not Counseling Tobacco User"
      or exists "Medical Reason for Not Ordering Tobacco Cessation Pharmacotherapy"
      or "Has Limited Life Expectancy"

define "Denominator Exceptions 3":
  exists "Medical Reason for Not Screening for Tobacco Use"
      or exists "Medical Reason for Not Counseling Tobacco User"
      or exists "Medical Reason for Not Ordering Tobacco Cessation Pharmacotherapy"
      or "Has Limited Life Expectancy"

define "Office Based Visit During Measurement Period":
  ( ["Encounter": "Health behavior intervention, individual, face-to-face; initial 30 minutes"]
      union ["Encounter": "Health behavior assessment, or re-assessment (ie, health-focused clinical interview, behavioral observations, clinical decision making)"]
      union ["Encounter": "Home Healthcare Services"]
      union ["Encounter": "Occupational Therapy Evaluation"]
      union ["Encounter": "Office Visit"]
      union ["Encounter": "Ophthalmological Services"]
      union ["Encounter": "Physical Therapy Evaluation"]
      union ["Encounter": "Psych Visit - Diagnostic Evaluation"]
      union ["Encounter": "Psych Visit - Psychotherapy"]
      union ["Encounter": "Psychoanalysis"]
      union ["Encounter": "Speech and Hearing Evaluation"] ) OfficeBasedEncounter
      where OfficeBasedEncounter.period during "Measurement Period"
        and OfficeBasedEncounter.status = 'finished'

define "Most Recent Tobacco Use Screening Indicates Tobacco Non User":
  ( Last(["Observation": "Tobacco Use Screening"] TobaccoUseScreening
        where Global."Normalize Interval"(TobaccoUseScreening.effective)overlaps "Measurement Period"
        sort by start of Global."Normalize Interval"(effective)
    )) MostRecentTobaccoUseScreening
      where MostRecentTobaccoUseScreening.value in "Tobacco Non-User"

define "Most Recent Tobacco Use Screening Indicates Tobacco User":
  ( Last(["Observation": "Tobacco Use Screening"] TobaccoUseScreening
        where Global."Normalize Interval"(TobaccoUseScreening.effective)overlaps "Measurement Period"
        sort by start of Global."Normalize Interval"(effective)
    )) MostRecentTobaccoUseScreening
      where MostRecentTobaccoUseScreening.value in "Tobacco User"

define "Denominator 2":
  "Initial Population"
      and "Most Recent Tobacco Use Screening Indicates Tobacco User" is not null

define "Numerator 1":
  "Most Recent Tobacco Use Screening Indicates Tobacco Non User" is not null
      or "Most Recent Tobacco Use Screening Indicates Tobacco User" is not null

define "Numerator 3":
  "Most Recent Tobacco Use Screening Indicates Tobacco Non User" is not null
      or ( "Most Recent Tobacco Use Screening Indicates Tobacco User" is not null
          and ( exists "Tobacco Cessation Counseling Given"
              or exists "Tobacco Cessation Pharmacotherapy Ordered"
              //or exists "Active Pharmacotherapy for Tobacco Cessation"
          )
      )

define function "Not Done"(res DomainResource ):
  if ( res R
      where ( "GetModiferExtension"(R, 'http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-notDone').value = true )
  ) is not null then true
    else false

define function "Not Done Reason in Medical Reason"(res DomainResource ):
  if ( res R
      where "GetModiferExtension"(R, 'http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-notDoneReason').value in "Medical Reason"
  ) is not null then true
    else false

define function "GetModifierExtensions"(res DomainResource, url String ):
  res.modifierExtension E
    where E.url = ( url )
    return E

define function "GetModiferExtension"(res DomainResource, url String ):
  singleton from "GetModifierExtensions"(res, url)
Content: application/elm+xml
Encoded data (214300 characters)
Content: application/elm+json
Encoded data (383772 characters)