dQM CMS Content Implementation Guide
2026.1.0 - CI Build
dQM CMS Content Implementation Guide, published by cqframework. This guide is not an authorized publication; it is the continuous build for version 2026.1.0 built by the FHIR (HL7® FHIR® Standard) CI Build. This version is based on the current content of https://github.com/cqframework/dqm-content-cms-2026/ and changes regularly. See the Directory of published versions
| Page standards status: Informative | Maturity Level: 1 |
{
"resourceType" : "Library",
"id" : "HOB",
"text" : {
"status" : "extensions",
"div" : "<div xmlns=\"http://www.w3.org/1999/xhtml\">\n <table class=\"narrative-table\">\n <tbody>\n<tr>\n\n\n<th colspan=\"2\" scope=\"row\" class=\"row-header\">Metadata</th>\n\n\n</tr>\n\n<tr>\n\n\n<th scope=\"row\" class=\"row-header\">Title</th>\n\n\n\n<td class=\"content-container\">HOB Elements and Logic</td>\n\n\n</tr>\n\n\n\n<tr>\n\n\n<th scope=\"row\" class=\"row-header\">Version</th>\n\n\n\n<td class=\"content-container\">2026.1.0</td>\n\n\n</tr>\n\n\n\n\n\n\n\n\n\n\n\n\n<tr>\n\n\n<th scope=\"row\" class=\"row-header\">Status</th>\n\n\n\n<td class=\"content-container\">Draft</td>\n\n\n</tr>\n\n\n\n\n<tr>\n\n\n<th scope=\"row\" class=\"row-header\">Experimental</th>\n\n\n\n<td class=\"content-container\">true</td>\n\n\n</tr>\n\n\n\n\n\n\n<tr>\n\n\n<th scope=\"row\" class=\"row-header\">Topic</th>\n\n\n\n<td class=\"content-container\">FHIR\n</td>\n\n\n</tr>\n\n<tr>\n\n\n<th scope=\"row\" class=\"row-header\">Topic</th>\n\n\n\n<td class=\"content-container\">CQL\n</td>\n\n\n</tr>\n\n\n\n\n\n\n\n\n\n\n\n\n\n<tr>\n\n\n<th scope=\"row\" class=\"row-header\">Description</th>\n\n\n\n<td class=\"content-container\"><div><p>DRAFT Data elements used in the calculation of Hospital-onset Bacteremia and Fungemia measures.</p>\n</div></td>\n\n\n</tr>\n\n\n\n\n\n\n<tr>\n\n\n<th scope=\"row\" class=\"row-header\">Type</th>\n\n\n\n<td class=\"content-container\">\n logic-library from <a href=\"http://terminology.hl7.org/7.3.0/CodeSystem-library-type.html\">http://terminology.hl7.org/CodeSystem/library-type</a> \n\n\n</td>\n\n\n</tr>\n\n\n\n\n\n\n\n\n<tr>\n\n\n<th colspan=\"2\" scope=\"row\" class=\"row-header\"><a name=\"parameters\"> </a>Parameters</th>\n\n\n</tr>\n\n\n<tr>\n\n\n<th scope=\"row\" class=\"row-header\">Parameter</th>\n\n\n\n<td class=\"content-container\">None</td>\n\n\n</tr>\n\n\n\n\n\n\n\n\n <tr>\n\n\n<th colspan=\"2\" scope=\"row\" class=\"row-header\">Library Content</th>\n\n\n</tr>\n \n \n <tr>\n <th scope=\"row\" class=\"row-header\">CQL Content</th>\n <td>\n <a name=\"cql-content\"> </a>\n <pre style=\"border: none;\" class=\"content-container highlight language-cql\"><code class=\"language-cql\">/*\nDraft CQL representation of Hospital Onset Bacteremia and Fungemia Surveillance Measure\n*/\nlibrary HOB\n\nusing FHIR version '4.0.1'\n\ninclude hl7.fhir.uv.cql.FHIRHelpers version '4.0.1' called FHIRHelpers\ninclude hl7.fhir.uv.cql.FHIRCommon version '2.0.0' called FHIRCommon\n\ninclude CQMCommon version '5.1.000' called CQMCommon\ninclude HOBOrganismTaxonomy\n\nvalueset "Bacteria and Fungi - HOB Specific": 'https://example.org/fhir/ValueSet/bacteria-and-fungi-hob-specific'\nvalueset "Bacterial Skin Commensals": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.24.7.281' version '20240918' // Was 20241003, verify\nvalueset "Community-associated Organisms - HOB Specific": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.24.7.1170' version '20250930'\nvalueset "Bacterial and Fungal Blood Culture Tests": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1190.63' version '20220721'\nvalueset "Enteral Medication Route": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1190.74' version '20240618'\nvalueset "Intravenous Medication Route": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1190.75' version '20240618'\nvalueset "Specimen Type - Blood": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.24.7.315' version '20250929'\nvalueset "Absolute Neutrophils": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.24.7.1173' version '20250913'\nvalueset "Antimicrobial Medications - I.V Antibacterials": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.24.7.1220' version '20260122'\nvalueset "Antimicrobial Medications - Oral Antibacterials": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.24.7.1220' version '20250813'\nvalueset "Antimicrobials for Bacteremia and Fungemia Surveillance Module": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.24.7.1220' version '20260205'\n\nparameter "Measurement Period" Interval<DateTime> \n default Interval[@2026-01-01T00:00:00.0, @2026-01-31T23:59:59.999]\n\ncontext Patient\n\n/*\nED/OBS encounter: Any patient visit to an emergency department (ED) or observation (OBS) location. One patient visit equals one encounter. ED/OBS are considered outpatient locations.\nHospital Stay: NHSN defines a hospital stay to be inclusive of any: (a) ED/OBS encounters, (b) inpatient admissions, or (c) ED/OBS encounters that lead to inpatient admissions (within 1 hour of ED/OBS encounters).\nInpatient admission: For NHSN reporting purposes, the ‘date admitted to the facility’ is hospital day (HD) 1. NHSN defines an inpatient as any patient cared for or housed on an inpatient location. Local status may differ from NHSN definition; all days spent in an inpatient unit, regardless of local admission status and/or billing status are included in the counts of admissions and inpatient days. For NHSN reporting purposes, the date admitted to the facility is the calendar date that the patient physically locates to an inpatient location.\nMeasurement Period: Time period selected for report generation/metric calculation\nAdult: Patients who are ≥18 years old on the calendar day of the start of the Hospital Stay\nPediatric: Patients who are < 18 years old on the calendar day of the start of the Hospital Stay\nNICU: Patients who are housed in a NICU location at the time of index blood culture collection\nOncology/Neutropenia: Patient either 1) located in an Oncology ward, or 2) with neutropenia define an absolute neutrophil count (ANC) <1000 cell/microL observed for ≥2 days in a +/- 7-day window period around the index blood culture\nO-COB: Outpatient Community-onset Bacteremia & Fungemia Event\nCOB: Community-onset Bacteremia & Fungemia Event\nHOB: Hospital-onset Bacteremia & Fungemia Event\n*/\n\ndefine "Bacterial and Fungal Blood Culture Test Results":\n [Observation: "Bacterial and Fungal Blood Culture Tests"] O\n where O.isLaboratory()\n and O.isResulted()\n\ndefine "Bacteremia or Fungemia Result":\n "Bacterial and Fungal Blood Culture Test Results" R\n where ((R.value as CodeableConcept) in "Bacteria and Fungi - HOB Specific")\n and not ((R.value as CodeableConcept) in "Bacterial Skin Commensals")\n\ndefine "Bacteremia or Fungemia Result With Specimen":\n from\n "Bacteremia or Fungemia Result" R,\n [Specimen: "Specimen Type - Blood"] S\n where R.specimen.references(S)\n return {\n result: R,\n specimen: S\n }\n\n// Assertion is that there is never more than one ED/Observation preceding an inpatient stay\n// i.e. ED -> ED -> Inpatient, ED -> Observation -> ED -> Inpatient, Observation -> Inpatient are all combinations that will never appear\n// TODO: This does not currently hold for real-world data, need to build encounter normalization logic\n// Note also that Encounter.classHistory is not defined, so Encounter.hospitalization.location will have a more accurate representation of class over time\ndefine "Outpatient Encounter":\n [Encounter: CQMCommon."Emergency Department Visit"] ED\n let observationEncounter: First(\n [Encounter: CQMCommon."Observation Services"] O\n where O.period starts 1 hour or less on or before end of ED.period\n sort by start of period\n ),\n endOfStay: Coalesce(end of observationEncounter.period, end of ED.period),\n inpatientEncounter: First(\n [Encounter: CQMCommon."Encounter Inpatient"] E\n where E.period starts 1 hour or less on or before endOfStay\n )\n return {\n edEncounter: ED,\n observationEncounter: observationEncounter,\n inpatientEncounter: inpatientEncounter,\n outpatientStay: Interval[start of ED.period, Coalesce(start of inpatientEncounter.period, endOfStay)],\n inpatientStay: inpatientEncounter.period\n }\n\ndefine "Inpatient Encounter":\n [Encounter: CQMCommon."Encounter Inpatient"] E\n let observationEncounter: Last(\n [Encounter: CQMCommon."Observation Services"] O\n where O.period ends 1 hour or less on or before start of E.period\n sort by end of period\n ),\n visitStart: Coalesce(start of observationEncounter.period, start of E.period),\n edEncounter: Last(\n [Encounter: CQMCommon."Emergency Department Visit"] ED\n where ED.period ends 1 hour or less on or before visitStart\n sort by end of period\n ),\n outpatientStay:\n if observationEncounter is null and edEncounter is null then\n null\n else\n Interval[Coalesce(start of edEncounter.period, start of observationEncounter.period), start of E.period]\n return {\n edEncounter: edEncounter,\n observationEncounter: observationEncounter,\n inpatientEncounter: E,\n outpatientStay: outpatientStay,\n inpatientStay: E.period\n }\n\n// TODO: USCDI+ Quality/USCDI Gap (Specimen Collection Time)\n// NOTE: Can we use effectiveTime here rather than Specimen Collection Time\ndefine "Encounter With O-COB Result":\n "Outpatient Encounter" E\n let results: (\n "Bacteremia or Fungemia Result With Specimen" RS \n where RS.specimen.collection.collected.toInterval()\n during E.outpatientStay\n )\n where exists (results)\n return {\n edEncounter: E.edEncounter,\n observationEncounter: E.observationEncounter,\n inpatientEncounter: E.inpatientEncounter,\n outpatientStay: E.outpatientStay,\n inpatientStay: E.inpatientStay,\n indexDate: Min(results R return start of R.specimen.collection.collected.toInterval()),\n organisms: results R return R.result.value as CodeableConcept\n }\n\ndefine "Encounter With COB Result":\n "Inpatient Encounter" E\n let \n oCOB: "Encounter With O-COB Result" oCOBEncounter where E.inpatientEncounter.id = oCOBEncounter.inpatientEncounter.id,\n results: (\n "Bacteremia or Fungemia Result With Specimen" RS\n where RS.specimen.collection.collected.toInterval()\n during day of Interval[start of E.inpatientStay, start of E.inpatientStay + 3 days]\n and not exists (\n oCOB.organisms O\n where O.organismMatches(RS.result.value as CodeableConcept)\n )\n )\n where exists (results)\n return {\n edEncounter: E.edEncounter,\n observationEncounter: E.observationEncounter,\n inpatientEncounter: E.inpatientEncounter,\n outpatientStay: E.outpatientStay,\n inpatientStay: E.inpatientStay,\n indexDate: Min(results R return start of R.specimen.collection.collected.toInterval()),\n organisms: results R return R.result.value as CodeableConcept\n }\n\ndefine "Encounter With HOB Result":\n "Inpatient Encounter" E\n let \n oCOB: "Encounter With O-COB Result" oCOBEncounter where E.inpatientEncounter.id = oCOBEncounter.inpatientEncounter.id,\n COB: "Encounter With COB Result" COBEncounter where E.inpatientEncounter.id = COBEncounter.inpatientEncounter.id,\n // Guard the interval: for stays of 3 days or fewer, start + 4 days is after the\n // stay end, which would construct an inverted (invalid) interval and error.\n hospitalOnsetWindow:\n if duration in days of E.inpatientStay > 3\n then Interval[start of E.inpatientStay + 4 days, end of E.inpatientStay]\n else null as Interval<DateTime>,\n results: (\n "Bacteremia or Fungemia Result With Specimen" RS\n where RS.specimen.collection.collected.toInterval()\n during day of hospitalOnsetWindow\n and not exists (\n oCOB.organisms O\n where O.organismMatches(RS.result.value as CodeableConcept)\n )\n and not exists (\n COB.organisms O\n where O.organismMatches(RS.result.value as CodeableConcept)\n )\n )\n where duration in days of E.inpatientStay > 3\n and exists (results)\n return {\n edEncounter: E.edEncounter,\n observationEncounter: E.observationEncounter,\n inpatientEncounter: E.inpatientEncounter,\n outpatientStay: E.outpatientStay,\n inpatientStay: E.inpatientStay,\n indexDate: Min(results R return start of R.specimen.collection.collected.toInterval()),\n organisms: results R return R.result.value as CodeableConcept\n }\n\n\n/*\nMetric: O-COB Prevalence Rate\nScoring: Proportion\nNumerator: Number of outpatient O-COB events occurring within the measurement period\nDenominator: Number of outpatient (ED/OBS) encounters occurring within the measurement period\n*/\n\ndefine "Outpatient Encounter During Measurement Period":\n "Outpatient Encounter" O\n where O.outpatientStay overlaps "Measurement Period"\n\ndefine "O-COB Prevalence Rate Initial Population":\n "Outpatient Encounter During Measurement Period" O\n return O.edEncounter\n\ndefine "O-COB Prevalence Rate Denominator":\n "Outpatient Encounter During Measurement Period" O\n return O.edEncounter\n\ndefine "O-COB Prevlanece Rate Numerator":\n "Encounter With O-COB Result" OCOBEvent\n where OCOBEvent.indexDate during "Measurement Period"\n return OCOBEvent.edEncounter\n\n/*\nMetric: Inpatient COB Prevalence Rate\nScoring: Proportion\nNumerator: Number of inpatient COB events occurring within the measurement period\nDenominator: Number of inpatient stays where at least one of the first three inpatient calendar days falls within the measurement period\n*/\n\ndefine "Community Eligible Inpatient Encounter During Measurement Period":\n "Inpatient Encounter" I\n let communityEligible: Interval[start of I.inpatientStay, Min({ start of I.inpatientStay + 3 days, end of I.inpatientStay })]\n where communityEligible overlaps "Measurement Period"\n\ndefine "COB Prevalence Rate Initial Population":\n "Community Eligible Inpatient Encounter During Measurement Period" I\n return I.inpatientEncounter // Tricky... encounter normalization will address this\n\ndefine "COB Prevalence Rate Denominator":\n "Community Eligible Inpatient Encounter During Measurement Period" I\n return I.inpatientEncounter // Tricky... encounter normalization will address this\n\ndefine "COB Prevalence Rate Numerator":\n "Encounter With COB Result" COBEvent\n where COBEvent.indexDate during "Measurement Period"\n return COBEvent.inpatientEncounter \n\n/*\nMetric: HOB Crude Risk\nScoring: Proportion\nNumerator: Number of inpatient stays with at least one HOB event occurring within the measurement period\nDenominator: Number of inpatient stays where there are any inpatient days eligible for a hosptial-onset event during the measurement period\nNotes: The denominator for HOB admission risk will include only those inpatient stays who were eligible for an HOB event in the measurement period: \n 1. Stays where day 4 (or later) of their admission occurred during the measurement period. \n 2. If an event occurs, then a stay will not be included in the denominator of subsequent measurement periods.\n*/\n\ndefine "Hospital Eligible Inpatient Encounter During Measurement Period":\n "Inpatient Encounter" I\n // Guard the interval: for stays of 3 days or fewer, start + 4 days is after the\n // stay end, which would construct an inverted (invalid) interval and error. The\n // conditional also subsumes the duration > 3 eligibility check.\n let hospitalEligible:\n if duration in days of I.inpatientStay > 3\n then Interval[start of I.inpatientStay + 4 days, end of I.inpatientStay]\n else null as Interval<DateTime>\n where hospitalEligible overlaps "Measurement Period"\n and not exists (\n "Encounter With HOB Result" HOBEvent\n where HOBEvent.inpatientEncounter ~ I.inpatientEncounter\n and HOBEvent.indexDate before start of "Measurement Period"\n )\n\ndefine "HOB Crude Risk Initial Population":\n "Hospital Eligible Inpatient Encounter During Measurement Period" I\n return I.inpatientEncounter\n\ndefine "HOB Crude Risk Denominator":\n "Hospital Eligible Inpatient Encounter During Measurement Period" I\n return I.inpatientEncounter\n\ndefine "HOB Crude Risk Numerator":\n "Encounter With HOB Result" HOBEvent\n where HOBEvent.indexDate during "Measurement Period"\n return HOBEvent.inpatientEncounter\n\n/*\nMetric: HOB Incidence Density\nScoring: Ratio /100.d\nNumerator: Number of HOB events\nDenominator: Number of inpatient days eligible for a hospital-onset event during the measurement period\nNotes: Eligible patient days are defined as: Inpatient day 4 until discharge or index HOB event date\n*/\n\ndefine "HOB Incidence Density Initial Population":\n "Hospital Eligible Inpatient Encounter During Measurement Period" I\n return I.inpatientEncounter\n\ndefine "HOB Incidence Density Denominator":\n "Hospital Eligible Inpatient Encounter During Measurement Period" I\n return I.inpatientEncounter\n\ndefine function "HOB Incidence Density Denominator Observation"(encounter Encounter):\n days between start of encounter.period + 4 days\n and Min({\n ("Encounter With HOB Result" HOBEvent where HOBEvent.inpatientEncounter ~ encounter).single().indexDate,\n end of encounter.period\n })\n\ndefine "HOB Incidence Density Numerator":\n "Encounter With HOB Result" I\n return I.inpatientEncounter\n\n// Just counting, so return 1\ndefine function "HOB Incidence Density Numerator Observation"(encounter Encounter):\n 1\n\n</code></pre>\n </td>\n </tr>\n \n \n\n<tr>\n <th colspan=\"2\" scope=\"row\" class=\"row-header\">Generated using version 0.5.6-cibuild of the sample-content-ig Liquid templates</th>\n</tr>\n\n </tbody>\n </table>\n</div>"
},
"extension" : [
{
"url" : "http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm",
"valueInteger" : 1
},
{
"url" : "http://hl7.org/fhir/StructureDefinition/structuredefinition-wg",
"valueCode" : "cds"
},
{
"url" : "http://hl7.org/fhir/StructureDefinition/structuredefinition-standards-status",
"valueCode" : "informative"
}
],
"url" : "https://madie.cms.gov/Library/HOB",
"version" : "2026.1.0",
"name" : "HOB",
"title" : "HOB Elements and Logic",
"status" : "draft",
"experimental" : true,
"type" : {
"coding" : [
{
"system" : "http://terminology.hl7.org/CodeSystem/library-type",
"code" : "logic-library"
}
]
},
"date" : "2026-07-30T20:17:17+00:00",
"description" : "DRAFT Data elements used in the calculation of Hospital-onset Bacteremia and Fungemia measures.",
"topic" : [
{
"text" : "FHIR"
},
{
"text" : "CQL"
}
],
"content" : [
{
"contentType" : "text/cql",
"data" : "LyoKRHJhZnQgQ1FMIHJlcHJlc2VudGF0aW9uIG9mIEhvc3BpdGFsIE9uc2V0IEJhY3RlcmVtaWEgYW5kIEZ1bmdlbWlhIFN1cnZlaWxsYW5jZSBNZWFzdXJlCiovCmxpYnJhcnkgSE9CCgp1c2luZyBGSElSIHZlcnNpb24gJzQuMC4xJwoKaW5jbHVkZSBobDcuZmhpci51di5jcWwuRkhJUkhlbHBlcnMgdmVyc2lvbiAnNC4wLjEnIGNhbGxlZCBGSElSSGVscGVycwppbmNsdWRlIGhsNy5maGlyLnV2LmNxbC5GSElSQ29tbW9uIHZlcnNpb24gJzIuMC4wJyBjYWxsZWQgRkhJUkNvbW1vbgoKaW5jbHVkZSBDUU1Db21tb24gdmVyc2lvbiAnNS4xLjAwMCcgY2FsbGVkIENRTUNvbW1vbgppbmNsdWRlIEhPQk9yZ2FuaXNtVGF4b25vbXkKCnZhbHVlc2V0ICJCYWN0ZXJpYSBhbmQgRnVuZ2kgLSBIT0IgU3BlY2lmaWMiOiAnaHR0cHM6Ly9leGFtcGxlLm9yZy9maGlyL1ZhbHVlU2V0L2JhY3RlcmlhLWFuZC1mdW5naS1ob2Itc3BlY2lmaWMnCnZhbHVlc2V0ICJCYWN0ZXJpYWwgU2tpbiBDb21tZW5zYWxzIjogJ2h0dHA6Ly9jdHMubmxtLm5paC5nb3YvZmhpci9WYWx1ZVNldC8yLjE2Ljg0MC4xLjExNDIyMi4yNC43LjI4MScgdmVyc2lvbiAnMjAyNDA5MTgnIC8vIFdhcyAyMDI0MTAwMywgdmVyaWZ5CnZhbHVlc2V0ICJDb21tdW5pdHktYXNzb2NpYXRlZCBPcmdhbmlzbXMgLSBIT0IgU3BlY2lmaWMiOiAnaHR0cDovL2N0cy5ubG0ubmloLmdvdi9maGlyL1ZhbHVlU2V0LzIuMTYuODQwLjEuMTE0MjIyLjI0LjcuMTE3MCcgdmVyc2lvbiAnMjAyNTA5MzAnCnZhbHVlc2V0ICJCYWN0ZXJpYWwgYW5kIEZ1bmdhbCBCbG9vZCBDdWx0dXJlIFRlc3RzIjogJ2h0dHA6Ly9jdHMubmxtLm5paC5nb3YvZmhpci9WYWx1ZVNldC8yLjE2Ljg0MC4xLjExMzc2Mi4xLjQuMTE5MC42MycgdmVyc2lvbiAnMjAyMjA3MjEnCnZhbHVlc2V0ICJFbnRlcmFsIE1lZGljYXRpb24gUm91dGUiOiAnaHR0cDovL2N0cy5ubG0ubmloLmdvdi9maGlyL1ZhbHVlU2V0LzIuMTYuODQwLjEuMTEzNzYyLjEuNC4xMTkwLjc0JyB2ZXJzaW9uICcyMDI0MDYxOCcKdmFsdWVzZXQgIkludHJhdmVub3VzIE1lZGljYXRpb24gUm91dGUiOiAnaHR0cDovL2N0cy5ubG0ubmloLmdvdi9maGlyL1ZhbHVlU2V0LzIuMTYuODQwLjEuMTEzNzYyLjEuNC4xMTkwLjc1JyB2ZXJzaW9uICcyMDI0MDYxOCcKdmFsdWVzZXQgIlNwZWNpbWVuIFR5cGUgLSBCbG9vZCI6ICdodHRwOi8vY3RzLm5sbS5uaWguZ292L2ZoaXIvVmFsdWVTZXQvMi4xNi44NDAuMS4xMTQyMjIuMjQuNy4zMTUnIHZlcnNpb24gJzIwMjUwOTI5Jwp2YWx1ZXNldCAiQWJzb2x1dGUgTmV1dHJvcGhpbHMiOiAnaHR0cDovL2N0cy5ubG0ubmloLmdvdi9maGlyL1ZhbHVlU2V0LzIuMTYuODQwLjEuMTE0MjIyLjI0LjcuMTE3MycgdmVyc2lvbiAnMjAyNTA5MTMnCnZhbHVlc2V0ICJBbnRpbWljcm9iaWFsIE1lZGljYXRpb25zIC0gSS5WIEFudGliYWN0ZXJpYWxzIjogJ2h0dHA6Ly9jdHMubmxtLm5paC5nb3YvZmhpci9WYWx1ZVNldC8yLjE2Ljg0MC4xLjExNDIyMi4yNC43LjEyMjAnIHZlcnNpb24gJzIwMjYwMTIyJwp2YWx1ZXNldCAiQW50aW1pY3JvYmlhbCBNZWRpY2F0aW9ucyAtIE9yYWwgQW50aWJhY3RlcmlhbHMiOiAnaHR0cDovL2N0cy5ubG0ubmloLmdvdi9maGlyL1ZhbHVlU2V0LzIuMTYuODQwLjEuMTE0MjIyLjI0LjcuMTIyMCcgdmVyc2lvbiAnMjAyNTA4MTMnCnZhbHVlc2V0ICJBbnRpbWljcm9iaWFscyBmb3IgQmFjdGVyZW1pYSBhbmQgRnVuZ2VtaWEgU3VydmVpbGxhbmNlIE1vZHVsZSI6ICdodHRwOi8vY3RzLm5sbS5uaWguZ292L2ZoaXIvVmFsdWVTZXQvMi4xNi44NDAuMS4xMTQyMjIuMjQuNy4xMjIwJyB2ZXJzaW9uICcyMDI2MDIwNScKCnBhcmFtZXRlciAiTWVhc3VyZW1lbnQgUGVyaW9kIiBJbnRlcnZhbDxEYXRlVGltZT4gCiAgZGVmYXVsdCBJbnRlcnZhbFtAMjAyNi0wMS0wMVQwMDowMDowMC4wLCBAMjAyNi0wMS0zMVQyMzo1OTo1OS45OTldCgpjb250ZXh0IFBhdGllbnQKCi8qCkVEL09CUyBlbmNvdW50ZXI6IEFueSBwYXRpZW50IHZpc2l0IHRvIGFuIGVtZXJnZW5jeSBkZXBhcnRtZW50IChFRCkgb3Igb2JzZXJ2YXRpb24gKE9CUykgbG9jYXRpb24uIE9uZSBwYXRpZW50IHZpc2l0IGVxdWFscyBvbmUgZW5jb3VudGVyLiBFRC9PQlMgYXJlIGNvbnNpZGVyZWQgb3V0cGF0aWVudCBsb2NhdGlvbnMuCkhvc3BpdGFsIFN0YXk6IE5IU04gZGVmaW5lcyBhIGhvc3BpdGFsIHN0YXkgdG8gYmUgaW5jbHVzaXZlIG9mIGFueTogKGEpIEVEL09CUyBlbmNvdW50ZXJzLCAoYikgaW5wYXRpZW50IGFkbWlzc2lvbnMsIG9yIChjKSBFRC9PQlMgZW5jb3VudGVycyB0aGF0IGxlYWQgdG8gaW5wYXRpZW50IGFkbWlzc2lvbnMgKHdpdGhpbiAxIGhvdXIgb2YgRUQvT0JTIGVuY291bnRlcnMpLgpJbnBhdGllbnQgYWRtaXNzaW9uOiBGb3IgTkhTTiByZXBvcnRpbmcgcHVycG9zZXMsIHRoZSDigJhkYXRlIGFkbWl0dGVkIHRvIHRoZSBmYWNpbGl0eeKAmSBpcyBob3NwaXRhbCBkYXkgKEhEKSAxLiBOSFNOIGRlZmluZXMgYW4gaW5wYXRpZW50IGFzIGFueSBwYXRpZW50IGNhcmVkIGZvciBvciBob3VzZWQgb24gYW4gaW5wYXRpZW50IGxvY2F0aW9uLiBMb2NhbCBzdGF0dXMgbWF5IGRpZmZlciBmcm9tIE5IU04gZGVmaW5pdGlvbjsgYWxsIGRheXMgc3BlbnQgaW4gYW4gaW5wYXRpZW50IHVuaXQsIHJlZ2FyZGxlc3Mgb2YgbG9jYWwgYWRtaXNzaW9uIHN0YXR1cyBhbmQvb3IgYmlsbGluZyBzdGF0dXMgYXJlIGluY2x1ZGVkIGluIHRoZSBjb3VudHMgb2YgYWRtaXNzaW9ucyBhbmQgaW5wYXRpZW50IGRheXMuIEZvciBOSFNOIHJlcG9ydGluZyBwdXJwb3NlcywgdGhlIGRhdGUgYWRtaXR0ZWQgdG8gdGhlIGZhY2lsaXR5IGlzIHRoZSBjYWxlbmRhciBkYXRlIHRoYXQgdGhlIHBhdGllbnQgcGh5c2ljYWxseSBsb2NhdGVzIHRvIGFuIGlucGF0aWVudCBsb2NhdGlvbi4KTWVhc3VyZW1lbnQgUGVyaW9kOiBUaW1lIHBlcmlvZCBzZWxlY3RlZCBmb3IgcmVwb3J0IGdlbmVyYXRpb24vbWV0cmljIGNhbGN1bGF0aW9uCkFkdWx0OiBQYXRpZW50cyB3aG8gYXJlIOKJpTE4IHllYXJzIG9sZCBvbiB0aGUgY2FsZW5kYXIgZGF5IG9mIHRoZSBzdGFydCBvZiB0aGUgSG9zcGl0YWwgU3RheQpQZWRpYXRyaWM6IFBhdGllbnRzIHdobyBhcmUgPCAxOCB5ZWFycyBvbGQgb24gdGhlIGNhbGVuZGFyIGRheSBvZiB0aGUgc3RhcnQgb2YgdGhlIEhvc3BpdGFsIFN0YXkKTklDVTogUGF0aWVudHMgd2hvIGFyZSBob3VzZWQgaW4gYSBOSUNVIGxvY2F0aW9uIGF0IHRoZSB0aW1lIG9mIGluZGV4IGJsb29kIGN1bHR1cmUgY29sbGVjdGlvbgpPbmNvbG9neS9OZXV0cm9wZW5pYTogUGF0aWVudCBlaXRoZXIgMSkgbG9jYXRlZCBpbiBhbiBPbmNvbG9neSB3YXJkLCBvciAyKSB3aXRoIG5ldXRyb3BlbmlhIGRlZmluZSBhbiBhYnNvbHV0ZSBuZXV0cm9waGlsIGNvdW50IChBTkMpIDwxMDAwIGNlbGwvbWljcm9MIG9ic2VydmVkIGZvciDiiaUyIGRheXMgaW4gYSArLy0gNy1kYXkgd2luZG93IHBlcmlvZCBhcm91bmQgdGhlIGluZGV4IGJsb29kIGN1bHR1cmUKTy1DT0I6IE91dHBhdGllbnQgQ29tbXVuaXR5LW9uc2V0IEJhY3RlcmVtaWEgJiBGdW5nZW1pYSBFdmVudApDT0I6IENvbW11bml0eS1vbnNldCBCYWN0ZXJlbWlhICYgRnVuZ2VtaWEgRXZlbnQKSE9COiBIb3NwaXRhbC1vbnNldCBCYWN0ZXJlbWlhICYgRnVuZ2VtaWEgRXZlbnQKKi8KCmRlZmluZSAiQmFjdGVyaWFsIGFuZCBGdW5nYWwgQmxvb2QgQ3VsdHVyZSBUZXN0IFJlc3VsdHMiOgogIFtPYnNlcnZhdGlvbjogIkJhY3RlcmlhbCBhbmQgRnVuZ2FsIEJsb29kIEN1bHR1cmUgVGVzdHMiXSBPCiAgICB3aGVyZSBPLmlzTGFib3JhdG9yeSgpCiAgICAgIGFuZCBPLmlzUmVzdWx0ZWQoKQoKZGVmaW5lICJCYWN0ZXJlbWlhIG9yIEZ1bmdlbWlhIFJlc3VsdCI6CiAgIkJhY3RlcmlhbCBhbmQgRnVuZ2FsIEJsb29kIEN1bHR1cmUgVGVzdCBSZXN1bHRzIiBSCiAgICB3aGVyZSAoKFIudmFsdWUgYXMgQ29kZWFibGVDb25jZXB0KSBpbiAiQmFjdGVyaWEgYW5kIEZ1bmdpIC0gSE9CIFNwZWNpZmljIikKICAgICAgYW5kIG5vdCAoKFIudmFsdWUgYXMgQ29kZWFibGVDb25jZXB0KSBpbiAiQmFjdGVyaWFsIFNraW4gQ29tbWVuc2FscyIpCgpkZWZpbmUgIkJhY3RlcmVtaWEgb3IgRnVuZ2VtaWEgUmVzdWx0IFdpdGggU3BlY2ltZW4iOgogIGZyb20KICAgICJCYWN0ZXJlbWlhIG9yIEZ1bmdlbWlhIFJlc3VsdCIgUiwKICAgIFtTcGVjaW1lbjogIlNwZWNpbWVuIFR5cGUgLSBCbG9vZCJdIFMKICAgIHdoZXJlIFIuc3BlY2ltZW4ucmVmZXJlbmNlcyhTKQogICAgcmV0dXJuIHsKICAgICAgcmVzdWx0OiBSLAogICAgICBzcGVjaW1lbjogUwogICAgfQoKLy8gQXNzZXJ0aW9uIGlzIHRoYXQgdGhlcmUgaXMgbmV2ZXIgbW9yZSB0aGFuIG9uZSBFRC9PYnNlcnZhdGlvbiBwcmVjZWRpbmcgYW4gaW5wYXRpZW50IHN0YXkKLy8gaS5lLiBFRCAtPiBFRCAtPiBJbnBhdGllbnQsIEVEIC0+IE9ic2VydmF0aW9uIC0+IEVEIC0+IElucGF0aWVudCwgT2JzZXJ2YXRpb24gLT4gSW5wYXRpZW50IGFyZSBhbGwgY29tYmluYXRpb25zIHRoYXQgd2lsbCBuZXZlciBhcHBlYXIKLy8gVE9ETzogVGhpcyBkb2VzIG5vdCBjdXJyZW50bHkgaG9sZCBmb3IgcmVhbC13b3JsZCBkYXRhLCBuZWVkIHRvIGJ1aWxkIGVuY291bnRlciBub3JtYWxpemF0aW9uIGxvZ2ljCi8vIE5vdGUgYWxzbyB0aGF0IEVuY291bnRlci5jbGFzc0hpc3RvcnkgaXMgbm90IGRlZmluZWQsIHNvIEVuY291bnRlci5ob3NwaXRhbGl6YXRpb24ubG9jYXRpb24gd2lsbCBoYXZlIGEgbW9yZSBhY2N1cmF0ZSByZXByZXNlbnRhdGlvbiBvZiBjbGFzcyBvdmVyIHRpbWUKZGVmaW5lICJPdXRwYXRpZW50IEVuY291bnRlciI6CiAgW0VuY291bnRlcjogQ1FNQ29tbW9uLiJFbWVyZ2VuY3kgRGVwYXJ0bWVudCBWaXNpdCJdIEVECiAgICBsZXQgb2JzZXJ2YXRpb25FbmNvdW50ZXI6IEZpcnN0KAogICAgICBbRW5jb3VudGVyOiBDUU1Db21tb24uIk9ic2VydmF0aW9uIFNlcnZpY2VzIl0gTwogICAgICAgIHdoZXJlIE8ucGVyaW9kIHN0YXJ0cyAxIGhvdXIgb3IgbGVzcyBvbiBvciBiZWZvcmUgZW5kIG9mIEVELnBlcmlvZAogICAgICAgIHNvcnQgYnkgc3RhcnQgb2YgcGVyaW9kCiAgICApLAogICAgZW5kT2ZTdGF5OiBDb2FsZXNjZShlbmQgb2Ygb2JzZXJ2YXRpb25FbmNvdW50ZXIucGVyaW9kLCBlbmQgb2YgRUQucGVyaW9kKSwKICAgIGlucGF0aWVudEVuY291bnRlcjogRmlyc3QoCiAgICAgIFtFbmNvdW50ZXI6IENRTUNvbW1vbi4iRW5jb3VudGVyIElucGF0aWVudCJdIEUKICAgICAgICB3aGVyZSBFLnBlcmlvZCBzdGFydHMgMSBob3VyIG9yIGxlc3Mgb24gb3IgYmVmb3JlIGVuZE9mU3RheQogICAgKQogIHJldHVybiB7CiAgICBlZEVuY291bnRlcjogRUQsCiAgICBvYnNlcnZhdGlvbkVuY291bnRlcjogb2JzZXJ2YXRpb25FbmNvdW50ZXIsCiAgICBpbnBhdGllbnRFbmNvdW50ZXI6IGlucGF0aWVudEVuY291bnRlciwKICAgIG91dHBhdGllbnRTdGF5OiBJbnRlcnZhbFtzdGFydCBvZiBFRC5wZXJpb2QsIENvYWxlc2NlKHN0YXJ0IG9mIGlucGF0aWVudEVuY291bnRlci5wZXJpb2QsIGVuZE9mU3RheSldLAogICAgaW5wYXRpZW50U3RheTogaW5wYXRpZW50RW5jb3VudGVyLnBlcmlvZAogIH0KCmRlZmluZSAiSW5wYXRpZW50IEVuY291bnRlciI6CiAgW0VuY291bnRlcjogQ1FNQ29tbW9uLiJFbmNvdW50ZXIgSW5wYXRpZW50Il0gRQogICAgbGV0IG9ic2VydmF0aW9uRW5jb3VudGVyOiBMYXN0KAogICAgICBbRW5jb3VudGVyOiBDUU1Db21tb24uIk9ic2VydmF0aW9uIFNlcnZpY2VzIl0gTwogICAgICAgIHdoZXJlIE8ucGVyaW9kIGVuZHMgMSBob3VyIG9yIGxlc3Mgb24gb3IgYmVmb3JlIHN0YXJ0IG9mIEUucGVyaW9kCiAgICAgICAgc29ydCBieSBlbmQgb2YgcGVyaW9kCiAgICApLAogICAgdmlzaXRTdGFydDogQ29hbGVzY2Uoc3RhcnQgb2Ygb2JzZXJ2YXRpb25FbmNvdW50ZXIucGVyaW9kLCBzdGFydCBvZiBFLnBlcmlvZCksCiAgICBlZEVuY291bnRlcjogTGFzdCgKICAgICAgW0VuY291bnRlcjogQ1FNQ29tbW9uLiJFbWVyZ2VuY3kgRGVwYXJ0bWVudCBWaXNpdCJdIEVECiAgICAgICAgd2hlcmUgRUQucGVyaW9kIGVuZHMgMSBob3VyIG9yIGxlc3Mgb24gb3IgYmVmb3JlIHZpc2l0U3RhcnQKICAgICAgICBzb3J0IGJ5IGVuZCBvZiBwZXJpb2QKICAgICksCiAgICBvdXRwYXRpZW50U3RheToKICAgICAgaWYgb2JzZXJ2YXRpb25FbmNvdW50ZXIgaXMgbnVsbCBhbmQgZWRFbmNvdW50ZXIgaXMgbnVsbCB0aGVuCiAgICAgICAgbnVsbAogICAgICBlbHNlCiAgICAgICAgSW50ZXJ2YWxbQ29hbGVzY2Uoc3RhcnQgb2YgZWRFbmNvdW50ZXIucGVyaW9kLCBzdGFydCBvZiBvYnNlcnZhdGlvbkVuY291bnRlci5wZXJpb2QpLCBzdGFydCBvZiBFLnBlcmlvZF0KICAgIHJldHVybiB7CiAgICAgIGVkRW5jb3VudGVyOiBlZEVuY291bnRlciwKICAgICAgb2JzZXJ2YXRpb25FbmNvdW50ZXI6IG9ic2VydmF0aW9uRW5jb3VudGVyLAogICAgICBpbnBhdGllbnRFbmNvdW50ZXI6IEUsCiAgICAgIG91dHBhdGllbnRTdGF5OiBvdXRwYXRpZW50U3RheSwKICAgICAgaW5wYXRpZW50U3RheTogRS5wZXJpb2QKICAgIH0KCi8vIFRPRE86IFVTQ0RJKyBRdWFsaXR5L1VTQ0RJIEdhcCAoU3BlY2ltZW4gQ29sbGVjdGlvbiBUaW1lKQovLyBOT1RFOiBDYW4gd2UgdXNlIGVmZmVjdGl2ZVRpbWUgaGVyZSByYXRoZXIgdGhhbiBTcGVjaW1lbiBDb2xsZWN0aW9uIFRpbWUKZGVmaW5lICJFbmNvdW50ZXIgV2l0aCBPLUNPQiBSZXN1bHQiOgogICJPdXRwYXRpZW50IEVuY291bnRlciIgRQogICAgbGV0IHJlc3VsdHM6ICgKICAgICAgIkJhY3RlcmVtaWEgb3IgRnVuZ2VtaWEgUmVzdWx0IFdpdGggU3BlY2ltZW4iIFJTIAogICAgICAgIHdoZXJlIFJTLnNwZWNpbWVuLmNvbGxlY3Rpb24uY29sbGVjdGVkLnRvSW50ZXJ2YWwoKQogICAgICAgICAgZHVyaW5nIEUub3V0cGF0aWVudFN0YXkKICAgICkKICAgIHdoZXJlIGV4aXN0cyAocmVzdWx0cykKICAgIHJldHVybiB7CiAgICAgIGVkRW5jb3VudGVyOiBFLmVkRW5jb3VudGVyLAogICAgICBvYnNlcnZhdGlvbkVuY291bnRlcjogRS5vYnNlcnZhdGlvbkVuY291bnRlciwKICAgICAgaW5wYXRpZW50RW5jb3VudGVyOiBFLmlucGF0aWVudEVuY291bnRlciwKICAgICAgb3V0cGF0aWVudFN0YXk6IEUub3V0cGF0aWVudFN0YXksCiAgICAgIGlucGF0aWVudFN0YXk6IEUuaW5wYXRpZW50U3RheSwKICAgICAgaW5kZXhEYXRlOiBNaW4ocmVzdWx0cyBSIHJldHVybiBzdGFydCBvZiBSLnNwZWNpbWVuLmNvbGxlY3Rpb24uY29sbGVjdGVkLnRvSW50ZXJ2YWwoKSksCiAgICAgIG9yZ2FuaXNtczogcmVzdWx0cyBSIHJldHVybiBSLnJlc3VsdC52YWx1ZSBhcyBDb2RlYWJsZUNvbmNlcHQKICAgIH0KCmRlZmluZSAiRW5jb3VudGVyIFdpdGggQ09CIFJlc3VsdCI6CiAgIklucGF0aWVudCBFbmNvdW50ZXIiIEUKICAgIGxldCAKICAgICAgb0NPQjogIkVuY291bnRlciBXaXRoIE8tQ09CIFJlc3VsdCIgb0NPQkVuY291bnRlciB3aGVyZSBFLmlucGF0aWVudEVuY291bnRlci5pZCA9IG9DT0JFbmNvdW50ZXIuaW5wYXRpZW50RW5jb3VudGVyLmlkLAogICAgICByZXN1bHRzOiAoCiAgICAgICAgIkJhY3RlcmVtaWEgb3IgRnVuZ2VtaWEgUmVzdWx0IFdpdGggU3BlY2ltZW4iIFJTCiAgICAgICAgICB3aGVyZSBSUy5zcGVjaW1lbi5jb2xsZWN0aW9uLmNvbGxlY3RlZC50b0ludGVydmFsKCkKICAgICAgICAgICAgZHVyaW5nIGRheSBvZiBJbnRlcnZhbFtzdGFydCBvZiBFLmlucGF0aWVudFN0YXksIHN0YXJ0IG9mIEUuaW5wYXRpZW50U3RheSArIDMgZGF5c10KICAgICAgICAgICAgYW5kIG5vdCBleGlzdHMgKAogICAgICAgICAgICAgIG9DT0Iub3JnYW5pc21zIE8KICAgICAgICAgICAgICAgIHdoZXJlIE8ub3JnYW5pc21NYXRjaGVzKFJTLnJlc3VsdC52YWx1ZSBhcyBDb2RlYWJsZUNvbmNlcHQpCiAgICAgICAgICAgICkKICAgICkKICAgIHdoZXJlIGV4aXN0cyAocmVzdWx0cykKICAgIHJldHVybiB7CiAgICAgIGVkRW5jb3VudGVyOiBFLmVkRW5jb3VudGVyLAogICAgICBvYnNlcnZhdGlvbkVuY291bnRlcjogRS5vYnNlcnZhdGlvbkVuY291bnRlciwKICAgICAgaW5wYXRpZW50RW5jb3VudGVyOiBFLmlucGF0aWVudEVuY291bnRlciwKICAgICAgb3V0cGF0aWVudFN0YXk6IEUub3V0cGF0aWVudFN0YXksCiAgICAgIGlucGF0aWVudFN0YXk6IEUuaW5wYXRpZW50U3RheSwKICAgICAgaW5kZXhEYXRlOiBNaW4ocmVzdWx0cyBSIHJldHVybiBzdGFydCBvZiBSLnNwZWNpbWVuLmNvbGxlY3Rpb24uY29sbGVjdGVkLnRvSW50ZXJ2YWwoKSksCiAgICAgIG9yZ2FuaXNtczogcmVzdWx0cyBSIHJldHVybiBSLnJlc3VsdC52YWx1ZSBhcyBDb2RlYWJsZUNvbmNlcHQKICAgIH0KCmRlZmluZSAiRW5jb3VudGVyIFdpdGggSE9CIFJlc3VsdCI6CiAgIklucGF0aWVudCBFbmNvdW50ZXIiIEUKICAgIGxldCAKICAgICAgb0NPQjogIkVuY291bnRlciBXaXRoIE8tQ09CIFJlc3VsdCIgb0NPQkVuY291bnRlciB3aGVyZSBFLmlucGF0aWVudEVuY291bnRlci5pZCA9IG9DT0JFbmNvdW50ZXIuaW5wYXRpZW50RW5jb3VudGVyLmlkLAogICAgICBDT0I6ICJFbmNvdW50ZXIgV2l0aCBDT0IgUmVzdWx0IiBDT0JFbmNvdW50ZXIgd2hlcmUgRS5pbnBhdGllbnRFbmNvdW50ZXIuaWQgPSBDT0JFbmNvdW50ZXIuaW5wYXRpZW50RW5jb3VudGVyLmlkLAogICAgICAvLyBHdWFyZCB0aGUgaW50ZXJ2YWw6IGZvciBzdGF5cyBvZiAzIGRheXMgb3IgZmV3ZXIsIHN0YXJ0ICsgNCBkYXlzIGlzIGFmdGVyIHRoZQogICAgICAvLyBzdGF5IGVuZCwgd2hpY2ggd291bGQgY29uc3RydWN0IGFuIGludmVydGVkIChpbnZhbGlkKSBpbnRlcnZhbCBhbmQgZXJyb3IuCiAgICAgIGhvc3BpdGFsT25zZXRXaW5kb3c6CiAgICAgICAgaWYgZHVyYXRpb24gaW4gZGF5cyBvZiBFLmlucGF0aWVudFN0YXkgPiAzCiAgICAgICAgICB0aGVuIEludGVydmFsW3N0YXJ0IG9mIEUuaW5wYXRpZW50U3RheSArIDQgZGF5cywgZW5kIG9mIEUuaW5wYXRpZW50U3RheV0KICAgICAgICAgIGVsc2UgbnVsbCBhcyBJbnRlcnZhbDxEYXRlVGltZT4sCiAgICAgIHJlc3VsdHM6ICgKICAgICAgICAiQmFjdGVyZW1pYSBvciBGdW5nZW1pYSBSZXN1bHQgV2l0aCBTcGVjaW1lbiIgUlMKICAgICAgICAgIHdoZXJlIFJTLnNwZWNpbWVuLmNvbGxlY3Rpb24uY29sbGVjdGVkLnRvSW50ZXJ2YWwoKQogICAgICAgICAgICBkdXJpbmcgZGF5IG9mIGhvc3BpdGFsT25zZXRXaW5kb3cKICAgICAgICAgICAgYW5kIG5vdCBleGlzdHMgKAogICAgICAgICAgICAgIG9DT0Iub3JnYW5pc21zIE8KICAgICAgICAgICAgICAgIHdoZXJlIE8ub3JnYW5pc21NYXRjaGVzKFJTLnJlc3VsdC52YWx1ZSBhcyBDb2RlYWJsZUNvbmNlcHQpCiAgICAgICAgICAgICkKICAgICAgICAgICAgYW5kIG5vdCBleGlzdHMgKAogICAgICAgICAgICAgIENPQi5vcmdhbmlzbXMgTwogICAgICAgICAgICAgICAgd2hlcmUgTy5vcmdhbmlzbU1hdGNoZXMoUlMucmVzdWx0LnZhbHVlIGFzIENvZGVhYmxlQ29uY2VwdCkKICAgICAgICAgICAgKQogICAgKQogICAgd2hlcmUgZHVyYXRpb24gaW4gZGF5cyBvZiBFLmlucGF0aWVudFN0YXkgPiAzCiAgICAgIGFuZCBleGlzdHMgKHJlc3VsdHMpCiAgICByZXR1cm4gewogICAgICBlZEVuY291bnRlcjogRS5lZEVuY291bnRlciwKICAgICAgb2JzZXJ2YXRpb25FbmNvdW50ZXI6IEUub2JzZXJ2YXRpb25FbmNvdW50ZXIsCiAgICAgIGlucGF0aWVudEVuY291bnRlcjogRS5pbnBhdGllbnRFbmNvdW50ZXIsCiAgICAgIG91dHBhdGllbnRTdGF5OiBFLm91dHBhdGllbnRTdGF5LAogICAgICBpbnBhdGllbnRTdGF5OiBFLmlucGF0aWVudFN0YXksCiAgICAgIGluZGV4RGF0ZTogTWluKHJlc3VsdHMgUiByZXR1cm4gc3RhcnQgb2YgUi5zcGVjaW1lbi5jb2xsZWN0aW9uLmNvbGxlY3RlZC50b0ludGVydmFsKCkpLAogICAgICBvcmdhbmlzbXM6IHJlc3VsdHMgUiByZXR1cm4gUi5yZXN1bHQudmFsdWUgYXMgQ29kZWFibGVDb25jZXB0CiAgICB9CgoKLyoKTWV0cmljOiBPLUNPQiBQcmV2YWxlbmNlIFJhdGUKU2NvcmluZzogUHJvcG9ydGlvbgpOdW1lcmF0b3I6IE51bWJlciBvZiBvdXRwYXRpZW50IE8tQ09CIGV2ZW50cyBvY2N1cnJpbmcgd2l0aGluIHRoZSBtZWFzdXJlbWVudCBwZXJpb2QKRGVub21pbmF0b3I6IE51bWJlciBvZiBvdXRwYXRpZW50IChFRC9PQlMpIGVuY291bnRlcnMgb2NjdXJyaW5nIHdpdGhpbiB0aGUgbWVhc3VyZW1lbnQgcGVyaW9kCiovCgpkZWZpbmUgIk91dHBhdGllbnQgRW5jb3VudGVyIER1cmluZyBNZWFzdXJlbWVudCBQZXJpb2QiOgogICJPdXRwYXRpZW50IEVuY291bnRlciIgTwogICAgd2hlcmUgTy5vdXRwYXRpZW50U3RheSBvdmVybGFwcyAiTWVhc3VyZW1lbnQgUGVyaW9kIgoKZGVmaW5lICJPLUNPQiBQcmV2YWxlbmNlIFJhdGUgSW5pdGlhbCBQb3B1bGF0aW9uIjoKICAiT3V0cGF0aWVudCBFbmNvdW50ZXIgRHVyaW5nIE1lYXN1cmVtZW50IFBlcmlvZCIgTwogICAgcmV0dXJuIE8uZWRFbmNvdW50ZXIKCmRlZmluZSAiTy1DT0IgUHJldmFsZW5jZSBSYXRlIERlbm9taW5hdG9yIjoKICAiT3V0cGF0aWVudCBFbmNvdW50ZXIgRHVyaW5nIE1lYXN1cmVtZW50IFBlcmlvZCIgTwogICAgcmV0dXJuIE8uZWRFbmNvdW50ZXIKCmRlZmluZSAiTy1DT0IgUHJldmxhbmVjZSBSYXRlIE51bWVyYXRvciI6CiAgIkVuY291bnRlciBXaXRoIE8tQ09CIFJlc3VsdCIgT0NPQkV2ZW50CiAgICB3aGVyZSBPQ09CRXZlbnQuaW5kZXhEYXRlIGR1cmluZyAiTWVhc3VyZW1lbnQgUGVyaW9kIgogICAgcmV0dXJuIE9DT0JFdmVudC5lZEVuY291bnRlcgoKLyoKTWV0cmljOiBJbnBhdGllbnQgQ09CIFByZXZhbGVuY2UgUmF0ZQpTY29yaW5nOiBQcm9wb3J0aW9uCk51bWVyYXRvcjogTnVtYmVyIG9mIGlucGF0aWVudCBDT0IgZXZlbnRzIG9jY3VycmluZyB3aXRoaW4gdGhlIG1lYXN1cmVtZW50IHBlcmlvZApEZW5vbWluYXRvcjogTnVtYmVyIG9mIGlucGF0aWVudCBzdGF5cyB3aGVyZSBhdCBsZWFzdCBvbmUgb2YgdGhlIGZpcnN0IHRocmVlIGlucGF0aWVudCBjYWxlbmRhciBkYXlzIGZhbGxzIHdpdGhpbiB0aGUgbWVhc3VyZW1lbnQgcGVyaW9kCiovCgpkZWZpbmUgIkNvbW11bml0eSBFbGlnaWJsZSBJbnBhdGllbnQgRW5jb3VudGVyIER1cmluZyBNZWFzdXJlbWVudCBQZXJpb2QiOgogICJJbnBhdGllbnQgRW5jb3VudGVyIiBJCiAgICBsZXQgY29tbXVuaXR5RWxpZ2libGU6IEludGVydmFsW3N0YXJ0IG9mIEkuaW5wYXRpZW50U3RheSwgTWluKHsgc3RhcnQgb2YgSS5pbnBhdGllbnRTdGF5ICsgMyBkYXlzLCBlbmQgb2YgSS5pbnBhdGllbnRTdGF5IH0pXQogICAgd2hlcmUgY29tbXVuaXR5RWxpZ2libGUgb3ZlcmxhcHMgIk1lYXN1cmVtZW50IFBlcmlvZCIKCmRlZmluZSAiQ09CIFByZXZhbGVuY2UgUmF0ZSBJbml0aWFsIFBvcHVsYXRpb24iOgogICJDb21tdW5pdHkgRWxpZ2libGUgSW5wYXRpZW50IEVuY291bnRlciBEdXJpbmcgTWVhc3VyZW1lbnQgUGVyaW9kIiBJCiAgICByZXR1cm4gSS5pbnBhdGllbnRFbmNvdW50ZXIgLy8gVHJpY2t5Li4uIGVuY291bnRlciBub3JtYWxpemF0aW9uIHdpbGwgYWRkcmVzcyB0aGlzCgpkZWZpbmUgIkNPQiBQcmV2YWxlbmNlIFJhdGUgRGVub21pbmF0b3IiOgogICJDb21tdW5pdHkgRWxpZ2libGUgSW5wYXRpZW50IEVuY291bnRlciBEdXJpbmcgTWVhc3VyZW1lbnQgUGVyaW9kIiBJCiAgICByZXR1cm4gSS5pbnBhdGllbnRFbmNvdW50ZXIgLy8gVHJpY2t5Li4uIGVuY291bnRlciBub3JtYWxpemF0aW9uIHdpbGwgYWRkcmVzcyB0aGlzCgpkZWZpbmUgIkNPQiBQcmV2YWxlbmNlIFJhdGUgTnVtZXJhdG9yIjoKICAiRW5jb3VudGVyIFdpdGggQ09CIFJlc3VsdCIgQ09CRXZlbnQKICAgIHdoZXJlIENPQkV2ZW50LmluZGV4RGF0ZSBkdXJpbmcgIk1lYXN1cmVtZW50IFBlcmlvZCIKICAgIHJldHVybiBDT0JFdmVudC5pbnBhdGllbnRFbmNvdW50ZXIgIAoKLyoKTWV0cmljOiBIT0IgQ3J1ZGUgUmlzawpTY29yaW5nOiBQcm9wb3J0aW9uCk51bWVyYXRvcjogTnVtYmVyIG9mIGlucGF0aWVudCBzdGF5cyB3aXRoIGF0IGxlYXN0IG9uZSBIT0IgZXZlbnQgb2NjdXJyaW5nIHdpdGhpbiB0aGUgbWVhc3VyZW1lbnQgcGVyaW9kCkRlbm9taW5hdG9yOiBOdW1iZXIgb2YgaW5wYXRpZW50IHN0YXlzIHdoZXJlIHRoZXJlIGFyZSBhbnkgaW5wYXRpZW50IGRheXMgZWxpZ2libGUgZm9yIGEgaG9zcHRpYWwtb25zZXQgZXZlbnQgZHVyaW5nIHRoZSBtZWFzdXJlbWVudCBwZXJpb2QKTm90ZXM6IFRoZSBkZW5vbWluYXRvciBmb3IgSE9CIGFkbWlzc2lvbiByaXNrIHdpbGwgaW5jbHVkZSBvbmx5IHRob3NlIGlucGF0aWVudCBzdGF5cyB3aG8gd2VyZSBlbGlnaWJsZSBmb3IgYW4gSE9CIGV2ZW50IGluIHRoZSBtZWFzdXJlbWVudCBwZXJpb2Q6ICAKICAxLiBTdGF5cyB3aGVyZSBkYXkgNCAob3IgbGF0ZXIpIG9mIHRoZWlyIGFkbWlzc2lvbiBvY2N1cnJlZCBkdXJpbmcgdGhlIG1lYXN1cmVtZW50IHBlcmlvZC4gIAogIDIuIElmIGFuIGV2ZW50IG9jY3VycywgdGhlbiBhIHN0YXkgd2lsbCBub3QgYmUgaW5jbHVkZWQgaW4gdGhlIGRlbm9taW5hdG9yIG9mIHN1YnNlcXVlbnQgbWVhc3VyZW1lbnQgcGVyaW9kcy4KKi8KCmRlZmluZSAiSG9zcGl0YWwgRWxpZ2libGUgSW5wYXRpZW50IEVuY291bnRlciBEdXJpbmcgTWVhc3VyZW1lbnQgUGVyaW9kIjoKICAiSW5wYXRpZW50IEVuY291bnRlciIgSQogICAgLy8gR3VhcmQgdGhlIGludGVydmFsOiBmb3Igc3RheXMgb2YgMyBkYXlzIG9yIGZld2VyLCBzdGFydCArIDQgZGF5cyBpcyBhZnRlciB0aGUKICAgIC8vIHN0YXkgZW5kLCB3aGljaCB3b3VsZCBjb25zdHJ1Y3QgYW4gaW52ZXJ0ZWQgKGludmFsaWQpIGludGVydmFsIGFuZCBlcnJvci4gVGhlCiAgICAvLyBjb25kaXRpb25hbCBhbHNvIHN1YnN1bWVzIHRoZSBkdXJhdGlvbiA+IDMgZWxpZ2liaWxpdHkgY2hlY2suCiAgICBsZXQgaG9zcGl0YWxFbGlnaWJsZToKICAgICAgaWYgZHVyYXRpb24gaW4gZGF5cyBvZiBJLmlucGF0aWVudFN0YXkgPiAzCiAgICAgICAgdGhlbiBJbnRlcnZhbFtzdGFydCBvZiBJLmlucGF0aWVudFN0YXkgKyA0IGRheXMsIGVuZCBvZiBJLmlucGF0aWVudFN0YXldCiAgICAgICAgZWxzZSBudWxsIGFzIEludGVydmFsPERhdGVUaW1lPgogICAgd2hlcmUgaG9zcGl0YWxFbGlnaWJsZSBvdmVybGFwcyAiTWVhc3VyZW1lbnQgUGVyaW9kIgogICAgICBhbmQgbm90IGV4aXN0cyAoCiAgICAgICAgIkVuY291bnRlciBXaXRoIEhPQiBSZXN1bHQiIEhPQkV2ZW50CiAgICAgICAgICB3aGVyZSBIT0JFdmVudC5pbnBhdGllbnRFbmNvdW50ZXIgfiBJLmlucGF0aWVudEVuY291bnRlcgogICAgICAgICAgICBhbmQgSE9CRXZlbnQuaW5kZXhEYXRlIGJlZm9yZSBzdGFydCBvZiAiTWVhc3VyZW1lbnQgUGVyaW9kIgogICAgICApCgpkZWZpbmUgIkhPQiBDcnVkZSBSaXNrIEluaXRpYWwgUG9wdWxhdGlvbiI6CiAgIkhvc3BpdGFsIEVsaWdpYmxlIElucGF0aWVudCBFbmNvdW50ZXIgRHVyaW5nIE1lYXN1cmVtZW50IFBlcmlvZCIgSQogICAgcmV0dXJuIEkuaW5wYXRpZW50RW5jb3VudGVyCgpkZWZpbmUgIkhPQiBDcnVkZSBSaXNrIERlbm9taW5hdG9yIjoKICAiSG9zcGl0YWwgRWxpZ2libGUgSW5wYXRpZW50IEVuY291bnRlciBEdXJpbmcgTWVhc3VyZW1lbnQgUGVyaW9kIiBJCiAgICByZXR1cm4gSS5pbnBhdGllbnRFbmNvdW50ZXIKCmRlZmluZSAiSE9CIENydWRlIFJpc2sgTnVtZXJhdG9yIjoKICAiRW5jb3VudGVyIFdpdGggSE9CIFJlc3VsdCIgSE9CRXZlbnQKICAgIHdoZXJlIEhPQkV2ZW50LmluZGV4RGF0ZSBkdXJpbmcgIk1lYXN1cmVtZW50IFBlcmlvZCIKICAgIHJldHVybiBIT0JFdmVudC5pbnBhdGllbnRFbmNvdW50ZXIKCi8qCk1ldHJpYzogSE9CIEluY2lkZW5jZSBEZW5zaXR5ClNjb3Jpbmc6IFJhdGlvIC8xMDAuZApOdW1lcmF0b3I6IE51bWJlciBvZiBIT0IgZXZlbnRzCkRlbm9taW5hdG9yOiBOdW1iZXIgb2YgaW5wYXRpZW50IGRheXMgZWxpZ2libGUgZm9yIGEgaG9zcGl0YWwtb25zZXQgZXZlbnQgZHVyaW5nIHRoZSBtZWFzdXJlbWVudCBwZXJpb2QKTm90ZXM6IEVsaWdpYmxlIHBhdGllbnQgZGF5cyBhcmUgZGVmaW5lZCBhczogSW5wYXRpZW50IGRheSA0IHVudGlsIGRpc2NoYXJnZSBvciBpbmRleCBIT0IgZXZlbnQgZGF0ZQoqLwoKZGVmaW5lICJIT0IgSW5jaWRlbmNlIERlbnNpdHkgSW5pdGlhbCBQb3B1bGF0aW9uIjoKICAiSG9zcGl0YWwgRWxpZ2libGUgSW5wYXRpZW50IEVuY291bnRlciBEdXJpbmcgTWVhc3VyZW1lbnQgUGVyaW9kIiBJCiAgICByZXR1cm4gSS5pbnBhdGllbnRFbmNvdW50ZXIKCmRlZmluZSAiSE9CIEluY2lkZW5jZSBEZW5zaXR5IERlbm9taW5hdG9yIjoKICAiSG9zcGl0YWwgRWxpZ2libGUgSW5wYXRpZW50IEVuY291bnRlciBEdXJpbmcgTWVhc3VyZW1lbnQgUGVyaW9kIiBJCiAgICByZXR1cm4gSS5pbnBhdGllbnRFbmNvdW50ZXIKCmRlZmluZSBmdW5jdGlvbiAiSE9CIEluY2lkZW5jZSBEZW5zaXR5IERlbm9taW5hdG9yIE9ic2VydmF0aW9uIihlbmNvdW50ZXIgRW5jb3VudGVyKToKICBkYXlzIGJldHdlZW4gc3RhcnQgb2YgZW5jb3VudGVyLnBlcmlvZCArIDQgZGF5cwogICAgYW5kIE1pbih7CiAgICAgICgiRW5jb3VudGVyIFdpdGggSE9CIFJlc3VsdCIgSE9CRXZlbnQgd2hlcmUgSE9CRXZlbnQuaW5wYXRpZW50RW5jb3VudGVyIH4gZW5jb3VudGVyKS5zaW5nbGUoKS5pbmRleERhdGUsCiAgICAgIGVuZCBvZiBlbmNvdW50ZXIucGVyaW9kCiAgICB9KQoKZGVmaW5lICJIT0IgSW5jaWRlbmNlIERlbnNpdHkgTnVtZXJhdG9yIjoKICAiRW5jb3VudGVyIFdpdGggSE9CIFJlc3VsdCIgSQogICAgcmV0dXJuIEkuaW5wYXRpZW50RW5jb3VudGVyCgovLyBKdXN0IGNvdW50aW5nLCBzbyByZXR1cm4gMQpkZWZpbmUgZnVuY3Rpb24gIkhPQiBJbmNpZGVuY2UgRGVuc2l0eSBOdW1lcmF0b3IgT2JzZXJ2YXRpb24iKGVuY291bnRlciBFbmNvdW50ZXIpOgogIDEKCg=="
}
]
}