WHO Clinical Care in Crisis Implementation Guide for Children
0.1.0 - ci-build

WHO Clinical Care in Crisis Implementation Guide for Children - Local Development build (v0.1.0). See the Directory of published versions

: CHEBase - XML Representation

Active as of 2023-10-04

Raw xml | Download



<Library xmlns="http://hl7.org/fhir">
  <id value="chebase"/>
  <text>
    <status value="generated"/>
    <div xmlns="http://www.w3.org/1999/xhtml"><h2>Related Artifacts</h2><table class="grid"><tr><td>depends-on</td><td><code>http://fhir.org/guides/who/anc-cds/Library/FHIRHelpers</code></td></tr></table><h2>Parameters</h2><table class="grid"><tr><td>encounterid</td><td>in</td><td/><td/><td>string</td></tr></table><h2>Data Requirements</h2><table class="grid"><tr><td colspan="2"><b>Type</b>: <a href="http://hl7.org/fhir/R4/patient.html">Patient</a> (<a href="http://hl7.org/fhir/R4/patient.html">Patient</a>)</td></tr></table><table class="grid"><tr><td colspan="2"><b>Type</b>: <a href="http://hl7.org/fhir/R4/encounter.html">Encounter</a> (<a href="http://hl7.org/fhir/R4/encounter.html">Encounter</a>)</td></tr></table><h2>Contents</h2><p><code>text/cql</code></p><pre><code class="language-sql">/*nter&quot;
@author: Patrick Delcroix
@description: This library is part of the project CHE Project, its allows standardisation for the observation processing
*/

library chebase version '1.0.313+build.456'

using FHIR version '4.0.1'

include FHIRHelpers version '4.0.1'

parameter &quot;encounterid&quot; String
//parameter &quot;Encounter&quot; Encounter$
codesystem &quot;RoleCodeSystem&quot; : 'https://fhir.dk.swisstph-mis.ch/matchbox/fhir/CodeSystem/emcare-custom-codes'
code &quot;Mother&quot;: 'MTH' from &quot;RoleCodeSystem&quot;

context Patient

//define encounterid:
//  &quot;Encounter&quot;.id




define &quot;Yes&quot;:
  true

define &quot;No&quot;:
  false 


define function IsInEncounter(ref FHIR.Reference):
    case
    when encounterid = ref.id then true
    when encounterid = Last(Split(ref.reference, '/')) then true
   // when ref.identifier is not null and id = ref.identifier.id then true
    else false
end

define getEncounters:
    [Encounter] E 
      where E.id = &quot;encounterid&quot;
        return E

define getEncounter:
    singleton from getEncounters

define function CHEExtensions(element Patient, id String):
  element.extension E
      where E.url = ('https://fhir.dk.swisstph-mis.ch/matchbox/fhir/StructureDefinition/' + id)
      return E

define function CHEExtension(element Patient, id String):
  singleton from CHEExtensions(element, id)

define function CHEExtensions(element Encounter, id String):
  element.extension E
      where E.url = ('https://fhir.dk.swisstph-mis.ch/matchbox/fhir/StructureDefinition/' + id)
      return E


define function postcordinationExtension(element Condition, postcordination List&lt;String&gt;):
  element.extension E
      where E.url = ('https://fhir.dk.swisstph-mis.ch/matchbox/fhir/StructureDefinition/postcordination')
      and E.value in postcordination


define function CHEExtension(element Encounter, id String):
  singleton from CHEExtensions(element, id)

define getPrimaryCareGiverReference:
  CHEExtension(Patient, 'primarycaregiver').value

define getPrimaryCareGiver:
  [RelatedPerson] RP where RP.id = Last(Split(getPrimaryCareGiverReference.reference, '/'))
    return RP

define isMotherPrimaryCareGiver:
  getPrimaryCareGiver is not null and Exists(getPrimaryCareGiver.relationship r where r ~ &quot;Mother&quot;)

define &quot;Biological Mother Vital Status&quot;:
  CHEExtension(Patient, 'motherVitalStatus').value
  
define &quot;Biological Father Vital Status&quot;:
  CHEExtension(Patient, 'fatherVitalStatus').value
// person accompanying the child is a participant with a null type
define getRelatedPersonReferenceAccompanyingTheChild:
  Coalesce(First(getEncounter.participant P where not exists(P.type) ).individual, getPrimaryCareGiverReference)

define getRelatedPersonsAccompanyingTheChild:
  [RelatedPerson] RP where RP.id = Last(Split(getRelatedPersonReferenceAccompanyingTheChild.reference, '/'))
    return RP


define getRelatedPersonAccompanyingTheChild:
  singleton from getRelatedPersonsAccompanyingTheChild


define &quot;Person accompanying child today's Relationship to Client&quot;:
//WORKARROUND   getRelatedPersonAccompanyingTheChild.relationship
  CHEExtension(getEncounter, 'motherpresent').value





define function getValue(O Observation):
  case  
      when  O is null then null
      when O.value is CodeableConcept then Coalesce(First(O.value.coding C where C.system  = 'https://fhir.dk.swisstph-mis.ch/matchbox/fhir/CodeSystem/che-custom-codes'), First(O.value.coding))
      else O.value
  end


define function assesObservation(O Observation):
  case  
      when  O is null then null
      when  O.status in  {'cancelled'} then false
      when O.value is null then  true
      else O.value
  end
/*      
define function GetObservationDuringEncounter(idlist List&lt;System.Code&gt;):
  if GetObservationDuringEncounterDone(idlist ) is null then 
      GetObservationDuringEncounterDone(idlist )
  else
    GetObservationDuringEncounterNotFound(idlist )
*/

define function GetObservationDuringEncounter(id System.Code):
      First([Observation: id ] O
        where   IsInEncounter(O.encounter) 
        and O.status in { 'final', 'amended', 'corrected','cancelled'} 
        sort by issued.value desc) 

  /*
  this is commented for performance improvement, even if it hides a valid observation if there is an more recent unvalid one
  Coalesce(GetObservationDuringEncounterDone(id ), GetObservationDuringEncounterNotFound(id ))
  */
/*
define function GetObservationDuringEncounterDone(idlist List&lt;System.Code&gt;):
      Last([Observation: idlist ] O
        where   IsInEncounter(O.encounter) 
        and O.status in { 'final', 'amended', 'corrected'})
*/
define function GetObservationDuringEncounterDone(id System.Code):
      First([Observation: id ] O
        where   IsInEncounter(O.encounter) 
        and O.status in { 'final', 'amended', 'corrected'} 
        sort by issued.value desc) 


define function HasObservationCodeDuringEncounterDone(id System.Code, valueCode System.Code):
    
    Exists([Observation: id ] O
        where   IsInEncounter(O.encounter) 
        and O.status in { 'final', 'amended', 'corrected'}
        and O.value is FHIR.CodeableConcept
        and O.value ~ valueCode)

//Exists([Observation] O where O.status in { 'final', 'amended', 'corrected'} and O.value is FHIR.CodeableConcept   and Exists( O.value.coding C where C is FHIR.Coding and C.code = FHIR.code {value: 'CHE.B20S2.DE04'}) )&quot;

/*
define function GetObservationDuringEncounterNotFound(idlist List&lt;System.Code&gt;):
      Last([Observation: idlist] O
       where  IsInEncounter(O.encounter) 
          and O.status in {'cancelled'})
          */
define function GetObservationDuringEncounterNotFound(id System.Code):
      First([Observation: id] O
       where  IsInEncounter(O.encounter) 
          and O.status in {'cancelled'}
          sort by issued.value desc)
/*

define function GetNumberObservationDuringEncounter(idlist List&lt;System.Code&gt;):
  Count(
    [Observation: idlist] O
        where  IsInEncounter( O.encounter) 
        and O.status in { 'final', 'amended', 'corrected'})
*/
define function GetNumberObservationDuringEncounter(id System.Code):
  Count(
    [Observation: id] O
        where  IsInEncounter( O.encounter) 
        and O.status in { 'final', 'amended', 'corrected'})

// ************************   GetObsValue ************************/
/*
define function GetObsValue(idlist List&lt;System.Code&gt;):
    getValue(GetObservationDuringEncounter(idlist))

define function GetObsValue(id System.Code):
    getValue(GetObservationDuringEncounter({id}))
*/

define function GetObsValue(id System.Code):
    getValue(GetObservationDuringEncounter(id))

define function GetObsValue(id System.String, codesystem System.String):
    getValue(GetObservationDuringEncounter(coding(id, codesystem)))

define function GetObsValue(id System.String):
    getValue(GetObservationDuringEncounter(coding(id, 'https://fhir.dk.swisstph-mis.ch/matchbox/fhir/CodeSystem/che-custom-codes')))

define function HasObsValueCode(id System.String, value System.Code):
   HasObservationCodeDuringEncounterDone(coding(id, 'https://fhir.dk.swisstph-mis.ch/matchbox/fhir/CodeSystem/che-custom-codes') , value )
  
define function HasObsValueCode(id System.String, value System.String):
   HasObservationCodeDuringEncounterDone(coding(id, 'https://fhir.dk.swisstph-mis.ch/matchbox/fhir/CodeSystem/che-custom-codes') , coding(value, 'https://fhir.dk.swisstph-mis.ch/matchbox/fhir/CodeSystem/che-custom-codes') )

define function HasObsValueCode(id System.Code, value System.String):
   HasObservationCodeDuringEncounterDone(id , coding(value, 'https://fhir.dk.swisstph-mis.ch/matchbox/fhir/CodeSystem/che-custom-codes') )

// ************************   HasObs ************************/
/*
define function HasObs(idlist List&lt;System.Code&gt;):
    assesObservation(GetObservationDuringEncounter(idlist))

define function HasObs(id System.Code):
    assesObservation(GetObservationDuringEncounter({id}))
*/
define function HasObs(id System.Code):
    assesObservation(GetObservationDuringEncounter(id))

define function HasObs(id System.String, codesystem System.String):
    assesObservation(GetObservationDuringEncounter(coding(id, codesystem)))

define function HasObs(id System.String):
    assesObservation(GetObservationDuringEncounter(coding(id)))

define function HasObs(id FHIR.code, codesystem System.String):
    assesObservation(GetObservationDuringEncounter(coding(id, codesystem)))
/*
define function GetHistoricObservation(idlist List&lt;System.Code&gt;, nbdays Integer):
  if GetHistoricObservationNotfound(idlist , codesystem , nbdays ) is null then 
      GetHistoricObservationNotfound(idlist , codesystem , nbdays )
  else
    GetHistoricObservationNotfound(idlist , codesystem , nbdays )
*/

define function GetHistoricObservation(id System.Code, nbdays Integer):
      First([Observation: id ] O
        where O.status in { 'final', 'amended', 'corrected','cancelled'} 
        and (difference in days between O.issued and Today()) &lt; nbdays 
        sort by issued.value desc )

  //Coalesce(GetHistoricObservationDone(id ,  nbdays ),  GetHistoricObservationNotfound(id  , nbdays ))
/*
define function GetHistoricObservationDone(idlist List&lt;System.Code&gt;, nbdays Integer):
      Last([Observation: idlist ] O
        where  O.status in { 'final', 'amended', 'corrected'}
        and (difference in days between O.issued and Today()) &lt; nbdays)
*/
define function GetHistoricObservationDone(id System.Code, nbdays Integer):
      First([Observation: id ] O
        where  O.status in { 'final', 'amended', 'corrected'}
        and (difference in days between O.issued and Today()) &lt; nbdays 
        sort by issued.value desc )

/*
define function GetHistoricObservationNotfound(idlist List&lt;System.Code&gt;, nbdays Integer):
      Last([Observation: idlist] O
        where  O.status in {'cancelled'}
*/
define function GetHistoricObservationNotfound(id System.Code, nbdays Integer):
      First([Observation: id] O
        where  O.status in {'cancelled'}
          and (difference in days between O.issued and Today()) &lt; nbdays 
        sort by issued.value desc)
// ************************   HasObsHistory ************************/

/*
define function HasObsHistory(idlist List&lt;System.Code&gt;,  nbdays Integer):
  assesObservation(GetHistoricObservation(idlist, nbdays))


 define function HasObsHistory(id System.Code, cnbdays Integer):
  assesObservation(GetHistoricObservation({id}, nbdays))
*/
define function HasObsHistory(id System.Code, nbdays Integer):
  assesObservation(GetHistoricObservation(id, nbdays))

define function HasObsHistory(id System.String, codesystem System.String, nbdays Integer):
  assesObservation(GetHistoricObservation(coding(id, codesystem), nbdays))


define function HasObsHistory(id System.String, nbdays Integer):
  assesObservation(GetHistoricObservation(coding(id), nbdays))

define function c(s System.String):
  FHIR.code { value: s }


define function coding(s System.String, url System.String):
  System.Code {
                code:  s ,
                system:  url 
            }

define function coding(s FHIR.code, url System.String):
  System.Code {
                code:  s.value ,
                system:  url 
            }

define function coding(s System.String):
  System.Code {
                code:  s ,
                system:  'https://fhir.dk.swisstph-mis.ch/matchbox/fhir/CodeSystem/che-custom-codes'
            }


define function ToUrl(s System.String):
  url {value:s}

define function ToIntC(b System.Boolean):
  case
  when b is null then 0
  when b = true then 1
  else 0
  end


// ************************   GetCond ************************/

define function GetConditions(id System.Code):
      [Condition: id] O
        where  IsInEncounter( O.encounter) 
        and exists(O.verificationStatus.coding C where C.code in {'unconfirmed', 'provisional', 'differential', 'confirmed'} 
        and C.system = 'http://terminology.hl7.org/CodeSystem/condition-ver-status')
        sort by recordedDate desc




define function GetStemCode(id System.String):
  coding(Split( id, '&amp;')[0])

define function GetPostcoordinationCode(id System.String):
  Tail(Split(id, '&amp;'))

define function GetCondition(id System.Code):
      First(GetConditions(id))


   
define function GetCondition(id System.Code, postcordination List&lt;System.String&gt;):
    First(
      [Condition: id] C
        where  IsInEncounter( C.encounter) 
        and exists(C.verificationStatus.coding cc where cc.code in {'unconfirmed', 'provisional', 'differential', 'confirmed'} 
        and cc.system = 'http://terminology.hl7.org/CodeSystem/condition-ver-status')
        and  postcordination is null or  Count(postcordinationExtension(C,postcordination)) &gt;= Count(postcordination)
        sort by recordedDate desc
    )


define function assesCondition(O Condition):
  if O is null then 
    false
  else
    true

define function GetCond(id System.Code):
  (GetCondition(id))

define function GetCond(id System.String, codesystem System.String):
  (GetCondition(coding(id, codesystem)))

define function GetCond(id System.String):
  (GetCondition(GetStemCode(id),GetPostcoordinationCode(id)))

// ************************   HasCond ************************/
/*
define function HasCond(idlist List&lt;System.Code&gt;):
  assesCondition(GetCondition(idlist))


3518GetCondition(id))
*/
define function HasCond(id System.String, codesystem System.String):
  assesCondition(GetCondition(coding(id, codesystem)))

define function HasCond(id System.String):
  assesCondition(GetCondition(coding(id)))

define function HasCond(id System.Code):
  assesCondition(GetCondition(id))

// ************************   PatientHasHistoryOfCondition ************************/
/*
define function GetHistoricCondition(idlist List&lt;System.Code&gt;,  nbdays Integer):
      Last([Condition: idlist] O
        where  (difference in days between O.recordedDate and Today()) &lt; nbdays
        and exists(O.verificationStatus.coding C where C.code in {'unconfirmed', 'provisional', 'differential', 'confirmed'} 
        and C.system = 'http://terminology.hl7.org/CodeSystem/condition-ver-status'))
*/

define function GetHistoricCondition(id System.Code,  nbdays Integer):
      First([Condition: id] O
        where  (difference in days between O.recordedDate and Today()) &lt; nbdays
        and exists(O.verificationStatus.coding C where C.code in {'unconfirmed', 'provisional', 'differential', 'confirmed'} 
        and C.system = 'http://terminology.hl7.org/CodeSystem/condition-ver-status') 
        sort by recordedDate desc)




/*
define function HasCondHistory(idlist List&lt;System.Code&gt;,  nbdays Integer):
  assesCondition(GetHistoricCondition(idlist,  nbdays))


define function HasCondHistory(id System.Code,  nbdays Integer):
  assesCondition(GetHistoricCondition({id}, nbdays))
*/
define function HasCondHistory(id System.Code, nbdays Integer):
  assesCondition(GetHistoricCondition(id,  nbdays))

define function HasCondHistory(id System.String, codesystem System.String, nbdays Integer):
  assesCondition(GetHistoricCondition(coding(id,codesystem),nbdays))


define function HasCondHistory(id System.String, nbdays Integer):
  assesCondition(GetHistoricCondition(coding(id),  nbdays))



//define function PatientHasConditionDuringEncounter(id String, codesystem url, duration Integer)):

//define function PatientHasConditionFromValueSetDuringEncounter(id String, codesystem url, duration Integer)):

//define function PatientHasHsistoryCondition(id String,codesystem url , duration Integer):
//define function PatientHasHsistoryConditionFromValueSet(id String,codesystem url , duration Integer):


// PatientHasSymptom(&quot;symptom name&quot;): symptom in the encounter


// PatientLastMeasureOf(&quot;measure name&quot;): measure in the encounter

// PatientLastHistoricMeasureOf(&quot;measure name&quot;, duration): measure in the patient history during duration

// PatientHasDiagnostic(&quot;Diagnostic name&quot; ): Diagnostic in the encounter

// PatientHasHistoryOfDiagnostic(&quot;Diagnostic name&quot;, duration ): Diagnostic in the patient history during duration

// PatientHasProposedorConfirmedDianostic(&quot;Diagnostic name&quot; ): Diagnostic in the encounter

// PatientHasHistoryOfProposedorConfirmedDianostic(&quot;Diagnostic name&quot;, duration ): Diagnostic in the patient history during duration

// PatientZScoreWfA(wieght, age)

// PatientWeightFromWfA(age, Muac)
</code></pre></div>
  </text>
  <url
       value="https://fhir.dk.swisstph-mis.ch/matchbox/fhir//Library/chebase"/>
  <version value="0.1.0"/>
  <name value="chebase"/>
  <title value="CHEBase"/>
  <status value="active"/>
  <type>
    <coding>
      <system value="http://hl7.org/fhir/ValueSet/library-type"/>
      <code value="logic-library"/>
    </coding>
  </type>
  <date value="2023-10-04T12:32:21+00:00"/>
  <publisher value="WHO"/>
  <contact>
    <name value="WHO"/>
    <telecom>
      <system value="url"/>
      <value value="http://who.int"/>
    </telecom>
  </contact>
  <relatedArtifact>
    <type value="depends-on"/>
    <resource value="http://fhir.org/guides/who/anc-cds/Library/FHIRHelpers"/>
  </relatedArtifact>
  <parameter>
    <name value="encounterid"/>
    <use value="in"/>
    <type value="string"/>
  </parameter>
  <dataRequirement>
    <type value="Patient"/>
    <profile value="http://hl7.org/fhir/StructureDefinition/Patient"/>
  </dataRequirement>
  <dataRequirement>
    <type value="Encounter"/>
    <profile value="http://hl7.org/fhir/StructureDefinition/Encounter"/>
  </dataRequirement>
  <content id="ig-loader-chebase.cql">
    <contentType value="text/cql"/>
    <data
          value="LypudGVyIgpAYXV0aG9yOiBQYXRyaWNrIERlbGNyb2l4CkBkZXNjcmlwdGlvbjogVGhpcyBsaWJyYXJ5IGlzIHBhcnQgb2YgdGhlIHByb2plY3QgQ0hFIFByb2plY3QsIGl0cyBhbGxvd3Mgc3RhbmRhcmRpc2F0aW9uIGZvciB0aGUgb2JzZXJ2YXRpb24gcHJvY2Vzc2luZwoqLwoKbGlicmFyeSBjaGViYXNlIHZlcnNpb24gJzEuMC4zMTMrYnVpbGQuNDU2JwoKdXNpbmcgRkhJUiB2ZXJzaW9uICc0LjAuMScKCmluY2x1ZGUgRkhJUkhlbHBlcnMgdmVyc2lvbiAnNC4wLjEnCgpwYXJhbWV0ZXIgImVuY291bnRlcmlkIiBTdHJpbmcKLy9wYXJhbWV0ZXIgIkVuY291bnRlciIgRW5jb3VudGVyJApjb2Rlc3lzdGVtICJSb2xlQ29kZVN5c3RlbSIgOiAnaHR0cHM6Ly9maGlyLmRrLnN3aXNzdHBoLW1pcy5jaC9tYXRjaGJveC9maGlyL0NvZGVTeXN0ZW0vZW1jYXJlLWN1c3RvbS1jb2RlcycKY29kZSAiTW90aGVyIjogJ01USCcgZnJvbSAiUm9sZUNvZGVTeXN0ZW0iCgpjb250ZXh0IFBhdGllbnQKCi8vZGVmaW5lIGVuY291bnRlcmlkOgovLyAgIkVuY291bnRlciIuaWQKCgoKCmRlZmluZSAiWWVzIjoKICB0cnVlCgpkZWZpbmUgIk5vIjoKICBmYWxzZSAKCgpkZWZpbmUgZnVuY3Rpb24gSXNJbkVuY291bnRlcihyZWYgRkhJUi5SZWZlcmVuY2UpOgogICAgY2FzZQogICAgd2hlbiBlbmNvdW50ZXJpZCA9IHJlZi5pZCB0aGVuIHRydWUKICAgIHdoZW4gZW5jb3VudGVyaWQgPSBMYXN0KFNwbGl0KHJlZi5yZWZlcmVuY2UsICcvJykpIHRoZW4gdHJ1ZQogICAvLyB3aGVuIHJlZi5pZGVudGlmaWVyIGlzIG5vdCBudWxsIGFuZCBpZCA9IHJlZi5pZGVudGlmaWVyLmlkIHRoZW4gdHJ1ZQogICAgZWxzZSBmYWxzZQplbmQKCmRlZmluZSBnZXRFbmNvdW50ZXJzOgogICAgW0VuY291bnRlcl0gRSAKICAgICAgd2hlcmUgRS5pZCA9ICJlbmNvdW50ZXJpZCIKICAgICAgICByZXR1cm4gRQoKZGVmaW5lIGdldEVuY291bnRlcjoKICAgIHNpbmdsZXRvbiBmcm9tIGdldEVuY291bnRlcnMKCmRlZmluZSBmdW5jdGlvbiBDSEVFeHRlbnNpb25zKGVsZW1lbnQgUGF0aWVudCwgaWQgU3RyaW5nKToKICBlbGVtZW50LmV4dGVuc2lvbiBFCiAgICAgIHdoZXJlIEUudXJsID0gKCdodHRwczovL2ZoaXIuZGsuc3dpc3N0cGgtbWlzLmNoL21hdGNoYm94L2ZoaXIvU3RydWN0dXJlRGVmaW5pdGlvbi8nICsgaWQpCiAgICAgIHJldHVybiBFCgpkZWZpbmUgZnVuY3Rpb24gQ0hFRXh0ZW5zaW9uKGVsZW1lbnQgUGF0aWVudCwgaWQgU3RyaW5nKToKICBzaW5nbGV0b24gZnJvbSBDSEVFeHRlbnNpb25zKGVsZW1lbnQsIGlkKQoKZGVmaW5lIGZ1bmN0aW9uIENIRUV4dGVuc2lvbnMoZWxlbWVudCBFbmNvdW50ZXIsIGlkIFN0cmluZyk6CiAgZWxlbWVudC5leHRlbnNpb24gRQogICAgICB3aGVyZSBFLnVybCA9ICgnaHR0cHM6Ly9maGlyLmRrLnN3aXNzdHBoLW1pcy5jaC9tYXRjaGJveC9maGlyL1N0cnVjdHVyZURlZmluaXRpb24vJyArIGlkKQogICAgICByZXR1cm4gRQoKCmRlZmluZSBmdW5jdGlvbiBwb3N0Y29yZGluYXRpb25FeHRlbnNpb24oZWxlbWVudCBDb25kaXRpb24sIHBvc3Rjb3JkaW5hdGlvbiBMaXN0PFN0cmluZz4pOgogIGVsZW1lbnQuZXh0ZW5zaW9uIEUKICAgICAgd2hlcmUgRS51cmwgPSAoJ2h0dHBzOi8vZmhpci5kay5zd2lzc3RwaC1taXMuY2gvbWF0Y2hib3gvZmhpci9TdHJ1Y3R1cmVEZWZpbml0aW9uL3Bvc3Rjb3JkaW5hdGlvbicpCiAgICAgIGFuZCBFLnZhbHVlIGluIHBvc3Rjb3JkaW5hdGlvbgoKCmRlZmluZSBmdW5jdGlvbiBDSEVFeHRlbnNpb24oZWxlbWVudCBFbmNvdW50ZXIsIGlkIFN0cmluZyk6CiAgc2luZ2xldG9uIGZyb20gQ0hFRXh0ZW5zaW9ucyhlbGVtZW50LCBpZCkKCmRlZmluZSBnZXRQcmltYXJ5Q2FyZUdpdmVyUmVmZXJlbmNlOgogIENIRUV4dGVuc2lvbihQYXRpZW50LCAncHJpbWFyeWNhcmVnaXZlcicpLnZhbHVlCgpkZWZpbmUgZ2V0UHJpbWFyeUNhcmVHaXZlcjoKICBbUmVsYXRlZFBlcnNvbl0gUlAgd2hlcmUgUlAuaWQgPSBMYXN0KFNwbGl0KGdldFByaW1hcnlDYXJlR2l2ZXJSZWZlcmVuY2UucmVmZXJlbmNlLCAnLycpKQogICAgcmV0dXJuIFJQCgpkZWZpbmUgaXNNb3RoZXJQcmltYXJ5Q2FyZUdpdmVyOgogIGdldFByaW1hcnlDYXJlR2l2ZXIgaXMgbm90IG51bGwgYW5kIEV4aXN0cyhnZXRQcmltYXJ5Q2FyZUdpdmVyLnJlbGF0aW9uc2hpcCByIHdoZXJlIHIgfiAiTW90aGVyIikKCmRlZmluZSAiQmlvbG9naWNhbCBNb3RoZXIgVml0YWwgU3RhdHVzIjoKICBDSEVFeHRlbnNpb24oUGF0aWVudCwgJ21vdGhlclZpdGFsU3RhdHVzJykudmFsdWUKICAKZGVmaW5lICJCaW9sb2dpY2FsIEZhdGhlciBWaXRhbCBTdGF0dXMiOgogIENIRUV4dGVuc2lvbihQYXRpZW50LCAnZmF0aGVyVml0YWxTdGF0dXMnKS52YWx1ZQovLyBwZXJzb24gYWNjb21wYW55aW5nIHRoZSBjaGlsZCBpcyBhIHBhcnRpY2lwYW50IHdpdGggYSBudWxsIHR5cGUKZGVmaW5lIGdldFJlbGF0ZWRQZXJzb25SZWZlcmVuY2VBY2NvbXBhbnlpbmdUaGVDaGlsZDoKICBDb2FsZXNjZShGaXJzdChnZXRFbmNvdW50ZXIucGFydGljaXBhbnQgUCB3aGVyZSBub3QgZXhpc3RzKFAudHlwZSkgKS5pbmRpdmlkdWFsLCBnZXRQcmltYXJ5Q2FyZUdpdmVyUmVmZXJlbmNlKQoKZGVmaW5lIGdldFJlbGF0ZWRQZXJzb25zQWNjb21wYW55aW5nVGhlQ2hpbGQ6CiAgW1JlbGF0ZWRQZXJzb25dIFJQIHdoZXJlIFJQLmlkID0gTGFzdChTcGxpdChnZXRSZWxhdGVkUGVyc29uUmVmZXJlbmNlQWNjb21wYW55aW5nVGhlQ2hpbGQucmVmZXJlbmNlLCAnLycpKQogICAgcmV0dXJuIFJQCgoKZGVmaW5lIGdldFJlbGF0ZWRQZXJzb25BY2NvbXBhbnlpbmdUaGVDaGlsZDoKICBzaW5nbGV0b24gZnJvbSBnZXRSZWxhdGVkUGVyc29uc0FjY29tcGFueWluZ1RoZUNoaWxkCgoKZGVmaW5lICJQZXJzb24gYWNjb21wYW55aW5nIGNoaWxkIHRvZGF5J3MgUmVsYXRpb25zaGlwIHRvIENsaWVudCI6Ci8vV09SS0FSUk9VTkQgICBnZXRSZWxhdGVkUGVyc29uQWNjb21wYW55aW5nVGhlQ2hpbGQucmVsYXRpb25zaGlwCiAgQ0hFRXh0ZW5zaW9uKGdldEVuY291bnRlciwgJ21vdGhlcnByZXNlbnQnKS52YWx1ZQoKCgoKCmRlZmluZSBmdW5jdGlvbiBnZXRWYWx1ZShPIE9ic2VydmF0aW9uKToKICBjYXNlICAKICAgICAgd2hlbiAgTyBpcyBudWxsIHRoZW4gbnVsbAogICAgICB3aGVuIE8udmFsdWUgaXMgQ29kZWFibGVDb25jZXB0IHRoZW4gQ29hbGVzY2UoRmlyc3QoTy52YWx1ZS5jb2RpbmcgQyB3aGVyZSBDLnN5c3RlbSAgPSAnaHR0cHM6Ly9maGlyLmRrLnN3aXNzdHBoLW1pcy5jaC9tYXRjaGJveC9maGlyL0NvZGVTeXN0ZW0vY2hlLWN1c3RvbS1jb2RlcycpLCBGaXJzdChPLnZhbHVlLmNvZGluZykpCiAgICAgIGVsc2UgTy52YWx1ZQogIGVuZAoKCmRlZmluZSBmdW5jdGlvbiBhc3Nlc09ic2VydmF0aW9uKE8gT2JzZXJ2YXRpb24pOgogIGNhc2UgIAogICAgICB3aGVuICBPIGlzIG51bGwgdGhlbiBudWxsCiAgICAgIHdoZW4gIE8uc3RhdHVzIGluICB7J2NhbmNlbGxlZCd9IHRoZW4gZmFsc2UKICAgICAgd2hlbiBPLnZhbHVlIGlzIG51bGwgdGhlbiAgdHJ1ZQogICAgICBlbHNlIE8udmFsdWUKICBlbmQKLyogICAgICAKZGVmaW5lIGZ1bmN0aW9uIEdldE9ic2VydmF0aW9uRHVyaW5nRW5jb3VudGVyKGlkbGlzdCBMaXN0PFN5c3RlbS5Db2RlPik6CiAgaWYgR2V0T2JzZXJ2YXRpb25EdXJpbmdFbmNvdW50ZXJEb25lKGlkbGlzdCApIGlzIG51bGwgdGhlbiAKICAgICAgR2V0T2JzZXJ2YXRpb25EdXJpbmdFbmNvdW50ZXJEb25lKGlkbGlzdCApCiAgZWxzZQogICAgR2V0T2JzZXJ2YXRpb25EdXJpbmdFbmNvdW50ZXJOb3RGb3VuZChpZGxpc3QgKQoqLwoKZGVmaW5lIGZ1bmN0aW9uIEdldE9ic2VydmF0aW9uRHVyaW5nRW5jb3VudGVyKGlkIFN5c3RlbS5Db2RlKToKICAgICAgRmlyc3QoW09ic2VydmF0aW9uOiBpZCBdIE8KICAgICAgICB3aGVyZSAgIElzSW5FbmNvdW50ZXIoTy5lbmNvdW50ZXIpIAogICAgICAgIGFuZCBPLnN0YXR1cyBpbiB7ICdmaW5hbCcsICdhbWVuZGVkJywgJ2NvcnJlY3RlZCcsJ2NhbmNlbGxlZCd9IAogICAgICAgIHNvcnQgYnkgaXNzdWVkLnZhbHVlIGRlc2MpIAoKICAvKgogIHRoaXMgaXMgY29tbWVudGVkIGZvciBwZXJmb3JtYW5jZSBpbXByb3ZlbWVudCwgZXZlbiBpZiBpdCBoaWRlcyBhIHZhbGlkIG9ic2VydmF0aW9uIGlmIHRoZXJlIGlzIGFuIG1vcmUgcmVjZW50IHVudmFsaWQgb25lCiAgQ29hbGVzY2UoR2V0T2JzZXJ2YXRpb25EdXJpbmdFbmNvdW50ZXJEb25lKGlkICksIEdldE9ic2VydmF0aW9uRHVyaW5nRW5jb3VudGVyTm90Rm91bmQoaWQgKSkKICAqLwovKgpkZWZpbmUgZnVuY3Rpb24gR2V0T2JzZXJ2YXRpb25EdXJpbmdFbmNvdW50ZXJEb25lKGlkbGlzdCBMaXN0PFN5c3RlbS5Db2RlPik6CiAgICAgIExhc3QoW09ic2VydmF0aW9uOiBpZGxpc3QgXSBPCiAgICAgICAgd2hlcmUgICBJc0luRW5jb3VudGVyKE8uZW5jb3VudGVyKSAKICAgICAgICBhbmQgTy5zdGF0dXMgaW4geyAnZmluYWwnLCAnYW1lbmRlZCcsICdjb3JyZWN0ZWQnfSkKKi8KZGVmaW5lIGZ1bmN0aW9uIEdldE9ic2VydmF0aW9uRHVyaW5nRW5jb3VudGVyRG9uZShpZCBTeXN0ZW0uQ29kZSk6CiAgICAgIEZpcnN0KFtPYnNlcnZhdGlvbjogaWQgXSBPCiAgICAgICAgd2hlcmUgICBJc0luRW5jb3VudGVyKE8uZW5jb3VudGVyKSAKICAgICAgICBhbmQgTy5zdGF0dXMgaW4geyAnZmluYWwnLCAnYW1lbmRlZCcsICdjb3JyZWN0ZWQnfSAKICAgICAgICBzb3J0IGJ5IGlzc3VlZC52YWx1ZSBkZXNjKSAKCgpkZWZpbmUgZnVuY3Rpb24gSGFzT2JzZXJ2YXRpb25Db2RlRHVyaW5nRW5jb3VudGVyRG9uZShpZCBTeXN0ZW0uQ29kZSwgdmFsdWVDb2RlIFN5c3RlbS5Db2RlKToKICAgIAogICAgRXhpc3RzKFtPYnNlcnZhdGlvbjogaWQgXSBPCiAgICAgICAgd2hlcmUgICBJc0luRW5jb3VudGVyKE8uZW5jb3VudGVyKSAKICAgICAgICBhbmQgTy5zdGF0dXMgaW4geyAnZmluYWwnLCAnYW1lbmRlZCcsICdjb3JyZWN0ZWQnfQogICAgICAgIGFuZCBPLnZhbHVlIGlzIEZISVIuQ29kZWFibGVDb25jZXB0CiAgICAgICAgYW5kIE8udmFsdWUgfiB2YWx1ZUNvZGUpCgovL0V4aXN0cyhbT2JzZXJ2YXRpb25dIE8gd2hlcmUgTy5zdGF0dXMgaW4geyAnZmluYWwnLCAnYW1lbmRlZCcsICdjb3JyZWN0ZWQnfSBhbmQgTy52YWx1ZSBpcyBGSElSLkNvZGVhYmxlQ29uY2VwdCAgIGFuZCBFeGlzdHMoIE8udmFsdWUuY29kaW5nIEMgd2hlcmUgQyBpcyBGSElSLkNvZGluZyBhbmQgQy5jb2RlID0gRkhJUi5jb2RlIHt2YWx1ZTogJ0NIRS5CMjBTMi5ERTA0J30pICkiCgovKgpkZWZpbmUgZnVuY3Rpb24gR2V0T2JzZXJ2YXRpb25EdXJpbmdFbmNvdW50ZXJOb3RGb3VuZChpZGxpc3QgTGlzdDxTeXN0ZW0uQ29kZT4pOgogICAgICBMYXN0KFtPYnNlcnZhdGlvbjogaWRsaXN0XSBPCiAgICAgICB3aGVyZSAgSXNJbkVuY291bnRlcihPLmVuY291bnRlcikgCiAgICAgICAgICBhbmQgTy5zdGF0dXMgaW4geydjYW5jZWxsZWQnfSkKICAgICAgICAgICovCmRlZmluZSBmdW5jdGlvbiBHZXRPYnNlcnZhdGlvbkR1cmluZ0VuY291bnRlck5vdEZvdW5kKGlkIFN5c3RlbS5Db2RlKToKICAgICAgRmlyc3QoW09ic2VydmF0aW9uOiBpZF0gTwogICAgICAgd2hlcmUgIElzSW5FbmNvdW50ZXIoTy5lbmNvdW50ZXIpIAogICAgICAgICAgYW5kIE8uc3RhdHVzIGluIHsnY2FuY2VsbGVkJ30KICAgICAgICAgIHNvcnQgYnkgaXNzdWVkLnZhbHVlIGRlc2MpCi8qCgpkZWZpbmUgZnVuY3Rpb24gR2V0TnVtYmVyT2JzZXJ2YXRpb25EdXJpbmdFbmNvdW50ZXIoaWRsaXN0IExpc3Q8U3lzdGVtLkNvZGU+KToKICBDb3VudCgKICAgIFtPYnNlcnZhdGlvbjogaWRsaXN0XSBPCiAgICAgICAgd2hlcmUgIElzSW5FbmNvdW50ZXIoIE8uZW5jb3VudGVyKSAKICAgICAgICBhbmQgTy5zdGF0dXMgaW4geyAnZmluYWwnLCAnYW1lbmRlZCcsICdjb3JyZWN0ZWQnfSkKKi8KZGVmaW5lIGZ1bmN0aW9uIEdldE51bWJlck9ic2VydmF0aW9uRHVyaW5nRW5jb3VudGVyKGlkIFN5c3RlbS5Db2RlKToKICBDb3VudCgKICAgIFtPYnNlcnZhdGlvbjogaWRdIE8KICAgICAgICB3aGVyZSAgSXNJbkVuY291bnRlciggTy5lbmNvdW50ZXIpIAogICAgICAgIGFuZCBPLnN0YXR1cyBpbiB7ICdmaW5hbCcsICdhbWVuZGVkJywgJ2NvcnJlY3RlZCd9KQoKLy8gKioqKioqKioqKioqKioqKioqKioqKioqICAgR2V0T2JzVmFsdWUgKioqKioqKioqKioqKioqKioqKioqKioqLwovKgpkZWZpbmUgZnVuY3Rpb24gR2V0T2JzVmFsdWUoaWRsaXN0IExpc3Q8U3lzdGVtLkNvZGU+KToKICAgIGdldFZhbHVlKEdldE9ic2VydmF0aW9uRHVyaW5nRW5jb3VudGVyKGlkbGlzdCkpCgpkZWZpbmUgZnVuY3Rpb24gR2V0T2JzVmFsdWUoaWQgU3lzdGVtLkNvZGUpOgogICAgZ2V0VmFsdWUoR2V0T2JzZXJ2YXRpb25EdXJpbmdFbmNvdW50ZXIoe2lkfSkpCiovCgpkZWZpbmUgZnVuY3Rpb24gR2V0T2JzVmFsdWUoaWQgU3lzdGVtLkNvZGUpOgogICAgZ2V0VmFsdWUoR2V0T2JzZXJ2YXRpb25EdXJpbmdFbmNvdW50ZXIoaWQpKQoKZGVmaW5lIGZ1bmN0aW9uIEdldE9ic1ZhbHVlKGlkIFN5c3RlbS5TdHJpbmcsIGNvZGVzeXN0ZW0gU3lzdGVtLlN0cmluZyk6CiAgICBnZXRWYWx1ZShHZXRPYnNlcnZhdGlvbkR1cmluZ0VuY291bnRlcihjb2RpbmcoaWQsIGNvZGVzeXN0ZW0pKSkKCmRlZmluZSBmdW5jdGlvbiBHZXRPYnNWYWx1ZShpZCBTeXN0ZW0uU3RyaW5nKToKICAgIGdldFZhbHVlKEdldE9ic2VydmF0aW9uRHVyaW5nRW5jb3VudGVyKGNvZGluZyhpZCwgJ2h0dHBzOi8vZmhpci5kay5zd2lzc3RwaC1taXMuY2gvbWF0Y2hib3gvZmhpci9Db2RlU3lzdGVtL2NoZS1jdXN0b20tY29kZXMnKSkpCgpkZWZpbmUgZnVuY3Rpb24gSGFzT2JzVmFsdWVDb2RlKGlkIFN5c3RlbS5TdHJpbmcsIHZhbHVlIFN5c3RlbS5Db2RlKToKICAgSGFzT2JzZXJ2YXRpb25Db2RlRHVyaW5nRW5jb3VudGVyRG9uZShjb2RpbmcoaWQsICdodHRwczovL2ZoaXIuZGsuc3dpc3N0cGgtbWlzLmNoL21hdGNoYm94L2ZoaXIvQ29kZVN5c3RlbS9jaGUtY3VzdG9tLWNvZGVzJykgLCB2YWx1ZSApCiAgCmRlZmluZSBmdW5jdGlvbiBIYXNPYnNWYWx1ZUNvZGUoaWQgU3lzdGVtLlN0cmluZywgdmFsdWUgU3lzdGVtLlN0cmluZyk6CiAgIEhhc09ic2VydmF0aW9uQ29kZUR1cmluZ0VuY291bnRlckRvbmUoY29kaW5nKGlkLCAnaHR0cHM6Ly9maGlyLmRrLnN3aXNzdHBoLW1pcy5jaC9tYXRjaGJveC9maGlyL0NvZGVTeXN0ZW0vY2hlLWN1c3RvbS1jb2RlcycpICwgY29kaW5nKHZhbHVlLCAnaHR0cHM6Ly9maGlyLmRrLnN3aXNzdHBoLW1pcy5jaC9tYXRjaGJveC9maGlyL0NvZGVTeXN0ZW0vY2hlLWN1c3RvbS1jb2RlcycpICkKCmRlZmluZSBmdW5jdGlvbiBIYXNPYnNWYWx1ZUNvZGUoaWQgU3lzdGVtLkNvZGUsIHZhbHVlIFN5c3RlbS5TdHJpbmcpOgogICBIYXNPYnNlcnZhdGlvbkNvZGVEdXJpbmdFbmNvdW50ZXJEb25lKGlkICwgY29kaW5nKHZhbHVlLCAnaHR0cHM6Ly9maGlyLmRrLnN3aXNzdHBoLW1pcy5jaC9tYXRjaGJveC9maGlyL0NvZGVTeXN0ZW0vY2hlLWN1c3RvbS1jb2RlcycpICkKCi8vICoqKioqKioqKioqKioqKioqKioqKioqKiAgIEhhc09icyAqKioqKioqKioqKioqKioqKioqKioqKiovCi8qCmRlZmluZSBmdW5jdGlvbiBIYXNPYnMoaWRsaXN0IExpc3Q8U3lzdGVtLkNvZGU+KToKICAgIGFzc2VzT2JzZXJ2YXRpb24oR2V0T2JzZXJ2YXRpb25EdXJpbmdFbmNvdW50ZXIoaWRsaXN0KSkKCmRlZmluZSBmdW5jdGlvbiBIYXNPYnMoaWQgU3lzdGVtLkNvZGUpOgogICAgYXNzZXNPYnNlcnZhdGlvbihHZXRPYnNlcnZhdGlvbkR1cmluZ0VuY291bnRlcih7aWR9KSkKKi8KZGVmaW5lIGZ1bmN0aW9uIEhhc09icyhpZCBTeXN0ZW0uQ29kZSk6CiAgICBhc3Nlc09ic2VydmF0aW9uKEdldE9ic2VydmF0aW9uRHVyaW5nRW5jb3VudGVyKGlkKSkKCmRlZmluZSBmdW5jdGlvbiBIYXNPYnMoaWQgU3lzdGVtLlN0cmluZywgY29kZXN5c3RlbSBTeXN0ZW0uU3RyaW5nKToKICAgIGFzc2VzT2JzZXJ2YXRpb24oR2V0T2JzZXJ2YXRpb25EdXJpbmdFbmNvdW50ZXIoY29kaW5nKGlkLCBjb2Rlc3lzdGVtKSkpCgpkZWZpbmUgZnVuY3Rpb24gSGFzT2JzKGlkIFN5c3RlbS5TdHJpbmcpOgogICAgYXNzZXNPYnNlcnZhdGlvbihHZXRPYnNlcnZhdGlvbkR1cmluZ0VuY291bnRlcihjb2RpbmcoaWQpKSkKCmRlZmluZSBmdW5jdGlvbiBIYXNPYnMoaWQgRkhJUi5jb2RlLCBjb2Rlc3lzdGVtIFN5c3RlbS5TdHJpbmcpOgogICAgYXNzZXNPYnNlcnZhdGlvbihHZXRPYnNlcnZhdGlvbkR1cmluZ0VuY291bnRlcihjb2RpbmcoaWQsIGNvZGVzeXN0ZW0pKSkKLyoKZGVmaW5lIGZ1bmN0aW9uIEdldEhpc3RvcmljT2JzZXJ2YXRpb24oaWRsaXN0IExpc3Q8U3lzdGVtLkNvZGU+LCBuYmRheXMgSW50ZWdlcik6CiAgaWYgR2V0SGlzdG9yaWNPYnNlcnZhdGlvbk5vdGZvdW5kKGlkbGlzdCAsIGNvZGVzeXN0ZW0gLCBuYmRheXMgKSBpcyBudWxsIHRoZW4gCiAgICAgIEdldEhpc3RvcmljT2JzZXJ2YXRpb25Ob3Rmb3VuZChpZGxpc3QgLCBjb2Rlc3lzdGVtICwgbmJkYXlzICkKICBlbHNlCiAgICBHZXRIaXN0b3JpY09ic2VydmF0aW9uTm90Zm91bmQoaWRsaXN0ICwgY29kZXN5c3RlbSAsIG5iZGF5cyApCiovCgpkZWZpbmUgZnVuY3Rpb24gR2V0SGlzdG9yaWNPYnNlcnZhdGlvbihpZCBTeXN0ZW0uQ29kZSwgbmJkYXlzIEludGVnZXIpOgogICAgICBGaXJzdChbT2JzZXJ2YXRpb246IGlkIF0gTwogICAgICAgIHdoZXJlIE8uc3RhdHVzIGluIHsgJ2ZpbmFsJywgJ2FtZW5kZWQnLCAnY29ycmVjdGVkJywnY2FuY2VsbGVkJ30gCiAgICAgICAgYW5kIChkaWZmZXJlbmNlIGluIGRheXMgYmV0d2VlbiBPLmlzc3VlZCBhbmQgVG9kYXkoKSkgPCBuYmRheXMgCiAgICAgICAgc29ydCBieSBpc3N1ZWQudmFsdWUgZGVzYyApCgogIC8vQ29hbGVzY2UoR2V0SGlzdG9yaWNPYnNlcnZhdGlvbkRvbmUoaWQgLCAgbmJkYXlzICksICBHZXRIaXN0b3JpY09ic2VydmF0aW9uTm90Zm91bmQoaWQgICwgbmJkYXlzICkpCi8qCmRlZmluZSBmdW5jdGlvbiBHZXRIaXN0b3JpY09ic2VydmF0aW9uRG9uZShpZGxpc3QgTGlzdDxTeXN0ZW0uQ29kZT4sIG5iZGF5cyBJbnRlZ2VyKToKICAgICAgTGFzdChbT2JzZXJ2YXRpb246IGlkbGlzdCBdIE8KICAgICAgICB3aGVyZSAgTy5zdGF0dXMgaW4geyAnZmluYWwnLCAnYW1lbmRlZCcsICdjb3JyZWN0ZWQnfQogICAgICAgIGFuZCAoZGlmZmVyZW5jZSBpbiBkYXlzIGJldHdlZW4gTy5pc3N1ZWQgYW5kIFRvZGF5KCkpIDwgbmJkYXlzKQoqLwpkZWZpbmUgZnVuY3Rpb24gR2V0SGlzdG9yaWNPYnNlcnZhdGlvbkRvbmUoaWQgU3lzdGVtLkNvZGUsIG5iZGF5cyBJbnRlZ2VyKToKICAgICAgRmlyc3QoW09ic2VydmF0aW9uOiBpZCBdIE8KICAgICAgICB3aGVyZSAgTy5zdGF0dXMgaW4geyAnZmluYWwnLCAnYW1lbmRlZCcsICdjb3JyZWN0ZWQnfQogICAgICAgIGFuZCAoZGlmZmVyZW5jZSBpbiBkYXlzIGJldHdlZW4gTy5pc3N1ZWQgYW5kIFRvZGF5KCkpIDwgbmJkYXlzIAogICAgICAgIHNvcnQgYnkgaXNzdWVkLnZhbHVlIGRlc2MgKQoKLyoKZGVmaW5lIGZ1bmN0aW9uIEdldEhpc3RvcmljT2JzZXJ2YXRpb25Ob3Rmb3VuZChpZGxpc3QgTGlzdDxTeXN0ZW0uQ29kZT4sIG5iZGF5cyBJbnRlZ2VyKToKICAgICAgTGFzdChbT2JzZXJ2YXRpb246IGlkbGlzdF0gTwogICAgICAgIHdoZXJlICBPLnN0YXR1cyBpbiB7J2NhbmNlbGxlZCd9CiovCmRlZmluZSBmdW5jdGlvbiBHZXRIaXN0b3JpY09ic2VydmF0aW9uTm90Zm91bmQoaWQgU3lzdGVtLkNvZGUsIG5iZGF5cyBJbnRlZ2VyKToKICAgICAgRmlyc3QoW09ic2VydmF0aW9uOiBpZF0gTwogICAgICAgIHdoZXJlICBPLnN0YXR1cyBpbiB7J2NhbmNlbGxlZCd9CiAgICAgICAgICBhbmQgKGRpZmZlcmVuY2UgaW4gZGF5cyBiZXR3ZWVuIE8uaXNzdWVkIGFuZCBUb2RheSgpKSA8IG5iZGF5cyAKICAgICAgICBzb3J0IGJ5IGlzc3VlZC52YWx1ZSBkZXNjKQovLyAqKioqKioqKioqKioqKioqKioqKioqKiogICBIYXNPYnNIaXN0b3J5ICoqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qCmRlZmluZSBmdW5jdGlvbiBIYXNPYnNIaXN0b3J5KGlkbGlzdCBMaXN0PFN5c3RlbS5Db2RlPiwgIG5iZGF5cyBJbnRlZ2VyKToKICBhc3Nlc09ic2VydmF0aW9uKEdldEhpc3RvcmljT2JzZXJ2YXRpb24oaWRsaXN0LCBuYmRheXMpKQoKCiBkZWZpbmUgZnVuY3Rpb24gSGFzT2JzSGlzdG9yeShpZCBTeXN0ZW0uQ29kZSwgY25iZGF5cyBJbnRlZ2VyKToKICBhc3Nlc09ic2VydmF0aW9uKEdldEhpc3RvcmljT2JzZXJ2YXRpb24oe2lkfSwgbmJkYXlzKSkKKi8KZGVmaW5lIGZ1bmN0aW9uIEhhc09ic0hpc3RvcnkoaWQgU3lzdGVtLkNvZGUsIG5iZGF5cyBJbnRlZ2VyKToKICBhc3Nlc09ic2VydmF0aW9uKEdldEhpc3RvcmljT2JzZXJ2YXRpb24oaWQsIG5iZGF5cykpCgpkZWZpbmUgZnVuY3Rpb24gSGFzT2JzSGlzdG9yeShpZCBTeXN0ZW0uU3RyaW5nLCBjb2Rlc3lzdGVtIFN5c3RlbS5TdHJpbmcsIG5iZGF5cyBJbnRlZ2VyKToKICBhc3Nlc09ic2VydmF0aW9uKEdldEhpc3RvcmljT2JzZXJ2YXRpb24oY29kaW5nKGlkLCBjb2Rlc3lzdGVtKSwgbmJkYXlzKSkKCgpkZWZpbmUgZnVuY3Rpb24gSGFzT2JzSGlzdG9yeShpZCBTeXN0ZW0uU3RyaW5nLCBuYmRheXMgSW50ZWdlcik6CiAgYXNzZXNPYnNlcnZhdGlvbihHZXRIaXN0b3JpY09ic2VydmF0aW9uKGNvZGluZyhpZCksIG5iZGF5cykpCgpkZWZpbmUgZnVuY3Rpb24gYyhzIFN5c3RlbS5TdHJpbmcpOgogIEZISVIuY29kZSB7IHZhbHVlOiBzIH0KCgpkZWZpbmUgZnVuY3Rpb24gY29kaW5nKHMgU3lzdGVtLlN0cmluZywgdXJsIFN5c3RlbS5TdHJpbmcpOgogIFN5c3RlbS5Db2RlIHsKICAgICAgICAgICAgICAgIGNvZGU6ICBzICwKICAgICAgICAgICAgICAgIHN5c3RlbTogIHVybCAKICAgICAgICAgICAgfQoKZGVmaW5lIGZ1bmN0aW9uIGNvZGluZyhzIEZISVIuY29kZSwgdXJsIFN5c3RlbS5TdHJpbmcpOgogIFN5c3RlbS5Db2RlIHsKICAgICAgICAgICAgICAgIGNvZGU6ICBzLnZhbHVlICwKICAgICAgICAgICAgICAgIHN5c3RlbTogIHVybCAKICAgICAgICAgICAgfQoKZGVmaW5lIGZ1bmN0aW9uIGNvZGluZyhzIFN5c3RlbS5TdHJpbmcpOgogIFN5c3RlbS5Db2RlIHsKICAgICAgICAgICAgICAgIGNvZGU6ICBzICwKICAgICAgICAgICAgICAgIHN5c3RlbTogICdodHRwczovL2ZoaXIuZGsuc3dpc3N0cGgtbWlzLmNoL21hdGNoYm94L2ZoaXIvQ29kZVN5c3RlbS9jaGUtY3VzdG9tLWNvZGVzJwogICAgICAgICAgICB9CgoKZGVmaW5lIGZ1bmN0aW9uIFRvVXJsKHMgU3lzdGVtLlN0cmluZyk6CiAgdXJsIHt2YWx1ZTpzfQoKZGVmaW5lIGZ1bmN0aW9uIFRvSW50QyhiIFN5c3RlbS5Cb29sZWFuKToKICBjYXNlCiAgd2hlbiBiIGlzIG51bGwgdGhlbiAwCiAgd2hlbiBiID0gdHJ1ZSB0aGVuIDEKICBlbHNlIDAKICBlbmQKCgovLyAqKioqKioqKioqKioqKioqKioqKioqKiogICBHZXRDb25kICoqKioqKioqKioqKioqKioqKioqKioqKi8KCmRlZmluZSBmdW5jdGlvbiBHZXRDb25kaXRpb25zKGlkIFN5c3RlbS5Db2RlKToKICAgICAgW0NvbmRpdGlvbjogaWRdIE8KICAgICAgICB3aGVyZSAgSXNJbkVuY291bnRlciggTy5lbmNvdW50ZXIpIAogICAgICAgIGFuZCBleGlzdHMoTy52ZXJpZmljYXRpb25TdGF0dXMuY29kaW5nIEMgd2hlcmUgQy5jb2RlIGluIHsndW5jb25maXJtZWQnLCAncHJvdmlzaW9uYWwnLCAnZGlmZmVyZW50aWFsJywgJ2NvbmZpcm1lZCd9IAogICAgICAgIGFuZCBDLnN5c3RlbSA9ICdodHRwOi8vdGVybWlub2xvZ3kuaGw3Lm9yZy9Db2RlU3lzdGVtL2NvbmRpdGlvbi12ZXItc3RhdHVzJykKICAgICAgICBzb3J0IGJ5IHJlY29yZGVkRGF0ZSBkZXNjCgoKCgpkZWZpbmUgZnVuY3Rpb24gR2V0U3RlbUNvZGUoaWQgU3lzdGVtLlN0cmluZyk6CiAgY29kaW5nKFNwbGl0KCBpZCwgJyYnKVswXSkKCmRlZmluZSBmdW5jdGlvbiBHZXRQb3N0Y29vcmRpbmF0aW9uQ29kZShpZCBTeXN0ZW0uU3RyaW5nKToKICBUYWlsKFNwbGl0KGlkLCAnJicpKQoKZGVmaW5lIGZ1bmN0aW9uIEdldENvbmRpdGlvbihpZCBTeXN0ZW0uQ29kZSk6CiAgICAgIEZpcnN0KEdldENvbmRpdGlvbnMoaWQpKQoKCiAgIApkZWZpbmUgZnVuY3Rpb24gR2V0Q29uZGl0aW9uKGlkIFN5c3RlbS5Db2RlLCBwb3N0Y29yZGluYXRpb24gTGlzdDxTeXN0ZW0uU3RyaW5nPik6CiAgICBGaXJzdCgKICAgICAgW0NvbmRpdGlvbjogaWRdIEMKICAgICAgICB3aGVyZSAgSXNJbkVuY291bnRlciggQy5lbmNvdW50ZXIpIAogICAgICAgIGFuZCBleGlzdHMoQy52ZXJpZmljYXRpb25TdGF0dXMuY29kaW5nIGNjIHdoZXJlIGNjLmNvZGUgaW4geyd1bmNvbmZpcm1lZCcsICdwcm92aXNpb25hbCcsICdkaWZmZXJlbnRpYWwnLCAnY29uZmlybWVkJ30gCiAgICAgICAgYW5kIGNjLnN5c3RlbSA9ICdodHRwOi8vdGVybWlub2xvZ3kuaGw3Lm9yZy9Db2RlU3lzdGVtL2NvbmRpdGlvbi12ZXItc3RhdHVzJykKICAgICAgICBhbmQgIHBvc3Rjb3JkaW5hdGlvbiBpcyBudWxsIG9yICBDb3VudChwb3N0Y29yZGluYXRpb25FeHRlbnNpb24oQyxwb3N0Y29yZGluYXRpb24pKSA+PSBDb3VudChwb3N0Y29yZGluYXRpb24pCiAgICAgICAgc29ydCBieSByZWNvcmRlZERhdGUgZGVzYwogICAgKQoKCmRlZmluZSBmdW5jdGlvbiBhc3Nlc0NvbmRpdGlvbihPIENvbmRpdGlvbik6CiAgaWYgTyBpcyBudWxsIHRoZW4gCiAgICBmYWxzZQogIGVsc2UKICAgIHRydWUKCmRlZmluZSBmdW5jdGlvbiBHZXRDb25kKGlkIFN5c3RlbS5Db2RlKToKICAoR2V0Q29uZGl0aW9uKGlkKSkKCmRlZmluZSBmdW5jdGlvbiBHZXRDb25kKGlkIFN5c3RlbS5TdHJpbmcsIGNvZGVzeXN0ZW0gU3lzdGVtLlN0cmluZyk6CiAgKEdldENvbmRpdGlvbihjb2RpbmcoaWQsIGNvZGVzeXN0ZW0pKSkKCmRlZmluZSBmdW5jdGlvbiBHZXRDb25kKGlkIFN5c3RlbS5TdHJpbmcpOgogIChHZXRDb25kaXRpb24oR2V0U3RlbUNvZGUoaWQpLEdldFBvc3Rjb29yZGluYXRpb25Db2RlKGlkKSkpCgovLyAqKioqKioqKioqKioqKioqKioqKioqKiogICBIYXNDb25kICoqKioqKioqKioqKioqKioqKioqKioqKi8KLyoKZGVmaW5lIGZ1bmN0aW9uIEhhc0NvbmQoaWRsaXN0IExpc3Q8U3lzdGVtLkNvZGU+KToKICBhc3Nlc0NvbmRpdGlvbihHZXRDb25kaXRpb24oaWRsaXN0KSkKCgozNTE4R2V0Q29uZGl0aW9uKGlkKSkKKi8KZGVmaW5lIGZ1bmN0aW9uIEhhc0NvbmQoaWQgU3lzdGVtLlN0cmluZywgY29kZXN5c3RlbSBTeXN0ZW0uU3RyaW5nKToKICBhc3Nlc0NvbmRpdGlvbihHZXRDb25kaXRpb24oY29kaW5nKGlkLCBjb2Rlc3lzdGVtKSkpCgpkZWZpbmUgZnVuY3Rpb24gSGFzQ29uZChpZCBTeXN0ZW0uU3RyaW5nKToKICBhc3Nlc0NvbmRpdGlvbihHZXRDb25kaXRpb24oY29kaW5nKGlkKSkpCgpkZWZpbmUgZnVuY3Rpb24gSGFzQ29uZChpZCBTeXN0ZW0uQ29kZSk6CiAgYXNzZXNDb25kaXRpb24oR2V0Q29uZGl0aW9uKGlkKSkKCi8vICoqKioqKioqKioqKioqKioqKioqKioqKiAgIFBhdGllbnRIYXNIaXN0b3J5T2ZDb25kaXRpb24gKioqKioqKioqKioqKioqKioqKioqKioqLwovKgpkZWZpbmUgZnVuY3Rpb24gR2V0SGlzdG9yaWNDb25kaXRpb24oaWRsaXN0IExpc3Q8U3lzdGVtLkNvZGU+LCAgbmJkYXlzIEludGVnZXIpOgogICAgICBMYXN0KFtDb25kaXRpb246IGlkbGlzdF0gTwogICAgICAgIHdoZXJlICAoZGlmZmVyZW5jZSBpbiBkYXlzIGJldHdlZW4gTy5yZWNvcmRlZERhdGUgYW5kIFRvZGF5KCkpIDwgbmJkYXlzCiAgICAgICAgYW5kIGV4aXN0cyhPLnZlcmlmaWNhdGlvblN0YXR1cy5jb2RpbmcgQyB3aGVyZSBDLmNvZGUgaW4geyd1bmNvbmZpcm1lZCcsICdwcm92aXNpb25hbCcsICdkaWZmZXJlbnRpYWwnLCAnY29uZmlybWVkJ30gCiAgICAgICAgYW5kIEMuc3lzdGVtID0gJ2h0dHA6Ly90ZXJtaW5vbG9neS5obDcub3JnL0NvZGVTeXN0ZW0vY29uZGl0aW9uLXZlci1zdGF0dXMnKSkKKi8KCmRlZmluZSBmdW5jdGlvbiBHZXRIaXN0b3JpY0NvbmRpdGlvbihpZCBTeXN0ZW0uQ29kZSwgIG5iZGF5cyBJbnRlZ2VyKToKICAgICAgRmlyc3QoW0NvbmRpdGlvbjogaWRdIE8KICAgICAgICB3aGVyZSAgKGRpZmZlcmVuY2UgaW4gZGF5cyBiZXR3ZWVuIE8ucmVjb3JkZWREYXRlIGFuZCBUb2RheSgpKSA8IG5iZGF5cwogICAgICAgIGFuZCBleGlzdHMoTy52ZXJpZmljYXRpb25TdGF0dXMuY29kaW5nIEMgd2hlcmUgQy5jb2RlIGluIHsndW5jb25maXJtZWQnLCAncHJvdmlzaW9uYWwnLCAnZGlmZmVyZW50aWFsJywgJ2NvbmZpcm1lZCd9IAogICAgICAgIGFuZCBDLnN5c3RlbSA9ICdodHRwOi8vdGVybWlub2xvZ3kuaGw3Lm9yZy9Db2RlU3lzdGVtL2NvbmRpdGlvbi12ZXItc3RhdHVzJykgCiAgICAgICAgc29ydCBieSByZWNvcmRlZERhdGUgZGVzYykKCgoKCi8qCmRlZmluZSBmdW5jdGlvbiBIYXNDb25kSGlzdG9yeShpZGxpc3QgTGlzdDxTeXN0ZW0uQ29kZT4sICBuYmRheXMgSW50ZWdlcik6CiAgYXNzZXNDb25kaXRpb24oR2V0SGlzdG9yaWNDb25kaXRpb24oaWRsaXN0LCAgbmJkYXlzKSkKCgpkZWZpbmUgZnVuY3Rpb24gSGFzQ29uZEhpc3RvcnkoaWQgU3lzdGVtLkNvZGUsICBuYmRheXMgSW50ZWdlcik6CiAgYXNzZXNDb25kaXRpb24oR2V0SGlzdG9yaWNDb25kaXRpb24oe2lkfSwgbmJkYXlzKSkKKi8KZGVmaW5lIGZ1bmN0aW9uIEhhc0NvbmRIaXN0b3J5KGlkIFN5c3RlbS5Db2RlLCBuYmRheXMgSW50ZWdlcik6CiAgYXNzZXNDb25kaXRpb24oR2V0SGlzdG9yaWNDb25kaXRpb24oaWQsICBuYmRheXMpKQoKZGVmaW5lIGZ1bmN0aW9uIEhhc0NvbmRIaXN0b3J5KGlkIFN5c3RlbS5TdHJpbmcsIGNvZGVzeXN0ZW0gU3lzdGVtLlN0cmluZywgbmJkYXlzIEludGVnZXIpOgogIGFzc2VzQ29uZGl0aW9uKEdldEhpc3RvcmljQ29uZGl0aW9uKGNvZGluZyhpZCxjb2Rlc3lzdGVtKSxuYmRheXMpKQoKCmRlZmluZSBmdW5jdGlvbiBIYXNDb25kSGlzdG9yeShpZCBTeXN0ZW0uU3RyaW5nLCBuYmRheXMgSW50ZWdlcik6CiAgYXNzZXNDb25kaXRpb24oR2V0SGlzdG9yaWNDb25kaXRpb24oY29kaW5nKGlkKSwgIG5iZGF5cykpCgoKCi8vZGVmaW5lIGZ1bmN0aW9uIFBhdGllbnRIYXNDb25kaXRpb25EdXJpbmdFbmNvdW50ZXIoaWQgU3RyaW5nLCBjb2Rlc3lzdGVtIHVybCwgZHVyYXRpb24gSW50ZWdlcikpOgoKLy9kZWZpbmUgZnVuY3Rpb24gUGF0aWVudEhhc0NvbmRpdGlvbkZyb21WYWx1ZVNldER1cmluZ0VuY291bnRlcihpZCBTdHJpbmcsIGNvZGVzeXN0ZW0gdXJsLCBkdXJhdGlvbiBJbnRlZ2VyKSk6CgovL2RlZmluZSBmdW5jdGlvbiBQYXRpZW50SGFzSHNpc3RvcnlDb25kaXRpb24oaWQgU3RyaW5nLGNvZGVzeXN0ZW0gdXJsICwgZHVyYXRpb24gSW50ZWdlcik6Ci8vZGVmaW5lIGZ1bmN0aW9uIFBhdGllbnRIYXNIc2lzdG9yeUNvbmRpdGlvbkZyb21WYWx1ZVNldChpZCBTdHJpbmcsY29kZXN5c3RlbSB1cmwgLCBkdXJhdGlvbiBJbnRlZ2VyKToKCgovLyBQYXRpZW50SGFzU3ltcHRvbSgic3ltcHRvbSBuYW1lIik6IHN5bXB0b20gaW4gdGhlIGVuY291bnRlcgoKCi8vIFBhdGllbnRMYXN0TWVhc3VyZU9mKCJtZWFzdXJlIG5hbWUiKTogbWVhc3VyZSBpbiB0aGUgZW5jb3VudGVyCgovLyBQYXRpZW50TGFzdEhpc3RvcmljTWVhc3VyZU9mKCJtZWFzdXJlIG5hbWUiLCBkdXJhdGlvbik6IG1lYXN1cmUgaW4gdGhlIHBhdGllbnQgaGlzdG9yeSBkdXJpbmcgZHVyYXRpb24KCi8vIFBhdGllbnRIYXNEaWFnbm9zdGljKCJEaWFnbm9zdGljIG5hbWUiICk6IERpYWdub3N0aWMgaW4gdGhlIGVuY291bnRlcgoKLy8gUGF0aWVudEhhc0hpc3RvcnlPZkRpYWdub3N0aWMoIkRpYWdub3N0aWMgbmFtZSIsIGR1cmF0aW9uICk6IERpYWdub3N0aWMgaW4gdGhlIHBhdGllbnQgaGlzdG9yeSBkdXJpbmcgZHVyYXRpb24KCi8vIFBhdGllbnRIYXNQcm9wb3NlZG9yQ29uZmlybWVkRGlhbm9zdGljKCJEaWFnbm9zdGljIG5hbWUiICk6IERpYWdub3N0aWMgaW4gdGhlIGVuY291bnRlcgoKLy8gUGF0aWVudEhhc0hpc3RvcnlPZlByb3Bvc2Vkb3JDb25maXJtZWREaWFub3N0aWMoIkRpYWdub3N0aWMgbmFtZSIsIGR1cmF0aW9uICk6IERpYWdub3N0aWMgaW4gdGhlIHBhdGllbnQgaGlzdG9yeSBkdXJpbmcgZHVyYXRpb24KCi8vIFBhdGllbnRaU2NvcmVXZkEod2llZ2h0LCBhZ2UpCgovLyBQYXRpZW50V2VpZ2h0RnJvbVdmQShhZ2UsIE11YWMpCg=="/>
  </content>
</Library>