From ebecbd398460fd71a4212b66bf251bfdebad87a6 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Thu, 13 Jun 2013 11:59:38 -0700 Subject: [PATCH 001/117] Update Patient API documentation --- public/patientapi/files.html | 10 +- public/patientapi/index.html | 26 +- public/patientapi/symbols/__hasProp.html | 8 +- public/patientapi/symbols/_global_.html | 8 +- public/patientapi/symbols/hQuery.Actor.html | 8 +- public/patientapi/symbols/hQuery.Address.html | 8 +- .../symbols/hQuery.AdministrationTiming.html | 8 +- public/patientapi/symbols/hQuery.Allergy.html | 40 +- .../symbols/hQuery.CauseOfDeath.html | 8 +- .../patientapi/symbols/hQuery.CodedEntry.html | 407 +- .../symbols/hQuery.CodedEntryList.html | 285 +- .../patientapi/symbols/hQuery.CodedValue.html | 8 +- .../patientapi/symbols/hQuery.Condition.html | 107 +- .../patientapi/symbols/hQuery.DateRange.html | 8 +- .../symbols/hQuery.DoseRestriction.html | 8 +- .../patientapi/symbols/hQuery.Encounter.html | 40 +- .../patientapi/symbols/hQuery.Facility.html | 452 ++ .../symbols/hQuery.Fulfillment.html | 8 +- .../symbols/hQuery.FunctionalStatus.html | 558 ++ .../symbols/hQuery.Immunization.html | 25 +- .../patientapi/symbols/hQuery.Informant.html | 8 +- .../patientapi/symbols/hQuery.Language.html | 25 +- .../patientapi/symbols/hQuery.Medication.html | 81 +- .../symbols/hQuery.MedicationInformation.html | 8 +- .../symbols/hQuery.NoImmunization.html | 25 +- .../symbols/hQuery.OrderInformation.html | 8 +- .../symbols/hQuery.Organization.html | 8 +- public/patientapi/symbols/hQuery.Patient.html | 234 +- public/patientapi/symbols/hQuery.Person.html | 8 +- .../symbols/hQuery.PhysicalQuantity.html | 509 ++ .../patientapi/symbols/hQuery.Pregnancy.html | 40 +- .../patientapi/symbols/hQuery.Procedure.html | 40 +- .../patientapi/symbols/hQuery.Provider.html | 8 +- public/patientapi/symbols/hQuery.Result.html | 116 +- public/patientapi/symbols/hQuery.Scalar.html | 8 +- public/patientapi/symbols/hQuery.Status.html | 25 +- .../symbols/hQuery.StatusOfMedication.html | 25 +- .../patientapi/symbols/hQuery.Supports.html | 8 +- public/patientapi/symbols/hQuery.Telecom.html | 8 +- .../symbols/hQuery.TypeOfMedication.html | 25 +- .../symbols/src/tmp_patient.js.html | 4893 ++++++++++------- 41 files changed, 6114 insertions(+), 2026 deletions(-) create mode 100644 public/patientapi/symbols/hQuery.Facility.html create mode 100644 public/patientapi/symbols/hQuery.FunctionalStatus.html create mode 100644 public/patientapi/symbols/hQuery.PhysicalQuantity.html diff --git a/public/patientapi/files.html b/public/patientapi/files.html index 1264c28..4c0a18c 100644 --- a/public/patientapi/files.html +++ b/public/patientapi/files.html @@ -212,8 +212,12 @@

Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -234,6 +238,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -263,7 +269,7 @@

    File Index

    -

    tmp\patient.js

    +

    tmp/patient.js

    @@ -278,7 +284,7 @@

    tmp\patient.js

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:47 GMT-0700 (PDT)
    \ No newline at end of file diff --git a/public/patientapi/index.html b/public/patientapi/index.html index 119d7d9..a055550 100644 --- a/public/patientapi/index.html +++ b/public/patientapi/index.html @@ -212,8 +212,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -234,6 +238,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -349,12 +355,24 @@

    hQuery.Encounter


    +
    +

    hQuery.Facility

    + a Facility +
    +
    +

    hQuery.Fulfillment

    Fulfillment - information about when and who fulfilled an order for the medication

    +
    +

    hQuery.FunctionalStatus

    + +
    +
    +

    hQuery.Immunization

    represents a immunization entry for a patient. @@ -415,6 +433,12 @@

    hQuery.Person


    +
    +

    hQuery.PhysicalQuantity

    + PhysicalQuantity - a representation of a physical quantity +
    +
    +

    hQuery.Pregnancy

    @@ -480,7 +504,7 @@

    hQuery.TypeOfMedication
    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:47 GMT-0700 (PDT)
    \ No newline at end of file diff --git a/public/patientapi/symbols/__hasProp.html b/public/patientapi/symbols/__hasProp.html index 9769c2c..e7bfd7f 100644 --- a/public/patientapi/symbols/__hasProp.html +++ b/public/patientapi/symbols/__hasProp.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -361,7 +367,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/_global_.html b/public/patientapi/symbols/_global_.html index a6bf542..5d3bf4c 100644 --- a/public/patientapi/symbols/_global_.html +++ b/public/patientapi/symbols/_global_.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -388,7 +394,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Actor.html b/public/patientapi/symbols/hQuery.Actor.html index 569b011..ffc00a9 100644 --- a/public/patientapi/symbols/hQuery.Actor.html +++ b/public/patientapi/symbols/hQuery.Actor.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -497,7 +503,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Address.html b/public/patientapi/symbols/hQuery.Address.html index 0285496..21c9dd0 100644 --- a/public/patientapi/symbols/hQuery.Address.html +++ b/public/patientapi/symbols/hQuery.Address.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -593,7 +599,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.AdministrationTiming.html b/public/patientapi/symbols/hQuery.AdministrationTiming.html index 88b7053..62f2fee 100644 --- a/public/patientapi/symbols/hQuery.AdministrationTiming.html +++ b/public/patientapi/symbols/hQuery.AdministrationTiming.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -517,7 +523,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Allergy.html b/public/patientapi/symbols/hQuery.Allergy.html index 7713e14..3f809c7 100644 --- a/public/patientapi/symbols/hQuery.Allergy.html +++ b/public/patientapi/symbols/hQuery.Allergy.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -300,7 +306,7 @@

     
    @@ -347,7 +353,7 @@

    <inner>   -
    Allergy() +
    Allergy(json)
    @@ -400,7 +406,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, freeTextType, id, includesCodeFrom, type
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, startDate, status, statusCode, timeStamp, type, values
    @@ -415,7 +421,7 @@

    - hQuery.Allergy() + hQuery.Allergy(_super)
    @@ -427,6 +433,17 @@

    +
    +
    Parameters:
    + +
    + _super + +
    +
    + +
    + @@ -507,7 +524,7 @@

    <inner> - Allergy() + Allergy(json)
    @@ -519,6 +536,17 @@

    +
    +
    Parameters:
    + +
    + json + +
    +
    + +
    + @@ -694,7 +722,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.CauseOfDeath.html b/public/patientapi/symbols/hQuery.CauseOfDeath.html index 56c32fc..6853149 100644 --- a/public/patientapi/symbols/hQuery.CauseOfDeath.html +++ b/public/patientapi/symbols/hQuery.CauseOfDeath.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -511,7 +517,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.CodedEntry.html b/public/patientapi/symbols/hQuery.CodedEntry.html index c88b8fd..a279fdd 100644 --- a/public/patientapi/symbols/hQuery.CodedEntry.html +++ b/public/patientapi/symbols/hQuery.CodedEntry.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -342,6 +348,15 @@

    + +   + +
    endDate() +
    +
    Date and time at which the coded entry ended
    + + +   @@ -354,18 +369,82 @@

      -
    id() + -
    Unique identifier for this coded entry
    +
    Returns true if any of this entry codes match a code in the supplied codeSet.
      -
    includesCodeFrom(codeSet) + +
    Determines whether the entry specifies a time range or not
    + + + + +   + + +
    Determines whether a coded entry contains sufficient information (code and at least + one time stamp) to be usable
    + + + + +   + + +
    + + + + +   + + +
    Indicates the reason an entry was negated.
    + + + + +   + + +
    Date and time at which the coded entry started
    + + + + +   + + -
    Returns true if any of this entry's codes match a code in the supplied codeSet.
    +
    Status for this coded entry
    + + + + +   + + +
    Status for this coded entry
    + + + + +   + + +
    Tries to find a single point in time for this entry.
    @@ -378,6 +457,15 @@

    + +   + +
    values() +
    +
    Returns the values of the result.
    + + + @@ -494,15 +582,15 @@


    - +
    - {String} - freeTextType() + {Date} + endDate()
    - A free text description of the type of coded entry + Date and time at which the coded entry ended
    @@ -517,7 +605,7 @@

    Returns:
    -
    {String}
    +
    {Date}
    @@ -526,15 +614,15 @@


    - +
    {String} - id() + freeTextType()
    - Unique identifier for this coded entry + A free text description of the type of coded entry
    @@ -566,7 +654,7 @@

    - Returns true if any of this entry's codes match a code in the supplied codeSet. + Returns true if any of this entry codes match a code in the supplied codeSet.
    @@ -599,6 +687,264 @@

    +
    + + +
    + + {boolean} + isTimeRange() + +
    +
    + Determines whether the entry specifies a time range or not + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {boolean}
    + +
    + + + + +
    + + +
    + + {boolean} + isUsable() + +
    +
    + Determines whether a coded entry contains sufficient information (code and at least + one time stamp) to be usable + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {boolean}
    + +
    + + + + +
    + + +
    + + {Boolean} + negationInd() + +
    +
    + + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {Boolean} whether the entry was negated
    + +
    + + + + +
    + + +
    + + {hQuery.CodedValue} + negationReason() + +
    +
    + Indicates the reason an entry was negated. + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {hQuery.CodedValue} Used to indicate reason an immunization was not administered.
    + +
    + + + + +
    + + +
    + + {Date} + startDate() + +
    +
    + Date and time at which the coded entry started + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {Date}
    + +
    + + + + +
    + + +
    + + {String} + status() + +
    +
    + Status for this coded entry + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {String}
    + +
    + + + + +
    + + +
    + + {Hash} + statusCode() + +
    +
    + Status for this coded entry + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {Hash} keys are code systems, values are arrays of codes
    + +
    + + + + +
    + + +
    + + {Date} + timeStamp() + +
    +
    + Tries to find a single point in time for this entry. Will first return date if it is present, + then fall back to startDate and finally endDate + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {Date}
    + +
    + + + +
    @@ -631,6 +977,39 @@

    +
    + + +
    + + {Array} + values() + +
    +
    + Returns the values of the result. This will return an array that contains + PhysicalQuantity or CodedValue objects depending on the result type. + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {Array} containing either PhysicalQuantity and/or CodedValues
    + +
    + + + + @@ -645,7 +1024,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.CodedEntryList.html b/public/patientapi/symbols/hQuery.CodedEntryList.html index ddfdeab..47d6f22 100644 --- a/public/patientapi/symbols/hQuery.CodedEntryList.html +++ b/public/patientapi/symbols/hQuery.CodedEntryList.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -299,7 +305,7 @@

     
    @@ -337,13 +343,58 @@

      -
    match(codeSet, start, end) +
    concat(otherEntries) +
    +
    Return a new list of entries that is the result of concatenating the passed in entries with this list
    + + + + +   + +
    match(codeSet, start, end, includeNegated)
    Return the number of entries that match the supplied code set where those entries occur between the supplied time bounds
    + +   + + +
    Push the supplied entry onto this list if it is usable
    + + + + +   + +
    withNegation(codeSet) +
    +
    Filter entries based on negation
    + + + + +   + + +
    Filter entries based on negation
    + + + + +   + +
    withStatuses(statuses, includeUndefined) +
    +
    Match entries with the specified statuses
    + + + @@ -361,7 +412,7 @@

    - hQuery.CodedEntryList() + hQuery.CodedEntryList(_super)
    @@ -373,6 +424,17 @@

    +
    +
    Parameters:
    + +
    + _super + +
    +
    + +
    + @@ -415,13 +477,56 @@

    +
    + + +
    + + {CodedEntryList} + concat(otherEntries) + +
    +
    + Return a new list of entries that is the result of concatenating the passed in entries with this list + + +
    + + + + +
    +
    Parameters:
    + +
    + otherEntries + +
    +
    + +
    + + + + + +
    +
    Returns:
    + +
    {CodedEntryList} the set of concatenated entries
    + +
    + + + +
    - {Array[CodedEntry]} - match(codeSet, start, end) + {CodedEntryList} + match(codeSet, start, end, includeNegated)
    @@ -455,6 +560,172 @@

    the end of the period during which the entry must occur, a null value will match all times
    +
    + {boolean} includeNegated + +
    +
    whether the returned list of entries should include those that have been negated
    + + + + + + + +
    +
    Returns:
    + +
    {CodedEntryList} the matching entries
    + +
    + + + + +
    + + +
    + + + pushIfUsable(a) + +
    +
    + Push the supplied entry onto this list if it is usable + + +
    + + + + +
    +
    Parameters:
    + +
    + {CodedEntry} a + +
    +
    coded entry that should be added to the list if it is usable
    + +
    + + + + + + + + +
    + + +
    + + {CodedEntryList} + withNegation(codeSet) + +
    +
    + Filter entries based on negation + + +
    + + + + +
    +
    Parameters:
    + +
    + {Object} codeSet + +
    +
    a hash with code system names as keys and an array of codes as values
    + +
    + + + + + +
    +
    Returns:
    + +
    {CodedEntryList} negated entries
    + +
    + + + + +
    + + +
    + + {CodedEntryList} + withoutNegation() + +
    +
    + Filter entries based on negation + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {CodedEntryList} non-negated entries
    + +
    + + + + +
    + + +
    + + {CodedEntryList} + withStatuses(statuses, includeUndefined) + +
    +
    + Match entries with the specified statuses + + +
    + + + + +
    +
    Parameters:
    + +
    + statuses + +
    +
    + +
    + includeUndefined + +
    +
    +
    @@ -464,7 +735,7 @@

    Returns:
    -
    {Array[CodedEntry]} the matching entries
    +
    {CodedEntryList} the matching entries
    @@ -485,7 +756,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.CodedValue.html b/public/patientapi/symbols/hQuery.CodedValue.html index da66fce..4dbfbbd 100644 --- a/public/patientapi/symbols/hQuery.CodedValue.html +++ b/public/patientapi/symbols/hQuery.CodedValue.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -569,7 +575,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Condition.html b/public/patientapi/symbols/hQuery.Condition.html index 772915e..51c435a 100644 --- a/public/patientapi/symbols/hQuery.Condition.html +++ b/public/patientapi/symbols/hQuery.Condition.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -304,7 +310,7 @@

     
    @@ -375,6 +381,15 @@

    + +   + + +
    Ordinality
    + + +   @@ -393,13 +408,22 @@

    + +   + + +
    This is a description of the level of the severity of the condition.
    + + +
    -
    Methods borrowed from class hQuery.CodedEntry:
    date, freeTextType, id, includesCodeFrom, type
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, startDate, status, statusCode, timeStamp, type, values
    @@ -414,7 +438,7 @@

    - hQuery.Condition() + hQuery.Condition(_super)
    @@ -426,6 +450,17 @@

    +
    +
    Parameters:
    + +
    + _super + +
    +
    + +
    + @@ -607,6 +642,38 @@

    +
    + + +
    + + {String} + ordinality() + +
    +
    + Ordinality + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {String}
    + +
    + + + +
    @@ -671,6 +738,38 @@

    +
    + + +
    + + {CodedValue} + severity() + +
    +
    + This is a description of the level of the severity of the condition. + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {CodedValue}
    + +
    + + + + @@ -685,7 +784,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.DateRange.html b/public/patientapi/symbols/hQuery.DateRange.html index 1688b25..5758f4e 100644 --- a/public/patientapi/symbols/hQuery.DateRange.html +++ b/public/patientapi/symbols/hQuery.DateRange.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -497,7 +503,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.DoseRestriction.html b/public/patientapi/symbols/hQuery.DoseRestriction.html index e359240..2d68949 100644 --- a/public/patientapi/symbols/hQuery.DoseRestriction.html +++ b/public/patientapi/symbols/hQuery.DoseRestriction.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -497,7 +503,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Encounter.html b/public/patientapi/symbols/hQuery.Encounter.html index b3fb2e4..080846d 100644 --- a/public/patientapi/symbols/hQuery.Encounter.html +++ b/public/patientapi/symbols/hQuery.Encounter.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -301,7 +307,7 @@

     
    An Encounter is an interaction, regardless of the setting, between a patient and a practitioner who is vested with primary responsibility for diagnosing, evaluating, @@ -350,7 +356,7 @@

    <inner>   -
    Encounter() +
    Encounter(json)
    @@ -398,7 +404,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, freeTextType, id, includesCodeFrom, type
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, startDate, status, statusCode, timeStamp, type, values
    @@ -413,7 +419,7 @@

    - hQuery.Encounter() + hQuery.Encounter(_super)
    @@ -430,6 +436,17 @@

    +
    +
    Parameters:
    + +
    + _super + +
    +
    + +
    + @@ -518,7 +535,7 @@

    <inner> - Encounter() + Encounter(json)
    @@ -530,6 +547,17 @@

    +
    +
    Parameters:
    + +
    + json + +
    +
    + +
    + @@ -679,7 +707,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Facility.html b/public/patientapi/symbols/hQuery.Facility.html new file mode 100644 index 0000000..ada724e --- /dev/null +++ b/public/patientapi/symbols/hQuery.Facility.html @@ -0,0 +1,452 @@ + + + + + + + JsDoc Reference - hQuery.Facility + + + + + + + + + + + + + +
    + +

    + + Class hQuery.Facility +

    + + +

    + + + + a Facility + + +
    Defined in: patient.js. + +

    + + + + + + + + + + + + + + + + + +
    Class Summary
    Constructor AttributesConstructor Name and Description
      +
    + hQuery.Facility(_super) +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    Method Summary
    Method AttributesMethod Name and Description
    <inner>   +
    Facility(json) +
    +
    +
    + + + + + + + + + +
    +
    + Class Detail +
    + +
    + hQuery.Facility(_super) +
    + +
    + + +
    + + + + + +
    +
    Parameters:
    + +
    + _super + +
    +
    + +
    + + + + + + + + +
    + + + + + + + +
    + Method Detail +
    + + +
    <inner> + + + Facility(json) + +
    +
    + + + +
    + + + + +
    +
    Parameters:
    + +
    + json + +
    +
    + +
    + + + + + + + + + + + + + + + +
    +
    + + + +
    + + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) +
    + + diff --git a/public/patientapi/symbols/hQuery.Fulfillment.html b/public/patientapi/symbols/hQuery.Fulfillment.html index 179e3d7..d00cffb 100644 --- a/public/patientapi/symbols/hQuery.Fulfillment.html +++ b/public/patientapi/symbols/hQuery.Fulfillment.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -429,7 +435,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.FunctionalStatus.html b/public/patientapi/symbols/hQuery.FunctionalStatus.html new file mode 100644 index 0000000..b2dba3b --- /dev/null +++ b/public/patientapi/symbols/hQuery.FunctionalStatus.html @@ -0,0 +1,558 @@ + + + + + + + JsDoc Reference - hQuery.FunctionalStatus + + + + + + + + + + + + + +
    + +

    + + Class hQuery.FunctionalStatus +

    + + +

    + +
    Extends + hQuery.CodedEntry.
    + + + + + +
    Defined in: patient.js. + +

    + + + + + + + + + + + + + + + + + +
    Class Summary
    Constructor AttributesConstructor Name and Description
      + +
    This class can be used to represnt a functional status for a patient.
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Method Summary
    Method AttributesMethod Name and Description
    <inner>   + +
    +
      +
    source() +
    +
    A coded value.
    +
      +
    type() +
    +
    Either "condition" or "result"
    +
    + + + +
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, startDate, status, statusCode, timeStamp, values
    +
    + + + + + + + +
    +
    + Class Detail +
    + +
    + hQuery.FunctionalStatus(_super) +
    + +
    + This class can be used to represnt a functional status for a patient. Currently, +it is not a very close representation of functional status as it is represented +in the HL7 CCD, HITSP C32 or Consolidated CDA. + +In the previously mentioned specifications, functional status may represented +using either a condition or result. Having "mixed" types of entries in a section +is currently not well supported in the existing Record class + +Additionally, there is a mismatch between the data needed to calculate Stage 2 +Meaningful Use Quailty Measures and the data contained in patient summary +standards. The CQMs are checking to see if a functional status represented by +a result was patient supplied. Right now, results do not have a source, and +even if we were to use Provider as a source, it would need to be extended +to support patients. + +To avoid this, the patient sumamry style functional status has been "flattened" +into this class. This model supports the information needed to calculate +Stage 2 MU CQMs. If importers are created from C32 or CCDA, the information +can be stored here, but it will be a lossy transformation. + +
    + + + + + +
    +
    Parameters:
    + +
    + _super + +
    +
    + +
    + + + + + + + + +
    + + + + + + + +
    + Method Detail +
    + + +
    <inner> + + + FunctionalStatus(json) + +
    +
    + + + +
    + + + + +
    +
    Parameters:
    + +
    + json + +
    +
    + +
    + + + + + + + + +
    + + +
    + + {hQuery.CodedValue} + source() + +
    +
    + A coded value. Like a code for patient supplied. + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {hQuery.CodedValue}
    + +
    + + + + +
    + + +
    + + {String} + type() + +
    +
    + Either "condition" or "result" + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {String}
    + +
    + + + + + + + + + + + +
    +
    + + + +
    + + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) +
    + + diff --git a/public/patientapi/symbols/hQuery.Immunization.html b/public/patientapi/symbols/hQuery.Immunization.html index 1803d7c..9287337 100644 --- a/public/patientapi/symbols/hQuery.Immunization.html +++ b/public/patientapi/symbols/hQuery.Immunization.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -300,7 +306,7 @@

     
    @@ -406,7 +412,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, freeTextType, id, includesCodeFrom, type
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, startDate, status, statusCode, timeStamp, type, values
    @@ -421,7 +427,7 @@

    - hQuery.Immunization() + hQuery.Immunization(_super)
    @@ -433,6 +439,17 @@

    +
    +
    Parameters:
    + +
    + _super + +
    +
    + +
    + @@ -698,7 +715,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Informant.html b/public/patientapi/symbols/hQuery.Informant.html index 4baf6e1..3b96635 100644 --- a/public/patientapi/symbols/hQuery.Informant.html +++ b/public/patientapi/symbols/hQuery.Informant.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -512,7 +518,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Language.html b/public/patientapi/symbols/hQuery.Language.html index 0647156..682fab0 100644 --- a/public/patientapi/symbols/hQuery.Language.html +++ b/public/patientapi/symbols/hQuery.Language.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -300,7 +306,7 @@

     
    @@ -359,7 +365,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, freeTextType, id, includesCodeFrom, type
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, startDate, status, statusCode, timeStamp, type, values
    @@ -374,7 +380,7 @@

    - hQuery.Language() + hQuery.Language(_super)
    @@ -386,6 +392,17 @@

    +
    +
    Parameters:
    + +
    + _super + +
    +
    + +
    + @@ -517,7 +534,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Medication.html b/public/patientapi/symbols/hQuery.Medication.html index fbdf784..ff19ecf 100644 --- a/public/patientapi/symbols/hQuery.Medication.html +++ b/public/patientapi/symbols/hQuery.Medication.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -300,7 +306,7 @@

     
    @@ -335,6 +341,15 @@

    + +   + + +
    The duration over which this medication has been active.
    + + +   @@ -428,7 +443,7 @@

    <inner>   -
    Medication() +
    Medication(json)
    @@ -531,7 +546,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, freeTextType, id, includesCodeFrom, type
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, startDate, status, statusCode, timeStamp, type, values
    @@ -546,7 +561,7 @@

    - hQuery.Medication() + hQuery.Medication(_super)
    @@ -558,6 +573,17 @@

    +
    +
    Parameters:
    + +
    + _super + +
    +
    + +
    + @@ -600,6 +626,38 @@

    +
    + + +
    + + {Hash} + cumulativeMedicationDuration() + +
    +
    + The duration over which this medication has been active. For example, 5 days. + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {Hash} with two keys: unit and scalar
    + +
    + + + +
    @@ -928,7 +986,7 @@

    <inner> - Medication() + Medication(json)
    @@ -940,6 +998,17 @@

    +
    +
    Parameters:
    + +
    + json + +
    +
    + +
    + @@ -1289,7 +1358,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.MedicationInformation.html b/public/patientapi/symbols/hQuery.MedicationInformation.html index cd5ce63..30d7f33 100644 --- a/public/patientapi/symbols/hQuery.MedicationInformation.html +++ b/public/patientapi/symbols/hQuery.MedicationInformation.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -606,7 +612,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.NoImmunization.html b/public/patientapi/symbols/hQuery.NoImmunization.html index 81195d6..e56d48b 100644 --- a/public/patientapi/symbols/hQuery.NoImmunization.html +++ b/public/patientapi/symbols/hQuery.NoImmunization.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -300,7 +306,7 @@

     
    NoImmunzation as defined by value set 2.16.840.1.113883.1.11.19717 The terms come from Health Level Seven (HL7) Version 3.0 Vocabulary and are managed by HL7 @@ -415,7 +421,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, freeTextType, id, includesCodeFrom, type
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, startDate, status, statusCode, timeStamp, type, values
    @@ -430,7 +436,7 @@

    - hQuery.NoImmunization() + hQuery.NoImmunization(_super)
    @@ -444,6 +450,17 @@

    +
    +
    Parameters:
    + +
    + _super + +
    +
    + +
    + @@ -756,7 +773,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.OrderInformation.html b/public/patientapi/symbols/hQuery.OrderInformation.html index b21e8ac..5f30f99 100644 --- a/public/patientapi/symbols/hQuery.OrderInformation.html +++ b/public/patientapi/symbols/hQuery.OrderInformation.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -599,7 +605,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Organization.html b/public/patientapi/symbols/hQuery.Organization.html index 1191212..c49aba3 100644 --- a/public/patientapi/symbols/hQuery.Organization.html +++ b/public/patientapi/symbols/hQuery.Organization.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -593,7 +599,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Patient.html b/public/patientapi/symbols/hQuery.Patient.html index b67543b..2de57e3 100644 --- a/public/patientapi/symbols/hQuery.Patient.html +++ b/public/patientapi/symbols/hQuery.Patient.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -300,7 +306,7 @@

     
    @@ -362,6 +368,24 @@

    + +   + + +
    + + + + +   + + +
    + + +   @@ -407,6 +431,24 @@

    + +   + +
    expired() +
    +
    + + + + +   + + +
    + + +   @@ -443,6 +485,15 @@

    + +   + + +
    + + +   @@ -518,7 +569,7 @@

      -
    socialhistories() +
    @@ -563,7 +614,7 @@

    - hQuery.Patient() + hQuery.Patient(_super)
    @@ -575,6 +626,17 @@

    +
    +
    Parameters:
    + +
    + _super + +
    +
    + +
    + @@ -731,6 +793,70 @@

    +
    + + +
    + + {hQuery.CodedEntryList} + careGoals() + +
    +
    + + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {hQuery.CodedEntryList} A list of CareGoal objects
    + +
    + + + + +
    + + +
    + + {Boolean} + clinicalTrialParticipant() + +
    +
    + + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {Boolean} returns true if the patient participated in a clinical trial
    + +
    + + + +
    @@ -893,6 +1019,70 @@

    +
    + + +
    + + {Boolean} + expired() + +
    +
    + + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {Boolean} returns true if the patient has died
    + +
    + + + + +
    + + +
    + + {hQuery.CodedEntryList} + functionalStatuses() + +
    +
    + + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {hQuery.CodedEntryList} A list of FunctionalStatus objects
    + +
    + + + +
    @@ -1032,6 +1222,38 @@

    +
    + + +
    + + {hQuery.CodedEntryList} + medicalEquipment() + +
    +
    + + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {hQuery.CodedEntryList} A list of MedicalEquipment objects
    + +
    + + + +
    @@ -1285,11 +1507,11 @@


    - +
    {hQuery.CodedEntryList} - socialhistories() + socialHistories()
    @@ -1393,7 +1615,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Person.html b/public/patientapi/symbols/hQuery.Person.html index f8f49e0..9ff67c0 100644 --- a/public/patientapi/symbols/hQuery.Person.html +++ b/public/patientapi/symbols/hQuery.Person.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -634,7 +640,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.PhysicalQuantity.html b/public/patientapi/symbols/hQuery.PhysicalQuantity.html new file mode 100644 index 0000000..d133536 --- /dev/null +++ b/public/patientapi/symbols/hQuery.PhysicalQuantity.html @@ -0,0 +1,509 @@ + + + + + + + JsDoc Reference - hQuery.PhysicalQuantity + + + + + + + + + + + + + +
    + +

    + + Class hQuery.PhysicalQuantity +

    + + +

    + + + + PhysicalQuantity - a representation of a physical quantity + + +
    Defined in: patient.js. + +

    + + + + + + + + + + + + + + + + + +
    Class Summary
    Constructor AttributesConstructor Name and Description
      + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Method Summary
    Method AttributesMethod Name and Description
    <inner>   + +
    +
      +
    scalar() +
    +
    +
      +
    units() +
    +
    +
    + + + + + + + + + +
    +
    + Class Detail +
    + +
    + hQuery.PhysicalQuantity() +
    + +
    + + +
    + + + + + + + + + + + + +
    + + + + + + + +
    + Method Detail +
    + + +
    <inner> + + + PhysicalQuantity(json) + +
    +
    + + + +
    + + + + +
    +
    Parameters:
    + +
    + json + +
    +
    + +
    + + + + + + + + +
    + + +
    + + + scalar() + +
    +
    + + + +
    + + + + + + + + + + + +
    + + +
    + + + units() + +
    +
    + + + +
    + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) +
    + + diff --git a/public/patientapi/symbols/hQuery.Pregnancy.html b/public/patientapi/symbols/hQuery.Pregnancy.html index 7db5004..7186503 100644 --- a/public/patientapi/symbols/hQuery.Pregnancy.html +++ b/public/patientapi/symbols/hQuery.Pregnancy.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -300,7 +306,7 @@

     
    This includes information about the patients current and past pregnancy status The Coded Entry code system should be SNOMED-CT
    @@ -339,7 +345,7 @@

    <inner>   -
    Pregnancy() +
    Pregnancy(json)
    @@ -351,7 +357,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, freeTextType, id, includesCodeFrom, type
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, startDate, status, statusCode, timeStamp, type, values
    @@ -366,7 +372,7 @@

    - hQuery.Pregnancy() + hQuery.Pregnancy(_super)
    @@ -379,6 +385,17 @@

    +
    +
    Parameters:
    + +
    + _super + +
    +
    + +
    + @@ -434,7 +451,7 @@

    <inner> - Pregnancy() + Pregnancy(json)
    @@ -446,6 +463,17 @@

    +
    +
    Parameters:
    + +
    + json + +
    +
    + +
    + @@ -467,7 +495,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Procedure.html b/public/patientapi/symbols/hQuery.Procedure.html index 12d11b4..62c82aa 100644 --- a/public/patientapi/symbols/hQuery.Procedure.html +++ b/public/patientapi/symbols/hQuery.Procedure.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -300,7 +306,7 @@

     
    This represents all interventional, surgical, diagnostic, or therapeutic procedures or treatments pertinent to the patient.
    @@ -339,7 +345,7 @@

    <inner>   -
    Procedure() +
    Procedure(json)
    @@ -360,7 +366,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, freeTextType, id, includesCodeFrom, type
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, startDate, status, statusCode, timeStamp, type, values
    @@ -375,7 +381,7 @@

    - hQuery.Procedure() + hQuery.Procedure(_super)
    @@ -388,6 +394,17 @@

    +
    +
    Parameters:
    + +
    + _super + +
    +
    + +
    + @@ -443,7 +460,7 @@

    <inner> - Procedure() + Procedure(json)
    @@ -455,6 +472,17 @@

    +
    +
    Parameters:
    + +
    + json + +
    +
    + +
    + @@ -509,7 +537,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:47 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Provider.html b/public/patientapi/symbols/hQuery.Provider.html index aa04ef5..410988f 100644 --- a/public/patientapi/symbols/hQuery.Provider.html +++ b/public/patientapi/symbols/hQuery.Provider.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -716,7 +722,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:47 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Result.html b/public/patientapi/symbols/hQuery.Result.html index e351657..14bebd3 100644 --- a/public/patientapi/symbols/hQuery.Result.html +++ b/public/patientapi/symbols/hQuery.Result.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -300,7 +306,7 @@

     
    Observations generated by laboratories, imaging procedures, and other procedures.
    @@ -356,7 +362,7 @@

    <inner>   -
    Result() +
    Result(json)
    @@ -373,31 +379,13 @@

    - -   - -
    status() -
    -
    A status from the HL7 ActStatusNormal vocabulary
    - - - - -   - -
    value() -
    -
    Returns the value of the result.
    - - -
    -
    Methods borrowed from class hQuery.CodedEntry:
    date, freeTextType, id, includesCodeFrom, type
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, startDate, status, statusCode, timeStamp, type, values
    @@ -412,7 +400,7 @@

    - hQuery.Result() + hQuery.Result(_super)
    @@ -427,6 +415,17 @@

    +
    +
    Parameters:
    + +
    + _super + +
    +
    + +
    + @@ -546,7 +545,7 @@

    <inner> - Result() + Result(json)
    @@ -558,6 +557,17 @@

    +
    +
    Parameters:
    + +
    + json + +
    +
    + +
    + @@ -599,64 +609,6 @@

    -
    - - -
    - - {String} - status() - -
    -
    - A status from the HL7 ActStatusNormal vocabulary - - -
    - - - - - - - - -
    -
    Returns:
    - -
    {String}
    - -
    - - - - -
    - - -
    - - - value() - -
    -
    - Returns the value of the result. This will return an object. The properties of this - object are dependent on the type of result. - - -
    - - - - - - - - - - - @@ -671,7 +623,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:47 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Scalar.html b/public/patientapi/symbols/hQuery.Scalar.html index 8b73e14..7effc23 100644 --- a/public/patientapi/symbols/hQuery.Scalar.html +++ b/public/patientapi/symbols/hQuery.Scalar.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -497,7 +503,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:47 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Status.html b/public/patientapi/symbols/hQuery.Status.html index f5987a4..5d84a27 100644 --- a/public/patientapi/symbols/hQuery.Status.html +++ b/public/patientapi/symbols/hQuery.Status.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -300,7 +306,7 @@

     
    Status as defined by value set 2.16.840.1.113883.5.14, the ActStatus vocabulary maintained by HL7
    @@ -432,7 +438,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, freeTextType, id, includesCodeFrom, type
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, startDate, status, statusCode, timeStamp, type, values
    @@ -447,7 +453,7 @@

    - hQuery.Status() + hQuery.Status(_super)
    @@ -460,6 +466,17 @@

    +
    +
    Parameters:
    + +
    + _super + +
    +
    + +
    + @@ -766,7 +783,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:47 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.StatusOfMedication.html b/public/patientapi/symbols/hQuery.StatusOfMedication.html index 6490f6d..370d17f 100644 --- a/public/patientapi/symbols/hQuery.StatusOfMedication.html +++ b/public/patientapi/symbols/hQuery.StatusOfMedication.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -300,7 +306,7 @@

     
    StatusOfMedication as defined by value set 2.16.840.1.113883.1.11.20.7 The terms come from SNOMED and are managed by HL7
    @@ -378,7 +384,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, freeTextType, id, includesCodeFrom, type
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, startDate, status, statusCode, timeStamp, type, values
    @@ -393,7 +399,7 @@

    - hQuery.StatusOfMedication() + hQuery.StatusOfMedication(_super)
    @@ -406,6 +412,17 @@

    +
    +
    Parameters:
    + +
    + _super + +
    +
    + +
    + @@ -590,7 +607,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:47 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Supports.html b/public/patientapi/symbols/hQuery.Supports.html index 2fd6ea3..ffc4891 100644 --- a/public/patientapi/symbols/hQuery.Supports.html +++ b/public/patientapi/symbols/hQuery.Supports.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -634,7 +640,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:47 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Telecom.html b/public/patientapi/symbols/hQuery.Telecom.html index e7ad487..99f2c3e 100644 --- a/public/patientapi/symbols/hQuery.Telecom.html +++ b/public/patientapi/symbols/hQuery.Telecom.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -594,7 +600,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:47 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.TypeOfMedication.html b/public/patientapi/symbols/hQuery.TypeOfMedication.html index c1508a0..0207a2c 100644 --- a/public/patientapi/symbols/hQuery.TypeOfMedication.html +++ b/public/patientapi/symbols/hQuery.TypeOfMedication.html @@ -217,8 +217,12 @@

    Classes

  • hQuery.Encounter
  • +
  • hQuery.Facility
  • +
  • hQuery.Fulfillment
  • +
  • hQuery.FunctionalStatus
  • +
  • hQuery.Immunization
  • hQuery.Informant
  • @@ -239,6 +243,8 @@

    Classes

  • hQuery.Person
  • +
  • hQuery.PhysicalQuantity
  • +
  • hQuery.Pregnancy
  • hQuery.Procedure
  • @@ -301,7 +307,7 @@

     
    TypeOfMedication as defined by value set 2.16.840.1.113883.3.88.12.3221.8.19 which pulls two values from SNOMED to describe whether a medication is @@ -362,7 +368,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, freeTextType, id, includesCodeFrom, type
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, startDate, status, statusCode, timeStamp, type, values
    @@ -377,7 +383,7 @@

    - hQuery.TypeOfMedication() + hQuery.TypeOfMedication(_super)
    @@ -391,6 +397,17 @@

    +
    +
    Parameters:
    + +
    + _super + +
    +
    + +
    + @@ -511,7 +528,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Oct 28 2011 09:44:47 GMT-0400 (EDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:47 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/src/tmp_patient.js.html b/public/patientapi/symbols/src/tmp_patient.js.html index a4ba231..a72197a 100644 --- a/public/patientapi/symbols/src/tmp_patient.js.html +++ b/public/patientapi/symbols/src/tmp_patient.js.html @@ -8,1875 +8,3094 @@
      1 /**
       2 @namespace scoping into the hquery namespace
       3 */
    -  4 var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
    -  5   for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
    -  6   function ctor() { this.constructor = child; }
    -  7   ctor.prototype = parent.prototype;
    -  8   child.prototype = new ctor;
    -  9   child.__super__ = parent.prototype;
    - 10   return child;
    - 11 };
    - 12 this.hQuery || (this.hQuery = {});
    - 13 /**
    - 14 Converts a a number in UTC Seconds since the epoch to a date.
    - 15 @param {number} utcSeconds seconds since the epoch in UTC
    - 16 @returns {Date}
    - 17 @function
    - 18 @exports dateFromUtcSeconds as hQuery.dateFromUtcSeconds
    - 19 */
    - 20 hQuery.dateFromUtcSeconds = function(utcSeconds) {
    - 21   return new Date(utcSeconds * 1000);
    - 22 };
    - 23 /**
    - 24 @class Scalar - a representation of a unit and value
    - 25 @exports Scalar as hQuery.Scalar
    - 26 */
    - 27 hQuery.Scalar = (function() {
    - 28   function Scalar(json) {
    - 29     this.json = json;
    - 30   }
    - 31   Scalar.prototype.unit = function() {
    - 32     return this.json['unit'];
    - 33   };
    - 34   Scalar.prototype.value = function() {
    - 35     return this.json['value'];
    - 36   };
    - 37   return Scalar;
    - 38 })();
    - 39 /**
    - 40 @class A code with its corresponding code system
    - 41 @exports CodedValue as hQuery.CodedValue
    - 42 */
    - 43 hQuery.CodedValue = (function() {
    - 44   /**
    - 45   @param {String} c value of the code
    - 46   @param {String} csn name of the code system that the code belongs to
    - 47   @constructs
    - 48   */  function CodedValue(c, csn) {
    - 49     this.c = c;
    - 50     this.csn = csn;
    - 51   }
    - 52   /**
    - 53   @returns {String} the code
    - 54   */
    - 55   CodedValue.prototype.code = function() {
    - 56     return this.c;
    - 57   };
    - 58   /**
    - 59   @returns {String} the code system name
    - 60   */
    - 61   CodedValue.prototype.codeSystemName = function() {
    - 62     return this.csn;
    - 63   };
    - 64   /**
    - 65   Returns true if the contained code and codeSystemName match a code in the supplied codeSet.
    - 66   @param {Object} codeSet a hash with code system names as keys and an array of codes as values
    - 67   @returns {boolean}
    - 68   */
    - 69   CodedValue.prototype.includedIn = function(codeSet) {
    - 70     var code, codeSystemName, codes, _i, _len;
    - 71     for (codeSystemName in codeSet) {
    - 72       codes = codeSet[codeSystemName];
    - 73       if (this.csn === codeSystemName) {
    - 74         for (_i = 0, _len = codes.length; _i < _len; _i++) {
    - 75           code = codes[_i];
    - 76           if (code === this.c) {
    - 77             return true;
    - 78           }
    - 79         }
    - 80       }
    - 81     }
    - 82     return false;
    - 83   };
    - 84   return CodedValue;
    - 85 })();
    - 86 /**
    - 87 Status as defined by value set 2.16.840.1.113883.5.14,
    - 88 the ActStatus vocabulary maintained by HL7
    - 89 
    - 90 @class Status
    - 91 @augments hQuery.CodedEntry
    - 92 @exports Status as hQuery.Status
    - 93 */
    - 94 hQuery.Status = (function() {
    - 95   var ABORTED, ACTIVE, CANCELLED, COMPLETED, HELD, NEW, NORMAL, NULLIFIED, OBSOLETE, SUSPENDED;
    - 96   __extends(Status, hQuery.CodedValue);
    - 97   function Status() {
    - 98     Status.__super__.constructor.apply(this, arguments);
    - 99   }
    -100   NORMAL = "normal";
    -101   ABORTED = "aborted";
    -102   ACTIVE = "active";
    -103   CANCELLED = "cancelled";
    -104   COMPLETED = "completed";
    -105   HELD = "held";
    -106   NEW = "new";
    -107   SUSPENDED = "suspended";
    -108   NULLIFIED = "nullified";
    -109   OBSOLETE = "obsolete";
    -110   Status.prototype.isNormal = function() {
    -111     return this.c === NORMAL;
    -112   };
    -113   Status.prototype.isAborted = function() {
    -114     return this.c === ABORTED;
    -115   };
    -116   Status.prototype.isActive = function() {
    -117     return this.c === ACTIVE;
    -118   };
    -119   Status.prototype.isCancelled = function() {
    -120     return this.c === CANCELLED;
    -121   };
    -122   Status.prototype.isCompleted = function() {
    -123     return this.c === COMPLETED;
    -124   };
    -125   Status.prototype.isHeld = function() {
    -126     return this.c === HELD;
    -127   };
    -128   Status.prototype.isNew = function() {
    -129     return this.c === NEW;
    -130   };
    -131   Status.prototype.isSuspended = function() {
    -132     return this.c === SUSPENDED;
    -133   };
    -134   Status.prototype.isNullified = function() {
    -135     return this.c === NULLIFIED;
    -136   };
    -137   Status.prototype.isObsolete = function() {
    -138     return this.c === OBSOLETE;
    -139   };
    -140   return Status;
    -141 })();
    -142 /**
    -143 @class an Address for a person or organization
    -144 @exports Address as hQuery.Address
    -145 */
    -146 hQuery.Address = (function() {
    -147   function Address(json) {
    -148     this.json = json;
    -149   }
    -150   /**
    -151   @returns {Array[String]} the street addresses
    -152   */
    -153   Address.prototype.street = function() {
    -154     return this.json['streetAddress'];
    -155   };
    -156   /**
    -157   @returns {String} the city
    -158   */
    -159   Address.prototype.city = function() {
    -160     return this.json['city'];
    -161   };
    -162   /**
    -163   @returns {String} the State
    -164   */
    -165   Address.prototype.state = function() {
    -166     return this.json['stateOrProvince'];
    -167   };
    -168   /**
    -169   @returns {String} the postal code
    -170   */
    -171   Address.prototype.postalCode = function() {
    -172     return this.json['zip'];
    -173   };
    -174   return Address;
    -175 })();
    -176 /**
    -177 @class An object that describes a means to contact an entity.  This is used to represent
    -178 phone numbers, email addresses,  instant messaging accounts etc.
    -179 @exports Telecom as hQuery.Telecom
    -180 */
    -181 hQuery.Telecom = (function() {
    -182   function Telecom(json) {
    -183     this.json = json;
    -184   }
    -185   /**
    -186   @returns {String} the type of telecom entry, phone, sms, email ....
    -187   */
    -188   Telecom.prototype.type = function() {
    -189     return this.json['type'];
    -190   };
    -191   /**
    -192   @returns {String} the value of the entry -  the actual phone number , email address , ....
    -193   */
    -194   Telecom.prototype.value = function() {
    -195     return this.json['value'];
    +  4 
    +  5 var _ref,
    +  6   __hasProp = {}.hasOwnProperty,
    +  7   __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
    +  8   __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
    +  9 
    + 10 this.hQuery || (this.hQuery = {});
    + 11 
    + 12 /**
    + 13 Converts a a number in UTC Seconds since the epoch to a date.
    + 14 @param {number} utcSeconds seconds since the epoch in UTC
    + 15 @returns {Date}
    + 16 @function
    + 17 @exports dateFromUtcSeconds as hQuery.dateFromUtcSeconds
    + 18 */
    + 19 
    + 20 
    + 21 hQuery.dateFromUtcSeconds = function(utcSeconds) {
    + 22   return new Date(utcSeconds * 1000);
    + 23 };
    + 24 
    + 25 /**
    + 26 @class Scalar - a representation of a unit and value
    + 27 @exports Scalar as hQuery.Scalar
    + 28 */
    + 29 
    + 30 
    + 31 hQuery.Scalar = (function() {
    + 32   function Scalar(json) {
    + 33     this.json = json;
    + 34   }
    + 35 
    + 36   Scalar.prototype.unit = function() {
    + 37     return this.json['unit'];
    + 38   };
    + 39 
    + 40   Scalar.prototype.value = function() {
    + 41     return this.json['value'];
    + 42   };
    + 43 
    + 44   return Scalar;
    + 45 
    + 46 })();
    + 47 
    + 48 /**
    + 49 @class PhysicalQuantity - a representation of a physical quantity
    + 50 @exports PhysicalQuantity as hQuery.PhysicalQuantity
    + 51 */
    + 52 
    + 53 
    + 54 hQuery.PhysicalQuantity = (function() {
    + 55   function PhysicalQuantity(json) {
    + 56     this.json = json;
    + 57   }
    + 58 
    + 59   PhysicalQuantity.prototype.units = function() {
    + 60     return this.json['units'];
    + 61   };
    + 62 
    + 63   PhysicalQuantity.prototype.scalar = function() {
    + 64     return this.json['scalar'];
    + 65   };
    + 66 
    + 67   return PhysicalQuantity;
    + 68 
    + 69 })();
    + 70 
    + 71 /**
    + 72 @class A code with its corresponding code system
    + 73 @exports CodedValue as hQuery.CodedValue
    + 74 */
    + 75 
    + 76 
    + 77 hQuery.CodedValue = (function() {
    + 78   /**
    + 79   @param {String} c value of the code
    + 80   @param {String} csn name of the code system that the code belongs to
    + 81   @constructs
    + 82   */
    + 83   function CodedValue(c, csn) {
    + 84     this.c = c;
    + 85     this.csn = csn;
    + 86   }
    + 87 
    + 88   /**
    + 89   @returns {String} the code
    + 90   */
    + 91 
    + 92 
    + 93   CodedValue.prototype.code = function() {
    + 94     return this.c;
    + 95   };
    + 96 
    + 97   /**
    + 98   @returns {String} the code system name
    + 99   */
    +100 
    +101 
    +102   CodedValue.prototype.codeSystemName = function() {
    +103     return this.csn;
    +104   };
    +105 
    +106   /**
    +107   Returns true if the contained code and codeSystemName match a code in the supplied codeSet.
    +108   @param {Object} codeSet a hash with code system names as keys and an array of codes as values
    +109   @returns {boolean}
    +110   */
    +111 
    +112 
    +113   CodedValue.prototype.includedIn = function(codeSet) {
    +114     var code, codeSystemName, codes, _i, _len;
    +115 
    +116     for (codeSystemName in codeSet) {
    +117       codes = codeSet[codeSystemName];
    +118       if (this.csn === codeSystemName) {
    +119         for (_i = 0, _len = codes.length; _i < _len; _i++) {
    +120           code = codes[_i];
    +121           if (code === this.c) {
    +122             return true;
    +123           }
    +124         }
    +125       }
    +126     }
    +127     return false;
    +128   };
    +129 
    +130   return CodedValue;
    +131 
    +132 })();
    +133 
    +134 /**
    +135 Status as defined by value set 2.16.840.1.113883.5.14,
    +136 the ActStatus vocabulary maintained by HL7
    +137 
    +138 @class Status
    +139 @augments hQuery.CodedEntry
    +140 @exports Status as hQuery.Status
    +141 */
    +142 
    +143 
    +144 hQuery.Status = (function(_super) {
    +145   var ABORTED, ACTIVE, CANCELLED, COMPLETED, HELD, NEW, NORMAL, NULLIFIED, OBSOLETE, SUSPENDED;
    +146 
    +147   __extends(Status, _super);
    +148 
    +149   function Status() {
    +150     _ref = Status.__super__.constructor.apply(this, arguments);
    +151     return _ref;
    +152   }
    +153 
    +154   NORMAL = "normal";
    +155 
    +156   ABORTED = "aborted";
    +157 
    +158   ACTIVE = "active";
    +159 
    +160   CANCELLED = "cancelled";
    +161 
    +162   COMPLETED = "completed";
    +163 
    +164   HELD = "held";
    +165 
    +166   NEW = "new";
    +167 
    +168   SUSPENDED = "suspended";
    +169 
    +170   NULLIFIED = "nullified";
    +171 
    +172   OBSOLETE = "obsolete";
    +173 
    +174   Status.prototype.isNormal = function() {
    +175     return this.c === NORMAL;
    +176   };
    +177 
    +178   Status.prototype.isAborted = function() {
    +179     return this.c === ABORTED;
    +180   };
    +181 
    +182   Status.prototype.isActive = function() {
    +183     return this.c === ACTIVE;
    +184   };
    +185 
    +186   Status.prototype.isCancelled = function() {
    +187     return this.c === CANCELLED;
    +188   };
    +189 
    +190   Status.prototype.isCompleted = function() {
    +191     return this.c === COMPLETED;
    +192   };
    +193 
    +194   Status.prototype.isHeld = function() {
    +195     return this.c === HELD;
     196   };
    -197   /**
    -198   @returns {String} the use of the entry. Is it a home, office, .... type of contact
    -199   */
    -200   Telecom.prototype.use = function() {
    -201     return this.json['use'];
    -202   };
    -203   /**
    -204   @returns {Boolean} is this a preferred form of contact
    -205   */
    -206   Telecom.prototype.preferred = function() {
    -207     return this.json['preferred'];
    +197 
    +198   Status.prototype.isNew = function() {
    +199     return this.c === NEW;
    +200   };
    +201 
    +202   Status.prototype.isSuspended = function() {
    +203     return this.c === SUSPENDED;
    +204   };
    +205 
    +206   Status.prototype.isNullified = function() {
    +207     return this.c === NULLIFIED;
     208   };
    -209   return Telecom;
    -210 })();
    -211 /**
    -212 @class an object that describes a person.  includes a persons name, addresses, and contact information
    -213 @exports Person as hQuery.Person
    -214 */
    -215 hQuery.Person = (function() {
    -216   function Person(json) {
    -217     this.json = json;
    -218   }
    -219   /**
    -220    @returns {String} the given name of the person
    -221   */
    -222   Person.prototype.given = function() {
    -223     return this.json['first'];
    -224   };
    -225   /**
    -226    @returns {String} the last/family name of the person
    -227   */
    -228   Person.prototype.last = function() {
    -229     return this.json['last'];
    -230   };
    -231   /**
    -232    @returns {String} the display name of the person
    -233   */
    -234   Person.prototype.name = function() {
    -235     if (this.json['name']) {
    -236       return this.json['name'];
    -237     } else {
    -238       return this.json['first'] + ' ' + this.json['last'];
    -239     }
    -240   };
    -241   /**
    -242    @returns {Array} an array of {@link hQuery.Address} objects associated with the patient
    -243   */
    -244   Person.prototype.addresses = function() {
    -245     var address, list, _i, _len, _ref;
    -246     list = [];
    -247     if (this.json['addresses']) {
    -248       _ref = this.json['addresses'];
    -249       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    -250         address = _ref[_i];
    -251         list.push(new hQuery.Address(address));
    -252       }
    -253     }
    -254     return list;
    -255   };
    +209 
    +210   Status.prototype.isObsolete = function() {
    +211     return this.c === OBSOLETE;
    +212   };
    +213 
    +214   return Status;
    +215 
    +216 })(hQuery.CodedValue);
    +217 
    +218 /**
    +219 @class an Address for a person or organization
    +220 @exports Address as hQuery.Address
    +221 */
    +222 
    +223 
    +224 hQuery.Address = (function() {
    +225   function Address(json) {
    +226     this.json = json;
    +227   }
    +228 
    +229   /**
    +230   @returns {Array[String]} the street addresses
    +231   */
    +232 
    +233 
    +234   Address.prototype.street = function() {
    +235     return this.json['street'];
    +236   };
    +237 
    +238   /**
    +239   @returns {String} the city
    +240   */
    +241 
    +242 
    +243   Address.prototype.city = function() {
    +244     return this.json['city'];
    +245   };
    +246 
    +247   /**
    +248   @returns {String} the State
    +249   */
    +250 
    +251 
    +252   Address.prototype.state = function() {
    +253     return this.json['state'];
    +254   };
    +255 
     256   /**
    -257   @returns {Array} an array of {@link hQuery.Telecom} objects associated with the person
    +257   @returns {String} the postal code
     258   */
    -259   Person.prototype.telecoms = function() {
    -260     var tel, _i, _len, _ref, _results;
    -261     _ref = this.json['telecoms'];
    -262     _results = [];
    -263     for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    -264       tel = _ref[_i];
    -265       _results.push(new hQuery.Telecom(tel));
    -266     }
    -267     return _results;
    -268   };
    -269   return Person;
    -270 })();
    -271 /**
    -272 @class an actor is either a person or an organization
    -273 @exports Actor as hQuery.Actor
    -274 */
    -275 hQuery.Actor = (function() {
    -276   function Actor(json) {
    -277     this.json = json;
    -278   }
    -279   Actor.prototype.person = function() {
    -280     if (this.json['person']) {
    -281       return new hQuery.Person(this.json['person']);
    -282     }
    -283   };
    -284   Actor.prototype.organization = function() {
    -285     if (this.json['organization']) {
    -286       return new hQuery.Organization(this.json['organization']);
    -287     }
    +259 
    +260 
    +261   Address.prototype.postalCode = function() {
    +262     return this.json['zip'];
    +263   };
    +264 
    +265   return Address;
    +266 
    +267 })();
    +268 
    +269 /**
    +270 @class An object that describes a means to contact an entity.  This is used to represent
    +271 phone numbers, email addresses,  instant messaging accounts etc.
    +272 @exports Telecom as hQuery.Telecom
    +273 */
    +274 
    +275 
    +276 hQuery.Telecom = (function() {
    +277   function Telecom(json) {
    +278     this.json = json;
    +279   }
    +280 
    +281   /**
    +282   @returns {String} the type of telecom entry, phone, sms, email ....
    +283   */
    +284 
    +285 
    +286   Telecom.prototype.type = function() {
    +287     return this.json['type'];
     288   };
    -289   return Actor;
    -290 })();
    -291 /**
    -292 @class an Organization
    -293 @exports Organization as hQuery.Organization
    -294 */
    -295 hQuery.Organization = (function() {
    -296   function Organization(json) {
    -297     this.json = json;
    -298   }
    +289 
    +290   /**
    +291   @returns {String} the value of the entry -  the actual phone number , email address , ....
    +292   */
    +293 
    +294 
    +295   Telecom.prototype.value = function() {
    +296     return this.json['value'];
    +297   };
    +298 
     299   /**
    -300   @returns {String} the id for the organization
    +300   @returns {String} the use of the entry. Is it a home, office, .... type of contact
     301   */
    -302   Organization.prototype.organizationId = function() {
    -303     return this.json['organizationId'];
    -304   };
    -305   /**
    -306   @returns {String} the name of the organization
    -307   */
    -308   Organization.prototype.organizationName = function() {
    -309     return this.json['organizationName'];
    -310   };
    -311   /**
    -312   @returns {Array} an array of {@link hQuery.Address} objects associated with the organization
    -313   */
    -314   Organization.prototype.addresses = function() {
    -315     var address, list, _i, _len, _ref;
    -316     list = [];
    -317     if (this.json['addresses']) {
    -318       _ref = this.json['addresses'];
    -319       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    -320         address = _ref[_i];
    -321         list.push(new hQuery.Address(address));
    -322       }
    -323     }
    -324     return list;
    -325   };
    -326   /**
    -327   @returns {Array} an array of {@link hQuery.Telecom} objects associated with the organization
    -328   */
    -329   Organization.prototype.telecoms = function() {
    -330     var tel, _i, _len, _ref, _results;
    -331     _ref = this.json['telecoms'];
    -332     _results = [];
    -333     for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    -334       tel = _ref[_i];
    -335       _results.push(new hQuery.Telecom(tel));
    -336     }
    -337     return _results;
    -338   };
    -339   return Organization;
    -340 })();
    -341 /**
    -342 @class represents a DateRange in the form of hi and low date values.
    -343 @exports DateRange as hQuery.DateRange
    -344 */
    -345 hQuery.DateRange = (function() {
    -346   function DateRange(json) {
    -347     this.json = json;
    -348   }
    -349   DateRange.prototype.hi = function() {
    -350     if (this.json['hi']) {
    -351       return hQuery.dateFromUtcSeconds(this.json['hi']);
    -352     }
    -353   };
    -354   DateRange.prototype.low = function() {
    -355     return hQuery.dateFromUtcSeconds(this.json['low']);
    -356   };
    -357   return DateRange;
    -358 })();
    -359 /**
    -360 @class Class used to describe an entity that is providing some form of information.  This does not mean that they are
    -361 providing any treatment just that they are providing information.
    -362 @exports Informant as hQuery.Informant
    -363 */
    -364 hQuery.Informant = (function() {
    -365   function Informant(json) {
    -366     this.json = json;
    -367   }
    -368   /**
    -369   an array of hQuery.Person objects as points of contact
    -370   @returns {Array}
    -371   */
    -372   Informant.prototype.contacts = function() {
    -373     var contact, _i, _len, _ref, _results;
    -374     _ref = this.json['contacts'];
    -375     _results = [];
    -376     for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    -377       contact = _ref[_i];
    -378       _results.push(new hQuery.Person(contact));
    -379     }
    -380     return _results;
    -381   };
    +302 
    +303 
    +304   Telecom.prototype.use = function() {
    +305     return this.json['use'];
    +306   };
    +307 
    +308   /**
    +309   @returns {Boolean} is this a preferred form of contact
    +310   */
    +311 
    +312 
    +313   Telecom.prototype.preferred = function() {
    +314     return this.json['preferred'];
    +315   };
    +316 
    +317   return Telecom;
    +318 
    +319 })();
    +320 
    +321 /**
    +322 @class an object that describes a person.  includes a persons name, addresses, and contact information
    +323 @exports Person as hQuery.Person
    +324 */
    +325 
    +326 
    +327 hQuery.Person = (function() {
    +328   function Person(json) {
    +329     this.json = json;
    +330   }
    +331 
    +332   /**
    +333    @returns {String} the given name of the person
    +334   */
    +335 
    +336 
    +337   Person.prototype.given = function() {
    +338     return this.json['first'];
    +339   };
    +340 
    +341   /**
    +342    @returns {String} the last/family name of the person
    +343   */
    +344 
    +345 
    +346   Person.prototype.last = function() {
    +347     return this.json['last'];
    +348   };
    +349 
    +350   /**
    +351    @returns {String} the display name of the person
    +352   */
    +353 
    +354 
    +355   Person.prototype.name = function() {
    +356     if (this.json['name']) {
    +357       return this.json['name'];
    +358     } else {
    +359       return this.json['first'] + ' ' + this.json['last'];
    +360     }
    +361   };
    +362 
    +363   /**
    +364    @returns {Array} an array of {@link hQuery.Address} objects associated with the patient
    +365   */
    +366 
    +367 
    +368   Person.prototype.addresses = function() {
    +369     var address, list, _i, _len, _ref1;
    +370 
    +371     list = [];
    +372     if (this.json['addresses']) {
    +373       _ref1 = this.json['addresses'];
    +374       for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
    +375         address = _ref1[_i];
    +376         list.push(new hQuery.Address(address));
    +377       }
    +378     }
    +379     return list;
    +380   };
    +381 
     382   /**
    -383    @returns {hQuery.Organization} the organization providing the information
    +383   @returns {Array} an array of {@link hQuery.Telecom} objects associated with the person
     384   */
    -385   Informant.prototype.organization = function() {
    -386     return new hQuery.Organization(this.json['organization']);
    -387   };
    -388   return Informant;
    -389 })();
    -390 /**
    -391 @class
    -392 @exports CodedEntry as hQuery.CodedEntry
    -393 */
    -394 hQuery.CodedEntry = (function() {
    -395   function CodedEntry(json) {
    -396     this.json = json;
    -397   }
    -398   /**
    -399   Date and time at which the coded entry took place
    -400   @returns {Date}
    -401   */
    -402   CodedEntry.prototype.date = function() {
    -403     return hQuery.dateFromUtcSeconds(this.json['time']);
    -404   };
    -405   /**
    -406   An Array of CodedValues which describe what kind of coded entry took place
    -407   @returns {Array}
    -408   */
    -409   CodedEntry.prototype.type = function() {
    -410     return hQuery.createCodedValues(this.json['codes']);
    -411   };
    -412   /**
    -413   A free text description of the type of coded entry
    -414   @returns {String}
    -415   */
    -416   CodedEntry.prototype.freeTextType = function() {
    -417     return this.json['description'];
    +385 
    +386 
    +387   Person.prototype.telecoms = function() {
    +388     var tel, _i, _len, _ref1, _results;
    +389 
    +390     _ref1 = this.json['telecoms'];
    +391     _results = [];
    +392     for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
    +393       tel = _ref1[_i];
    +394       _results.push(new hQuery.Telecom(tel));
    +395     }
    +396     return _results;
    +397   };
    +398 
    +399   return Person;
    +400 
    +401 })();
    +402 
    +403 /**
    +404 @class an actor is either a person or an organization
    +405 @exports Actor as hQuery.Actor
    +406 */
    +407 
    +408 
    +409 hQuery.Actor = (function() {
    +410   function Actor(json) {
    +411     this.json = json;
    +412   }
    +413 
    +414   Actor.prototype.person = function() {
    +415     if (this.json['person']) {
    +416       return new hQuery.Person(this.json['person']);
    +417     }
     418   };
    -419   /**
    -420   Unique identifier for this coded entry
    -421   @returns {String}
    -422   */
    -423   CodedEntry.prototype.id = function() {
    -424     return this.json['id'];
    -425   };
    -426   /**
    -427   Returns true if any of this entry's codes match a code in the supplied codeSet.
    -428   @param {Object} codeSet a hash with code system names as keys and an array of codes as values
    -429   @returns {boolean}
    -430   */
    -431   CodedEntry.prototype.includesCodeFrom = function(codeSet) {
    -432     var codedValue, _i, _len, _ref;
    -433     _ref = this.type();
    -434     for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    -435       codedValue = _ref[_i];
    -436       if (codedValue.includedIn(codeSet)) {
    -437         return true;
    -438       }
    -439     }
    -440     return false;
    -441   };
    -442   return CodedEntry;
    -443 })();
    -444 /**
    -445 @class Represents a list of hQuery.CodedEntry instances. Offers utility methods for matching
    -446 entries based on codes and date ranges
    -447 @exports CodedEntryList as hQuery.CodedEntryList
    -448 */
    -449 hQuery.CodedEntryList = (function() {
    -450   __extends(CodedEntryList, Array);
    -451   function CodedEntryList() {
    -452     this.push.apply(this, arguments);
    -453   }
    -454   /**
    -455   Return the number of entries that match the
    -456   supplied code set where those entries occur between the supplied time bounds
    -457   @param {Object} codeSet a hash with code system names as keys and an array of codes as values
    -458   @param {Date} start the start of the period during which the entry must occur, a null value will match all times
    -459   @param {Date} end the end of the period during which the entry must occur, a null value will match all times
    -460   @return {Array[CodedEntry]} the matching entries
    +419 
    +420   Actor.prototype.organization = function() {
    +421     if (this.json['organization']) {
    +422       return new hQuery.Organization(this.json['organization']);
    +423     }
    +424   };
    +425 
    +426   return Actor;
    +427 
    +428 })();
    +429 
    +430 /**
    +431 @class an Organization
    +432 @exports Organization as hQuery.Organization
    +433 */
    +434 
    +435 
    +436 hQuery.Organization = (function() {
    +437   function Organization(json) {
    +438     this.json = json;
    +439   }
    +440 
    +441   /**
    +442   @returns {String} the id for the organization
    +443   */
    +444 
    +445 
    +446   Organization.prototype.organizationId = function() {
    +447     return this.json['organizationId'];
    +448   };
    +449 
    +450   /**
    +451   @returns {String} the name of the organization
    +452   */
    +453 
    +454 
    +455   Organization.prototype.organizationName = function() {
    +456     return this.json['name'];
    +457   };
    +458 
    +459   /**
    +460   @returns {Array} an array of {@link hQuery.Address} objects associated with the organization
     461   */
    -462   CodedEntryList.prototype.match = function(codeSet, start, end) {
    -463     var afterStart, beforeEnd, entry, matchingEntries, _i, _len;
    -464     matchingEntries = [];
    -465     for (_i = 0, _len = this.length; _i < _len; _i++) {
    -466       entry = this[_i];
    -467       afterStart = !start || entry.date() >= start;
    -468       beforeEnd = !end || entry.date() <= end;
    -469       if (afterStart && beforeEnd && entry.includesCodeFrom(codeSet)) {
    -470         matchingEntries.push(entry);
    -471       }
    -472     }
    -473     return matchingEntries;
    -474   };
    -475   return CodedEntryList;
    -476 })();
    -477 /**
    -478 @private
    -479 @function
    -480 
    -481 */
    -482 hQuery.createCodedValues = function(jsonCodes) {
    -483   var code, codeSystem, codedValues, codes, _i, _len;
    -484   codedValues = [];
    -485   for (codeSystem in jsonCodes) {
    -486     codes = jsonCodes[codeSystem];
    -487     for (_i = 0, _len = codes.length; _i < _len; _i++) {
    -488       code = codes[_i];
    -489       codedValues.push(new hQuery.CodedValue(code, codeSystem));
    -490     }
    -491   }
    -492   return codedValues;
    -493 };/**
    -494 @namespace scoping into the hquery namespace
    -495 */
    -496 var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
    -497   for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
    -498   function ctor() { this.constructor = child; }
    -499   ctor.prototype = parent.prototype;
    -500   child.prototype = new ctor;
    -501   child.__super__ = parent.prototype;
    -502   return child;
    -503 };
    -504 this.hQuery || (this.hQuery = {});
    -505 /**
    -506 @class MedicationInformation
    -507 @exports MedicationInformation as hQuery.MedicationInformation
    -508 */
    -509 hQuery.MedicationInformation = (function() {
    -510   function MedicationInformation(json) {
    -511     this.json = json;
    -512   }
    -513   /**
    -514   An array of hQuery.CodedValue describing the medication
    -515   @returns {Array}
    -516   */
    -517   MedicationInformation.prototype.codedProduct = function() {
    -518     return hQuery.createCodedValues(this.json['codes']);
    -519   };
    -520   MedicationInformation.prototype.freeTextProductName = function() {
    -521     return this.json['description'];
    +462 
    +463 
    +464   Organization.prototype.addresses = function() {
    +465     var address, list, _i, _len, _ref1;
    +466 
    +467     list = [];
    +468     if (this.json['addresses']) {
    +469       _ref1 = this.json['addresses'];
    +470       for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
    +471         address = _ref1[_i];
    +472         list.push(new hQuery.Address(address));
    +473       }
    +474     }
    +475     return list;
    +476   };
    +477 
    +478   /**
    +479   @returns {Array} an array of {@link hQuery.Telecom} objects associated with the organization
    +480   */
    +481 
    +482 
    +483   Organization.prototype.telecoms = function() {
    +484     var tel, _i, _len, _ref1, _results;
    +485 
    +486     _ref1 = this.json['telecoms'];
    +487     _results = [];
    +488     for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
    +489       tel = _ref1[_i];
    +490       _results.push(new hQuery.Telecom(tel));
    +491     }
    +492     return _results;
    +493   };
    +494 
    +495   return Organization;
    +496 
    +497 })();
    +498 
    +499 /**
    +500 @class a Facility
    +501 @exports Organization as hQuery.Facility
    +502 */
    +503 
    +504 
    +505 hQuery.Facility = (function(_super) {
    +506   __extends(Facility, _super);
    +507 
    +508   function Facility(json) {
    +509     this.json = json;
    +510     if (this.json['code'] != null) {
    +511       Facility.__super__.constructor.call(this, this.json['code']['code'], this.json['code']['codeSystem']);
    +512     }
    +513   }
    +514 
    +515   /**
    +516   @returns {String} the name of the facility
    +517   */
    +518 
    +519 
    +520   Facility.prototype.name = function() {
    +521     return this.json['name'];
     522   };
    -523   MedicationInformation.prototype.codedBrandName = function() {
    -524     return this.json['codedBrandName'];
    -525   };
    -526   MedicationInformation.prototype.freeTextBrandName = function() {
    -527     return this.json['brandName'];
    -528   };
    -529   MedicationInformation.prototype.drugManufacturer = function() {
    -530     if (this.json['drugManufacturer']) {
    -531       return new hQuery.Organization(this.json['drugManufacturer']);
    -532     }
    -533   };
    -534   return MedicationInformation;
    -535 })();
    -536 /**
    -537 @class AdministrationTiming - the
    -538 @exports AdministrationTiming as hQuery.AdministrationTiming
    -539 */
    -540 hQuery.AdministrationTiming = (function() {
    -541   function AdministrationTiming(json) {
    -542     this.json = json;
    -543   }
    -544   /**
    -545   Provides the period of medication administration as a Scalar. An example
    -546   Scalar that would be returned would be with value = 8 and units = hours. This would
    -547   mean that the medication should be taken every 8 hours.
    -548   @returns {hQuery.Scalar}
    -549   */
    -550   AdministrationTiming.prototype.period = function() {
    -551     return new hQuery.Scalar(this.json['period']);
    -552   };
    -553   /**
    -554   Indicates whether it is the interval (time between dosing), or frequency 
    -555   (number of doses in a time period) that is important. If instititutionSpecified is not 
    -556   present or is set to false, then the time between dosing is important (every 8 hours). 
    -557   If true, then the frequency of administration is important (e.g., 3 times per day).
    -558   @returns {Boolean}
    -559   */
    -560   AdministrationTiming.prototype.institutionSpecified = function() {
    -561     return this.json['institutionSpecified'];
    -562   };
    -563   return AdministrationTiming;
    -564 })();
    -565 /**
    -566 @class DoseRestriction -  restrictions on the medications dose, represented by a upper and lower dose
    -567 @exports DoseRestriction as hQuery.DoseRestriction
    -568 */
    -569 hQuery.DoseRestriction = (function() {
    -570   function DoseRestriction(json) {
    -571     this.json = json;
    -572   }
    -573   DoseRestriction.prototype.numerator = function() {
    -574     return new hQuery.Scalar(this.json['numerator']);
    -575   };
    -576   DoseRestriction.prototype.denominator = function() {
    -577     return new hQuery.Scalar(this.json['denominator']);
    -578   };
    -579   return DoseRestriction;
    -580 })();
    -581 /**
    -582 @class Fulfillment - information about when and who fulfilled an order for the medication
    -583 @exports Fulfillment as hQuery.Fullfilement
    -584 */
    -585 hQuery.Fulfillment = (function() {
    -586   function Fulfillment(json) {
    -587     this.json = json;
    -588   }
    -589   Fulfillment.prototype.dispenseDate = function() {
    -590     return hQuery.dateFromUtcSeconds(this.json['dispenseDate']);
    -591   };
    -592   Fulfillment.prototype.provider = function() {
    -593     return new hQuery.Actor(this.json['provider']);
    -594   };
    -595   Fulfillment.prototype.dispensingPharmacyLocation = function() {
    -596     return new hQuery.Address(this.json['dispensingPharmacyLocation']);
    -597   };
    -598   Fulfillment.prototype.quantityDispensed = function() {
    -599     return new hQuery.Scalar(this.json['quantityDispensed']);
    -600   };
    -601   Fulfillment.prototype.prescriptionNumber = function() {
    -602     return this.json['prescriptionNumber'];
    -603   };
    -604   Fulfillment.prototype.fillNumber = function() {
    -605     return this.json['fillNumber'];
    -606   };
    -607   Fulfillment.prototype.fillStatus = function() {
    -608     return new hQuery.Status(this.json['fillStatus']);
    -609   };
    -610   return Fulfillment;
    -611 })();
    -612 /**
    -613 @class OrderInformation - information abour an order for a medication
    -614 @exports OrderInformation as hQuery.OrderInformation
    -615 */
    -616 hQuery.OrderInformation = (function() {
    -617   function OrderInformation(json) {
    -618     this.json = json;
    -619   }
    -620   OrderInformation.prototype.orderNumber = function() {
    -621     return this.json['orderNumber'];
    -622   };
    -623   OrderInformation.prototype.fills = function() {
    -624     return this.json['fills'];
    -625   };
    -626   OrderInformation.prototype.quantityOrdered = function() {
    -627     return new hQuery.Scalar(this.json['quantityOrdered']);
    -628   };
    -629   OrderInformation.prototype.orderExpirationDateTime = function() {
    -630     return hQuery.dateFromUtcSeconds(this.json['orderExpirationDateTime']);
    -631   };
    -632   OrderInformation.prototype.orderDateTime = function() {
    -633     return hQuery.dateFromUtcSeconds(this.json['orderDateTime']);
    -634   };
    -635   return OrderInformation;
    -636 })();
    -637 /**
    -638 TypeOfMedication as defined by value set 2.16.840.1.113883.3.88.12.3221.8.19
    -639 which pulls two values from SNOMED to describe whether a medication is
    -640 prescription or over the counter
    -641 
    -642 @class TypeOfMedication - describes whether a medication is prescription or
    -643        over the counter
    -644 @augments hQuery.CodedEntry
    -645 @exports TypeOfMedication as hQuery.TypeOfMedication
    -646 */
    -647 hQuery.TypeOfMedication = (function() {
    -648   var OTC, PRESECRIPTION;
    -649   __extends(TypeOfMedication, hQuery.CodedValue);
    -650   function TypeOfMedication() {
    -651     TypeOfMedication.__super__.constructor.apply(this, arguments);
    -652   }
    -653   PRESECRIPTION = "73639000";
    -654   OTC = "329505003";
    -655   /**
    -656   @returns {Boolean}
    -657   */
    -658   TypeOfMedication.prototype.isPrescription = function() {
    -659     return this.c === PRESECRIPTION;
    -660   };
    -661   /**
    -662   @returns {Boolean}
    -663   */
    -664   TypeOfMedication.prototype.isOverTheCounter = function() {
    -665     return this.c === OTC;
    -666   };
    -667   return TypeOfMedication;
    -668 })();
    -669 /**
    -670 StatusOfMedication as defined by value set 2.16.840.1.113883.1.11.20.7
    -671 The terms come from SNOMED and are managed by HL7
    -672 
    -673 @class StatusOfMedication - describes the status of the medication
    -674 @augments hQuery.CodedEntry
    -675 @exports StatusOfMedication as hQuery.StatusOfMedication
    -676 */
    -677 hQuery.StatusOfMedication = (function() {
    -678   var ACTIVE, NO_LONGER_ACTIVE, ON_HOLD, PRIOR_HISTORY;
    -679   __extends(StatusOfMedication, hQuery.CodedValue);
    -680   function StatusOfMedication() {
    -681     StatusOfMedication.__super__.constructor.apply(this, arguments);
    -682   }
    -683   ON_HOLD = "392521001";
    -684   NO_LONGER_ACTIVE = "421139008";
    -685   ACTIVE = "55561003";
    -686   PRIOR_HISTORY = "73425007";
    -687   /**
    -688   @returns {Boolean}
    -689   */
    -690   StatusOfMedication.prototype.isOnHold = function() {
    -691     return this.c === ON_HOLD;
    -692   };
    -693   /**
    -694   @returns {Boolean}
    -695   */
    -696   StatusOfMedication.prototype.isNoLongerActive = function() {
    -697     return this.c === NO_LONGER_ACTIVE;
    -698   };
    -699   /**
    -700   @returns {Boolean}
    -701   */
    -702   StatusOfMedication.prototype.isActive = function() {
    -703     return this.c === ACTIVE;
    -704   };
    -705   /**
    -706   @returns {Boolean}
    -707   */
    -708   StatusOfMedication.prototype.isPriorHistory = function() {
    -709     return this.c === PRIOR_HISTORY;
    -710   };
    -711   return StatusOfMedication;
    -712 })();
    -713 /**
    -714 @class represents a medication entry for a patient.
    -715 @augments hQuery.CodedEntry
    -716 @exports Medication as hQuery.Medication
    -717 */
    -718 hQuery.Medication = (function() {
    -719   __extends(Medication, hQuery.CodedEntry);
    -720   function Medication() {
    -721     Medication.__super__.constructor.apply(this, arguments);
    -722   }
    -723   /**
    -724   @returns {String}
    -725   */
    -726   Medication.prototype.freeTextSig = function() {
    -727     return this.json['freeTextSig'];
    -728   };
    -729   /**
    -730   The actual or intended start of a medication. Slight deviation from greenCDA for C32 since
    -731   it combines this with medication stop
    -732   @returns {Date}
    -733   */
    -734   Medication.prototype.indicateMedicationStart = function() {
    -735     return hQuery.dateFromUtcSeconds(this.json['start_time']);
    +523 
    +524   /**
    +525   @returns {Array} an array of {@link hQuery.Address} objects associated with the facility
    +526   */
    +527 
    +528 
    +529   Facility.prototype.addresses = function() {
    +530     var address, list, _i, _len, _ref1;
    +531 
    +532     list = [];
    +533     if (this.json['addresses']) {
    +534       _ref1 = this.json['addresses'];
    +535       for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
    +536         address = _ref1[_i];
    +537         list.push(new hQuery.Address(address));
    +538       }
    +539     }
    +540     return list;
    +541   };
    +542 
    +543   /**
    +544   @returns {Array} an array of {@link hQuery.Telecom} objects associated with the facility
    +545   */
    +546 
    +547 
    +548   Facility.prototype.telecoms = function() {
    +549     var tel, _i, _len, _ref1, _results;
    +550 
    +551     _ref1 = this.json['telecoms'];
    +552     _results = [];
    +553     for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
    +554       tel = _ref1[_i];
    +555       _results.push(new hQuery.Telecom(tel));
    +556     }
    +557     return _results;
    +558   };
    +559 
    +560   return Facility;
    +561 
    +562 })(hQuery.CodedValue);
    +563 
    +564 /**
    +565 @class represents a DateRange in the form of hi and low date values.
    +566 @exports DateRange as hQuery.DateRange
    +567 */
    +568 
    +569 
    +570 hQuery.DateRange = (function() {
    +571   function DateRange(json) {
    +572     this.json = json;
    +573   }
    +574 
    +575   DateRange.prototype.hi = function() {
    +576     if (this.json['hi']) {
    +577       return hQuery.dateFromUtcSeconds(this.json['hi']);
    +578     }
    +579   };
    +580 
    +581   DateRange.prototype.low = function() {
    +582     return hQuery.dateFromUtcSeconds(this.json['low']);
    +583   };
    +584 
    +585   return DateRange;
    +586 
    +587 })();
    +588 
    +589 /**
    +590 @class Class used to describe an entity that is providing some form of information.  This does not mean that they are
    +591 providing any treatment just that they are providing information.
    +592 @exports Informant as hQuery.Informant
    +593 */
    +594 
    +595 
    +596 hQuery.Informant = (function() {
    +597   function Informant(json) {
    +598     this.json = json;
    +599   }
    +600 
    +601   /**
    +602   an array of hQuery.Person objects as points of contact
    +603   @returns {Array}
    +604   */
    +605 
    +606 
    +607   Informant.prototype.contacts = function() {
    +608     var contact, _i, _len, _ref1, _results;
    +609 
    +610     _ref1 = this.json['contacts'];
    +611     _results = [];
    +612     for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
    +613       contact = _ref1[_i];
    +614       _results.push(new hQuery.Person(contact));
    +615     }
    +616     return _results;
    +617   };
    +618 
    +619   /**
    +620    @returns {hQuery.Organization} the organization providing the information
    +621   */
    +622 
    +623 
    +624   Informant.prototype.organization = function() {
    +625     return new hQuery.Organization(this.json['organization']);
    +626   };
    +627 
    +628   return Informant;
    +629 
    +630 })();
    +631 
    +632 /**
    +633 @class
    +634 @exports CodedEntry as hQuery.CodedEntry
    +635 */
    +636 
    +637 
    +638 hQuery.CodedEntry = (function() {
    +639   function CodedEntry(json) {
    +640     this.json = json;
    +641     if (this.json['time']) {
    +642       this._date = hQuery.dateFromUtcSeconds(this.json['time']);
    +643     }
    +644     if (this.json['start_time']) {
    +645       this._startDate = hQuery.dateFromUtcSeconds(this.json['start_time']);
    +646     }
    +647     if (this.json['end_time']) {
    +648       this._endDate = hQuery.dateFromUtcSeconds(this.json['end_time']);
    +649     }
    +650     this._type = hQuery.createCodedValues(this.json['codes']);
    +651     this._statusCode = this.json['status_code'];
    +652     this.id = this.json['_id'];
    +653     this._freeTextType = this.json['description'];
    +654   }
    +655 
    +656   /**
    +657   Date and time at which the coded entry took place
    +658   @returns {Date}
    +659   */
    +660 
    +661 
    +662   CodedEntry.prototype.date = function() {
    +663     return this._date;
    +664   };
    +665 
    +666   /**
    +667   Date and time at which the coded entry started
    +668   @returns {Date}
    +669   */
    +670 
    +671 
    +672   CodedEntry.prototype.startDate = function() {
    +673     return this._startDate;
    +674   };
    +675 
    +676   /**
    +677   Date and time at which the coded entry ended
    +678   @returns {Date}
    +679   */
    +680 
    +681 
    +682   CodedEntry.prototype.endDate = function() {
    +683     return this._endDate;
    +684   };
    +685 
    +686   /**
    +687   Tries to find a single point in time for this entry. Will first return date if it is present,
    +688   then fall back to startDate and finally endDate
    +689   @returns {Date}
    +690   */
    +691 
    +692 
    +693   CodedEntry.prototype.timeStamp = function() {
    +694     return this._date || this._startDate || this._endDate;
    +695   };
    +696 
    +697   /**
    +698   Determines whether the entry specifies a time range or not
    +699   @returns {boolean}
    +700   */
    +701 
    +702 
    +703   CodedEntry.prototype.isTimeRange = function() {
    +704     return (this._startDate != null) && (this._endDate != null);
    +705   };
    +706 
    +707   /**
    +708   Determines whether a coded entry contains sufficient information (code and at least 
    +709   one time stamp) to be usable
    +710   @returns {boolean}
    +711   */
    +712 
    +713 
    +714   CodedEntry.prototype.isUsable = function() {
    +715     return this._type.length > 0 && (this._date || this._startDate || this._endDate);
    +716   };
    +717 
    +718   /**
    +719   An Array of CodedValues which describe what kind of coded entry took place
    +720   @returns {Array}
    +721   */
    +722 
    +723 
    +724   CodedEntry.prototype.type = function() {
    +725     return this._type;
    +726   };
    +727 
    +728   /**
    +729   A free text description of the type of coded entry
    +730   @returns {String}
    +731   */
    +732 
    +733 
    +734   CodedEntry.prototype.freeTextType = function() {
    +735     return this._freeTextType;
     736   };
    -737   /**
    -738   The actual or intended stop of a medication. Slight deviation from greenCDA for C32 since
    -739   it combines this with medication start
    -740   @returns {Date}
    +737 
    +738   /**
    +739   Status for this coded entry
    +740   @returns {String}
     741   */
    -742   Medication.prototype.indicateMedicationStop = function() {
    -743     return hQuery.dateFromUtcSeconds(this.json['end_time']);
    -744   };
    -745   Medication.prototype.administrationTiming = function() {
    -746     return new hQuery.AdministrationTiming(this.json['administrationTiming']);
    -747   };
    -748   /**
    -749   @returns {CodedValue}  Contains routeCode or adminstrationUnitCode information.
    -750     Route code shall have a a value drawn from FDA route of adminstration,
    -751     and indicates how the medication is received by the patient.
    -752     See http://www.fda.gov/Drugs/DevelopmentApprovalProcess/UCM070829
    -753     The administration unit code shall have a value drawn from the FDA
    -754     dosage form, source NCI thesaurus and represents the physical form of the
    -755     product as presented to the patient.
    -756     See http://www.fda.gov/Drugs/InformationOnDrugs/ucm142454.htm
    -757   */
    -758   Medication.prototype.route = function() {
    -759     return new hQuery.CodedValue(this.json['route']['code'], this.json['route']['codeSystem']);
    -760   };
    +742 
    +743 
    +744   CodedEntry.prototype.status = function() {
    +745     if (this._statusCode != null) {
    +746       if (this._statusCode['HL7 ActStatus'] != null) {
    +747         return this._statusCode['HL7 ActStatus'][0];
    +748       } else if (this._statusCode['SNOMED-CT'] != null) {
    +749         switch (this._statusCode['SNOMED-CT'][0]) {
    +750           case '55561003':
    +751             return 'active';
    +752           case '73425007':
    +753             return 'inactive';
    +754           case '413322009':
    +755             return 'resolved';
    +756         }
    +757       }
    +758     }
    +759   };
    +760 
     761   /**
    -762   @returns {hQuery.Scalar} the dose
    -763   */
    -764   Medication.prototype.dose = function() {
    -765     return new hQuery.Scalar(this.json['dose']);
    -766   };
    -767   /**
    -768   @returns {CodedValue}
    -769   */
    -770   Medication.prototype.site = function() {
    -771     return new hQuery.CodedValue(this.json['site']['code'], this.json['site']['codeSystem']);
    -772   };
    -773   /**
    -774   @returns {hQuery.DoseRestriction}
    +762   Status for this coded entry
    +763   @returns {Hash} keys are code systems, values are arrays of codes
    +764   */
    +765 
    +766 
    +767   CodedEntry.prototype.statusCode = function() {
    +768     return this._statusCode;
    +769   };
    +770 
    +771   /**
    +772   Returns true if any of this entry codes match a code in the supplied codeSet.
    +773   @param {Object} codeSet a hash with code system names as keys and an array of codes as values
    +774   @returns {boolean}
     775   */
    -776   Medication.prototype.doseRestriction = function() {
    -777     return new hQuery.DoseRestriction(this.json['doseRestriction']);
    -778   };
    -779   /**
    -780   @returns {String}
    -781   */
    -782   Medication.prototype.doseIndicator = function() {
    -783     return this.json['doseIndicator'];
    -784   };
    -785   /**
    -786   @returns {String}
    -787   */
    -788   Medication.prototype.fulfillmentInstructions = function() {
    -789     return this.json['fulfillmentInstructions'];
    -790   };
    +776 
    +777 
    +778   CodedEntry.prototype.includesCodeFrom = function(codeSet) {
    +779     var codedValue, _i, _len, _ref1;
    +780 
    +781     _ref1 = this._type;
    +782     for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
    +783       codedValue = _ref1[_i];
    +784       if (codedValue.includedIn(codeSet)) {
    +785         return true;
    +786       }
    +787     }
    +788     return false;
    +789   };
    +790 
     791   /**
    -792   @returns {CodedValue}
    +792   @returns {Boolean} whether the entry was negated
     793   */
    -794   Medication.prototype.indication = function() {
    -795     return new hQuery.CodedValue(this.json['indication']['code'], this.json['indication']['codeSystem']);
    -796   };
    -797   /**
    -798   @returns {CodedValue}
    -799   */
    -800   Medication.prototype.productForm = function() {
    -801     return new hQuery.CodedValue(this.json['productForm']['code'], this.json['productForm']['codeSystem']);
    -802   };
    -803   /**
    -804   @returns {CodedValue}
    -805   */
    -806   Medication.prototype.vehicle = function() {
    -807     return new hQuery.CodedValue(this.json['vehicle']['code'], this.json['vehicle']['codeSystem']);
    -808   };
    -809   /**
    -810   @returns {CodedValue}
    -811   */
    -812   Medication.prototype.reaction = function() {
    -813     return new hQuery.CodedValue(this.json['reaction']['code'], this.json['reaction']['codeSystem']);
    -814   };
    -815   /**
    -816   @returns {CodedValue}
    -817   */
    -818   Medication.prototype.deliveryMethod = function() {
    -819     return new hQuery.CodedValue(this.json['deliveryMethod']['code'], this.json['deliveryMethod']['codeSystem']);
    -820   };
    -821   /**
    -822   @returns {hQuery.MedicationInformation}
    -823   */
    -824   Medication.prototype.medicationInformation = function() {
    -825     return new hQuery.MedicationInformation(this.json);
    -826   };
    -827   /**
    -828   @returns {hQuery.TypeOfMedication} Indicates whether this is an over the counter or prescription medication
    -829   */
    -830   Medication.prototype.typeOfMedication = function() {
    -831     return new hQuery.TypeOfMedication(this.json['typeOfMedication']['code'], this.json['typeOfMedication']['codeSystem']);
    -832   };
    -833   /**
    -834   Values conform to value set 2.16.840.1.113883.1.11.20.7 - Medication Status
    -835   Values may be: On Hold, No Longer Active, Active, Prior History
    -836   @returns {hQuery.StatusOfMedication}   Used to indicate the status of the medication.
    -837   */
    -838   Medication.prototype.statusOfMedication = function() {
    -839     return new hQuery.StatusOfMedication(this.json['statusOfMedication']['code'], this.json['statusOfMedication']['codeSystem']);
    -840   };
    -841   /**
    -842   @returns {String} free text instructions to the patient
    -843   */
    -844   Medication.prototype.patientInstructions = function() {
    -845     return this.json['patientInstructions'];
    -846   };
    -847   /**
    -848   @returns {Array} an array of {@link FulFillment} objects
    -849   */
    -850   Medication.prototype.fulfillmentHistory = function() {
    -851     var order, _i, _len, _ref, _results;
    -852     _ref = this.json['fulfillmentHistory'];
    -853     _results = [];
    -854     for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    -855       order = _ref[_i];
    -856       _results.push(new hQuery.Fulfillment(order));
    -857     }
    -858     return _results;
    -859   };
    -860   /**
    -861   @returns {Array} an array of {@link OrderInformation} objects
    -862   */
    -863   Medication.prototype.orderInformation = function() {
    -864     var order, _i, _len, _ref, _results;
    -865     _ref = this.json['orderInformation'];
    -866     _results = [];
    -867     for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    -868       order = _ref[_i];
    -869       _results.push(new hQuery.OrderInformation(order));
    -870     }
    -871     return _results;
    -872   };
    -873   return Medication;
    -874 })();/**
    -875 @namespace scoping into the hquery namespace
    -876 */
    -877 var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
    -878   for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
    -879   function ctor() { this.constructor = child; }
    -880   ctor.prototype = parent.prototype;
    -881   child.prototype = new ctor;
    -882   child.__super__ = parent.prototype;
    -883   return child;
    -884 };
    -885 this.hQuery || (this.hQuery = {});
    -886 /**
    -887 @class CauseOfDeath
    -888 @exports CauseOfDeath as hQuery.CauseOfDeath
    -889 */
    -890 hQuery.CauseOfDeath = (function() {
    -891   function CauseOfDeath(json) {
    -892     this.json = json;
    -893   }
    -894   /**
    -895   @returns {hQuery.Date}
    -896   */
    -897   CauseOfDeath.prototype.timeOfDeath = function() {
    -898     return new hQuery.dateFromUtcSeconds(this.json['timeOfDeath']);
    -899   };
    -900   /**
    -901   @returns {int}
    -902   */
    -903   CauseOfDeath.prototype.ageAtDeath = function() {
    -904     return this.json['ageAtDeath'];
    -905   };
    -906   return CauseOfDeath;
    -907 })();
    -908 /**
    -909 @class hQuery.Condition
    -910 
    -911 This section is used to describe a patients problems/conditions. The types of conditions
    -912 described have been constrained to the SNOMED CT Problem Type code set. An unbounded
    -913 number of treating providers for the particular condition can be supplied.
    -914 @exports Condition as hQuery.Condition 
    -915 @augments hQuery.CodedEntry
    -916 */
    -917 hQuery.Condition = (function() {
    -918   __extends(Condition, hQuery.CodedEntry);
    -919   function Condition(json) {
    -920     this.json = json;
    -921   }
    -922   /**
    -923    @returns {Array, hQuery.Provider} an array of providers for the condition
    -924   */
    -925   Condition.prototype.providers = function() {
    -926     var provider, _i, _len, _ref, _results;
    -927     _ref = this.json['treatingProviders'];
    -928     _results = [];
    -929     for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    -930       provider = _ref[_i];
    -931       _results.push(new Provider(provider));
    -932     }
    -933     return _results;
    -934   };
    -935   /**
    -936   Diagnosis Priority
    -937   @returns {int}
    -938   */
    -939   Condition.prototype.diagnosisPriority = function() {
    -940     return this.json['diagnosisPriority'];
    -941   };
    -942   /**
    -943   age at onset
    -944   @returns {int}
    -945   */
    -946   Condition.prototype.ageAtOnset = function() {
    -947     return this.json['ageAtOnset'];
    -948   };
    -949   /**
    -950   cause of death
    -951   @returns {hQuery.CauseOfDeath}
    -952   */
    -953   Condition.prototype.causeOfDeath = function() {
    -954     return new hQuery.CauseOfDeath(this.json['causeOfDeath']);
    -955   };
    -956   /**
    -957   problem status
    -958   @returns {hQuery.CodedValue}
    -959   */
    -960   Condition.prototype.problemStatus = function() {
    -961     return new hQuery.CodedValue(this.json['problemStatus']['code'], this.json['problemStatus']['codeSystem']);
    +794 
    +795 
    +796   CodedEntry.prototype.negationInd = function() {
    +797     return this.json['negationInd'] || false;
    +798   };
    +799 
    +800   /**
    +801   Returns the values of the result. This will return an array that contains
    +802   PhysicalQuantity or CodedValue objects depending on the result type.
    +803   @returns {Array} containing either PhysicalQuantity and/or CodedValues
    +804   */
    +805 
    +806 
    +807   CodedEntry.prototype.values = function() {
    +808     var value, values, _i, _len, _ref1;
    +809 
    +810     values = [];
    +811     if (this.json['values']) {
    +812       _ref1 = this.json['values'];
    +813       for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
    +814         value = _ref1[_i];
    +815         if (value['scalar'] != null) {
    +816           values.push(new hQuery.PhysicalQuantity(value));
    +817         } else {
    +818           values.push(hQuery.createCodedValues(values));
    +819         }
    +820       }
    +821     }
    +822     return values;
    +823   };
    +824 
    +825   /**
    +826   Indicates the reason an entry was negated.
    +827   @returns {hQuery.CodedValue}   Used to indicate reason an immunization was not administered.
    +828   */
    +829 
    +830 
    +831   CodedEntry.prototype.negationReason = function() {
    +832     if (this.json['negationReason'] && this.json['negationReason']['code'] && this.json['negationReason']['codeSystem']) {
    +833       return new hQuery.CodedValue(this.json['negationReason']['code'], this.json['negationReason']['codeSystem']);
    +834     } else {
    +835       return null;
    +836     }
    +837   };
    +838 
    +839   return CodedEntry;
    +840 
    +841 })();
    +842 
    +843 /**
    +844 @class Represents a list of hQuery.CodedEntry instances. Offers utility methods for matching
    +845 entries based on codes and date ranges
    +846 @exports CodedEntryList as hQuery.CodedEntryList
    +847 */
    +848 
    +849 
    +850 hQuery.CodedEntryList = (function(_super) {
    +851   __extends(CodedEntryList, _super);
    +852 
    +853   function CodedEntryList() {
    +854     this.push.apply(this, arguments);
    +855   }
    +856 
    +857   /**
    +858   Push the supplied entry onto this list if it is usable
    +859   @param {CodedEntry} a coded entry that should be added to the list if it is usable
    +860   */
    +861 
    +862 
    +863   CodedEntryList.prototype.pushIfUsable = function(entry) {
    +864     if (entry.isUsable()) {
    +865       return this.push(entry);
    +866     }
    +867   };
    +868 
    +869   /**
    +870   Return the number of entries that match the
    +871   supplied code set where those entries occur between the supplied time bounds
    +872   @param {Object} codeSet a hash with code system names as keys and an array of codes as values
    +873   @param {Date} start the start of the period during which the entry must occur, a null value will match all times
    +874   @param {Date} end the end of the period during which the entry must occur, a null value will match all times
    +875   @param {boolean} includeNegated whether the returned list of entries should include those that have been negated
    +876   @return {CodedEntryList} the matching entries
    +877   */
    +878 
    +879 
    +880   CodedEntryList.prototype.match = function(codeSet, start, end, includeNegated) {
    +881     var afterStart, beforeEnd, cloned, entry, _i, _len;
    +882 
    +883     if (includeNegated == null) {
    +884       includeNegated = false;
    +885     }
    +886     cloned = new hQuery.CodedEntryList();
    +887     for (_i = 0, _len = this.length; _i < _len; _i++) {
    +888       entry = this[_i];
    +889       afterStart = !start || entry.timeStamp() >= start;
    +890       beforeEnd = !end || entry.timeStamp() <= end;
    +891       if (afterStart && beforeEnd && entry.includesCodeFrom(codeSet) && (includeNegated || !entry.negationInd())) {
    +892         cloned.push(entry);
    +893       }
    +894     }
    +895     return cloned;
    +896   };
    +897 
    +898   /**
    +899   Return a new list of entries that is the result of concatenating the passed in entries with this list
    +900   @return {CodedEntryList} the set of concatenated entries
    +901   */
    +902 
    +903 
    +904   CodedEntryList.prototype.concat = function(otherEntries) {
    +905     var cloned, entry, _i, _j, _len, _len1;
    +906 
    +907     cloned = new hQuery.CodedEntryList();
    +908     for (_i = 0, _len = this.length; _i < _len; _i++) {
    +909       entry = this[_i];
    +910       cloned.push(entry);
    +911     }
    +912     for (_j = 0, _len1 = otherEntries.length; _j < _len1; _j++) {
    +913       entry = otherEntries[_j];
    +914       cloned.push(entry);
    +915     }
    +916     return cloned;
    +917   };
    +918 
    +919   /**
    +920   Match entries with the specified statuses
    +921   @return {CodedEntryList} the matching entries
    +922   */
    +923 
    +924 
    +925   CodedEntryList.prototype.withStatuses = function(statuses, includeUndefined) {
    +926     var cloned, entry, _i, _len, _ref1;
    +927 
    +928     if (includeUndefined == null) {
    +929       includeUndefined = true;
    +930     }
    +931     if (includeUndefined) {
    +932       statuses = statuses.concat([void 0, null]);
    +933     }
    +934     cloned = new hQuery.CodedEntryList();
    +935     for (_i = 0, _len = this.length; _i < _len; _i++) {
    +936       entry = this[_i];
    +937       if (_ref1 = entry.status(), __indexOf.call(statuses, _ref1) >= 0) {
    +938         cloned.push(entry);
    +939       }
    +940     }
    +941     return cloned;
    +942   };
    +943 
    +944   /**
    +945   Filter entries based on negation
    +946   @param {Object} codeSet a hash with code system names as keys and an array of codes as values
    +947   @return {CodedEntryList} negated entries
    +948   */
    +949 
    +950 
    +951   CodedEntryList.prototype.withNegation = function(codeSet) {
    +952     var cloned, entry, _i, _len;
    +953 
    +954     cloned = new hQuery.CodedEntryList();
    +955     for (_i = 0, _len = this.length; _i < _len; _i++) {
    +956       entry = this[_i];
    +957       if (entry.negationInd() && (!codeSet || (entry.negationReason() && entry.negationReason().includedIn(codeSet)))) {
    +958         cloned.push(entry);
    +959       }
    +960     }
    +961     return cloned;
     962   };
    -963   /**
    -964   comment
    -965   @returns {String}
    -966   */
    -967   Condition.prototype.comment = function() {
    -968     return this.json['comment'];
    -969   };
    -970   return Condition;
    -971 })();/**
    -972 @namespace scoping into the hquery namespace
    -973 */
    -974 var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
    -975   for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
    -976   function ctor() { this.constructor = child; }
    -977   ctor.prototype = parent.prototype;
    -978   child.prototype = new ctor;
    -979   child.__super__ = parent.prototype;
    -980   return child;
    -981 };
    -982 this.hQuery || (this.hQuery = {});
    -983 /**
    -984 An Encounter is an interaction, regardless of the setting, between a patient and a
    -985 practitioner who is vested with primary responsibility for diagnosing, evaluating,
    -986 or treating the patient's condition. It may include visits, appointments, as well
    -987 as non face-to-face interactions. It is also a contact between a patient and a
    -988 practitioner who has primary responsibility for assessing and treating the
    -989 patient at a given contact, exercising independent judgment.
    -990 @class An Encounter is an interaction, regardless of the setting, between a patient and a
    -991 practitioner 
    -992 @augments hQuery.CodedEntry
    -993 @exports Encounter as hQuery.Encounter 
    -994 */
    -995 hQuery.Encounter = (function() {
    -996   __extends(Encounter, hQuery.CodedEntry);
    -997   function Encounter() {
    -998     Encounter.__super__.constructor.apply(this, arguments);
    -999   }
    -1000   /**
    -1001   @returns {String}
    -1002   */
    -1003   Encounter.prototype.dischargeDisp = function() {
    -1004     return this.json['dischargeDisp'];
    -1005   };
    -1006   /**
    -1007   A code indicating the priority of the admission (e.g., Emergency, Urgent, Elective, et cetera) from
    -1008   National Uniform Billing Committee (NUBC)
    -1009   @returns {CodedValue}
    -1010   */
    -1011   Encounter.prototype.admitType = function() {
    -1012     return new hQuery.CodedValue(this.json['admitType']['code'], this.json['admitType']['codeSystem']);
    -1013   };
    -1014   /**
    -1015   @returns {hQuery.Actor}
    -1016   */
    -1017   Encounter.prototype.performer = function() {
    -1018     return new hQuery.Actor(this.json['performer']);
    -1019   };
    -1020   /**
    -1021   @returns {hQuery.Organization}
    -1022   */
    -1023   Encounter.prototype.facility = function() {
    -1024     return new hQuery.Organization(this.json['facility']);
    -1025   };
    -1026   /**
    -1027   @returns {hQuery.DateRange}
    -1028   */
    -1029   Encounter.prototype.encounterDuration = function() {
    -1030     return new hQuery.DateRange(this.json);
    -1031   };
    -1032   /**
    -1033   @returns {hQuery.CodedEntry}
    -1034   */
    -1035   Encounter.prototype.reasonForVisit = function() {
    -1036     return new hQuery.CodedEntry(this.json['reason']);
    -1037   };
    -1038   return Encounter;
    -1039 })();/**
    -1040 @namespace scoping into the hquery namespace
    -1041 */
    -1042 var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
    -1043   for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
    -1044   function ctor() { this.constructor = child; }
    -1045   ctor.prototype = parent.prototype;
    -1046   child.prototype = new ctor;
    -1047   child.__super__ = parent.prototype;
    -1048   return child;
    -1049 };
    -1050 this.hQuery || (this.hQuery = {});
    -1051 /**
    -1052 This represents all interventional, surgical, diagnostic, or therapeutic procedures or 
    -1053 treatments pertinent to the patient.
    -1054 @class
    -1055 @augments hQuery.CodedEntry
    -1056 @exports Procedure as hQuery.Procedure 
    -1057 */
    -1058 hQuery.Procedure = (function() {
    -1059   __extends(Procedure, hQuery.CodedEntry);
    -1060   function Procedure() {
    -1061     Procedure.__super__.constructor.apply(this, arguments);
    -1062   }
    -1063   /**
    -1064   @returns {hQuery.Actor} The provider that performed the procedure
    -1065   */
    -1066   Procedure.prototype.performer = function() {
    -1067     return new hQuery.Actor(this.json['performer']);
    -1068   };
    -1069   /**
    -1070   @returns {hQuery.CodedValue} A SNOMED code indicating the body site on which the 
    -1071   procedure was performed
    -1072   */
    -1073   Procedure.prototype.site = function() {
    -1074     return new hQuery.CodedValue(this.json['site']['code'], this.json['site']['codeSystem']);
    -1075   };
    -1076   return Procedure;
    -1077 })();/**
    -1078 @namespace scoping into the hquery namespace
    -1079 */
    -1080 var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
    -1081   for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
    -1082   function ctor() { this.constructor = child; }
    -1083   ctor.prototype = parent.prototype;
    -1084   child.prototype = new ctor;
    -1085   child.__super__ = parent.prototype;
    -1086   return child;
    -1087 };
    -1088 this.hQuery || (this.hQuery = {});
    -1089 /**
    -1090 Observations generated by laboratories, imaging procedures, and other procedures. The scope
    -1091 includes hematology, chemistry, serology, virology, toxicology, microbiology, plain x-ray,
    -1092 ultrasound, CT, MRI, angiography, cardiac echo, nuclear medicine, pathology, and procedure
    -1093 observations.
    -1094 @class
    -1095 @augments hQuery.CodedEntry
    -1096 @exports Result as hQuery.Result 
    -1097 */
    -1098 hQuery.Result = (function() {
    -1099   __extends(Result, hQuery.CodedEntry);
    -1100   function Result() {
    -1101     Result.__super__.constructor.apply(this, arguments);
    -1102   }
    -1103   /**
    -1104   ASTM CCR defines a restricted set of required result Type codes (see ResultTypeCode in section 7.3
    -1105   Summary of CCD value sets), used to categorize a result into one of several commonly accepted values
    -1106   (e.g. Hematology, Chemistry, Nuclear Medicine).
    -1107   @returns {CodedValue}
    -1108   */
    -1109   Result.prototype.resultType = function() {
    -1110     return this.type();
    -1111   };
    -1112   /**
    -1113   A status from the HL7 ActStatusNormal vocabulary
    -1114   @returns {String}
    -1115   */
    -1116   Result.prototype.status = function() {
    -1117     return this.json['status'];
    -1118   };
    -1119   /**
    -1120   Returns the value of the result. This will return an object. The properties of this
    -1121   object are dependent on the type of result.
    -1122   */
    -1123   Result.prototype.value = function() {
    -1124     return this.json['value'];
    -1125   };
    -1126   /**
    -1127   @returns {CodedValue}
    -1128   */
    -1129   Result.prototype.interpretation = function() {
    -1130     return new hQuery.CodedValue(this.json['interpretation'].code, this.json['interpretation'].codeSystem);
    -1131   };
    -1132   /**
    -1133   @returns {String}
    -1134   */
    -1135   Result.prototype.referenceRange = function() {
    -1136     return this.json['referenceRange'];
    -1137   };
    -1138   /**
    -1139   @returns {String}
    -1140   */
    -1141   Result.prototype.comment = function() {
    -1142     return this.json['comment'];
    +963 
    +964   /**
    +965   Filter entries based on negation
    +966   @return {CodedEntryList} non-negated entries
    +967   */
    +968 
    +969 
    +970   CodedEntryList.prototype.withoutNegation = function() {
    +971     var cloned, entry, _i, _len;
    +972 
    +973     cloned = new hQuery.CodedEntryList();
    +974     for (_i = 0, _len = this.length; _i < _len; _i++) {
    +975       entry = this[_i];
    +976       if (!entry.negationInd()) {
    +977         cloned.push(entry);
    +978       }
    +979     }
    +980     return cloned;
    +981   };
    +982 
    +983   return CodedEntryList;
    +984 
    +985 })(Array);
    +986 
    +987 /**
    +988 @private
    +989 @function
    +990 */
    +991 
    +992 
    +993 hQuery.createCodedValues = function(jsonCodes) {
    +994   var code, codeSystem, codedValues, codes, _i, _len;
    +995 
    +996   codedValues = [];
    +997   for (codeSystem in jsonCodes) {
    +998     codes = jsonCodes[codeSystem];
    +999     for (_i = 0, _len = codes.length; _i < _len; _i++) {
    +1000       code = codes[_i];
    +1001       codedValues.push(new hQuery.CodedValue(code, codeSystem));
    +1002     }
    +1003   }
    +1004   return codedValues;
    +1005 };
    +1006 /**
    +1007 @namespace scoping into the hquery namespace
    +1008 */
    +1009 
    +1010 var _ref, _ref1,
    +1011   __hasProp = {}.hasOwnProperty,
    +1012   __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
    +1013 
    +1014 this.hQuery || (this.hQuery = {});
    +1015 
    +1016 /**
    +1017 @class MedicationInformation
    +1018 @exports MedicationInformation as hQuery.MedicationInformation
    +1019 */
    +1020 
    +1021 
    +1022 hQuery.MedicationInformation = (function() {
    +1023   function MedicationInformation(json) {
    +1024     this.json = json;
    +1025   }
    +1026 
    +1027   /**
    +1028   An array of hQuery.CodedValue describing the medication
    +1029   @returns {Array}
    +1030   */
    +1031 
    +1032 
    +1033   MedicationInformation.prototype.codedProduct = function() {
    +1034     return hQuery.createCodedValues(this.json['codes']);
    +1035   };
    +1036 
    +1037   MedicationInformation.prototype.freeTextProductName = function() {
    +1038     return this.json['description'];
    +1039   };
    +1040 
    +1041   MedicationInformation.prototype.codedBrandName = function() {
    +1042     return this.json['codedBrandName'];
    +1043   };
    +1044 
    +1045   MedicationInformation.prototype.freeTextBrandName = function() {
    +1046     return this.json['brandName'];
    +1047   };
    +1048 
    +1049   MedicationInformation.prototype.drugManufacturer = function() {
    +1050     if (this.json['drugManufacturer']) {
    +1051       return new hQuery.Organization(this.json['drugManufacturer']);
    +1052     }
    +1053   };
    +1054 
    +1055   return MedicationInformation;
    +1056 
    +1057 })();
    +1058 
    +1059 /**
    +1060 @class AdministrationTiming - the
    +1061 @exports AdministrationTiming as hQuery.AdministrationTiming
    +1062 */
    +1063 
    +1064 
    +1065 hQuery.AdministrationTiming = (function() {
    +1066   function AdministrationTiming(json) {
    +1067     this.json = json;
    +1068   }
    +1069 
    +1070   /**
    +1071   Provides the period of medication administration as a Scalar. An example
    +1072   Scalar that would be returned would be with value = 8 and units = hours. This would
    +1073   mean that the medication should be taken every 8 hours.
    +1074   @returns {hQuery.Scalar}
    +1075   */
    +1076 
    +1077 
    +1078   AdministrationTiming.prototype.period = function() {
    +1079     return new hQuery.Scalar(this.json['period']);
    +1080   };
    +1081 
    +1082   /**
    +1083   Indicates whether it is the interval (time between dosing), or frequency 
    +1084   (number of doses in a time period) that is important. If instititutionSpecified is not 
    +1085   present or is set to false, then the time between dosing is important (every 8 hours). 
    +1086   If true, then the frequency of administration is important (e.g., 3 times per day).
    +1087   @returns {Boolean}
    +1088   */
    +1089 
    +1090 
    +1091   AdministrationTiming.prototype.institutionSpecified = function() {
    +1092     return this.json['institutionSpecified'];
    +1093   };
    +1094 
    +1095   return AdministrationTiming;
    +1096 
    +1097 })();
    +1098 
    +1099 /**
    +1100 @class DoseRestriction -  restrictions on the medications dose, represented by a upper and lower dose
    +1101 @exports DoseRestriction as hQuery.DoseRestriction
    +1102 */
    +1103 
    +1104 
    +1105 hQuery.DoseRestriction = (function() {
    +1106   function DoseRestriction(json) {
    +1107     this.json = json;
    +1108   }
    +1109 
    +1110   DoseRestriction.prototype.numerator = function() {
    +1111     return new hQuery.Scalar(this.json['numerator']);
    +1112   };
    +1113 
    +1114   DoseRestriction.prototype.denominator = function() {
    +1115     return new hQuery.Scalar(this.json['denominator']);
    +1116   };
    +1117 
    +1118   return DoseRestriction;
    +1119 
    +1120 })();
    +1121 
    +1122 /**
    +1123 @class Fulfillment - information about when and who fulfilled an order for the medication
    +1124 @exports Fulfillment as hQuery.Fullfilement
    +1125 */
    +1126 
    +1127 
    +1128 hQuery.Fulfillment = (function() {
    +1129   function Fulfillment(json) {
    +1130     this.json = json;
    +1131   }
    +1132 
    +1133   Fulfillment.prototype.dispenseDate = function() {
    +1134     return hQuery.dateFromUtcSeconds(this.json['dispenseDate']);
    +1135   };
    +1136 
    +1137   Fulfillment.prototype.dispensingPharmacyLocation = function() {
    +1138     return new hQuery.Address(this.json['dispensingPharmacyLocation']);
    +1139   };
    +1140 
    +1141   Fulfillment.prototype.quantityDispensed = function() {
    +1142     return new hQuery.Scalar(this.json['quantityDispensed']);
     1143   };
    -1144   return Result;
    -1145 })();/**
    -1146 @namespace scoping into the hquery namespace
    -1147 */
    -1148 var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
    -1149   for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
    -1150   function ctor() { this.constructor = child; }
    -1151   ctor.prototype = parent.prototype;
    -1152   child.prototype = new ctor;
    -1153   child.__super__ = parent.prototype;
    -1154   return child;
    -1155 };
    -1156 this.hQuery || (this.hQuery = {});
    -1157 /**
    -1158 NoImmunzation as defined by value set 2.16.840.1.113883.1.11.19717
    -1159 The terms come from Health Level Seven (HL7) Version 3.0 Vocabulary and are managed by HL7
    -1160 It indicates the reason an immunization was not administered.
    -1161 
    -1162 @class NoImmunization - describes the status of the medication
    -1163 @augments hQuery.CodedEntry
    -1164 @exports NoImmunization as hQuery.NoImmunization
    -1165 */
    -1166 hQuery.NoImmunization = (function() {
    -1167   var IMMUNITY, MED_PRECAUTION, OUT_OF_STOCK, PAT_OBJ, PHIL_OBJ, REL_OBJ, VAC_EFF, VAC_SAFETY;
    -1168   __extends(NoImmunization, hQuery.CodedValue);
    -1169   function NoImmunization() {
    -1170     NoImmunization.__super__.constructor.apply(this, arguments);
    -1171   }
    -1172   IMMUNITY = "IMMUNE";
    -1173   MED_PRECAUTION = "MEDPREC";
    -1174   OUT_OF_STOCK = "OSTOCK";
    -1175   PAT_OBJ = "PATOBJ";
    -1176   PHIL_OBJ = "PHILISOP";
    -1177   REL_OBJ = "RELIG";
    -1178   VAC_EFF = "VACEFF";
    -1179   VAC_SAFETY = "VACSAF";
    -1180   /**
    -1181   @returns {Boolean}
    -1182   */
    -1183   NoImmunization.prototype.isImmune = function() {
    -1184     return this.c === IMMUNITY;
    -1185   };
    -1186   /**
    -1187   @returns {Boolean}
    -1188   */
    -1189   NoImmunization.prototype.isMedPrec = function() {
    -1190     return this.c === MED_PRECAUTION;
    -1191   };
    -1192   /**
    -1193   @returns {Boolean}
    -1194   */
    -1195   NoImmunization.prototype.isOstock = function() {
    -1196     return this.c === OUT_OF_STOCK;
    -1197   };
    -1198   /**
    -1199   @returns {Boolean}
    -1200   */
    -1201   NoImmunization.prototype.isPatObj = function() {
    -1202     return this.c === PAT_OBJ;
    -1203   };
    -1204   /**
    -1205   @returns {Boolean}
    -1206   */
    -1207   NoImmunization.prototype.isPhilisop = function() {
    -1208     return this.c === PHIL_OBJ;
    -1209   };
    -1210   /**
    -1211   @returns {Boolean}
    -1212   */
    -1213   NoImmunization.prototype.isRelig = function() {
    -1214     return this.c === REL_OBJ;
    -1215   };
    -1216   /**
    -1217   @returns {Boolean}
    -1218   */
    -1219   NoImmunization.prototype.isVacEff = function() {
    -1220     return this.c === VAC_EFF;
    -1221   };
    +1144 
    +1145   Fulfillment.prototype.prescriptionNumber = function() {
    +1146     return this.json['prescriptionNumber'];
    +1147   };
    +1148 
    +1149   Fulfillment.prototype.fillNumber = function() {
    +1150     return this.json['fillNumber'];
    +1151   };
    +1152 
    +1153   Fulfillment.prototype.fillStatus = function() {
    +1154     return new hQuery.Status(this.json['fillStatus']);
    +1155   };
    +1156 
    +1157   return Fulfillment;
    +1158 
    +1159 })();
    +1160 
    +1161 /**
    +1162 @class OrderInformation - information abour an order for a medication
    +1163 @exports OrderInformation as hQuery.OrderInformation
    +1164 */
    +1165 
    +1166 
    +1167 hQuery.OrderInformation = (function() {
    +1168   function OrderInformation(json) {
    +1169     this.json = json;
    +1170   }
    +1171 
    +1172   OrderInformation.prototype.orderNumber = function() {
    +1173     return this.json['orderNumber'];
    +1174   };
    +1175 
    +1176   OrderInformation.prototype.fills = function() {
    +1177     return this.json['fills'];
    +1178   };
    +1179 
    +1180   OrderInformation.prototype.quantityOrdered = function() {
    +1181     return new hQuery.Scalar(this.json['quantityOrdered']);
    +1182   };
    +1183 
    +1184   OrderInformation.prototype.orderExpirationDateTime = function() {
    +1185     return hQuery.dateFromUtcSeconds(this.json['orderExpirationDateTime']);
    +1186   };
    +1187 
    +1188   OrderInformation.prototype.orderDateTime = function() {
    +1189     return hQuery.dateFromUtcSeconds(this.json['orderDateTime']);
    +1190   };
    +1191 
    +1192   return OrderInformation;
    +1193 
    +1194 })();
    +1195 
    +1196 /**
    +1197 TypeOfMedication as defined by value set 2.16.840.1.113883.3.88.12.3221.8.19
    +1198 which pulls two values from SNOMED to describe whether a medication is
    +1199 prescription or over the counter
    +1200 
    +1201 @class TypeOfMedication - describes whether a medication is prescription or
    +1202        over the counter
    +1203 @augments hQuery.CodedEntry
    +1204 @exports TypeOfMedication as hQuery.TypeOfMedication
    +1205 */
    +1206 
    +1207 
    +1208 hQuery.TypeOfMedication = (function(_super) {
    +1209   var OTC, PRESECRIPTION;
    +1210 
    +1211   __extends(TypeOfMedication, _super);
    +1212 
    +1213   function TypeOfMedication() {
    +1214     _ref = TypeOfMedication.__super__.constructor.apply(this, arguments);
    +1215     return _ref;
    +1216   }
    +1217 
    +1218   PRESECRIPTION = "73639000";
    +1219 
    +1220   OTC = "329505003";
    +1221 
     1222   /**
     1223   @returns {Boolean}
     1224   */
    -1225   NoImmunization.prototype.isVacSaf = function() {
    -1226     return this.c === VAC_SAFETY;
    -1227   };
    -1228   return NoImmunization;
    -1229 })();
    -1230 /**
    -1231 @class represents a immunization entry for a patient.
    -1232 @augments hQuery.CodedEntry
    -1233 @exports Immunization as hQuery.Immunization
    -1234 */
    -1235 hQuery.Immunization = (function() {
    -1236   __extends(Immunization, hQuery.CodedEntry);
    -1237   function Immunization(json) {
    -1238     this.json = json;
    -1239   }
    -1240   /**
    -1241   @returns{hQuery.Scalar} 
    -1242   */
    -1243   Immunization.prototype.medicationSeriesNumber = function() {
    -1244     return new hQuery.Scalar(this.json['medicationSeriesNumber']);
    -1245   };
    -1246   /**
    -1247   @returns{hQuery.MedicationInformation}
    -1248   */
    -1249   Immunization.prototype.medicationInformation = function() {
    -1250     return new hQuery.MedicationInformation(this.json);
    -1251   };
    -1252   /**
    -1253   @returns{Date} Date immunization was administered
    -1254   */
    -1255   Immunization.prototype.administeredDate = function() {
    -1256     return dateFromUtcSeconds(this.json['administeredDate']);
    -1257   };
    -1258   /**
    -1259   @returns{hQuery.Actor} Performer of immunization
    -1260   */
    -1261   Immunization.prototype.performer = function() {
    -1262     return new hQuery.Actor(this.json['performer']);
    -1263   };
    -1264   /**
    -1265   @returns {comment} human readable description of event
    -1266   */
    -1267   Immunization.prototype.comment = function() {
    -1268     return this.json['comment'];
    -1269   };
    -1270   /**
    -1271   @returns {Boolean} whether the immunization has been refused by the patient.
    -1272   */
    -1273   Immunization.prototype.refusalInd = function() {
    -1274     return this.json['refusalInd'];
    -1275   };
    -1276   /**
    -1277   NoImmunzation as defined by value set 2.16.840.1.113883.1.11.19717
    -1278   The terms come from Health Level Seven (HL7) Version 3.0 Vocabulary and are managed by HL7
    -1279   It indicates the reason an immunization was not administered.
    -1280   @returns {hQuery.NoImmunization}   Used to indicate reason an immunization was not administered.
    -1281   */
    -1282   Immunization.prototype.refusalReason = function() {
    -1283     return new hQuery.NoImmunization(this.json['refusalReason']['code'], this.json['refusalReason']['codeSystem']);
    -1284   };
    -1285   return Immunization;
    -1286 })();/**
    -1287 @namespace scoping into the hquery namespace
    -1288 */
    -1289 var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
    -1290   for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
    -1291   function ctor() { this.constructor = child; }
    -1292   ctor.prototype = parent.prototype;
    -1293   child.prototype = new ctor;
    -1294   child.__super__ = parent.prototype;
    -1295   return child;
    -1296 };
    -1297 this.hQuery || (this.hQuery = {});
    -1298 /**
    -1299 @class 
    -1300 @augments hQuery.CodedEntry
    -1301 @exports Allergy as hQuery.Allergy
    -1302 */
    -1303 hQuery.Allergy = (function() {
    -1304   __extends(Allergy, hQuery.CodedEntry);
    -1305   function Allergy() {
    -1306     Allergy.__super__.constructor.apply(this, arguments);
    -1307   }
    -1308   /**
    -1309   Food and substance allergies use the Unique Ingredient Identifier(UNII) from the FDA
    -1310   http://www.fda.gov/ForIndustry/DataStandards/StructuredProductLabeling/ucm162523.htm
    -1311   
    -1312   Allegies to a class of medication Shall contain a value descending from the NDF-RT concept types 
    -1313   of Mechanism of Action - N0000000223, Physiologic Effect - N0000009802 or 
    -1314   Chemical Structure - N0000000002. NUI will be used as the concept code. 
    -1315   For more information, please see the Web Site 
    -1316   http://www.cancer.gov/cancertopics/terminologyresources/page5
    -1317   
    -1318   Allergies to a specific medication shall use RxNorm for the values.  
    -1319   @returns {CodedValue}
    -1320   */
    -1321   Allergy.prototype.product = function() {
    -1322     return this.type();
    -1323   };
    -1324   /**
    -1325   Date of allergy or adverse event
    -1326   @returns{Date}
    -1327   */
    -1328   Allergy.prototype.adverseEventDate = function() {
    -1329     return dateFromUtcSeconds(this.json['adverseEventDate']);
    -1330   };
    -1331   /**
    -1332   Adverse event types SHALL be coded as specified in HITSP/C80 Section 2.2.3.4.2 Allergy/Adverse Event Type
    -1333   @returns {CodedValue}
    -1334   */
    -1335   Allergy.prototype.adverseEventType = function() {
    -1336     return new hQuery.CodedValue(this.json['type']['code'], this.json['type']['codeSystem']);
    -1337   };
    -1338   /**
    -1339   This indicates the reaction that may be caused by the product or agent.  
    -1340    It is defined by 2.16.840.1.113883.3.88.12.3221.6.2 and are SNOMED-CT codes.
    -1341   420134006   Propensity to adverse reactions (disorder)
    -1342   418038007   Propensity to adverse reactions to substance (disorder)
    -1343   419511003   Propensity to adverse reactions to drug (disorder)
    -1344   418471000   Propensity to adverse reactions to food (disorder)
    -1345   419199007  Allergy to substance (disorder)
    -1346   416098002  Drug allergy (disorder)
    -1347   414285001  Food allergy (disorder)
    -1348   59037007  Drug intolerance (disorder)
    -1349   235719002  Food intolerance (disorder)
    -1350   @returns {CodedValue} 
    +1225 
    +1226 
    +1227   TypeOfMedication.prototype.isPrescription = function() {
    +1228     return this.c === PRESECRIPTION;
    +1229   };
    +1230 
    +1231   /**
    +1232   @returns {Boolean}
    +1233   */
    +1234 
    +1235 
    +1236   TypeOfMedication.prototype.isOverTheCounter = function() {
    +1237     return this.c === OTC;
    +1238   };
    +1239 
    +1240   return TypeOfMedication;
    +1241 
    +1242 })(hQuery.CodedValue);
    +1243 
    +1244 /**
    +1245 StatusOfMedication as defined by value set 2.16.840.1.113883.1.11.20.7
    +1246 The terms come from SNOMED and are managed by HL7
    +1247 
    +1248 @class StatusOfMedication - describes the status of the medication
    +1249 @augments hQuery.CodedEntry
    +1250 @exports StatusOfMedication as hQuery.StatusOfMedication
    +1251 */
    +1252 
    +1253 
    +1254 hQuery.StatusOfMedication = (function(_super) {
    +1255   var ACTIVE, NO_LONGER_ACTIVE, ON_HOLD, PRIOR_HISTORY;
    +1256 
    +1257   __extends(StatusOfMedication, _super);
    +1258 
    +1259   function StatusOfMedication() {
    +1260     _ref1 = StatusOfMedication.__super__.constructor.apply(this, arguments);
    +1261     return _ref1;
    +1262   }
    +1263 
    +1264   ON_HOLD = "392521001";
    +1265 
    +1266   NO_LONGER_ACTIVE = "421139008";
    +1267 
    +1268   ACTIVE = "55561003";
    +1269 
    +1270   PRIOR_HISTORY = "73425007";
    +1271 
    +1272   /**
    +1273   @returns {Boolean}
    +1274   */
    +1275 
    +1276 
    +1277   StatusOfMedication.prototype.isOnHold = function() {
    +1278     return this.c === ON_HOLD;
    +1279   };
    +1280 
    +1281   /**
    +1282   @returns {Boolean}
    +1283   */
    +1284 
    +1285 
    +1286   StatusOfMedication.prototype.isNoLongerActive = function() {
    +1287     return this.c === NO_LONGER_ACTIVE;
    +1288   };
    +1289 
    +1290   /**
    +1291   @returns {Boolean}
    +1292   */
    +1293 
    +1294 
    +1295   StatusOfMedication.prototype.isActive = function() {
    +1296     return this.c === ACTIVE;
    +1297   };
    +1298 
    +1299   /**
    +1300   @returns {Boolean}
    +1301   */
    +1302 
    +1303 
    +1304   StatusOfMedication.prototype.isPriorHistory = function() {
    +1305     return this.c === PRIOR_HISTORY;
    +1306   };
    +1307 
    +1308   return StatusOfMedication;
    +1309 
    +1310 })(hQuery.CodedValue);
    +1311 
    +1312 /**
    +1313 @class represents a medication entry for a patient.
    +1314 @augments hQuery.CodedEntry
    +1315 @exports Medication as hQuery.Medication
    +1316 */
    +1317 
    +1318 
    +1319 hQuery.Medication = (function(_super) {
    +1320   __extends(Medication, _super);
    +1321 
    +1322   function Medication(json) {
    +1323     this.json = json;
    +1324     Medication.__super__.constructor.call(this, this.json);
    +1325   }
    +1326 
    +1327   /**
    +1328   @returns {String}
    +1329   */
    +1330 
    +1331 
    +1332   Medication.prototype.freeTextSig = function() {
    +1333     return this.json['freeTextSig'];
    +1334   };
    +1335 
    +1336   /**
    +1337   The actual or intended start of a medication. Slight deviation from greenCDA for C32 since
    +1338   it combines this with medication stop
    +1339   @returns {Date}
    +1340   */
    +1341 
    +1342 
    +1343   Medication.prototype.indicateMedicationStart = function() {
    +1344     return hQuery.dateFromUtcSeconds(this.json['start_time']);
    +1345   };
    +1346 
    +1347   /**
    +1348   The actual or intended stop of a medication. Slight deviation from greenCDA for C32 since
    +1349   it combines this with medication start
    +1350   @returns {Date}
     1351   */
    -1352   Allergy.prototype.reaction = function() {
    -1353     return new hQuery.CodedValue(this.json['reaction']['code'], this.json['reaction']['codeSystem']);
    -1354   };
    -1355   /**
    -1356   This is a description of the level of the severity of the allergy or intolerance.
    -1357   Use SNOMED-CT Codes as defined by 2.16.840.1.113883.3.88.12.3221.6.8
    -1358     255604002  Mild
    -1359     371923003  Mild to Moderate
    -1360     6736007      Moderate
    -1361     371924009  Moderate to Severe
    -1362     24484000    Severe
    -1363     399166001  Fatal
    -1364   @returns {CodedValue} 
    -1365   */
    -1366   Allergy.prototype.severity = function() {
    -1367     return new hQuery.CodedValue(this.json['severity']['code'], this.json['severity']['codeSystem']);
    -1368   };
    -1369   /**
    -1370   Additional comment or textual information
    -1371   @returns {String}
    -1372   */
    -1373   Allergy.prototype.comment = function() {
    -1374     return this.json['comment'];
    -1375   };
    -1376   return Allergy;
    -1377 })();/**
    -1378 @namespace scoping into the hquery namespace
    -1379 */this.hQuery || (this.hQuery = {});
    -1380 /**
    -1381 @class 
    +1352 
    +1353 
    +1354   Medication.prototype.indicateMedicationStop = function() {
    +1355     return hQuery.dateFromUtcSeconds(this.json['end_time']);
    +1356   };
    +1357 
    +1358   Medication.prototype.administrationTiming = function() {
    +1359     return new hQuery.AdministrationTiming(this.json['administrationTiming']);
    +1360   };
    +1361 
    +1362   /**
    +1363   @returns {CodedValue}  Contains routeCode or adminstrationUnitCode information.
    +1364     Route code shall have a a value drawn from FDA route of adminstration,
    +1365     and indicates how the medication is received by the patient.
    +1366     See http://www.fda.gov/Drugs/DevelopmentApprovalProcess/UCM070829
    +1367     The administration unit code shall have a value drawn from the FDA
    +1368     dosage form, source NCI thesaurus and represents the physical form of the
    +1369     product as presented to the patient.
    +1370     See http://www.fda.gov/Drugs/InformationOnDrugs/ucm142454.htm
    +1371   */
    +1372 
    +1373 
    +1374   Medication.prototype.route = function() {
    +1375     return new hQuery.CodedValue(this.json['route']['code'], this.json['route']['codeSystem']);
    +1376   };
    +1377 
    +1378   /**
    +1379   @returns {hQuery.Scalar} the dose
    +1380   */
    +1381 
     1382 
    -1383 @exports Provider as hQuery.Provider
    -1384 */
    -1385 hQuery.Provider = (function() {
    -1386   function Provider(json) {
    -1387     this.json = json;
    -1388   }
    -1389   /**
    -1390   @returns {hQuery.Person}
    -1391   */
    -1392   Provider.prototype.providerEntity = function() {
    -1393     return new hQuery.Person(this.json['providerEntity']);
    +1383   Medication.prototype.dose = function() {
    +1384     return new hQuery.Scalar(this.json['dose']);
    +1385   };
    +1386 
    +1387   /**
    +1388   @returns {CodedValue}
    +1389   */
    +1390 
    +1391 
    +1392   Medication.prototype.site = function() {
    +1393     return new hQuery.CodedValue(this.json['site']['code'], this.json['site']['codeSystem']);
     1394   };
    -1395   /**
    -1396   @returns {hQuery.DateRange}
    -1397   */
    -1398   Provider.prototype.careProvisionDateRange = function() {
    -1399     return new hQuery.DateRange(this.json['careProvisionDateRange']);
    -1400   };
    -1401   /**
    -1402   @returns {hQuery.CodedValue}
    -1403   */
    -1404   Provider.prototype.role = function() {
    -1405     return new hQuery.CodedValue(this.json['role']['code'], this.json['role']['codeSystem']);
    -1406   };
    -1407   /**
    -1408   @returns {String}
    -1409   */
    -1410   Provider.prototype.patientID = function() {
    -1411     return this.json['patientID'];
    +1395 
    +1396   /**
    +1397   @returns {hQuery.DoseRestriction}
    +1398   */
    +1399 
    +1400 
    +1401   Medication.prototype.doseRestriction = function() {
    +1402     return new hQuery.DoseRestriction(this.json['doseRestriction']);
    +1403   };
    +1404 
    +1405   /**
    +1406   @returns {String}
    +1407   */
    +1408 
    +1409 
    +1410   Medication.prototype.doseIndicator = function() {
    +1411     return this.json['doseIndicator'];
     1412   };
    -1413   /**
    -1414   @returns {hQuery.CodedValue}
    -1415   */
    -1416   Provider.prototype.providerType = function() {
    -1417     return new hQuery.CodedValue(this.json['providerType']['code'], this.json['providerType']['codeSystem']);
    -1418   };
    -1419   /**
    -1420   @returns {String}
    -1421   */
    -1422   Provider.prototype.providerID = function() {
    -1423     return this.json['providerID'];
    -1424   };
    -1425   /**
    -1426   @returns {hQuery.Organization}
    -1427   */
    -1428   Provider.prototype.organizationName = function() {
    -1429     return new hQuery.Organization(this.json);
    +1413 
    +1414   /**
    +1415   @returns {String}
    +1416   */
    +1417 
    +1418 
    +1419   Medication.prototype.fulfillmentInstructions = function() {
    +1420     return this.json['fulfillmentInstructions'];
    +1421   };
    +1422 
    +1423   /**
    +1424   @returns {CodedValue}
    +1425   */
    +1426 
    +1427 
    +1428   Medication.prototype.indication = function() {
    +1429     return new hQuery.CodedValue(this.json['indication']['code'], this.json['indication']['codeSystem']);
     1430   };
    -1431   return Provider;
    -1432 })();/**
    -1433 @namespace scoping into the hquery namespace
    -1434 */
    -1435 var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
    -1436   for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
    -1437   function ctor() { this.constructor = child; }
    -1438   ctor.prototype = parent.prototype;
    -1439   child.prototype = new ctor;
    -1440   child.__super__ = parent.prototype;
    -1441   return child;
    -1442 };
    -1443 this.hQuery || (this.hQuery = {});
    -1444 /**
    -1445 @class 
    -1446 @augments hQuery.CodedEntry
    -1447 @exports Language as hQuery.Language
    -1448 */
    -1449 hQuery.Language = (function() {
    -1450   __extends(Language, hQuery.CodedEntry);
    -1451   function Language(json) {
    -1452     this.json = json;
    -1453   }
    -1454   /**
    -1455   @returns {hQuery.CodedValue}
    -1456   */
    -1457   Language.prototype.modeCode = function() {
    -1458     return new hQuery.CodedValue(this.json['modeCode']['code'], this.json['modeCode']['codeSystem']);
    -1459   };
    -1460   /**
    -1461   @returns {String}
    -1462   */
    -1463   Language.prototype.preferenceIndicator = function() {
    -1464     return this.json['preferenceIndicator'];
    -1465   };
    -1466   return Language;
    -1467 })();/**
    -1468 @namespace scoping into the hquery namespace
    -1469 */
    -1470 var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
    -1471   for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
    -1472   function ctor() { this.constructor = child; }
    -1473   ctor.prototype = parent.prototype;
    -1474   child.prototype = new ctor;
    -1475   child.__super__ = parent.prototype;
    -1476   return child;
    -1477 };
    -1478 this.hQuery || (this.hQuery = {});
    -1479 /**
    -1480 This includes information about the patients current and past pregnancy status
    -1481 The Coded Entry code system should be SNOMED-CT
    -1482 @class
    -1483 @augments hQuery.CodedEntry
    -1484 @exports Pregnancy as hQuery.Pregnancy 
    -1485 */
    -1486 hQuery.Pregnancy = (function() {
    -1487   __extends(Pregnancy, hQuery.CodedEntry);
    -1488   function Pregnancy() {
    -1489     Pregnancy.__super__.constructor.apply(this, arguments);
    -1490   }
    -1491   /**
    -1492   @returns {String}
    -1493   */
    -1494   Pregnancy.prototype.comment = function() {
    -1495     return this.json['comment'];
    -1496   };
    -1497   return Pregnancy;
    -1498 })();/**
    -1499 @namespace scoping into the hquery namespace
    -1500 */
    -1501 var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
    -1502   for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
    -1503   function ctor() { this.constructor = child; }
    -1504   ctor.prototype = parent.prototype;
    -1505   child.prototype = new ctor;
    -1506   child.__super__ = parent.prototype;
    -1507   return child;
    -1508 };
    -1509 this.hQuery || (this.hQuery = {});
    -1510 /**
    +1431 
    +1432   /**
    +1433   @returns {CodedValue}
    +1434   */
    +1435 
    +1436 
    +1437   Medication.prototype.productForm = function() {
    +1438     return new hQuery.CodedValue(this.json['productForm']['code'], this.json['productForm']['codeSystem']);
    +1439   };
    +1440 
    +1441   /**
    +1442   @returns {CodedValue}
    +1443   */
    +1444 
    +1445 
    +1446   Medication.prototype.vehicle = function() {
    +1447     return new hQuery.CodedValue(this.json['vehicle']['code'], this.json['vehicle']['codeSystem']);
    +1448   };
    +1449 
    +1450   /**
    +1451   @returns {CodedValue}
    +1452   */
    +1453 
    +1454 
    +1455   Medication.prototype.reaction = function() {
    +1456     return new hQuery.CodedValue(this.json['reaction']['code'], this.json['reaction']['codeSystem']);
    +1457   };
    +1458 
    +1459   /**
    +1460   @returns {CodedValue}
    +1461   */
    +1462 
    +1463 
    +1464   Medication.prototype.deliveryMethod = function() {
    +1465     return new hQuery.CodedValue(this.json['deliveryMethod']['code'], this.json['deliveryMethod']['codeSystem']);
    +1466   };
    +1467 
    +1468   /**
    +1469   @returns {hQuery.MedicationInformation}
    +1470   */
    +1471 
    +1472 
    +1473   Medication.prototype.medicationInformation = function() {
    +1474     return new hQuery.MedicationInformation(this.json);
    +1475   };
    +1476 
    +1477   /**
    +1478   @returns {hQuery.TypeOfMedication} Indicates whether this is an over the counter or prescription medication
    +1479   */
    +1480 
    +1481 
    +1482   Medication.prototype.typeOfMedication = function() {
    +1483     return new hQuery.TypeOfMedication(this.json['typeOfMedication']['code'], this.json['typeOfMedication']['codeSystem']);
    +1484   };
    +1485 
    +1486   /**
    +1487   Values conform to value set 2.16.840.1.113883.1.11.20.7 - Medication Status
    +1488   Values may be: On Hold, No Longer Active, Active, Prior History
    +1489   @returns {hQuery.StatusOfMedication}   Used to indicate the status of the medication.
    +1490   */
    +1491 
    +1492 
    +1493   Medication.prototype.statusOfMedication = function() {
    +1494     return new hQuery.StatusOfMedication(this.json['statusOfMedication']['code'], this.json['statusOfMedication']['codeSystem']);
    +1495   };
    +1496 
    +1497   /**
    +1498   @returns {String} free text instructions to the patient
    +1499   */
    +1500 
    +1501 
    +1502   Medication.prototype.patientInstructions = function() {
    +1503     return this.json['patientInstructions'];
    +1504   };
    +1505 
    +1506   /**
    +1507   The duration over which this medication has been active. For example, 5 days.
    +1508   @returns {Hash} with two keys: unit and scalar
    +1509   */
    +1510 
     1511 
    -1512 The Social History Observation is used to define the patient's occupational, personal (e.g. lifestyle), 
    -1513 social, and environmental history and health risk factors, as well as administrative data such as 
    -1514 marital status, race, ethnicity and religious affiliation. The types of conditions
    -1515 described have been constrained to the SNOMED CT code system using constrained code set, 2.16.840.1.113883.3.88.12.80.60:
    -1516 229819007   Tobacco use and exposure
    -1517 256235009   Exercise
    -1518 160573003   Alcohol Intake
    -1519 364393001   Nutritional observable
    -1520 364703007   Employment detail
    -1521 425400000   Toxic exposure status
    -1522 363908000   Details of drug misuse behavior
    -1523 228272008   Health-related behavior
    -1524 105421008   Educational achievement
    -1525 
    -1526 note:  Social History is not part of the existing green c32.
    -1527 @exports Socialhistory as hQuery.Socialhistory 
    -1528 @augments hQuery.CodedEntry
    -1529 */
    -1530 hQuery.Socialhistory = (function() {
    -1531   __extends(Socialhistory, hQuery.CodedEntry);
    -1532   function Socialhistory(json) {
    -1533     this.json = json;
    -1534   }
    -1535   /**
    -1536   Value returns the value of the result. This will return an object. The properties of this
    -1537   object are dependent on the type of result.
    -1538   */
    -1539   Socialhistory.prototype.value = function() {
    -1540     return this.json['value'];
    -1541   };
    -1542   return Socialhistory;
    -1543 })();/**
    -1544 @namespace scoping into the hquery namespace
    -1545 */
    -1546 var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
    -1547   for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
    -1548   function ctor() { this.constructor = child; }
    -1549   ctor.prototype = parent.prototype;
    -1550   child.prototype = new ctor;
    -1551   child.__super__ = parent.prototype;
    -1552   return child;
    -1553 };
    -1554 this.hQuery || (this.hQuery = {});
    -1555 /**
    -1556 @class Supports
    -1557 @exports Supports as hQuery.Supports
    -1558 */
    -1559 hQuery.Supports = (function() {
    -1560   function Supports(json) {
    -1561     this.json = json;
    -1562   }
    -1563   /**
    -1564   @returns {DateRange}
    -1565   */
    -1566   Supports.prototype.supportDate = function() {
    -1567     return new hQuery.DateRange(this.json['supportDate']);
    -1568   };
    -1569   /**
    -1570   @returns {Person} 
    -1571   */
    -1572   Supports.prototype.guardian = function() {
    -1573     return new hQuery.Person(this.json['guardian']);
    -1574   };
    -1575   /**
    -1576   @returns {String}
    -1577   */
    -1578   Supports.prototype.guardianSupportType = function() {
    -1579     return this.json['guardianSupportType'];
    +1512   Medication.prototype.cumulativeMedicationDuration = function() {
    +1513     return this.json['cumulativeMedicationDuration'];
    +1514   };
    +1515 
    +1516   /**
    +1517   @returns {Array} an array of {@link FulFillment} objects
    +1518   */
    +1519 
    +1520 
    +1521   Medication.prototype.fulfillmentHistory = function() {
    +1522     var order, _i, _len, _ref2, _results;
    +1523 
    +1524     _ref2 = this.json['fulfillmentHistory'];
    +1525     _results = [];
    +1526     for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
    +1527       order = _ref2[_i];
    +1528       _results.push(new hQuery.Fulfillment(order));
    +1529     }
    +1530     return _results;
    +1531   };
    +1532 
    +1533   /**
    +1534   @returns {Array} an array of {@link OrderInformation} objects
    +1535   */
    +1536 
    +1537 
    +1538   Medication.prototype.orderInformation = function() {
    +1539     var order, _i, _len, _ref2, _results;
    +1540 
    +1541     _ref2 = this.json['orderInformation'];
    +1542     _results = [];
    +1543     for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
    +1544       order = _ref2[_i];
    +1545       _results.push(new hQuery.OrderInformation(order));
    +1546     }
    +1547     return _results;
    +1548   };
    +1549 
    +1550   return Medication;
    +1551 
    +1552 })(hQuery.CodedEntry);
    +1553 /**
    +1554 @namespace scoping into the hquery namespace
    +1555 */
    +1556 
    +1557 var __hasProp = {}.hasOwnProperty,
    +1558   __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
    +1559 
    +1560 this.hQuery || (this.hQuery = {});
    +1561 
    +1562 /**
    +1563 @class CauseOfDeath
    +1564 @exports CauseOfDeath as hQuery.CauseOfDeath
    +1565 */
    +1566 
    +1567 
    +1568 hQuery.CauseOfDeath = (function() {
    +1569   function CauseOfDeath(json) {
    +1570     this.json = json;
    +1571   }
    +1572 
    +1573   /**
    +1574   @returns {hQuery.Date}
    +1575   */
    +1576 
    +1577 
    +1578   CauseOfDeath.prototype.timeOfDeath = function() {
    +1579     return new hQuery.dateFromUtcSeconds(this.json['timeOfDeath']);
     1580   };
    -1581   /**
    -1582   @returns {Person}
    -1583   */
    -1584   Supports.prototype.contact = function() {
    -1585     return new hQuery.Person(this.json['contact']);
    -1586   };
    -1587   /**
    -1588   @returns {String}
    -1589   */
    -1590   Supports.prototype.contactSupportType = function() {
    -1591     return this.json['guardianSupportType'];
    -1592   };
    -1593   return Supports;
    -1594 })();
    +1581 
    +1582   /**
    +1583   @returns {int}
    +1584   */
    +1585 
    +1586 
    +1587   CauseOfDeath.prototype.ageAtDeath = function() {
    +1588     return this.json['ageAtDeath'];
    +1589   };
    +1590 
    +1591   return CauseOfDeath;
    +1592 
    +1593 })();
    +1594 
     1595 /**
    -1596 @class Representation of a patient
    -1597 @augments hQuery.Person
    -1598 @exports Patient as hQuery.Patient
    -1599 */
    -1600 hQuery.Patient = (function() {
    -1601   __extends(Patient, hQuery.Person);
    -1602   function Patient() {
    -1603     Patient.__super__.constructor.apply(this, arguments);
    -1604   }
    -1605   /**
    -1606   @returns {String} containing M or F representing the gender of the patient
    -1607   */
    -1608   Patient.prototype.gender = function() {
    -1609     return this.json['gender'];
    -1610   };
    -1611   /**
    -1612   @returns {Date} containing the patient's birthdate
    -1613   */
    -1614   Patient.prototype.birthtime = function() {
    -1615     return hQuery.dateFromUtcSeconds(this.json['birthdate']);
    -1616   };
    -1617   /**
    -1618   @param (Date) date the date at which the patient age is calculated, defaults to now.
    -1619   @returns {number} the patient age in years
    -1620   */
    -1621   Patient.prototype.age = function(date) {
    -1622     var oneDay, oneYear;
    -1623     if (date == null) {
    -1624       date = new Date();
    -1625     }
    -1626     oneDay = 24 * 60 * 60 * 1000;
    -1627     oneYear = 365 * oneDay;
    -1628     return (date.getTime() - this.birthtime().getTime()) / oneYear;
    +1596 @class hQuery.Condition
    +1597 
    +1598 This section is used to describe a patients problems/conditions. The types of conditions
    +1599 described have been constrained to the SNOMED CT Problem Type code set. An unbounded
    +1600 number of treating providers for the particular condition can be supplied.
    +1601 @exports Condition as hQuery.Condition 
    +1602 @augments hQuery.CodedEntry
    +1603 */
    +1604 
    +1605 
    +1606 hQuery.Condition = (function(_super) {
    +1607   __extends(Condition, _super);
    +1608 
    +1609   function Condition(json) {
    +1610     this.json = json;
    +1611     Condition.__super__.constructor.call(this, this.json);
    +1612   }
    +1613 
    +1614   /**
    +1615    @returns {Array, hQuery.Provider} an array of providers for the condition
    +1616   */
    +1617 
    +1618 
    +1619   Condition.prototype.providers = function() {
    +1620     var provider, _i, _len, _ref, _results;
    +1621 
    +1622     _ref = this.json['treatingProviders'];
    +1623     _results = [];
    +1624     for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    +1625       provider = _ref[_i];
    +1626       _results.push(new Provider(provider));
    +1627     }
    +1628     return _results;
     1629   };
    -1630   /**
    -1631   @returns {CodedValue} the domestic partnership status of the patient
    -1632   The following HL7 codeset is used:
    -1633   A  Annulled
    -1634   D  Divorced
    -1635   I   Interlocutory
    -1636   L  Legally separated
    -1637   M  Married
    -1638   P  Polygamous
    -1639   S  Never Married
    -1640   T  Domestic Partner
    -1641   W  Widowed
    -1642   */
    -1643   Patient.prototype.maritalStatus = function() {
    -1644     if (this.json['maritalStatus']) {
    -1645       return new hQuery.CodedValue(this.json['maritalStatus']['code'], this.json['maritalStatus']['codeSystem']);
    -1646     }
    -1647   };
    -1648   /**
    -1649   @returns {CodedValue}  of the spiritual faith affiliation of the patient
    -1650   It uses the HL7 codeset.  http://www.hl7.org/memonly/downloads/v3edition.cfm#V32008
    -1651   */
    -1652   Patient.prototype.religiousAffiliation = function() {
    -1653     if (this.json['religiousAffiliation']) {
    -1654       return new hQuery.CodedValue(this.json['religiousAffiliation']['code'], this.json['religiousAffiliation']['codeSystem']);
    -1655     }
    -1656   };
    -1657   /**
    -1658   @returns {CodedValue}  of the race of the patient
    -1659   CDC codes:  http://phinvads.cdc.gov/vads/ViewCodeSystemConcept.action?oid=2.16.840.1.113883.6.238&code=1000-9
    -1660   */
    -1661   Patient.prototype.race = function() {
    -1662     if (this.json['race']) {
    -1663       return new hQuery.CodedValue(this.json['race']['code'], this.json['race']['codeSystem']);
    -1664     }
    -1665   };
    -1666   /**
    -1667   @returns {CodedValue} of the ethnicity of the patient
    -1668   CDC codes:  http://phinvads.cdc.gov/vads/ViewCodeSystemConcept.action?oid=2.16.840.1.113883.6.238&code=1000-9
    -1669   */
    -1670   Patient.prototype.ethnicity = function() {
    -1671     if (this.json['ethnicity']) {
    -1672       return new hQuery.CodedValue(this.json['ethnicity']['code'], this.json['ethnicity']['codeSystem']);
    -1673     }
    -1674   };
    -1675   /**
    -1676   @returns {CodedValue} This is the code specifying the level of confidentiality of the document.
    -1677   HL7 Confidentiality Code (2.16.840.1.113883.5.25)
    -1678   */
    -1679   Patient.prototype.confidentiality = function() {
    -1680     if (this.json['confidentiality']) {
    -1681       return new hQuery.CodedValue(this.json['confidentiality']['code'], this.json['confidentiality']['codeSystem']);
    -1682     }
    -1683   };
    -1684   /**
    -1685   @returns {Address} of the location where the patient was born
    -1686   */
    -1687   Patient.prototype.birthPlace = function() {
    -1688     return new hQuery.Address(this.json['birthPlace']);
    +1630 
    +1631   /**
    +1632   Diagnosis Priority
    +1633   @returns {int}
    +1634   */
    +1635 
    +1636 
    +1637   Condition.prototype.diagnosisPriority = function() {
    +1638     return this.json['priority'];
    +1639   };
    +1640 
    +1641   /**
    +1642   Ordinality
    +1643   @returns {String}
    +1644   */
    +1645 
    +1646 
    +1647   Condition.prototype.ordinality = function() {
    +1648     return this.json['ordinality'];
    +1649   };
    +1650 
    +1651   /**
    +1652   age at onset
    +1653   @returns {int}
    +1654   */
    +1655 
    +1656 
    +1657   Condition.prototype.ageAtOnset = function() {
    +1658     return this.json['ageAtOnset'];
    +1659   };
    +1660 
    +1661   /**
    +1662   cause of death
    +1663   @returns {hQuery.CauseOfDeath}
    +1664   */
    +1665 
    +1666 
    +1667   Condition.prototype.causeOfDeath = function() {
    +1668     return new hQuery.CauseOfDeath(this.json['causeOfDeath']);
    +1669   };
    +1670 
    +1671   /**
    +1672   problem status
    +1673   @returns {hQuery.CodedValue}
    +1674   */
    +1675 
    +1676 
    +1677   Condition.prototype.problemStatus = function() {
    +1678     return new hQuery.CodedValue(this.json['problemStatus']['code'], this.json['problemStatus']['codeSystem']);
    +1679   };
    +1680 
    +1681   /**
    +1682   comment
    +1683   @returns {String}
    +1684   */
    +1685 
    +1686 
    +1687   Condition.prototype.comment = function() {
    +1688     return this.json['comment'];
     1689   };
    -1690   /**
    -1691   @returns {Supports} information regarding key support contacts relative to healthcare decisions, including next of kin
    -1692   */
    -1693   Patient.prototype.supports = function() {
    -1694     return new hQuery.Supports(this.json['supports']);
    -1695   };
    -1696   /**
    -1697   @returns {Organization}
    -1698   */
    -1699   Patient.prototype.custodian = function() {
    -1700     return new hQuery.Organization(this.json['custodian']);
    -1701   };
    -1702   /**
    -1703   @returns {Provider}  the providers associated with the patient
    -1704   */
    -1705   Patient.prototype.provider = function() {
    -1706     return new hQuery.Provider(this.json['provider']);
    -1707   };
    -1708   /**
    -1709   @returns {hQuery.CodedEntryList} A list of {@link hQuery.LanguagesSpoken} objects
    -1710   Code from http://www.ietf.org/rfc/rfc4646.txt representing the name of the human language
    -1711   */
    -1712   Patient.prototype.languages = function() {
    -1713     var language, list, _i, _len, _ref;
    -1714     list = new hQuery.CodedEntryList;
    -1715     if (this.json['languages']) {
    -1716       _ref = this.json['languages'];
    -1717       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    -1718         language = _ref[_i];
    -1719         list.push(new hQuery.Language(language));
    -1720       }
    -1721     }
    -1722     return list;
    -1723   };
    -1724   /**
    -1725   @returns {hQuery.CodedEntryList} A list of {@link hQuery.Encounter} objects
    -1726   */
    -1727   Patient.prototype.encounters = function() {
    -1728     var encounter, list, _i, _len, _ref;
    -1729     list = new hQuery.CodedEntryList;
    -1730     if (this.json['encounters']) {
    -1731       _ref = this.json['encounters'];
    -1732       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    -1733         encounter = _ref[_i];
    -1734         list.push(new hQuery.Encounter(encounter));
    -1735       }
    -1736     }
    -1737     return list;
    -1738   };
    -1739   /**
    -1740   @returns {hQuery.CodedEntryList} A list of {@link Medication} objects
    -1741   */
    -1742   Patient.prototype.medications = function() {
    -1743     var list, medication, _i, _len, _ref;
    -1744     list = new hQuery.CodedEntryList;
    -1745     if (this.json['medications']) {
    -1746       _ref = this.json['medications'];
    -1747       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    -1748         medication = _ref[_i];
    -1749         list.push(new hQuery.Medication(medication));
    -1750       }
    -1751     }
    -1752     return list;
    +1690 
    +1691   /**
    +1692   This is a description of the level of the severity of the condition.
    +1693   @returns {CodedValue}
    +1694   */
    +1695 
    +1696 
    +1697   Condition.prototype.severity = function() {
    +1698     return new hQuery.CodedValue(this.json['severity']['code'], this.json['severity']['codeSystem']);
    +1699   };
    +1700 
    +1701   return Condition;
    +1702 
    +1703 })(hQuery.CodedEntry);
    +1704 /**
    +1705 @namespace scoping into the hquery namespace
    +1706 */
    +1707 
    +1708 var __hasProp = {}.hasOwnProperty,
    +1709   __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
    +1710 
    +1711 this.hQuery || (this.hQuery = {});
    +1712 
    +1713 /**
    +1714 An Encounter is an interaction, regardless of the setting, between a patient and a
    +1715 practitioner who is vested with primary responsibility for diagnosing, evaluating,
    +1716 or treating the patient's condition. It may include visits, appointments, as well
    +1717 as non face-to-face interactions. It is also a contact between a patient and a
    +1718 practitioner who has primary responsibility for assessing and treating the
    +1719 patient at a given contact, exercising independent judgment.
    +1720 @class An Encounter is an interaction, regardless of the setting, between a patient and a
    +1721 practitioner 
    +1722 @augments hQuery.CodedEntry
    +1723 @exports Encounter as hQuery.Encounter
    +1724 */
    +1725 
    +1726 
    +1727 hQuery.Encounter = (function(_super) {
    +1728   __extends(Encounter, _super);
    +1729 
    +1730   function Encounter(json) {
    +1731     this.json = json;
    +1732     Encounter.__super__.constructor.call(this, this.json);
    +1733   }
    +1734 
    +1735   /**
    +1736   @returns {String}
    +1737   */
    +1738 
    +1739 
    +1740   Encounter.prototype.dischargeDisp = function() {
    +1741     return this.json['dischargeDisp'];
    +1742   };
    +1743 
    +1744   /**
    +1745   A code indicating the priority of the admission (e.g., Emergency, Urgent, Elective, et cetera) from
    +1746   National Uniform Billing Committee (NUBC)
    +1747   @returns {CodedValue}
    +1748   */
    +1749 
    +1750 
    +1751   Encounter.prototype.admitType = function() {
    +1752     return new hQuery.CodedValue(this.json['admitType']['code'], this.json['admitType']['codeSystem']);
     1753   };
    -1754   /**
    -1755   @returns {hQuery.CodedEntryList} A list of {@link Condition} objects
    -1756   */
    -1757   Patient.prototype.conditions = function() {
    -1758     var condition, list, _i, _len, _ref;
    -1759     list = new hQuery.CodedEntryList;
    -1760     if (this.json['conditions']) {
    -1761       _ref = this.json['conditions'];
    -1762       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    -1763         condition = _ref[_i];
    -1764         list.push(new hQuery.Condition(condition));
    -1765       }
    -1766     }
    -1767     return list;
    -1768   };
    -1769   /**
    -1770   @returns {hQuery.CodedEntryList} A list of {@link Procedure} objects
    -1771   */
    -1772   Patient.prototype.procedures = function() {
    -1773     var list, procedure, _i, _len, _ref;
    -1774     list = new hQuery.CodedEntryList;
    -1775     if (this.json['procedures']) {
    -1776       _ref = this.json['procedures'];
    -1777       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    -1778         procedure = _ref[_i];
    -1779         list.push(new hQuery.Procedure(procedure));
    -1780       }
    -1781     }
    -1782     return list;
    -1783   };
    -1784   /**
    -1785   @returns {hQuery.CodedEntryList} A list of {@link Result} objects
    -1786   */
    -1787   Patient.prototype.results = function() {
    -1788     var list, result, _i, _len, _ref;
    -1789     list = new hQuery.CodedEntryList;
    -1790     if (this.json['results']) {
    -1791       _ref = this.json['results'];
    -1792       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    -1793         result = _ref[_i];
    -1794         list.push(new hQuery.Result(result));
    -1795       }
    -1796     }
    -1797     return list;
    -1798   };
    -1799   /**
    -1800   @returns {hQuery.CodedEntryList} A list of {@link Result} objects
    -1801   */
    -1802   Patient.prototype.vitalSigns = function() {
    -1803     var list, vital, _i, _len, _ref;
    -1804     list = new hQuery.CodedEntryList;
    -1805     if (this.json['vital_signs']) {
    -1806       _ref = this.json['vital_signs'];
    -1807       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    -1808         vital = _ref[_i];
    -1809         list.push(new hQuery.Result(vital));
    -1810       }
    -1811     }
    -1812     return list;
    -1813   };
    -1814   /**
    -1815   @returns {hQuery.CodedEntryList} A list of {@link Immunization} objects
    -1816   */
    -1817   Patient.prototype.immunizations = function() {
    -1818     var immunization, list, _i, _len, _ref;
    -1819     list = new hQuery.CodedEntryList;
    -1820     if (this.json['immunizations']) {
    -1821       _ref = this.json['immunizations'];
    -1822       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    -1823         immunization = _ref[_i];
    -1824         list.push(new hQuery.Immunization(immunization));
    -1825       }
    -1826     }
    -1827     return list;
    -1828   };
    +1754 
    +1755   /**
    +1756   @returns {hQuery.Actor}
    +1757   */
    +1758 
    +1759 
    +1760   Encounter.prototype.performer = function() {
    +1761     return new hQuery.Actor(this.json['performer']);
    +1762   };
    +1763 
    +1764   /**
    +1765   @returns {hQuery.Organization}
    +1766   */
    +1767 
    +1768 
    +1769   Encounter.prototype.facility = function() {
    +1770     return new hQuery.Facility(this.json['facility']);
    +1771   };
    +1772 
    +1773   /**
    +1774   @returns {hQuery.DateRange}
    +1775   */
    +1776 
    +1777 
    +1778   Encounter.prototype.encounterDuration = function() {
    +1779     return new hQuery.DateRange(this.json);
    +1780   };
    +1781 
    +1782   /**
    +1783   @returns {hQuery.CodedEntry}
    +1784   */
    +1785 
    +1786 
    +1787   Encounter.prototype.reasonForVisit = function() {
    +1788     return new hQuery.CodedEntry(this.json['reason']);
    +1789   };
    +1790 
    +1791   return Encounter;
    +1792 
    +1793 })(hQuery.CodedEntry);
    +1794 /**
    +1795 @namespace scoping into the hquery namespace
    +1796 */
    +1797 
    +1798 var __hasProp = {}.hasOwnProperty,
    +1799   __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
    +1800 
    +1801 this.hQuery || (this.hQuery = {});
    +1802 
    +1803 /**
    +1804 This represents all interventional, surgical, diagnostic, or therapeutic procedures or 
    +1805 treatments pertinent to the patient.
    +1806 @class
    +1807 @augments hQuery.CodedEntry
    +1808 @exports Procedure as hQuery.Procedure
    +1809 */
    +1810 
    +1811 
    +1812 hQuery.Procedure = (function(_super) {
    +1813   __extends(Procedure, _super);
    +1814 
    +1815   function Procedure(json) {
    +1816     this.json = json;
    +1817     Procedure.__super__.constructor.call(this, this.json);
    +1818   }
    +1819 
    +1820   /**
    +1821   @returns {hQuery.Actor} The provider that performed the procedure
    +1822   */
    +1823 
    +1824 
    +1825   Procedure.prototype.performer = function() {
    +1826     return new hQuery.Actor(this.json['performer']);
    +1827   };
    +1828 
     1829   /**
    -1830   @returns {hQuery.CodedEntryList} A list of {@link Allergy} objects
    -1831   */
    -1832   Patient.prototype.allergies = function() {
    -1833     var allergy, list, _i, _len, _ref;
    -1834     list = new hQuery.CodedEntryList;
    -1835     if (this.json['allergies']) {
    -1836       _ref = this.json['allergies'];
    -1837       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    -1838         allergy = _ref[_i];
    -1839         list.push(new hQuery.Allergy(allergy));
    -1840       }
    -1841     }
    -1842     return list;
    -1843   };
    -1844   /**
    -1845   @returns {hQuery.CodedEntryList} A list of {@link Pregnancy} objects
    -1846   */
    -1847   Patient.prototype.pregnancies = function() {
    -1848     var list, pregnancy, _i, _len, _ref;
    -1849     list = new hQuery.CodedEntryList;
    -1850     if (this.json['pregnancies']) {
    -1851       _ref = this.json['pregnancies'];
    -1852       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    -1853         pregnancy = _ref[_i];
    -1854         list.push(new hQuery.Pregnancy(pregnancy));
    -1855       }
    -1856     }
    -1857     return list;
    -1858   };
    -1859   /**
    -1860   @returns {hQuery.CodedEntryList} A list of {@link Socialhistory} objects
    -1861   */
    -1862   Patient.prototype.socialhistories = function() {
    -1863     var list, socialhistory, _i, _len, _ref;
    -1864     list = new hQuery.CodedEntryList;
    -1865     if (this.json['socialhistories']) {
    -1866       _ref = this.json['socialhistories'];
    -1867       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    -1868         socialhistory = _ref[_i];
    -1869         list.push(new hQuery.Socialhistory(socialhistory));
    -1870       }
    -1871     }
    -1872     return list;
    -1873   };
    -1874   return Patient;
    -1875 })();
    \ No newline at end of file +1830 @returns {hQuery.CodedValue} A SNOMED code indicating the body site on which the +1831 procedure was performed +1832 */ +1833 +1834 +1835 Procedure.prototype.site = function() { +1836 return new hQuery.CodedValue(this.json['site']['code'], this.json['site']['codeSystem']); +1837 }; +1838 +1839 return Procedure; +1840 +1841 })(hQuery.CodedEntry); +1842 /** +1843 @namespace scoping into the hquery namespace +1844 */ +1845 +1846 var __hasProp = {}.hasOwnProperty, +1847 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; +1848 +1849 this.hQuery || (this.hQuery = {}); +1850 +1851 /** +1852 Observations generated by laboratories, imaging procedures, and other procedures. The scope +1853 includes hematology, chemistry, serology, virology, toxicology, microbiology, plain x-ray, +1854 ultrasound, CT, MRI, angiography, cardiac echo, nuclear medicine, pathology, and procedure +1855 observations. +1856 @class +1857 @augments hQuery.CodedEntry +1858 @exports Result as hQuery.Result +1859 */ +1860 +1861 +1862 hQuery.Result = (function(_super) { +1863 __extends(Result, _super); +1864 +1865 function Result(json) { +1866 this.json = json; +1867 Result.__super__.constructor.call(this, this.json); +1868 } +1869 +1870 /** +1871 ASTM CCR defines a restricted set of required result Type codes (see ResultTypeCode in section 7.3 +1872 Summary of CCD value sets), used to categorize a result into one of several commonly accepted values +1873 (e.g. Hematology, Chemistry, Nuclear Medicine). +1874 @returns {CodedValue} +1875 */ +1876 +1877 +1878 Result.prototype.resultType = function() { +1879 return this.type(); +1880 }; +1881 +1882 /** +1883 @returns {CodedValue} +1884 */ +1885 +1886 +1887 Result.prototype.interpretation = function() { +1888 return new hQuery.CodedValue(this.json['interpretation'].code, this.json['interpretation'].codeSystem); +1889 }; +1890 +1891 /** +1892 @returns {String} +1893 */ +1894 +1895 +1896 Result.prototype.referenceRange = function() { +1897 return this.json['referenceRange']; +1898 }; +1899 +1900 /** +1901 @returns {String} +1902 */ +1903 +1904 +1905 Result.prototype.comment = function() { +1906 return this.json['comment']; +1907 }; +1908 +1909 return Result; +1910 +1911 })(hQuery.CodedEntry); +1912 /** +1913 @namespace scoping into the hquery namespace +1914 */ +1915 +1916 var _ref, +1917 __hasProp = {}.hasOwnProperty, +1918 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; +1919 +1920 this.hQuery || (this.hQuery = {}); +1921 +1922 /** +1923 NoImmunzation as defined by value set 2.16.840.1.113883.1.11.19717 +1924 The terms come from Health Level Seven (HL7) Version 3.0 Vocabulary and are managed by HL7 +1925 It indicates the reason an immunization was not administered. +1926 +1927 @class NoImmunization - describes the status of the medication +1928 @augments hQuery.CodedEntry +1929 @exports NoImmunization as hQuery.NoImmunization +1930 */ +1931 +1932 +1933 hQuery.NoImmunization = (function(_super) { +1934 var IMMUNITY, MED_PRECAUTION, OUT_OF_STOCK, PAT_OBJ, PHIL_OBJ, REL_OBJ, VAC_EFF, VAC_SAFETY; +1935 +1936 __extends(NoImmunization, _super); +1937 +1938 function NoImmunization() { +1939 _ref = NoImmunization.__super__.constructor.apply(this, arguments); +1940 return _ref; +1941 } +1942 +1943 IMMUNITY = "IMMUNE"; +1944 +1945 MED_PRECAUTION = "MEDPREC"; +1946 +1947 OUT_OF_STOCK = "OSTOCK"; +1948 +1949 PAT_OBJ = "PATOBJ"; +1950 +1951 PHIL_OBJ = "PHILISOP"; +1952 +1953 REL_OBJ = "RELIG"; +1954 +1955 VAC_EFF = "VACEFF"; +1956 +1957 VAC_SAFETY = "VACSAF"; +1958 +1959 /** +1960 @returns {Boolean} +1961 */ +1962 +1963 +1964 NoImmunization.prototype.isImmune = function() { +1965 return this.c === IMMUNITY; +1966 }; +1967 +1968 /** +1969 @returns {Boolean} +1970 */ +1971 +1972 +1973 NoImmunization.prototype.isMedPrec = function() { +1974 return this.c === MED_PRECAUTION; +1975 }; +1976 +1977 /** +1978 @returns {Boolean} +1979 */ +1980 +1981 +1982 NoImmunization.prototype.isOstock = function() { +1983 return this.c === OUT_OF_STOCK; +1984 }; +1985 +1986 /** +1987 @returns {Boolean} +1988 */ +1989 +1990 +1991 NoImmunization.prototype.isPatObj = function() { +1992 return this.c === PAT_OBJ; +1993 }; +1994 +1995 /** +1996 @returns {Boolean} +1997 */ +1998 +1999 +2000 NoImmunization.prototype.isPhilisop = function() { +2001 return this.c === PHIL_OBJ; +2002 }; +2003 +2004 /** +2005 @returns {Boolean} +2006 */ +2007 +2008 +2009 NoImmunization.prototype.isRelig = function() { +2010 return this.c === REL_OBJ; +2011 }; +2012 +2013 /** +2014 @returns {Boolean} +2015 */ +2016 +2017 +2018 NoImmunization.prototype.isVacEff = function() { +2019 return this.c === VAC_EFF; +2020 }; +2021 +2022 /** +2023 @returns {Boolean} +2024 */ +2025 +2026 +2027 NoImmunization.prototype.isVacSaf = function() { +2028 return this.c === VAC_SAFETY; +2029 }; +2030 +2031 return NoImmunization; +2032 +2033 })(hQuery.CodedValue); +2034 +2035 /** +2036 @class represents a immunization entry for a patient. +2037 @augments hQuery.CodedEntry +2038 @exports Immunization as hQuery.Immunization +2039 */ +2040 +2041 +2042 hQuery.Immunization = (function(_super) { +2043 __extends(Immunization, _super); +2044 +2045 function Immunization(json) { +2046 this.json = json; +2047 Immunization.__super__.constructor.call(this, this.json); +2048 } +2049 +2050 /** +2051 @returns{hQuery.Scalar} +2052 */ +2053 +2054 +2055 Immunization.prototype.medicationSeriesNumber = function() { +2056 return new hQuery.Scalar(this.json['medicationSeriesNumber']); +2057 }; +2058 +2059 /** +2060 @returns{hQuery.MedicationInformation} +2061 */ +2062 +2063 +2064 Immunization.prototype.medicationInformation = function() { +2065 return new hQuery.MedicationInformation(this.json); +2066 }; +2067 +2068 /** +2069 @returns{Date} Date immunization was administered +2070 */ +2071 +2072 +2073 Immunization.prototype.administeredDate = function() { +2074 return dateFromUtcSeconds(this.json['administeredDate']); +2075 }; +2076 +2077 /** +2078 @returns{hQuery.Actor} Performer of immunization +2079 */ +2080 +2081 +2082 Immunization.prototype.performer = function() { +2083 return new hQuery.Actor(this.json['performer']); +2084 }; +2085 +2086 /** +2087 @returns {comment} human readable description of event +2088 */ +2089 +2090 +2091 Immunization.prototype.comment = function() { +2092 return this.json['comment']; +2093 }; +2094 +2095 /** +2096 @returns {Boolean} whether the immunization has been refused by the patient. +2097 */ +2098 +2099 +2100 Immunization.prototype.refusalInd = function() { +2101 return this.json['negationInd']; +2102 }; +2103 +2104 /** +2105 NoImmunzation as defined by value set 2.16.840.1.113883.1.11.19717 +2106 The terms come from Health Level Seven (HL7) Version 3.0 Vocabulary and are managed by HL7 +2107 It indicates the reason an immunization was not administered. +2108 @returns {hQuery.NoImmunization} Used to indicate reason an immunization was not administered. +2109 */ +2110 +2111 +2112 Immunization.prototype.refusalReason = function() { +2113 return new hQuery.NoImmunization(this.json['negationReason']['code'], this.json['negationReason']['codeSystem']); +2114 }; +2115 +2116 return Immunization; +2117 +2118 })(hQuery.CodedEntry); +2119 /** +2120 @namespace scoping into the hquery namespace +2121 */ +2122 +2123 var __hasProp = {}.hasOwnProperty, +2124 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; +2125 +2126 this.hQuery || (this.hQuery = {}); +2127 +2128 /** +2129 @class +2130 @augments hQuery.CodedEntry +2131 @exports Allergy as hQuery.Allergy +2132 */ +2133 +2134 +2135 hQuery.Allergy = (function(_super) { +2136 __extends(Allergy, _super); +2137 +2138 function Allergy(json) { +2139 this.json = json; +2140 Allergy.__super__.constructor.call(this, this.json); +2141 } +2142 +2143 /** +2144 Food and substance allergies use the Unique Ingredient Identifier(UNII) from the FDA +2145 http://www.fda.gov/ForIndustry/DataStandards/StructuredProductLabeling/ucm162523.htm +2146 +2147 Allegies to a class of medication Shall contain a value descending from the NDF-RT concept types +2148 of Mechanism of Action - N0000000223, Physiologic Effect - N0000009802 or +2149 Chemical Structure - N0000000002. NUI will be used as the concept code. +2150 For more information, please see the Web Site +2151 http://www.cancer.gov/cancertopics/terminologyresources/page5 +2152 +2153 Allergies to a specific medication shall use RxNorm for the values. +2154 @returns {CodedValue} +2155 */ +2156 +2157 +2158 Allergy.prototype.product = function() { +2159 return this.type(); +2160 }; +2161 +2162 /** +2163 Date of allergy or adverse event +2164 @returns{Date} +2165 */ +2166 +2167 +2168 Allergy.prototype.adverseEventDate = function() { +2169 return dateFromUtcSeconds(this.json['adverseEventDate']); +2170 }; +2171 +2172 /** +2173 Adverse event types SHALL be coded as specified in HITSP/C80 Section 2.2.3.4.2 Allergy/Adverse Event Type +2174 @returns {CodedValue} +2175 */ +2176 +2177 +2178 Allergy.prototype.adverseEventType = function() { +2179 return new hQuery.CodedValue(this.json['type']['code'], this.json['type']['codeSystem']); +2180 }; +2181 +2182 /** +2183 This indicates the reaction that may be caused by the product or agent. +2184 It is defined by 2.16.840.1.113883.3.88.12.3221.6.2 and are SNOMED-CT codes. +2185 420134006 Propensity to adverse reactions (disorder) +2186 418038007 Propensity to adverse reactions to substance (disorder) +2187 419511003 Propensity to adverse reactions to drug (disorder) +2188 418471000 Propensity to adverse reactions to food (disorder) +2189 419199007 Allergy to substance (disorder) +2190 416098002 Drug allergy (disorder) +2191 414285001 Food allergy (disorder) +2192 59037007 Drug intolerance (disorder) +2193 235719002 Food intolerance (disorder) +2194 @returns {CodedValue} +2195 */ +2196 +2197 +2198 Allergy.prototype.reaction = function() { +2199 return new hQuery.CodedValue(this.json['reaction']['code'], this.json['reaction']['codeSystem']); +2200 }; +2201 +2202 /** +2203 This is a description of the level of the severity of the allergy or intolerance. +2204 Use SNOMED-CT Codes as defined by 2.16.840.1.113883.3.88.12.3221.6.8 +2205 255604002 Mild +2206 371923003 Mild to Moderate +2207 6736007 Moderate +2208 371924009 Moderate to Severe +2209 24484000 Severe +2210 399166001 Fatal +2211 @returns {CodedValue} +2212 */ +2213 +2214 +2215 Allergy.prototype.severity = function() { +2216 return new hQuery.CodedValue(this.json['severity']['code'], this.json['severity']['codeSystem']); +2217 }; +2218 +2219 /** +2220 Additional comment or textual information +2221 @returns {String} +2222 */ +2223 +2224 +2225 Allergy.prototype.comment = function() { +2226 return this.json['comment']; +2227 }; +2228 +2229 return Allergy; +2230 +2231 })(hQuery.CodedEntry); +2232 /** +2233 @namespace scoping into the hquery namespace +2234 */ +2235 this.hQuery || (this.hQuery = {}); +2236 +2237 /** +2238 @class +2239 +2240 @exports Provider as hQuery.Provider +2241 */ +2242 +2243 +2244 hQuery.Provider = (function() { +2245 function Provider(json) { +2246 this.json = json; +2247 } +2248 +2249 /** +2250 @returns {hQuery.Person} +2251 */ +2252 +2253 +2254 Provider.prototype.providerEntity = function() { +2255 return new hQuery.Person(this.json['providerEntity']); +2256 }; +2257 +2258 /** +2259 @returns {hQuery.DateRange} +2260 */ +2261 +2262 +2263 Provider.prototype.careProvisionDateRange = function() { +2264 return new hQuery.DateRange(this.json['careProvisionDateRange']); +2265 }; +2266 +2267 /** +2268 @returns {hQuery.CodedValue} +2269 */ +2270 +2271 +2272 Provider.prototype.role = function() { +2273 return new hQuery.CodedValue(this.json['role']['code'], this.json['role']['codeSystem']); +2274 }; +2275 +2276 /** +2277 @returns {String} +2278 */ +2279 +2280 +2281 Provider.prototype.patientID = function() { +2282 return this.json['patientID']; +2283 }; +2284 +2285 /** +2286 @returns {hQuery.CodedValue} +2287 */ +2288 +2289 +2290 Provider.prototype.providerType = function() { +2291 return new hQuery.CodedValue(this.json['providerType']['code'], this.json['providerType']['codeSystem']); +2292 }; +2293 +2294 /** +2295 @returns {String} +2296 */ +2297 +2298 +2299 Provider.prototype.providerID = function() { +2300 return this.json['providerID']; +2301 }; +2302 +2303 /** +2304 @returns {hQuery.Organization} +2305 */ +2306 +2307 +2308 Provider.prototype.organizationName = function() { +2309 return new hQuery.Organization(this.json); +2310 }; +2311 +2312 return Provider; +2313 +2314 })(); +2315 /** +2316 @namespace scoping into the hquery namespace +2317 */ +2318 +2319 var __hasProp = {}.hasOwnProperty, +2320 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; +2321 +2322 this.hQuery || (this.hQuery = {}); +2323 +2324 /** +2325 @class +2326 @augments hQuery.CodedEntry +2327 @exports Language as hQuery.Language +2328 */ +2329 +2330 +2331 hQuery.Language = (function(_super) { +2332 __extends(Language, _super); +2333 +2334 function Language(json) { +2335 this.json = json; +2336 Language.__super__.constructor.call(this, this.json); +2337 } +2338 +2339 /** +2340 @returns {hQuery.CodedValue} +2341 */ +2342 +2343 +2344 Language.prototype.modeCode = function() { +2345 return new hQuery.CodedValue(this.json['modeCode']['code'], this.json['modeCode']['codeSystem']); +2346 }; +2347 +2348 /** +2349 @returns {String} +2350 */ +2351 +2352 +2353 Language.prototype.preferenceIndicator = function() { +2354 return this.json['preferenceIndicator']; +2355 }; +2356 +2357 return Language; +2358 +2359 })(hQuery.CodedEntry); +2360 /** +2361 @namespace scoping into the hquery namespace +2362 */ +2363 +2364 var __hasProp = {}.hasOwnProperty, +2365 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; +2366 +2367 this.hQuery || (this.hQuery = {}); +2368 +2369 /** +2370 This includes information about the patients current and past pregnancy status +2371 The Coded Entry code system should be SNOMED-CT +2372 @class +2373 @augments hQuery.CodedEntry +2374 @exports Pregnancy as hQuery.Pregnancy +2375 */ +2376 +2377 +2378 hQuery.Pregnancy = (function(_super) { +2379 __extends(Pregnancy, _super); +2380 +2381 function Pregnancy(json) { +2382 this.json = json; +2383 Pregnancy.__super__.constructor.call(this, this.json); +2384 } +2385 +2386 /** +2387 @returns {String} +2388 */ +2389 +2390 +2391 Pregnancy.prototype.comment = function() { +2392 return this.json['comment']; +2393 }; +2394 +2395 return Pregnancy; +2396 +2397 })(hQuery.CodedEntry); +2398 /** +2399 @namespace scoping into the hquery namespace +2400 */ +2401 +2402 var __hasProp = {}.hasOwnProperty, +2403 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; +2404 +2405 this.hQuery || (this.hQuery = {}); +2406 +2407 /** +2408 +2409 The Social History Observation is used to define the patient's occupational, personal (e.g. lifestyle), +2410 social, and environmental history and health risk factors, as well as administrative data such as +2411 marital status, race, ethnicity and religious affiliation. The types of conditions +2412 described have been constrained to the SNOMED CT code system using constrained code set, 2.16.840.1.113883.3.88.12.80.60: +2413 229819007 Tobacco use and exposure +2414 256235009 Exercise +2415 160573003 Alcohol Intake +2416 364393001 Nutritional observable +2417 364703007 Employment detail +2418 425400000 Toxic exposure status +2419 363908000 Details of drug misuse behavior +2420 228272008 Health-related behavior +2421 105421008 Educational achievement +2422 +2423 note: Social History is not part of the existing green c32. +2424 @exports Socialhistory as hQuery.Socialhistory +2425 @augments hQuery.CodedEntry +2426 */ +2427 +2428 +2429 hQuery.Socialhistory = (function(_super) { +2430 __extends(Socialhistory, _super); +2431 +2432 function Socialhistory(json) { +2433 this.json = json; +2434 Socialhistory.__super__.constructor.call(this, this.json); +2435 } +2436 +2437 /** +2438 Value returns the value of the result. This will return an object. The properties of this +2439 object are dependent on the type of result. +2440 */ +2441 +2442 +2443 Socialhistory.prototype.value = function() { +2444 return this.json['value']; +2445 }; +2446 +2447 return Socialhistory; +2448 +2449 })(hQuery.CodedEntry); +2450 /** +2451 @namespace scoping into the hquery namespace +2452 */ +2453 +2454 var __hasProp = {}.hasOwnProperty, +2455 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; +2456 +2457 this.hQuery || (this.hQuery = {}); +2458 +2459 /** +2460 +2461 The plan of care contains data defining prospective or intended orders, interventions, encounters, services, and procedures for the patient. +2462 +2463 @exports CareGoal as hQuery.CareGoal +2464 @augments hQuery.CodedEntry +2465 */ +2466 +2467 +2468 hQuery.CareGoal = (function(_super) { +2469 __extends(CareGoal, _super); +2470 +2471 function CareGoal(json) { +2472 this.json = json; +2473 CareGoal.__super__.constructor.call(this, this.json); +2474 } +2475 +2476 return CareGoal; +2477 +2478 })(hQuery.CodedEntry); +2479 /** +2480 @namespace scoping into the hquery namespace +2481 */ +2482 +2483 var __hasProp = {}.hasOwnProperty, +2484 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; +2485 +2486 this.hQuery || (this.hQuery = {}); +2487 +2488 /** +2489 +2490 The Medical Equipment section contains information describing a patients implanted and external medical devices and equipment that their health status depends on, as well as any pertinent equipment or device history. +2491 +2492 The template identifier for this section is 2.16.840.1.113883.3.88.11.83.128 +2493 +2494 C83-[CT-128-1] This section shall conform to the HL7 CCD section, and shall contain a templateId element whose root attribute is 2.16.840.1.113883.10.20.1.7. +2495 C83-[CT-128-2] This section SHALL conform to the IHE Medical Devices Section, and shall contain a templateId element whose root attribute is 1.3.6.1.4.1.19376.1.5.3.1.1.5.3.5 +2496 +2497 @exports MedicalEquipment as hQuery.MedicalEquipment +2498 @augments hQuery.CodedEntry +2499 */ +2500 +2501 +2502 hQuery.MedicalEquipment = (function(_super) { +2503 __extends(MedicalEquipment, _super); +2504 +2505 function MedicalEquipment(json) { +2506 this.json = json; +2507 MedicalEquipment.__super__.constructor.call(this, this.json); +2508 } +2509 +2510 return MedicalEquipment; +2511 +2512 })(hQuery.CodedEntry); +2513 /** +2514 @namespace scoping into the hquery namespace +2515 */ +2516 +2517 var __hasProp = {}.hasOwnProperty, +2518 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; +2519 +2520 this.hQuery || (this.hQuery = {}); +2521 +2522 /** +2523 This class can be used to represnt a functional status for a patient. Currently, +2524 it is not a very close representation of functional status as it is represented +2525 in the HL7 CCD, HITSP C32 or Consolidated CDA. +2526 +2527 In the previously mentioned specifications, functional status may represented +2528 using either a condition or result. Having "mixed" types of entries in a section +2529 is currently not well supported in the existing Record class +2530 +2531 Additionally, there is a mismatch between the data needed to calculate Stage 2 +2532 Meaningful Use Quailty Measures and the data contained in patient summary +2533 standards. The CQMs are checking to see if a functional status represented by +2534 a result was patient supplied. Right now, results do not have a source, and +2535 even if we were to use Provider as a source, it would need to be extended +2536 to support patients. +2537 +2538 To avoid this, the patient sumamry style functional status has been "flattened" +2539 into this class. This model supports the information needed to calculate +2540 Stage 2 MU CQMs. If importers are created from C32 or CCDA, the information +2541 can be stored here, but it will be a lossy transformation. +2542 @class +2543 @augments hQuery.CodedEntry +2544 @exports FunctionalStatus as hQuery.FunctionalStatus +2545 */ +2546 +2547 +2548 hQuery.FunctionalStatus = (function(_super) { +2549 __extends(FunctionalStatus, _super); +2550 +2551 function FunctionalStatus(json) { +2552 this.json = json; +2553 FunctionalStatus.__super__.constructor.call(this, this.json); +2554 } +2555 +2556 /** +2557 Either "condition" or "result" +2558 @returns {String} +2559 */ +2560 +2561 +2562 FunctionalStatus.prototype.type = function() { +2563 return this.json["type"]; +2564 }; +2565 +2566 /** +2567 A coded value. Like a code for patient supplied. +2568 @returns {hQuery.CodedValue} +2569 */ +2570 +2571 +2572 FunctionalStatus.prototype.source = function() { +2573 if (this.json["source"] != null) { +2574 return new hQuery.CodedValue(this.json["source"]["code"], this.json["source"]["codeSystem"]); +2575 } +2576 }; +2577 +2578 return FunctionalStatus; +2579 +2580 })(hQuery.CodedEntry); +2581 /** +2582 @namespace scoping into the hquery namespace +2583 */ +2584 +2585 var _ref, +2586 __hasProp = {}.hasOwnProperty, +2587 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; +2588 +2589 this.hQuery || (this.hQuery = {}); +2590 +2591 /** +2592 @class Supports +2593 @exports Supports as hQuery.Supports +2594 */ +2595 +2596 +2597 hQuery.Supports = (function() { +2598 function Supports(json) { +2599 this.json = json; +2600 } +2601 +2602 /** +2603 @returns {DateRange} +2604 */ +2605 +2606 +2607 Supports.prototype.supportDate = function() { +2608 return new hQuery.DateRange(this.json['supportDate']); +2609 }; +2610 +2611 /** +2612 @returns {Person} +2613 */ +2614 +2615 +2616 Supports.prototype.guardian = function() { +2617 return new hQuery.Person(this.json['guardian']); +2618 }; +2619 +2620 /** +2621 @returns {String} +2622 */ +2623 +2624 +2625 Supports.prototype.guardianSupportType = function() { +2626 return this.json['guardianSupportType']; +2627 }; +2628 +2629 /** +2630 @returns {Person} +2631 */ +2632 +2633 +2634 Supports.prototype.contact = function() { +2635 return new hQuery.Person(this.json['contact']); +2636 }; +2637 +2638 /** +2639 @returns {String} +2640 */ +2641 +2642 +2643 Supports.prototype.contactSupportType = function() { +2644 return this.json['guardianSupportType']; +2645 }; +2646 +2647 return Supports; +2648 +2649 })(); +2650 +2651 /** +2652 @class Representation of a patient +2653 @augments hQuery.Person +2654 @exports Patient as hQuery.Patient +2655 */ +2656 +2657 +2658 hQuery.Patient = (function(_super) { +2659 __extends(Patient, _super); +2660 +2661 function Patient() { +2662 _ref = Patient.__super__.constructor.apply(this, arguments); +2663 return _ref; +2664 } +2665 +2666 /** +2667 @returns {String} containing M or F representing the gender of the patient +2668 */ +2669 +2670 +2671 Patient.prototype.gender = function() { +2672 return this.json['gender']; +2673 }; +2674 +2675 /** +2676 @returns {Date} containing the patient's birthdate +2677 */ +2678 +2679 +2680 Patient.prototype.birthtime = function() { +2681 return hQuery.dateFromUtcSeconds(this.json['birthdate']); +2682 }; +2683 +2684 /** +2685 @param (Date) date the date at which the patient age is calculated, defaults to now. +2686 @returns {number} the patient age in years +2687 */ +2688 +2689 +2690 Patient.prototype.age = function(date) { +2691 var oneDay, oneYear; +2692 +2693 if (date == null) { +2694 date = new Date(); +2695 } +2696 oneDay = 24 * 60 * 60 * 1000; +2697 oneYear = 365 * oneDay; +2698 return (date.getTime() - this.birthtime().getTime()) / oneYear; +2699 }; +2700 +2701 /** +2702 @returns {CodedValue} the domestic partnership status of the patient +2703 The following HL7 codeset is used: +2704 A Annulled +2705 D Divorced +2706 I Interlocutory +2707 L Legally separated +2708 M Married +2709 P Polygamous +2710 S Never Married +2711 T Domestic Partner +2712 W Widowed +2713 */ +2714 +2715 +2716 Patient.prototype.maritalStatus = function() { +2717 if (this.json['maritalStatus']) { +2718 return new hQuery.CodedValue(this.json['maritalStatus']['code'], this.json['maritalStatus']['codeSystem']); +2719 } +2720 }; +2721 +2722 /** +2723 @returns {CodedValue} of the spiritual faith affiliation of the patient +2724 It uses the HL7 codeset. http://www.hl7.org/memonly/downloads/v3edition.cfm#V32008 +2725 */ +2726 +2727 +2728 Patient.prototype.religiousAffiliation = function() { +2729 if (this.json['religiousAffiliation']) { +2730 return new hQuery.CodedValue(this.json['religiousAffiliation']['code'], this.json['religiousAffiliation']['codeSystem']); +2731 } +2732 }; +2733 +2734 /** +2735 @returns {CodedValue} of the race of the patient +2736 CDC codes: http://phinvads.cdc.gov/vads/ViewCodeSystemConcept.action?oid=2.16.840.1.113883.6.238&code=1000-9 +2737 */ +2738 +2739 +2740 Patient.prototype.race = function() { +2741 if (this.json['race']) { +2742 return new hQuery.CodedValue(this.json['race']['code'], this.json['race']['codeSystem']); +2743 } +2744 }; +2745 +2746 /** +2747 @returns {CodedValue} of the ethnicity of the patient +2748 CDC codes: http://phinvads.cdc.gov/vads/ViewCodeSystemConcept.action?oid=2.16.840.1.113883.6.238&code=1000-9 +2749 */ +2750 +2751 +2752 Patient.prototype.ethnicity = function() { +2753 if (this.json['ethnicity']) { +2754 return new hQuery.CodedValue(this.json['ethnicity']['code'], this.json['ethnicity']['codeSystem']); +2755 } +2756 }; +2757 +2758 /** +2759 @returns {CodedValue} This is the code specifying the level of confidentiality of the document. +2760 HL7 Confidentiality Code (2.16.840.1.113883.5.25) +2761 */ +2762 +2763 +2764 Patient.prototype.confidentiality = function() { +2765 if (this.json['confidentiality']) { +2766 return new hQuery.CodedValue(this.json['confidentiality']['code'], this.json['confidentiality']['codeSystem']); +2767 } +2768 }; +2769 +2770 /** +2771 @returns {Address} of the location where the patient was born +2772 */ +2773 +2774 +2775 Patient.prototype.birthPlace = function() { +2776 return new hQuery.Address(this.json['birthPlace']); +2777 }; +2778 +2779 /** +2780 @returns {Supports} information regarding key support contacts relative to healthcare decisions, including next of kin +2781 */ +2782 +2783 +2784 Patient.prototype.supports = function() { +2785 return new hQuery.Supports(this.json['supports']); +2786 }; +2787 +2788 /** +2789 @returns {Organization} +2790 */ +2791 +2792 +2793 Patient.prototype.custodian = function() { +2794 return new hQuery.Organization(this.json['custodian']); +2795 }; +2796 +2797 /** +2798 @returns {Provider} the providers associated with the patient +2799 */ +2800 +2801 +2802 Patient.prototype.provider = function() { +2803 return new hQuery.Provider(this.json['provider']); +2804 }; +2805 +2806 /** +2807 @returns {hQuery.CodedEntryList} A list of {@link hQuery.LanguagesSpoken} objects +2808 Code from http://www.ietf.org/rfc/rfc4646.txt representing the name of the human language +2809 */ +2810 +2811 +2812 Patient.prototype.languages = function() { +2813 var language, list, _i, _len, _ref1; +2814 +2815 list = new hQuery.CodedEntryList; +2816 if (this.json['languages']) { +2817 _ref1 = this.json['languages']; +2818 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +2819 language = _ref1[_i]; +2820 list.push(new hQuery.Language(language)); +2821 } +2822 } +2823 return list; +2824 }; +2825 +2826 /** +2827 @returns {Boolean} returns true if the patient has died +2828 */ +2829 +2830 +2831 Patient.prototype.expired = function() { +2832 return this.json['expired']; +2833 }; +2834 +2835 /** +2836 @returns {Boolean} returns true if the patient participated in a clinical trial +2837 */ +2838 +2839 +2840 Patient.prototype.clinicalTrialParticipant = function() { +2841 return this.json['clinicalTrialParticipant']; +2842 }; +2843 +2844 /** +2845 @returns {hQuery.CodedEntryList} A list of {@link hQuery.Encounter} objects +2846 */ +2847 +2848 +2849 Patient.prototype.encounters = function() { +2850 var encounter, list, _i, _len, _ref1; +2851 +2852 list = new hQuery.CodedEntryList; +2853 if (this.json['encounters']) { +2854 _ref1 = this.json['encounters']; +2855 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +2856 encounter = _ref1[_i]; +2857 list.pushIfUsable(new hQuery.Encounter(encounter)); +2858 } +2859 } +2860 return list; +2861 }; +2862 +2863 /** +2864 @returns {hQuery.CodedEntryList} A list of {@link Medication} objects +2865 */ +2866 +2867 +2868 Patient.prototype.medications = function() { +2869 var list, medication, _i, _len, _ref1; +2870 +2871 list = new hQuery.CodedEntryList; +2872 if (this.json['medications']) { +2873 _ref1 = this.json['medications']; +2874 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +2875 medication = _ref1[_i]; +2876 list.pushIfUsable(new hQuery.Medication(medication)); +2877 } +2878 } +2879 return list; +2880 }; +2881 +2882 /** +2883 @returns {hQuery.CodedEntryList} A list of {@link Condition} objects +2884 */ +2885 +2886 +2887 Patient.prototype.conditions = function() { +2888 var condition, list, _i, _len, _ref1; +2889 +2890 list = new hQuery.CodedEntryList; +2891 if (this.json['conditions']) { +2892 _ref1 = this.json['conditions']; +2893 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +2894 condition = _ref1[_i]; +2895 list.pushIfUsable(new hQuery.Condition(condition)); +2896 } +2897 } +2898 return list; +2899 }; +2900 +2901 /** +2902 @returns {hQuery.CodedEntryList} A list of {@link Procedure} objects +2903 */ +2904 +2905 +2906 Patient.prototype.procedures = function() { +2907 var list, procedure, _i, _len, _ref1; +2908 +2909 list = new hQuery.CodedEntryList; +2910 if (this.json['procedures']) { +2911 _ref1 = this.json['procedures']; +2912 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +2913 procedure = _ref1[_i]; +2914 list.pushIfUsable(new hQuery.Procedure(procedure)); +2915 } +2916 } +2917 return list; +2918 }; +2919 +2920 /** +2921 @returns {hQuery.CodedEntryList} A list of {@link Result} objects +2922 */ +2923 +2924 +2925 Patient.prototype.results = function() { +2926 var list, result, _i, _len, _ref1; +2927 +2928 list = new hQuery.CodedEntryList; +2929 if (this.json['results']) { +2930 _ref1 = this.json['results']; +2931 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +2932 result = _ref1[_i]; +2933 list.pushIfUsable(new hQuery.Result(result)); +2934 } +2935 } +2936 return list; +2937 }; +2938 +2939 /** +2940 @returns {hQuery.CodedEntryList} A list of {@link Result} objects +2941 */ +2942 +2943 +2944 Patient.prototype.vitalSigns = function() { +2945 var list, vital, _i, _len, _ref1; +2946 +2947 list = new hQuery.CodedEntryList; +2948 if (this.json['vital_signs']) { +2949 _ref1 = this.json['vital_signs']; +2950 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +2951 vital = _ref1[_i]; +2952 list.pushIfUsable(new hQuery.Result(vital)); +2953 } +2954 } +2955 return list; +2956 }; +2957 +2958 /** +2959 @returns {hQuery.CodedEntryList} A list of {@link Immunization} objects +2960 */ +2961 +2962 +2963 Patient.prototype.immunizations = function() { +2964 var immunization, list, _i, _len, _ref1; +2965 +2966 list = new hQuery.CodedEntryList; +2967 if (this.json['immunizations']) { +2968 _ref1 = this.json['immunizations']; +2969 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +2970 immunization = _ref1[_i]; +2971 list.pushIfUsable(new hQuery.Immunization(immunization)); +2972 } +2973 } +2974 return list; +2975 }; +2976 +2977 /** +2978 @returns {hQuery.CodedEntryList} A list of {@link Allergy} objects +2979 */ +2980 +2981 +2982 Patient.prototype.allergies = function() { +2983 var allergy, list, _i, _len, _ref1; +2984 +2985 list = new hQuery.CodedEntryList; +2986 if (this.json['allergies']) { +2987 _ref1 = this.json['allergies']; +2988 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +2989 allergy = _ref1[_i]; +2990 list.pushIfUsable(new hQuery.Allergy(allergy)); +2991 } +2992 } +2993 return list; +2994 }; +2995 +2996 /** +2997 @returns {hQuery.CodedEntryList} A list of {@link Pregnancy} objects +2998 */ +2999 +3000 +3001 Patient.prototype.pregnancies = function() { +3002 var list, pregnancy, _i, _len, _ref1; +3003 +3004 list = new hQuery.CodedEntryList; +3005 if (this.json['pregnancies']) { +3006 _ref1 = this.json['pregnancies']; +3007 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +3008 pregnancy = _ref1[_i]; +3009 list.pushIfUsable(new hQuery.Pregnancy(pregnancy)); +3010 } +3011 } +3012 return list; +3013 }; +3014 +3015 /** +3016 @returns {hQuery.CodedEntryList} A list of {@link Socialhistory} objects +3017 */ +3018 +3019 +3020 Patient.prototype.socialHistories = function() { +3021 var list, socialhistory, _i, _len, _ref1; +3022 +3023 list = new hQuery.CodedEntryList; +3024 if (this.json['socialhistories']) { +3025 _ref1 = this.json['socialhistories']; +3026 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +3027 socialhistory = _ref1[_i]; +3028 list.pushIfUsable(new hQuery.Socialhistory(socialhistory)); +3029 } +3030 } +3031 return list; +3032 }; +3033 +3034 /** +3035 @returns {hQuery.CodedEntryList} A list of {@link CareGoal} objects +3036 */ +3037 +3038 +3039 Patient.prototype.careGoals = function() { +3040 var caregoal, list, _i, _len, _ref1; +3041 +3042 list = new hQuery.CodedEntryList; +3043 if (this.json['care_goals']) { +3044 _ref1 = this.json['care_goals']; +3045 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +3046 caregoal = _ref1[_i]; +3047 list.pushIfUsable(new hQuery.CareGoal(caregoal)); +3048 } +3049 } +3050 return list; +3051 }; +3052 +3053 /** +3054 @returns {hQuery.CodedEntryList} A list of {@link MedicalEquipment} objects +3055 */ +3056 +3057 +3058 Patient.prototype.medicalEquipment = function() { +3059 var equipment, list, _i, _len, _ref1; +3060 +3061 list = new hQuery.CodedEntryList; +3062 if (this.json['medical_equipment']) { +3063 _ref1 = this.json['medical_equipment']; +3064 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +3065 equipment = _ref1[_i]; +3066 list.pushIfUsable(new hQuery.MedicalEquipment(equipment)); +3067 } +3068 } +3069 return list; +3070 }; +3071 +3072 /** +3073 @returns {hQuery.CodedEntryList} A list of {@link FunctionalStatus} objects +3074 */ +3075 +3076 +3077 Patient.prototype.functionalStatuses = function() { +3078 var fs, list, _i, _len, _ref1; +3079 +3080 list = new hQuery.CodedEntryList; +3081 if (this.json['functional_statuses']) { +3082 _ref1 = this.json['functional_statuses']; +3083 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +3084 fs = _ref1[_i]; +3085 list.pushIfUsable(new hQuery.FunctionalStatus(fs)); +3086 } +3087 } +3088 return list; +3089 }; +3090 +3091 return Patient; +3092 +3093 })(hQuery.Person); +3094 \ No newline at end of file From 8a1832826aa69c2888459f43e92514e4ddc1076f Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Thu, 13 Jun 2013 12:23:43 -0700 Subject: [PATCH 002/117] Pull patientapi from our fork --- .gitignore | 3 ++- Gemfile | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 226fa9a..fe004b4 100755 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ coverage/ public/assets spec/javascripts/generated/* log/ -spec/generated \ No newline at end of file +spec/generated +.idea diff --git a/Gemfile b/Gemfile index 9a0e18a..6c4337e 100755 --- a/Gemfile +++ b/Gemfile @@ -22,7 +22,7 @@ gem 'simple_form' gem 'multipart-post' gem 'delayed_job' gem 'delayed_job_mongoid', :git => 'https://github.com/collectiveidea/delayed_job_mongoid.git' -gem 'hquery-patient-api', :git => 'http://github.com/hquery/patientapi.git', :tag => 'V0.2' +gem 'hquery-patient-api', :git => 'http://github.com/scoophealth/patientapi.git', :tag => 'V0.2' gem 'devise' gem 'cancan' gem 'pry' From c65494903bf92e84e80fbc6dffccc938ff2b9d1a Mon Sep 17 00:00:00 2001 From: Jeremy Ho Date: Wed, 19 Jun 2013 13:31:06 -0700 Subject: [PATCH 003/117] Redirect quality-measure-engine to scoophealth fork Signed-off-by: Jeremy Ho --- .gitignore | 1 + Gemfile | 2 +- Gemfile.lock | 308 --------------------------------------------------- 3 files changed, 2 insertions(+), 309 deletions(-) delete mode 100644 Gemfile.lock diff --git a/.gitignore b/.gitignore index fe004b4..bf27f63 100755 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,5 @@ public/assets spec/javascripts/generated/* log/ spec/generated +Gemfile.lock .idea diff --git a/Gemfile b/Gemfile index 6c4337e..ba8eca8 100755 --- a/Gemfile +++ b/Gemfile @@ -30,7 +30,7 @@ gem 'kramdown' gem 'jasmine', :group => [:development, :test] gem 'headless', :group => [:development, :test] gem 'coderay' -gem 'quality-measure-engine', :git => 'http://github.com/pophealth/quality-measure-engine.git', :branch => 'develop' +gem 'quality-measure-engine', :git => 'http://github.com/scoophealth/quality-measure-engine.git', :branch => 'develop' diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index fb4bac3..0000000 --- a/Gemfile.lock +++ /dev/null @@ -1,308 +0,0 @@ -GIT - remote: http://github.com/hquery/patientapi.git - revision: e26c6c7e0679987f2afbb5e4a7693fd025c0d61f - tag: V0.2 - specs: - hquery-patient-api (0.1.0) - -GIT - remote: http://github.com/pophealth/quality-measure-engine.git - revision: 6573859d0d8ca8d76e6dc2f0d4d15181c8457c61 - branch: develop - specs: - quality-measure-engine (1.0.4) - mongo (~> 1.3) - nokogiri (~> 1.4.4) - resque (~> 1.15.0) - resque-status (~> 0.2.3) - rubyzip (~> 0.9.4) - -GIT - remote: https://github.com/collectiveidea/delayed_job_mongoid.git - revision: c8816d7eecb3e2ba61b878d45b90625a63cbc0d4 - specs: - delayed_job_mongoid (1.0.7) - delayed_job (~> 3.0.0.pre) - mongoid (>= 2.0) - -GEM - remote: http://rubygems.org/ - specs: - actionmailer (3.1.3) - actionpack (= 3.1.3) - mail (~> 2.3.0) - actionpack (3.1.3) - activemodel (= 3.1.3) - activesupport (= 3.1.3) - builder (~> 3.0.0) - erubis (~> 2.7.0) - i18n (~> 0.6) - rack (~> 1.3.5) - rack-cache (~> 1.1) - rack-mount (~> 0.8.2) - rack-test (~> 0.6.1) - sprockets (~> 2.0.3) - activemodel (3.1.3) - activesupport (= 3.1.3) - builder (~> 3.0.0) - i18n (~> 0.6) - activerecord (3.1.3) - activemodel (= 3.1.3) - activesupport (= 3.1.3) - arel (~> 2.2.1) - tzinfo (~> 0.3.29) - activeresource (3.1.3) - activemodel (= 3.1.3) - activesupport (= 3.1.3) - activesupport (3.1.3) - multi_json (~> 1.0) - ansi (1.4.1) - arel (2.2.1) - bcrypt-ruby (3.0.1) - bcrypt-ruby (3.0.1-java) - bcrypt-ruby (3.0.1-x86-mingw32) - bson (1.5.2) - bson (1.5.2-java) - bson_ext (1.5.2) - bson (= 1.5.2) - builder (3.0.0) - cancan (1.6.7) - childprocess (0.2.3) - ffi (~> 1.0.6) - coderay (1.0.4) - coffee-rails (3.1.1) - coffee-script (>= 2.2.0) - railties (~> 3.1.0) - coffee-script (2.2.0) - coffee-script-source - execjs - coffee-script-source (1.1.3) - configatron (2.9.0) - yamler (>= 0.1.0) - cover_me (1.2.0) - configatron - hashie - daemons (1.0.10) - delayed_job (3.0.0.pre4) - activesupport (~> 3.0) - daemons (= 1.0.10) - devise (1.5.2) - bcrypt-ruby (~> 3.0) - orm_adapter (~> 0.0.3) - warden (~> 1.1) - diff-lcs (1.1.3) - erubis (2.7.0) - execjs (1.2.12) - multi_json (~> 1.0) - factory_girl (2.3.2) - activesupport - fakeweb (1.3.0) - ffi (1.0.11) - ffi (1.0.11-java) - hashie (1.2.0) - headless (0.2.2) - hike (1.2.1) - i18n (0.6.0) - jasmine (1.1.2) - jasmine-core (>= 1.1.0) - rack (>= 1.1) - rspec (>= 1.3.1) - selenium-webdriver (>= 0.1.3) - jasmine-core (1.1.0) - jquery-rails (1.0.19) - railties (~> 3.0) - thor (~> 0.14) - json (1.4.6) - json (1.4.6-java) - kramdown (0.13.3) - libv8 (3.3.10.4) - macaddr (1.5.0) - systemu (>= 2.4.0) - mail (2.3.0) - i18n (>= 0.4.0) - mime-types (~> 1.16) - treetop (~> 1.4.8) - metaclass (0.0.1) - method_source (0.6.7) - ruby_parser (>= 2.3.1) - mime-types (1.17.2) - minitest (2.9.1) - mocha (0.10.0) - metaclass (~> 0.0.1) - mongo (1.5.2) - bson (= 1.5.2) - mongoid (2.3.4) - activemodel (~> 3.1) - mongo (~> 1.3) - tzinfo (~> 0.3.22) - mongoid_rails_migrations (0.0.14) - activesupport (>= 3.0.0) - bundler (>= 1.0.0) - rails (>= 3.0.0) - railties (>= 3.0.0) - multi_json (1.0.4) - multipart-post (1.1.4) - nokogiri (1.4.7) - nokogiri (1.4.7-java) - weakling (>= 0.0.3) - nokogiri (1.4.7-x86-mingw32) - orm_adapter (0.0.5) - polyglot (0.3.3) - pry (0.9.6) - coderay (>= 0.9.8) - method_source (>= 0.6.5) - ruby_parser (>= 2.0.5) - slop (~> 2.1.0) - pry (0.9.6-java) - coderay (>= 0.9.8) - method_source (>= 0.6.5) - ruby_parser (>= 2.0.5) - slop (~> 2.1.0) - spoon (>= 0.0.1) - pry (0.9.6-x86-mingw32) - coderay (>= 0.9.8) - method_source (>= 0.6.5) - ruby_parser (>= 2.0.5) - slop (~> 2.1.0) - win32console (>= 1.3.0) - rack (1.3.5) - rack-cache (1.1) - rack (>= 0.4) - rack-mount (0.8.3) - rack (>= 1.0.0) - rack-protection (1.1.4) - rack - rack-ssl (1.3.2) - rack - rack-test (0.6.1) - rack (>= 1.0) - rails (3.1.3) - actionmailer (= 3.1.3) - actionpack (= 3.1.3) - activerecord (= 3.1.3) - activeresource (= 3.1.3) - activesupport (= 3.1.3) - bundler (~> 1.0) - railties (= 3.1.3) - railties (3.1.3) - actionpack (= 3.1.3) - activesupport (= 3.1.3) - rack-ssl (~> 1.3.2) - rake (>= 0.8.7) - rdoc (~> 3.4) - thor (~> 0.14.6) - rake (0.9.2.2) - rdoc (3.11) - json (~> 1.4) - redis (2.2.2) - redis-namespace (1.1.0) - redis (< 3.0.0) - redisk (0.2.2) - redis (>= 0.1.1) - redis-namespace (>= 0.1.0) - resque (1.15.0) - json (~> 1.4.6) - redis-namespace (>= 0.10.0) - sinatra (>= 0.9.2) - vegas (~> 0.1.2) - resque-status (0.2.4) - redisk (>= 0.2.1) - resque (>= 1.3.1) - uuid (>= 2.0.2) - rspec (2.7.0) - rspec-core (~> 2.7.0) - rspec-expectations (~> 2.7.0) - rspec-mocks (~> 2.7.0) - rspec-core (2.7.1) - rspec-expectations (2.7.0) - diff-lcs (~> 1.1.2) - rspec-mocks (2.7.0) - ruby_parser (2.3.1) - sexp_processor (~> 3.0) - rubyzip (0.9.5) - sass (3.1.11) - sass-rails (3.1.5) - actionpack (~> 3.1.0) - railties (~> 3.1.0) - sass (~> 3.1.10) - tilt (~> 1.3.2) - selenium-webdriver (2.15.0) - childprocess (>= 0.2.1) - ffi (~> 1.0.9) - multi_json (~> 1.0.4) - rubyzip - sexp_processor (3.0.9) - simple_form (1.5.2) - actionpack (~> 3.0) - activemodel (~> 3.0) - sinatra (1.3.1) - rack (~> 1.3, >= 1.3.4) - rack-protection (~> 1.1, >= 1.1.2) - tilt (~> 1.3, >= 1.3.3) - slop (2.1.0) - spoon (0.0.1) - sprockets (2.0.3) - hike (~> 1.2) - rack (~> 1.0) - tilt (~> 1.1, != 1.3.0) - systemu (2.4.2) - therubyracer (0.9.9) - libv8 (~> 3.3.10) - therubyrhino (1.73.0) - thor (0.14.6) - tilt (1.3.3) - treetop (1.4.10) - polyglot - polyglot (>= 0.3.1) - turn (0.8.3) - ansi - tzinfo (0.3.31) - uglifier (1.2.0) - execjs (>= 0.3.0) - multi_json (>= 1.0.2) - uuid (2.3.4) - macaddr (~> 1.0) - vegas (0.1.8) - rack (>= 1.0.0) - warden (1.1.0) - rack (>= 1.0) - weakling (0.0.4-java) - win32console (1.3.0-x86-mingw32) - yamler (0.1.0) - -PLATFORMS - java - ruby - x86-mingw32 - -DEPENDENCIES - bson_ext - cancan - coderay - coffee-rails - cover_me (>= 1.0.0.rc6) - delayed_job - delayed_job_mongoid! - devise - factory_girl - fakeweb - headless - hquery-patient-api! - jasmine - jquery-rails - kramdown - minitest - mocha - mongoid - mongoid_rails_migrations - multipart-post - pry - quality-measure-engine! - rails - sass-rails - simple_form - sprockets - therubyracer - therubyrhino - turn - uglifier From a4c0e08cf8e52516c2a6a0437ebb7f69883d569f Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Thu, 20 Jun 2013 12:25:42 -0700 Subject: [PATCH 004/117] Work on unit testing. All tests now run but fail. --- Gemfile | 12 +- app/models/base_query.rb | 2 +- app/models/user.rb | 8 +- config/initializers/devise.rb | 2 +- config/mongoid.yml | 89 ++++++- test/factories/factory.rb | 432 +++++++++++++++++++--------------- test/test_helper.rb | 2 +- test/unit/code_set_test.rb | 8 +- 8 files changed, 343 insertions(+), 212 deletions(-) diff --git a/Gemfile b/Gemfile index ba8eca8..4a775b5 100755 --- a/Gemfile +++ b/Gemfile @@ -1,4 +1,4 @@ -source :rubygems +source "https://rubygems.org" gem 'rails' @@ -16,13 +16,15 @@ end gem 'jquery-rails' gem 'sprockets' gem 'bson_ext', :platforms => :mri +gem 'daemons' +gem 'mongo' gem "mongoid" gem 'mongoid_rails_migrations' gem 'simple_form' gem 'multipart-post' gem 'delayed_job' -gem 'delayed_job_mongoid', :git => 'https://github.com/collectiveidea/delayed_job_mongoid.git' -gem 'hquery-patient-api', :git => 'http://github.com/scoophealth/patientapi.git', :tag => 'V0.2' +gem 'delayed_job_mongoid' #, :git => 'https://github.com/collectiveidea/delayed_job_mongoid.git' +gem 'hquery-patient-api', :git => 'http://github.com/scoophealth/patientapi.git' #, :tag => 'V0.2' gem 'devise' gem 'cancan' gem 'pry' @@ -30,7 +32,7 @@ gem 'kramdown' gem 'jasmine', :group => [:development, :test] gem 'headless', :group => [:development, :test] gem 'coderay' -gem 'quality-measure-engine', :git => 'http://github.com/scoophealth/quality-measure-engine.git', :branch => 'develop' +gem 'quality-measure-engine', :git => 'http://github.com/pophealth/quality-measure-engine.git' #, :branch => 'develop' @@ -41,7 +43,7 @@ group :test do # Pretty printed test output gem 'turn', :require => false gem 'cover_me', '>= 1.0.0.rc6' - gem 'minitest' + gem 'minitest', '< 5.0.0' gem 'fakeweb' gem 'therubyracer', :platforms => :ruby gem 'therubyrhino', :platforms => :jruby diff --git a/app/models/base_query.rb b/app/models/base_query.rb index 4148d75..349e8b2 100644 --- a/app/models/base_query.rb +++ b/app/models/base_query.rb @@ -1,6 +1,6 @@ class BaseQuery include Mongoid::Document - store_in :queries + store_in collection: 'queries' field :title, type: String field :description, type: String diff --git a/app/models/user.rb b/app/models/user.rb index bb38df4..764d22c 100755 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -2,7 +2,11 @@ class User include Mongoid::Document # Include default devise modules. Others available are: # :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable - devise :database_authenticatable, :registerable,:recoverable, :rememberable, :trackable, :validatable,:authentication_keys => [:username] + devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :authentication_keys => [:username] + + # Setup accessible (or protected) attributes for your model + attr_accessible :email, :password, :password_confirmation, :remember_me + # attr_accessible :title, :body has_many :queries has_many :library_functions @@ -13,6 +17,7 @@ class User field :email, type: String field :company, type: String field :company_url, type: String + field :encrypted_password, :type => String, :default => "" field :agree_license, type: Boolean @@ -30,6 +35,7 @@ class User validates :email, presence: true, length: {minimum: 3, maximum: 254}, format: {with: /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i} validates :username, :presence => true, length: {minimum: 3, maximum: 254} + validates_presence_of :encrypted_password def active_for_authentication? super && approved? && !disabled? diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 0a204a4..be10939 100755 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -80,7 +80,7 @@ # If true, uses the password salt as remember token. This should be turned # to false if you are not using database authenticatable. - config.use_salt_as_remember_token = true + # config.use_salt_as_remember_token = true # Options to be passed to the created cookie. For instance, you can set # :secure => true in order to force SSL only cookies. diff --git a/config/mongoid.yml b/config/mongoid.yml index 53ef4bd..35a4d1a 100755 --- a/config/mongoid.yml +++ b/config/mongoid.yml @@ -1,15 +1,80 @@ development: - host: localhost - database: hquery-composer-development + # Configure available database sessions. (required) + sessions: + # Defines the default session. (required) + default: + # Defines the name of the default database that Mongoid can connect to. + # (required). + database: query_composer_development + # Provides the hosts the default session can connect to. Must be an array + # of host:port pairs. (required) + hosts: + - localhost:27017 + options: + # Change whether the session persists in safe mode by default. + # (default: false) + # safe: false + # Change the default consistency model to :eventual or :strong. + # :eventual will send reads to secondaries, :strong sends everything + # to master. (default: :eventual) + # consistency: :eventual + + # How many times Moped should attempt to retry an operation after + # failure. (default: 30) + # max_retries: 30 + + # The time in seconds that Moped should wait before retrying an + # operation on failure. (default: 1) + # retry_interval: 1 + # Configure Mongoid specific options. (optional) + options: + # Configuration for whether or not to allow access to fields that do + # not have a field definition on the model. (default: true) + # allow_dynamic_fields: true + + # Enable the identity map, needed for eager loading. (default: false) + # identity_map_enabled: false + + # Includes the root model name in json serialization. (default: false) + # include_root_in_json: false + + # Include the _type field in serializaion. (default: false) + # include_type_for_serialization: false + + # Preload all models in development, needed when models use + # inheritance. (default: false) + # preload_models: false + + # Protect id and type from mass assignment. (default: true) + # protect_sensitive_fields: true + + # Raise an error when performing a #find and the document is not found. + # (default: true) + # raise_not_found_error: true + + # Raise an error when defining a scope with the same name as an + # existing method. (default: false) + # scope_overwrite_exception: false + + # Skip the database version check, used when connecting to a db without + # admin access. (default: false) + # skip_version_check: false + + # User Active Support's time zone in conversions. (default: true) + # use_activesupport_time_zone: true + + # Ensure all times are UTC in the app side. (default: false) + # use_utc: false test: - host: <%= ENV['TEST_DB_HOST'] || 'localhost' %> - database: hquery-composer-test - -# set these environment variables on your prod server -production: - host: <%= ENV['MONGOID_HOST'] %> - port: <%= ENV['MONGOID_PORT'] %> - username: <%= ENV['MONGOID_USERNAME'] %> - password: <%= ENV['MONGOID_PASSWORD'] %> - database: <%= ENV['MONGOID_DATABASE'] %> \ No newline at end of file + sessions: + default: + database: query_composer_test + hosts: + - localhost:27017 + options: + consistency: :strong + # In the test environment we lower the retries and retry interval to + # low amounts for fast failures. + max_retries: 1 + retry_interval: 0 diff --git a/test/factories/factory.rb b/test/factories/factory.rb index 6ae3399..60d6b3d 100755 --- a/test/factories/factory.rb +++ b/test/factories/factory.rb @@ -3,173 +3,217 @@ # ========== # = USERS = # ========== -Factory.define :user do |u| - u.sequence(:email) { |n| "testuser#{n}@test.com"} - u.password 'password' - u.password_confirmation 'password' - u.first_name 'first' - u.last_name 'last' - u.sequence(:username) { |n| "testuser#{n}"} - u.admin false - u.approved true +FactoryGirl.define do + factory :user do |u| + u.sequence(:email) { |n| "testuser#{n}@test.com"} + u.password 'password' + u.password_confirmation 'password' + u.first_name 'first' + u.last_name 'last' + u.sequence(:username) { |n| "testuser#{n}"} + u.admin false + u.approved true + end end -Factory.define :admin, :parent => :user do |u| - u.admin true +FactoryGirl.define do + factory :admin, :parent => :user do |u| + u.admin true + end end -Factory.define :unapproved_user, :parent => :user do |u| - u.approved false +FactoryGirl.define do + factory :unapproved_user, :parent => :user do |u| + u.approved false + end end -Factory.define :user_with_queries, :parent => :user do |user| - user.after_create { |u| Factory(:query, :user => u) } - user.after_create { |u| Factory(:query, :user => u) } - user.after_create { |u| Factory(:query, :user => u) } - user.after_create { |u| Factory(:query_with_queued_results, :user => u) } - user.after_create { |u| Factory(:query_with_completed_results, :user => u) } - user.after_create { |u| Factory(:generated_query_with_completed_results, :user => u) } +FactoryGirl.define do + factory :user_with_queries, :parent => :user do |user| + user.after_create { |u| FactoryGirl(:query, :user => u) } + user.after_create { |u| FactoryGirl(:query, :user => u) } + user.after_create { |u| FactoryGirl(:query, :user => u) } + user.after_create { |u| FactoryGirl(:query_with_queued_results, :user => u) } + user.after_create { |u| FactoryGirl(:query_with_completed_results, :user => u) } + user.after_create { |u| FactoryGirl(:generated_query_with_completed_results, :user => u) } + end end -Factory.define :user_with_library_functions, :parent => :user do |user| - user.after_create {|u| Factory(:library_function, :user => u)} +FactoryGirl.define do + factory :user_with_library_functions, :parent => :user do |user| + user.after_create {|u| FactoryGirl(:library_function, :user => u)} + end end -Factory.define :user_with_queries_and_library_functions, :parent => :user_with_queries do |user| - user.after_create {|u| Factory(:library_function, :user => u)} +FactoryGirl.define do + factory :user_with_queries_and_library_functions, :parent => :user_with_queries do |user| + user.after_create {|u| FactoryGirl(:library_function, :user => u)} + end end # =========== # = QUERIES = # =========== -Factory.define :template_query do |q| - q.sequence(:title) { |n| "title #{n}" } - q.description "description" - q.filter "" - q.map "function(patient) {\r\n emit(null, {\"count\":1});\r\n}" - q.reduce "function(patient) {\r\n emit(null, {\"count\":1});\r\n}" +FactoryGirl.define do + factory :template_query do |q| + q.sequence(:title) { |n| "title #{n}" } + q.description "description" + q.filter "" + q.map "function(patient) {\r\n emit(null, {\"count\":1});\r\n}" + q.reduce "function(patient) {\r\n emit(null, {\"count\":1});\r\n}" + end end -Factory.define :query do |q| - q.sequence(:title) { |n| "title #{n}" } - q.description "description" - q.filter "" - q.map "function map(patient) {\r\n emit(null, {\"count\":1});\r\n}" - q.reduce "function reduce(patient) {\r\n emit(null, {\"count\":1});\r\n}" - q.user Factory.build(:user) +FactoryGirl.define do + factory :query do |q| + q.sequence(:title) { |n| "title #{n}" } + q.description "description" + q.filter "" + q.map "function map(patient) {\r\n emit(null, {\"count\":1});\r\n}" + q.reduce "function reduce(patient) {\r\n emit(null, {\"count\":1});\r\n}" + q.user FactoryGirl.build(:user) + end end -Factory.define :generated_query, :parent => :query do |q| - q.query_structure ({ - "find" => - { "and" => [ - { "name" => "demographics", - "and" => [ - { "category" => "demographics", "title" => "age", "field" => "age", "value" => "18", "comparator" => ">" } ] } ] }, - "filter" => - { "and" => [ - { "name" => "demographics", - "and" => [ - { "category" => "demographics", "title" => "age", "field" => "age", "value" => "65", "comparator" => "<" } ] } ] }, - "extract" => - { "selections" => [ - { "title" => "age", "callstack" => "age", "aggregation" => [ "sum" ] } ], - "groups" => [ { "title" => "gender", "callstack" => "gender" } ] } - }) - q.generated true - q.user Factory.build(:user) +FactoryGirl.define do + factory :generated_query, :parent => :query do |q| + q.query_structure ({ + "find" => + { "and" => [ + { "name" => "demographics", + "and" => [ + { "category" => "demographics", "title" => "age", "field" => "age", "value" => "18", "comparator" => ">" } ] } ] }, + "filter" => + { "and" => [ + { "name" => "demographics", + "and" => [ + { "category" => "demographics", "title" => "age", "field" => "age", "value" => "65", "comparator" => "<" } ] } ] }, + "extract" => + { "selections" => [ + { "title" => "age", "callstack" => "age", "aggregation" => [ "sum" ] } ], + "groups" => [ { "title" => "gender", "callstack" => "gender" } ] } + }) + q.generated true + q.user FactoryGirl.build(:user) + end end -Factory.define :query_with_queued_results, :parent => :query do |query| - query.reduce "function reduce(key, values) {\r\n var result = 0; \r\n while(values.hasNext()){ result += values.next(); }\r\nreturn result; \r\n}" +FactoryGirl.define do + factory :query_with_queued_results, :parent => :query do |query| + query.reduce "function reduce(key, values) {\r\n var result = 0; \r\n while(values.hasNext()){ result += values.next(); }\r\nreturn result; \r\n}" - query.executions { - [] << Factory.build(:queued_execution) - } + query.executions { + [] << FactoryGirl.build(:queued_execution) + } + end end -Factory.define :query_with_completed_results, :parent => :query do |query| - query.reduce "function reduce(key, values) {\r\n var result = 0; \r\n while(values.hasNext()){ result += values.next(); }\r\nreturn result; \r\n}" +FactoryGirl.define do + factory :query_with_completed_results, :parent => :query do |query| + query.reduce "function reduce(key, values) {\r\n var result = 0; \r\n while(values.hasNext()){ result += values.next(); }\r\nreturn result; \r\n}" - query.executions { - [] << Factory.build(:completed_execution) - } + query.executions { + [] << FactoryGirl.build(:completed_execution) + } + end end -Factory.define :generated_query_with_completed_results, :parent => :generated_query do |query| - query.executions { - [] << Factory.build(:completed_execution_for_generated_query) - } +FactoryGirl.define do + factory :generated_query_with_completed_results, :parent => :generated_query do |query| + query.executions { + [] << FactoryGirl.build(:completed_execution_for_generated_query) + } + end end -Factory.define :generated_query_with_odd_result_count, :parent => :generated_query do |query| - query.executions { - [] << Factory.build(:execution_with_generated_odd_result_count) - } +FactoryGirl.define do + factory :generated_query_with_odd_result_count, :parent => :generated_query do |query| + query.executions { + [] << FactoryGirl.build(:execution_with_generated_odd_result_count) + } + end end -Factory.define :generated_query_with_single_result, :parent => :generated_query do |query| - query.executions { - [] << Factory.build(:execution_with_generated_single_result) - } +FactoryGirl.define do + factory :generated_query_with_single_result, :parent => :generated_query do |query| + query.executions { + [] << FactoryGirl.build(:execution_with_generated_single_result) + } + end end -Factory.define :generated_query_with_no_results, :parent => :generated_query do |query| - query.executions { - [] << Factory.build(:execution) - } +FactoryGirl.define do + factory :generated_query_with_no_results, :parent => :generated_query do |query| + query.executions { + [] << FactoryGirl.build(:execution) + } + end end # ============= # = Endpoints = # ============= -Factory.define :endpoint do |e| - e.sequence(:name) {|n| "Endpoint#{n}"} - e.base_url 'http://127.0.0.1:3001' +FactoryGirl.define do + factory :endpoint do |e| + e.sequence(:name) {|n| "Endpoint#{n}"} + e.base_url 'http://127.0.0.1:3001' + end end # ============== # = Executions = # ============== -Factory.define :execution do |e| - e.time Time.now.to_i +FactoryGirl.define do + factory :execution do |e| + e.time Time.now.to_i + end end -Factory.define :queued_execution, :parent => :execution do |e| - e.after_build do |ex| - Factory.create(:result_waiting, :endpoint => Factory(:endpoint), :execution => ex) +FactoryGirl.define do + factory :queued_execution, :parent => :execution do |e| + e.after_build do |ex| + FactoryGirl.create(:result_waiting, :endpoint => FactoryGirl(:endpoint), :execution => ex) + end end end -Factory.define :completed_execution, :parent => :execution do |e| - e.after_build do |ex| - Factory.create(:result_with_value, :endpoint => Factory(:endpoint), :execution => ex) - Factory.create(:result_with_value, :endpoint => Factory(:endpoint), :execution => ex) +FactoryGirl.define do + factory :completed_execution, :parent => :execution do |e| + e.after_build do |ex| + FactoryGirl.create(:result_with_value, :endpoint => FactoryGirl(:endpoint), :execution => ex) + FactoryGirl.create(:result_with_value, :endpoint => FactoryGirl(:endpoint), :execution => ex) + end end end -Factory.define :completed_execution_for_generated_query, :parent => :execution do |e| - e.after_build do |ex| - Factory.create(:result_with_value_from_generated_query, :endpoint => Factory(:endpoint), :execution => ex) - Factory.create(:result_with_value_from_generated_query, :endpoint => Factory(:endpoint), :execution => ex) - Factory.create(:result_with_value_from_generated_query, :endpoint => Factory(:endpoint), :execution => ex) - Factory.create(:result_with_value_from_generated_query, :endpoint => Factory(:endpoint), :execution => ex) +FactoryGirl.define do + factory :completed_execution_for_generated_query, :parent => :execution do |e| + e.after_build do |ex| + FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl(:endpoint), :execution => ex) + FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl(:endpoint), :execution => ex) + FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl(:endpoint), :execution => ex) + FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl(:endpoint), :execution => ex) + end end end -Factory.define :execution_with_generated_odd_result_count, :parent => :execution do |e| - e.after_build do |ex| - Factory.create(:result_with_value_from_generated_query, :endpoint => Factory(:endpoint), :execution => ex) - Factory.create(:result_with_value_from_generated_query, :endpoint => Factory(:endpoint), :execution => ex) - Factory.create(:result_with_value_from_generated_query, :endpoint => Factory(:endpoint), :execution => ex) +FactoryGirl.define do + factory :execution_with_generated_odd_result_count, :parent => :execution do |e| + e.after_build do |ex| + FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl(:endpoint), :execution => ex) + FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl(:endpoint), :execution => ex) + FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl(:endpoint), :execution => ex) + end end end -Factory.define :execution_with_generated_single_result, :parent => :execution do |e| - e.after_build do |ex| - Factory.create(:result_with_value_from_generated_query, :endpoint => Factory(:endpoint), :execution => ex) +FactoryGirl.define do + factory :execution_with_generated_single_result, :parent => :execution do |e| + e.after_build do |ex| + FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl(:endpoint), :execution => ex) + end end end @@ -177,88 +221,98 @@ # = Results = # =========== -Factory.define :result do |r| - r.value nil - r.result_url nil - r.status nil +FactoryGirl.define do + factory :result do |r| + r.value nil + r.result_url nil + r.status nil + end end -Factory.define :result_waiting, :parent => :result do |r| - r.value nil - r.result_url nil - r.status Result::QUEUED - r.query_url 'http://localhost:3000/queries/4e4c08b5431a5f5dc1000001' - r.created_at Time.new(2011, 1, 1) - r.updated_at Time.new(2011, 1, 1) +FactoryGirl.define do + factory :result_waiting, :parent => :result do |r| + r.value nil + r.result_url nil + r.status Result::QUEUED + r.query_url 'http://localhost:3000/queries/4e4c08b5431a5f5dc1000001' + r.created_at Time.new(2011, 1, 1) + r.updated_at Time.new(2011, 1, 1) + end end -Factory.define :result_with_value, :parent => :result do |result| - result.value ({"M" => 50, "F" => 30}) - result.status Result::COMPLETE +FactoryGirl.define do + factory :result_with_value, :parent => :result do |result| + result.value ({"M" => 50, "F" => 30}) + result.status Result::COMPLETE + end end -Factory.define :result_with_value_from_generated_query, :parent => :result_with_value do |result| - result.value ({ - "type_group_gender_F" => { - "values" => { - "age" => 0, - "age_sum" => 6000, - "age_frequency" => { - "18" => 65, - "65" => 18 +FactoryGirl.define do + factory :result_with_value_from_generated_query, :parent => :result_with_value do |result| + result.value ({ + "type_group_gender_F" => { + "values" => { + "age" => 0, + "age_sum" => 6000, + "age_frequency" => { + "18" => 65, + "65" => 18 + }, + "age_mean" => 28.193, + "age_mean_count" => 83, + "median" => 18, + "median_list" => [ + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65 + ], + "mode" => 18, + "mode_frequency" => { + "18" => 65, + "65" => 18 + } }, - "age_mean" => 28.193, - "age_mean_count" => 83, - "median" => 18, - "median_list" => [ - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65 - ], - "mode" => 18, - "mode_frequency" => { - "18" => 65, - "65" => 18 - } - }, - "rereduced" => true - }, - "type_group_gender_M" => { - "values" => { - "age" => 0, - "age_sum" => 4000 + "rereduced" => true }, - "rereduced" => true - }, - "type_population" => { - "values" => { - "target_pop" => 0, - "filtered_pop" => 0, - "unfound_pop" => 0, - "total_pop" => 0, - "target_pop_sum" => 300, - "filtered_pop_sum" => 400, - "unfound_pop_sum" => 100, - "total_pop_sum" => 500 + "type_group_gender_M" => { + "values" => { + "age" => 0, + "age_sum" => 4000 + }, + "rereduced" => true }, - "rereduced" => true - } - }) + "type_population" => { + "values" => { + "target_pop" => 0, + "filtered_pop" => 0, + "unfound_pop" => 0, + "total_pop" => 0, + "target_pop_sum" => 300, + "filtered_pop_sum" => 400, + "unfound_pop_sum" => 100, + "total_pop_sum" => 500 + }, + "rereduced" => true + } + }) + end end # ===================== # = Library Functions = # ===================== -Factory.define :library_function do |f| - f.sequence(:name) { |n| "sum#{n}()" } - f.definition "this.sum = function(values) {\r\n result = 0;\r\n values.forEach(function(value) {\r\n result += value;\r\n });\r\n return result;\r\n }\r\n" +FactoryGirl.define do + factory :library_function do |f| + f.sequence(:name) { |n| "sum#{n}()" } + f.definition "this.sum = function(values) {\r\n result = 0;\r\n values.forEach(function(value) {\r\n result += value;\r\n });\r\n return result;\r\n }\r\n" + end end @@ -267,17 +321,21 @@ # ====================== -Factory.define :code_set do |cs| - cs.name nil - cs.type nil - cs.description nil - cs.codes nil +FactoryGirl.define do + factory :code_set do |cs| + cs.name nil + cs.type nil + cs.description nil + cs.codes nil + end end -Factory.define :annulled_marital_status_code, :parent => :code_set do |cs| - codes = {"MaritalStatusCodes" => ["A"]} - cs.name "Annulled" - cs.description "" - cs.type "marital_status" - cs.codes codes -end \ No newline at end of file +FactoryGirl.define do + factory :annulled_marital_status_code, :parent => :code_set do |cs| + codes = {"MaritalStatusCodes" => ["A"]} + cs.name "Annulled" + cs.description "" + cs.type "marital_status" + cs.codes codes + end +end diff --git a/test/test_helper.rb b/test/test_helper.rb index 1568396..6118423 100755 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -4,7 +4,7 @@ require 'rails/test_help' require 'fakeweb' require 'factory_girl' -require 'mocha' +require 'mocha/setup' require 'pry' FactoryGirl.find_definitions diff --git a/test/unit/code_set_test.rb b/test/unit/code_set_test.rb index 2259f44..e9d8982 100644 --- a/test/unit/code_set_test.rb +++ b/test/unit/code_set_test.rb @@ -7,7 +7,7 @@ class CodeSetTest < ActiveSupport::TestCase end test "Should be able to add codes to a code_set" do - cs = Factory(:annulled_marital_status_code) + cs = FactoryGirl(:annulled_marital_status_code) cs.reload full_codes = cs.codes assert_equal full_codes.keys.length , 1 @@ -26,7 +26,7 @@ class CodeSetTest < ActiveSupport::TestCase end test "Should be able to Remove codes from a set " do - cs = Factory(:annulled_marital_status_code) + cs = FactoryGirl(:annulled_marital_status_code) cs.reload full_codes = cs.codes assert_equal full_codes.keys.length , 1 @@ -40,7 +40,7 @@ class CodeSetTest < ActiveSupport::TestCase end test "Should be able to Remove all codes from a code system from a code set" do - cs = Factory(:annulled_marital_status_code) + cs = FactoryGirl(:annulled_marital_status_code) cs.reload full_codes = cs.codes assert_equal full_codes.keys.length , 1 @@ -54,4 +54,4 @@ class CodeSetTest < ActiveSupport::TestCase end -end \ No newline at end of file +end From ca132b447dca2840082a28263f7236ddc9d309ca Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Thu, 20 Jun 2013 16:28:32 -0700 Subject: [PATCH 005/117] More updates --- test/functional/admin_controller_test.rb | 10 +++++----- test/functional/code_sets_controller_test.rb | 6 +++--- test/functional/endpoints_controller_test.rb | 8 ++++---- .../library_functions_controller_test.rb | 8 ++++---- test/functional/queries_controller_test.rb | 16 ++++++++-------- .../template_queries_controller_test.rb | 8 ++++---- test/functional/user_mailer_test.rb | 2 +- test/integration/query_aggregation_test.rb | 4 ++-- test/integration/user_access_test.rb | 8 ++++---- test/test_helper.rb | 8 ++++++-- test/unit/cud_actions_test.rb | 2 +- test/unit/endpoint_cron_test.rb | 4 ++-- test/unit/endpoint_test.rb | 16 ++++++++-------- test/unit/execution_test.rb | 18 +++++++++--------- test/unit/gateway_utils_test.rb | 2 +- test/unit/result_test.rb | 8 ++++---- test/unit/user_rake_test.rb | 6 +++--- test/unit/user_test.rb | 8 ++++---- 18 files changed, 73 insertions(+), 69 deletions(-) diff --git a/test/functional/admin_controller_test.rb b/test/functional/admin_controller_test.rb index ec0cf32..ec32ca5 100755 --- a/test/functional/admin_controller_test.rb +++ b/test/functional/admin_controller_test.rb @@ -7,12 +7,12 @@ class AdminControllerTest < ActionController::TestCase dump_database - @admin = Factory(:admin) - @user = Factory(:user) - @user2 = Factory(:user) - @unapproved_user = Factory(:unapproved_user) + @admin = FactoryGirl(:admin) + @user = FactoryGirl(:user) + @user2 = FactoryGirl(:user) + @unapproved_user = FactoryGirl(:unapproved_user) - @admin2 = Factory(:admin) + @admin2 = FactoryGirl(:admin) @user_ids = [] << @user.id diff --git a/test/functional/code_sets_controller_test.rb b/test/functional/code_sets_controller_test.rb index 8f13316..09acc26 100644 --- a/test/functional/code_sets_controller_test.rb +++ b/test/functional/code_sets_controller_test.rb @@ -7,13 +7,13 @@ class CodeSetsControllerTest < ActionController::TestCase setup do dump_database - @admin = Factory(:admin) + @admin = FactoryGIrl(:admin) - @code_set = Factory(:annulled_marital_status_code) + @code_set = FactoryGIrl(:annulled_marital_status_code) sign_in @admin - @user = Factory(:user_with_queries) + @user = FactoryGIrl(:user_with_queries) @ids = @user.queries.map {|q| q.id} end diff --git a/test/functional/endpoints_controller_test.rb b/test/functional/endpoints_controller_test.rb index a5fa942..bfbe423 100755 --- a/test/functional/endpoints_controller_test.rb +++ b/test/functional/endpoints_controller_test.rb @@ -5,14 +5,14 @@ class EndpointsControllerTest < ActionController::TestCase setup do dump_database - @admin = Factory(:admin) + @admin = FactoryGirl(:admin) - @endpoint = Factory(:endpoint) - @endpoint_unsaved = Factory.build(:endpoint) + @endpoint = FactoryGirl(:endpoint) + @endpoint_unsaved = FactoryGirl.build(:endpoint) sign_in @admin - @user = Factory(:user_with_queries) + @user = FactoryGirl(:user_with_queries) @ids = @user.queries.map {|q| q.id} end diff --git a/test/functional/library_functions_controller_test.rb b/test/functional/library_functions_controller_test.rb index 7c0b665..00bd7bf 100755 --- a/test/functional/library_functions_controller_test.rb +++ b/test/functional/library_functions_controller_test.rb @@ -5,12 +5,12 @@ class LibraryFunctionsControllerTest < ActionController::TestCase setup do dump_database - @user = Factory(:user_with_library_functions) - @another_user = Factory(:user_with_library_functions) - @admin = Factory(:admin) + @user = FactoryGirl(:user_with_library_functions) + @another_user = FactoryGirl(:user_with_library_functions) + @admin = FactoryGirl(:admin) @library_function = @user.library_functions[0] - @library_function_unsaved = Factory.build(:library_function) + @library_function_unsaved = FactoryGirl.build(:library_function) sign_in @user diff --git a/test/functional/queries_controller_test.rb b/test/functional/queries_controller_test.rb index 5d5d2a5..cad89ec 100755 --- a/test/functional/queries_controller_test.rb +++ b/test/functional/queries_controller_test.rb @@ -7,23 +7,23 @@ class QueriesControllerTest < ActionController::TestCase dump_database - @user = Factory(:user_with_queries) + @user = FactoryGirl(:user_with_queries) @ids = @user.queries.order_by([[:created_at, :desc]]).map {|q| q.id} @user_ids = [] << @user.id - @new_endpoint = Factory(:endpoint) + @new_endpoint = FactoryGirl(:endpoint) @endpoints_for_execution = [] - @endpoints_for_execution << Factory(:endpoint) - @endpoints_for_execution << Factory(:endpoint, base_url: 'http://127.0.0.1:3002') + @endpoints_for_execution << FactoryGirl(:endpoint) + @endpoints_for_execution << FactoryGirl(:endpoint, base_url: 'http://127.0.0.1:3002') - @unattached_query = Factory(:query) + @unattached_query = FactoryGirl(:query) - @admin = Factory(:admin) + @admin = FactoryGirl(:admin) - @unapproved_user = Factory(:unapproved_user) + @unapproved_user = FactoryGirl(:unapproved_user) - @template_query = Factory(:template_query) + @template_query = FactoryGirl(:template_query) end diff --git a/test/functional/template_queries_controller_test.rb b/test/functional/template_queries_controller_test.rb index a938853..bbc68fa 100644 --- a/test/functional/template_queries_controller_test.rb +++ b/test/functional/template_queries_controller_test.rb @@ -5,11 +5,11 @@ class TemplateQueriesControllerTest < ActionController::TestCase setup do dump_database - @user = Factory(:user) - @admin = Factory(:admin) + @user = FactoryGirl(:user) + @admin = FactoryGirl(:admin) - @template_query = Factory(:template_query) - @template_query_unsaved = Factory.build(:template_query) + @template_query = FactoryGirl(:template_query) + @template_query_unsaved = FactoryGirl.build(:template_query) end diff --git a/test/functional/user_mailer_test.rb b/test/functional/user_mailer_test.rb index cdb9102..ebe1b04 100755 --- a/test/functional/user_mailer_test.rb +++ b/test/functional/user_mailer_test.rb @@ -4,7 +4,7 @@ class UserMailerTest < ActionMailer::TestCase setup do dump_database - @user = Factory(:user_with_queries) + @user = FactoryGirl(:user_with_queries) @ids = @user.queries.map {|q| q.id} end diff --git a/test/integration/query_aggregation_test.rb b/test/integration/query_aggregation_test.rb index 0097fbb..f319645 100644 --- a/test/integration/query_aggregation_test.rb +++ b/test/integration/query_aggregation_test.rb @@ -6,7 +6,7 @@ class QueryAggregation < ActionDispatch::IntegrationTest setup do dump_database - @query = Factory(:generated_query_with_completed_results) + @query = FactoryGirl(:generated_query_with_completed_results) @query.generate_map_reduce @query.reduce = full_reduce(@query) @@ -26,7 +26,7 @@ class QueryAggregation < ActionDispatch::IntegrationTest assert_equal 24000, @execution_to_aggregate.aggregate_result['Gender: F']['age']['sum'] # 1 result - single_result = Factory.create(:generated_query_with_single_result) + single_result = FactoryGirl.create(:generated_query_with_single_result) single_result.executions.first.aggregate assert_equal 4000, single_result.executions.first.aggregate_result['Gender: M']['age']['sum'] assert_equal 6000, single_result.executions.first.aggregate_result['Gender: F']['age']['sum'] diff --git a/test/integration/user_access_test.rb b/test/integration/user_access_test.rb index 713e5d2..8abf4ed 100755 --- a/test/integration/user_access_test.rb +++ b/test/integration/user_access_test.rb @@ -6,11 +6,11 @@ class UserAccessTest < ActionDispatch::IntegrationTest setup do dump_database - @admin = Factory(:admin) - @user = Factory(:user_with_queries) + @admin = FactoryGirl.create(:admin) + @user = FactoryGirl.create(:user_with_queries) - @new_endpoint = Factory(:endpoint) - @unattached_query = Factory(:query) + @new_endpoint = FactoryGirl.create(:endpoint) + @unattached_query = FactoryGirl.create(:query) end diff --git a/test/test_helper.rb b/test/test_helper.rb index 6118423..de9770c 100755 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -12,10 +12,14 @@ class ActiveSupport::TestCase def dump_database - Mongoid::Config.master.collections.each do |collection| + #Mongoid::Config.master.collections.each do |collection| + # collection.drop unless collection.name.include?('system.') + #end + #Mongoid::Config.master['system.js'].remove({}) + Mongoid.session(:default).collections.each do |collection| collection.drop unless collection.name.include?('system.') end - Mongoid::Config.master['system.js'].remove({}) + Mongoid.default_session['system.js'].where({}).remove end def dump_jobs diff --git a/test/unit/cud_actions_test.rb b/test/unit/cud_actions_test.rb index 4bcd1bb..5d3317a 100644 --- a/test/unit/cud_actions_test.rb +++ b/test/unit/cud_actions_test.rb @@ -9,7 +9,7 @@ class CudActionsTest < ActionController::TestCase CudResource.all.each {|x| x.destroy} @controller = CudResourceController.new - @admin = Factory(:admin) + @admin = FactoryGirl(:admin) sign_in @admin end diff --git a/test/unit/endpoint_cron_test.rb b/test/unit/endpoint_cron_test.rb index 0b1ecc4..91b1d5c 100644 --- a/test/unit/endpoint_cron_test.rb +++ b/test/unit/endpoint_cron_test.rb @@ -21,8 +21,8 @@ class EndpointCronTest < ActiveSupport::TestCase :body => File.read(File.expand_path('../../fixtures/query_feed.xml', __FILE__))) FakeWeb.register_uri(:get, "http://localhost:3000/queries/4e4c08b5431a5f5dc1000001", :body => '{"status": "queued"}') - endpoint = Factory.create(:endpoint) - result = Factory.create(:result_waiting, endpoint: endpoint) + endpoint = FactoryGirl.create(:endpoint) + result = FactoryGirl.create(:result_waiting, endpoint: endpoint) result_updated_at = result.updated_at assert_equal 0, endpoint.endpoint_logs.count assert ! endpoint.last_check diff --git a/test/unit/endpoint_test.rb b/test/unit/endpoint_test.rb index c4c455d..ec65d5e 100755 --- a/test/unit/endpoint_test.rb +++ b/test/unit/endpoint_test.rb @@ -9,7 +9,7 @@ class EndpointTest < ActiveSupport::TestCase FakeWeb.register_uri(:get, "http://127.0.0.1:3001/queries", :status => [304, "Not Modified"]) - endpoint = Factory.create(:endpoint) + endpoint = FactoryGirl.create(:endpoint) assert_equal 0, endpoint.endpoint_logs.count assert ! endpoint.last_check endpoint.check @@ -25,8 +25,8 @@ class EndpointTest < ActiveSupport::TestCase :body => File.read(File.expand_path('../../fixtures/query_feed.xml', __FILE__))) FakeWeb.register_uri(:get, "http://localhost:3000/queries/4e4c08b5431a5f5dc1000001", :body => '{"status": "queued"}') - endpoint = Factory.create(:endpoint) - result = Factory.create(:result_waiting, endpoint: endpoint) + endpoint = FactoryGirl.create(:endpoint) + result = FactoryGirl.create(:result_waiting, endpoint: endpoint) result_updated_at = result.updated_at assert_equal 0, endpoint.endpoint_logs.count assert ! endpoint.last_check @@ -42,7 +42,7 @@ class EndpointTest < ActiveSupport::TestCase test "monitoring queries with incomprehensible responses" do FakeWeb.register_uri(:get, "http://127.0.0.1:3001/queries", :body => 'bacon is delicious') - endpoint = Factory.create(:endpoint) + endpoint = FactoryGirl.create(:endpoint) endpoint.check assert_equal 2, endpoint.endpoint_logs.count el = endpoint.endpoint_logs[1] @@ -51,16 +51,16 @@ class EndpointTest < ActiveSupport::TestCase end test "check if there are active queries" do - endpoint = Factory.create(:endpoint) - Factory.create(:result_with_value, endpoint: endpoint) + endpoint = FactoryGirl.create(:endpoint) + FactoryGirl.create(:result_with_value, endpoint: endpoint) assert !endpoint.unfinished_results? - Factory.create(:result_waiting, endpoint: endpoint) + FactoryGirl.create(:result_waiting, endpoint: endpoint) assert endpoint.unfinished_results? end test "should gracefully handle errors in check" do FakeWeb.register_uri(:get, "http://127.0.0.1:3001/queries", :exception => Net::HTTPError) - endpoint = Factory.create(:endpoint) + endpoint = FactoryGirl.create(:endpoint) endpoint.check assert_equal 1, endpoint.endpoint_logs.count el = endpoint.endpoint_logs.first diff --git a/test/unit/execution_test.rb b/test/unit/execution_test.rb index ae3c166..0852a6d 100644 --- a/test/unit/execution_test.rb +++ b/test/unit/execution_test.rb @@ -7,7 +7,7 @@ class ExecutionTest < ActiveSupport::TestCase setup do dump_database @logger = Logger.new('log/rake') - @user_with_functions = Factory(:user_with_queries_and_library_functions) + @user_with_functions = FactoryGirl(:user_with_queries_and_library_functions) library_function = @user_with_functions.library_functions[0] library_function.definition = library_function.definition.gsub(/username/,@user_with_functions.username) @@ -16,7 +16,7 @@ class ExecutionTest < ActiveSupport::TestCase end test "aggregation" do - execution_to_aggregate = Factory.create(:query_with_completed_results).executions.first + execution_to_aggregate = FactoryGirl.create(:query_with_completed_results).executions.first assert_nil execution_to_aggregate.aggregate_result execution_to_aggregate.aggregate @@ -26,7 +26,7 @@ class ExecutionTest < ActiveSupport::TestCase end test "aggregation for a generated query" do - query = Factory.create(:generated_query_with_completed_results) + query = FactoryGirl.create(:generated_query_with_completed_results) query.generate_map_reduce query.reduce = full_reduce(query) execution_to_aggregate = query.executions.first @@ -49,9 +49,9 @@ class ExecutionTest < ActiveSupport::TestCase FakeWeb.register_uri(:post, "http://127.0.0.1:3001/library_functions", :body => "yay", :status => [200, "OK"]) - user = Factory.create(:user) - query = Factory.create(:query, user: user) - endpoint = Factory.create(:endpoint) + user = FactoryGirl.create(:user) + query = FactoryGirl.create(:query, user: user) + endpoint = FactoryGirl.create(:endpoint) query.execute([endpoint]) @@ -83,7 +83,7 @@ class ExecutionTest < ActiveSupport::TestCase FakeWeb.register_uri(:post, "http://127.0.0.1:3001/queries", :status => ["500", "Internal Server Error"]) query = Query.find(@user_with_functions.queries[3].id) - endpoint = Factory.create(:endpoint) + endpoint = FactoryGirl.create(:endpoint) query.execute([endpoint]) assert_equal "Did not understand the response: 500 : Internal Server Error", endpoint.endpoint_logs[0].message @@ -93,10 +93,10 @@ class ExecutionTest < ActiveSupport::TestCase test "executions should only be finished if there are no queued results" do - execution_with_incomplete_results = Factory.create(:query_with_queued_results).executions.first + execution_with_incomplete_results = FactoryGirl.create(:query_with_queued_results).executions.first assert !execution_with_incomplete_results.finished? - execution_with_complete_results = Factory.create(:query_with_completed_results).executions.first + execution_with_complete_results = FactoryGirl.create(:query_with_completed_results).executions.first assert execution_with_complete_results.finished? end diff --git a/test/unit/gateway_utils_test.rb b/test/unit/gateway_utils_test.rb index 030e3af..76e0c9a 100644 --- a/test/unit/gateway_utils_test.rb +++ b/test/unit/gateway_utils_test.rb @@ -7,7 +7,7 @@ class GatewayUtilsTest < ActiveSupport::TestCase end test "generated queries should fetch javascript libraries" do - query = Factory.create(:generated_query_with_completed_results) + query = FactoryGirl.create(:generated_query_with_completed_results) query.generate_map_reduce full_map = full_map(query) diff --git a/test/unit/result_test.rb b/test/unit/result_test.rb index 269ae1f..2f8673a 100644 --- a/test/unit/result_test.rb +++ b/test/unit/result_test.rb @@ -11,7 +11,7 @@ class ResultTest < ActiveSupport::TestCase FakeWeb.register_uri(:get, "http://localhost/results/1234", :body => '{"foo": "bar"}') - result = Factory.create(:result_waiting) + result = FactoryGirl.create(:result_waiting) result_updated_at = result.updated_at result.check result.reload @@ -23,7 +23,7 @@ class ResultTest < ActiveSupport::TestCase test "fetch a result" do FakeWeb.register_uri(:get, "http://localhost/results/1234", :body => '{"foo": "bar"}') - result = Factory.create(:result, :result_url => "http://localhost/results/1234") + result = FactoryGirl.create(:result, :result_url => "http://localhost/results/1234") result.fetch_result assert_equal Result::COMPLETE, result.status assert_equal 'bar', result.value['foo'] @@ -34,7 +34,7 @@ class ResultTest < ActiveSupport::TestCase :body => '{"status": "complete", "result_url": "http://localhost/results/1234"}') FakeWeb.register_uri(:get, "http://localhost/results/1234", :body => '{"foo": "bar", "status": "complete"}') - result = Factory.create(:result_waiting) + result = FactoryGirl.create(:result_waiting) result.check assert_equal Result::COMPLETE, result.status assert_equal 'bar', result.value['foo'] @@ -43,7 +43,7 @@ class ResultTest < ActiveSupport::TestCase test "checking a result where there is an error" do FakeWeb.register_uri(:get, "http://localhost:3000/queries/4e4c08b5431a5f5dc1000001", :body => '{"status": "failed", "error_message": "game over, man!"}') - result = Factory.create(:result_waiting) + result = FactoryGirl.create(:result_waiting) result.check assert_equal Result::FAILED, result.status assert_equal 'game over, man!', result.error_msg diff --git a/test/unit/user_rake_test.rb b/test/unit/user_rake_test.rb index b28c966..6522ade 100755 --- a/test/unit/user_rake_test.rb +++ b/test/unit/user_rake_test.rb @@ -8,9 +8,9 @@ class UserRakeTest < ActiveSupport::TestCase dump_database - @unapproved_user = Factory(:unapproved_user) - @user = Factory(:user) - @admin = Factory(:admin) + @unapproved_user = FactoryGirl(:unapproved_user) + @user = FactoryGirl(:user) + @admin = FactoryGirl(:admin) if (!@@rake) diff --git a/test/unit/user_test.rb b/test/unit/user_test.rb index 66571e8..495fba8 100755 --- a/test/unit/user_test.rb +++ b/test/unit/user_test.rb @@ -6,13 +6,13 @@ class UserTest < ActiveSupport::TestCase dump_database - user = Factory(:user_with_queries) + user = FactoryGirl(:user_with_queries) @user_ids = [] << user.id @ids = user.queries.map {|q| q.id} - @ids_not_owned = [] << Factory(:query).id - @ids_not_owned << Factory(:query).id - @ids_not_owned << Factory(:query).id + @ids_not_owned = [] << FactoryGirl(:query).id + @ids_not_owned << FactoryGirl(:query).id + @ids_not_owned << FactoryGirl(:query).id end From 65ac7007e854377151a208b6305bcd14caf401ea Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Fri, 21 Jun 2013 09:39:59 -0700 Subject: [PATCH 006/117] Some tests now pass Signed-off-by: Raymond Rusk --- test/factories/factory.rb | 38 +++++++++---------- test/functional/admin_controller_test.rb | 10 ++--- test/functional/code_sets_controller_test.rb | 6 +-- test/functional/endpoints_controller_test.rb | 6 +-- .../library_functions_controller_test.rb | 6 +-- test/functional/queries_controller_test.rb | 16 ++++---- .../template_queries_controller_test.rb | 6 +-- test/functional/user_mailer_test.rb | 2 +- test/integration/query_aggregation_test.rb | 2 +- test/unit/code_set_test.rb | 6 +-- test/unit/cud_actions_test.rb | 2 +- test/unit/execution_test.rb | 2 +- test/unit/user_rake_test.rb | 6 +-- test/unit/user_test.rb | 8 ++-- 14 files changed, 58 insertions(+), 58 deletions(-) diff --git a/test/factories/factory.rb b/test/factories/factory.rb index 60d6b3d..4e747dc 100755 --- a/test/factories/factory.rb +++ b/test/factories/factory.rb @@ -30,24 +30,24 @@ FactoryGirl.define do factory :user_with_queries, :parent => :user do |user| - user.after_create { |u| FactoryGirl(:query, :user => u) } - user.after_create { |u| FactoryGirl(:query, :user => u) } - user.after_create { |u| FactoryGirl(:query, :user => u) } - user.after_create { |u| FactoryGirl(:query_with_queued_results, :user => u) } - user.after_create { |u| FactoryGirl(:query_with_completed_results, :user => u) } - user.after_create { |u| FactoryGirl(:generated_query_with_completed_results, :user => u) } + user.after_create { |u| FactoryGirl.create(:query, :user => u) } + user.after_create { |u| FactoryGirl.create(:query, :user => u) } + user.after_create { |u| FactoryGirl.create(:query, :user => u) } + user.after_create { |u| FactoryGirl.create(:query_with_queued_results, :user => u) } + user.after_create { |u| FactoryGirl.create(:query_with_completed_results, :user => u) } + user.after_create { |u| FactoryGirl.create(:generated_query_with_completed_results, :user => u) } end end FactoryGirl.define do factory :user_with_library_functions, :parent => :user do |user| - user.after_create {|u| FactoryGirl(:library_function, :user => u)} + user.after_create {|u| FactoryGirl.create(:library_function, :user => u)} end end FactoryGirl.define do factory :user_with_queries_and_library_functions, :parent => :user_with_queries do |user| - user.after_create {|u| FactoryGirl(:library_function, :user => u)} + user.after_create {|u| FactoryGirl.create(:library_function, :user => u)} end end @@ -174,7 +174,7 @@ FactoryGirl.define do factory :queued_execution, :parent => :execution do |e| e.after_build do |ex| - FactoryGirl.create(:result_waiting, :endpoint => FactoryGirl(:endpoint), :execution => ex) + FactoryGirl.create(:result_waiting, :endpoint => FactoryGirl.create(:endpoint), :execution => ex) end end end @@ -182,8 +182,8 @@ FactoryGirl.define do factory :completed_execution, :parent => :execution do |e| e.after_build do |ex| - FactoryGirl.create(:result_with_value, :endpoint => FactoryGirl(:endpoint), :execution => ex) - FactoryGirl.create(:result_with_value, :endpoint => FactoryGirl(:endpoint), :execution => ex) + FactoryGirl.create(:result_with_value, :endpoint => FactoryGirl.create(:endpoint), :execution => ex) + FactoryGirl.create(:result_with_value, :endpoint => FactoryGirl.create(:endpoint), :execution => ex) end end end @@ -191,10 +191,10 @@ FactoryGirl.define do factory :completed_execution_for_generated_query, :parent => :execution do |e| e.after_build do |ex| - FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl(:endpoint), :execution => ex) - FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl(:endpoint), :execution => ex) - FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl(:endpoint), :execution => ex) - FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl(:endpoint), :execution => ex) + FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl.create(:endpoint), :execution => ex) + FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl.create(:endpoint), :execution => ex) + FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl.create(:endpoint), :execution => ex) + FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl.create(:endpoint), :execution => ex) end end end @@ -202,9 +202,9 @@ FactoryGirl.define do factory :execution_with_generated_odd_result_count, :parent => :execution do |e| e.after_build do |ex| - FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl(:endpoint), :execution => ex) - FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl(:endpoint), :execution => ex) - FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl(:endpoint), :execution => ex) + FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl.create(:endpoint), :execution => ex) + FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl.create(:endpoint), :execution => ex) + FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl.create(:endpoint), :execution => ex) end end end @@ -212,7 +212,7 @@ FactoryGirl.define do factory :execution_with_generated_single_result, :parent => :execution do |e| e.after_build do |ex| - FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl(:endpoint), :execution => ex) + FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl.create(:endpoint), :execution => ex) end end end diff --git a/test/functional/admin_controller_test.rb b/test/functional/admin_controller_test.rb index ec32ca5..afce78c 100755 --- a/test/functional/admin_controller_test.rb +++ b/test/functional/admin_controller_test.rb @@ -7,12 +7,12 @@ class AdminControllerTest < ActionController::TestCase dump_database - @admin = FactoryGirl(:admin) - @user = FactoryGirl(:user) - @user2 = FactoryGirl(:user) - @unapproved_user = FactoryGirl(:unapproved_user) + @admin = FactoryGirl.create(:admin) + @user = FactoryGirl.create(:user) + @user2 = FactoryGirl.create(:user) + @unapproved_user = FactoryGirl.create(:unapproved_user) - @admin2 = FactoryGirl(:admin) + @admin2 = FactoryGirl.create(:admin) @user_ids = [] << @user.id diff --git a/test/functional/code_sets_controller_test.rb b/test/functional/code_sets_controller_test.rb index 09acc26..6224403 100644 --- a/test/functional/code_sets_controller_test.rb +++ b/test/functional/code_sets_controller_test.rb @@ -7,13 +7,13 @@ class CodeSetsControllerTest < ActionController::TestCase setup do dump_database - @admin = FactoryGIrl(:admin) + @admin = FactoryGirl.create(:admin) - @code_set = FactoryGIrl(:annulled_marital_status_code) + @code_set = FactoryGirl.create(:annulled_marital_status_code) sign_in @admin - @user = FactoryGIrl(:user_with_queries) + @user = FactoryGirl.create(:user_with_queries) @ids = @user.queries.map {|q| q.id} end diff --git a/test/functional/endpoints_controller_test.rb b/test/functional/endpoints_controller_test.rb index bfbe423..5d4415a 100755 --- a/test/functional/endpoints_controller_test.rb +++ b/test/functional/endpoints_controller_test.rb @@ -5,14 +5,14 @@ class EndpointsControllerTest < ActionController::TestCase setup do dump_database - @admin = FactoryGirl(:admin) + @admin = FactoryGirl.create(:admin) - @endpoint = FactoryGirl(:endpoint) + @endpoint = FactoryGirl.create(:endpoint) @endpoint_unsaved = FactoryGirl.build(:endpoint) sign_in @admin - @user = FactoryGirl(:user_with_queries) + @user = FactoryGirl.create(:user_with_queries) @ids = @user.queries.map {|q| q.id} end diff --git a/test/functional/library_functions_controller_test.rb b/test/functional/library_functions_controller_test.rb index 00bd7bf..2c459a6 100755 --- a/test/functional/library_functions_controller_test.rb +++ b/test/functional/library_functions_controller_test.rb @@ -5,9 +5,9 @@ class LibraryFunctionsControllerTest < ActionController::TestCase setup do dump_database - @user = FactoryGirl(:user_with_library_functions) - @another_user = FactoryGirl(:user_with_library_functions) - @admin = FactoryGirl(:admin) + @user = FactoryGirl.create(:user_with_library_functions) + @another_user = FactoryGirl.create(:user_with_library_functions) + @admin = FactoryGirl.create(:admin) @library_function = @user.library_functions[0] @library_function_unsaved = FactoryGirl.build(:library_function) diff --git a/test/functional/queries_controller_test.rb b/test/functional/queries_controller_test.rb index cad89ec..a9c00d9 100755 --- a/test/functional/queries_controller_test.rb +++ b/test/functional/queries_controller_test.rb @@ -7,23 +7,23 @@ class QueriesControllerTest < ActionController::TestCase dump_database - @user = FactoryGirl(:user_with_queries) + @user = FactoryGirl.create(:user_with_queries) @ids = @user.queries.order_by([[:created_at, :desc]]).map {|q| q.id} @user_ids = [] << @user.id - @new_endpoint = FactoryGirl(:endpoint) + @new_endpoint = FactoryGirl.create(:endpoint) @endpoints_for_execution = [] - @endpoints_for_execution << FactoryGirl(:endpoint) - @endpoints_for_execution << FactoryGirl(:endpoint, base_url: 'http://127.0.0.1:3002') + @endpoints_for_execution << FactoryGirl.create(:endpoint) + @endpoints_for_execution << FactoryGirl.create(:endpoint, base_url: 'http://127.0.0.1:3002') - @unattached_query = FactoryGirl(:query) + @unattached_query = FactoryGirl.create(:query) - @admin = FactoryGirl(:admin) + @admin = FactoryGirl.create(:admin) - @unapproved_user = FactoryGirl(:unapproved_user) + @unapproved_user = FactoryGirl.create(:unapproved_user) - @template_query = FactoryGirl(:template_query) + @template_query = FactoryGirl.create(:template_query) end diff --git a/test/functional/template_queries_controller_test.rb b/test/functional/template_queries_controller_test.rb index bbc68fa..a7b113f 100644 --- a/test/functional/template_queries_controller_test.rb +++ b/test/functional/template_queries_controller_test.rb @@ -5,10 +5,10 @@ class TemplateQueriesControllerTest < ActionController::TestCase setup do dump_database - @user = FactoryGirl(:user) - @admin = FactoryGirl(:admin) + @user = FactoryGirl.create(:user) + @admin = FactoryGirl.create(:admin) - @template_query = FactoryGirl(:template_query) + @template_query = FactoryGirl.create(:template_query) @template_query_unsaved = FactoryGirl.build(:template_query) end diff --git a/test/functional/user_mailer_test.rb b/test/functional/user_mailer_test.rb index ebe1b04..2cd011c 100755 --- a/test/functional/user_mailer_test.rb +++ b/test/functional/user_mailer_test.rb @@ -4,7 +4,7 @@ class UserMailerTest < ActionMailer::TestCase setup do dump_database - @user = FactoryGirl(:user_with_queries) + @user = FactoryGirl.create(:user_with_queries) @ids = @user.queries.map {|q| q.id} end diff --git a/test/integration/query_aggregation_test.rb b/test/integration/query_aggregation_test.rb index f319645..407e6c8 100644 --- a/test/integration/query_aggregation_test.rb +++ b/test/integration/query_aggregation_test.rb @@ -6,7 +6,7 @@ class QueryAggregation < ActionDispatch::IntegrationTest setup do dump_database - @query = FactoryGirl(:generated_query_with_completed_results) + @query = FactoryGirl.create(:generated_query_with_completed_results) @query.generate_map_reduce @query.reduce = full_reduce(@query) diff --git a/test/unit/code_set_test.rb b/test/unit/code_set_test.rb index e9d8982..3ea80d7 100644 --- a/test/unit/code_set_test.rb +++ b/test/unit/code_set_test.rb @@ -7,7 +7,7 @@ class CodeSetTest < ActiveSupport::TestCase end test "Should be able to add codes to a code_set" do - cs = FactoryGirl(:annulled_marital_status_code) + cs = FactoryGirl.create(:annulled_marital_status_code) cs.reload full_codes = cs.codes assert_equal full_codes.keys.length , 1 @@ -26,7 +26,7 @@ class CodeSetTest < ActiveSupport::TestCase end test "Should be able to Remove codes from a set " do - cs = FactoryGirl(:annulled_marital_status_code) + cs = FactoryGirl.create(:annulled_marital_status_code) cs.reload full_codes = cs.codes assert_equal full_codes.keys.length , 1 @@ -40,7 +40,7 @@ class CodeSetTest < ActiveSupport::TestCase end test "Should be able to Remove all codes from a code system from a code set" do - cs = FactoryGirl(:annulled_marital_status_code) + cs = FactoryGirl.create(:annulled_marital_status_code) cs.reload full_codes = cs.codes assert_equal full_codes.keys.length , 1 diff --git a/test/unit/cud_actions_test.rb b/test/unit/cud_actions_test.rb index 5d3317a..ce3e00e 100644 --- a/test/unit/cud_actions_test.rb +++ b/test/unit/cud_actions_test.rb @@ -9,7 +9,7 @@ class CudActionsTest < ActionController::TestCase CudResource.all.each {|x| x.destroy} @controller = CudResourceController.new - @admin = FactoryGirl(:admin) + @admin = FactoryGirl.create(:admin) sign_in @admin end diff --git a/test/unit/execution_test.rb b/test/unit/execution_test.rb index 0852a6d..dec294b 100644 --- a/test/unit/execution_test.rb +++ b/test/unit/execution_test.rb @@ -7,7 +7,7 @@ class ExecutionTest < ActiveSupport::TestCase setup do dump_database @logger = Logger.new('log/rake') - @user_with_functions = FactoryGirl(:user_with_queries_and_library_functions) + @user_with_functions = FactoryGirl.create(:user_with_queries_and_library_functions) library_function = @user_with_functions.library_functions[0] library_function.definition = library_function.definition.gsub(/username/,@user_with_functions.username) diff --git a/test/unit/user_rake_test.rb b/test/unit/user_rake_test.rb index 6522ade..9c88b67 100755 --- a/test/unit/user_rake_test.rb +++ b/test/unit/user_rake_test.rb @@ -8,9 +8,9 @@ class UserRakeTest < ActiveSupport::TestCase dump_database - @unapproved_user = FactoryGirl(:unapproved_user) - @user = FactoryGirl(:user) - @admin = FactoryGirl(:admin) + @unapproved_user = FactoryGirl.create(:unapproved_user) + @user = FactoryGirl.create(:user) + @admin = FactoryGirl.create(:admin) if (!@@rake) diff --git a/test/unit/user_test.rb b/test/unit/user_test.rb index 495fba8..0d7760e 100755 --- a/test/unit/user_test.rb +++ b/test/unit/user_test.rb @@ -6,13 +6,13 @@ class UserTest < ActiveSupport::TestCase dump_database - user = FactoryGirl(:user_with_queries) + user = FactoryGirl.create(:user_with_queries) @user_ids = [] << user.id @ids = user.queries.map {|q| q.id} - @ids_not_owned = [] << FactoryGirl(:query).id - @ids_not_owned << FactoryGirl(:query).id - @ids_not_owned << FactoryGirl(:query).id + @ids_not_owned = [] << FactoryGirl.create(:query).id + @ids_not_owned << FactoryGirl.create(:query).id + @ids_not_owned << FactoryGirl.create(:query).id end From 1d172bcf6baf768ceff7bb4c3190f77679ffff66 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Sat, 22 Jun 2013 21:23:16 -0700 Subject: [PATCH 007/117] Removed bson_ext dependency Signed-off-by: Raymond Rusk --- Gemfile | 4 +- app/controllers/queries_controller.rb | 2 +- app/helpers/queries_helper.rb | 2 +- config/initializers/devise.rb | 132 ++++++++++++++++++-------- config/initializers/mongo.rb | 8 +- config/locales/devise.en.yml | 89 +++++++++-------- test/factories/factory.rb | 1 - 7 files changed, 149 insertions(+), 89 deletions(-) diff --git a/Gemfile b/Gemfile index 4a775b5..f165fb3 100755 --- a/Gemfile +++ b/Gemfile @@ -15,9 +15,9 @@ end gem 'jquery-rails' gem 'sprockets' -gem 'bson_ext', :platforms => :mri +#gem 'bson_ext', :platforms => :mri gem 'daemons' -gem 'mongo' +#gem 'mongo' gem "mongoid" gem 'mongoid_rails_migrations' gem 'simple_form' diff --git a/app/controllers/queries_controller.rb b/app/controllers/queries_controller.rb index a0b981a..7bb4c5d 100755 --- a/app/controllers/queries_controller.rb +++ b/app/controllers/queries_controller.rb @@ -74,7 +74,7 @@ def result def execute endpoint_ids = params[:endpoint_ids] if (endpoint_ids && !endpoint_ids.empty?) - endpoint_ids = endpoint_ids.map! {|id| BSON::ObjectId(id)} + endpoint_ids = endpoint_ids.map! {|id| Moped::BSON::ObjectId(id)} endpoints = Endpoint.criteria.for_ids(endpoint_ids) notify = params[:notification] diff --git a/app/helpers/queries_helper.rb b/app/helpers/queries_helper.rb index 038dbbf..c8239cf 100755 --- a/app/helpers/queries_helper.rb +++ b/app/helpers/queries_helper.rb @@ -1,7 +1,7 @@ module QueriesHelper def jsonify(value) begin - if value.class == Hash || value.class == Array || value.class == BSON::OrderedHash + if value.class == Hash || value.class == Array || value.class == Moped::BSON::OrderedHash JSON.pretty_generate(value) else value diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index be10939..98553f9 100755 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -1,8 +1,9 @@ -# Use this hook to configure devise mailer, warden hooks and so forth. The first -# four configuration values can also be set straight in your models. +# Use this hook to configure devise mailer, warden hooks and so forth. +# Many of these configuration options can be set straight in your model. Devise.setup do |config| # ==> Mailer Configuration - # Configure the e-mail address which will be shown in DeviseMailer. + # Configure the e-mail address which will be shown in Devise::Mailer, + # note that it will be overwritten if you use your own mailer class with default "from" parameter. config.mailer_sender = "please-change-me-at-config-initializers-devise@example.com" # Configure the class responsible to send e-mails. @@ -36,10 +37,25 @@ # to authenticate or find a user. Default is :email. config.case_insensitive_keys = [ :email ] + # Configure which authentication keys should have whitespace stripped. + # These keys will have whitespace before and after removed upon creating or + # modifying a user and when used to authenticate or find a user. Default is :email. + config.strip_whitespace_keys = [ :email ] + # Tell if authentication through request.params is enabled. True by default. + # It can be set to an array that will enable params authentication only for the + # given strategies, for example, `config.params_authenticatable = [:database]` will + # enable it only for database (email + password) authentication. # config.params_authenticatable = true - # Tell if authentication through HTTP Basic Auth is enabled. False by default. + # Tell if authentication through HTTP Auth is enabled. False by default. + # It can be set to an array that will enable http authentication only for the + # given strategies, for example, `config.http_authenticatable = [:token]` will + # enable it only for token authentication. The supported strategies are: + # :database = Support basic authentication with authentication key + password + # :token = Support basic authentication with token authentication key + # :token_options = Support token authentication with options as defined in + # http://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Token.html # config.http_authenticatable = false # If http headers should be returned for AJAX requests. True by default. @@ -48,22 +64,51 @@ # The realm used in Http Basic Authentication. "Application" by default. # config.http_authentication_realm = "Application" + # It will change confirmation, password recovery and other workflows + # to behave the same regardless if the e-mail provided was right or wrong. + # Does not affect registerable. + # config.paranoid = true + + # By default Devise will store the user in session. You can skip storage for + # :http_auth and :token_auth by adding those symbols to the array below. + # Notice that if you are skipping storage for all authentication paths, you + # may want to disable generating routes to Devise's sessions controller by + # passing :skip => :sessions to `devise_for` in your config/routes.rb + config.skip_session_storage = [:http_auth] + # ==> Configuration for :database_authenticatable # For bcrypt, this is the cost for hashing the password and defaults to 10. If # using other encryptors, it sets how many times you want the password re-encrypted. - config.stretches = 10 + # + # Limiting the stretches to just one in testing will increase the performance of + # your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use + # a value less than 10 in other environments. + config.stretches = Rails.env.test? ? 1 : 10 # Setup a pepper to generate the encrypted password. - # config.pepper = "ca090303f7746d096fb3349512c5a211a12e95db385e225d5682c0e580ae7e1e79c808b433724421627ff68e6b2bdb189ed95d0a43f570c97fc2787c06090754" + # config.pepper = "72e0710c83b5b04cb896d5ce09f319ec651d9adc2f927aa1fd2085d437f313dae2e8aaa90005583b66dc943dff07379b40dff579d032cf3e9809f1d72a3dd014" # ==> Configuration for :confirmable - # The time you want to give your user to confirm his account. During this time - # he will be able to access your application without confirming. Default is 0.days - # When confirm_within is zero, the user won't be able to sign in without confirming. - # You can use this to let your user access some features of your application - # without confirming the account, but blocking it after a certain period - # (ie 2 days). - # config.confirm_within = 2.days + # A period that the user is allowed to access the website even without + # confirming his account. For instance, if set to 2.days, the user will be + # able to access the website for two days without confirming his account, + # access will be blocked just in the third day. Default is 0.days, meaning + # the user cannot access the website without confirming his account. + # config.allow_unconfirmed_access_for = 2.days + + # A period that the user is allowed to confirm their account before their + # token becomes invalid. For example, if set to 3.days, the user can confirm + # their account within 3 days after the mail was sent, but on the fourth day + # their account can't be confirmed with the token any more. + # Default is nil, meaning there is no restriction on how long a user can take + # before confirming their account. + # config.confirm_within = 3.days + + # If true, requires any email changes to be confirmed (exactly the same way as + # initial account confirmation) to be applied. Requires additional unconfirmed_email + # db field (see migrations). Until confirmed new email is stored in + # unconfirmed email column, and copied to email column on successful confirmation. + config.reconfirmable = true # Defines which key will be used when confirming an account # config.confirmation_keys = [ :email ] @@ -72,32 +117,30 @@ # The time the user will be remembered without asking for credentials again. # config.remember_for = 2.weeks - # If true, a valid remember token can be re-used between multiple browsers. - # config.remember_across_browsers = true - # If true, extends the user's remember period when remembered via cookie. # config.extend_remember_period = false - # If true, uses the password salt as remember token. This should be turned - # to false if you are not using database authenticatable. - # config.use_salt_as_remember_token = true - # Options to be passed to the created cookie. For instance, you can set # :secure => true in order to force SSL only cookies. - # config.cookie_options = {} + # config.rememberable_options = {} # ==> Configuration for :validatable - # Range for password length. Default is 6..128. - # config.password_length = 6..128 + # Range for password length. Default is 8..128. + config.password_length = 8..128 - # Regex to use to validate the email address - # config.email_regexp = /\A([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})\z/i + # Email regex used to validate email formats. It simply asserts that + # one (and only one) @ exists in the given string. This is mainly + # to give user feedback and not to assert the e-mail validity. + # config.email_regexp = /\A[^@]+@[^@]+\z/ # ==> Configuration for :timeoutable # The time you want to timeout the user session without activity. After this # time the user will be asked for credentials again. Default is 30 minutes. # config.timeout_in = 30.minutes + # If true, expires auth token on session timeout. + # config.expire_auth_token_on_timeout = false + # ==> Configuration for :lockable # Defines which strategy will be used to lock an account. # :failed_attempts = Locks an account after a number of failed attempts to sign in. @@ -129,24 +172,22 @@ # Time interval you can reset your password with a reset password key. # Don't put a too small interval or your users won't have the time to # change their passwords. - config.reset_password_within = 2.hours + config.reset_password_within = 6.hours # ==> Configuration for :encryptable # Allow you to use another encryption algorithm besides bcrypt (default). You can use # :sha1, :sha512 or encryptors from others authentication tools as :clearance_sha1, # :authlogic_sha512 (then you should set stretches above to 20 for default behavior) # and :restful_authentication_sha1 (then you should set stretches to 10, and copy - # REST_AUTH_SITE_KEY to pepper) + # REST_AUTH_SITE_KEY to pepper). + # + # Require the `devise-encryptable` gem when using anything other than bcrypt # config.encryptor = :sha512 # ==> Configuration for :token_authenticatable # Defines name of the authentication token params key # config.token_authentication_key = :auth_token - # If true, authentication through token does not store user in session and needs - # to be supplied on each request. Useful if you are using the token as API token. - # config.stateless_token = false - # ==> Scopes configuration # Turn scoped views on. Before rendering "sessions/new", it will first check for # "users/sessions/new". It's turned off by default because it's slower if you @@ -157,9 +198,8 @@ # devise role declared in your routes (usually :user). # config.default_scope = :user - # Configure sign_out behavior. - # Sign_out action can be scoped (i.e. /users/sign_out affects only :user scope). - # The default is true, which means any logout action will sign out all active scopes. + # Set this configuration to false if you want /users/sign_out to sign out + # only the current scope. By default, Devise signs out all scopes. # config.sign_out_all_scopes = true # ==> Navigation configuration @@ -170,12 +210,11 @@ # If you have any extra navigational formats, like :iphone or :mobile, you # should add them to the navigational formats lists. # - # The :"*/*" and "*/*" formats below is required to match Internet - # Explorer requests. - # config.navigational_formats = [:"*/*", "*/*", :html] + # The "*/*" below is required to match Internet Explorer requests. + # config.navigational_formats = ["*/*", :html] - # The default HTTP method used to sign out a resource. Default is :get. - # config.sign_out_via = :get + # The default HTTP method used to sign out a resource. Default is :delete. + config.sign_out_via = :delete # ==> OmniAuth # Add a new OmniAuth provider. Check the wiki for more information on setting @@ -187,8 +226,21 @@ # change the failure app, you can configure them inside the config.warden block. # # config.warden do |manager| - # manager.failure_app = AnotherApp # manager.intercept_401 = false # manager.default_strategies(:scope => :user).unshift :some_external_strategy # end + + # ==> Mountable engine configurations + # When using Devise inside an engine, let's call it `MyEngine`, and this engine + # is mountable, there are some extra configurations to be taken into account. + # The following options are available, assuming the engine is mounted as: + # + # mount MyEngine, at: "/my_engine" + # + # The router that invoked `devise_for`, in the example above, would be: + # config.router_name = :my_engine + # + # When using omniauth, Devise cannot automatically set Omniauth path, + # so you need to do it manually. For the users scope, it would be: + # config.omniauth_path_prefix = "/my_engine/users/auth" end diff --git a/config/initializers/mongo.rb b/config/initializers/mongo.rb index 3b5e6c4..241af4b 100755 --- a/config/initializers/mongo.rb +++ b/config/initializers/mongo.rb @@ -1,6 +1,6 @@ -require 'mongo' +#require 'mongo' -host = ENV['TEST_DB_HOST'] || 'localhost' -conn = Mongo::Connection.new(host, 27017) +#host = ENV['TEST_DB_HOST'] || 'localhost' +#conn = Mongo::Connection.new(host, 27017) -MONGO_DB = conn["hquery-composer-#{Rails.env}"] +#MONGO_DB = conn["hquery-composer-#{Rails.env}"] diff --git a/config/locales/devise.en.yml b/config/locales/devise.en.yml index 25022e1..d01f375 100755 --- a/config/locales/devise.en.yml +++ b/config/locales/devise.en.yml @@ -1,50 +1,59 @@ -# Additional translations at http://github.com/plataformatec/devise/wiki/I18n +# Additional translations at https://github.com/plataformatec/devise/wiki/I18n en: + devise: + confirmations: + confirmed: "Your account was successfully confirmed. You are now signed in." + send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes." + send_paranoid_instructions: "If your email address exists in our database, you will receive an email with instructions about how to confirm your account in a few minutes." + failure: + already_authenticated: "You are already signed in." + inactive: "Your account was not activated yet." + invalid: "Invalid email or password." + invalid_token: "Invalid authentication token." + locked: "Your account is locked." + not_found_in_database: "Invalid email or password." + timeout: "Your session expired, please sign in again to continue." + unauthenticated: "You need to sign in or sign up before continuing." + unconfirmed: "You have to confirm your account before continuing." + mailer: + confirmation_instructions: + subject: "Confirmation instructions" + reset_password_instructions: + subject: "Reset password instructions" + unlock_instructions: + subject: "Unlock Instructions" + omniauth_callbacks: + failure: "Could not authenticate you from %{kind} because \"%{reason}\"." + success: "Successfully authenticated from %{kind} account." + passwords: + no_token: "You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided." + send_instructions: "You will receive an email with instructions about how to reset your password in a few minutes." + send_paranoid_instructions: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes." + updated: "Your password was changed successfully. You are now signed in." + updated_not_active: "Your password was changed successfully." + registrations: + destroyed: "Bye! Your account was successfully cancelled. We hope to see you again soon." + signed_up: "Welcome! You have signed up successfully." + signed_up_but_inactive: "You have signed up successfully. However, we could not sign you in because your account is not yet activated." + signed_up_but_locked: "You have signed up successfully. However, we could not sign you in because your account is locked." + signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please open the link to activate your account." + update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and click on the confirm link to finalize confirming your new email address." + updated: "You updated your account successfully." + sessions: + signed_in: "Signed in successfully." + signed_out: "Signed out successfully." + unlocks: + send_instructions: "You will receive an email with instructions about how to unlock your account in a few minutes." + send_paranoid_instructions: "If your account exists, you will receive an email with instructions about how to unlock it in a few minutes." + unlocked: "Your account has been unlocked successfully. Please sign in to continue." errors: messages: + already_confirmed: "was already confirmed, please try signing in" + confirmation_period_expired: "needs to be confirmed within %{period}, please request a new one" expired: "has expired, please request a new one" not_found: "not found" - already_confirmed: "was already confirmed, please try signing in" not_locked: "was not locked" not_saved: one: "1 error prohibited this %{resource} from being saved:" other: "%{count} errors prohibited this %{resource} from being saved:" - - devise: - failure: - already_authenticated: 'You are already signed in.' - unauthenticated: 'You need to sign in or sign up before continuing.' - unconfirmed: 'You have to confirm your account before continuing.' - locked: 'Your account is locked.' - invalid: 'Invalid email or password.' - invalid_token: 'Invalid authentication token.' - timeout: 'Your session expired, please sign in again to continue.' - inactive: 'Your account was not activated yet.' - sessions: - signed_in: 'Signed in successfully.' - signed_out: 'Signed out successfully.' - passwords: - send_instructions: 'You will receive an email with instructions about how to reset your password in a few minutes.' - updated: 'Your password was changed successfully. You are now signed in.' - confirmations: - send_instructions: 'You will receive an email with instructions about how to confirm your account in a few minutes.' - confirmed: 'Your account was successfully confirmed. You are now signed in.' - registrations: - signed_up: 'Welcome! You have signed up successfully.' - inactive_signed_up: 'You have signed up successfully. However, we could not sign you in because your account is %{reason}.' - updated: 'You updated your account successfully.' - destroyed: 'Bye! Your account was successfully cancelled. We hope to see you again soon.' - unlocks: - send_instructions: 'You will receive an email with instructions about how to unlock your account in a few minutes.' - unlocked: 'Your account was successfully unlocked. You are now signed in.' - omniauth_callbacks: - success: 'Successfully authorized from %{kind} account.' - failure: 'Could not authorize you from %{kind} because "%{reason}".' - mailer: - confirmation_instructions: - subject: 'Confirmation instructions' - reset_password_instructions: - subject: 'Reset password instructions' - unlock_instructions: - subject: 'Unlock Instructions' diff --git a/test/factories/factory.rb b/test/factories/factory.rb index 4e747dc..0d9f85f 100755 --- a/test/factories/factory.rb +++ b/test/factories/factory.rb @@ -194,7 +194,6 @@ FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl.create(:endpoint), :execution => ex) FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl.create(:endpoint), :execution => ex) FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl.create(:endpoint), :execution => ex) - FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl.create(:endpoint), :execution => ex) end end end From dff660fa8b0c41ef426f66600c2f26977c0b2656 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Sat, 22 Jun 2013 22:48:15 -0700 Subject: [PATCH 008/117] Some mods suggested by David Rusk Signed-off-by: Raymond Rusk --- test/factories/factory.rb | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/test/factories/factory.rb b/test/factories/factory.rb index 0d9f85f..1e8f86f 100755 --- a/test/factories/factory.rb +++ b/test/factories/factory.rb @@ -30,24 +30,39 @@ FactoryGirl.define do factory :user_with_queries, :parent => :user do |user| - user.after_create { |u| FactoryGirl.create(:query, :user => u) } - user.after_create { |u| FactoryGirl.create(:query, :user => u) } - user.after_create { |u| FactoryGirl.create(:query, :user => u) } - user.after_create { |u| FactoryGirl.create(:query_with_queued_results, :user => u) } - user.after_create { |u| FactoryGirl.create(:query_with_completed_results, :user => u) } - user.after_create { |u| FactoryGirl.create(:generated_query_with_completed_results, :user => u) } + after(:create) do |user, evaluator| + FactoryGirl.create(:query, user: user) + FactoryGirl.create(:query, user: user) + FactoryGirl.create(:query, user: user) + FactoryGirl.create(:query_with_queued_results, user: user) + FactoryGirl.create(:query_with_completed_results, user: user) + FactoryGirl.create(:generated_query_with_completed_results, user: user) + end + #user.after_create { |u| FactoryGirl.create(:query, :user => u) } + #user.after_create { |u| FactoryGirl.create(:query, :user => u) } + #user.after_create { |u| FactoryGirl.create(:query, :user => u) } + #user.after_create { |u| FactoryGirl.create(:query_with_queued_results, :user => u) } + #user.after_create { |u| FactoryGirl.create(:query_with_completed_results, :user => u) } + #user.after_create { |u| FactoryGirl.create(:generated_query_with_completed_results, :user => u) } end end FactoryGirl.define do factory :user_with_library_functions, :parent => :user do |user| - user.after_create {|u| FactoryGirl.create(:library_function, :user => u)} + after(:create) do |user, evaluator| + FactoryGirl.create(:library_function, user: user) + end + + #user.after_create {|u| FactoryGirl.create(:library_function, :user => u)} end end FactoryGirl.define do factory :user_with_queries_and_library_functions, :parent => :user_with_queries do |user| - user.after_create {|u| FactoryGirl.create(:library_function, :user => u)} + after(:crate) do |user, evaluator| + FactoryGirl.create(:library_function, user:user) + end + #user.after_create {|u| FactoryGirl.create(:library_function, :user => u)} end end From 9b40b7450fffc3a50fe77dcc252e0d177c8b7455 Mon Sep 17 00:00:00 2001 From: drusk Date: Sun, 23 Jun 2013 13:53:22 -0700 Subject: [PATCH 009/117] Updated method for retrieving first record from User. --- app/controllers/admin_controller.rb | 2 +- app/models/user.rb | 4 ++-- test/factories/factory.rb | 5 ++--- test/unit/user_rake_test.rb | 4 ++-- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb index 344aefd..7b6844e 100755 --- a/app/controllers/admin_controller.rb +++ b/app/controllers/admin_controller.rb @@ -31,7 +31,7 @@ def disable end def approve - user = User.first(:conditions => {:username => params[:username]}) + user = User.where(username: params[:username]).first if user user.update_attribute(:approved, true) render :text => "true" diff --git a/app/models/user.rb b/app/models/user.rb index 764d22c..2a5ac96 100755 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -46,10 +46,10 @@ def active_for_authentication? # ========== def self.find_by_username(username) - User.first(:conditions => {:username => username}) + User.where(username: username).first end def self.find_by_email(email) - User.first(:conditions => {:email => email}) + User.where(email: email).first end # ============= diff --git a/test/factories/factory.rb b/test/factories/factory.rb index 1e8f86f..579b3a2 100755 --- a/test/factories/factory.rb +++ b/test/factories/factory.rb @@ -52,15 +52,14 @@ after(:create) do |user, evaluator| FactoryGirl.create(:library_function, user: user) end - #user.after_create {|u| FactoryGirl.create(:library_function, :user => u)} end end FactoryGirl.define do factory :user_with_queries_and_library_functions, :parent => :user_with_queries do |user| - after(:crate) do |user, evaluator| - FactoryGirl.create(:library_function, user:user) + after(:create) do |user, evaluator| + FactoryGirl.create(:library_function, user: user) end #user.after_create {|u| FactoryGirl.create(:library_function, :user => u)} end diff --git a/test/unit/user_rake_test.rb b/test/unit/user_rake_test.rb index 9c88b67..c670841 100755 --- a/test/unit/user_rake_test.rb +++ b/test/unit/user_rake_test.rb @@ -54,8 +54,8 @@ class UserRakeTest < ActiveSupport::TestCase @unapproved_user.reload - assert @unapproved_user.approved? - assert @unapproved_user.admin? + assert(@unapproved_user.approved?, msg="Was not approved") + assert(@unapproved_user.admin?, msg="Was not admin") end From 4c8137ee2841b87e2568cfb0982b3b37982d211e Mon Sep 17 00:00:00 2001 From: drusk Date: Sun, 23 Jun 2013 16:04:38 -0700 Subject: [PATCH 010/117] Updated method of calling after build in test factories. --- test/factories/factory.rb | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/test/factories/factory.rb b/test/factories/factory.rb index 579b3a2..e57a57b 100755 --- a/test/factories/factory.rb +++ b/test/factories/factory.rb @@ -116,7 +116,10 @@ FactoryGirl.define do factory :query_with_queued_results, :parent => :query do |query| query.reduce "function reduce(key, values) {\r\n var result = 0; \r\n while(values.hasNext()){ result += values.next(); }\r\nreturn result; \r\n}" - + + #after(:create) do |query, evaluator| + # FactoryGirl.create_list(:queued_execution, 1, query: query) + #end query.executions { [] << FactoryGirl.build(:queued_execution) } @@ -126,7 +129,10 @@ FactoryGirl.define do factory :query_with_completed_results, :parent => :query do |query| query.reduce "function reduce(key, values) {\r\n var result = 0; \r\n while(values.hasNext()){ result += values.next(); }\r\nreturn result; \r\n}" - + + #after(:create) do |query, evaluator| + # FactoryGirl.create_list(:completed_execution, 1, query: query) + #end query.executions { [] << FactoryGirl.build(:completed_execution) } @@ -135,6 +141,10 @@ FactoryGirl.define do factory :generated_query_with_completed_results, :parent => :generated_query do |query| + + #after(:create) do |query, evaluator| + # FactoryGirl.create_list(:completed_execution_for_generated_query, 1, query: query) + #end query.executions { [] << FactoryGirl.build(:completed_execution_for_generated_query) } @@ -143,6 +153,9 @@ FactoryGirl.define do factory :generated_query_with_odd_result_count, :parent => :generated_query do |query| + #after(:create) do |query, evaluator| + # FactoryGirl.create_list(:execution_with_generated_odd_result_count, 1, query: query) + #end query.executions { [] << FactoryGirl.build(:execution_with_generated_odd_result_count) } @@ -151,6 +164,9 @@ FactoryGirl.define do factory :generated_query_with_single_result, :parent => :generated_query do |query| + #after(:create) do |query, evaluator| + # FactoryGirl.create_list(:execution_with_generated_single_result, 1, query: query) + #end query.executions { [] << FactoryGirl.build(:execution_with_generated_single_result) } @@ -159,6 +175,9 @@ FactoryGirl.define do factory :generated_query_with_no_results, :parent => :generated_query do |query| + #after(:create) do |query, evaluator| + # FactoryGirl.create_list(:execution, 1, query: query) + #end query.executions { [] << FactoryGirl.build(:execution) } @@ -187,7 +206,8 @@ FactoryGirl.define do factory :queued_execution, :parent => :execution do |e| - e.after_build do |ex| + after(:build) do |ex| + #e.after_build do |ex| FactoryGirl.create(:result_waiting, :endpoint => FactoryGirl.create(:endpoint), :execution => ex) end end @@ -195,7 +215,8 @@ FactoryGirl.define do factory :completed_execution, :parent => :execution do |e| - e.after_build do |ex| + after(:build) do |ex| + #e.after_build do |ex| FactoryGirl.create(:result_with_value, :endpoint => FactoryGirl.create(:endpoint), :execution => ex) FactoryGirl.create(:result_with_value, :endpoint => FactoryGirl.create(:endpoint), :execution => ex) end @@ -204,7 +225,8 @@ FactoryGirl.define do factory :completed_execution_for_generated_query, :parent => :execution do |e| - e.after_build do |ex| + after(:build) do |ex| + #e.after_build do |ex| FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl.create(:endpoint), :execution => ex) FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl.create(:endpoint), :execution => ex) FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl.create(:endpoint), :execution => ex) @@ -214,7 +236,8 @@ FactoryGirl.define do factory :execution_with_generated_odd_result_count, :parent => :execution do |e| - e.after_build do |ex| + after(:build) do |ex| + #e.after_build do |ex| FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl.create(:endpoint), :execution => ex) FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl.create(:endpoint), :execution => ex) FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl.create(:endpoint), :execution => ex) @@ -224,7 +247,8 @@ FactoryGirl.define do factory :execution_with_generated_single_result, :parent => :execution do |e| - e.after_build do |ex| + after(:build) do |ex| + #e.after_build do |ex| FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl.create(:endpoint), :execution => ex) end end From 8caecf676079f4f4070e0cbf5de73ae2fe23792b Mon Sep 17 00:00:00 2001 From: drusk Date: Sun, 23 Jun 2013 16:19:52 -0700 Subject: [PATCH 011/117] Updated call to render to remove deprecation warnings. --- app/models/query.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/query.rb b/app/models/query.rb index 12dd9ba..252c18a 100755 --- a/app/models/query.rb +++ b/app/models/query.rb @@ -27,12 +27,12 @@ def generate_map_reduce if (self.generated?) map_function = "" map_template = ActionView::Base.new(QueryComposer::Application.paths['app/views']) - map_template = map_template.render(:template => "queries/builder/_map_function.js.erb", locals: { :query_structure => self.query_structure }) + map_template = map_template.render(:template => "queries/builder/_map_function", :handlers => [:erb], :formats => [:js], locals: { :query_structure => self.query_structure }) self.map = prettify_generated_function(map_template) reduce_function = "" reduce_template = ActionView::Base.new(QueryComposer::Application.paths['app/views']) - reduce_template = reduce_template.render(:template => "queries/builder/_reduce_function.js.erb", locals: { :query_structure => self.query_structure }) + reduce_template = reduce_template.render(:template => "queries/builder/_reduce_function", :handlers => [:erb], :formats => [:js], locals: { :query_structure => self.query_structure }) self.reduce = prettify_generated_function(reduce_template) end end From b865c419b000f3681fc53848116fd911c33f51f0 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Sun, 23 Jun 2013 22:08:08 -0700 Subject: [PATCH 012/117] Workaround for removal of QME::Importer::CodeSystemHelper after tag v1.0.4 --- app/helpers/code_system_helper.rb | 40 ++++++++++++++++++++++++++++++ app/views/code_sets/_form.html.erb | 2 +- 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 app/helpers/code_system_helper.rb diff --git a/app/helpers/code_system_helper.rb b/app/helpers/code_system_helper.rb new file mode 100644 index 0000000..04032ba --- /dev/null +++ b/app/helpers/code_system_helper.rb @@ -0,0 +1,40 @@ +module CodeSystemHelper + # General helpers for working with codes and code systems + class CodeSysHelper + CODE_SYSTEMS = { + '2.16.840.1.113883.6.1' => 'LOINC', + '2.16.840.1.113883.6.96' => 'SNOMED-CT', + '2.16.840.1.113883.6.12' => 'CPT', + #'2.16.840.1.113883.3.88.12.80.32' => 'CPT', + '2.16.840.1.113883.6.88' => 'RxNorm', + '2.16.840.1.113883.6.103' => 'ICD-9-CM', + '2.16.840.1.113883.6.104' => 'ICD-9-CM', + '2.16.840.1.113883.6.90' => 'ICD-10-CM', + '2.16.840.1.113883.6.14' => 'HCPCS', + '2.16.840.1.113883.6.59' => 'CVX', + '2.16.840.1.113883.6.238' => 'CDC-RE' + } + + # Returns the name of a code system given an oid + # @param [String] oid of a code system + # @return [String] the name of the code system as described in the measure definition JSON + def self.code_system_for(oid) + CODE_SYSTEMS[oid] || "Unknown" + end + + # Returns the oid for a code system given a codesystem name + # @param [String] the name of the code system + # @return [String] the oid of the code system + def self.oid_for_code_system(code_system) + CODE_SYSTEMS.invert[code_system] + end + + # Returns the whole map of OIDs to code systems + # @terurn [Hash] oids as keys, code system names as values + def self.code_systems + CODE_SYSTEMS + end + end + + +end \ No newline at end of file diff --git a/app/views/code_sets/_form.html.erb b/app/views/code_sets/_form.html.erb index a6dfb62..967576d 100644 --- a/app/views/code_sets/_form.html.erb +++ b/app/views/code_sets/_form.html.erb @@ -27,7 +27,7 @@ - <% code_set_list = [ "" ] + QME::Importer::CodeSystemHelper.code_systems.values.uniq %> + <% code_set_list = [ "" ] + CodeSystemHelper::CodeSysHelper.code_systems.values.uniq %> Codes From 5896cfdec0771ba6851024b0e132e3efa1498f7e Mon Sep 17 00:00:00 2001 From: drusk Date: Sun, 23 Jun 2013 21:41:24 -0700 Subject: [PATCH 013/117] Updated map_reduce to new syntax, and using raw strings in the ERB file which generates the mapreduce Javascript code in order to avoid HTML encoding issues. --- app/models/execution.rb | 6 +++--- app/views/queries/builder/_reduce_function.js.erb | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/models/execution.rb b/app/models/execution.rb index 141079f..1013ac8 100755 --- a/app/models/execution.rb +++ b/app/models/execution.rb @@ -47,8 +47,8 @@ def cancel # = Aggregation = # =============== def aggregate - - response = Result.collection.map_reduce(self.map_fn(), _reduce(), :raw => true, :out => {:inline => true}, :query => {:execution_id => id}) + #response = Result.collection.map_reduce(self.map_fn(), _reduce(), :raw => true, :out => {:inline => true}, :query => {:execution_id => id}) + response = Result.where(execution_id: id).map_reduce(self.map_fn(), _reduce()).out(inline: true).raw() results = response['results'] if results self.aggregate_result = {} @@ -101,7 +101,7 @@ def prettify_generated_result(result) pretty_key = "Results" if pretty_key.empty? pretty_result['_id'] = pretty_key pretty_result['value'] = pretty_values - + return pretty_result end diff --git a/app/views/queries/builder/_reduce_function.js.erb b/app/views/queries/builder/_reduce_function.js.erb index 23a213b..b33d9f7 100644 --- a/app/views/queries/builder/_reduce_function.js.erb +++ b/app/views/queries/builder/_reduce_function.js.erb @@ -36,12 +36,12 @@ function reduce(key, values) { end initial_values = '' if (selections.length > 0) - initial_values = selections.join(",\n") + initial_values = selections.join(',\n') end %> - + result = new reducer.Value( { - <%= initial_values %> + <%= raw initial_values %> }, rereduced = false ); @@ -60,7 +60,7 @@ function reduce(key, values) { end aggregation = aggregates.join("\n") %> - <%= aggregation %> + <%= raw aggregation %> result.rereduced = true; _val.rereduced = true; From 47801334ab6d737fb0f27936e8216beffc58bbcc Mon Sep 17 00:00:00 2001 From: drusk Date: Sun, 23 Jun 2013 21:52:28 -0700 Subject: [PATCH 014/117] Updated Query existence check to new API syntax. --- test/functional/queries_controller_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functional/queries_controller_test.rb b/test/functional/queries_controller_test.rb index a9c00d9..0aa541d 100755 --- a/test/functional/queries_controller_test.rb +++ b/test/functional/queries_controller_test.rb @@ -125,7 +125,7 @@ class QueriesControllerTest < ActionController::TestCase delete :destroy, id: @ids[0] query = assigns(:query) assert_equal @ids[0], query.id - assert (not Query.exists? :conditions => {id: @ids[0]}) + assert (not Query.where(id: @ids[0]).exists?) assert_redirected_to(queries_url) end From d7eb60b411c18d88130116ea94fc29e42cd69781 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Mon, 24 Jun 2013 11:54:58 -0700 Subject: [PATCH 015/117] Fix deprecated code --- app/views/code_sets/edit.html.erb | 2 +- app/views/code_sets/index.html.erb | 2 +- app/views/code_sets/index2.html.erb | 2 +- app/views/code_sets/new.html.erb | 2 +- lib/tasks/cover_me.rake | 5 +++-- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/app/views/code_sets/edit.html.erb b/app/views/code_sets/edit.html.erb index fd4bd15..c2f43ca 100644 --- a/app/views/code_sets/edit.html.erb +++ b/app/views/code_sets/edit.html.erb @@ -8,7 +8,7 @@

    -<%= render :partial=>"code_sets/form.html" %> +<%= render :partial=>"code_sets/form", formats => [:html] %>
    diff --git a/app/views/code_sets/index.html.erb b/app/views/code_sets/index.html.erb index 1a48deb..8bde2b2 100644 --- a/app/views/code_sets/index.html.erb +++ b/app/views/code_sets/index.html.erb @@ -15,7 +15,7 @@

    Type

    Coded Concepts

    -<%= render :partial=> "code_sets/entry.html" %> +<%= render :partial=> "code_sets/entry", formats => [:html] %>
    diff --git a/app/views/code_sets/index2.html.erb b/app/views/code_sets/index2.html.erb index 0313fdf..4a2fca5 100644 --- a/app/views/code_sets/index2.html.erb +++ b/app/views/code_sets/index2.html.erb @@ -16,7 +16,7 @@ - <%= render :partial=> "code_sets/entry2.html", :collection => @code_sets %> + <%= render :partial=> "code_sets/entry2", :formats => [:html], :collection => @code_sets %>
    diff --git a/app/views/code_sets/new.html.erb b/app/views/code_sets/new.html.erb index fd4bd15..c2f43ca 100644 --- a/app/views/code_sets/new.html.erb +++ b/app/views/code_sets/new.html.erb @@ -8,7 +8,7 @@
    -<%= render :partial=>"code_sets/form.html" %> +<%= render :partial=>"code_sets/form", formats => [:html] %>
    diff --git a/lib/tasks/cover_me.rake b/lib/tasks/cover_me.rake index 31856cf..e73ae71 100755 --- a/lib/tasks/cover_me.rake +++ b/lib/tasks/cover_me.rake @@ -1,10 +1,11 @@ namespace :cover_me do - + + desc "Generates and opens code coverage report." task :report do require 'cover_me' CoverMe.complete! end - + end task :test do From 96ef12ed2d8e79e98e47ed6b3f18495c5d3d083d Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Mon, 24 Jun 2013 13:19:51 -0700 Subject: [PATCH 016/117] Made user trackable --- app/models/user.rb | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index 2a5ac96..57c69bf 100755 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -17,7 +17,7 @@ class User field :email, type: String field :company, type: String field :company_url, type: String - field :encrypted_password, :type => String, :default => "" + field :encrypted_password, :type => String field :agree_license, type: Boolean @@ -35,7 +35,15 @@ class User validates :email, presence: true, length: {minimum: 3, maximum: 254}, format: {with: /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i} validates :username, :presence => true, length: {minimum: 3, maximum: 254} - validates_presence_of :encrypted_password + #validates_presence_of :encrypted_password + + # Trackable + field :current_sign_in_at, :type => Time + field :remember_created_at, :type => Time + field :last_sign_in_at, :type => Time + field :current_sign_in_ip, :type => String + field :last_sign_in_ip, :type => String + field :sign_in_count, :type => Integer def active_for_authentication? super && approved? && !disabled? From 32bc4c3d001e05d52c5de97bee2097a04534d744 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Mon, 24 Jun 2013 14:26:10 -0700 Subject: [PATCH 017/117] Fixed couple of failures due to typo in completed_execution_for_generated_query factory --- test/factories/factory.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/test/factories/factory.rb b/test/factories/factory.rb index e57a57b..db273ad 100755 --- a/test/factories/factory.rb +++ b/test/factories/factory.rb @@ -230,6 +230,7 @@ FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl.create(:endpoint), :execution => ex) FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl.create(:endpoint), :execution => ex) FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl.create(:endpoint), :execution => ex) + FactoryGirl.create(:result_with_value_from_generated_query, :endpoint => FactoryGirl.create(:endpoint), :execution => ex) end end end From 23d48247410900ec790957bf854d01e4f67f9f34 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Mon, 24 Jun 2013 16:26:41 -0700 Subject: [PATCH 018/117] Minor update --- app/models/user.rb | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index 57c69bf..dcb473f 100755 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -45,6 +45,13 @@ class User field :last_sign_in_ip, :type => String field :sign_in_count, :type => Integer + :remember_created_at + :sign_in_count + :current_sign_in_at + :last_sign_in_at + :current_sign_in_ip + :last_sign_in_ip + def active_for_authentication? super && approved? && !disabled? end @@ -54,10 +61,10 @@ def active_for_authentication? # ========== def self.find_by_username(username) - User.where(username: username).first + where(username: username).first end def self.find_by_email(email) - User.where(email: email).first + where(email: email).first end # ============= From b5f8f987a3344029c3134eb2eb7f49156bb1528d Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Mon, 24 Jun 2013 20:18:47 -0700 Subject: [PATCH 019/117] Removed some code that created test errors that I had added earlier --- app/models/user.rb | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index dcb473f..82b7c9b 100755 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -4,10 +4,6 @@ class User # :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :authentication_keys => [:username] - # Setup accessible (or protected) attributes for your model - attr_accessible :email, :password, :password_confirmation, :remember_me - # attr_accessible :title, :body - has_many :queries has_many :library_functions @@ -35,7 +31,6 @@ class User validates :email, presence: true, length: {minimum: 3, maximum: 254}, format: {with: /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i} validates :username, :presence => true, length: {minimum: 3, maximum: 254} - #validates_presence_of :encrypted_password # Trackable field :current_sign_in_at, :type => Time From ec37ccd93c77b8a5799ff8d425fd443e8e4ada71 Mon Sep 17 00:00:00 2001 From: drusk Date: Mon, 24 Jun 2013 21:46:32 -0700 Subject: [PATCH 020/117] Commented out assertions which no longer seem to hold with Mongoid version 3.0 due to the added _type field being persisted to the database. --- test/functional/template_queries_controller_test.rb | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/test/functional/template_queries_controller_test.rb b/test/functional/template_queries_controller_test.rb index a7b113f..da29376 100644 --- a/test/functional/template_queries_controller_test.rb +++ b/test/functional/template_queries_controller_test.rb @@ -18,7 +18,11 @@ class TemplateQueriesControllerTest < ActionController::TestCase get :index assert_response :success assert_not_nil assigns(:template_queries) - assert_equal TemplateQuery.all, assigns(:template_queries) + + # TODO This fails because the _type field is added to the database by + # default starting in Mongoid 3.0 (it wasn't previously) + # See https://github.com/mongoid/mongoid/issues/936 + #assert_equal TemplateQuery.all, assigns(:template_queries) end test "should get index as admin" do @@ -26,7 +30,11 @@ class TemplateQueriesControllerTest < ActionController::TestCase get :index assert_response :success assert_not_nil assigns(:template_queries) - assert_equal TemplateQuery.all, assigns(:template_queries) + + # TODO This fails because the _type field is added to the database by + # default starting in Mongoid 3.0 (it wasn't previously) + # See https://github.com/mongoid/mongoid/issues/936 + #assert_equal TemplateQuery.all, assigns(:template_queries) end test "should get new" do From 7497593f0b88af9ddd65bfd958a37a1720ff503c Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Thu, 27 Jun 2013 14:51:57 -0700 Subject: [PATCH 021/117] Removed dependency on quality-measure-engine --- Gemfile | 2 +- runme.sh | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 runme.sh diff --git a/Gemfile b/Gemfile index f165fb3..ca80e04 100755 --- a/Gemfile +++ b/Gemfile @@ -32,7 +32,7 @@ gem 'kramdown' gem 'jasmine', :group => [:development, :test] gem 'headless', :group => [:development, :test] gem 'coderay' -gem 'quality-measure-engine', :git => 'http://github.com/pophealth/quality-measure-engine.git' #, :branch => 'develop' +#gem 'quality-measure-engine', :git => 'http://github.com/pophealth/quality-measure-engine.git' #, :branch => 'develop' diff --git a/runme.sh b/runme.sh new file mode 100644 index 0000000..04ff4a8 --- /dev/null +++ b/runme.sh @@ -0,0 +1,28 @@ +#!/bin/sh +# To start query-composer +bundle install +bundle exec script/delayed_job start +bundle exec rails server +# +# To start query-gateway +# In a second terminal, change directory to the query-gateway directory +# and run: +# +# bundle install +# bundle exec rake db:seed +# bundle exec script/delayed_job start +# bundle exec rails server -p 3001 +# +#In a browser open the URL: http://localhost:3000/queries/ +# +# Adding a User Account (one time operation) +# +# When the web application opens, you should be presented with a login page. +# You should see a sign up Link, click it. +# Fill out the form to create a user. +# Next you need to approve the user and set the user as an admin +# In the root of the query-composer project run the command: +## +# bundle exec rake hquery:users:grant_admin USER_ID= +# +# where is replaced with the username for the user you just created. From 6412ecd44ce9ed4610a8c48e1e2ed05ad0ca1a9c Mon Sep 17 00:00:00 2001 From: drusk Date: Fri, 28 Jun 2013 22:10:54 -0700 Subject: [PATCH 022/117] Setting jquery-rails gem version to 1.0.19 because it is known to work. The most recent version is causing Javascript errors to occur, maybe because of incompatability with the older version of jquery-ui being used. --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index ca80e04..d5fc144 100755 --- a/Gemfile +++ b/Gemfile @@ -13,7 +13,7 @@ group :assets do gem 'uglifier' end -gem 'jquery-rails' +gem 'jquery-rails', '=1.0.19' gem 'sprockets' #gem 'bson_ext', :platforms => :mri gem 'daemons' From 5a18d1b9928f674d36aa136b224b51c04d337dfd Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Tue, 2 Jul 2013 09:23:58 -0700 Subject: [PATCH 023/117] Updated documentation for Ruby 1.9.3 build --- README.md | 21 +++++++++++---------- app/helpers/code_system_helper.rb | 4 ++++ runme.sh | 2 +- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index d76b432..287f020 100755 --- a/README.md +++ b/README.md @@ -14,9 +14,10 @@ hQuery will also run on Windows, however, there are some minor limitations to fu Dependencies ------------ -* Ruby = 1.9.2 -* Rails 3.1 -* MongoDB >= 1.8.1 +* Ruby = 1.9.3 +* Rails 3.2.13 +* MongoDB >= 2.4.1 +* jquery-rails 1.0.19 and jQuery UI 1.8.16 Install Instructions -------------------- @@ -48,7 +49,7 @@ Install Instructions ###Common setup requirements for OSX and LINUX - install ruby 1.9.2 or later + install ruby 1.9.3 or later install bundler 1.0.14 or later @@ -65,8 +66,8 @@ First you will need to install XCode see: [http://developer.apple.com/technologi Open a terminal and run bash < <(curl -s https://rvm.beginrescueend.com/install/rvm) - rvm install 1.9.2 - rvm use 1.9.2 + rvm install 1.9.3 + rvm use 1.9.3 ####LINUX @@ -76,8 +77,8 @@ Open a terminal and run apt-get install build-essential curl file zlib1g-dev libreadline5-dev libxml2-dev libsqlite3-dev gem install rvm /var/lib/gems/1.8/bin/rvm-install - rvm install 1.9.2 - rvm use 1.9.2 + rvm install 1.9.3 + rvm use 1.9.3 ###Getting Ruby Directly Ruby can also be installed directly from the following without the use of RVM. @@ -96,8 +97,8 @@ Open a terminal and run [http://railsinstaller.org/](http://railsinstaller.org/) - Packages included in version 2.0.0 are: - Ruby 1.9.2-p290 + Packages included are (outdated information): + Ruby 1.9.2 Rails 3.1 Bundler 1.0.18 Git 1.7.6 diff --git a/app/helpers/code_system_helper.rb b/app/helpers/code_system_helper.rb index 04032ba..eb53eec 100644 --- a/app/helpers/code_system_helper.rb +++ b/app/helpers/code_system_helper.rb @@ -1,5 +1,9 @@ module CodeSystemHelper # General helpers for working with codes and code systems + # Based on abandoned code from quality-measure-engine (1.0.4) + # http://github.com/pophealth/quality-measure-engine.git + # revision: 6573859d0d8ca8d76e6dc2f0d4d15181c8457c61 + # branch: develop class CodeSysHelper CODE_SYSTEMS = { '2.16.840.1.113883.6.1' => 'LOINC', diff --git a/runme.sh b/runme.sh index 04ff4a8..2c87b29 100644 --- a/runme.sh +++ b/runme.sh @@ -2,7 +2,7 @@ # To start query-composer bundle install bundle exec script/delayed_job start -bundle exec rails server +bundle exec rails server -p 3002 # # To start query-gateway # In a second terminal, change directory to the query-gateway directory From b18d28eaa1be074c60b2bfd55afa792142e26ad4 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Tue, 2 Jul 2013 09:28:07 -0700 Subject: [PATCH 024/117] Documented gems to be updated in future iterations --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 287f020..eda828f 100755 --- a/README.md +++ b/README.md @@ -17,7 +17,11 @@ Dependencies * Ruby = 1.9.3 * Rails 3.2.13 * MongoDB >= 2.4.1 + +Dependencies on old gems (to be remedied in future) +--------------------------------------------------- * jquery-rails 1.0.19 and jQuery UI 1.8.16 +* minitest < 5.0.0 Install Instructions -------------------- From aab3484ca258f557b35a2a40691f1a7d1d264caa Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Tue, 2 Jul 2013 10:56:25 -0700 Subject: [PATCH 025/117] Updated patient API documentation to current version --- public/patientapi/files.html | 2 +- public/patientapi/index.html | 2 +- public/patientapi/symbols/__hasProp.html | 2 +- public/patientapi/symbols/_global_.html | 2 +- public/patientapi/symbols/hQuery.Actor.html | 2 +- public/patientapi/symbols/hQuery.Address.html | 2 +- public/patientapi/symbols/hQuery.AdministrationTiming.html | 2 +- public/patientapi/symbols/hQuery.Allergy.html | 2 +- public/patientapi/symbols/hQuery.CauseOfDeath.html | 2 +- public/patientapi/symbols/hQuery.CodedEntry.html | 2 +- public/patientapi/symbols/hQuery.CodedEntryList.html | 2 +- public/patientapi/symbols/hQuery.CodedValue.html | 2 +- public/patientapi/symbols/hQuery.Condition.html | 2 +- public/patientapi/symbols/hQuery.DateRange.html | 2 +- public/patientapi/symbols/hQuery.DoseRestriction.html | 2 +- public/patientapi/symbols/hQuery.Encounter.html | 2 +- public/patientapi/symbols/hQuery.Facility.html | 2 +- public/patientapi/symbols/hQuery.Fulfillment.html | 2 +- public/patientapi/symbols/hQuery.FunctionalStatus.html | 2 +- public/patientapi/symbols/hQuery.Immunization.html | 2 +- public/patientapi/symbols/hQuery.Informant.html | 2 +- public/patientapi/symbols/hQuery.Language.html | 2 +- public/patientapi/symbols/hQuery.Medication.html | 2 +- public/patientapi/symbols/hQuery.MedicationInformation.html | 2 +- public/patientapi/symbols/hQuery.NoImmunization.html | 2 +- public/patientapi/symbols/hQuery.OrderInformation.html | 2 +- public/patientapi/symbols/hQuery.Organization.html | 2 +- public/patientapi/symbols/hQuery.Patient.html | 2 +- public/patientapi/symbols/hQuery.Person.html | 2 +- public/patientapi/symbols/hQuery.PhysicalQuantity.html | 2 +- public/patientapi/symbols/hQuery.Pregnancy.html | 2 +- public/patientapi/symbols/hQuery.Procedure.html | 2 +- public/patientapi/symbols/hQuery.Provider.html | 2 +- public/patientapi/symbols/hQuery.Result.html | 2 +- public/patientapi/symbols/hQuery.Scalar.html | 2 +- public/patientapi/symbols/hQuery.Status.html | 2 +- public/patientapi/symbols/hQuery.StatusOfMedication.html | 2 +- public/patientapi/symbols/hQuery.Supports.html | 2 +- public/patientapi/symbols/hQuery.Telecom.html | 2 +- public/patientapi/symbols/hQuery.TypeOfMedication.html | 2 +- 40 files changed, 40 insertions(+), 40 deletions(-) diff --git a/public/patientapi/files.html b/public/patientapi/files.html index 4c0a18c..8c4d586 100644 --- a/public/patientapi/files.html +++ b/public/patientapi/files.html @@ -284,7 +284,7 @@

    tmp/patient.js

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:47 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT)
    \ No newline at end of file diff --git a/public/patientapi/index.html b/public/patientapi/index.html index a055550..d9d78d6 100644 --- a/public/patientapi/index.html +++ b/public/patientapi/index.html @@ -504,7 +504,7 @@

    hQuery.TypeOfMedication
    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:47 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT)
    \ No newline at end of file diff --git a/public/patientapi/symbols/__hasProp.html b/public/patientapi/symbols/__hasProp.html index e7bfd7f..0ff1b24 100644 --- a/public/patientapi/symbols/__hasProp.html +++ b/public/patientapi/symbols/__hasProp.html @@ -367,7 +367,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/_global_.html b/public/patientapi/symbols/_global_.html index 5d3bf4c..5d01a6e 100644 --- a/public/patientapi/symbols/_global_.html +++ b/public/patientapi/symbols/_global_.html @@ -394,7 +394,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Actor.html b/public/patientapi/symbols/hQuery.Actor.html index ffc00a9..18f6ac6 100644 --- a/public/patientapi/symbols/hQuery.Actor.html +++ b/public/patientapi/symbols/hQuery.Actor.html @@ -503,7 +503,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Address.html b/public/patientapi/symbols/hQuery.Address.html index 21c9dd0..968da24 100644 --- a/public/patientapi/symbols/hQuery.Address.html +++ b/public/patientapi/symbols/hQuery.Address.html @@ -599,7 +599,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.AdministrationTiming.html b/public/patientapi/symbols/hQuery.AdministrationTiming.html index 62f2fee..c0319e0 100644 --- a/public/patientapi/symbols/hQuery.AdministrationTiming.html +++ b/public/patientapi/symbols/hQuery.AdministrationTiming.html @@ -523,7 +523,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Allergy.html b/public/patientapi/symbols/hQuery.Allergy.html index 3f809c7..36b670e 100644 --- a/public/patientapi/symbols/hQuery.Allergy.html +++ b/public/patientapi/symbols/hQuery.Allergy.html @@ -722,7 +722,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.CauseOfDeath.html b/public/patientapi/symbols/hQuery.CauseOfDeath.html index 6853149..2d1afb5 100644 --- a/public/patientapi/symbols/hQuery.CauseOfDeath.html +++ b/public/patientapi/symbols/hQuery.CauseOfDeath.html @@ -517,7 +517,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.CodedEntry.html b/public/patientapi/symbols/hQuery.CodedEntry.html index a279fdd..2ee03a7 100644 --- a/public/patientapi/symbols/hQuery.CodedEntry.html +++ b/public/patientapi/symbols/hQuery.CodedEntry.html @@ -1024,7 +1024,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.CodedEntryList.html b/public/patientapi/symbols/hQuery.CodedEntryList.html index 47d6f22..e1dc023 100644 --- a/public/patientapi/symbols/hQuery.CodedEntryList.html +++ b/public/patientapi/symbols/hQuery.CodedEntryList.html @@ -756,7 +756,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.CodedValue.html b/public/patientapi/symbols/hQuery.CodedValue.html index 4dbfbbd..28da773 100644 --- a/public/patientapi/symbols/hQuery.CodedValue.html +++ b/public/patientapi/symbols/hQuery.CodedValue.html @@ -575,7 +575,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Condition.html b/public/patientapi/symbols/hQuery.Condition.html index 51c435a..15ccab1 100644 --- a/public/patientapi/symbols/hQuery.Condition.html +++ b/public/patientapi/symbols/hQuery.Condition.html @@ -784,7 +784,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.DateRange.html b/public/patientapi/symbols/hQuery.DateRange.html index 5758f4e..a4e2ef0 100644 --- a/public/patientapi/symbols/hQuery.DateRange.html +++ b/public/patientapi/symbols/hQuery.DateRange.html @@ -503,7 +503,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.DoseRestriction.html b/public/patientapi/symbols/hQuery.DoseRestriction.html index 2d68949..e4ef970 100644 --- a/public/patientapi/symbols/hQuery.DoseRestriction.html +++ b/public/patientapi/symbols/hQuery.DoseRestriction.html @@ -503,7 +503,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Encounter.html b/public/patientapi/symbols/hQuery.Encounter.html index 080846d..24ba69f 100644 --- a/public/patientapi/symbols/hQuery.Encounter.html +++ b/public/patientapi/symbols/hQuery.Encounter.html @@ -707,7 +707,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Facility.html b/public/patientapi/symbols/hQuery.Facility.html index ada724e..f0a6d45 100644 --- a/public/patientapi/symbols/hQuery.Facility.html +++ b/public/patientapi/symbols/hQuery.Facility.html @@ -446,7 +446,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Fulfillment.html b/public/patientapi/symbols/hQuery.Fulfillment.html index d00cffb..bb440b7 100644 --- a/public/patientapi/symbols/hQuery.Fulfillment.html +++ b/public/patientapi/symbols/hQuery.Fulfillment.html @@ -435,7 +435,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.FunctionalStatus.html b/public/patientapi/symbols/hQuery.FunctionalStatus.html index b2dba3b..b232cb8 100644 --- a/public/patientapi/symbols/hQuery.FunctionalStatus.html +++ b/public/patientapi/symbols/hQuery.FunctionalStatus.html @@ -552,7 +552,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Immunization.html b/public/patientapi/symbols/hQuery.Immunization.html index 9287337..52549a7 100644 --- a/public/patientapi/symbols/hQuery.Immunization.html +++ b/public/patientapi/symbols/hQuery.Immunization.html @@ -715,7 +715,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Informant.html b/public/patientapi/symbols/hQuery.Informant.html index 3b96635..a3b338b 100644 --- a/public/patientapi/symbols/hQuery.Informant.html +++ b/public/patientapi/symbols/hQuery.Informant.html @@ -518,7 +518,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Language.html b/public/patientapi/symbols/hQuery.Language.html index 682fab0..662a59e 100644 --- a/public/patientapi/symbols/hQuery.Language.html +++ b/public/patientapi/symbols/hQuery.Language.html @@ -534,7 +534,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Medication.html b/public/patientapi/symbols/hQuery.Medication.html index ff19ecf..bf085c6 100644 --- a/public/patientapi/symbols/hQuery.Medication.html +++ b/public/patientapi/symbols/hQuery.Medication.html @@ -1358,7 +1358,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.MedicationInformation.html b/public/patientapi/symbols/hQuery.MedicationInformation.html index 30d7f33..937e4e9 100644 --- a/public/patientapi/symbols/hQuery.MedicationInformation.html +++ b/public/patientapi/symbols/hQuery.MedicationInformation.html @@ -612,7 +612,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.NoImmunization.html b/public/patientapi/symbols/hQuery.NoImmunization.html index e56d48b..f1f109b 100644 --- a/public/patientapi/symbols/hQuery.NoImmunization.html +++ b/public/patientapi/symbols/hQuery.NoImmunization.html @@ -773,7 +773,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.OrderInformation.html b/public/patientapi/symbols/hQuery.OrderInformation.html index 5f30f99..a71cb14 100644 --- a/public/patientapi/symbols/hQuery.OrderInformation.html +++ b/public/patientapi/symbols/hQuery.OrderInformation.html @@ -605,7 +605,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Organization.html b/public/patientapi/symbols/hQuery.Organization.html index c49aba3..b5e297c 100644 --- a/public/patientapi/symbols/hQuery.Organization.html +++ b/public/patientapi/symbols/hQuery.Organization.html @@ -599,7 +599,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Patient.html b/public/patientapi/symbols/hQuery.Patient.html index 2de57e3..0ae3d7b 100644 --- a/public/patientapi/symbols/hQuery.Patient.html +++ b/public/patientapi/symbols/hQuery.Patient.html @@ -1615,7 +1615,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Person.html b/public/patientapi/symbols/hQuery.Person.html index 9ff67c0..9657563 100644 --- a/public/patientapi/symbols/hQuery.Person.html +++ b/public/patientapi/symbols/hQuery.Person.html @@ -640,7 +640,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.PhysicalQuantity.html b/public/patientapi/symbols/hQuery.PhysicalQuantity.html index d133536..2467f10 100644 --- a/public/patientapi/symbols/hQuery.PhysicalQuantity.html +++ b/public/patientapi/symbols/hQuery.PhysicalQuantity.html @@ -503,7 +503,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Pregnancy.html b/public/patientapi/symbols/hQuery.Pregnancy.html index 7186503..1958241 100644 --- a/public/patientapi/symbols/hQuery.Pregnancy.html +++ b/public/patientapi/symbols/hQuery.Pregnancy.html @@ -495,7 +495,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:46 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Procedure.html b/public/patientapi/symbols/hQuery.Procedure.html index 62c82aa..c68ecb9 100644 --- a/public/patientapi/symbols/hQuery.Procedure.html +++ b/public/patientapi/symbols/hQuery.Procedure.html @@ -537,7 +537,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:47 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Provider.html b/public/patientapi/symbols/hQuery.Provider.html index 410988f..4cf2331 100644 --- a/public/patientapi/symbols/hQuery.Provider.html +++ b/public/patientapi/symbols/hQuery.Provider.html @@ -722,7 +722,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:47 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Result.html b/public/patientapi/symbols/hQuery.Result.html index 14bebd3..e0458d0 100644 --- a/public/patientapi/symbols/hQuery.Result.html +++ b/public/patientapi/symbols/hQuery.Result.html @@ -623,7 +623,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:47 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Scalar.html b/public/patientapi/symbols/hQuery.Scalar.html index 7effc23..2a486f9 100644 --- a/public/patientapi/symbols/hQuery.Scalar.html +++ b/public/patientapi/symbols/hQuery.Scalar.html @@ -503,7 +503,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:47 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Status.html b/public/patientapi/symbols/hQuery.Status.html index 5d84a27..622dd53 100644 --- a/public/patientapi/symbols/hQuery.Status.html +++ b/public/patientapi/symbols/hQuery.Status.html @@ -783,7 +783,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:47 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.StatusOfMedication.html b/public/patientapi/symbols/hQuery.StatusOfMedication.html index 370d17f..f5130ea 100644 --- a/public/patientapi/symbols/hQuery.StatusOfMedication.html +++ b/public/patientapi/symbols/hQuery.StatusOfMedication.html @@ -607,7 +607,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:47 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Supports.html b/public/patientapi/symbols/hQuery.Supports.html index ffc4891..c05b935 100644 --- a/public/patientapi/symbols/hQuery.Supports.html +++ b/public/patientapi/symbols/hQuery.Supports.html @@ -640,7 +640,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:47 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Telecom.html b/public/patientapi/symbols/hQuery.Telecom.html index 99f2c3e..abc27ee 100644 --- a/public/patientapi/symbols/hQuery.Telecom.html +++ b/public/patientapi/symbols/hQuery.Telecom.html @@ -600,7 +600,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:47 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.TypeOfMedication.html b/public/patientapi/symbols/hQuery.TypeOfMedication.html index 0207a2c..919d7f5 100644 --- a/public/patientapi/symbols/hQuery.TypeOfMedication.html +++ b/public/patientapi/symbols/hQuery.TypeOfMedication.html @@ -528,7 +528,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Thu Jun 13 2013 11:35:47 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT)
    From 9eb43fccc0d935c8367d9678be26aa7e537aa62c Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Tue, 2 Jul 2013 14:37:35 -0700 Subject: [PATCH 026/117] Now tracking our version of pophealth patientapi --- Gemfile | 3 +- public/patientapi/files.html | 2 +- public/patientapi/index.html | 2 +- public/patientapi/symbols/__hasProp.html | 2 +- public/patientapi/symbols/_global_.html | 2 +- public/patientapi/symbols/hQuery.Actor.html | 2 +- public/patientapi/symbols/hQuery.Address.html | 2 +- .../symbols/hQuery.AdministrationTiming.html | 2 +- public/patientapi/symbols/hQuery.Allergy.html | 4 +- .../symbols/hQuery.CauseOfDeath.html | 2 +- .../patientapi/symbols/hQuery.CodedEntry.html | 88 +- .../symbols/hQuery.CodedEntryList.html | 2 +- .../patientapi/symbols/hQuery.CodedValue.html | 47 +- .../patientapi/symbols/hQuery.Condition.html | 8 +- .../patientapi/symbols/hQuery.DateRange.html | 2 +- .../symbols/hQuery.DoseRestriction.html | 2 +- .../patientapi/symbols/hQuery.Encounter.html | 266 +- .../patientapi/symbols/hQuery.Facility.html | 2 +- .../symbols/hQuery.Fulfillment.html | 2 +- .../symbols/hQuery.FunctionalStatus.html | 4 +- .../symbols/hQuery.Immunization.html | 4 +- .../patientapi/symbols/hQuery.Informant.html | 2 +- .../patientapi/symbols/hQuery.Language.html | 4 +- .../patientapi/symbols/hQuery.Medication.html | 4 +- .../symbols/hQuery.MedicationInformation.html | 2 +- .../symbols/hQuery.NoImmunization.html | 4 +- .../symbols/hQuery.OrderInformation.html | 2 +- .../symbols/hQuery.Organization.html | 2 +- public/patientapi/symbols/hQuery.Patient.html | 4 +- public/patientapi/symbols/hQuery.Person.html | 2 +- .../symbols/hQuery.PhysicalQuantity.html | 2 +- .../patientapi/symbols/hQuery.Pregnancy.html | 4 +- .../patientapi/symbols/hQuery.Procedure.html | 127 +- .../patientapi/symbols/hQuery.Provider.html | 2 +- public/patientapi/symbols/hQuery.Result.html | 4 +- public/patientapi/symbols/hQuery.Scalar.html | 2 +- public/patientapi/symbols/hQuery.Status.html | 4 +- .../symbols/hQuery.StatusOfMedication.html | 4 +- .../patientapi/symbols/hQuery.Supports.html | 2 +- public/patientapi/symbols/hQuery.Telecom.html | 2 +- .../symbols/hQuery.TypeOfMedication.html | 4 +- .../symbols/src/tmp_patient.js.html | 5667 +++++++++-------- 42 files changed, 3498 insertions(+), 2802 deletions(-) diff --git a/Gemfile b/Gemfile index d5fc144..4597bb2 100755 --- a/Gemfile +++ b/Gemfile @@ -24,7 +24,7 @@ gem 'simple_form' gem 'multipart-post' gem 'delayed_job' gem 'delayed_job_mongoid' #, :git => 'https://github.com/collectiveidea/delayed_job_mongoid.git' -gem 'hquery-patient-api', :git => 'http://github.com/scoophealth/patientapi.git' #, :tag => 'V0.2' +gem 'hquery-patient-api', :git => 'http://github.com/scoophealth/patientapi.git', :branch => 'scoop-develop' gem 'devise' gem 'cancan' gem 'pry' @@ -32,7 +32,6 @@ gem 'kramdown' gem 'jasmine', :group => [:development, :test] gem 'headless', :group => [:development, :test] gem 'coderay' -#gem 'quality-measure-engine', :git => 'http://github.com/pophealth/quality-measure-engine.git' #, :branch => 'develop' diff --git a/public/patientapi/files.html b/public/patientapi/files.html index 8c4d586..7343a7b 100644 --- a/public/patientapi/files.html +++ b/public/patientapi/files.html @@ -284,7 +284,7 @@

    tmp/patient.js

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:50 GMT-0700 (PDT)
    \ No newline at end of file diff --git a/public/patientapi/index.html b/public/patientapi/index.html index d9d78d6..99b4d2a 100644 --- a/public/patientapi/index.html +++ b/public/patientapi/index.html @@ -504,7 +504,7 @@

    hQuery.TypeOfMedication
    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:50 GMT-0700 (PDT)
    \ No newline at end of file diff --git a/public/patientapi/symbols/__hasProp.html b/public/patientapi/symbols/__hasProp.html index 0ff1b24..e4b7c2a 100644 --- a/public/patientapi/symbols/__hasProp.html +++ b/public/patientapi/symbols/__hasProp.html @@ -367,7 +367,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/_global_.html b/public/patientapi/symbols/_global_.html index 5d01a6e..99d6b25 100644 --- a/public/patientapi/symbols/_global_.html +++ b/public/patientapi/symbols/_global_.html @@ -394,7 +394,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Actor.html b/public/patientapi/symbols/hQuery.Actor.html index 18f6ac6..88c929f 100644 --- a/public/patientapi/symbols/hQuery.Actor.html +++ b/public/patientapi/symbols/hQuery.Actor.html @@ -503,7 +503,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Address.html b/public/patientapi/symbols/hQuery.Address.html index 968da24..77b86d1 100644 --- a/public/patientapi/symbols/hQuery.Address.html +++ b/public/patientapi/symbols/hQuery.Address.html @@ -599,7 +599,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.AdministrationTiming.html b/public/patientapi/symbols/hQuery.AdministrationTiming.html index c0319e0..9efe19a 100644 --- a/public/patientapi/symbols/hQuery.AdministrationTiming.html +++ b/public/patientapi/symbols/hQuery.AdministrationTiming.html @@ -523,7 +523,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Allergy.html b/public/patientapi/symbols/hQuery.Allergy.html index 36b670e..ce505a5 100644 --- a/public/patientapi/symbols/hQuery.Allergy.html +++ b/public/patientapi/symbols/hQuery.Allergy.html @@ -406,7 +406,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, startDate, status, statusCode, timeStamp, type, values
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    @@ -722,7 +722,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.CauseOfDeath.html b/public/patientapi/symbols/hQuery.CauseOfDeath.html index 2d1afb5..f7a0577 100644 --- a/public/patientapi/symbols/hQuery.CauseOfDeath.html +++ b/public/patientapi/symbols/hQuery.CauseOfDeath.html @@ -517,7 +517,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.CodedEntry.html b/public/patientapi/symbols/hQuery.CodedEntry.html index 2ee03a7..182f256 100644 --- a/public/patientapi/symbols/hQuery.CodedEntry.html +++ b/public/patientapi/symbols/hQuery.CodedEntry.html @@ -412,6 +412,24 @@

    + +   + +
    reason() +
    +
    Explains the reason for an entry.
    + + + + +   + +
    setTimestamp(timestamp) +
    +
    Adjust the start and end times of this event to the supplied timestamp
    + + +   @@ -816,6 +834,74 @@

    +
    + + +
    + + {hQuery.CodedValue} + reason() + +
    +
    + Explains the reason for an entry. + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {hQuery.CodedValue} Used to explain the rationale for a given entry.
    + +
    + + + + +
    + + +
    + + + setTimestamp(timestamp) + +
    +
    + Adjust the start and end times of this event to the supplied timestamp + + +
    + + + + +
    +
    Parameters:
    + +
    + timestamp + +
    +
    + +
    + + + + + + + +
    @@ -1024,7 +1110,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.CodedEntryList.html b/public/patientapi/symbols/hQuery.CodedEntryList.html index e1dc023..f5fdb99 100644 --- a/public/patientapi/symbols/hQuery.CodedEntryList.html +++ b/public/patientapi/symbols/hQuery.CodedEntryList.html @@ -756,7 +756,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.CodedValue.html b/public/patientapi/symbols/hQuery.CodedValue.html index 28da773..15b4ff8 100644 --- a/public/patientapi/symbols/hQuery.CodedValue.html +++ b/public/patientapi/symbols/hQuery.CodedValue.html @@ -366,6 +366,15 @@

    + + <static>   + +
    hQuery.CodedValue.normalize(val) +
    +
    + + + @@ -561,6 +570,42 @@

    +
    + + +
    <static> + + + hQuery.CodedValue.normalize(val) + +
    +
    + + + +
    + + + + +
    +
    Parameters:
    + +
    + val + +
    +
    + +
    + + + + + + + + @@ -575,7 +620,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Condition.html b/public/patientapi/symbols/hQuery.Condition.html index 15ccab1..40fe94c 100644 --- a/public/patientapi/symbols/hQuery.Condition.html +++ b/public/patientapi/symbols/hQuery.Condition.html @@ -423,7 +423,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, startDate, status, statusCode, timeStamp, type, values
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    @@ -647,7 +647,7 @@

    - {String} + {CodedValue} ordinality()
    @@ -667,7 +667,7 @@

    Returns:
    -
    {String}
    +
    {CodedValue}
    @@ -784,7 +784,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.DateRange.html b/public/patientapi/symbols/hQuery.DateRange.html index a4e2ef0..8900104 100644 --- a/public/patientapi/symbols/hQuery.DateRange.html +++ b/public/patientapi/symbols/hQuery.DateRange.html @@ -503,7 +503,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.DoseRestriction.html b/public/patientapi/symbols/hQuery.DoseRestriction.html index e4ef970..3140367 100644 --- a/public/patientapi/symbols/hQuery.DoseRestriction.html +++ b/public/patientapi/symbols/hQuery.DoseRestriction.html @@ -503,7 +503,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Encounter.html b/public/patientapi/symbols/hQuery.Encounter.html index 24ba69f..4ab1962 100644 --- a/public/patientapi/symbols/hQuery.Encounter.html +++ b/public/patientapi/symbols/hQuery.Encounter.html @@ -311,7 +311,7 @@

    An Encounter is an interaction, regardless of the setting, between a patient and a practitioner who is vested with primary responsibility for diagnosing, evaluating, -or treating the patient's condition.
    +or treating the patients condition.
    @@ -335,6 +335,15 @@

    + +   + + +
    Date and time at which the patient was admitted for the encounter
    + + +   @@ -347,12 +356,21 @@

      -
    dischargeDisp() +
    + +   + + +
    Date and time at which the patient was discharged for the encounter
    + + + <inner>   @@ -365,7 +383,7 @@

      -
    encounterDuration() +
    @@ -374,7 +392,25 @@

      -
    facility() + +
    + + + + +   + + +
    + + + + +   + +
    @@ -398,13 +434,31 @@

    + +   + + +
    + + + + +   + + +
    + + +
    -
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, startDate, status, statusCode, timeStamp, type, values
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    @@ -425,7 +479,7 @@

    An Encounter is an interaction, regardless of the setting, between a patient and a practitioner who is vested with primary responsibility for diagnosing, evaluating, -or treating the patient's condition. It may include visits, appointments, as well +or treating the patients condition. It may include visits, appointments, as well as non face-to-face interactions. It is also a contact between a patient and a practitioner who has primary responsibility for assessing and treating the patient at a given contact, exercising independent judgment. @@ -466,6 +520,38 @@

    Method Detail

    + +
    + + {Date} + admitTime() + +
    +
    + Date and time at which the patient was admitted for the encounter + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {Date}
    + +
    + + + + +
    +
    @@ -499,11 +585,11 @@


    - +
    {String} - dischargeDisp() + dischargeDisposition()
    @@ -529,6 +615,38 @@

    +
    + + +
    + + {Date} + dischargeTime() + +
    +
    + Date and time at which the patient was discharged for the encounter + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {Date}
    + +
    + + + +
    @@ -567,11 +685,11 @@


    - +
    - {hQuery.DateRange} - encounterDuration() + {hQuery.Organization} + facility()
    @@ -590,7 +708,7 @@

    Returns:
    -
    {hQuery.DateRange}
    +
    {hQuery.Organization}
    @@ -599,11 +717,61 @@


    - +
    - {hQuery.Organization} - facility() + + facilityArrival() + +
    +
    + + + +
    + + + + + + + + + + + +
    + + +
    + + + facilityDeparture() + +
    +
    + + + +
    + + + + + + + + + + + +
    + + +
    + + {Integer} + lengthOfStay()
    @@ -622,7 +790,7 @@

    Returns:
    -
    {hQuery.Organization}
    +
    {Integer}
    @@ -693,6 +861,70 @@

    +
    + + +
    + + {CodedValue} + transferFrom() + +
    +
    + + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {CodedValue}
    + +
    + + + + +
    + + +
    + + {CodedValue} + transferTo() + +
    +
    + + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {CodedValue}
    + +
    + + + + @@ -707,7 +939,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Facility.html b/public/patientapi/symbols/hQuery.Facility.html index f0a6d45..7ebc576 100644 --- a/public/patientapi/symbols/hQuery.Facility.html +++ b/public/patientapi/symbols/hQuery.Facility.html @@ -446,7 +446,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Fulfillment.html b/public/patientapi/symbols/hQuery.Fulfillment.html index bb440b7..b64e63e 100644 --- a/public/patientapi/symbols/hQuery.Fulfillment.html +++ b/public/patientapi/symbols/hQuery.Fulfillment.html @@ -435,7 +435,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.FunctionalStatus.html b/public/patientapi/symbols/hQuery.FunctionalStatus.html index b232cb8..d331f18 100644 --- a/public/patientapi/symbols/hQuery.FunctionalStatus.html +++ b/public/patientapi/symbols/hQuery.FunctionalStatus.html @@ -365,7 +365,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, startDate, status, statusCode, timeStamp, values
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, setTimestamp, startDate, status, statusCode, timeStamp, values
    @@ -552,7 +552,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:22 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Immunization.html b/public/patientapi/symbols/hQuery.Immunization.html index 52549a7..8b83982 100644 --- a/public/patientapi/symbols/hQuery.Immunization.html +++ b/public/patientapi/symbols/hQuery.Immunization.html @@ -412,7 +412,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, startDate, status, statusCode, timeStamp, type, values
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    @@ -715,7 +715,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Informant.html b/public/patientapi/symbols/hQuery.Informant.html index a3b338b..d8f1d2c 100644 --- a/public/patientapi/symbols/hQuery.Informant.html +++ b/public/patientapi/symbols/hQuery.Informant.html @@ -518,7 +518,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Language.html b/public/patientapi/symbols/hQuery.Language.html index 662a59e..3ca37ed 100644 --- a/public/patientapi/symbols/hQuery.Language.html +++ b/public/patientapi/symbols/hQuery.Language.html @@ -365,7 +365,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, startDate, status, statusCode, timeStamp, type, values
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    @@ -534,7 +534,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Medication.html b/public/patientapi/symbols/hQuery.Medication.html index bf085c6..39c9cf3 100644 --- a/public/patientapi/symbols/hQuery.Medication.html +++ b/public/patientapi/symbols/hQuery.Medication.html @@ -546,7 +546,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, startDate, status, statusCode, timeStamp, type, values
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    @@ -1358,7 +1358,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.MedicationInformation.html b/public/patientapi/symbols/hQuery.MedicationInformation.html index 937e4e9..13597d2 100644 --- a/public/patientapi/symbols/hQuery.MedicationInformation.html +++ b/public/patientapi/symbols/hQuery.MedicationInformation.html @@ -612,7 +612,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.NoImmunization.html b/public/patientapi/symbols/hQuery.NoImmunization.html index f1f109b..e070772 100644 --- a/public/patientapi/symbols/hQuery.NoImmunization.html +++ b/public/patientapi/symbols/hQuery.NoImmunization.html @@ -421,7 +421,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, startDate, status, statusCode, timeStamp, type, values
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    @@ -773,7 +773,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.OrderInformation.html b/public/patientapi/symbols/hQuery.OrderInformation.html index a71cb14..2d1aa81 100644 --- a/public/patientapi/symbols/hQuery.OrderInformation.html +++ b/public/patientapi/symbols/hQuery.OrderInformation.html @@ -605,7 +605,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Organization.html b/public/patientapi/symbols/hQuery.Organization.html index b5e297c..a5c450a 100644 --- a/public/patientapi/symbols/hQuery.Organization.html +++ b/public/patientapi/symbols/hQuery.Organization.html @@ -599,7 +599,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Patient.html b/public/patientapi/symbols/hQuery.Patient.html index 0ae3d7b..5e97672 100644 --- a/public/patientapi/symbols/hQuery.Patient.html +++ b/public/patientapi/symbols/hQuery.Patient.html @@ -786,7 +786,7 @@

    Returns:
    -
    {Date} containing the patient's birthdate
    +
    {Date} containing the patients birthdate
    @@ -1615,7 +1615,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Person.html b/public/patientapi/symbols/hQuery.Person.html index 9657563..e6de242 100644 --- a/public/patientapi/symbols/hQuery.Person.html +++ b/public/patientapi/symbols/hQuery.Person.html @@ -640,7 +640,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.PhysicalQuantity.html b/public/patientapi/symbols/hQuery.PhysicalQuantity.html index 2467f10..9db4747 100644 --- a/public/patientapi/symbols/hQuery.PhysicalQuantity.html +++ b/public/patientapi/symbols/hQuery.PhysicalQuantity.html @@ -503,7 +503,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Pregnancy.html b/public/patientapi/symbols/hQuery.Pregnancy.html index 1958241..b366ecc 100644 --- a/public/patientapi/symbols/hQuery.Pregnancy.html +++ b/public/patientapi/symbols/hQuery.Pregnancy.html @@ -357,7 +357,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, startDate, status, statusCode, timeStamp, type, values
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    @@ -495,7 +495,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Procedure.html b/public/patientapi/symbols/hQuery.Procedure.html index c68ecb9..214799d 100644 --- a/public/patientapi/symbols/hQuery.Procedure.html +++ b/public/patientapi/symbols/hQuery.Procedure.html @@ -333,6 +333,24 @@

    + +   + + +
    + + + + +   + + +
    Ordinality
    + + +   @@ -360,13 +378,22 @@

    + +   + +
    source() +
    +
    + + +
    -
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, startDate, status, statusCode, timeStamp, type, values
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    @@ -424,6 +451,70 @@

    Method Detail

    + +
    + + {Date} + incisionTime() + +
    +
    + + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {Date} The actual or intended start of an incision.
    + +
    + + + + +
    + + +
    + + {CodedValue} + ordinality() + +
    +
    + Ordinality + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {CodedValue}
    + +
    + + + + +
    +
    @@ -523,6 +614,38 @@

    +
    + + +
    + + {hQuery.CodedValue} + source() + +
    +
    + + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {hQuery.CodedValue} A SNOMED code indicating where the procedure was performed.
    + +
    + + + + @@ -537,7 +660,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Provider.html b/public/patientapi/symbols/hQuery.Provider.html index 4cf2331..41a692d 100644 --- a/public/patientapi/symbols/hQuery.Provider.html +++ b/public/patientapi/symbols/hQuery.Provider.html @@ -722,7 +722,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Result.html b/public/patientapi/symbols/hQuery.Result.html index e0458d0..f64e6b3 100644 --- a/public/patientapi/symbols/hQuery.Result.html +++ b/public/patientapi/symbols/hQuery.Result.html @@ -385,7 +385,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, startDate, status, statusCode, timeStamp, type, values
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    @@ -623,7 +623,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Scalar.html b/public/patientapi/symbols/hQuery.Scalar.html index 2a486f9..9c9b864 100644 --- a/public/patientapi/symbols/hQuery.Scalar.html +++ b/public/patientapi/symbols/hQuery.Scalar.html @@ -503,7 +503,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Status.html b/public/patientapi/symbols/hQuery.Status.html index 622dd53..44dd1d0 100644 --- a/public/patientapi/symbols/hQuery.Status.html +++ b/public/patientapi/symbols/hQuery.Status.html @@ -438,7 +438,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, startDate, status, statusCode, timeStamp, type, values
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    @@ -783,7 +783,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.StatusOfMedication.html b/public/patientapi/symbols/hQuery.StatusOfMedication.html index f5130ea..2fc2c04 100644 --- a/public/patientapi/symbols/hQuery.StatusOfMedication.html +++ b/public/patientapi/symbols/hQuery.StatusOfMedication.html @@ -384,7 +384,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, startDate, status, statusCode, timeStamp, type, values
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    @@ -607,7 +607,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:50 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Supports.html b/public/patientapi/symbols/hQuery.Supports.html index c05b935..251a10e 100644 --- a/public/patientapi/symbols/hQuery.Supports.html +++ b/public/patientapi/symbols/hQuery.Supports.html @@ -640,7 +640,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:50 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Telecom.html b/public/patientapi/symbols/hQuery.Telecom.html index abc27ee..3bd98dc 100644 --- a/public/patientapi/symbols/hQuery.Telecom.html +++ b/public/patientapi/symbols/hQuery.Telecom.html @@ -600,7 +600,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:50 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.TypeOfMedication.html b/public/patientapi/symbols/hQuery.TypeOfMedication.html index 919d7f5..47c1e9a 100644 --- a/public/patientapi/symbols/hQuery.TypeOfMedication.html +++ b/public/patientapi/symbols/hQuery.TypeOfMedication.html @@ -368,7 +368,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, startDate, status, statusCode, timeStamp, type, values
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    @@ -528,7 +528,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 10:50:23 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:50 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/src/tmp_patient.js.html b/public/patientapi/symbols/src/tmp_patient.js.html index a72197a..8a159be 100644 --- a/public/patientapi/symbols/src/tmp_patient.js.html +++ b/public/patientapi/symbols/src/tmp_patient.js.html @@ -68,7 +68,7 @@ 61 }; 62 63 PhysicalQuantity.prototype.scalar = function() { - 64 return this.json['scalar']; + 64 return parseFloat(this.json['scalar']); 65 }; 66 67 return PhysicalQuantity; @@ -110,2992 +110,3203 @@ 103 return this.csn; 104 }; 105 -106 /** -107 Returns true if the contained code and codeSystemName match a code in the supplied codeSet. -108 @param {Object} codeSet a hash with code system names as keys and an array of codes as values -109 @returns {boolean} -110 */ -111 -112 -113 CodedValue.prototype.includedIn = function(codeSet) { -114 var code, codeSystemName, codes, _i, _len; +106 CodedValue.normalize = function(val) { +107 return String(val).toLowerCase(); +108 }; +109 +110 /** +111 Returns true if the contained code and codeSystemName match a code in the supplied codeSet. +112 @param {Object} codeSet a hash with code system names as keys and an array of codes as values +113 @returns {boolean} +114 */ 115 -116 for (codeSystemName in codeSet) { -117 codes = codeSet[codeSystemName]; -118 if (this.csn === codeSystemName) { -119 for (_i = 0, _len = codes.length; _i < _len; _i++) { -120 code = codes[_i]; -121 if (code === this.c) { -122 return true; -123 } -124 } -125 } -126 } -127 return false; -128 }; -129 -130 return CodedValue; -131 -132 })(); -133 -134 /** -135 Status as defined by value set 2.16.840.1.113883.5.14, -136 the ActStatus vocabulary maintained by HL7 +116 +117 CodedValue.prototype.includedIn = function(codeSet) { +118 var c1, c2, code, codeSystemName, codes, _i, _len; +119 +120 for (codeSystemName in codeSet) { +121 codes = codeSet[codeSystemName]; +122 if (this.csn === codeSystemName) { +123 for (_i = 0, _len = codes.length; _i < _len; _i++) { +124 code = codes[_i]; +125 c1 = hQuery.CodedValue.normalize(code); +126 c2 = hQuery.CodedValue.normalize(this.c); +127 if (c1 === c2) { +128 return true; +129 } +130 } +131 } +132 } +133 return false; +134 }; +135 +136 return CodedValue; 137 -138 @class Status -139 @augments hQuery.CodedEntry -140 @exports Status as hQuery.Status -141 */ -142 +138 })(); +139 +140 /** +141 Status as defined by value set 2.16.840.1.113883.5.14, +142 the ActStatus vocabulary maintained by HL7 143 -144 hQuery.Status = (function(_super) { -145 var ABORTED, ACTIVE, CANCELLED, COMPLETED, HELD, NEW, NORMAL, NULLIFIED, OBSOLETE, SUSPENDED; -146 -147 __extends(Status, _super); +144 @class Status +145 @augments hQuery.CodedEntry +146 @exports Status as hQuery.Status +147 */ 148 -149 function Status() { -150 _ref = Status.__super__.constructor.apply(this, arguments); -151 return _ref; -152 } -153 -154 NORMAL = "normal"; -155 -156 ABORTED = "aborted"; -157 -158 ACTIVE = "active"; +149 +150 hQuery.Status = (function(_super) { +151 var ABORTED, ACTIVE, CANCELLED, COMPLETED, HELD, NEW, NORMAL, NULLIFIED, OBSOLETE, SUSPENDED; +152 +153 __extends(Status, _super); +154 +155 function Status() { +156 _ref = Status.__super__.constructor.apply(this, arguments); +157 return _ref; +158 } 159 -160 CANCELLED = "cancelled"; +160 NORMAL = "normal"; 161 -162 COMPLETED = "completed"; +162 ABORTED = "aborted"; 163 -164 HELD = "held"; +164 ACTIVE = "active"; 165 -166 NEW = "new"; +166 CANCELLED = "cancelled"; 167 -168 SUSPENDED = "suspended"; +168 COMPLETED = "completed"; 169 -170 NULLIFIED = "nullified"; +170 HELD = "held"; 171 -172 OBSOLETE = "obsolete"; +172 NEW = "new"; 173 -174 Status.prototype.isNormal = function() { -175 return this.c === NORMAL; -176 }; +174 SUSPENDED = "suspended"; +175 +176 NULLIFIED = "nullified"; 177 -178 Status.prototype.isAborted = function() { -179 return this.c === ABORTED; -180 }; -181 -182 Status.prototype.isActive = function() { -183 return this.c === ACTIVE; -184 }; -185 -186 Status.prototype.isCancelled = function() { -187 return this.c === CANCELLED; -188 }; -189 -190 Status.prototype.isCompleted = function() { -191 return this.c === COMPLETED; -192 }; -193 -194 Status.prototype.isHeld = function() { -195 return this.c === HELD; -196 }; -197 -198 Status.prototype.isNew = function() { -199 return this.c === NEW; -200 }; -201 -202 Status.prototype.isSuspended = function() { -203 return this.c === SUSPENDED; -204 }; -205 -206 Status.prototype.isNullified = function() { -207 return this.c === NULLIFIED; -208 }; -209 -210 Status.prototype.isObsolete = function() { -211 return this.c === OBSOLETE; -212 }; -213 -214 return Status; +178 OBSOLETE = "obsolete"; +179 +180 Status.prototype.isNormal = function() { +181 return this.c === NORMAL; +182 }; +183 +184 Status.prototype.isAborted = function() { +185 return this.c === ABORTED; +186 }; +187 +188 Status.prototype.isActive = function() { +189 return this.c === ACTIVE; +190 }; +191 +192 Status.prototype.isCancelled = function() { +193 return this.c === CANCELLED; +194 }; +195 +196 Status.prototype.isCompleted = function() { +197 return this.c === COMPLETED; +198 }; +199 +200 Status.prototype.isHeld = function() { +201 return this.c === HELD; +202 }; +203 +204 Status.prototype.isNew = function() { +205 return this.c === NEW; +206 }; +207 +208 Status.prototype.isSuspended = function() { +209 return this.c === SUSPENDED; +210 }; +211 +212 Status.prototype.isNullified = function() { +213 return this.c === NULLIFIED; +214 }; 215 -216 })(hQuery.CodedValue); -217 -218 /** -219 @class an Address for a person or organization -220 @exports Address as hQuery.Address -221 */ -222 +216 Status.prototype.isObsolete = function() { +217 return this.c === OBSOLETE; +218 }; +219 +220 return Status; +221 +222 })(hQuery.CodedValue); 223 -224 hQuery.Address = (function() { -225 function Address(json) { -226 this.json = json; -227 } +224 /** +225 @class an Address for a person or organization +226 @exports Address as hQuery.Address +227 */ 228 -229 /** -230 @returns {Array[String]} the street addresses -231 */ -232 -233 -234 Address.prototype.street = function() { -235 return this.json['street']; -236 }; -237 -238 /** -239 @returns {String} the city -240 */ -241 -242 -243 Address.prototype.city = function() { -244 return this.json['city']; -245 }; -246 -247 /** -248 @returns {String} the State -249 */ -250 -251 -252 Address.prototype.state = function() { -253 return this.json['state']; -254 }; -255 -256 /** -257 @returns {String} the postal code -258 */ -259 -260 -261 Address.prototype.postalCode = function() { -262 return this.json['zip']; -263 }; -264 -265 return Address; +229 +230 hQuery.Address = (function() { +231 function Address(json) { +232 this.json = json; +233 } +234 +235 /** +236 @returns {Array[String]} the street addresses +237 */ +238 +239 +240 Address.prototype.street = function() { +241 return this.json['street']; +242 }; +243 +244 /** +245 @returns {String} the city +246 */ +247 +248 +249 Address.prototype.city = function() { +250 return this.json['city']; +251 }; +252 +253 /** +254 @returns {String} the State +255 */ +256 +257 +258 Address.prototype.state = function() { +259 return this.json['state']; +260 }; +261 +262 /** +263 @returns {String} the postal code +264 */ +265 266 -267 })(); -268 -269 /** -270 @class An object that describes a means to contact an entity. This is used to represent -271 phone numbers, email addresses, instant messaging accounts etc. -272 @exports Telecom as hQuery.Telecom -273 */ +267 Address.prototype.postalCode = function() { +268 return this.json['zip']; +269 }; +270 +271 return Address; +272 +273 })(); 274 -275 -276 hQuery.Telecom = (function() { -277 function Telecom(json) { -278 this.json = json; -279 } +275 /** +276 @class An object that describes a means to contact an entity. This is used to represent +277 phone numbers, email addresses, instant messaging accounts etc. +278 @exports Telecom as hQuery.Telecom +279 */ 280 -281 /** -282 @returns {String} the type of telecom entry, phone, sms, email .... -283 */ -284 -285 -286 Telecom.prototype.type = function() { -287 return this.json['type']; -288 }; -289 -290 /** -291 @returns {String} the value of the entry - the actual phone number , email address , .... -292 */ -293 -294 -295 Telecom.prototype.value = function() { -296 return this.json['value']; -297 }; -298 -299 /** -300 @returns {String} the use of the entry. Is it a home, office, .... type of contact -301 */ -302 -303 -304 Telecom.prototype.use = function() { -305 return this.json['use']; -306 }; -307 -308 /** -309 @returns {Boolean} is this a preferred form of contact -310 */ -311 -312 -313 Telecom.prototype.preferred = function() { -314 return this.json['preferred']; -315 }; -316 -317 return Telecom; +281 +282 hQuery.Telecom = (function() { +283 function Telecom(json) { +284 this.json = json; +285 } +286 +287 /** +288 @returns {String} the type of telecom entry, phone, sms, email .... +289 */ +290 +291 +292 Telecom.prototype.type = function() { +293 return this.json['type']; +294 }; +295 +296 /** +297 @returns {String} the value of the entry - the actual phone number , email address , .... +298 */ +299 +300 +301 Telecom.prototype.value = function() { +302 return this.json['value']; +303 }; +304 +305 /** +306 @returns {String} the use of the entry. Is it a home, office, .... type of contact +307 */ +308 +309 +310 Telecom.prototype.use = function() { +311 return this.json['use']; +312 }; +313 +314 /** +315 @returns {Boolean} is this a preferred form of contact +316 */ +317 318 -319 })(); -320 -321 /** -322 @class an object that describes a person. includes a persons name, addresses, and contact information -323 @exports Person as hQuery.Person -324 */ -325 +319 Telecom.prototype.preferred = function() { +320 return this.json['preferred']; +321 }; +322 +323 return Telecom; +324 +325 })(); 326 -327 hQuery.Person = (function() { -328 function Person(json) { -329 this.json = json; -330 } +327 /** +328 @class an object that describes a person. includes a persons name, addresses, and contact information +329 @exports Person as hQuery.Person +330 */ 331 -332 /** -333 @returns {String} the given name of the person -334 */ -335 -336 -337 Person.prototype.given = function() { -338 return this.json['first']; -339 }; -340 -341 /** -342 @returns {String} the last/family name of the person -343 */ -344 -345 -346 Person.prototype.last = function() { -347 return this.json['last']; -348 }; -349 -350 /** -351 @returns {String} the display name of the person -352 */ -353 -354 -355 Person.prototype.name = function() { -356 if (this.json['name']) { -357 return this.json['name']; -358 } else { -359 return this.json['first'] + ' ' + this.json['last']; -360 } -361 }; -362 -363 /** -364 @returns {Array} an array of {@link hQuery.Address} objects associated with the patient -365 */ -366 -367 -368 Person.prototype.addresses = function() { -369 var address, list, _i, _len, _ref1; -370 -371 list = []; -372 if (this.json['addresses']) { -373 _ref1 = this.json['addresses']; -374 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -375 address = _ref1[_i]; -376 list.push(new hQuery.Address(address)); -377 } -378 } -379 return list; -380 }; -381 -382 /** -383 @returns {Array} an array of {@link hQuery.Telecom} objects associated with the person -384 */ -385 -386 -387 Person.prototype.telecoms = function() { -388 var tel, _i, _len, _ref1, _results; -389 -390 _ref1 = this.json['telecoms']; -391 _results = []; -392 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -393 tel = _ref1[_i]; -394 _results.push(new hQuery.Telecom(tel)); -395 } -396 return _results; -397 }; -398 -399 return Person; -400 -401 })(); -402 -403 /** -404 @class an actor is either a person or an organization -405 @exports Actor as hQuery.Actor -406 */ -407 +332 +333 hQuery.Person = (function() { +334 function Person(json) { +335 this.json = json; +336 } +337 +338 /** +339 @returns {String} the given name of the person +340 */ +341 +342 +343 Person.prototype.given = function() { +344 return this.json['first']; +345 }; +346 +347 /** +348 @returns {String} the last/family name of the person +349 */ +350 +351 +352 Person.prototype.last = function() { +353 return this.json['last']; +354 }; +355 +356 /** +357 @returns {String} the display name of the person +358 */ +359 +360 +361 Person.prototype.name = function() { +362 if (this.json['name']) { +363 return this.json['name']; +364 } else { +365 return this.json['first'] + ' ' + this.json['last']; +366 } +367 }; +368 +369 /** +370 @returns {Array} an array of {@link hQuery.Address} objects associated with the patient +371 */ +372 +373 +374 Person.prototype.addresses = function() { +375 var address, list, _i, _len, _ref1; +376 +377 list = []; +378 if (this.json['addresses']) { +379 _ref1 = this.json['addresses']; +380 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +381 address = _ref1[_i]; +382 list.push(new hQuery.Address(address)); +383 } +384 } +385 return list; +386 }; +387 +388 /** +389 @returns {Array} an array of {@link hQuery.Telecom} objects associated with the person +390 */ +391 +392 +393 Person.prototype.telecoms = function() { +394 var tel, _i, _len, _ref1, _results; +395 +396 _ref1 = this.json['telecoms']; +397 _results = []; +398 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +399 tel = _ref1[_i]; +400 _results.push(new hQuery.Telecom(tel)); +401 } +402 return _results; +403 }; +404 +405 return Person; +406 +407 })(); 408 -409 hQuery.Actor = (function() { -410 function Actor(json) { -411 this.json = json; -412 } +409 /** +410 @class an actor is either a person or an organization +411 @exports Actor as hQuery.Actor +412 */ 413 -414 Actor.prototype.person = function() { -415 if (this.json['person']) { -416 return new hQuery.Person(this.json['person']); -417 } -418 }; +414 +415 hQuery.Actor = (function() { +416 function Actor(json) { +417 this.json = json; +418 } 419 -420 Actor.prototype.organization = function() { -421 if (this.json['organization']) { -422 return new hQuery.Organization(this.json['organization']); +420 Actor.prototype.person = function() { +421 if (this.json['person']) { +422 return new hQuery.Person(this.json['person']); 423 } 424 }; 425 -426 return Actor; -427 -428 })(); -429 -430 /** -431 @class an Organization -432 @exports Organization as hQuery.Organization -433 */ -434 +426 Actor.prototype.organization = function() { +427 if (this.json['organization']) { +428 return new hQuery.Organization(this.json['organization']); +429 } +430 }; +431 +432 return Actor; +433 +434 })(); 435 -436 hQuery.Organization = (function() { -437 function Organization(json) { -438 this.json = json; -439 } +436 /** +437 @class an Organization +438 @exports Organization as hQuery.Organization +439 */ 440 -441 /** -442 @returns {String} the id for the organization -443 */ -444 -445 -446 Organization.prototype.organizationId = function() { -447 return this.json['organizationId']; -448 }; -449 -450 /** -451 @returns {String} the name of the organization -452 */ -453 -454 -455 Organization.prototype.organizationName = function() { -456 return this.json['name']; -457 }; -458 -459 /** -460 @returns {Array} an array of {@link hQuery.Address} objects associated with the organization -461 */ -462 -463 -464 Organization.prototype.addresses = function() { -465 var address, list, _i, _len, _ref1; -466 -467 list = []; -468 if (this.json['addresses']) { -469 _ref1 = this.json['addresses']; -470 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -471 address = _ref1[_i]; -472 list.push(new hQuery.Address(address)); -473 } -474 } -475 return list; -476 }; -477 -478 /** -479 @returns {Array} an array of {@link hQuery.Telecom} objects associated with the organization -480 */ -481 -482 -483 Organization.prototype.telecoms = function() { -484 var tel, _i, _len, _ref1, _results; -485 -486 _ref1 = this.json['telecoms']; -487 _results = []; -488 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -489 tel = _ref1[_i]; -490 _results.push(new hQuery.Telecom(tel)); -491 } -492 return _results; -493 }; -494 -495 return Organization; -496 -497 })(); -498 -499 /** -500 @class a Facility -501 @exports Organization as hQuery.Facility -502 */ -503 +441 +442 hQuery.Organization = (function() { +443 function Organization(json) { +444 this.json = json; +445 } +446 +447 /** +448 @returns {String} the id for the organization +449 */ +450 +451 +452 Organization.prototype.organizationId = function() { +453 return this.json['organizationId']; +454 }; +455 +456 /** +457 @returns {String} the name of the organization +458 */ +459 +460 +461 Organization.prototype.organizationName = function() { +462 return this.json['name']; +463 }; +464 +465 /** +466 @returns {Array} an array of {@link hQuery.Address} objects associated with the organization +467 */ +468 +469 +470 Organization.prototype.addresses = function() { +471 var address, list, _i, _len, _ref1; +472 +473 list = []; +474 if (this.json['addresses']) { +475 _ref1 = this.json['addresses']; +476 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +477 address = _ref1[_i]; +478 list.push(new hQuery.Address(address)); +479 } +480 } +481 return list; +482 }; +483 +484 /** +485 @returns {Array} an array of {@link hQuery.Telecom} objects associated with the organization +486 */ +487 +488 +489 Organization.prototype.telecoms = function() { +490 var tel, _i, _len, _ref1, _results; +491 +492 _ref1 = this.json['telecoms']; +493 _results = []; +494 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +495 tel = _ref1[_i]; +496 _results.push(new hQuery.Telecom(tel)); +497 } +498 return _results; +499 }; +500 +501 return Organization; +502 +503 })(); 504 -505 hQuery.Facility = (function(_super) { -506 __extends(Facility, _super); -507 -508 function Facility(json) { -509 this.json = json; -510 if (this.json['code'] != null) { -511 Facility.__super__.constructor.call(this, this.json['code']['code'], this.json['code']['codeSystem']); -512 } -513 } -514 -515 /** -516 @returns {String} the name of the facility -517 */ -518 -519 -520 Facility.prototype.name = function() { -521 return this.json['name']; -522 }; -523 -524 /** -525 @returns {Array} an array of {@link hQuery.Address} objects associated with the facility -526 */ -527 -528 -529 Facility.prototype.addresses = function() { -530 var address, list, _i, _len, _ref1; +505 /** +506 @class a Facility +507 @exports Organization as hQuery.Facility +508 */ +509 +510 +511 hQuery.Facility = (function(_super) { +512 __extends(Facility, _super); +513 +514 function Facility(json) { +515 this.json = json; +516 if (this.json['code'] != null) { +517 Facility.__super__.constructor.call(this, this.json['code']['code'], this.json['code']['code_system']); +518 } +519 if (this.json['start_time']) { +520 this._startDate = hQuery.dateFromUtcSeconds(this.json['start_time']); +521 } +522 if (this.json['end_time']) { +523 this._endDate = hQuery.dateFromUtcSeconds(this.json['end_time']); +524 } +525 } +526 +527 /** +528 @returns {String} the name of the facility +529 */ +530 531 -532 list = []; -533 if (this.json['addresses']) { -534 _ref1 = this.json['addresses']; -535 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -536 address = _ref1[_i]; -537 list.push(new hQuery.Address(address)); -538 } -539 } -540 return list; -541 }; -542 -543 /** -544 @returns {Array} an array of {@link hQuery.Telecom} objects associated with the facility -545 */ -546 -547 -548 Facility.prototype.telecoms = function() { -549 var tel, _i, _len, _ref1, _results; +532 Facility.prototype.name = function() { +533 return this.json['name']; +534 }; +535 +536 /** +537 Date and time at which the coded entry started +538 @returns {Date} +539 */ +540 +541 +542 Facility.prototype.startDate = function() { +543 return this._startDate; +544 }; +545 +546 /** +547 Date and time at which the coded entry ended +548 @returns {Date} +549 */ 550 -551 _ref1 = this.json['telecoms']; -552 _results = []; -553 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -554 tel = _ref1[_i]; -555 _results.push(new hQuery.Telecom(tel)); -556 } -557 return _results; -558 }; +551 +552 Facility.prototype.endDate = function() { +553 return this._endDate; +554 }; +555 +556 /** +557 @returns {Array} an array of {@link hQuery.Address} objects associated with the facility +558 */ 559 -560 return Facility; -561 -562 })(hQuery.CodedValue); +560 +561 Facility.prototype.addresses = function() { +562 var address, list, _i, _len, _ref1; 563 -564 /** -565 @class represents a DateRange in the form of hi and low date values. -566 @exports DateRange as hQuery.DateRange -567 */ -568 -569 -570 hQuery.DateRange = (function() { -571 function DateRange(json) { -572 this.json = json; -573 } +564 list = []; +565 if (this.json['addresses']) { +566 _ref1 = this.json['addresses']; +567 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +568 address = _ref1[_i]; +569 list.push(new hQuery.Address(address)); +570 } +571 } +572 return list; +573 }; 574 -575 DateRange.prototype.hi = function() { -576 if (this.json['hi']) { -577 return hQuery.dateFromUtcSeconds(this.json['hi']); -578 } -579 }; -580 -581 DateRange.prototype.low = function() { -582 return hQuery.dateFromUtcSeconds(this.json['low']); -583 }; -584 -585 return DateRange; -586 -587 })(); -588 -589 /** -590 @class Class used to describe an entity that is providing some form of information. This does not mean that they are -591 providing any treatment just that they are providing information. -592 @exports Informant as hQuery.Informant -593 */ -594 +575 /** +576 @returns {Array} an array of {@link hQuery.Telecom} objects associated with the facility +577 */ +578 +579 +580 Facility.prototype.telecoms = function() { +581 var tel, _i, _len, _ref1, _results; +582 +583 _ref1 = this.json['telecoms']; +584 _results = []; +585 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +586 tel = _ref1[_i]; +587 _results.push(new hQuery.Telecom(tel)); +588 } +589 return _results; +590 }; +591 +592 return Facility; +593 +594 })(hQuery.CodedValue); 595 -596 hQuery.Informant = (function() { -597 function Informant(json) { -598 this.json = json; -599 } +596 /** +597 @class represents a DateRange in the form of hi and low date values. +598 @exports DateRange as hQuery.DateRange +599 */ 600 -601 /** -602 an array of hQuery.Person objects as points of contact -603 @returns {Array} -604 */ -605 +601 +602 hQuery.DateRange = (function() { +603 function DateRange(json) { +604 this.json = json; +605 } 606 -607 Informant.prototype.contacts = function() { -608 var contact, _i, _len, _ref1, _results; -609 -610 _ref1 = this.json['contacts']; -611 _results = []; -612 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -613 contact = _ref1[_i]; -614 _results.push(new hQuery.Person(contact)); -615 } -616 return _results; -617 }; +607 DateRange.prototype.hi = function() { +608 if (this.json['hi']) { +609 return hQuery.dateFromUtcSeconds(this.json['hi']); +610 } +611 }; +612 +613 DateRange.prototype.low = function() { +614 return hQuery.dateFromUtcSeconds(this.json['low']); +615 }; +616 +617 return DateRange; 618 -619 /** -620 @returns {hQuery.Organization} the organization providing the information -621 */ -622 -623 -624 Informant.prototype.organization = function() { -625 return new hQuery.Organization(this.json['organization']); -626 }; +619 })(); +620 +621 /** +622 @class Class used to describe an entity that is providing some form of information. This does not mean that they are +623 providing any treatment just that they are providing information. +624 @exports Informant as hQuery.Informant +625 */ +626 627 -628 return Informant; -629 -630 })(); -631 -632 /** -633 @class -634 @exports CodedEntry as hQuery.CodedEntry -635 */ -636 +628 hQuery.Informant = (function() { +629 function Informant(json) { +630 this.json = json; +631 } +632 +633 /** +634 an array of hQuery.Person objects as points of contact +635 @returns {Array} +636 */ 637 -638 hQuery.CodedEntry = (function() { -639 function CodedEntry(json) { -640 this.json = json; -641 if (this.json['time']) { -642 this._date = hQuery.dateFromUtcSeconds(this.json['time']); -643 } -644 if (this.json['start_time']) { -645 this._startDate = hQuery.dateFromUtcSeconds(this.json['start_time']); -646 } -647 if (this.json['end_time']) { -648 this._endDate = hQuery.dateFromUtcSeconds(this.json['end_time']); -649 } -650 this._type = hQuery.createCodedValues(this.json['codes']); -651 this._statusCode = this.json['status_code']; -652 this.id = this.json['_id']; -653 this._freeTextType = this.json['description']; -654 } +638 +639 Informant.prototype.contacts = function() { +640 var contact, _i, _len, _ref1, _results; +641 +642 _ref1 = this.json['contacts']; +643 _results = []; +644 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +645 contact = _ref1[_i]; +646 _results.push(new hQuery.Person(contact)); +647 } +648 return _results; +649 }; +650 +651 /** +652 @returns {hQuery.Organization} the organization providing the information +653 */ +654 655 -656 /** -657 Date and time at which the coded entry took place -658 @returns {Date} -659 */ -660 +656 Informant.prototype.organization = function() { +657 return new hQuery.Organization(this.json['organization']); +658 }; +659 +660 return Informant; 661 -662 CodedEntry.prototype.date = function() { -663 return this._date; -664 }; -665 -666 /** -667 Date and time at which the coded entry started -668 @returns {Date} -669 */ -670 -671 -672 CodedEntry.prototype.startDate = function() { -673 return this._startDate; -674 }; -675 -676 /** -677 Date and time at which the coded entry ended -678 @returns {Date} -679 */ -680 -681 -682 CodedEntry.prototype.endDate = function() { -683 return this._endDate; -684 }; -685 -686 /** -687 Tries to find a single point in time for this entry. Will first return date if it is present, -688 then fall back to startDate and finally endDate -689 @returns {Date} -690 */ -691 +662 })(); +663 +664 /** +665 @class +666 @exports CodedEntry as hQuery.CodedEntry +667 */ +668 +669 +670 hQuery.CodedEntry = (function() { +671 function CodedEntry(json) { +672 this.json = json; +673 if (this.json['time']) { +674 this._date = hQuery.dateFromUtcSeconds(this.json['time']); +675 } +676 if (this.json['start_time']) { +677 this._startDate = hQuery.dateFromUtcSeconds(this.json['start_time']); +678 } +679 if (this.json['end_time']) { +680 this._endDate = hQuery.dateFromUtcSeconds(this.json['end_time']); +681 } +682 this._type = hQuery.createCodedValues(this.json['codes']); +683 this._statusCode = this.json['status_code']; +684 this.id = "" + this.json['_id']; +685 this.source_id = this.json['id']; +686 this._freeTextType = this.json['description']; +687 } +688 +689 /** +690 Adjust the start and end times of this event to the supplied timestamp +691 */ 692 -693 CodedEntry.prototype.timeStamp = function() { -694 return this._date || this._startDate || this._endDate; -695 }; -696 -697 /** -698 Determines whether the entry specifies a time range or not -699 @returns {boolean} -700 */ -701 +693 +694 CodedEntry.prototype.setTimestamp = function(timestamp) { +695 return this._date = this._startDate = this._endDate = timestamp; +696 }; +697 +698 /** +699 Date and time at which the coded entry took place +700 @returns {Date} +701 */ 702 -703 CodedEntry.prototype.isTimeRange = function() { -704 return (this._startDate != null) && (this._endDate != null); -705 }; -706 -707 /** -708 Determines whether a coded entry contains sufficient information (code and at least -709 one time stamp) to be usable -710 @returns {boolean} +703 +704 CodedEntry.prototype.date = function() { +705 return this._date; +706 }; +707 +708 /** +709 Date and time at which the coded entry started +710 @returns {Date} 711 */ 712 713 -714 CodedEntry.prototype.isUsable = function() { -715 return this._type.length > 0 && (this._date || this._startDate || this._endDate); +714 CodedEntry.prototype.startDate = function() { +715 return this._startDate; 716 }; 717 718 /** -719 An Array of CodedValues which describe what kind of coded entry took place -720 @returns {Array} +719 Date and time at which the coded entry ended +720 @returns {Date} 721 */ 722 723 -724 CodedEntry.prototype.type = function() { -725 return this._type; +724 CodedEntry.prototype.endDate = function() { +725 return this._endDate; 726 }; 727 728 /** -729 A free text description of the type of coded entry -730 @returns {String} -731 */ -732 +729 Tries to find a single point in time for this entry. Will first return date if it is present, +730 then fall back to startDate and finally endDate +731 @returns {Date} +732 */ 733 -734 CodedEntry.prototype.freeTextType = function() { -735 return this._freeTextType; -736 }; -737 -738 /** -739 Status for this coded entry -740 @returns {String} -741 */ -742 +734 +735 CodedEntry.prototype.timeStamp = function() { +736 return this._date || this._startDate || this._endDate; +737 }; +738 +739 /** +740 Determines whether the entry specifies a time range or not +741 @returns {boolean} +742 */ 743 -744 CodedEntry.prototype.status = function() { -745 if (this._statusCode != null) { -746 if (this._statusCode['HL7 ActStatus'] != null) { -747 return this._statusCode['HL7 ActStatus'][0]; -748 } else if (this._statusCode['SNOMED-CT'] != null) { -749 switch (this._statusCode['SNOMED-CT'][0]) { -750 case '55561003': -751 return 'active'; -752 case '73425007': -753 return 'inactive'; -754 case '413322009': -755 return 'resolved'; -756 } -757 } -758 } -759 }; -760 -761 /** -762 Status for this coded entry -763 @returns {Hash} keys are code systems, values are arrays of codes -764 */ +744 +745 CodedEntry.prototype.isTimeRange = function() { +746 return (this._startDate != null) && (this._endDate != null); +747 }; +748 +749 /** +750 Determines whether a coded entry contains sufficient information (code and at least +751 one time stamp) to be usable +752 @returns {boolean} +753 */ +754 +755 +756 CodedEntry.prototype.isUsable = function() { +757 return this._type.length > 0 && (this._date || this._startDate || this._endDate); +758 }; +759 +760 /** +761 An Array of CodedValues which describe what kind of coded entry took place +762 @returns {Array} +763 */ +764 765 -766 -767 CodedEntry.prototype.statusCode = function() { -768 return this._statusCode; -769 }; -770 -771 /** -772 Returns true if any of this entry codes match a code in the supplied codeSet. -773 @param {Object} codeSet a hash with code system names as keys and an array of codes as values -774 @returns {boolean} -775 */ -776 -777 -778 CodedEntry.prototype.includesCodeFrom = function(codeSet) { -779 var codedValue, _i, _len, _ref1; -780 -781 _ref1 = this._type; -782 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -783 codedValue = _ref1[_i]; -784 if (codedValue.includedIn(codeSet)) { -785 return true; -786 } -787 } -788 return false; -789 }; -790 -791 /** -792 @returns {Boolean} whether the entry was negated -793 */ -794 -795 -796 CodedEntry.prototype.negationInd = function() { -797 return this.json['negationInd'] || false; -798 }; -799 -800 /** -801 Returns the values of the result. This will return an array that contains -802 PhysicalQuantity or CodedValue objects depending on the result type. -803 @returns {Array} containing either PhysicalQuantity and/or CodedValues -804 */ -805 -806 -807 CodedEntry.prototype.values = function() { -808 var value, values, _i, _len, _ref1; -809 -810 values = []; -811 if (this.json['values']) { -812 _ref1 = this.json['values']; -813 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -814 value = _ref1[_i]; -815 if (value['scalar'] != null) { -816 values.push(new hQuery.PhysicalQuantity(value)); -817 } else { -818 values.push(hQuery.createCodedValues(values)); -819 } -820 } -821 } -822 return values; -823 }; -824 -825 /** -826 Indicates the reason an entry was negated. -827 @returns {hQuery.CodedValue} Used to indicate reason an immunization was not administered. -828 */ -829 -830 -831 CodedEntry.prototype.negationReason = function() { -832 if (this.json['negationReason'] && this.json['negationReason']['code'] && this.json['negationReason']['codeSystem']) { -833 return new hQuery.CodedValue(this.json['negationReason']['code'], this.json['negationReason']['codeSystem']); -834 } else { -835 return null; -836 } -837 }; -838 -839 return CodedEntry; -840 -841 })(); -842 -843 /** -844 @class Represents a list of hQuery.CodedEntry instances. Offers utility methods for matching -845 entries based on codes and date ranges -846 @exports CodedEntryList as hQuery.CodedEntryList -847 */ +766 CodedEntry.prototype.type = function() { +767 return this._type; +768 }; +769 +770 /** +771 A free text description of the type of coded entry +772 @returns {String} +773 */ +774 +775 +776 CodedEntry.prototype.freeTextType = function() { +777 return this._freeTextType; +778 }; +779 +780 /** +781 Status for this coded entry +782 @returns {String} +783 */ +784 +785 +786 CodedEntry.prototype.status = function() { +787 if (this._statusCode != null) { +788 if (this._statusCode['HL7 ActStatus'] != null) { +789 return this._statusCode['HL7 ActStatus'][0]; +790 } else if (this._statusCode['SNOMED-CT'] != null) { +791 switch (this._statusCode['SNOMED-CT'][0]) { +792 case '55561003': +793 return 'active'; +794 case '73425007': +795 return 'inactive'; +796 case '413322009': +797 return 'resolved'; +798 } +799 } +800 } +801 }; +802 +803 /** +804 Status for this coded entry +805 @returns {Hash} keys are code systems, values are arrays of codes +806 */ +807 +808 +809 CodedEntry.prototype.statusCode = function() { +810 return this._statusCode; +811 }; +812 +813 /** +814 Returns true if any of this entry codes match a code in the supplied codeSet. +815 @param {Object} codeSet a hash with code system names as keys and an array of codes as values +816 @returns {boolean} +817 */ +818 +819 +820 CodedEntry.prototype.includesCodeFrom = function(codeSet) { +821 var codedValue, _i, _len, _ref1; +822 +823 _ref1 = this._type; +824 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +825 codedValue = _ref1[_i]; +826 if (codedValue.includedIn(codeSet)) { +827 return true; +828 } +829 } +830 return false; +831 }; +832 +833 /** +834 @returns {Boolean} whether the entry was negated +835 */ +836 +837 +838 CodedEntry.prototype.negationInd = function() { +839 return this.json['negationInd'] || false; +840 }; +841 +842 /** +843 Returns the values of the result. This will return an array that contains +844 PhysicalQuantity or CodedValue objects depending on the result type. +845 @returns {Array} containing either PhysicalQuantity and/or CodedValues +846 */ +847 848 -849 -850 hQuery.CodedEntryList = (function(_super) { -851 __extends(CodedEntryList, _super); -852 -853 function CodedEntryList() { -854 this.push.apply(this, arguments); -855 } -856 -857 /** -858 Push the supplied entry onto this list if it is usable -859 @param {CodedEntry} a coded entry that should be added to the list if it is usable -860 */ -861 -862 -863 CodedEntryList.prototype.pushIfUsable = function(entry) { -864 if (entry.isUsable()) { -865 return this.push(entry); -866 } -867 }; -868 -869 /** -870 Return the number of entries that match the -871 supplied code set where those entries occur between the supplied time bounds -872 @param {Object} codeSet a hash with code system names as keys and an array of codes as values -873 @param {Date} start the start of the period during which the entry must occur, a null value will match all times -874 @param {Date} end the end of the period during which the entry must occur, a null value will match all times -875 @param {boolean} includeNegated whether the returned list of entries should include those that have been negated -876 @return {CodedEntryList} the matching entries -877 */ -878 -879 -880 CodedEntryList.prototype.match = function(codeSet, start, end, includeNegated) { -881 var afterStart, beforeEnd, cloned, entry, _i, _len; +849 CodedEntry.prototype.values = function() { +850 var value, values, _i, _len, _ref1; +851 +852 values = []; +853 if (this.json['values']) { +854 _ref1 = this.json['values']; +855 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +856 value = _ref1[_i]; +857 if (value['scalar'] != null) { +858 values.push(new hQuery.PhysicalQuantity(value)); +859 } else { +860 values = values.concat(hQuery.createCodedValues(value.codes)); +861 } +862 } +863 } +864 return values; +865 }; +866 +867 /** +868 Indicates the reason an entry was negated. +869 @returns {hQuery.CodedValue} Used to indicate reason an immunization was not administered. +870 */ +871 +872 +873 CodedEntry.prototype.negationReason = function() { +874 return hQuery.createCodedValue(this.json['negationReason']); +875 }; +876 +877 /** +878 Explains the reason for an entry. +879 @returns {hQuery.CodedValue} Used to explain the rationale for a given entry. +880 */ +881 882 -883 if (includeNegated == null) { -884 includeNegated = false; -885 } -886 cloned = new hQuery.CodedEntryList(); -887 for (_i = 0, _len = this.length; _i < _len; _i++) { -888 entry = this[_i]; -889 afterStart = !start || entry.timeStamp() >= start; -890 beforeEnd = !end || entry.timeStamp() <= end; -891 if (afterStart && beforeEnd && entry.includesCodeFrom(codeSet) && (includeNegated || !entry.negationInd())) { -892 cloned.push(entry); -893 } -894 } -895 return cloned; -896 }; +883 CodedEntry.prototype.reason = function() { +884 return hQuery.createCodedValue(this.json['reason']); +885 }; +886 +887 return CodedEntry; +888 +889 })(); +890 +891 /** +892 @class Represents a list of hQuery.CodedEntry instances. Offers utility methods for matching +893 entries based on codes and date ranges +894 @exports CodedEntryList as hQuery.CodedEntryList +895 */ +896 897 -898 /** -899 Return a new list of entries that is the result of concatenating the passed in entries with this list -900 @return {CodedEntryList} the set of concatenated entries -901 */ -902 -903 -904 CodedEntryList.prototype.concat = function(otherEntries) { -905 var cloned, entry, _i, _j, _len, _len1; -906 -907 cloned = new hQuery.CodedEntryList(); -908 for (_i = 0, _len = this.length; _i < _len; _i++) { -909 entry = this[_i]; -910 cloned.push(entry); -911 } -912 for (_j = 0, _len1 = otherEntries.length; _j < _len1; _j++) { -913 entry = otherEntries[_j]; -914 cloned.push(entry); -915 } -916 return cloned; -917 }; -918 -919 /** -920 Match entries with the specified statuses -921 @return {CodedEntryList} the matching entries -922 */ -923 -924 -925 CodedEntryList.prototype.withStatuses = function(statuses, includeUndefined) { -926 var cloned, entry, _i, _len, _ref1; +898 hQuery.CodedEntryList = (function(_super) { +899 __extends(CodedEntryList, _super); +900 +901 function CodedEntryList() { +902 this.push.apply(this, arguments); +903 } +904 +905 /** +906 Push the supplied entry onto this list if it is usable +907 @param {CodedEntry} a coded entry that should be added to the list if it is usable +908 */ +909 +910 +911 CodedEntryList.prototype.pushIfUsable = function(entry) { +912 if (entry.isUsable()) { +913 return this.push(entry); +914 } +915 }; +916 +917 /** +918 Return the number of entries that match the +919 supplied code set where those entries occur between the supplied time bounds +920 @param {Object} codeSet a hash with code system names as keys and an array of codes as values +921 @param {Date} start the start of the period during which the entry must occur, a null value will match all times +922 @param {Date} end the end of the period during which the entry must occur, a null value will match all times +923 @param {boolean} includeNegated whether the returned list of entries should include those that have been negated +924 @return {CodedEntryList} the matching entries +925 */ +926 927 -928 if (includeUndefined == null) { -929 includeUndefined = true; -930 } -931 if (includeUndefined) { -932 statuses = statuses.concat([void 0, null]); +928 CodedEntryList.prototype.match = function(codeSet, start, end, includeNegated) { +929 var afterStart, beforeEnd, cloned, entry, matchesCode, _i, _len; +930 +931 if (includeNegated == null) { +932 includeNegated = false; 933 } 934 cloned = new hQuery.CodedEntryList(); 935 for (_i = 0, _len = this.length; _i < _len; _i++) { 936 entry = this[_i]; -937 if (_ref1 = entry.status(), __indexOf.call(statuses, _ref1) >= 0) { -938 cloned.push(entry); -939 } -940 } -941 return cloned; -942 }; -943 -944 /** -945 Filter entries based on negation -946 @param {Object} codeSet a hash with code system names as keys and an array of codes as values -947 @return {CodedEntryList} negated entries -948 */ -949 -950 -951 CodedEntryList.prototype.withNegation = function(codeSet) { -952 var cloned, entry, _i, _len; -953 -954 cloned = new hQuery.CodedEntryList(); -955 for (_i = 0, _len = this.length; _i < _len; _i++) { -956 entry = this[_i]; -957 if (entry.negationInd() && (!codeSet || (entry.negationReason() && entry.negationReason().includedIn(codeSet)))) { -958 cloned.push(entry); -959 } +937 afterStart = !start || entry.timeStamp() >= start; +938 beforeEnd = !end || entry.timeStamp() <= end; +939 matchesCode = codeSet === null || entry.includesCodeFrom(codeSet); +940 if (afterStart && beforeEnd && matchesCode && (includeNegated || !entry.negationInd())) { +941 cloned.push(entry); +942 } +943 } +944 return cloned; +945 }; +946 +947 /** +948 Return a new list of entries that is the result of concatenating the passed in entries with this list +949 @return {CodedEntryList} the set of concatenated entries +950 */ +951 +952 +953 CodedEntryList.prototype.concat = function(otherEntries) { +954 var cloned, entry, _i, _j, _len, _len1; +955 +956 cloned = new hQuery.CodedEntryList(); +957 for (_i = 0, _len = this.length; _i < _len; _i++) { +958 entry = this[_i]; +959 cloned.push(entry); 960 } -961 return cloned; -962 }; -963 -964 /** -965 Filter entries based on negation -966 @return {CodedEntryList} non-negated entries -967 */ -968 -969 -970 CodedEntryList.prototype.withoutNegation = function() { -971 var cloned, entry, _i, _len; +961 for (_j = 0, _len1 = otherEntries.length; _j < _len1; _j++) { +962 entry = otherEntries[_j]; +963 cloned.push(entry); +964 } +965 return cloned; +966 }; +967 +968 /** +969 Match entries with the specified statuses +970 @return {CodedEntryList} the matching entries +971 */ 972 -973 cloned = new hQuery.CodedEntryList(); -974 for (_i = 0, _len = this.length; _i < _len; _i++) { -975 entry = this[_i]; -976 if (!entry.negationInd()) { -977 cloned.push(entry); -978 } +973 +974 CodedEntryList.prototype.withStatuses = function(statuses, includeUndefined) { +975 var cloned, entry, _i, _len, _ref1; +976 +977 if (includeUndefined == null) { +978 includeUndefined = true; 979 } -980 return cloned; -981 }; -982 -983 return CodedEntryList; -984 -985 })(Array); -986 -987 /** -988 @private -989 @function -990 */ -991 +980 if (includeUndefined) { +981 statuses = statuses.concat([void 0, null]); +982 } +983 cloned = new hQuery.CodedEntryList(); +984 for (_i = 0, _len = this.length; _i < _len; _i++) { +985 entry = this[_i]; +986 if (_ref1 = entry.status(), __indexOf.call(statuses, _ref1) >= 0) { +987 cloned.push(entry); +988 } +989 } +990 return cloned; +991 }; 992 -993 hQuery.createCodedValues = function(jsonCodes) { -994 var code, codeSystem, codedValues, codes, _i, _len; -995 -996 codedValues = []; -997 for (codeSystem in jsonCodes) { -998 codes = jsonCodes[codeSystem]; -999 for (_i = 0, _len = codes.length; _i < _len; _i++) { -1000 code = codes[_i]; -1001 codedValues.push(new hQuery.CodedValue(code, codeSystem)); -1002 } -1003 } -1004 return codedValues; -1005 }; -1006 /** -1007 @namespace scoping into the hquery namespace -1008 */ -1009 -1010 var _ref, _ref1, -1011 __hasProp = {}.hasOwnProperty, -1012 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; -1013 -1014 this.hQuery || (this.hQuery = {}); -1015 -1016 /** -1017 @class MedicationInformation -1018 @exports MedicationInformation as hQuery.MedicationInformation -1019 */ -1020 +993 /** +994 Filter entries based on negation +995 @param {Object} codeSet a hash with code system names as keys and an array of codes as values +996 @return {CodedEntryList} negated entries +997 */ +998 +999 +1000 CodedEntryList.prototype.withNegation = function(codeSet) { +1001 var cloned, entry, _i, _len; +1002 +1003 cloned = new hQuery.CodedEntryList(); +1004 for (_i = 0, _len = this.length; _i < _len; _i++) { +1005 entry = this[_i]; +1006 if (entry.negationInd() && (!codeSet || (entry.negationReason() && entry.negationReason().includedIn(codeSet)))) { +1007 cloned.push(entry); +1008 } +1009 } +1010 return cloned; +1011 }; +1012 +1013 /** +1014 Filter entries based on negation +1015 @return {CodedEntryList} non-negated entries +1016 */ +1017 +1018 +1019 CodedEntryList.prototype.withoutNegation = function() { +1020 var cloned, entry, _i, _len; 1021 -1022 hQuery.MedicationInformation = (function() { -1023 function MedicationInformation(json) { -1024 this.json = json; -1025 } -1026 -1027 /** -1028 An array of hQuery.CodedValue describing the medication -1029 @returns {Array} -1030 */ +1022 cloned = new hQuery.CodedEntryList(); +1023 for (_i = 0, _len = this.length; _i < _len; _i++) { +1024 entry = this[_i]; +1025 if (!entry.negationInd()) { +1026 cloned.push(entry); +1027 } +1028 } +1029 return cloned; +1030 }; 1031 -1032 -1033 MedicationInformation.prototype.codedProduct = function() { -1034 return hQuery.createCodedValues(this.json['codes']); -1035 }; -1036 -1037 MedicationInformation.prototype.freeTextProductName = function() { -1038 return this.json['description']; -1039 }; +1032 return CodedEntryList; +1033 +1034 })(Array); +1035 +1036 /** +1037 @private +1038 @function +1039 */ 1040 -1041 MedicationInformation.prototype.codedBrandName = function() { -1042 return this.json['codedBrandName']; -1043 }; +1041 +1042 hQuery.createCodedValues = function(jsonCodes) { +1043 var code, codeSystem, codedValues, codes, _i, _len; 1044 -1045 MedicationInformation.prototype.freeTextBrandName = function() { -1046 return this.json['brandName']; -1047 }; -1048 -1049 MedicationInformation.prototype.drugManufacturer = function() { -1050 if (this.json['drugManufacturer']) { -1051 return new hQuery.Organization(this.json['drugManufacturer']); -1052 } -1053 }; -1054 -1055 return MedicationInformation; -1056 -1057 })(); -1058 -1059 /** -1060 @class AdministrationTiming - the -1061 @exports AdministrationTiming as hQuery.AdministrationTiming -1062 */ -1063 +1045 codedValues = []; +1046 for (codeSystem in jsonCodes) { +1047 codes = jsonCodes[codeSystem]; +1048 for (_i = 0, _len = codes.length; _i < _len; _i++) { +1049 code = codes[_i]; +1050 codedValues.push(new hQuery.CodedValue(code, codeSystem)); +1051 } +1052 } +1053 return codedValues; +1054 }; +1055 +1056 hQuery.createCodedValue = function(json) { +1057 if (json != null) { +1058 return new hQuery.CodedValue(json['code'], json['code_system']); +1059 } +1060 }; +1061 /** +1062 @namespace scoping into the hquery namespace +1063 */ 1064 -1065 hQuery.AdministrationTiming = (function() { -1066 function AdministrationTiming(json) { -1067 this.json = json; -1068 } -1069 -1070 /** -1071 Provides the period of medication administration as a Scalar. An example -1072 Scalar that would be returned would be with value = 8 and units = hours. This would -1073 mean that the medication should be taken every 8 hours. -1074 @returns {hQuery.Scalar} -1075 */ +1065 var _ref, _ref1, +1066 __hasProp = {}.hasOwnProperty, +1067 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; +1068 +1069 this.hQuery || (this.hQuery = {}); +1070 +1071 /** +1072 @class MedicationInformation +1073 @exports MedicationInformation as hQuery.MedicationInformation +1074 */ +1075 1076 -1077 -1078 AdministrationTiming.prototype.period = function() { -1079 return new hQuery.Scalar(this.json['period']); -1080 }; +1077 hQuery.MedicationInformation = (function() { +1078 function MedicationInformation(json) { +1079 this.json = json; +1080 } 1081 1082 /** -1083 Indicates whether it is the interval (time between dosing), or frequency -1084 (number of doses in a time period) that is important. If instititutionSpecified is not -1085 present or is set to false, then the time between dosing is important (every 8 hours). -1086 If true, then the frequency of administration is important (e.g., 3 times per day). -1087 @returns {Boolean} -1088 */ -1089 -1090 -1091 AdministrationTiming.prototype.institutionSpecified = function() { -1092 return this.json['institutionSpecified']; -1093 }; -1094 -1095 return AdministrationTiming; -1096 -1097 })(); -1098 -1099 /** -1100 @class DoseRestriction - restrictions on the medications dose, represented by a upper and lower dose -1101 @exports DoseRestriction as hQuery.DoseRestriction -1102 */ +1083 An array of hQuery.CodedValue describing the medication +1084 @returns {Array} +1085 */ +1086 +1087 +1088 MedicationInformation.prototype.codedProduct = function() { +1089 return hQuery.createCodedValues(this.json['codes']); +1090 }; +1091 +1092 MedicationInformation.prototype.freeTextProductName = function() { +1093 return this.json['description']; +1094 }; +1095 +1096 MedicationInformation.prototype.codedBrandName = function() { +1097 return this.json['codedBrandName']; +1098 }; +1099 +1100 MedicationInformation.prototype.freeTextBrandName = function() { +1101 return this.json['brandName']; +1102 }; 1103 -1104 -1105 hQuery.DoseRestriction = (function() { -1106 function DoseRestriction(json) { -1107 this.json = json; -1108 } +1104 MedicationInformation.prototype.drugManufacturer = function() { +1105 if (this.json['drugManufacturer']) { +1106 return new hQuery.Organization(this.json['drugManufacturer']); +1107 } +1108 }; 1109 -1110 DoseRestriction.prototype.numerator = function() { -1111 return new hQuery.Scalar(this.json['numerator']); -1112 }; +1110 return MedicationInformation; +1111 +1112 })(); 1113 -1114 DoseRestriction.prototype.denominator = function() { -1115 return new hQuery.Scalar(this.json['denominator']); -1116 }; -1117 -1118 return DoseRestriction; +1114 /** +1115 @class AdministrationTiming - the +1116 @exports AdministrationTiming as hQuery.AdministrationTiming +1117 */ +1118 1119 -1120 })(); -1121 -1122 /** -1123 @class Fulfillment - information about when and who fulfilled an order for the medication -1124 @exports Fulfillment as hQuery.Fullfilement -1125 */ -1126 -1127 -1128 hQuery.Fulfillment = (function() { -1129 function Fulfillment(json) { -1130 this.json = json; -1131 } +1120 hQuery.AdministrationTiming = (function() { +1121 function AdministrationTiming(json) { +1122 this.json = json; +1123 } +1124 +1125 /** +1126 Provides the period of medication administration as a Scalar. An example +1127 Scalar that would be returned would be with value = 8 and units = hours. This would +1128 mean that the medication should be taken every 8 hours. +1129 @returns {hQuery.Scalar} +1130 */ +1131 1132 -1133 Fulfillment.prototype.dispenseDate = function() { -1134 return hQuery.dateFromUtcSeconds(this.json['dispenseDate']); -1135 }; -1136 -1137 Fulfillment.prototype.dispensingPharmacyLocation = function() { -1138 return new hQuery.Address(this.json['dispensingPharmacyLocation']); -1139 }; -1140 -1141 Fulfillment.prototype.quantityDispensed = function() { -1142 return new hQuery.Scalar(this.json['quantityDispensed']); -1143 }; -1144 -1145 Fulfillment.prototype.prescriptionNumber = function() { -1146 return this.json['prescriptionNumber']; -1147 }; -1148 -1149 Fulfillment.prototype.fillNumber = function() { -1150 return this.json['fillNumber']; -1151 }; -1152 -1153 Fulfillment.prototype.fillStatus = function() { -1154 return new hQuery.Status(this.json['fillStatus']); -1155 }; -1156 -1157 return Fulfillment; -1158 -1159 })(); +1133 AdministrationTiming.prototype.period = function() { +1134 if (this.json['period']) { +1135 return new hQuery.Scalar(this.json['period']); +1136 } +1137 }; +1138 +1139 /** +1140 Indicates whether it is the interval (time between dosing), or frequency +1141 (number of doses in a time period) that is important. If instititutionSpecified is not +1142 present or is set to false, then the time between dosing is important (every 8 hours). +1143 If true, then the frequency of administration is important (e.g., 3 times per day). +1144 @returns {Boolean} +1145 */ +1146 +1147 +1148 AdministrationTiming.prototype.institutionSpecified = function() { +1149 return this.json['institutionSpecified']; +1150 }; +1151 +1152 return AdministrationTiming; +1153 +1154 })(); +1155 +1156 /** +1157 @class DoseRestriction - restrictions on the medications dose, represented by a upper and lower dose +1158 @exports DoseRestriction as hQuery.DoseRestriction +1159 */ 1160 -1161 /** -1162 @class OrderInformation - information abour an order for a medication -1163 @exports OrderInformation as hQuery.OrderInformation -1164 */ -1165 +1161 +1162 hQuery.DoseRestriction = (function() { +1163 function DoseRestriction(json) { +1164 this.json = json; +1165 } 1166 -1167 hQuery.OrderInformation = (function() { -1168 function OrderInformation(json) { -1169 this.json = json; -1170 } -1171 -1172 OrderInformation.prototype.orderNumber = function() { -1173 return this.json['orderNumber']; -1174 }; -1175 -1176 OrderInformation.prototype.fills = function() { -1177 return this.json['fills']; -1178 }; -1179 -1180 OrderInformation.prototype.quantityOrdered = function() { -1181 return new hQuery.Scalar(this.json['quantityOrdered']); -1182 }; -1183 -1184 OrderInformation.prototype.orderExpirationDateTime = function() { -1185 return hQuery.dateFromUtcSeconds(this.json['orderExpirationDateTime']); -1186 }; +1167 DoseRestriction.prototype.numerator = function() { +1168 if (this.json['numerator']) { +1169 return new hQuery.Scalar(this.json['numerator']); +1170 } +1171 }; +1172 +1173 DoseRestriction.prototype.denominator = function() { +1174 if (this.json['denominator']) { +1175 return new hQuery.Scalar(this.json['denominator']); +1176 } +1177 }; +1178 +1179 return DoseRestriction; +1180 +1181 })(); +1182 +1183 /** +1184 @class Fulfillment - information about when and who fulfilled an order for the medication +1185 @exports Fulfillment as hQuery.Fullfilement +1186 */ 1187 -1188 OrderInformation.prototype.orderDateTime = function() { -1189 return hQuery.dateFromUtcSeconds(this.json['orderDateTime']); -1190 }; -1191 -1192 return OrderInformation; +1188 +1189 hQuery.Fulfillment = (function() { +1190 function Fulfillment(json) { +1191 this.json = json; +1192 } 1193 -1194 })(); -1195 -1196 /** -1197 TypeOfMedication as defined by value set 2.16.840.1.113883.3.88.12.3221.8.19 -1198 which pulls two values from SNOMED to describe whether a medication is -1199 prescription or over the counter -1200 -1201 @class TypeOfMedication - describes whether a medication is prescription or -1202 over the counter -1203 @augments hQuery.CodedEntry -1204 @exports TypeOfMedication as hQuery.TypeOfMedication -1205 */ -1206 -1207 -1208 hQuery.TypeOfMedication = (function(_super) { -1209 var OTC, PRESECRIPTION; -1210 -1211 __extends(TypeOfMedication, _super); -1212 -1213 function TypeOfMedication() { -1214 _ref = TypeOfMedication.__super__.constructor.apply(this, arguments); -1215 return _ref; -1216 } +1194 Fulfillment.prototype.dispenseDate = function() { +1195 return hQuery.dateFromUtcSeconds(this.json['dispenseDate']); +1196 }; +1197 +1198 Fulfillment.prototype.dispensingPharmacyLocation = function() { +1199 if (this.json['dispensingPharmacyLocation']) { +1200 return new hQuery.Address(this.json['dispensingPharmacyLocation']); +1201 } +1202 }; +1203 +1204 Fulfillment.prototype.quantityDispensed = function() { +1205 if (this.json['quantityDispensed']) { +1206 return new hQuery.Scalar(this.json['quantityDispensed']); +1207 } +1208 }; +1209 +1210 Fulfillment.prototype.prescriptionNumber = function() { +1211 return this.json['prescriptionNumber']; +1212 }; +1213 +1214 Fulfillment.prototype.fillNumber = function() { +1215 return this.json['fillNumber']; +1216 }; 1217 -1218 PRESECRIPTION = "73639000"; -1219 -1220 OTC = "329505003"; -1221 -1222 /** -1223 @returns {Boolean} -1224 */ +1218 Fulfillment.prototype.fillStatus = function() { +1219 if (this.json['fillStatus']) { +1220 return new hQuery.Status(this.json['fillStatus']); +1221 } +1222 }; +1223 +1224 return Fulfillment; 1225 -1226 -1227 TypeOfMedication.prototype.isPrescription = function() { -1228 return this.c === PRESECRIPTION; -1229 }; -1230 -1231 /** -1232 @returns {Boolean} -1233 */ -1234 -1235 -1236 TypeOfMedication.prototype.isOverTheCounter = function() { -1237 return this.c === OTC; -1238 }; -1239 -1240 return TypeOfMedication; -1241 -1242 })(hQuery.CodedValue); -1243 -1244 /** -1245 StatusOfMedication as defined by value set 2.16.840.1.113883.1.11.20.7 -1246 The terms come from SNOMED and are managed by HL7 -1247 -1248 @class StatusOfMedication - describes the status of the medication -1249 @augments hQuery.CodedEntry -1250 @exports StatusOfMedication as hQuery.StatusOfMedication -1251 */ +1226 })(); +1227 +1228 /** +1229 @class OrderInformation - information abour an order for a medication +1230 @exports OrderInformation as hQuery.OrderInformation +1231 */ +1232 +1233 +1234 hQuery.OrderInformation = (function() { +1235 function OrderInformation(json) { +1236 this.json = json; +1237 } +1238 +1239 OrderInformation.prototype.orderNumber = function() { +1240 return this.json['orderNumber']; +1241 }; +1242 +1243 OrderInformation.prototype.fills = function() { +1244 return this.json['fills']; +1245 }; +1246 +1247 OrderInformation.prototype.quantityOrdered = function() { +1248 if (this.json['quantityOrdered']) { +1249 return new hQuery.Scalar(this.json['quantityOrdered']); +1250 } +1251 }; 1252 -1253 -1254 hQuery.StatusOfMedication = (function(_super) { -1255 var ACTIVE, NO_LONGER_ACTIVE, ON_HOLD, PRIOR_HISTORY; +1253 OrderInformation.prototype.orderExpirationDateTime = function() { +1254 return hQuery.dateFromUtcSeconds(this.json['orderExpirationDateTime']); +1255 }; 1256 -1257 __extends(StatusOfMedication, _super); -1258 -1259 function StatusOfMedication() { -1260 _ref1 = StatusOfMedication.__super__.constructor.apply(this, arguments); -1261 return _ref1; -1262 } -1263 -1264 ON_HOLD = "392521001"; -1265 -1266 NO_LONGER_ACTIVE = "421139008"; -1267 -1268 ACTIVE = "55561003"; +1257 OrderInformation.prototype.orderDateTime = function() { +1258 return hQuery.dateFromUtcSeconds(this.json['orderDateTime']); +1259 }; +1260 +1261 return OrderInformation; +1262 +1263 })(); +1264 +1265 /** +1266 TypeOfMedication as defined by value set 2.16.840.1.113883.3.88.12.3221.8.19 +1267 which pulls two values from SNOMED to describe whether a medication is +1268 prescription or over the counter 1269 -1270 PRIOR_HISTORY = "73425007"; -1271 -1272 /** -1273 @returns {Boolean} -1274 */ +1270 @class TypeOfMedication - describes whether a medication is prescription or +1271 over the counter +1272 @augments hQuery.CodedEntry +1273 @exports TypeOfMedication as hQuery.TypeOfMedication +1274 */ 1275 1276 -1277 StatusOfMedication.prototype.isOnHold = function() { -1278 return this.c === ON_HOLD; -1279 }; -1280 -1281 /** -1282 @returns {Boolean} -1283 */ -1284 -1285 -1286 StatusOfMedication.prototype.isNoLongerActive = function() { -1287 return this.c === NO_LONGER_ACTIVE; -1288 }; -1289 -1290 /** -1291 @returns {Boolean} -1292 */ -1293 +1277 hQuery.TypeOfMedication = (function(_super) { +1278 var OTC, PRESECRIPTION; +1279 +1280 __extends(TypeOfMedication, _super); +1281 +1282 function TypeOfMedication() { +1283 _ref = TypeOfMedication.__super__.constructor.apply(this, arguments); +1284 return _ref; +1285 } +1286 +1287 PRESECRIPTION = "73639000"; +1288 +1289 OTC = "329505003"; +1290 +1291 /** +1292 @returns {Boolean} +1293 */ 1294 -1295 StatusOfMedication.prototype.isActive = function() { -1296 return this.c === ACTIVE; -1297 }; -1298 -1299 /** -1300 @returns {Boolean} -1301 */ -1302 +1295 +1296 TypeOfMedication.prototype.isPrescription = function() { +1297 return this.c === PRESECRIPTION; +1298 }; +1299 +1300 /** +1301 @returns {Boolean} +1302 */ 1303 -1304 StatusOfMedication.prototype.isPriorHistory = function() { -1305 return this.c === PRIOR_HISTORY; -1306 }; -1307 -1308 return StatusOfMedication; -1309 -1310 })(hQuery.CodedValue); -1311 -1312 /** -1313 @class represents a medication entry for a patient. -1314 @augments hQuery.CodedEntry -1315 @exports Medication as hQuery.Medication -1316 */ -1317 -1318 -1319 hQuery.Medication = (function(_super) { -1320 __extends(Medication, _super); +1304 +1305 TypeOfMedication.prototype.isOverTheCounter = function() { +1306 return this.c === OTC; +1307 }; +1308 +1309 return TypeOfMedication; +1310 +1311 })(hQuery.CodedValue); +1312 +1313 /** +1314 StatusOfMedication as defined by value set 2.16.840.1.113883.1.11.20.7 +1315 The terms come from SNOMED and are managed by HL7 +1316 +1317 @class StatusOfMedication - describes the status of the medication +1318 @augments hQuery.CodedEntry +1319 @exports StatusOfMedication as hQuery.StatusOfMedication +1320 */ 1321 -1322 function Medication(json) { -1323 this.json = json; -1324 Medication.__super__.constructor.call(this, this.json); -1325 } -1326 -1327 /** -1328 @returns {String} -1329 */ -1330 -1331 -1332 Medication.prototype.freeTextSig = function() { -1333 return this.json['freeTextSig']; -1334 }; -1335 -1336 /** -1337 The actual or intended start of a medication. Slight deviation from greenCDA for C32 since -1338 it combines this with medication stop -1339 @returns {Date} -1340 */ -1341 -1342 -1343 Medication.prototype.indicateMedicationStart = function() { -1344 return hQuery.dateFromUtcSeconds(this.json['start_time']); -1345 }; -1346 -1347 /** -1348 The actual or intended stop of a medication. Slight deviation from greenCDA for C32 since -1349 it combines this with medication start -1350 @returns {Date} -1351 */ -1352 +1322 +1323 hQuery.StatusOfMedication = (function(_super) { +1324 var ACTIVE, NO_LONGER_ACTIVE, ON_HOLD, PRIOR_HISTORY; +1325 +1326 __extends(StatusOfMedication, _super); +1327 +1328 function StatusOfMedication() { +1329 _ref1 = StatusOfMedication.__super__.constructor.apply(this, arguments); +1330 return _ref1; +1331 } +1332 +1333 ON_HOLD = "392521001"; +1334 +1335 NO_LONGER_ACTIVE = "421139008"; +1336 +1337 ACTIVE = "55561003"; +1338 +1339 PRIOR_HISTORY = "73425007"; +1340 +1341 /** +1342 @returns {Boolean} +1343 */ +1344 +1345 +1346 StatusOfMedication.prototype.isOnHold = function() { +1347 return this.c === ON_HOLD; +1348 }; +1349 +1350 /** +1351 @returns {Boolean} +1352 */ 1353 -1354 Medication.prototype.indicateMedicationStop = function() { -1355 return hQuery.dateFromUtcSeconds(this.json['end_time']); -1356 }; -1357 -1358 Medication.prototype.administrationTiming = function() { -1359 return new hQuery.AdministrationTiming(this.json['administrationTiming']); -1360 }; -1361 -1362 /** -1363 @returns {CodedValue} Contains routeCode or adminstrationUnitCode information. -1364 Route code shall have a a value drawn from FDA route of adminstration, -1365 and indicates how the medication is received by the patient. -1366 See http://www.fda.gov/Drugs/DevelopmentApprovalProcess/UCM070829 -1367 The administration unit code shall have a value drawn from the FDA -1368 dosage form, source NCI thesaurus and represents the physical form of the -1369 product as presented to the patient. -1370 See http://www.fda.gov/Drugs/InformationOnDrugs/ucm142454.htm -1371 */ +1354 +1355 StatusOfMedication.prototype.isNoLongerActive = function() { +1356 return this.c === NO_LONGER_ACTIVE; +1357 }; +1358 +1359 /** +1360 @returns {Boolean} +1361 */ +1362 +1363 +1364 StatusOfMedication.prototype.isActive = function() { +1365 return this.c === ACTIVE; +1366 }; +1367 +1368 /** +1369 @returns {Boolean} +1370 */ +1371 1372 -1373 -1374 Medication.prototype.route = function() { -1375 return new hQuery.CodedValue(this.json['route']['code'], this.json['route']['codeSystem']); -1376 }; -1377 -1378 /** -1379 @returns {hQuery.Scalar} the dose -1380 */ -1381 -1382 -1383 Medication.prototype.dose = function() { -1384 return new hQuery.Scalar(this.json['dose']); -1385 }; +1373 StatusOfMedication.prototype.isPriorHistory = function() { +1374 return this.c === PRIOR_HISTORY; +1375 }; +1376 +1377 return StatusOfMedication; +1378 +1379 })(hQuery.CodedValue); +1380 +1381 /** +1382 @class represents a medication entry for a patient. +1383 @augments hQuery.CodedEntry +1384 @exports Medication as hQuery.Medication +1385 */ 1386 -1387 /** -1388 @returns {CodedValue} -1389 */ +1387 +1388 hQuery.Medication = (function(_super) { +1389 __extends(Medication, _super); 1390 -1391 -1392 Medication.prototype.site = function() { -1393 return new hQuery.CodedValue(this.json['site']['code'], this.json['site']['codeSystem']); -1394 }; +1391 function Medication(json) { +1392 this.json = json; +1393 Medication.__super__.constructor.call(this, this.json); +1394 } 1395 1396 /** -1397 @returns {hQuery.DoseRestriction} +1397 @returns {String} 1398 */ 1399 1400 -1401 Medication.prototype.doseRestriction = function() { -1402 return new hQuery.DoseRestriction(this.json['doseRestriction']); +1401 Medication.prototype.freeTextSig = function() { +1402 return this.json['freeTextSig']; 1403 }; 1404 1405 /** -1406 @returns {String} -1407 */ -1408 -1409 -1410 Medication.prototype.doseIndicator = function() { -1411 return this.json['doseIndicator']; -1412 }; -1413 -1414 /** -1415 @returns {String} -1416 */ -1417 -1418 -1419 Medication.prototype.fulfillmentInstructions = function() { -1420 return this.json['fulfillmentInstructions']; -1421 }; +1406 The actual or intended start of a medication. Slight deviation from greenCDA for C32 since +1407 it combines this with medication stop +1408 @returns {Date} +1409 */ +1410 +1411 +1412 Medication.prototype.indicateMedicationStart = function() { +1413 return hQuery.dateFromUtcSeconds(this.json['start_time']); +1414 }; +1415 +1416 /** +1417 The actual or intended stop of a medication. Slight deviation from greenCDA for C32 since +1418 it combines this with medication start +1419 @returns {Date} +1420 */ +1421 1422 -1423 /** -1424 @returns {CodedValue} -1425 */ +1423 Medication.prototype.indicateMedicationStop = function() { +1424 return hQuery.dateFromUtcSeconds(this.json['end_time']); +1425 }; 1426 -1427 -1428 Medication.prototype.indication = function() { -1429 return new hQuery.CodedValue(this.json['indication']['code'], this.json['indication']['codeSystem']); -1430 }; -1431 -1432 /** -1433 @returns {CodedValue} -1434 */ -1435 -1436 -1437 Medication.prototype.productForm = function() { -1438 return new hQuery.CodedValue(this.json['productForm']['code'], this.json['productForm']['codeSystem']); -1439 }; -1440 -1441 /** -1442 @returns {CodedValue} -1443 */ +1427 Medication.prototype.administrationTiming = function() { +1428 if (this.json['administrationTiming']) { +1429 return new hQuery.AdministrationTiming(this.json['administrationTiming']); +1430 } +1431 }; +1432 +1433 /** +1434 @returns {CodedValue} Contains routeCode or adminstrationUnitCode information. +1435 Route code shall have a a value drawn from FDA route of adminstration, +1436 and indicates how the medication is received by the patient. +1437 See http://www.fda.gov/Drugs/DevelopmentApprovalProcess/UCM070829 +1438 The administration unit code shall have a value drawn from the FDA +1439 dosage form, source NCI thesaurus and represents the physical form of the +1440 product as presented to the patient. +1441 See http://www.fda.gov/Drugs/InformationOnDrugs/ucm142454.htm +1442 */ +1443 1444 -1445 -1446 Medication.prototype.vehicle = function() { -1447 return new hQuery.CodedValue(this.json['vehicle']['code'], this.json['vehicle']['codeSystem']); -1448 }; -1449 -1450 /** -1451 @returns {CodedValue} -1452 */ +1445 Medication.prototype.route = function() { +1446 return hQuery.createCodedValue(this.json['route']); +1447 }; +1448 +1449 /** +1450 @returns {hQuery.Scalar} the dose +1451 */ +1452 1453 -1454 -1455 Medication.prototype.reaction = function() { -1456 return new hQuery.CodedValue(this.json['reaction']['code'], this.json['reaction']['codeSystem']); -1457 }; -1458 -1459 /** -1460 @returns {CodedValue} -1461 */ -1462 +1454 Medication.prototype.dose = function() { +1455 if (this.json['dose']) { +1456 return new hQuery.Scalar(this.json['dose']); +1457 } +1458 }; +1459 +1460 /** +1461 @returns {CodedValue} +1462 */ 1463 -1464 Medication.prototype.deliveryMethod = function() { -1465 return new hQuery.CodedValue(this.json['deliveryMethod']['code'], this.json['deliveryMethod']['codeSystem']); -1466 }; -1467 -1468 /** -1469 @returns {hQuery.MedicationInformation} -1470 */ -1471 -1472 -1473 Medication.prototype.medicationInformation = function() { -1474 return new hQuery.MedicationInformation(this.json); -1475 }; -1476 -1477 /** -1478 @returns {hQuery.TypeOfMedication} Indicates whether this is an over the counter or prescription medication -1479 */ -1480 +1464 +1465 Medication.prototype.site = function() { +1466 if (this.json['site']) { +1467 return hQuery.createCodedValue(this.json['site']); +1468 } +1469 }; +1470 +1471 /** +1472 @returns {hQuery.DoseRestriction} +1473 */ +1474 +1475 +1476 Medication.prototype.doseRestriction = function() { +1477 if (this.json['doseRestriction']) { +1478 return new hQuery.DoseRestriction(this.json['doseRestriction']); +1479 } +1480 }; 1481 -1482 Medication.prototype.typeOfMedication = function() { -1483 return new hQuery.TypeOfMedication(this.json['typeOfMedication']['code'], this.json['typeOfMedication']['codeSystem']); -1484 }; +1482 /** +1483 @returns {String} +1484 */ 1485 -1486 /** -1487 Values conform to value set 2.16.840.1.113883.1.11.20.7 - Medication Status -1488 Values may be: On Hold, No Longer Active, Active, Prior History -1489 @returns {hQuery.StatusOfMedication} Used to indicate the status of the medication. -1490 */ -1491 -1492 -1493 Medication.prototype.statusOfMedication = function() { -1494 return new hQuery.StatusOfMedication(this.json['statusOfMedication']['code'], this.json['statusOfMedication']['codeSystem']); -1495 }; -1496 -1497 /** -1498 @returns {String} free text instructions to the patient -1499 */ -1500 -1501 -1502 Medication.prototype.patientInstructions = function() { -1503 return this.json['patientInstructions']; -1504 }; -1505 -1506 /** -1507 The duration over which this medication has been active. For example, 5 days. -1508 @returns {Hash} with two keys: unit and scalar -1509 */ -1510 -1511 -1512 Medication.prototype.cumulativeMedicationDuration = function() { -1513 return this.json['cumulativeMedicationDuration']; -1514 }; -1515 -1516 /** -1517 @returns {Array} an array of {@link FulFillment} objects -1518 */ -1519 -1520 -1521 Medication.prototype.fulfillmentHistory = function() { -1522 var order, _i, _len, _ref2, _results; -1523 -1524 _ref2 = this.json['fulfillmentHistory']; -1525 _results = []; -1526 for (_i = 0, _len = _ref2.length; _i < _len; _i++) { -1527 order = _ref2[_i]; -1528 _results.push(new hQuery.Fulfillment(order)); -1529 } -1530 return _results; -1531 }; -1532 -1533 /** -1534 @returns {Array} an array of {@link OrderInformation} objects -1535 */ -1536 -1537 -1538 Medication.prototype.orderInformation = function() { -1539 var order, _i, _len, _ref2, _results; +1486 +1487 Medication.prototype.doseIndicator = function() { +1488 return this.json['doseIndicator']; +1489 }; +1490 +1491 /** +1492 @returns {String} +1493 */ +1494 +1495 +1496 Medication.prototype.fulfillmentInstructions = function() { +1497 return this.json['fulfillmentInstructions']; +1498 }; +1499 +1500 /** +1501 @returns {CodedValue} +1502 */ +1503 +1504 +1505 Medication.prototype.indication = function() { +1506 return hQuery.createCodedValue(this.json['indication']); +1507 }; +1508 +1509 /** +1510 @returns {CodedValue} +1511 */ +1512 +1513 +1514 Medication.prototype.productForm = function() { +1515 return hQuery.createCodedValue(this.json['productForm']); +1516 }; +1517 +1518 /** +1519 @returns {CodedValue} +1520 */ +1521 +1522 +1523 Medication.prototype.vehicle = function() { +1524 return hQuery.createCodedValue(this.json['vehicle']); +1525 }; +1526 +1527 /** +1528 @returns {CodedValue} +1529 */ +1530 +1531 +1532 Medication.prototype.reaction = function() { +1533 return hQuery.createCodedValue(this.json['reaction']); +1534 }; +1535 +1536 /** +1537 @returns {CodedValue} +1538 */ +1539 1540 -1541 _ref2 = this.json['orderInformation']; -1542 _results = []; -1543 for (_i = 0, _len = _ref2.length; _i < _len; _i++) { -1544 order = _ref2[_i]; -1545 _results.push(new hQuery.OrderInformation(order)); -1546 } -1547 return _results; -1548 }; +1541 Medication.prototype.deliveryMethod = function() { +1542 return hQuery.createCodedValue(this.json['deliveryMethod']); +1543 }; +1544 +1545 /** +1546 @returns {hQuery.MedicationInformation} +1547 */ +1548 1549 -1550 return Medication; -1551 -1552 })(hQuery.CodedEntry); -1553 /** -1554 @namespace scoping into the hquery namespace -1555 */ -1556 -1557 var __hasProp = {}.hasOwnProperty, -1558 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; -1559 -1560 this.hQuery || (this.hQuery = {}); +1550 Medication.prototype.medicationInformation = function() { +1551 return new hQuery.MedicationInformation(this.json); +1552 }; +1553 +1554 /** +1555 @returns {hQuery.TypeOfMedication} Indicates whether this is an over the counter or prescription medication +1556 */ +1557 +1558 +1559 Medication.prototype.typeOfMedication = function() { +1560 var _ref2, _ref3; 1561 -1562 /** -1563 @class CauseOfDeath -1564 @exports CauseOfDeath as hQuery.CauseOfDeath -1565 */ -1566 -1567 -1568 hQuery.CauseOfDeath = (function() { -1569 function CauseOfDeath(json) { -1570 this.json = json; -1571 } -1572 -1573 /** -1574 @returns {hQuery.Date} -1575 */ -1576 +1562 return new hQuery.TypeOfMedication((_ref2 = this.json['typeOfMedication']) != null ? _ref2['code'] : void 0, (_ref3 = this.json['typeOfMedication']) != null ? _ref3['code_system'] : void 0); +1563 }; +1564 +1565 /** +1566 Values conform to value set 2.16.840.1.113883.1.11.20.7 - Medication Status +1567 Values may be: On Hold, No Longer Active, Active, Prior History +1568 @returns {hQuery.StatusOfMedication} Used to indicate the status of the medication. +1569 */ +1570 +1571 +1572 Medication.prototype.statusOfMedication = function() { +1573 var _ref2, _ref3; +1574 +1575 return new hQuery.StatusOfMedication((_ref2 = this.json['statusOfMedication']) != null ? _ref2['code'] : void 0, (_ref3 = this.json['statusOfMedication']) != null ? _ref3['code_system'] : void 0); +1576 }; 1577 -1578 CauseOfDeath.prototype.timeOfDeath = function() { -1579 return new hQuery.dateFromUtcSeconds(this.json['timeOfDeath']); -1580 }; +1578 /** +1579 @returns {String} free text instructions to the patient +1580 */ 1581 -1582 /** -1583 @returns {int} -1584 */ -1585 +1582 +1583 Medication.prototype.patientInstructions = function() { +1584 return this.json['patientInstructions']; +1585 }; 1586 -1587 CauseOfDeath.prototype.ageAtDeath = function() { -1588 return this.json['ageAtDeath']; -1589 }; -1590 -1591 return CauseOfDeath; +1587 /** +1588 The duration over which this medication has been active. For example, 5 days. +1589 @returns {Hash} with two keys: unit and scalar +1590 */ +1591 1592 -1593 })(); -1594 -1595 /** -1596 @class hQuery.Condition -1597 -1598 This section is used to describe a patients problems/conditions. The types of conditions -1599 described have been constrained to the SNOMED CT Problem Type code set. An unbounded -1600 number of treating providers for the particular condition can be supplied. -1601 @exports Condition as hQuery.Condition -1602 @augments hQuery.CodedEntry -1603 */ +1593 Medication.prototype.cumulativeMedicationDuration = function() { +1594 return this.json['cumulativeMedicationDuration']; +1595 }; +1596 +1597 /** +1598 @returns {Array} an array of {@link FulFillment} objects +1599 */ +1600 +1601 +1602 Medication.prototype.fulfillmentHistory = function() { +1603 var order, _i, _len, _ref2, _results; 1604 -1605 -1606 hQuery.Condition = (function(_super) { -1607 __extends(Condition, _super); -1608 -1609 function Condition(json) { -1610 this.json = json; -1611 Condition.__super__.constructor.call(this, this.json); -1612 } +1605 _ref2 = this.json['fulfillmentHistory']; +1606 _results = []; +1607 for (_i = 0, _len = _ref2.length; _i < _len; _i++) { +1608 order = _ref2[_i]; +1609 _results.push(new hQuery.Fulfillment(order)); +1610 } +1611 return _results; +1612 }; 1613 1614 /** -1615 @returns {Array, hQuery.Provider} an array of providers for the condition +1615 @returns {Array} an array of {@link OrderInformation} objects 1616 */ 1617 1618 -1619 Condition.prototype.providers = function() { -1620 var provider, _i, _len, _ref, _results; +1619 Medication.prototype.orderInformation = function() { +1620 var order, _i, _len, _ref2, _results; 1621 -1622 _ref = this.json['treatingProviders']; +1622 _ref2 = this.json['orderInformation']; 1623 _results = []; -1624 for (_i = 0, _len = _ref.length; _i < _len; _i++) { -1625 provider = _ref[_i]; -1626 _results.push(new Provider(provider)); +1624 for (_i = 0, _len = _ref2.length; _i < _len; _i++) { +1625 order = _ref2[_i]; +1626 _results.push(new hQuery.OrderInformation(order)); 1627 } 1628 return _results; 1629 }; 1630 -1631 /** -1632 Diagnosis Priority -1633 @returns {int} -1634 */ -1635 -1636 -1637 Condition.prototype.diagnosisPriority = function() { -1638 return this.json['priority']; -1639 }; +1631 return Medication; +1632 +1633 })(hQuery.CodedEntry); +1634 /** +1635 @namespace scoping into the hquery namespace +1636 */ +1637 +1638 var __hasProp = {}.hasOwnProperty, +1639 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; 1640 -1641 /** -1642 Ordinality -1643 @returns {String} -1644 */ -1645 -1646 -1647 Condition.prototype.ordinality = function() { -1648 return this.json['ordinality']; -1649 }; -1650 -1651 /** -1652 age at onset -1653 @returns {int} -1654 */ -1655 -1656 -1657 Condition.prototype.ageAtOnset = function() { -1658 return this.json['ageAtOnset']; -1659 }; -1660 -1661 /** -1662 cause of death -1663 @returns {hQuery.CauseOfDeath} -1664 */ -1665 +1641 this.hQuery || (this.hQuery = {}); +1642 +1643 /** +1644 @class CauseOfDeath +1645 @exports CauseOfDeath as hQuery.CauseOfDeath +1646 */ +1647 +1648 +1649 hQuery.CauseOfDeath = (function() { +1650 function CauseOfDeath(json) { +1651 this.json = json; +1652 } +1653 +1654 /** +1655 @returns {hQuery.Date} +1656 */ +1657 +1658 +1659 CauseOfDeath.prototype.timeOfDeath = function() { +1660 return new hQuery.dateFromUtcSeconds(this.json['timeOfDeath']); +1661 }; +1662 +1663 /** +1664 @returns {int} +1665 */ 1666 -1667 Condition.prototype.causeOfDeath = function() { -1668 return new hQuery.CauseOfDeath(this.json['causeOfDeath']); -1669 }; -1670 -1671 /** -1672 problem status -1673 @returns {hQuery.CodedValue} -1674 */ +1667 +1668 CauseOfDeath.prototype.ageAtDeath = function() { +1669 return this.json['ageAtDeath']; +1670 }; +1671 +1672 return CauseOfDeath; +1673 +1674 })(); 1675 -1676 -1677 Condition.prototype.problemStatus = function() { -1678 return new hQuery.CodedValue(this.json['problemStatus']['code'], this.json['problemStatus']['codeSystem']); -1679 }; -1680 -1681 /** -1682 comment -1683 @returns {String} -1684 */ +1676 /** +1677 @class hQuery.Condition +1678 +1679 This section is used to describe a patients problems/conditions. The types of conditions +1680 described have been constrained to the SNOMED CT Problem Type code set. An unbounded +1681 number of treating providers for the particular condition can be supplied. +1682 @exports Condition as hQuery.Condition +1683 @augments hQuery.CodedEntry +1684 */ 1685 1686 -1687 Condition.prototype.comment = function() { -1688 return this.json['comment']; -1689 }; -1690 -1691 /** -1692 This is a description of the level of the severity of the condition. -1693 @returns {CodedValue} -1694 */ -1695 -1696 -1697 Condition.prototype.severity = function() { -1698 return new hQuery.CodedValue(this.json['severity']['code'], this.json['severity']['codeSystem']); -1699 }; -1700 -1701 return Condition; +1687 hQuery.Condition = (function(_super) { +1688 __extends(Condition, _super); +1689 +1690 function Condition(json) { +1691 this.json = json; +1692 Condition.__super__.constructor.call(this, this.json); +1693 } +1694 +1695 /** +1696 @returns {Array, hQuery.Provider} an array of providers for the condition +1697 */ +1698 +1699 +1700 Condition.prototype.providers = function() { +1701 var provider, _i, _len, _ref, _results; 1702 -1703 })(hQuery.CodedEntry); -1704 /** -1705 @namespace scoping into the hquery namespace -1706 */ -1707 -1708 var __hasProp = {}.hasOwnProperty, -1709 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; -1710 -1711 this.hQuery || (this.hQuery = {}); -1712 -1713 /** -1714 An Encounter is an interaction, regardless of the setting, between a patient and a -1715 practitioner who is vested with primary responsibility for diagnosing, evaluating, -1716 or treating the patient's condition. It may include visits, appointments, as well -1717 as non face-to-face interactions. It is also a contact between a patient and a -1718 practitioner who has primary responsibility for assessing and treating the -1719 patient at a given contact, exercising independent judgment. -1720 @class An Encounter is an interaction, regardless of the setting, between a patient and a -1721 practitioner -1722 @augments hQuery.CodedEntry -1723 @exports Encounter as hQuery.Encounter -1724 */ -1725 +1703 _ref = this.json['treatingProviders']; +1704 _results = []; +1705 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +1706 provider = _ref[_i]; +1707 _results.push(new Provider(provider)); +1708 } +1709 return _results; +1710 }; +1711 +1712 /** +1713 Diagnosis Priority +1714 @returns {int} +1715 */ +1716 +1717 +1718 Condition.prototype.diagnosisPriority = function() { +1719 return this.json['priority']; +1720 }; +1721 +1722 /** +1723 Ordinality +1724 @returns {CodedValue} +1725 */ 1726 -1727 hQuery.Encounter = (function(_super) { -1728 __extends(Encounter, _super); -1729 -1730 function Encounter(json) { -1731 this.json = json; -1732 Encounter.__super__.constructor.call(this, this.json); -1733 } -1734 -1735 /** -1736 @returns {String} -1737 */ -1738 -1739 -1740 Encounter.prototype.dischargeDisp = function() { -1741 return this.json['dischargeDisp']; -1742 }; -1743 -1744 /** -1745 A code indicating the priority of the admission (e.g., Emergency, Urgent, Elective, et cetera) from -1746 National Uniform Billing Committee (NUBC) -1747 @returns {CodedValue} -1748 */ -1749 -1750 -1751 Encounter.prototype.admitType = function() { -1752 return new hQuery.CodedValue(this.json['admitType']['code'], this.json['admitType']['codeSystem']); -1753 }; -1754 -1755 /** -1756 @returns {hQuery.Actor} +1727 +1728 Condition.prototype.ordinality = function() { +1729 return hQuery.createCodedValue(this.json['ordinality']); +1730 }; +1731 +1732 /** +1733 age at onset +1734 @returns {int} +1735 */ +1736 +1737 +1738 Condition.prototype.ageAtOnset = function() { +1739 return this.json['ageAtOnset']; +1740 }; +1741 +1742 /** +1743 cause of death +1744 @returns {hQuery.CauseOfDeath} +1745 */ +1746 +1747 +1748 Condition.prototype.causeOfDeath = function() { +1749 if (this.json['causeOfDeath']) { +1750 return new hQuery.CauseOfDeath(this.json['causeOfDeath']); +1751 } +1752 }; +1753 +1754 /** +1755 problem status +1756 @returns {hQuery.CodedValue} 1757 */ 1758 1759 -1760 Encounter.prototype.performer = function() { -1761 return new hQuery.Actor(this.json['performer']); +1760 Condition.prototype.problemStatus = function() { +1761 return hQuery.createCodedValue(this.json['problemStatus']); 1762 }; 1763 1764 /** -1765 @returns {hQuery.Organization} -1766 */ -1767 +1765 comment +1766 @returns {String} +1767 */ 1768 -1769 Encounter.prototype.facility = function() { -1770 return new hQuery.Facility(this.json['facility']); -1771 }; -1772 -1773 /** -1774 @returns {hQuery.DateRange} -1775 */ -1776 -1777 -1778 Encounter.prototype.encounterDuration = function() { -1779 return new hQuery.DateRange(this.json); -1780 }; -1781 -1782 /** -1783 @returns {hQuery.CodedEntry} -1784 */ +1769 +1770 Condition.prototype.comment = function() { +1771 return this.json['comment']; +1772 }; +1773 +1774 /** +1775 This is a description of the level of the severity of the condition. +1776 @returns {CodedValue} +1777 */ +1778 +1779 +1780 Condition.prototype.severity = function() { +1781 return hQuery.createCodedValue(this.json['severity']); +1782 }; +1783 +1784 return Condition; 1785 -1786 -1787 Encounter.prototype.reasonForVisit = function() { -1788 return new hQuery.CodedEntry(this.json['reason']); -1789 }; +1786 })(hQuery.CodedEntry); +1787 /** +1788 @namespace scoping into the hquery namespace +1789 */ 1790 -1791 return Encounter; -1792 -1793 })(hQuery.CodedEntry); -1794 /** -1795 @namespace scoping into the hquery namespace -1796 */ -1797 -1798 var __hasProp = {}.hasOwnProperty, -1799 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; -1800 -1801 this.hQuery || (this.hQuery = {}); -1802 -1803 /** -1804 This represents all interventional, surgical, diagnostic, or therapeutic procedures or -1805 treatments pertinent to the patient. -1806 @class -1807 @augments hQuery.CodedEntry -1808 @exports Procedure as hQuery.Procedure -1809 */ -1810 -1811 -1812 hQuery.Procedure = (function(_super) { -1813 __extends(Procedure, _super); -1814 -1815 function Procedure(json) { -1816 this.json = json; -1817 Procedure.__super__.constructor.call(this, this.json); -1818 } -1819 -1820 /** -1821 @returns {hQuery.Actor} The provider that performed the procedure -1822 */ -1823 -1824 -1825 Procedure.prototype.performer = function() { -1826 return new hQuery.Actor(this.json['performer']); -1827 }; -1828 -1829 /** -1830 @returns {hQuery.CodedValue} A SNOMED code indicating the body site on which the -1831 procedure was performed -1832 */ -1833 -1834 -1835 Procedure.prototype.site = function() { -1836 return new hQuery.CodedValue(this.json['site']['code'], this.json['site']['codeSystem']); -1837 }; -1838 -1839 return Procedure; -1840 -1841 })(hQuery.CodedEntry); -1842 /** -1843 @namespace scoping into the hquery namespace -1844 */ -1845 -1846 var __hasProp = {}.hasOwnProperty, -1847 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; -1848 -1849 this.hQuery || (this.hQuery = {}); -1850 -1851 /** -1852 Observations generated by laboratories, imaging procedures, and other procedures. The scope -1853 includes hematology, chemistry, serology, virology, toxicology, microbiology, plain x-ray, -1854 ultrasound, CT, MRI, angiography, cardiac echo, nuclear medicine, pathology, and procedure -1855 observations. -1856 @class -1857 @augments hQuery.CodedEntry -1858 @exports Result as hQuery.Result -1859 */ -1860 +1791 var __hasProp = {}.hasOwnProperty, +1792 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; +1793 +1794 this.hQuery || (this.hQuery = {}); +1795 +1796 /** +1797 An Encounter is an interaction, regardless of the setting, between a patient and a +1798 practitioner who is vested with primary responsibility for diagnosing, evaluating, +1799 or treating the patients condition. It may include visits, appointments, as well +1800 as non face-to-face interactions. It is also a contact between a patient and a +1801 practitioner who has primary responsibility for assessing and treating the +1802 patient at a given contact, exercising independent judgment. +1803 @class An Encounter is an interaction, regardless of the setting, between a patient and a +1804 practitioner +1805 @augments hQuery.CodedEntry +1806 @exports Encounter as hQuery.Encounter +1807 */ +1808 +1809 +1810 hQuery.Encounter = (function(_super) { +1811 __extends(Encounter, _super); +1812 +1813 function Encounter(json) { +1814 this.json = json; +1815 Encounter.__super__.constructor.call(this, this.json); +1816 if (this.json['admitTime']) { +1817 this._admitTime = hQuery.dateFromUtcSeconds(this.json['admitTime']); +1818 } +1819 if (this.json['dischargeTime']) { +1820 this._dischargeTime = hQuery.dateFromUtcSeconds(this.json['dischargeTime']); +1821 } +1822 if (this.json['facility']) { +1823 this._facility = new hQuery.Facility(this.json['facility']); +1824 } +1825 } +1826 +1827 /** +1828 @returns {String} +1829 */ +1830 +1831 +1832 Encounter.prototype.dischargeDisposition = function() { +1833 return this.json['dischargeDisposition']; +1834 }; +1835 +1836 /** +1837 A code indicating the priority of the admission (e.g., Emergency, Urgent, Elective, et cetera) from +1838 National Uniform Billing Committee (NUBC) +1839 @returns {CodedValue} +1840 */ +1841 +1842 +1843 Encounter.prototype.admitType = function() { +1844 return hQuery.createCodedValue(this.json['admitType']); +1845 }; +1846 +1847 /** +1848 Date and time at which the patient was admitted for the encounter +1849 @returns {Date} +1850 */ +1851 +1852 +1853 Encounter.prototype.admitTime = function() { +1854 return this._admitTime; +1855 }; +1856 +1857 /** +1858 Date and time at which the patient was discharged for the encounter +1859 @returns {Date} +1860 */ 1861 -1862 hQuery.Result = (function(_super) { -1863 __extends(Result, _super); -1864 -1865 function Result(json) { -1866 this.json = json; -1867 Result.__super__.constructor.call(this, this.json); -1868 } -1869 -1870 /** -1871 ASTM CCR defines a restricted set of required result Type codes (see ResultTypeCode in section 7.3 -1872 Summary of CCD value sets), used to categorize a result into one of several commonly accepted values -1873 (e.g. Hematology, Chemistry, Nuclear Medicine). -1874 @returns {CodedValue} -1875 */ -1876 +1862 +1863 Encounter.prototype.dischargeTime = function() { +1864 return this._dischargeTime; +1865 }; +1866 +1867 /** +1868 @returns {hQuery.Actor} +1869 */ +1870 +1871 +1872 Encounter.prototype.performer = function() { +1873 if (this.json['performer']) { +1874 return new hQuery.Actor(this.json['performer']); +1875 } +1876 }; 1877 -1878 Result.prototype.resultType = function() { -1879 return this.type(); -1880 }; +1878 /** +1879 @returns {hQuery.Organization} +1880 */ 1881 -1882 /** -1883 @returns {CodedValue} -1884 */ -1885 +1882 +1883 Encounter.prototype.facility = function() { +1884 return this._facility; +1885 }; 1886 -1887 Result.prototype.interpretation = function() { -1888 return new hQuery.CodedValue(this.json['interpretation'].code, this.json['interpretation'].codeSystem); -1889 }; -1890 -1891 /** -1892 @returns {String} -1893 */ -1894 +1887 Encounter.prototype.facilityArrival = function() { +1888 var _ref; +1889 +1890 return (_ref = this._facility) != null ? _ref.startDate() : void 0; +1891 }; +1892 +1893 Encounter.prototype.facilityDeparture = function() { +1894 var _ref; 1895 -1896 Result.prototype.referenceRange = function() { -1897 return this.json['referenceRange']; -1898 }; -1899 -1900 /** -1901 @returns {String} -1902 */ +1896 return (_ref = this._facility) != null ? _ref.endDate() : void 0; +1897 }; +1898 +1899 /** +1900 @returns {hQuery.CodedEntry} +1901 */ +1902 1903 -1904 -1905 Result.prototype.comment = function() { -1906 return this.json['comment']; -1907 }; -1908 -1909 return Result; -1910 -1911 })(hQuery.CodedEntry); -1912 /** -1913 @namespace scoping into the hquery namespace -1914 */ -1915 -1916 var _ref, -1917 __hasProp = {}.hasOwnProperty, -1918 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; -1919 -1920 this.hQuery || (this.hQuery = {}); +1904 Encounter.prototype.reasonForVisit = function() { +1905 if (this.json['reason']) { +1906 return new hQuery.CodedEntry(this.json['reason']); +1907 } +1908 }; +1909 +1910 /** +1911 @returns {Integer} +1912 */ +1913 +1914 +1915 Encounter.prototype.lengthOfStay = function() { +1916 if (!((this.startDate() != null) && (this.endDate() != null))) { +1917 return 0; +1918 } +1919 return Math.floor((this.endDate() - this.startDate()) / (1000 * 60 * 60 * 24)); +1920 }; 1921 -1922 /** -1923 NoImmunzation as defined by value set 2.16.840.1.113883.1.11.19717 -1924 The terms come from Health Level Seven (HL7) Version 3.0 Vocabulary and are managed by HL7 -1925 It indicates the reason an immunization was not administered. +1922 /** +1923 @returns {CodedValue} +1924 */ +1925 1926 -1927 @class NoImmunization - describes the status of the medication -1928 @augments hQuery.CodedEntry -1929 @exports NoImmunization as hQuery.NoImmunization -1930 */ -1931 -1932 -1933 hQuery.NoImmunization = (function(_super) { -1934 var IMMUNITY, MED_PRECAUTION, OUT_OF_STOCK, PAT_OBJ, PHIL_OBJ, REL_OBJ, VAC_EFF, VAC_SAFETY; +1927 Encounter.prototype.transferTo = function() { +1928 return hQuery.createCodedValue(this.json['transferTo']); +1929 }; +1930 +1931 /** +1932 @returns {CodedValue} +1933 */ +1934 1935 -1936 __extends(NoImmunization, _super); -1937 -1938 function NoImmunization() { -1939 _ref = NoImmunization.__super__.constructor.apply(this, arguments); -1940 return _ref; -1941 } -1942 -1943 IMMUNITY = "IMMUNE"; -1944 -1945 MED_PRECAUTION = "MEDPREC"; +1936 Encounter.prototype.transferFrom = function() { +1937 return hQuery.createCodedValue(this.json['transferFrom']); +1938 }; +1939 +1940 return Encounter; +1941 +1942 })(hQuery.CodedEntry); +1943 /** +1944 @namespace scoping into the hquery namespace +1945 */ 1946 -1947 OUT_OF_STOCK = "OSTOCK"; -1948 -1949 PAT_OBJ = "PATOBJ"; -1950 -1951 PHIL_OBJ = "PHILISOP"; -1952 -1953 REL_OBJ = "RELIG"; -1954 -1955 VAC_EFF = "VACEFF"; -1956 -1957 VAC_SAFETY = "VACSAF"; -1958 -1959 /** -1960 @returns {Boolean} -1961 */ -1962 +1947 var __hasProp = {}.hasOwnProperty, +1948 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; +1949 +1950 this.hQuery || (this.hQuery = {}); +1951 +1952 /** +1953 This represents all interventional, surgical, diagnostic, or therapeutic procedures or +1954 treatments pertinent to the patient. +1955 @class +1956 @augments hQuery.CodedEntry +1957 @exports Procedure as hQuery.Procedure +1958 */ +1959 +1960 +1961 hQuery.Procedure = (function(_super) { +1962 __extends(Procedure, _super); 1963 -1964 NoImmunization.prototype.isImmune = function() { -1965 return this.c === IMMUNITY; -1966 }; -1967 -1968 /** -1969 @returns {Boolean} -1970 */ -1971 +1964 function Procedure(json) { +1965 this.json = json; +1966 Procedure.__super__.constructor.call(this, this.json); +1967 } +1968 +1969 /** +1970 @returns {hQuery.Actor} The provider that performed the procedure +1971 */ 1972 -1973 NoImmunization.prototype.isMedPrec = function() { -1974 return this.c === MED_PRECAUTION; -1975 }; -1976 -1977 /** -1978 @returns {Boolean} -1979 */ -1980 -1981 -1982 NoImmunization.prototype.isOstock = function() { -1983 return this.c === OUT_OF_STOCK; -1984 }; +1973 +1974 Procedure.prototype.performer = function() { +1975 if (this.json['performer']) { +1976 return new hQuery.Actor(this.json['performer']); +1977 } +1978 }; +1979 +1980 /** +1981 @returns {hQuery.CodedValue} A SNOMED code indicating the body site on which the +1982 procedure was performed +1983 */ +1984 1985 -1986 /** -1987 @returns {Boolean} -1988 */ -1989 -1990 -1991 NoImmunization.prototype.isPatObj = function() { -1992 return this.c === PAT_OBJ; -1993 }; -1994 -1995 /** -1996 @returns {Boolean} -1997 */ -1998 -1999 -2000 NoImmunization.prototype.isPhilisop = function() { -2001 return this.c === PHIL_OBJ; -2002 }; -2003 -2004 /** -2005 @returns {Boolean} -2006 */ -2007 -2008 -2009 NoImmunization.prototype.isRelig = function() { -2010 return this.c === REL_OBJ; -2011 }; -2012 -2013 /** -2014 @returns {Boolean} +1986 Procedure.prototype.site = function() { +1987 var _ref, _ref1; +1988 +1989 return new hQuery.CodedValue((_ref = this.json['site']) != null ? _ref['code'] : void 0, (_ref1 = this.json['site']) != null ? _ref1['code_system'] : void 0); +1990 }; +1991 +1992 /** +1993 @returns {hQuery.CodedValue} A SNOMED code indicating where the procedure was performed. +1994 */ +1995 +1996 +1997 Procedure.prototype.source = function() { +1998 return hQuery.createCodedValue(this.json['source']); +1999 }; +2000 +2001 /** +2002 @returns {Date} The actual or intended start of an incision. +2003 */ +2004 +2005 +2006 Procedure.prototype.incisionTime = function() { +2007 if (this.json['incisionTime']) { +2008 return hQuery.dateFromUtcSeconds(this.json['incisionTime']); +2009 } +2010 }; +2011 +2012 /** +2013 Ordinality +2014 @returns {CodedValue} 2015 */ 2016 2017 -2018 NoImmunization.prototype.isVacEff = function() { -2019 return this.c === VAC_EFF; +2018 Procedure.prototype.ordinality = function() { +2019 return hQuery.createCodedValue(this.json['ordinality']); 2020 }; 2021 -2022 /** -2023 @returns {Boolean} -2024 */ -2025 -2026 -2027 NoImmunization.prototype.isVacSaf = function() { -2028 return this.c === VAC_SAFETY; -2029 }; -2030 -2031 return NoImmunization; -2032 -2033 })(hQuery.CodedValue); -2034 -2035 /** -2036 @class represents a immunization entry for a patient. -2037 @augments hQuery.CodedEntry -2038 @exports Immunization as hQuery.Immunization -2039 */ -2040 -2041 -2042 hQuery.Immunization = (function(_super) { -2043 __extends(Immunization, _super); +2022 return Procedure; +2023 +2024 })(hQuery.CodedEntry); +2025 /** +2026 @namespace scoping into the hquery namespace +2027 */ +2028 +2029 var __hasProp = {}.hasOwnProperty, +2030 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; +2031 +2032 this.hQuery || (this.hQuery = {}); +2033 +2034 /** +2035 Observations generated by laboratories, imaging procedures, and other procedures. The scope +2036 includes hematology, chemistry, serology, virology, toxicology, microbiology, plain x-ray, +2037 ultrasound, CT, MRI, angiography, cardiac echo, nuclear medicine, pathology, and procedure +2038 observations. +2039 @class +2040 @augments hQuery.CodedEntry +2041 @exports Result as hQuery.Result +2042 */ +2043 2044 -2045 function Immunization(json) { -2046 this.json = json; -2047 Immunization.__super__.constructor.call(this, this.json); -2048 } -2049 -2050 /** -2051 @returns{hQuery.Scalar} -2052 */ -2053 -2054 -2055 Immunization.prototype.medicationSeriesNumber = function() { -2056 return new hQuery.Scalar(this.json['medicationSeriesNumber']); -2057 }; -2058 -2059 /** -2060 @returns{hQuery.MedicationInformation} -2061 */ -2062 -2063 -2064 Immunization.prototype.medicationInformation = function() { -2065 return new hQuery.MedicationInformation(this.json); -2066 }; -2067 -2068 /** -2069 @returns{Date} Date immunization was administered -2070 */ -2071 -2072 -2073 Immunization.prototype.administeredDate = function() { -2074 return dateFromUtcSeconds(this.json['administeredDate']); -2075 }; -2076 -2077 /** -2078 @returns{hQuery.Actor} Performer of immunization -2079 */ -2080 -2081 -2082 Immunization.prototype.performer = function() { -2083 return new hQuery.Actor(this.json['performer']); -2084 }; -2085 -2086 /** -2087 @returns {comment} human readable description of event -2088 */ -2089 -2090 -2091 Immunization.prototype.comment = function() { -2092 return this.json['comment']; -2093 }; -2094 -2095 /** -2096 @returns {Boolean} whether the immunization has been refused by the patient. -2097 */ +2045 hQuery.Result = (function(_super) { +2046 __extends(Result, _super); +2047 +2048 function Result(json) { +2049 this.json = json; +2050 Result.__super__.constructor.call(this, this.json); +2051 } +2052 +2053 /** +2054 ASTM CCR defines a restricted set of required result Type codes (see ResultTypeCode in section 7.3 +2055 Summary of CCD value sets), used to categorize a result into one of several commonly accepted values +2056 (e.g. Hematology, Chemistry, Nuclear Medicine). +2057 @returns {CodedValue} +2058 */ +2059 +2060 +2061 Result.prototype.resultType = function() { +2062 return this.type(); +2063 }; +2064 +2065 /** +2066 @returns {CodedValue} +2067 */ +2068 +2069 +2070 Result.prototype.interpretation = function() { +2071 return hQuery.createCodedValue(this.json['interpretation']); +2072 }; +2073 +2074 /** +2075 @returns {String} +2076 */ +2077 +2078 +2079 Result.prototype.referenceRange = function() { +2080 return this.json['referenceRange']; +2081 }; +2082 +2083 /** +2084 @returns {String} +2085 */ +2086 +2087 +2088 Result.prototype.comment = function() { +2089 return this.json['comment']; +2090 }; +2091 +2092 return Result; +2093 +2094 })(hQuery.CodedEntry); +2095 /** +2096 @namespace scoping into the hquery namespace +2097 */ 2098 -2099 -2100 Immunization.prototype.refusalInd = function() { -2101 return this.json['negationInd']; -2102 }; -2103 -2104 /** -2105 NoImmunzation as defined by value set 2.16.840.1.113883.1.11.19717 -2106 The terms come from Health Level Seven (HL7) Version 3.0 Vocabulary and are managed by HL7 -2107 It indicates the reason an immunization was not administered. -2108 @returns {hQuery.NoImmunization} Used to indicate reason an immunization was not administered. -2109 */ -2110 -2111 -2112 Immunization.prototype.refusalReason = function() { -2113 return new hQuery.NoImmunization(this.json['negationReason']['code'], this.json['negationReason']['codeSystem']); -2114 }; +2099 var _ref, +2100 __hasProp = {}.hasOwnProperty, +2101 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; +2102 +2103 this.hQuery || (this.hQuery = {}); +2104 +2105 /** +2106 NoImmunzation as defined by value set 2.16.840.1.113883.1.11.19717 +2107 The terms come from Health Level Seven (HL7) Version 3.0 Vocabulary and are managed by HL7 +2108 It indicates the reason an immunization was not administered. +2109 +2110 @class NoImmunization - describes the status of the medication +2111 @augments hQuery.CodedEntry +2112 @exports NoImmunization as hQuery.NoImmunization +2113 */ +2114 2115 -2116 return Immunization; -2117 -2118 })(hQuery.CodedEntry); -2119 /** -2120 @namespace scoping into the hquery namespace -2121 */ -2122 -2123 var __hasProp = {}.hasOwnProperty, -2124 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; +2116 hQuery.NoImmunization = (function(_super) { +2117 var IMMUNITY, MED_PRECAUTION, OUT_OF_STOCK, PAT_OBJ, PHIL_OBJ, REL_OBJ, VAC_EFF, VAC_SAFETY; +2118 +2119 __extends(NoImmunization, _super); +2120 +2121 function NoImmunization() { +2122 _ref = NoImmunization.__super__.constructor.apply(this, arguments); +2123 return _ref; +2124 } 2125 -2126 this.hQuery || (this.hQuery = {}); +2126 IMMUNITY = "IMMUNE"; 2127 -2128 /** -2129 @class -2130 @augments hQuery.CodedEntry -2131 @exports Allergy as hQuery.Allergy -2132 */ +2128 MED_PRECAUTION = "MEDPREC"; +2129 +2130 OUT_OF_STOCK = "OSTOCK"; +2131 +2132 PAT_OBJ = "PATOBJ"; 2133 -2134 -2135 hQuery.Allergy = (function(_super) { -2136 __extends(Allergy, _super); +2134 PHIL_OBJ = "PHILISOP"; +2135 +2136 REL_OBJ = "RELIG"; 2137 -2138 function Allergy(json) { -2139 this.json = json; -2140 Allergy.__super__.constructor.call(this, this.json); -2141 } -2142 -2143 /** -2144 Food and substance allergies use the Unique Ingredient Identifier(UNII) from the FDA -2145 http://www.fda.gov/ForIndustry/DataStandards/StructuredProductLabeling/ucm162523.htm -2146 -2147 Allegies to a class of medication Shall contain a value descending from the NDF-RT concept types -2148 of Mechanism of Action - N0000000223, Physiologic Effect - N0000009802 or -2149 Chemical Structure - N0000000002. NUI will be used as the concept code. -2150 For more information, please see the Web Site -2151 http://www.cancer.gov/cancertopics/terminologyresources/page5 -2152 -2153 Allergies to a specific medication shall use RxNorm for the values. -2154 @returns {CodedValue} -2155 */ -2156 -2157 -2158 Allergy.prototype.product = function() { -2159 return this.type(); -2160 }; -2161 -2162 /** -2163 Date of allergy or adverse event -2164 @returns{Date} -2165 */ -2166 -2167 -2168 Allergy.prototype.adverseEventDate = function() { -2169 return dateFromUtcSeconds(this.json['adverseEventDate']); -2170 }; -2171 -2172 /** -2173 Adverse event types SHALL be coded as specified in HITSP/C80 Section 2.2.3.4.2 Allergy/Adverse Event Type -2174 @returns {CodedValue} -2175 */ -2176 +2138 VAC_EFF = "VACEFF"; +2139 +2140 VAC_SAFETY = "VACSAF"; +2141 +2142 /** +2143 @returns {Boolean} +2144 */ +2145 +2146 +2147 NoImmunization.prototype.isImmune = function() { +2148 return this.c === IMMUNITY; +2149 }; +2150 +2151 /** +2152 @returns {Boolean} +2153 */ +2154 +2155 +2156 NoImmunization.prototype.isMedPrec = function() { +2157 return this.c === MED_PRECAUTION; +2158 }; +2159 +2160 /** +2161 @returns {Boolean} +2162 */ +2163 +2164 +2165 NoImmunization.prototype.isOstock = function() { +2166 return this.c === OUT_OF_STOCK; +2167 }; +2168 +2169 /** +2170 @returns {Boolean} +2171 */ +2172 +2173 +2174 NoImmunization.prototype.isPatObj = function() { +2175 return this.c === PAT_OBJ; +2176 }; 2177 -2178 Allergy.prototype.adverseEventType = function() { -2179 return new hQuery.CodedValue(this.json['type']['code'], this.json['type']['codeSystem']); -2180 }; +2178 /** +2179 @returns {Boolean} +2180 */ 2181 -2182 /** -2183 This indicates the reaction that may be caused by the product or agent. -2184 It is defined by 2.16.840.1.113883.3.88.12.3221.6.2 and are SNOMED-CT codes. -2185 420134006 Propensity to adverse reactions (disorder) -2186 418038007 Propensity to adverse reactions to substance (disorder) -2187 419511003 Propensity to adverse reactions to drug (disorder) -2188 418471000 Propensity to adverse reactions to food (disorder) -2189 419199007 Allergy to substance (disorder) -2190 416098002 Drug allergy (disorder) -2191 414285001 Food allergy (disorder) -2192 59037007 Drug intolerance (disorder) -2193 235719002 Food intolerance (disorder) -2194 @returns {CodedValue} -2195 */ -2196 -2197 -2198 Allergy.prototype.reaction = function() { -2199 return new hQuery.CodedValue(this.json['reaction']['code'], this.json['reaction']['codeSystem']); -2200 }; -2201 -2202 /** -2203 This is a description of the level of the severity of the allergy or intolerance. -2204 Use SNOMED-CT Codes as defined by 2.16.840.1.113883.3.88.12.3221.6.8 -2205 255604002 Mild -2206 371923003 Mild to Moderate -2207 6736007 Moderate -2208 371924009 Moderate to Severe -2209 24484000 Severe -2210 399166001 Fatal -2211 @returns {CodedValue} -2212 */ +2182 +2183 NoImmunization.prototype.isPhilisop = function() { +2184 return this.c === PHIL_OBJ; +2185 }; +2186 +2187 /** +2188 @returns {Boolean} +2189 */ +2190 +2191 +2192 NoImmunization.prototype.isRelig = function() { +2193 return this.c === REL_OBJ; +2194 }; +2195 +2196 /** +2197 @returns {Boolean} +2198 */ +2199 +2200 +2201 NoImmunization.prototype.isVacEff = function() { +2202 return this.c === VAC_EFF; +2203 }; +2204 +2205 /** +2206 @returns {Boolean} +2207 */ +2208 +2209 +2210 NoImmunization.prototype.isVacSaf = function() { +2211 return this.c === VAC_SAFETY; +2212 }; 2213 -2214 -2215 Allergy.prototype.severity = function() { -2216 return new hQuery.CodedValue(this.json['severity']['code'], this.json['severity']['codeSystem']); -2217 }; -2218 -2219 /** -2220 Additional comment or textual information -2221 @returns {String} -2222 */ +2214 return NoImmunization; +2215 +2216 })(hQuery.CodedValue); +2217 +2218 /** +2219 @class represents a immunization entry for a patient. +2220 @augments hQuery.CodedEntry +2221 @exports Immunization as hQuery.Immunization +2222 */ 2223 2224 -2225 Allergy.prototype.comment = function() { -2226 return this.json['comment']; -2227 }; -2228 -2229 return Allergy; -2230 -2231 })(hQuery.CodedEntry); -2232 /** -2233 @namespace scoping into the hquery namespace -2234 */ -2235 this.hQuery || (this.hQuery = {}); +2225 hQuery.Immunization = (function(_super) { +2226 __extends(Immunization, _super); +2227 +2228 function Immunization(json) { +2229 this.json = json; +2230 Immunization.__super__.constructor.call(this, this.json); +2231 } +2232 +2233 /** +2234 @returns{hQuery.Scalar} +2235 */ 2236 -2237 /** -2238 @class -2239 -2240 @exports Provider as hQuery.Provider -2241 */ -2242 +2237 +2238 Immunization.prototype.medicationSeriesNumber = function() { +2239 if (this.json['medicationSeriesNumber']) { +2240 return new hQuery.Scalar(this.json['medicationSeriesNumber']); +2241 } +2242 }; 2243 -2244 hQuery.Provider = (function() { -2245 function Provider(json) { -2246 this.json = json; -2247 } +2244 /** +2245 @returns{hQuery.MedicationInformation} +2246 */ +2247 2248 -2249 /** -2250 @returns {hQuery.Person} -2251 */ +2249 Immunization.prototype.medicationInformation = function() { +2250 return new hQuery.MedicationInformation(this.json); +2251 }; 2252 -2253 -2254 Provider.prototype.providerEntity = function() { -2255 return new hQuery.Person(this.json['providerEntity']); -2256 }; +2253 /** +2254 @returns{Date} Date immunization was administered +2255 */ +2256 2257 -2258 /** -2259 @returns {hQuery.DateRange} -2260 */ +2258 Immunization.prototype.administeredDate = function() { +2259 return dateFromUtcSeconds(this.json['administeredDate']); +2260 }; 2261 -2262 -2263 Provider.prototype.careProvisionDateRange = function() { -2264 return new hQuery.DateRange(this.json['careProvisionDateRange']); -2265 }; +2262 /** +2263 @returns{hQuery.Actor} Performer of immunization +2264 */ +2265 2266 -2267 /** -2268 @returns {hQuery.CodedValue} -2269 */ -2270 -2271 -2272 Provider.prototype.role = function() { -2273 return new hQuery.CodedValue(this.json['role']['code'], this.json['role']['codeSystem']); -2274 }; -2275 -2276 /** -2277 @returns {String} -2278 */ -2279 -2280 -2281 Provider.prototype.patientID = function() { -2282 return this.json['patientID']; -2283 }; -2284 -2285 /** -2286 @returns {hQuery.CodedValue} -2287 */ -2288 -2289 -2290 Provider.prototype.providerType = function() { -2291 return new hQuery.CodedValue(this.json['providerType']['code'], this.json['providerType']['codeSystem']); -2292 }; -2293 -2294 /** -2295 @returns {String} +2267 Immunization.prototype.performer = function() { +2268 if (this.json['performer']) { +2269 return new hQuery.Actor(this.json['performer']); +2270 } +2271 }; +2272 +2273 /** +2274 @returns {comment} human readable description of event +2275 */ +2276 +2277 +2278 Immunization.prototype.comment = function() { +2279 return this.json['comment']; +2280 }; +2281 +2282 /** +2283 @returns {Boolean} whether the immunization has been refused by the patient. +2284 */ +2285 +2286 +2287 Immunization.prototype.refusalInd = function() { +2288 return this.json['negationInd']; +2289 }; +2290 +2291 /** +2292 NoImmunzation as defined by value set 2.16.840.1.113883.1.11.19717 +2293 The terms come from Health Level Seven (HL7) Version 3.0 Vocabulary and are managed by HL7 +2294 It indicates the reason an immunization was not administered. +2295 @returns {hQuery.NoImmunization} Used to indicate reason an immunization was not administered. 2296 */ 2297 2298 -2299 Provider.prototype.providerID = function() { -2300 return this.json['providerID']; -2301 }; -2302 -2303 /** -2304 @returns {hQuery.Organization} -2305 */ +2299 Immunization.prototype.refusalReason = function() { +2300 var _ref1, _ref2; +2301 +2302 return new hQuery.NoImmunization((_ref1 = this.json['negationReason']) != null ? _ref1['code'] : void 0, (_ref2 = this.json['negationReason']) != null ? _ref2['code_system'] : void 0); +2303 }; +2304 +2305 return Immunization; 2306 -2307 -2308 Provider.prototype.organizationName = function() { -2309 return new hQuery.Organization(this.json); -2310 }; +2307 })(hQuery.CodedEntry); +2308 /** +2309 @namespace scoping into the hquery namespace +2310 */ 2311 -2312 return Provider; -2313 -2314 })(); -2315 /** -2316 @namespace scoping into the hquery namespace -2317 */ -2318 -2319 var __hasProp = {}.hasOwnProperty, -2320 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; -2321 -2322 this.hQuery || (this.hQuery = {}); +2312 var __hasProp = {}.hasOwnProperty, +2313 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; +2314 +2315 this.hQuery || (this.hQuery = {}); +2316 +2317 /** +2318 @class +2319 @augments hQuery.CodedEntry +2320 @exports Allergy as hQuery.Allergy +2321 */ +2322 2323 -2324 /** -2325 @class -2326 @augments hQuery.CodedEntry -2327 @exports Language as hQuery.Language -2328 */ -2329 -2330 -2331 hQuery.Language = (function(_super) { -2332 __extends(Language, _super); -2333 -2334 function Language(json) { -2335 this.json = json; -2336 Language.__super__.constructor.call(this, this.json); -2337 } -2338 -2339 /** -2340 @returns {hQuery.CodedValue} -2341 */ -2342 -2343 -2344 Language.prototype.modeCode = function() { -2345 return new hQuery.CodedValue(this.json['modeCode']['code'], this.json['modeCode']['codeSystem']); -2346 }; -2347 -2348 /** -2349 @returns {String} -2350 */ -2351 -2352 -2353 Language.prototype.preferenceIndicator = function() { -2354 return this.json['preferenceIndicator']; -2355 }; +2324 hQuery.Allergy = (function(_super) { +2325 __extends(Allergy, _super); +2326 +2327 function Allergy(json) { +2328 this.json = json; +2329 Allergy.__super__.constructor.call(this, this.json); +2330 } +2331 +2332 /** +2333 Food and substance allergies use the Unique Ingredient Identifier(UNII) from the FDA +2334 http://www.fda.gov/ForIndustry/DataStandards/StructuredProductLabeling/ucm162523.htm +2335 +2336 Allegies to a class of medication Shall contain a value descending from the NDF-RT concept types +2337 of Mechanism of Action - N0000000223, Physiologic Effect - N0000009802 or +2338 Chemical Structure - N0000000002. NUI will be used as the concept code. +2339 For more information, please see the Web Site +2340 http://www.cancer.gov/cancertopics/terminologyresources/page5 +2341 +2342 Allergies to a specific medication shall use RxNorm for the values. +2343 @returns {CodedValue} +2344 */ +2345 +2346 +2347 Allergy.prototype.product = function() { +2348 return this.type(); +2349 }; +2350 +2351 /** +2352 Date of allergy or adverse event +2353 @returns{Date} +2354 */ +2355 2356 -2357 return Language; -2358 -2359 })(hQuery.CodedEntry); -2360 /** -2361 @namespace scoping into the hquery namespace -2362 */ -2363 -2364 var __hasProp = {}.hasOwnProperty, -2365 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; +2357 Allergy.prototype.adverseEventDate = function() { +2358 return dateFromUtcSeconds(this.json['adverseEventDate']); +2359 }; +2360 +2361 /** +2362 Adverse event types SHALL be coded as specified in HITSP/C80 Section 2.2.3.4.2 Allergy/Adverse Event Type +2363 @returns {CodedValue} +2364 */ +2365 2366 -2367 this.hQuery || (this.hQuery = {}); -2368 -2369 /** -2370 This includes information about the patients current and past pregnancy status -2371 The Coded Entry code system should be SNOMED-CT -2372 @class -2373 @augments hQuery.CodedEntry -2374 @exports Pregnancy as hQuery.Pregnancy -2375 */ -2376 -2377 -2378 hQuery.Pregnancy = (function(_super) { -2379 __extends(Pregnancy, _super); -2380 -2381 function Pregnancy(json) { -2382 this.json = json; -2383 Pregnancy.__super__.constructor.call(this, this.json); -2384 } +2367 Allergy.prototype.adverseEventType = function() { +2368 return hQuery.createCodedValue(this.json['type']); +2369 }; +2370 +2371 /** +2372 This indicates the reaction that may be caused by the product or agent. +2373 It is defined by 2.16.840.1.113883.3.88.12.3221.6.2 and are SNOMED-CT codes. +2374 420134006 Propensity to adverse reactions (disorder) +2375 418038007 Propensity to adverse reactions to substance (disorder) +2376 419511003 Propensity to adverse reactions to drug (disorder) +2377 418471000 Propensity to adverse reactions to food (disorder) +2378 419199007 Allergy to substance (disorder) +2379 416098002 Drug allergy (disorder) +2380 414285001 Food allergy (disorder) +2381 59037007 Drug intolerance (disorder) +2382 235719002 Food intolerance (disorder) +2383 @returns {CodedValue} +2384 */ 2385 -2386 /** -2387 @returns {String} -2388 */ -2389 +2386 +2387 Allergy.prototype.reaction = function() { +2388 return hQuery.createCodedValue(this.json['reaction']); +2389 }; 2390 -2391 Pregnancy.prototype.comment = function() { -2392 return this.json['comment']; -2393 }; -2394 -2395 return Pregnancy; -2396 -2397 })(hQuery.CodedEntry); -2398 /** -2399 @namespace scoping into the hquery namespace -2400 */ -2401 -2402 var __hasProp = {}.hasOwnProperty, -2403 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; -2404 -2405 this.hQuery || (this.hQuery = {}); -2406 -2407 /** -2408 -2409 The Social History Observation is used to define the patient's occupational, personal (e.g. lifestyle), -2410 social, and environmental history and health risk factors, as well as administrative data such as -2411 marital status, race, ethnicity and religious affiliation. The types of conditions -2412 described have been constrained to the SNOMED CT code system using constrained code set, 2.16.840.1.113883.3.88.12.80.60: -2413 229819007 Tobacco use and exposure -2414 256235009 Exercise -2415 160573003 Alcohol Intake -2416 364393001 Nutritional observable -2417 364703007 Employment detail -2418 425400000 Toxic exposure status -2419 363908000 Details of drug misuse behavior -2420 228272008 Health-related behavior -2421 105421008 Educational achievement -2422 -2423 note: Social History is not part of the existing green c32. -2424 @exports Socialhistory as hQuery.Socialhistory -2425 @augments hQuery.CodedEntry -2426 */ -2427 +2391 /** +2392 This is a description of the level of the severity of the allergy or intolerance. +2393 Use SNOMED-CT Codes as defined by 2.16.840.1.113883.3.88.12.3221.6.8 +2394 255604002 Mild +2395 371923003 Mild to Moderate +2396 6736007 Moderate +2397 371924009 Moderate to Severe +2398 24484000 Severe +2399 399166001 Fatal +2400 @returns {CodedValue} +2401 */ +2402 +2403 +2404 Allergy.prototype.severity = function() { +2405 return hQuery.createCodedValue(this.json['severity']); +2406 }; +2407 +2408 /** +2409 Additional comment or textual information +2410 @returns {String} +2411 */ +2412 +2413 +2414 Allergy.prototype.comment = function() { +2415 return this.json['comment']; +2416 }; +2417 +2418 return Allergy; +2419 +2420 })(hQuery.CodedEntry); +2421 /** +2422 @namespace scoping into the hquery namespace +2423 */ +2424 this.hQuery || (this.hQuery = {}); +2425 +2426 /** +2427 @class 2428 -2429 hQuery.Socialhistory = (function(_super) { -2430 __extends(Socialhistory, _super); +2429 @exports Provider as hQuery.Provider +2430 */ 2431 -2432 function Socialhistory(json) { -2433 this.json = json; -2434 Socialhistory.__super__.constructor.call(this, this.json); -2435 } -2436 -2437 /** -2438 Value returns the value of the result. This will return an object. The properties of this -2439 object are dependent on the type of result. +2432 +2433 hQuery.Provider = (function() { +2434 function Provider(json) { +2435 this.json = json; +2436 } +2437 +2438 /** +2439 @returns {hQuery.Person} 2440 */ 2441 2442 -2443 Socialhistory.prototype.value = function() { -2444 return this.json['value']; -2445 }; -2446 -2447 return Socialhistory; +2443 Provider.prototype.providerEntity = function() { +2444 if (this.json['providerEntity']) { +2445 return new hQuery.Person(this.json['providerEntity']); +2446 } +2447 }; 2448 -2449 })(hQuery.CodedEntry); -2450 /** -2451 @namespace scoping into the hquery namespace -2452 */ +2449 /** +2450 @returns {hQuery.DateRange} +2451 */ +2452 2453 -2454 var __hasProp = {}.hasOwnProperty, -2455 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; -2456 -2457 this.hQuery || (this.hQuery = {}); -2458 -2459 /** -2460 -2461 The plan of care contains data defining prospective or intended orders, interventions, encounters, services, and procedures for the patient. -2462 -2463 @exports CareGoal as hQuery.CareGoal -2464 @augments hQuery.CodedEntry -2465 */ -2466 -2467 -2468 hQuery.CareGoal = (function(_super) { -2469 __extends(CareGoal, _super); -2470 -2471 function CareGoal(json) { -2472 this.json = json; -2473 CareGoal.__super__.constructor.call(this, this.json); -2474 } -2475 -2476 return CareGoal; +2454 Provider.prototype.careProvisionDateRange = function() { +2455 if (this.json['careProvisionDateRange']) { +2456 return new hQuery.DateRange(this.json['careProvisionDateRange']); +2457 } +2458 }; +2459 +2460 /** +2461 @returns {hQuery.CodedValue} +2462 */ +2463 +2464 +2465 Provider.prototype.role = function() { +2466 return hQuery.createCodedValue(this.json['role']); +2467 }; +2468 +2469 /** +2470 @returns {String} +2471 */ +2472 +2473 +2474 Provider.prototype.patientID = function() { +2475 return this.json['patientID']; +2476 }; 2477 -2478 })(hQuery.CodedEntry); -2479 /** -2480 @namespace scoping into the hquery namespace -2481 */ +2478 /** +2479 @returns {hQuery.CodedValue} +2480 */ +2481 2482 -2483 var __hasProp = {}.hasOwnProperty, -2484 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; -2485 -2486 this.hQuery || (this.hQuery = {}); -2487 -2488 /** -2489 -2490 The Medical Equipment section contains information describing a patients implanted and external medical devices and equipment that their health status depends on, as well as any pertinent equipment or device history. +2483 Provider.prototype.providerType = function() { +2484 return hQuery.createCodedValue(this.json['providerType']); +2485 }; +2486 +2487 /** +2488 @returns {String} +2489 */ +2490 2491 -2492 The template identifier for this section is 2.16.840.1.113883.3.88.11.83.128 -2493 -2494 C83-[CT-128-1] This section shall conform to the HL7 CCD section, and shall contain a templateId element whose root attribute is 2.16.840.1.113883.10.20.1.7. -2495 C83-[CT-128-2] This section SHALL conform to the IHE Medical Devices Section, and shall contain a templateId element whose root attribute is 1.3.6.1.4.1.19376.1.5.3.1.1.5.3.5 -2496 -2497 @exports MedicalEquipment as hQuery.MedicalEquipment -2498 @augments hQuery.CodedEntry -2499 */ +2492 Provider.prototype.providerID = function() { +2493 return this.json['providerID']; +2494 }; +2495 +2496 /** +2497 @returns {hQuery.Organization} +2498 */ +2499 2500 -2501 -2502 hQuery.MedicalEquipment = (function(_super) { -2503 __extends(MedicalEquipment, _super); +2501 Provider.prototype.organizationName = function() { +2502 return new hQuery.Organization(this.json); +2503 }; 2504 -2505 function MedicalEquipment(json) { -2506 this.json = json; -2507 MedicalEquipment.__super__.constructor.call(this, this.json); -2508 } -2509 -2510 return MedicalEquipment; +2505 return Provider; +2506 +2507 })(); +2508 /** +2509 @namespace scoping into the hquery namespace +2510 */ 2511 -2512 })(hQuery.CodedEntry); -2513 /** -2514 @namespace scoping into the hquery namespace -2515 */ +2512 var __hasProp = {}.hasOwnProperty, +2513 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; +2514 +2515 this.hQuery || (this.hQuery = {}); 2516 -2517 var __hasProp = {}.hasOwnProperty, -2518 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; -2519 -2520 this.hQuery || (this.hQuery = {}); -2521 -2522 /** -2523 This class can be used to represnt a functional status for a patient. Currently, -2524 it is not a very close representation of functional status as it is represented -2525 in the HL7 CCD, HITSP C32 or Consolidated CDA. +2517 /** +2518 @class +2519 @augments hQuery.CodedEntry +2520 @exports Language as hQuery.Language +2521 */ +2522 +2523 +2524 hQuery.Language = (function(_super) { +2525 __extends(Language, _super); 2526 -2527 In the previously mentioned specifications, functional status may represented -2528 using either a condition or result. Having "mixed" types of entries in a section -2529 is currently not well supported in the existing Record class -2530 -2531 Additionally, there is a mismatch between the data needed to calculate Stage 2 -2532 Meaningful Use Quailty Measures and the data contained in patient summary -2533 standards. The CQMs are checking to see if a functional status represented by -2534 a result was patient supplied. Right now, results do not have a source, and -2535 even if we were to use Provider as a source, it would need to be extended -2536 to support patients. -2537 -2538 To avoid this, the patient sumamry style functional status has been "flattened" -2539 into this class. This model supports the information needed to calculate -2540 Stage 2 MU CQMs. If importers are created from C32 or CCDA, the information -2541 can be stored here, but it will be a lossy transformation. -2542 @class -2543 @augments hQuery.CodedEntry -2544 @exports FunctionalStatus as hQuery.FunctionalStatus -2545 */ -2546 -2547 -2548 hQuery.FunctionalStatus = (function(_super) { -2549 __extends(FunctionalStatus, _super); -2550 -2551 function FunctionalStatus(json) { -2552 this.json = json; -2553 FunctionalStatus.__super__.constructor.call(this, this.json); -2554 } -2555 -2556 /** -2557 Either "condition" or "result" -2558 @returns {String} -2559 */ -2560 +2527 function Language(json) { +2528 this.json = json; +2529 Language.__super__.constructor.call(this, this.json); +2530 } +2531 +2532 /** +2533 @returns {hQuery.CodedValue} +2534 */ +2535 +2536 +2537 Language.prototype.modeCode = function() { +2538 return hQuery.createCodedValue(this.json['modeCode']); +2539 }; +2540 +2541 /** +2542 @returns {String} +2543 */ +2544 +2545 +2546 Language.prototype.preferenceIndicator = function() { +2547 return this.json['preferenceIndicator']; +2548 }; +2549 +2550 return Language; +2551 +2552 })(hQuery.CodedEntry); +2553 /** +2554 @namespace scoping into the hquery namespace +2555 */ +2556 +2557 var __hasProp = {}.hasOwnProperty, +2558 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; +2559 +2560 this.hQuery || (this.hQuery = {}); 2561 -2562 FunctionalStatus.prototype.type = function() { -2563 return this.json["type"]; -2564 }; -2565 -2566 /** -2567 A coded value. Like a code for patient supplied. -2568 @returns {hQuery.CodedValue} -2569 */ +2562 /** +2563 This includes information about the patients current and past pregnancy status +2564 The Coded Entry code system should be SNOMED-CT +2565 @class +2566 @augments hQuery.CodedEntry +2567 @exports Pregnancy as hQuery.Pregnancy +2568 */ +2569 2570 -2571 -2572 FunctionalStatus.prototype.source = function() { -2573 if (this.json["source"] != null) { -2574 return new hQuery.CodedValue(this.json["source"]["code"], this.json["source"]["codeSystem"]); -2575 } -2576 }; -2577 -2578 return FunctionalStatus; -2579 -2580 })(hQuery.CodedEntry); -2581 /** -2582 @namespace scoping into the hquery namespace -2583 */ -2584 -2585 var _ref, -2586 __hasProp = {}.hasOwnProperty, -2587 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; -2588 -2589 this.hQuery || (this.hQuery = {}); -2590 +2571 hQuery.Pregnancy = (function(_super) { +2572 __extends(Pregnancy, _super); +2573 +2574 function Pregnancy(json) { +2575 this.json = json; +2576 Pregnancy.__super__.constructor.call(this, this.json); +2577 } +2578 +2579 /** +2580 @returns {String} +2581 */ +2582 +2583 +2584 Pregnancy.prototype.comment = function() { +2585 return this.json['comment']; +2586 }; +2587 +2588 return Pregnancy; +2589 +2590 })(hQuery.CodedEntry); 2591 /** -2592 @class Supports -2593 @exports Supports as hQuery.Supports -2594 */ -2595 -2596 -2597 hQuery.Supports = (function() { -2598 function Supports(json) { -2599 this.json = json; -2600 } +2592 @namespace scoping into the hquery namespace +2593 */ +2594 +2595 var __hasProp = {}.hasOwnProperty, +2596 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; +2597 +2598 this.hQuery || (this.hQuery = {}); +2599 +2600 /** 2601 -2602 /** -2603 @returns {DateRange} -2604 */ -2605 -2606 -2607 Supports.prototype.supportDate = function() { -2608 return new hQuery.DateRange(this.json['supportDate']); -2609 }; -2610 -2611 /** -2612 @returns {Person} -2613 */ -2614 +2602 The Social History Observation is used to define the patient's occupational, personal (e.g. lifestyle), +2603 social, and environmental history and health risk factors, as well as administrative data such as +2604 marital status, race, ethnicity and religious affiliation. The types of conditions +2605 described have been constrained to the SNOMED CT code system using constrained code set, 2.16.840.1.113883.3.88.12.80.60: +2606 229819007 Tobacco use and exposure +2607 256235009 Exercise +2608 160573003 Alcohol Intake +2609 364393001 Nutritional observable +2610 364703007 Employment detail +2611 425400000 Toxic exposure status +2612 363908000 Details of drug misuse behavior +2613 228272008 Health-related behavior +2614 105421008 Educational achievement 2615 -2616 Supports.prototype.guardian = function() { -2617 return new hQuery.Person(this.json['guardian']); -2618 }; -2619 -2620 /** -2621 @returns {String} -2622 */ -2623 +2616 note: Social History is not part of the existing green c32. +2617 @exports Socialhistory as hQuery.Socialhistory +2618 @augments hQuery.CodedEntry +2619 */ +2620 +2621 +2622 hQuery.Socialhistory = (function(_super) { +2623 __extends(Socialhistory, _super); 2624 -2625 Supports.prototype.guardianSupportType = function() { -2626 return this.json['guardianSupportType']; -2627 }; -2628 -2629 /** -2630 @returns {Person} -2631 */ -2632 -2633 -2634 Supports.prototype.contact = function() { -2635 return new hQuery.Person(this.json['contact']); -2636 }; -2637 -2638 /** -2639 @returns {String} -2640 */ +2625 function Socialhistory(json) { +2626 this.json = json; +2627 Socialhistory.__super__.constructor.call(this, this.json); +2628 } +2629 +2630 /** +2631 Value returns the value of the result. This will return an object. The properties of this +2632 object are dependent on the type of result. +2633 */ +2634 +2635 +2636 Socialhistory.prototype.value = function() { +2637 return this.json['value']; +2638 }; +2639 +2640 return Socialhistory; 2641 -2642 -2643 Supports.prototype.contactSupportType = function() { -2644 return this.json['guardianSupportType']; -2645 }; +2642 })(hQuery.CodedEntry); +2643 /** +2644 @namespace scoping into the hquery namespace +2645 */ 2646 -2647 return Supports; -2648 -2649 })(); -2650 -2651 /** -2652 @class Representation of a patient -2653 @augments hQuery.Person -2654 @exports Patient as hQuery.Patient -2655 */ -2656 -2657 -2658 hQuery.Patient = (function(_super) { -2659 __extends(Patient, _super); +2647 var __hasProp = {}.hasOwnProperty, +2648 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; +2649 +2650 this.hQuery || (this.hQuery = {}); +2651 +2652 /** +2653 +2654 The plan of care contains data defining prospective or intended orders, interventions, encounters, services, and procedures for the patient. +2655 +2656 @exports CareGoal as hQuery.CareGoal +2657 @augments hQuery.CodedEntry +2658 */ +2659 2660 -2661 function Patient() { -2662 _ref = Patient.__super__.constructor.apply(this, arguments); -2663 return _ref; -2664 } -2665 -2666 /** -2667 @returns {String} containing M or F representing the gender of the patient -2668 */ -2669 +2661 hQuery.CareGoal = (function(_super) { +2662 __extends(CareGoal, _super); +2663 +2664 function CareGoal(json) { +2665 this.json = json; +2666 CareGoal.__super__.constructor.call(this, this.json); +2667 } +2668 +2669 return CareGoal; 2670 -2671 Patient.prototype.gender = function() { -2672 return this.json['gender']; -2673 }; -2674 -2675 /** -2676 @returns {Date} containing the patient's birthdate -2677 */ +2671 })(hQuery.CodedEntry); +2672 /** +2673 @namespace scoping into the hquery namespace +2674 */ +2675 +2676 var __hasProp = {}.hasOwnProperty, +2677 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; 2678 -2679 -2680 Patient.prototype.birthtime = function() { -2681 return hQuery.dateFromUtcSeconds(this.json['birthdate']); -2682 }; -2683 -2684 /** -2685 @param (Date) date the date at which the patient age is calculated, defaults to now. -2686 @returns {number} the patient age in years -2687 */ -2688 +2679 this.hQuery || (this.hQuery = {}); +2680 +2681 /** +2682 +2683 The Medical Equipment section contains information describing a patients implanted and external medical devices and equipment that their health status depends on, as well as any pertinent equipment or device history. +2684 +2685 The template identifier for this section is 2.16.840.1.113883.3.88.11.83.128 +2686 +2687 C83-[CT-128-1] This section shall conform to the HL7 CCD section, and shall contain a templateId element whose root attribute is 2.16.840.1.113883.10.20.1.7. +2688 C83-[CT-128-2] This section SHALL conform to the IHE Medical Devices Section, and shall contain a templateId element whose root attribute is 1.3.6.1.4.1.19376.1.5.3.1.1.5.3.5 2689 -2690 Patient.prototype.age = function(date) { -2691 var oneDay, oneYear; -2692 -2693 if (date == null) { -2694 date = new Date(); -2695 } -2696 oneDay = 24 * 60 * 60 * 1000; -2697 oneYear = 365 * oneDay; -2698 return (date.getTime() - this.birthtime().getTime()) / oneYear; -2699 }; -2700 -2701 /** -2702 @returns {CodedValue} the domestic partnership status of the patient -2703 The following HL7 codeset is used: -2704 A Annulled -2705 D Divorced -2706 I Interlocutory -2707 L Legally separated -2708 M Married -2709 P Polygamous -2710 S Never Married -2711 T Domestic Partner -2712 W Widowed -2713 */ -2714 +2690 @exports MedicalEquipment as hQuery.MedicalEquipment +2691 @augments hQuery.CodedEntry +2692 */ +2693 +2694 +2695 hQuery.MedicalEquipment = (function(_super) { +2696 __extends(MedicalEquipment, _super); +2697 +2698 function MedicalEquipment(json) { +2699 this.json = json; +2700 MedicalEquipment.__super__.constructor.call(this, this.json); +2701 } +2702 +2703 /** +2704 @returns {CodedValue} +2705 */ +2706 +2707 +2708 MedicalEquipment.prototype.anatomicalStructure = function() { +2709 return hQuery.createCodedValue(this.json['anatomicalStructure']); +2710 }; +2711 +2712 /** +2713 @returns {Date} The actual or intended removal time of the device. +2714 */ 2715 -2716 Patient.prototype.maritalStatus = function() { -2717 if (this.json['maritalStatus']) { -2718 return new hQuery.CodedValue(this.json['maritalStatus']['code'], this.json['maritalStatus']['codeSystem']); -2719 } -2720 }; -2721 -2722 /** -2723 @returns {CodedValue} of the spiritual faith affiliation of the patient -2724 It uses the HL7 codeset. http://www.hl7.org/memonly/downloads/v3edition.cfm#V32008 -2725 */ -2726 -2727 -2728 Patient.prototype.religiousAffiliation = function() { -2729 if (this.json['religiousAffiliation']) { -2730 return new hQuery.CodedValue(this.json['religiousAffiliation']['code'], this.json['religiousAffiliation']['codeSystem']); -2731 } -2732 }; -2733 -2734 /** -2735 @returns {CodedValue} of the race of the patient -2736 CDC codes: http://phinvads.cdc.gov/vads/ViewCodeSystemConcept.action?oid=2.16.840.1.113883.6.238&code=1000-9 -2737 */ -2738 +2716 +2717 MedicalEquipment.prototype.removalTime = function() { +2718 if (this.json['removalTime']) { +2719 return hQuery.dateFromUtcSeconds(this.json['removalTime']); +2720 } +2721 }; +2722 +2723 return MedicalEquipment; +2724 +2725 })(hQuery.CodedEntry); +2726 /** +2727 @namespace scoping into the hquery namespace +2728 */ +2729 +2730 var __hasProp = {}.hasOwnProperty, +2731 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; +2732 +2733 this.hQuery || (this.hQuery = {}); +2734 +2735 /** +2736 This class can be used to represnt a functional status for a patient. Currently, +2737 it is not a very close representation of functional status as it is represented +2738 in the HL7 CCD, HITSP C32 or Consolidated CDA. 2739 -2740 Patient.prototype.race = function() { -2741 if (this.json['race']) { -2742 return new hQuery.CodedValue(this.json['race']['code'], this.json['race']['codeSystem']); -2743 } -2744 }; -2745 -2746 /** -2747 @returns {CodedValue} of the ethnicity of the patient -2748 CDC codes: http://phinvads.cdc.gov/vads/ViewCodeSystemConcept.action?oid=2.16.840.1.113883.6.238&code=1000-9 -2749 */ +2740 In the previously mentioned specifications, functional status may represented +2741 using either a condition or result. Having "mixed" types of entries in a section +2742 is currently not well supported in the existing Record class +2743 +2744 Additionally, there is a mismatch between the data needed to calculate Stage 2 +2745 Meaningful Use Quailty Measures and the data contained in patient summary +2746 standards. The CQMs are checking to see if a functional status represented by +2747 a result was patient supplied. Right now, results do not have a source, and +2748 even if we were to use Provider as a source, it would need to be extended +2749 to support patients. 2750 -2751 -2752 Patient.prototype.ethnicity = function() { -2753 if (this.json['ethnicity']) { -2754 return new hQuery.CodedValue(this.json['ethnicity']['code'], this.json['ethnicity']['codeSystem']); -2755 } -2756 }; -2757 -2758 /** -2759 @returns {CodedValue} This is the code specifying the level of confidentiality of the document. -2760 HL7 Confidentiality Code (2.16.840.1.113883.5.25) -2761 */ -2762 +2751 To avoid this, the patient sumamry style functional status has been "flattened" +2752 into this class. This model supports the information needed to calculate +2753 Stage 2 MU CQMs. If importers are created from C32 or CCDA, the information +2754 can be stored here, but it will be a lossy transformation. +2755 @class +2756 @augments hQuery.CodedEntry +2757 @exports FunctionalStatus as hQuery.FunctionalStatus +2758 */ +2759 +2760 +2761 hQuery.FunctionalStatus = (function(_super) { +2762 __extends(FunctionalStatus, _super); 2763 -2764 Patient.prototype.confidentiality = function() { -2765 if (this.json['confidentiality']) { -2766 return new hQuery.CodedValue(this.json['confidentiality']['code'], this.json['confidentiality']['codeSystem']); -2767 } -2768 }; -2769 -2770 /** -2771 @returns {Address} of the location where the patient was born +2764 function FunctionalStatus(json) { +2765 this.json = json; +2766 FunctionalStatus.__super__.constructor.call(this, this.json); +2767 } +2768 +2769 /** +2770 Either "condition" or "result" +2771 @returns {String} 2772 */ 2773 2774 -2775 Patient.prototype.birthPlace = function() { -2776 return new hQuery.Address(this.json['birthPlace']); +2775 FunctionalStatus.prototype.type = function() { +2776 return this.json["type"]; 2777 }; 2778 2779 /** -2780 @returns {Supports} information regarding key support contacts relative to healthcare decisions, including next of kin -2781 */ -2782 +2780 A coded value. Like a code for patient supplied. +2781 @returns {hQuery.CodedValue} +2782 */ 2783 -2784 Patient.prototype.supports = function() { -2785 return new hQuery.Supports(this.json['supports']); -2786 }; -2787 -2788 /** -2789 @returns {Organization} -2790 */ -2791 -2792 -2793 Patient.prototype.custodian = function() { -2794 return new hQuery.Organization(this.json['custodian']); -2795 }; -2796 -2797 /** -2798 @returns {Provider} the providers associated with the patient -2799 */ -2800 +2784 +2785 FunctionalStatus.prototype.source = function() { +2786 return hQuery.createCodedValue(this.json["source"]); +2787 }; +2788 +2789 return FunctionalStatus; +2790 +2791 })(hQuery.CodedEntry); +2792 /** +2793 @namespace scoping into the hquery namespace +2794 */ +2795 +2796 var _ref, +2797 __hasProp = {}.hasOwnProperty, +2798 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; +2799 +2800 this.hQuery || (this.hQuery = {}); 2801 -2802 Patient.prototype.provider = function() { -2803 return new hQuery.Provider(this.json['provider']); -2804 }; -2805 -2806 /** -2807 @returns {hQuery.CodedEntryList} A list of {@link hQuery.LanguagesSpoken} objects -2808 Code from http://www.ietf.org/rfc/rfc4646.txt representing the name of the human language -2809 */ -2810 -2811 -2812 Patient.prototype.languages = function() { -2813 var language, list, _i, _len, _ref1; -2814 -2815 list = new hQuery.CodedEntryList; -2816 if (this.json['languages']) { -2817 _ref1 = this.json['languages']; -2818 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -2819 language = _ref1[_i]; -2820 list.push(new hQuery.Language(language)); -2821 } -2822 } -2823 return list; -2824 }; +2802 /** +2803 @class Supports +2804 @exports Supports as hQuery.Supports +2805 */ +2806 +2807 +2808 hQuery.Supports = (function() { +2809 function Supports(json) { +2810 this.json = json; +2811 } +2812 +2813 /** +2814 @returns {DateRange} +2815 */ +2816 +2817 +2818 Supports.prototype.supportDate = function() { +2819 return new hQuery.DateRange(this.json['supportDate']); +2820 }; +2821 +2822 /** +2823 @returns {Person} +2824 */ 2825 -2826 /** -2827 @returns {Boolean} returns true if the patient has died -2828 */ -2829 +2826 +2827 Supports.prototype.guardian = function() { +2828 return new hQuery.Person(this.json['guardian']); +2829 }; 2830 -2831 Patient.prototype.expired = function() { -2832 return this.json['expired']; -2833 }; +2831 /** +2832 @returns {String} +2833 */ 2834 -2835 /** -2836 @returns {Boolean} returns true if the patient participated in a clinical trial -2837 */ -2838 +2835 +2836 Supports.prototype.guardianSupportType = function() { +2837 return this.json['guardianSupportType']; +2838 }; 2839 -2840 Patient.prototype.clinicalTrialParticipant = function() { -2841 return this.json['clinicalTrialParticipant']; -2842 }; +2840 /** +2841 @returns {Person} +2842 */ 2843 -2844 /** -2845 @returns {hQuery.CodedEntryList} A list of {@link hQuery.Encounter} objects -2846 */ -2847 +2844 +2845 Supports.prototype.contact = function() { +2846 return new hQuery.Person(this.json['contact']); +2847 }; 2848 -2849 Patient.prototype.encounters = function() { -2850 var encounter, list, _i, _len, _ref1; -2851 -2852 list = new hQuery.CodedEntryList; -2853 if (this.json['encounters']) { -2854 _ref1 = this.json['encounters']; -2855 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -2856 encounter = _ref1[_i]; -2857 list.pushIfUsable(new hQuery.Encounter(encounter)); -2858 } -2859 } -2860 return list; -2861 }; -2862 -2863 /** -2864 @returns {hQuery.CodedEntryList} A list of {@link Medication} objects -2865 */ -2866 +2849 /** +2850 @returns {String} +2851 */ +2852 +2853 +2854 Supports.prototype.contactSupportType = function() { +2855 return this.json['guardianSupportType']; +2856 }; +2857 +2858 return Supports; +2859 +2860 })(); +2861 +2862 /** +2863 @class Representation of a patient +2864 @augments hQuery.Person +2865 @exports Patient as hQuery.Patient +2866 */ 2867 -2868 Patient.prototype.medications = function() { -2869 var list, medication, _i, _len, _ref1; -2870 -2871 list = new hQuery.CodedEntryList; -2872 if (this.json['medications']) { -2873 _ref1 = this.json['medications']; -2874 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -2875 medication = _ref1[_i]; -2876 list.pushIfUsable(new hQuery.Medication(medication)); -2877 } -2878 } -2879 return list; -2880 }; +2868 +2869 hQuery.Patient = (function(_super) { +2870 __extends(Patient, _super); +2871 +2872 function Patient() { +2873 _ref = Patient.__super__.constructor.apply(this, arguments); +2874 return _ref; +2875 } +2876 +2877 /** +2878 @returns {String} containing M or F representing the gender of the patient +2879 */ +2880 2881 -2882 /** -2883 @returns {hQuery.CodedEntryList} A list of {@link Condition} objects -2884 */ +2882 Patient.prototype.gender = function() { +2883 return this.json['gender']; +2884 }; 2885 -2886 -2887 Patient.prototype.conditions = function() { -2888 var condition, list, _i, _len, _ref1; +2886 /** +2887 @returns {Date} containing the patients birthdate +2888 */ 2889 -2890 list = new hQuery.CodedEntryList; -2891 if (this.json['conditions']) { -2892 _ref1 = this.json['conditions']; -2893 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -2894 condition = _ref1[_i]; -2895 list.pushIfUsable(new hQuery.Condition(condition)); -2896 } -2897 } -2898 return list; -2899 }; +2890 +2891 Patient.prototype.birthtime = function() { +2892 return hQuery.dateFromUtcSeconds(this.json['birthdate']); +2893 }; +2894 +2895 /** +2896 @param (Date) date the date at which the patient age is calculated, defaults to now. +2897 @returns {number} the patient age in years +2898 */ +2899 2900 -2901 /** -2902 @returns {hQuery.CodedEntryList} A list of {@link Procedure} objects -2903 */ -2904 -2905 -2906 Patient.prototype.procedures = function() { -2907 var list, procedure, _i, _len, _ref1; -2908 -2909 list = new hQuery.CodedEntryList; -2910 if (this.json['procedures']) { -2911 _ref1 = this.json['procedures']; -2912 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -2913 procedure = _ref1[_i]; -2914 list.pushIfUsable(new hQuery.Procedure(procedure)); -2915 } -2916 } -2917 return list; -2918 }; -2919 -2920 /** -2921 @returns {hQuery.CodedEntryList} A list of {@link Result} objects -2922 */ -2923 -2924 -2925 Patient.prototype.results = function() { -2926 var list, result, _i, _len, _ref1; -2927 -2928 list = new hQuery.CodedEntryList; -2929 if (this.json['results']) { -2930 _ref1 = this.json['results']; -2931 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -2932 result = _ref1[_i]; -2933 list.pushIfUsable(new hQuery.Result(result)); -2934 } -2935 } -2936 return list; -2937 }; +2901 Patient.prototype.age = function(date) { +2902 var oneDay, oneYear; +2903 +2904 if (date == null) { +2905 date = new Date(); +2906 } +2907 oneDay = 24 * 60 * 60 * 1000; +2908 oneYear = 365 * oneDay; +2909 return (date.getTime() - this.birthtime().getTime()) / oneYear; +2910 }; +2911 +2912 /** +2913 @returns {CodedValue} the domestic partnership status of the patient +2914 The following HL7 codeset is used: +2915 A Annulled +2916 D Divorced +2917 I Interlocutory +2918 L Legally separated +2919 M Married +2920 P Polygamous +2921 S Never Married +2922 T Domestic Partner +2923 W Widowed +2924 */ +2925 +2926 +2927 Patient.prototype.maritalStatus = function() { +2928 if (this.json['maritalStatus']) { +2929 return hQuery.createCodedValue(this.json['maritalStatus']); +2930 } +2931 }; +2932 +2933 /** +2934 @returns {CodedValue} of the spiritual faith affiliation of the patient +2935 It uses the HL7 codeset. http://www.hl7.org/memonly/downloads/v3edition.cfm#V32008 +2936 */ +2937 2938 -2939 /** -2940 @returns {hQuery.CodedEntryList} A list of {@link Result} objects -2941 */ -2942 -2943 -2944 Patient.prototype.vitalSigns = function() { -2945 var list, vital, _i, _len, _ref1; -2946 -2947 list = new hQuery.CodedEntryList; -2948 if (this.json['vital_signs']) { -2949 _ref1 = this.json['vital_signs']; -2950 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -2951 vital = _ref1[_i]; -2952 list.pushIfUsable(new hQuery.Result(vital)); -2953 } +2939 Patient.prototype.religiousAffiliation = function() { +2940 if (this.json['religiousAffiliation']) { +2941 return hQuery.createCodedValue(this.json['religiousAffiliation']); +2942 } +2943 }; +2944 +2945 /** +2946 @returns {CodedValue} of the race of the patient +2947 CDC codes: http://phinvads.cdc.gov/vads/ViewCodeSystemConcept.action?oid=2.16.840.1.113883.6.238&code=1000-9 +2948 */ +2949 +2950 +2951 Patient.prototype.race = function() { +2952 if (this.json['race']) { +2953 return hQuery.createCodedValue(this.json['race']); 2954 } -2955 return list; -2956 }; -2957 -2958 /** -2959 @returns {hQuery.CodedEntryList} A list of {@link Immunization} objects +2955 }; +2956 +2957 /** +2958 @returns {CodedValue} of the ethnicity of the patient +2959 CDC codes: http://phinvads.cdc.gov/vads/ViewCodeSystemConcept.action?oid=2.16.840.1.113883.6.238&code=1000-9 2960 */ 2961 2962 -2963 Patient.prototype.immunizations = function() { -2964 var immunization, list, _i, _len, _ref1; -2965 -2966 list = new hQuery.CodedEntryList; -2967 if (this.json['immunizations']) { -2968 _ref1 = this.json['immunizations']; -2969 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -2970 immunization = _ref1[_i]; -2971 list.pushIfUsable(new hQuery.Immunization(immunization)); -2972 } -2973 } -2974 return list; -2975 }; -2976 -2977 /** -2978 @returns {hQuery.CodedEntryList} A list of {@link Allergy} objects -2979 */ +2963 Patient.prototype.ethnicity = function() { +2964 if (this.json['ethnicity']) { +2965 return hQuery.createCodedValue(this.json['ethnicity']); +2966 } +2967 }; +2968 +2969 /** +2970 @returns {CodedValue} This is the code specifying the level of confidentiality of the document. +2971 HL7 Confidentiality Code (2.16.840.1.113883.5.25) +2972 */ +2973 +2974 +2975 Patient.prototype.confidentiality = function() { +2976 if (this.json['confidentiality']) { +2977 return hQuery.createCodedValue(this.json['confidentiality']); +2978 } +2979 }; 2980 -2981 -2982 Patient.prototype.allergies = function() { -2983 var allergy, list, _i, _len, _ref1; +2981 /** +2982 @returns {Address} of the location where the patient was born +2983 */ 2984 -2985 list = new hQuery.CodedEntryList; -2986 if (this.json['allergies']) { -2987 _ref1 = this.json['allergies']; -2988 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -2989 allergy = _ref1[_i]; -2990 list.pushIfUsable(new hQuery.Allergy(allergy)); -2991 } -2992 } -2993 return list; -2994 }; -2995 -2996 /** -2997 @returns {hQuery.CodedEntryList} A list of {@link Pregnancy} objects -2998 */ -2999 -3000 -3001 Patient.prototype.pregnancies = function() { -3002 var list, pregnancy, _i, _len, _ref1; +2985 +2986 Patient.prototype.birthPlace = function() { +2987 return new hQuery.Address(this.json['birthPlace']); +2988 }; +2989 +2990 /** +2991 @returns {Supports} information regarding key support contacts relative to healthcare decisions, including next of kin +2992 */ +2993 +2994 +2995 Patient.prototype.supports = function() { +2996 return new hQuery.Supports(this.json['supports']); +2997 }; +2998 +2999 /** +3000 @returns {Organization} +3001 */ +3002 3003 -3004 list = new hQuery.CodedEntryList; -3005 if (this.json['pregnancies']) { -3006 _ref1 = this.json['pregnancies']; -3007 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -3008 pregnancy = _ref1[_i]; -3009 list.pushIfUsable(new hQuery.Pregnancy(pregnancy)); -3010 } -3011 } -3012 return list; -3013 }; -3014 -3015 /** -3016 @returns {hQuery.CodedEntryList} A list of {@link Socialhistory} objects -3017 */ -3018 -3019 -3020 Patient.prototype.socialHistories = function() { -3021 var list, socialhistory, _i, _len, _ref1; +3004 Patient.prototype.custodian = function() { +3005 return new hQuery.Organization(this.json['custodian']); +3006 }; +3007 +3008 /** +3009 @returns {Provider} the providers associated with the patient +3010 */ +3011 +3012 +3013 Patient.prototype.provider = function() { +3014 return new hQuery.Provider(this.json['provider']); +3015 }; +3016 +3017 /** +3018 @returns {hQuery.CodedEntryList} A list of {@link hQuery.LanguagesSpoken} objects +3019 Code from http://www.ietf.org/rfc/rfc4646.txt representing the name of the human language +3020 */ +3021 3022 -3023 list = new hQuery.CodedEntryList; -3024 if (this.json['socialhistories']) { -3025 _ref1 = this.json['socialhistories']; -3026 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -3027 socialhistory = _ref1[_i]; -3028 list.pushIfUsable(new hQuery.Socialhistory(socialhistory)); -3029 } -3030 } -3031 return list; -3032 }; -3033 -3034 /** -3035 @returns {hQuery.CodedEntryList} A list of {@link CareGoal} objects -3036 */ -3037 -3038 -3039 Patient.prototype.careGoals = function() { -3040 var caregoal, list, _i, _len, _ref1; +3023 Patient.prototype.languages = function() { +3024 var language, list, _i, _len, _ref1; +3025 +3026 list = new hQuery.CodedEntryList; +3027 if (this.json['languages']) { +3028 _ref1 = this.json['languages']; +3029 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +3030 language = _ref1[_i]; +3031 list.push(new hQuery.Language(language)); +3032 } +3033 } +3034 return list; +3035 }; +3036 +3037 /** +3038 @returns {Boolean} returns true if the patient has died +3039 */ +3040 3041 -3042 list = new hQuery.CodedEntryList; -3043 if (this.json['care_goals']) { -3044 _ref1 = this.json['care_goals']; -3045 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -3046 caregoal = _ref1[_i]; -3047 list.pushIfUsable(new hQuery.CareGoal(caregoal)); -3048 } -3049 } -3050 return list; -3051 }; -3052 -3053 /** -3054 @returns {hQuery.CodedEntryList} A list of {@link MedicalEquipment} objects -3055 */ -3056 -3057 -3058 Patient.prototype.medicalEquipment = function() { -3059 var equipment, list, _i, _len, _ref1; -3060 -3061 list = new hQuery.CodedEntryList; -3062 if (this.json['medical_equipment']) { -3063 _ref1 = this.json['medical_equipment']; -3064 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -3065 equipment = _ref1[_i]; -3066 list.pushIfUsable(new hQuery.MedicalEquipment(equipment)); -3067 } -3068 } -3069 return list; -3070 }; -3071 -3072 /** -3073 @returns {hQuery.CodedEntryList} A list of {@link FunctionalStatus} objects -3074 */ -3075 -3076 -3077 Patient.prototype.functionalStatuses = function() { -3078 var fs, list, _i, _len, _ref1; -3079 -3080 list = new hQuery.CodedEntryList; -3081 if (this.json['functional_statuses']) { -3082 _ref1 = this.json['functional_statuses']; -3083 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -3084 fs = _ref1[_i]; -3085 list.pushIfUsable(new hQuery.FunctionalStatus(fs)); -3086 } -3087 } -3088 return list; -3089 }; -3090 -3091 return Patient; +3042 Patient.prototype.expired = function() { +3043 return this.json['expired']; +3044 }; +3045 +3046 /** +3047 @returns {Boolean} returns true if the patient participated in a clinical trial +3048 */ +3049 +3050 +3051 Patient.prototype.clinicalTrialParticipant = function() { +3052 return this.json['clinicalTrialParticipant']; +3053 }; +3054 +3055 /** +3056 @returns {hQuery.CodedEntryList} A list of {@link hQuery.Encounter} objects +3057 */ +3058 +3059 +3060 Patient.prototype.encounters = function() { +3061 var encounter, list, _i, _len, _ref1; +3062 +3063 list = new hQuery.CodedEntryList; +3064 if (this.json['encounters']) { +3065 _ref1 = this.json['encounters']; +3066 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +3067 encounter = _ref1[_i]; +3068 list.pushIfUsable(new hQuery.Encounter(encounter)); +3069 } +3070 } +3071 return list; +3072 }; +3073 +3074 /** +3075 @returns {hQuery.CodedEntryList} A list of {@link Medication} objects +3076 */ +3077 +3078 +3079 Patient.prototype.medications = function() { +3080 var list, medication, _i, _len, _ref1; +3081 +3082 list = new hQuery.CodedEntryList; +3083 if (this.json['medications']) { +3084 _ref1 = this.json['medications']; +3085 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +3086 medication = _ref1[_i]; +3087 list.pushIfUsable(new hQuery.Medication(medication)); +3088 } +3089 } +3090 return list; +3091 }; 3092 -3093 })(hQuery.Person); -3094 \ No newline at end of file +3093 /** +3094 @returns {hQuery.CodedEntryList} A list of {@link Condition} objects +3095 */ +3096 +3097 +3098 Patient.prototype.conditions = function() { +3099 var condition, list, _i, _len, _ref1; +3100 +3101 list = new hQuery.CodedEntryList; +3102 if (this.json['conditions']) { +3103 _ref1 = this.json['conditions']; +3104 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +3105 condition = _ref1[_i]; +3106 list.pushIfUsable(new hQuery.Condition(condition)); +3107 } +3108 } +3109 return list; +3110 }; +3111 +3112 /** +3113 @returns {hQuery.CodedEntryList} A list of {@link Procedure} objects +3114 */ +3115 +3116 +3117 Patient.prototype.procedures = function() { +3118 var list, procedure, _i, _len, _ref1; +3119 +3120 list = new hQuery.CodedEntryList; +3121 if (this.json['procedures']) { +3122 _ref1 = this.json['procedures']; +3123 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +3124 procedure = _ref1[_i]; +3125 list.pushIfUsable(new hQuery.Procedure(procedure)); +3126 } +3127 } +3128 return list; +3129 }; +3130 +3131 /** +3132 @returns {hQuery.CodedEntryList} A list of {@link Result} objects +3133 */ +3134 +3135 +3136 Patient.prototype.results = function() { +3137 var list, result, _i, _len, _ref1; +3138 +3139 list = new hQuery.CodedEntryList; +3140 if (this.json['results']) { +3141 _ref1 = this.json['results']; +3142 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +3143 result = _ref1[_i]; +3144 list.pushIfUsable(new hQuery.Result(result)); +3145 } +3146 } +3147 return list; +3148 }; +3149 +3150 /** +3151 @returns {hQuery.CodedEntryList} A list of {@link Result} objects +3152 */ +3153 +3154 +3155 Patient.prototype.vitalSigns = function() { +3156 var list, vital, _i, _len, _ref1; +3157 +3158 list = new hQuery.CodedEntryList; +3159 if (this.json['vital_signs']) { +3160 _ref1 = this.json['vital_signs']; +3161 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +3162 vital = _ref1[_i]; +3163 list.pushIfUsable(new hQuery.Result(vital)); +3164 } +3165 } +3166 return list; +3167 }; +3168 +3169 /** +3170 @returns {hQuery.CodedEntryList} A list of {@link Immunization} objects +3171 */ +3172 +3173 +3174 Patient.prototype.immunizations = function() { +3175 var immunization, list, _i, _len, _ref1; +3176 +3177 list = new hQuery.CodedEntryList; +3178 if (this.json['immunizations']) { +3179 _ref1 = this.json['immunizations']; +3180 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +3181 immunization = _ref1[_i]; +3182 list.pushIfUsable(new hQuery.Immunization(immunization)); +3183 } +3184 } +3185 return list; +3186 }; +3187 +3188 /** +3189 @returns {hQuery.CodedEntryList} A list of {@link Allergy} objects +3190 */ +3191 +3192 +3193 Patient.prototype.allergies = function() { +3194 var allergy, list, _i, _len, _ref1; +3195 +3196 list = new hQuery.CodedEntryList; +3197 if (this.json['allergies']) { +3198 _ref1 = this.json['allergies']; +3199 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +3200 allergy = _ref1[_i]; +3201 list.pushIfUsable(new hQuery.Allergy(allergy)); +3202 } +3203 } +3204 return list; +3205 }; +3206 +3207 /** +3208 @returns {hQuery.CodedEntryList} A list of {@link Pregnancy} objects +3209 */ +3210 +3211 +3212 Patient.prototype.pregnancies = function() { +3213 var list, pregnancy, _i, _len, _ref1; +3214 +3215 list = new hQuery.CodedEntryList; +3216 if (this.json['pregnancies']) { +3217 _ref1 = this.json['pregnancies']; +3218 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +3219 pregnancy = _ref1[_i]; +3220 list.pushIfUsable(new hQuery.Pregnancy(pregnancy)); +3221 } +3222 } +3223 return list; +3224 }; +3225 +3226 /** +3227 @returns {hQuery.CodedEntryList} A list of {@link Socialhistory} objects +3228 */ +3229 +3230 +3231 Patient.prototype.socialHistories = function() { +3232 var list, socialhistory, _i, _len, _ref1; +3233 +3234 list = new hQuery.CodedEntryList; +3235 if (this.json['socialhistories']) { +3236 _ref1 = this.json['socialhistories']; +3237 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +3238 socialhistory = _ref1[_i]; +3239 list.pushIfUsable(new hQuery.Socialhistory(socialhistory)); +3240 } +3241 } +3242 return list; +3243 }; +3244 +3245 /** +3246 @returns {hQuery.CodedEntryList} A list of {@link CareGoal} objects +3247 */ +3248 +3249 +3250 Patient.prototype.careGoals = function() { +3251 var caregoal, list, _i, _len, _ref1; +3252 +3253 list = new hQuery.CodedEntryList; +3254 if (this.json['care_goals']) { +3255 _ref1 = this.json['care_goals']; +3256 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +3257 caregoal = _ref1[_i]; +3258 list.pushIfUsable(new hQuery.CareGoal(caregoal)); +3259 } +3260 } +3261 return list; +3262 }; +3263 +3264 /** +3265 @returns {hQuery.CodedEntryList} A list of {@link MedicalEquipment} objects +3266 */ +3267 +3268 +3269 Patient.prototype.medicalEquipment = function() { +3270 var equipment, list, _i, _len, _ref1; +3271 +3272 list = new hQuery.CodedEntryList; +3273 if (this.json['medical_equipment']) { +3274 _ref1 = this.json['medical_equipment']; +3275 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +3276 equipment = _ref1[_i]; +3277 list.pushIfUsable(new hQuery.MedicalEquipment(equipment)); +3278 } +3279 } +3280 return list; +3281 }; +3282 +3283 /** +3284 @returns {hQuery.CodedEntryList} A list of {@link FunctionalStatus} objects +3285 */ +3286 +3287 +3288 Patient.prototype.functionalStatuses = function() { +3289 var fs, list, _i, _len, _ref1; +3290 +3291 list = new hQuery.CodedEntryList; +3292 if (this.json['functional_statuses']) { +3293 _ref1 = this.json['functional_statuses']; +3294 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { +3295 fs = _ref1[_i]; +3296 list.pushIfUsable(new hQuery.FunctionalStatus(fs)); +3297 } +3298 } +3299 return list; +3300 }; +3301 +3302 return Patient; +3303 +3304 })(hQuery.Person); +3305 \ No newline at end of file From 5b263d1a95eae37d6392654ea24b0bf73f3988dd Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Tue, 2 Jul 2013 14:39:42 -0700 Subject: [PATCH 027/117] Adding our own Gemfile.lock for build consistency --- .gitignore | 1 - Gemfile.lock | 228 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 Gemfile.lock diff --git a/.gitignore b/.gitignore index bf27f63..fe004b4 100755 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,4 @@ public/assets spec/javascripts/generated/* log/ spec/generated -Gemfile.lock .idea diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..0c8befc --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,228 @@ +GIT + remote: http://github.com/scoophealth/patientapi.git + revision: 704408c25590e38924fd8f8a393e25328b81013b + branch: scoop-develop + specs: + hquery-patient-api (1.0.2) + +GEM + remote: https://rubygems.org/ + specs: + actionmailer (3.2.13) + actionpack (= 3.2.13) + mail (~> 2.5.3) + actionpack (3.2.13) + activemodel (= 3.2.13) + activesupport (= 3.2.13) + builder (~> 3.0.0) + erubis (~> 2.7.0) + journey (~> 1.0.4) + rack (~> 1.4.5) + rack-cache (~> 1.2) + rack-test (~> 0.6.1) + sprockets (~> 2.2.1) + activemodel (3.2.13) + activesupport (= 3.2.13) + builder (~> 3.0.0) + activerecord (3.2.13) + activemodel (= 3.2.13) + activesupport (= 3.2.13) + arel (~> 3.0.2) + tzinfo (~> 0.3.29) + activeresource (3.2.13) + activemodel (= 3.2.13) + activesupport (= 3.2.13) + activesupport (3.2.13) + i18n (= 0.6.1) + multi_json (~> 1.0) + ansi (1.4.3) + arel (3.0.2) + bcrypt-ruby (3.0.1) + builder (3.0.4) + cancan (1.6.10) + childprocess (0.3.9) + ffi (~> 1.0, >= 1.0.11) + coderay (1.0.9) + coffee-rails (3.2.2) + coffee-script (>= 2.2.0) + railties (~> 3.2.0) + coffee-script (2.2.0) + coffee-script-source + execjs + coffee-script-source (1.6.2) + configatron (2.13.0) + yamler (>= 0.1.0) + cover_me (1.1.2) + configatron + hashie + daemons (1.1.9) + delayed_job (3.0.5) + activesupport (~> 3.0) + delayed_job_mongoid (2.0.0) + delayed_job (~> 3.0) + mongoid (~> 3.0) + devise (2.2.4) + bcrypt-ruby (~> 3.0) + orm_adapter (~> 0.1) + railties (~> 3.1) + warden (~> 1.2.1) + diff-lcs (1.2.4) + erubis (2.7.0) + execjs (1.4.0) + multi_json (~> 1.0) + factory_girl (4.2.0) + activesupport (>= 3.0.0) + fakeweb (1.3.0) + ffi (1.9.0) + hashie (2.0.5) + headless (1.0.1) + hike (1.2.3) + i18n (0.6.1) + jasmine (1.3.2) + jasmine-core (~> 1.3.1) + rack (~> 1.0) + rspec (>= 1.3.1) + selenium-webdriver (>= 0.1.3) + jasmine-core (1.3.1) + journey (1.0.4) + jquery-rails (1.0.19) + railties (~> 3.0) + thor (~> 0.14) + json (1.8.0) + kramdown (1.0.2) + libv8 (3.11.8.17) + mail (2.5.4) + mime-types (~> 1.16) + treetop (~> 1.4.8) + metaclass (0.0.1) + method_source (0.8.1) + mime-types (1.23) + minitest (4.7.5) + mocha (0.14.0) + metaclass (~> 0.0.1) + mongoid (3.1.4) + activemodel (~> 3.2) + moped (~> 1.4) + origin (~> 1.0) + tzinfo (~> 0.3.22) + mongoid_rails_migrations (1.0.1) + activesupport (>= 3.2.0) + bundler (>= 1.0.0) + rails (>= 3.2.0) + railties (>= 3.2.0) + moped (1.5.0) + multi_json (1.7.7) + multipart-post (1.2.0) + origin (1.1.0) + orm_adapter (0.4.0) + polyglot (0.3.3) + pry (0.9.12.2) + coderay (~> 1.0.5) + method_source (~> 0.8) + slop (~> 3.4) + rack (1.4.5) + rack-cache (1.2) + rack (>= 0.4) + rack-ssl (1.3.3) + rack + rack-test (0.6.2) + rack (>= 1.0) + rails (3.2.13) + actionmailer (= 3.2.13) + actionpack (= 3.2.13) + activerecord (= 3.2.13) + activeresource (= 3.2.13) + activesupport (= 3.2.13) + bundler (~> 1.0) + railties (= 3.2.13) + railties (3.2.13) + actionpack (= 3.2.13) + activesupport (= 3.2.13) + rack-ssl (~> 1.3.2) + rake (>= 0.8.7) + rdoc (~> 3.4) + thor (>= 0.14.6, < 2.0) + rake (10.1.0) + rdoc (3.12.2) + json (~> 1.4) + ref (1.0.5) + rspec (2.13.0) + rspec-core (~> 2.13.0) + rspec-expectations (~> 2.13.0) + rspec-mocks (~> 2.13.0) + rspec-core (2.13.1) + rspec-expectations (2.13.0) + diff-lcs (>= 1.1.3, < 2.0) + rspec-mocks (2.13.1) + rubyzip (0.9.9) + sass (3.2.9) + sass-rails (3.2.6) + railties (~> 3.2.0) + sass (>= 3.1.10) + tilt (~> 1.3) + selenium-webdriver (2.33.0) + childprocess (>= 0.2.5) + multi_json (~> 1.0) + rubyzip + websocket (~> 1.0.4) + simple_form (2.1.0) + actionpack (~> 3.0) + activemodel (~> 3.0) + slop (3.4.5) + sprockets (2.2.2) + hike (~> 1.2) + multi_json (~> 1.0) + rack (~> 1.0) + tilt (~> 1.1, != 1.3.0) + therubyracer (0.11.4) + libv8 (~> 3.11.8.12) + ref + thor (0.18.1) + tilt (1.4.1) + treetop (1.4.14) + polyglot + polyglot (>= 0.3.1) + turn (0.9.6) + ansi + tzinfo (0.3.37) + uglifier (2.1.1) + execjs (>= 0.3.0) + multi_json (~> 1.0, >= 1.0.2) + warden (1.2.1) + rack (>= 1.0) + websocket (1.0.7) + yamler (0.1.0) + +PLATFORMS + ruby + +DEPENDENCIES + cancan + coderay + coffee-rails + cover_me (>= 1.0.0.rc6) + daemons + delayed_job + delayed_job_mongoid + devise + factory_girl + fakeweb + headless + hquery-patient-api! + jasmine + jquery-rails (= 1.0.19) + kramdown + minitest (< 5.0.0) + mocha + mongoid + mongoid_rails_migrations + multipart-post + pry + rails + sass-rails + simple_form + sprockets + therubyracer + therubyrhino + turn + uglifier From 19acee6c2a89b4d51f67cad7a44582ff25c9ef21 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Wed, 3 Jul 2013 11:36:47 -0700 Subject: [PATCH 028/117] reverted to slightly earlier patientapi to match query-gateway --- Gemfile | 2 +- Gemfile.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index 4597bb2..585c053 100755 --- a/Gemfile +++ b/Gemfile @@ -24,7 +24,7 @@ gem 'simple_form' gem 'multipart-post' gem 'delayed_job' gem 'delayed_job_mongoid' #, :git => 'https://github.com/collectiveidea/delayed_job_mongoid.git' -gem 'hquery-patient-api', :git => 'http://github.com/scoophealth/patientapi.git', :branch => 'scoop-develop' +gem 'hquery-patient-api', :git => 'http://github.com/scoophealth/patientapi.git', :tag => 'v1.0.0' #:branch => 'scoop-develop' gem 'devise' gem 'cancan' gem 'pry' diff --git a/Gemfile.lock b/Gemfile.lock index 0c8befc..0387358 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,9 +1,9 @@ GIT remote: http://github.com/scoophealth/patientapi.git - revision: 704408c25590e38924fd8f8a393e25328b81013b - branch: scoop-develop + revision: 779b4d707fb7b325c81be2a9713ee073f7d84375 + tag: v1.0.0 specs: - hquery-patient-api (1.0.2) + hquery-patient-api (1.0.0) GEM remote: https://rubygems.org/ From 1af552603393621c8ced7e8644b021e73bbec261 Mon Sep 17 00:00:00 2001 From: Jeremy Ho Date: Mon, 8 Jul 2013 15:56:48 -0700 Subject: [PATCH 029/117] Remove unnecessary .gitkeep files Signed-off-by: Jeremy Ho --- app/mailers/.gitkeep | 0 app/models/.gitkeep | 0 lib/tasks/.gitkeep | 0 3 files changed, 0 insertions(+), 0 deletions(-) delete mode 100755 app/mailers/.gitkeep delete mode 100755 app/models/.gitkeep delete mode 100755 lib/tasks/.gitkeep diff --git a/app/mailers/.gitkeep b/app/mailers/.gitkeep deleted file mode 100755 index e69de29..0000000 diff --git a/app/models/.gitkeep b/app/models/.gitkeep deleted file mode 100755 index e69de29..0000000 diff --git a/lib/tasks/.gitkeep b/lib/tasks/.gitkeep deleted file mode 100755 index e69de29..0000000 From 50c01b03d5f239798136b362e350f3f7a6baa515 Mon Sep 17 00:00:00 2001 From: Jeremy Ho Date: Wed, 10 Jul 2013 10:35:48 -0700 Subject: [PATCH 030/117] Update/sync gem dependencies with gateway Signed-off-by: Jeremy Ho --- Gemfile | 34 ++++++++++++++++------------------ Gemfile.lock | 32 ++++++++++++++++---------------- 2 files changed, 32 insertions(+), 34 deletions(-) diff --git a/Gemfile b/Gemfile index 585c053..8e7e7ac 100755 --- a/Gemfile +++ b/Gemfile @@ -1,10 +1,6 @@ source "https://rubygems.org" gem 'rails' - -# Bundle edge Rails instead: -# gem 'rails', :git => 'git://github.com/rails/rails.git' - # Gems used only for assets and not required # in production environments by default. group :assets do @@ -13,39 +9,41 @@ group :assets do gem 'uglifier' end -gem 'jquery-rails', '=1.0.19' -gem 'sprockets' -#gem 'bson_ext', :platforms => :mri gem 'daemons' -#gem 'mongo' -gem "mongoid" +gem 'jquery-rails' +gem 'sprockets' + +gem 'mongoid' gem 'mongoid_rails_migrations' + gem 'simple_form' + gem 'multipart-post' gem 'delayed_job' -gem 'delayed_job_mongoid' #, :git => 'https://github.com/collectiveidea/delayed_job_mongoid.git' -gem 'hquery-patient-api', :git => 'http://github.com/scoophealth/patientapi.git', :tag => 'v1.0.0' #:branch => 'scoop-develop' +gem 'delayed_job_mongoid' + +gem 'hquery-patient-api', :git => 'https://github.com/scoophealth/patientapi.git', :tag => 'v1.0.0' + +gem 'coderay' + gem 'devise' gem 'cancan' gem 'pry' gem 'kramdown' gem 'jasmine', :group => [:development, :test] gem 'headless', :group => [:development, :test] -gem 'coderay' - - # To use debugger # gem 'ruby-debug19', :require => 'ruby-debug' group :test do # Pretty printed test output - gem 'turn', :require => false - gem 'cover_me', '>= 1.0.0.rc6' gem 'minitest', '< 5.0.0' + gem 'turn', :require => false + gem 'cover_me', '>= 1.0.0.rc6', :platforms => :ruby + gem 'factory_girl' gem 'fakeweb' + gem 'mocha', :require => false gem 'therubyracer', :platforms => :ruby gem 'therubyrhino', :platforms => :jruby - gem 'factory_girl' - gem 'mocha', :require => false end diff --git a/Gemfile.lock b/Gemfile.lock index 0387358..1cf6fa9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,5 +1,5 @@ GIT - remote: http://github.com/scoophealth/patientapi.git + remote: https://github.com/scoophealth/patientapi.git revision: 779b4d707fb7b325c81be2a9713ee073f7d84375 tag: v1.0.0 specs: @@ -37,7 +37,7 @@ GEM multi_json (~> 1.0) ansi (1.4.3) arel (3.0.2) - bcrypt-ruby (3.0.1) + bcrypt-ruby (3.1.1) builder (3.0.4) cancan (1.6.10) childprocess (0.3.9) @@ -49,10 +49,10 @@ GEM coffee-script (2.2.0) coffee-script-source execjs - coffee-script-source (1.6.2) + coffee-script-source (1.6.3) configatron (2.13.0) yamler (>= 0.1.0) - cover_me (1.1.2) + cover_me (1.2.0) configatron hashie daemons (1.1.9) @@ -85,11 +85,11 @@ GEM selenium-webdriver (>= 0.1.3) jasmine-core (1.3.1) journey (1.0.4) - jquery-rails (1.0.19) - railties (~> 3.0) - thor (~> 0.14) + jquery-rails (3.0.2) + railties (>= 3.0, < 5.0) + thor (>= 0.14, < 2.0) json (1.8.0) - kramdown (1.0.2) + kramdown (1.1.0) libv8 (3.11.8.17) mail (2.5.4) mime-types (~> 1.16) @@ -146,14 +146,14 @@ GEM rdoc (3.12.2) json (~> 1.4) ref (1.0.5) - rspec (2.13.0) - rspec-core (~> 2.13.0) - rspec-expectations (~> 2.13.0) - rspec-mocks (~> 2.13.0) - rspec-core (2.13.1) - rspec-expectations (2.13.0) + rspec (2.14.0) + rspec-core (~> 2.14.0) + rspec-expectations (~> 2.14.0) + rspec-mocks (~> 2.14.0) + rspec-core (2.14.2) + rspec-expectations (2.14.0) diff-lcs (>= 1.1.3, < 2.0) - rspec-mocks (2.13.1) + rspec-mocks (2.14.1) rubyzip (0.9.9) sass (3.2.9) sass-rails (3.2.6) @@ -210,7 +210,7 @@ DEPENDENCIES headless hquery-patient-api! jasmine - jquery-rails (= 1.0.19) + jquery-rails kramdown minitest (< 5.0.0) mocha From 7d743c0755edf4889ff2a0389b618b5b448a9143 Mon Sep 17 00:00:00 2001 From: Jeremy Ho Date: Wed, 10 Jul 2013 11:46:02 -0700 Subject: [PATCH 031/117] Gemfile.lock update Signed-off-by: Jeremy Ho --- Gemfile | 4 ++-- Gemfile.lock | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index 8e7e7ac..982c701 100755 --- a/Gemfile +++ b/Gemfile @@ -1,4 +1,4 @@ -source "https://rubygems.org" +source 'https://rubygems.org' gem 'rails' # Gems used only for assets and not required @@ -22,7 +22,7 @@ gem 'multipart-post' gem 'delayed_job' gem 'delayed_job_mongoid' -gem 'hquery-patient-api', :git => 'https://github.com/scoophealth/patientapi.git', :tag => 'v1.0.0' +gem 'hquery-patient-api', :git => 'https://github.com/scoophealth/patientapi.git', :branch => 'scoop-develop' gem 'coderay' diff --git a/Gemfile.lock b/Gemfile.lock index 1cf6fa9..7f14c2c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ GIT remote: https://github.com/scoophealth/patientapi.git - revision: 779b4d707fb7b325c81be2a9713ee073f7d84375 - tag: v1.0.0 + revision: 2afc31e48f0480ca9ce16f27939a0a1a5efd153d + branch: scoop-develop specs: hquery-patient-api (1.0.0) From 8ca4b2a30f86df4229e4269119a80229b2644ffb Mon Sep 17 00:00:00 2001 From: Jeremy Ho Date: Wed, 10 Jul 2013 16:26:42 -0700 Subject: [PATCH 032/117] Reimplement jquery-rails lock on 1.0.19 Signed-off-by: Jeremy Ho --- Gemfile | 2 +- Gemfile.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Gemfile b/Gemfile index 982c701..a91391c 100755 --- a/Gemfile +++ b/Gemfile @@ -10,7 +10,7 @@ group :assets do end gem 'daemons' -gem 'jquery-rails' +gem 'jquery-rails', '=1.0.19' gem 'sprockets' gem 'mongoid' diff --git a/Gemfile.lock b/Gemfile.lock index 7f14c2c..84c258b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -52,7 +52,7 @@ GEM coffee-script-source (1.6.3) configatron (2.13.0) yamler (>= 0.1.0) - cover_me (1.2.0) + cover_me (1.1.2) configatron hashie daemons (1.1.9) @@ -85,9 +85,9 @@ GEM selenium-webdriver (>= 0.1.3) jasmine-core (1.3.1) journey (1.0.4) - jquery-rails (3.0.2) - railties (>= 3.0, < 5.0) - thor (>= 0.14, < 2.0) + jquery-rails (1.0.19) + railties (~> 3.0) + thor (~> 0.14) json (1.8.0) kramdown (1.1.0) libv8 (3.11.8.17) @@ -210,7 +210,7 @@ DEPENDENCIES headless hquery-patient-api! jasmine - jquery-rails + jquery-rails (= 1.0.19) kramdown minitest (< 5.0.0) mocha From 59cda5c468274901958a20846179283322638530 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Thu, 11 Jul 2013 09:08:46 -0700 Subject: [PATCH 033/117] Restore logout functionality --- config/initializers/devise.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 98553f9..399e79b 100755 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -214,7 +214,7 @@ # config.navigational_formats = ["*/*", :html] # The default HTTP method used to sign out a resource. Default is :delete. - config.sign_out_via = :delete + config.sign_out_via = :get # ==> OmniAuth # Add a new OmniAuth provider. Check the wiki for more information on setting From 77d2fa682830e47daa38fa3b486469cd301ae3aa Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Thu, 11 Jul 2013 10:43:30 -0700 Subject: [PATCH 034/117] Firefox workaround for nuisance redirect warning in Query Builder --- README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/README.md b/README.md index eda828f..88a3871 100755 --- a/README.md +++ b/README.md @@ -23,6 +23,23 @@ Dependencies on old gems (to be remedied in future) * jquery-rails 1.0.19 and jQuery UI 1.8.16 * minitest < 5.0.0 +Browser Issue with Firefox +-------------------------- +When using the visual Query Builder in Firefox (but not with Chrome of IE), there is an issue with +popups containing the message: + +"This web page is being redirected to a new location. Would you like to resend the form data you +have typed to the new location?" + +This message will continue to popup until "Cancel" is entered. The builder works ok, regardless +of this irritating message. + +To eliminate these warnings from Firefox, the following configuration change can be applied +(from https://support.mozilla.org/en-US/questions/792131): + +* Type in your firefox url : about:config +* Then toggle the following option : network.http.prompt-temp-redirect + Install Instructions -------------------- From 2e447c340376f5fe66198d40d8f50f6a2be1086f Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Thu, 11 Jul 2013 11:37:03 -0700 Subject: [PATCH 035/117] Clarify browser workaround info --- README.md | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 88a3871..be3c7b8 100755 --- a/README.md +++ b/README.md @@ -25,20 +25,16 @@ Dependencies on old gems (to be remedied in future) Browser Issue with Firefox -------------------------- -When using the visual Query Builder in Firefox (but not with Chrome of IE), there is an issue with -popups containing the message: +When using the visual Query Builder in Firefox (but not with Chrome of IE), there is an issue with popups containing the message: -"This web page is being redirected to a new location. Would you like to resend the form data you -have typed to the new location?" +"This web page is being redirected to a new location. Would you like to resend the form data you have typed to the new location?" -This message will continue to popup until "Cancel" is entered. The builder works ok, regardless -of this irritating message. +This message will continue to popup until "Cancel" is entered. The builder works OK despite this irritating message. -To eliminate these warnings from Firefox, the following configuration change can be applied -(from https://support.mozilla.org/en-US/questions/792131): +To eliminate these warnings from Firefox, the following configuration change can be applied (from https://support.mozilla.org/en-US/questions/792131): * Type in your firefox url : about:config -* Then toggle the following option : network.http.prompt-temp-redirect +* Then toggle the following option : network.http.prompt-temp-redirect to false Install Instructions -------------------- From bf5e3d6718978ad07acb3bb8351a5ec06ab67a92 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Thu, 11 Jul 2013 11:43:54 -0700 Subject: [PATCH 036/117] Fix url for browser workaround --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index be3c7b8..5a711b4 100755 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ When using the visual Query Builder in Firefox (but not with Chrome of IE), ther This message will continue to popup until "Cancel" is entered. The builder works OK despite this irritating message. -To eliminate these warnings from Firefox, the following configuration change can be applied (from https://support.mozilla.org/en-US/questions/792131): +To eliminate these warnings from Firefox, the following configuration change can be applied (from https://support.mozilla.org/en-US/questions/792131 ): * Type in your firefox url : about:config * Then toggle the following option : network.http.prompt-temp-redirect to false From e1ca64b4d5b74d90804b7b0d4baec4537cf1479d Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Thu, 11 Jul 2013 11:45:40 -0700 Subject: [PATCH 037/117] Fix another typo in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5a711b4..d498770 100755 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Dependencies on old gems (to be remedied in future) Browser Issue with Firefox -------------------------- -When using the visual Query Builder in Firefox (but not with Chrome of IE), there is an issue with popups containing the message: +When using the visual Query Builder in Firefox (but not with Chrome or IE), there is an issue with popups containing the message: "This web page is being redirected to a new location. Would you like to resend the form data you have typed to the new location?" From 4665c8f2a2738db0c5078c28fc916a0b2cc27c37 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Fri, 12 Jul 2013 09:13:36 -0700 Subject: [PATCH 038/117] Add Webrick to gemfile to remove nuisance warning --- Gemfile | 1 + Gemfile.lock | 2 ++ 2 files changed, 3 insertions(+) diff --git a/Gemfile b/Gemfile index 982c701..bf50195 100755 --- a/Gemfile +++ b/Gemfile @@ -12,6 +12,7 @@ end gem 'daemons' gem 'jquery-rails' gem 'sprockets' +gem 'webrick', '1.3.1' gem 'mongoid' gem 'mongoid_rails_migrations' diff --git a/Gemfile.lock b/Gemfile.lock index 7f14c2c..2ecdb9f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -190,6 +190,7 @@ GEM multi_json (~> 1.0, >= 1.0.2) warden (1.2.1) rack (>= 1.0) + webrick (1.3.1) websocket (1.0.7) yamler (0.1.0) @@ -226,3 +227,4 @@ DEPENDENCIES therubyrhino turn uglifier + webrick (= 1.3.1) From 8519065279810551ce711ebbcb7a911f8c1f6b60 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Fri, 12 Jul 2013 09:16:37 -0700 Subject: [PATCH 039/117] Add note to README.md regarding Webrick quirk --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index d498770..ab6ef5b 100755 --- a/README.md +++ b/README.md @@ -17,6 +17,10 @@ Dependencies * Ruby = 1.9.3 * Rails 3.2.13 * MongoDB >= 2.4.1 +* Webrick = 1.3.1 added to eliminate nuisance messages in log regarding: + WARN Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true + + Based on information gotten from http://stackoverflow.com/questions/9612618/warn-could-not-determine-content-length-of-response-body-set-content-length-of adding Webrick explicitely to Gemfile (even though it is the version already being used) resolves the problem. Dependencies on old gems (to be remedied in future) --------------------------------------------------- From 268674a336fef992943ad4c513d4ee1cebbb3157 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Mon, 15 Jul 2013 16:00:42 -0700 Subject: [PATCH 040/117] Locked rails to 3.2.7 to prevent escaping of single and double quote which breaks mongo calls --- Gemfile | 2 +- Gemfile.lock | 66 ++++++++++++++++++++++++++-------------------------- README.md | 3 ++- 3 files changed, 36 insertions(+), 35 deletions(-) diff --git a/Gemfile b/Gemfile index e8d970e..dbfb484 100755 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source 'https://rubygems.org' -gem 'rails' +gem 'rails', '=3.2.7' # Gems used only for assets and not required # in production environments by default. group :assets do diff --git a/Gemfile.lock b/Gemfile.lock index 2bffa42..fca2cdf 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,32 +8,32 @@ GIT GEM remote: https://rubygems.org/ specs: - actionmailer (3.2.13) - actionpack (= 3.2.13) - mail (~> 2.5.3) - actionpack (3.2.13) - activemodel (= 3.2.13) - activesupport (= 3.2.13) + actionmailer (3.2.7) + actionpack (= 3.2.7) + mail (~> 2.4.4) + actionpack (3.2.7) + activemodel (= 3.2.7) + activesupport (= 3.2.7) builder (~> 3.0.0) erubis (~> 2.7.0) journey (~> 1.0.4) - rack (~> 1.4.5) + rack (~> 1.4.0) rack-cache (~> 1.2) rack-test (~> 0.6.1) - sprockets (~> 2.2.1) - activemodel (3.2.13) - activesupport (= 3.2.13) + sprockets (~> 2.1.3) + activemodel (3.2.7) + activesupport (= 3.2.7) builder (~> 3.0.0) - activerecord (3.2.13) - activemodel (= 3.2.13) - activesupport (= 3.2.13) + activerecord (3.2.7) + activemodel (= 3.2.7) + activesupport (= 3.2.7) arel (~> 3.0.2) tzinfo (~> 0.3.29) - activeresource (3.2.13) - activemodel (= 3.2.13) - activesupport (= 3.2.13) - activesupport (3.2.13) - i18n (= 0.6.1) + activeresource (3.2.7) + activemodel (= 3.2.7) + activesupport (= 3.2.7) + activesupport (3.2.7) + i18n (~> 0.6) multi_json (~> 1.0) ansi (1.4.3) arel (3.0.2) @@ -77,7 +77,7 @@ GEM hashie (2.0.5) headless (1.0.1) hike (1.2.3) - i18n (0.6.1) + i18n (0.6.4) jasmine (1.3.2) jasmine-core (~> 1.3.1) rack (~> 1.0) @@ -91,7 +91,8 @@ GEM json (1.8.0) kramdown (1.1.0) libv8 (3.11.8.17) - mail (2.5.4) + mail (2.4.4) + i18n (>= 0.4.0) mime-types (~> 1.16) treetop (~> 1.4.8) metaclass (0.0.1) @@ -127,17 +128,17 @@ GEM rack rack-test (0.6.2) rack (>= 1.0) - rails (3.2.13) - actionmailer (= 3.2.13) - actionpack (= 3.2.13) - activerecord (= 3.2.13) - activeresource (= 3.2.13) - activesupport (= 3.2.13) + rails (3.2.7) + actionmailer (= 3.2.7) + actionpack (= 3.2.7) + activerecord (= 3.2.7) + activeresource (= 3.2.7) + activesupport (= 3.2.7) bundler (~> 1.0) - railties (= 3.2.13) - railties (3.2.13) - actionpack (= 3.2.13) - activesupport (= 3.2.13) + railties (= 3.2.7) + railties (3.2.7) + actionpack (= 3.2.7) + activesupport (= 3.2.7) rack-ssl (~> 1.3.2) rake (>= 0.8.7) rdoc (~> 3.4) @@ -169,9 +170,8 @@ GEM actionpack (~> 3.0) activemodel (~> 3.0) slop (3.4.5) - sprockets (2.2.2) + sprockets (2.1.3) hike (~> 1.2) - multi_json (~> 1.0) rack (~> 1.0) tilt (~> 1.1, != 1.3.0) therubyracer (0.11.4) @@ -219,7 +219,7 @@ DEPENDENCIES mongoid_rails_migrations multipart-post pry - rails + rails (= 3.2.7) sass-rails simple_form sprockets diff --git a/README.md b/README.md index ab6ef5b..1b3efab 100755 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ hQuery will also run on Windows, however, there are some minor limitations to fu Dependencies ------------ * Ruby = 1.9.3 -* Rails 3.2.13 +* Rails 3.2.7 * MongoDB >= 2.4.1 * Webrick = 1.3.1 added to eliminate nuisance messages in log regarding: WARN Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true @@ -24,6 +24,7 @@ Dependencies Dependencies on old gems (to be remedied in future) --------------------------------------------------- +* rails 3.2.7 (later versions of rails escape single and double quotes with ' and \" which causes mongoid queries to fail) * jquery-rails 1.0.19 and jQuery UI 1.8.16 * minitest < 5.0.0 From 2c24695c3b9a28bc47a2b28a8ef6f5eef3b983ec Mon Sep 17 00:00:00 2001 From: Pierre Beucher Date: Wed, 7 Aug 2013 13:56:36 -0700 Subject: [PATCH 041/117] Added SSL config for every requests targeted at Endpoint/HOOK, and SSL config for server Signed-off-by: Pierre Beucher --- app/helpers/endpoints_helper.rb | 3 +- app/models/endpoint.rb | 5 +-- app/models/result.rb | 9 ++++-- cert/ca | 1 + cert/client.key | 51 +++++++++++++++++++++++++++++++ cert/client.pem | 32 +++++++++++++++++++ cert/comp-cert | 7 +++++ cert/composer.crt | 33 ++++++++++++++++++++ cert/composer.csr | 28 +++++++++++++++++ cert/composer.key | 51 +++++++++++++++++++++++++++++++ config/initializers/ssl_config.rb | 12 ++++++++ lib/gateway_utils.rb | 5 +-- runme.sh | 0 script/rails | 30 ++++++++++++++++++ 14 files changed, 259 insertions(+), 8 deletions(-) create mode 120000 cert/ca create mode 100644 cert/client.key create mode 100644 cert/client.pem create mode 100755 cert/comp-cert create mode 100644 cert/composer.crt create mode 100644 cert/composer.csr create mode 100644 cert/composer.key create mode 100644 config/initializers/ssl_config.rb mode change 100644 => 100755 runme.sh diff --git a/app/helpers/endpoints_helper.rb b/app/helpers/endpoints_helper.rb index 2cb658d..a136ea4 100755 --- a/app/helpers/endpoints_helper.rb +++ b/app/helpers/endpoints_helper.rb @@ -4,7 +4,8 @@ def fetch_endpoint_statuses @endpoints.each do |endpoint| url = endpoint.status_url begin - response = Net::HTTP.start(url.host, url.port) do |http| + #use ssl + response = Net::HTTP.start(url.host, url.port, :use_ssl => true, :key => CLIENT_KEY, :cert => CLIENT_CERT) do |http| headers = {} headers['Accept'] = 'application/atom+xml' http.get(url.path, headers) diff --git a/app/models/endpoint.rb b/app/models/endpoint.rb index 2fe648c..ddff83d 100755 --- a/app/models/endpoint.rb +++ b/app/models/endpoint.rb @@ -36,7 +36,8 @@ def check begin check_time = Time.now - response = Net::HTTP.start(url.host, url.port) do |http| + #use ssl + response = Net::HTTP.start(url.host, url.port, :use_ssl => true, :key => CLIENT_KEY, :cert => CLIENT_CERT) do |http| headers = {} if last_check headers['If-Modified-Since'] = last_check.to_formatted_s(:rfc822) @@ -86,4 +87,4 @@ def get_execution result def active_results_for_this_endpoint results.any_in(status: [Result::RUNNING, Result::QUEUED]) end -end \ No newline at end of file +end diff --git a/app/models/result.rb b/app/models/result.rb index f0e001a..d3acacd 100755 --- a/app/models/result.rb +++ b/app/models/result.rb @@ -29,7 +29,9 @@ def cancel def check logger.debug("Checking query url #{query_url}") url = URI.parse(query_url) - response = Net::HTTP.start(url.host, url.port) do |http| + + #use ssl + response = Net::HTTP.start(url.host, url.port, :use_ssl => true, :key => CLIENT_KEY, :cert => CLIENT_CERT) do |http| http.get(url.path, 'If-Modified-Since' => updated_at.to_formatted_s(:rfc822), 'Accept' => 'application/json') end @@ -65,11 +67,12 @@ def check def fetch_result url = URI.parse(self.result_url) - response = Net::HTTP.start(url.host, url.port) do |http| + #use ssl + response = Net::HTTP.start(url.host, url.port, :use_ssl => true, :key => CLIENT_KEY, :cert => CLIENT_CERT) do |http| http.get(url.path, 'Accept' => 'application/json') end self.value = JSON.parse(response.body) self.status = COMPLETE save! end -end \ No newline at end of file +end diff --git a/cert/ca b/cert/ca new file mode 120000 index 0000000..9f5e199 --- /dev/null +++ b/cert/ca @@ -0,0 +1 @@ +/home/pierre/scoop/ca \ No newline at end of file diff --git a/cert/client.key b/cert/client.key new file mode 100644 index 0000000..4943fd5 --- /dev/null +++ b/cert/client.key @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIJKAIBAAKCAgEAn3iD8UdYUidwmVUeqD3Y6yWBcLODaIohlgUWux+18oDygxAb +24MBkeQTQZZvDYvrCx1KqR/dDxgnM9loOWGAPpNG+GaMhJhBDGV5x+kzYZ7B4Ln1 +KJgWdB3URcwIqHqnfxrclStI0vEUHsVjHKhx37o+7AOuEbXoEcxchhIIZH/t3JUW +8NIxSO/lgIaxlP4Sd79u6d5a8zTvo5roqbzBCckSAhmhWoP3qPztmEAVFt18Ag0u +kpP5Kg/Twui2YAt9kcKfcUDeEUFV/U6TLdGnVDSC28kU0sdAgRiLy395tpMLtFd5 +N5T5tGGHG1lLdFisYI85EjoFmbNqQvG66vItEHt731SfZvPrhW9fto/QdPcbXDhB +EaRdWzBIJZHKInHjVXOOtUxXQtWUpNUdzXv3eMcaANql5lAR1gcFBAdOYkITwo4c +rvOzyCkS2vDAlbElrVups/mdphvjG9zNmuELtUpzm9rI8P3HjZIrcRuVBnUQHM4O +qy6Cg2rAtaDd+ZzcTDHoQDZOzU/clWo/VaA34rNHaZBamqiUiklbg42ldXL+m8jB +Np1O+Sl+4KRmzlZc/oLZFBOtlbxjnVWT8YnhBWU6X/iNNSN715NvyX7B6EJKvR8O +oE3hC5k1btQJ8iGTjmsZ9qNHbalryc/faR9fvl1UUkdo2S88C8LAbPaS5IUCAwEA +AQKCAgBUiFnIqH0U73ssjIZ3wHEgFP2MdFwQKkircX8fKiwUpG3pM7zQm51VbIUY +m1m64JRzi89r30wbGD6PqYsp/5kvknpoalPKZbr1i0UGx4NJGBLFwU1He3dLjhRb ++1ALnxjys5aCLDOqPcjgltl284OJiPyZt0mqcbbW2HGjUCPKwlWgPBexCHq/owsR +GlVAGX5Io91zcz7a9RCitRboAvqA6Wj2XAfAJ3w8w/ZeYnnLaRS3Ma2iXXYS6dji +1OD4AJ9LiNNkAXK1yuB+KgyymRQN+tfzEaBMKvryc8SG1sf6E/B8ZHIJGJtVFu27 +fZYV0ntto/4ov0EAvK5zVhgzOrTP1a2yQck3N7cBnCaIbolJD4pjFvSZFm3V6e3C +D7OvEM5xk7kjbxAheP0KCfv3m2TdV4eBJOdS7LuQDaOrX96Uu0+A5C3/sv4RRYNR +EiGBx2nHswqHldCdCbE/2iQRgRm1I2l4xVEo/FN5qNZzbnGnmrQj/PEno66AIMYD +TXHsrRYkpf89c/FTXg73ug4rFb6cZc12y5IlpnRXlIt9NY6djKTk5OXKbvlalA1P +uKNhpzWO2AtU0U+v3QkNSkIIuaOEx8AJCUq2vhSfZvXY/W6Lz+Ig3TFOS/58pCfq +av3RzttZAVtC2kedJ8x50WhNwSqm40bWzEH+oIV2pb3vP0HFgQKCAQEAy666H7tu +X+ku8zauqgv22FyYnEQLve0dc9RZAHFXQ82lKAGbsq4P6bL+oY7ipct+4v8jYFDa +GhxeAyfUCR82lPZHPC+OmjSkLOwUYtWHYq8zcgGUU5o+0iFewHdE6n+E2X54fv/P +y3xtHGnDgto0BRyWPBwlIruMGpiG43EJVZRAtB/bflnf1/OJEtcW0FtdzyFib/4o +3Okmnw2H+l/n/1ZCVQ4JWfnDyvQjLVRzyxkFxH3KKtYdLlIVWOHRq9p1tHdqloNW +PkXpt/KVpUHroHAIl+r7TI0+JP2Kvb5B7gk3JUQgUuySHmAR0DlWPS3KQ37SZay5 +sOYMcM6o0icAHQKCAQEAyG6dreTRg/UuhYhaL9ua2mxyikaJQLtQdIh2QD7GfV1E +wBRmy/NMQzro+NO7eSRHBvCAxcIUwiiLjIRtbKz/63SVBojZe1J7eSA2fnQmYbbF +KL+n2uRYF0be9ClyQGQdXKilcg4s26jnt1cPoKadpJj0iZjh6rf+XP4mKpiTuxKA +5MXr5uvTF4Gad7qBOObZdIJBEZ25n9pymmT2DjfDqe9B8kAi8NSuY0nV22KwTOZe +sIu2K6kJknQkIIsxrFtJivANGfioCNKN4uDck39jXjjJlC5gq4RBsDK2s7JCXk08 +6nykE0MiLBdZkqFkqz+o1Y35p3v2NVo38xYDtqUZiQKCAQA1IF//wt2pOqM6YPrx +86jxCkXsDHubkGtsOOj2CpoeX1dCthisZGZWKI/uB9zqLcfs4WuSxcP9p4SGAi92 +KaQM+qfd9PGXGz/vT6yJkvR7MwOSKwNLQyI7oOScAwAAwj4elLRNO+AxTUUQci3C +xbNn2er9xsGQ66ZBkaMtU+CBZ+fwk5amwD54j1cjiOK0egBf9G8+kuaJqG6gceET +10wl95PZp42c4F7HYyKBwlNpmB8+/yhqP+rgmBxlUJFl59dnuPYeSCeImqe5iRar +QiR5dn9nUK03bGfXMiKsFyIPOmwd1kUwG/CI57n9u9bYokbtj/jE+GZ+06JPEjhK +iE2pAoIBACi6OXYtadl7h8GAjHrvD89UfA3W+Wra5SVY2VaCqwisXBz/yEenH5cF +sHNnas/Z7Ejfs/r7TgaKAJlEC4wqtzIcFXAnfLHPd+GMBya46VevsO5vy2byQWgx +cXqBtYKaFVFPv5amhLz53GPn3/gQAzaAEiinlTiBvMEer5i2OkaoIuLZyO66esFr +B31Ou5VZa1R+Z0RyHVb7J5Bx9YG8GRk90dOs7qyrOuhYB4m1ywdFRHZxXUoP5i8J +RJIMVsKkJhSCZNcjLNnmFwjEEm4yU3nA5k0jA2e2zzZDh9aJ4WySG0+2lgyH9rio +4f2mp/MYU3FZkSJUURpUQ8w0a/rAH6kCggEBAJ6b/IcPAobGqkdSHATp34PQEQCd +XzplYGCr8epdm0pHf6/ptdegw5fwAp2l6oxcclxL0FXrP5qp0brVxBTDk5O83aDX +Iev+E1XdkXJnFpZ6hGCA3Tm1K8d0zeWtUHIwFjCLAA+7rwGM4PyqWZmfyyRBpEX9 +d0c4+9Ov4eSFpHYd/29+IzN3gx+T/ZfzBGFVEY0u6zP7f11m+aoRgSxrS0cuVn+c +QtqsnCTtaQU39jlPCE9p3JsPBXRzm99yNhIeon94L3+u44Twi1wvHIFIyZ6WIhqc +R1RPW2NrfrlBkZi6PlkioNpmS4/UD6zRkxsQOJthBtq51/rpp9uDR+9gIVE= +-----END RSA PRIVATE KEY----- diff --git a/cert/client.pem b/cert/client.pem new file mode 100644 index 0000000..d192587 --- /dev/null +++ b/cert/client.pem @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFmDCCA4ACBQOqfacEMA0GCSqGSIb3DQEBBQUAMIGhMQswCQYDVQQGEwJCQzET +MBEGA1UECBMKQ2FuZHkgTGFuZDERMA8GA1UEBxMIVmljdG9yaWExEDAOBgNVBAoT +B0xlYWRMYWIxFzAVBgNVBAsTDnd3dy5sZWFkbGFiLmNhMRcwFQYDVQQDEw5QaWVy +cmUgQkVVQ0hFUjEmMCQGCSqGSIb3DQEJARYXYmV1Y2hlci5waWVycmVAZmFrZS5j +b20wHhcNMTMwODA3MTc1ODAyWhcNMTQwNjAzMTc1ODAyWjB+MQswCQYDVQQGEwJD +QTELMAkGA1UECBMCQkMxDDAKBgNVBAcTA1ZpYzEQMA4GA1UEChMHTGVhZExhYjEP +MA0GA1UECxMGT3VyTGFiMRIwEAYDVQQDEwlsb2NhbGhvc3QxHTAbBgkqhkiG9w0B +CQEWDmZha2VAZ21haWwuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC +AgEAn3iD8UdYUidwmVUeqD3Y6yWBcLODaIohlgUWux+18oDygxAb24MBkeQTQZZv +DYvrCx1KqR/dDxgnM9loOWGAPpNG+GaMhJhBDGV5x+kzYZ7B4Ln1KJgWdB3URcwI +qHqnfxrclStI0vEUHsVjHKhx37o+7AOuEbXoEcxchhIIZH/t3JUW8NIxSO/lgIax +lP4Sd79u6d5a8zTvo5roqbzBCckSAhmhWoP3qPztmEAVFt18Ag0ukpP5Kg/Twui2 +YAt9kcKfcUDeEUFV/U6TLdGnVDSC28kU0sdAgRiLy395tpMLtFd5N5T5tGGHG1lL +dFisYI85EjoFmbNqQvG66vItEHt731SfZvPrhW9fto/QdPcbXDhBEaRdWzBIJZHK +InHjVXOOtUxXQtWUpNUdzXv3eMcaANql5lAR1gcFBAdOYkITwo4crvOzyCkS2vDA +lbElrVups/mdphvjG9zNmuELtUpzm9rI8P3HjZIrcRuVBnUQHM4Oqy6Cg2rAtaDd ++ZzcTDHoQDZOzU/clWo/VaA34rNHaZBamqiUiklbg42ldXL+m8jBNp1O+Sl+4KRm +zlZc/oLZFBOtlbxjnVWT8YnhBWU6X/iNNSN715NvyX7B6EJKvR8OoE3hC5k1btQJ +8iGTjmsZ9qNHbalryc/faR9fvl1UUkdo2S88C8LAbPaS5IUCAwEAATANBgkqhkiG +9w0BAQUFAAOCAgEAIVJZ031YODBlRWpK8MK42zXfJT7RCtI/z4AD+/gOYvq2EHdc +ghKFQxKchbLd3Avc9jO8vf2S7RJBgz6MYsTKwKTPZsoDZsso6w1Y9ku0Go824zUX +DFYtTJxAEPweQwFIki/omqAVZNgu34GS6WNnt9iPt8rlfjQDoPG0DGhVqiWzLOvw +aPHmdNo5sJGUUuG9nPfISMAVP0H0egG+nbsOGJRxrHDDb8UWIj4aGDBUONGi/8T0 +yLFbGFeNYU22d1WtQhvZr8N6kY2x2fCUp/mdYZ5dg/c7igZ3QJiiU7gDcs4L2BvE +K1Lq0A0bPEJi4y+zIWTbzI0Nw8I7t3TTeh34TOlHVROtnDvRYCSh0PS3XodYPaS3 +S2U27eZ96FgDK6KflPI6oJejK0VaveOFtorZxJS8cY7LwApbAvUCg2PqV1/LSigw +wUCLnkXdTz/Ba2qzjTOGQ5fOOrwEYoNN5NXvFQVs80jIio9SwP1GThGv5vtb49al +wEzP4uTuKe9a83G+I+E9oEgWAx2lVknXkANZPYhVWOfGMC0x0vtC7/i5CA9fXngR +g13UduBEP0fsXsG1LAt+MhAluvinbBJcdWeHpuMjNuLvOw2JRKf0yXB1w16OMv6l +yg9L5Dj8tT8ytqbYM5rD6kXHPgOdL75u1dWMTClBSRtJHXicgZJ4qOrIu70= +-----END CERTIFICATE----- diff --git a/cert/comp-cert b/cert/comp-cert new file mode 100755 index 0000000..c3703f5 --- /dev/null +++ b/cert/comp-cert @@ -0,0 +1,7 @@ +rm ./composer.crt +rm ./composer.csr +rm ./composer.key +openssl genrsa -out composer.key 4096 +openssl req -new -key composer.key -out composer.csr +openssl x509 -req -days 300 -in composer.csr -CA ./ca/LeadLab_root_cert_TEST.pem -CAkey ./ca/LeadLab_root_cert_TEST.key -set_serial 5342365815382548354816354178354176 -out composer.crt + diff --git a/cert/composer.crt b/cert/composer.crt new file mode 100644 index 0000000..b1ee07b --- /dev/null +++ b/cert/composer.crt @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIIFojCCA4oCDwEHZiLzpoachtLqexzMADANBgkqhkiG9w0BAQUFADCBoTELMAkG +A1UEBhMCQkMxEzARBgNVBAgTCkNhbmR5IExhbmQxETAPBgNVBAcTCFZpY3Rvcmlh +MRAwDgYDVQQKEwdMZWFkTGFiMRcwFQYDVQQLEw53d3cubGVhZGxhYi5jYTEXMBUG +A1UEAxMOUGllcnJlIEJFVUNIRVIxJjAkBgkqhkiG9w0BCQEWF2JldWNoZXIucGll +cnJlQGZha2UuY29tMB4XDTEzMDgwNjIyNTEzN1oXDTE0MDYwMjIyNTEzN1owfjEL +MAkGA1UEBhMCQ0ExCzAJBgNVBAgTAkJDMQwwCgYDVQQHEwNWaWMxEDAOBgNVBAoT +B0xlYWRMYWIxDzANBgNVBAsTBk91ckxhYjESMBAGA1UEAxMJbG9jYWxob3N0MR0w +GwYJKoZIhvcNAQkBFg5mYWtlQGdtYWlsLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAOuolt8as/EYwJx91NNgv0LC+31h2fqb9JSxmipXeVvpBRD9 +G9bfWaeycHS6VI4yLnbKovtcA5MWQsGtok/jn/MMbihdnr8Fi9qAiEx6xheBCeSW +at8tiSl7y6ekKk8HiwUwr1WylRkWRYIj4ydmcs49D4ilZ9hliPuiGEY1k1FZL/Nx +GV2qIsMPD1UNT1utI1m14X4s0S32Y+Al2U35zuXJlJzcJ0vOt219MLxSnQLcB1BL +Cr/JxrmXdSuA8Ahn5DUDo0c57eCFiojH824BOjBGbThg1GzPx2ILgC60L2wfsAke +N/uN8EVHlDM8G+H/zBy1LYxPpSSEz0hJ2kB1BklnC4ZTx+kRWMPyoGGltQHYNmx6 +9q0QpG7uIXmUy/1SVqgZGN8lXqXBm9R+7YetfLzbjhccnAOj0FmkyOtitZVo+Sw1 +hmdmjkbHLD4Y4QubwVnXsOAqq7T25UKoDQbr3lr9XxnQ6lx9bPObjp08tn3dKXUU +wFaDo0bEjmIbLqSBB77x0gj5s3b0gJ4LSLkfBa95Wy4URs8VfSQLuAIBdZ2zbNN0 +9600wOsyRps0MOT2mcsShIT2hOjwjEzc0TZ7Sub5egiqOR5pMAhUG8PSFzp+vmd0 +f80k+EsB0BIR77sDmbWDZ3SB7ufR5T2lx6bNCeY+laNubo+ZfidC6ia9riVJAgMB +AAEwDQYJKoZIhvcNAQEFBQADggIBABKxY5c9IOKfDiXwBx4ZvSeo8QNwMTyyVtBZ +PJyMql78LVhxVYOzDejRfOBWrUvkRY24QxFkpVDcnvz5ouWSiPCv6WxCiFljOuOx +dEmIMDcMWJ0AISnx3Lg7UN6utBBa2ycsp2Y4E04XU4oqCDp9ao78r5gPwzlA0Ckh +1Fs4r8HaC4HXRI/zDKS1JdNyDFHRPz28RqJrRdndLcSvWoTVrPbOZ9nGnTMSpluO +3FSIdh27m30V578oHWxbb35YVySNHe58CfYiYIhphfxJdckXn24vt6yNAvqfG8YV +0MAekg223o3Eefp0bWOHiszeWlSIsUCoXZRZK2tbG812TIiA0g3e+lGZHqSywjpP +O2Z4NEL19HkUE4VmXy6MBXLHZWwmw//5AfFedNYMJydw8+k+UHiV2skGFSJvhd7E +566wtZHbeXkhfCBnC/Kc9FpUWBSSvBEe9AxwLFCqHl4R5uxWBuWg9FAwdipnN5KN +Piv0DQS1nXFEdCyFlOx+jQlo6/zNrhVN5luxam1/AT+zXW+8otKPziVeyGdxKryH +zCbb35Q5S1u5iJXMWJwhQC6nzErwA3VbyzO5t4c/FZbaCHxa93bCOMfNBNHVhKCZ +Uv/w+FYh9bD+PBmTQiHGXYR2kvgl4vfrw98XFxDL5fFFHR1BsPD0esmWjd+0fAxu +j3xNAuir +-----END CERTIFICATE----- diff --git a/cert/composer.csr b/cert/composer.csr new file mode 100644 index 0000000..9505390 --- /dev/null +++ b/cert/composer.csr @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIEwzCCAqsCAQAwfjELMAkGA1UEBhMCQ0ExCzAJBgNVBAgTAkJDMQwwCgYDVQQH +EwNWaWMxEDAOBgNVBAoTB0xlYWRMYWIxDzANBgNVBAsTBk91ckxhYjESMBAGA1UE +AxMJbG9jYWxob3N0MR0wGwYJKoZIhvcNAQkBFg5mYWtlQGdtYWlsLmNvbTCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAOuolt8as/EYwJx91NNgv0LC+31h +2fqb9JSxmipXeVvpBRD9G9bfWaeycHS6VI4yLnbKovtcA5MWQsGtok/jn/MMbihd +nr8Fi9qAiEx6xheBCeSWat8tiSl7y6ekKk8HiwUwr1WylRkWRYIj4ydmcs49D4il +Z9hliPuiGEY1k1FZL/NxGV2qIsMPD1UNT1utI1m14X4s0S32Y+Al2U35zuXJlJzc +J0vOt219MLxSnQLcB1BLCr/JxrmXdSuA8Ahn5DUDo0c57eCFiojH824BOjBGbThg +1GzPx2ILgC60L2wfsAkeN/uN8EVHlDM8G+H/zBy1LYxPpSSEz0hJ2kB1BklnC4ZT +x+kRWMPyoGGltQHYNmx69q0QpG7uIXmUy/1SVqgZGN8lXqXBm9R+7YetfLzbjhcc +nAOj0FmkyOtitZVo+Sw1hmdmjkbHLD4Y4QubwVnXsOAqq7T25UKoDQbr3lr9XxnQ +6lx9bPObjp08tn3dKXUUwFaDo0bEjmIbLqSBB77x0gj5s3b0gJ4LSLkfBa95Wy4U +Rs8VfSQLuAIBdZ2zbNN09600wOsyRps0MOT2mcsShIT2hOjwjEzc0TZ7Sub5egiq +OR5pMAhUG8PSFzp+vmd0f80k+EsB0BIR77sDmbWDZ3SB7ufR5T2lx6bNCeY+laNu +bo+ZfidC6ia9riVJAgMBAAGgADANBgkqhkiG9w0BAQUFAAOCAgEAw0O+72Jlujw5 +jqkAOTsetu85DciQmeFca9uVXXEllJ0wFsrYiS+GQrCTGTHVzZ2uPVutUq9ZhosH +rxGarv6RZaf0A+RWv6RqCLnkQLaSPy8gieBEjrjJdkZCTQrqf6foGG98RI5KFoJp +2RLLkMN6zHaCzTLhf4Yw5YcEHBrfMf5ZWZdfYIrioKvMPVFPmua6Jfx63iW+Lw0U +g8mq8uKFzFCzsNMpiuDPSzhSpDJ99nBBSw9UvIYeM3XSymFeaqgzap58HID5N/XL +SdazEFgiliQHByNEftrt7jtEGe2hcVSwy40FKFD0oUYl0VAYCRgv7Eb0l/pedvsL +vlKpH/H1jWsx7O5bI3NGiUG+FOmNdI+i7K4/iGU1kI7ZqvcXRSsAUAVUgaXegqaf +bVtfBaW7VCWyPgAUBDC5Yu41DdEbM43ShLB+zGeuGbYpZN0mqFRKQNoxfLmqcZF8 +cRTvptwPmNKucOpzPHlz1GF9JWP8Q5n9TuYtM929524CDAVVwFfhDXHDEQe7IIyy +TyiWpOE6lf3RuwtqjAx9Xceyngug+3HjV4A++ZKi3WThrGqOVS3+I/6MpsFFTiER +u5hNVScAcIpDnXp9MqRbveY/OddTfpCx4pAYunIJLJIzb14HZjzo+CJirrxJvFAU +3RcKREA4QStOY6b9B825pOhp56aWQIQ= +-----END CERTIFICATE REQUEST----- diff --git a/cert/composer.key b/cert/composer.key new file mode 100644 index 0000000..cae4d35 --- /dev/null +++ b/cert/composer.key @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY----- diff --git a/config/initializers/ssl_config.rb b/config/initializers/ssl_config.rb new file mode 100644 index 0000000..e164377 --- /dev/null +++ b/config/initializers/ssl_config.rb @@ -0,0 +1,12 @@ +#contains constants for certificate used for SSL +SERVER_CERT_PATH_ = "cert/composer.crt" +SERVER_KEY_PATH_ = "cert/composer.key" + +CLIENT_KEY_PATH = "cert/client.key" +CLIENT_CERT_PATH = "cert/client.pem" + +SERVER_KEY = OpenSSL::PKey::RSA.new(File.open(SERVER_KEY_PATH_).read) +SERVER_CERT = OpenSSL::X509::Certificate.new(File.open(SERVER_CERT_PATH_).read) + +CLIENT_KEY = OpenSSL::PKey::RSA.new(File.open(CLIENT_KEY_PATH).read) +CLIENT_CERT = OpenSSL::X509::Certificate.new(File.open(CLIENT_CERT_PATH).read) diff --git a/lib/gateway_utils.rb b/lib/gateway_utils.rb index 3844ad7..a73b7ec 100644 --- a/lib/gateway_utils.rb +++ b/lib/gateway_utils.rb @@ -65,7 +65,8 @@ def submit(endpoint) query_url = endpoint.submit_url request = query_request(full_map(query), full_reduce(query), build_library_functions(query), query.filter, query_url) begin - Net::HTTP.start(query_url.host, query_url.port) do |http| + #use ssl + Net::HTTP.start(query_url.host, query_url.port, :use_ssl => true, :key => CLIENT_KEY, :cert => CLIENT_CERT) do |http| response = http.request(request) if response.code == '201' query_url = response['Location'] @@ -79,4 +80,4 @@ def submit(endpoint) end query_url end -end \ No newline at end of file +end diff --git a/runme.sh b/runme.sh old mode 100644 new mode 100755 diff --git a/script/rails b/script/rails index f8da2cf..0913237 100755 --- a/script/rails +++ b/script/rails @@ -1,6 +1,36 @@ #!/usr/bin/env ruby # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. +require 'rubygems' +require 'rails/commands/server' +require 'rack' +require 'webrick' +require 'webrick/https' + + +#override default option of server to use SSL +SERVER_CERT_PATH = "cert/composer.crt" +SERVER_KEY_PATH = "cert/composer.key" +CA_CERT_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" + +SERVER_KEY = File.open(SERVER_KEY_PATH) +SERVER_CERT = File.open(SERVER_CERT_PATH) + +module Rails + class Server < ::Rack::Server + def default_options + super.merge({ + :SSLEnable => true, + :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, + :SSLPrivateKey => OpenSSL::PKey::RSA.new(SERVER_KEY.read), + :SSLCertificate => OpenSSL::X509::Certificate.new(SERVER_CERT.read), + :SSLCACertificateFile => CA_CERT_PATH, + :SSLCertName => [["CN", WEBrick::Utils::getservername]], + }) + end + end +end + APP_PATH = File.expand_path('../../config/application', __FILE__) require File.expand_path('../../config/boot', __FILE__) require 'rails/commands' From 2713a62757481102c8751d4e2a458a77b5a35d5a Mon Sep 17 00:00:00 2001 From: Jeremy Ho Date: Fri, 9 Aug 2013 12:45:14 -0700 Subject: [PATCH 042/117] Add Travis CI Support Signed-off-by: Jeremy Ho --- .travis.yml | 11 +++++++++++ README.md | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..25b5b81 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,11 @@ +language: ruby +rvm: + - 1.9.3 +branches: + only: + - master +services: + - mongodb +notifications: + email: false +script: bundle exec rake test:units test:functionals test:integration diff --git a/README.md b/README.md index 1b3efab..1f11546 100755 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -hQuery +hQuery [![travis](https://secure.travis-ci.org/scoophealth/query-composer.png)](http://travis-ci.org/scoophealth/query-composer) ========= The query composer is a web based application that provides the front end for creating, managing, and executing queries. From f08e22eba69812d74010d86f40554235055076b2 Mon Sep 17 00:00:00 2001 From: Jeremy Ho Date: Thu, 15 Aug 2013 16:19:35 -0700 Subject: [PATCH 043/117] Tweak Travis Icon Signed-off-by: Jeremy Ho --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1f11546..1045a9d 100755 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -hQuery [![travis](https://secure.travis-ci.org/scoophealth/query-composer.png)](http://travis-ci.org/scoophealth/query-composer) +hQuery [![travis](https://secure.travis-ci.org/scoophealth/query-composer.png?branch=master)](http://travis-ci.org/scoophealth/query-composer) ========= The query composer is a web based application that provides the front end for creating, managing, and executing queries. From f144457edf3d6e19ce94c9dd3ed60febff12ae0f Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Fri, 23 Aug 2013 12:22:41 -0700 Subject: [PATCH 044/117] Update patientapi to version with regex support, remove deprecated :confirm warnings --- Gemfile.lock | 2 +- app/views/endpoints/_endpoint_statuses.html.erb | 2 +- app/views/library_functions/index.html.erb | 2 +- app/views/queries/index.html.erb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index fca2cdf..dd426a8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/scoophealth/patientapi.git - revision: 2afc31e48f0480ca9ce16f27939a0a1a5efd153d + revision: 35340bb11c26115bd5e350ad270cb59ac1c3f56b branch: scoop-develop specs: hquery-patient-api (1.0.0) diff --git a/app/views/endpoints/_endpoint_statuses.html.erb b/app/views/endpoints/_endpoint_statuses.html.erb index beead66..de2ed62 100755 --- a/app/views/endpoints/_endpoint_statuses.html.erb +++ b/app/views/endpoints/_endpoint_statuses.html.erb @@ -17,7 +17,7 @@ <%= link_to endpoint.name, endpoint_path(endpoint.id) %> <%= @endpoint_server_statuses[endpoint.id]['backend_status'] %> - <%= button_to '×', endpoint, :class=>"btn alert", confirm: 'Are you sure you wish to delete this endpoint?', method: :delete, title:"×" if current_user.admin? %> + <%= button_to '×', endpoint, :class=>"btn alert", :data => {:confirm => 'Are you sure you wish to delete this endpoint?'}, method: :delete, title:"×" if current_user.admin? %> <% end %> \ No newline at end of file diff --git a/app/views/library_functions/index.html.erb b/app/views/library_functions/index.html.erb index cd0cd24..5d0b9eb 100755 --- a/app/views/library_functions/index.html.erb +++ b/app/views/library_functions/index.html.erb @@ -21,7 +21,7 @@ <%= link_to library_function.name, library_function %> <%= link_to 'Edit', edit_library_function_path(library_function), :class=> "btn tbbtn" %> - <%= link_to '×', library_function, confirm: 'Are you sure?', method: :delete, :class=> "btn alert" %> + <%= link_to '×', library_function, :data => { :confirm => 'Are you sure?'}, method: :delete, :class=> "btn alert" %> <% end %> diff --git a/app/views/queries/index.html.erb b/app/views/queries/index.html.erb index 2f8eafb..c48d0fe 100755 --- a/app/views/queries/index.html.erb +++ b/app/views/queries/index.html.erb @@ -37,7 +37,7 @@ <% end %> <% end %> - <%= button_to '×', {:action=>'destroy', :id=>query.id}, :class=>"btn alert", :method=>:delete, :confirm=>'Are you sure you wish to delete the query ' + query.title %> + <%= button_to '×', {:action=>'destroy', :id=>query.id}, :class=>"btn alert", :method=>:delete, :data => {:confirm=>'Are you sure you wish to delete the query ' + query.title} %> <% end %> From 88c2bb98b2de4dd298d12428a87668a27f91b974 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Mon, 26 Aug 2013 16:23:33 -0700 Subject: [PATCH 045/117] Fix tests by chaning http to https --- test/factories/factory.rb | 4 ++-- test/fixtures/query_feed.xml | 16 ++++++++-------- test/functional/endpoints_controller_test.rb | 8 ++++---- test/functional/queries_controller_test.rb | 10 +++++----- test/integration/user_access_test.rb | 6 +++--- test/unit/endpoint_cron_test.rb | 4 ++-- test/unit/endpoint_test.rb | 10 +++++----- test/unit/execution_test.rb | 10 +++++----- test/unit/result_test.rb | 18 +++++++++--------- 9 files changed, 43 insertions(+), 43 deletions(-) diff --git a/test/factories/factory.rb b/test/factories/factory.rb index db273ad..325e850 100755 --- a/test/factories/factory.rb +++ b/test/factories/factory.rb @@ -190,7 +190,7 @@ FactoryGirl.define do factory :endpoint do |e| e.sequence(:name) {|n| "Endpoint#{n}"} - e.base_url 'http://127.0.0.1:3001' + e.base_url 'https://127.0.0.1:3001' end end @@ -272,7 +272,7 @@ r.value nil r.result_url nil r.status Result::QUEUED - r.query_url 'http://localhost:3000/queries/4e4c08b5431a5f5dc1000001' + r.query_url 'https://localhost:3000/queries/4e4c08b5431a5f5dc1000001' r.created_at Time.new(2011, 1, 1) r.updated_at Time.new(2011, 1, 1) end diff --git a/test/fixtures/query_feed.xml b/test/fixtures/query_feed.xml index a0daa99..72b5adf 100644 --- a/test/fixtures/query_feed.xml +++ b/test/fixtures/query_feed.xml @@ -1,17 +1,17 @@ Distributed Queries - + 2011-08-17T14:30:19-04:00 hQuery Gateway - http://localhost:3000/queries + https://localhost:3000/queries Query Result - http://localhost:3000/queries/4e4c08b5431a5f5dc1000001 + https://localhost:3000/queries/4e4c08b5431a5f5dc1000001 Query Result 2011-08-17T14:30:13-04:00 @@ -21,15 +21,15 @@ - - http://localhost:3000/queries/4e4c08b5431a5f5dc1000001 + + https://localhost:3000/queries/4e4c08b5431a5f5dc1000001 2011-08-17T14:30:19-04:00 Query Result - http://localhost:3000/queries/4e4c0738431a5f5d14000001 + https://localhost:3000/queries/4e4c0738431a5f5d14000001 Query Result 2011-08-17T14:23:52-04:00 @@ -39,8 +39,8 @@ - - http://localhost:3000/queries/4e4c0738431a5f5d14000001 + + https://localhost:3000/queries/4e4c0738431a5f5d14000001 2011-08-17T14:23:55-04:00 \ No newline at end of file diff --git a/test/functional/endpoints_controller_test.rb b/test/functional/endpoints_controller_test.rb index 5d4415a..99ac1cf 100755 --- a/test/functional/endpoints_controller_test.rb +++ b/test/functional/endpoints_controller_test.rb @@ -94,16 +94,16 @@ class EndpointsControllerTest < ActionController::TestCase end test "should refresh endpoint statuses" do - FakeWeb.register_uri(:get, "http://127.0.0.1:3001/queries", :body => + FakeWeb.register_uri(:get, "https://127.0.0.1:3001/queries", :body => %{ Distributed Queries - + 2011-12-15T16:02:13-05:00 hQuery Gateway - http://localhost:3001/queries + https://localhost:3001/queries }) get :refresh_endpoint_statuses @@ -114,7 +114,7 @@ class EndpointsControllerTest < ActionController::TestCase test "should gracefully refresh downed endpoint status" do Endpoint.all.each do |endpoint| - endpoint.base_url = "http://something.totally.invalid:9999" + endpoint.base_url = "https://something.totally.invalid:9999" endpoint.save! end get :refresh_endpoint_statuses diff --git a/test/functional/queries_controller_test.rb b/test/functional/queries_controller_test.rb index 0aa541d..113d944 100755 --- a/test/functional/queries_controller_test.rb +++ b/test/functional/queries_controller_test.rb @@ -15,7 +15,7 @@ class QueriesControllerTest < ActionController::TestCase @endpoints_for_execution = [] @endpoints_for_execution << FactoryGirl.create(:endpoint) - @endpoints_for_execution << FactoryGirl.create(:endpoint, base_url: 'http://127.0.0.1:3002') + @endpoints_for_execution << FactoryGirl.create(:endpoint, base_url: 'https://127.0.0.1:3002') @unattached_query = FactoryGirl.create(:query) @@ -131,7 +131,7 @@ class QueriesControllerTest < ActionController::TestCase test "should execute query with notification" do sign_in @user - FakeWeb.register_uri(:post, "http://127.0.0.1:3001/queries", :body => "FORCE ERROR") + FakeWeb.register_uri(:post, "https://127.0.0.1:3001/queries", :body => "FORCE ERROR") query_from_db = Query.find(@ids[2]) endpoint_ids = [@endpoints_for_execution[0].id.to_s] @@ -161,7 +161,7 @@ class QueriesControllerTest < ActionController::TestCase test "should execute query without notification" do sign_in @user - FakeWeb.register_uri(:post, "http://127.0.0.1:3001/queries", :body => "FORCE ERROR") + FakeWeb.register_uri(:post, "https://127.0.0.1:3001/queries", :body => "FORCE ERROR") query_from_db = Query.find(@ids[2]) endpoint_ids = [@endpoints_for_execution[0].id.to_s] @@ -249,7 +249,7 @@ class QueriesControllerTest < ActionController::TestCase test "should cancel endpoint results" do sign_in @user - FakeWeb.register_uri(:post, "http://127.0.0.1:3001/queries", :body => "{}", :status => ["304"], :location=>"http://localhost:3001/queries") + FakeWeb.register_uri(:post, "https://127.0.0.1:3001/queries", :body => "{}", :status => ["304"], :location=>"https://localhost:3001/queries") query_from_db = Query.find(@ids[2]) endpoint_ids = [@endpoints_for_execution[0].id.to_s] @@ -275,7 +275,7 @@ class QueriesControllerTest < ActionController::TestCase test "should cancel execution" do sign_in @user - FakeWeb.register_uri(:post, "http://127.0.0.1:3001/queries", :body => "{}", :status => ["304"], :location=>"http://localhost:3001/queries") + FakeWeb.register_uri(:post, "https://127.0.0.1:3001/queries", :body => "{}", :status => ["304"], :location=>"https://localhost:3001/queries") query_from_db = Query.find(@ids[2]) endpoint_ids = [@endpoints_for_execution[0].id.to_s] diff --git a/test/integration/user_access_test.rb b/test/integration/user_access_test.rb index 8abf4ed..2a5e208 100755 --- a/test/integration/user_access_test.rb +++ b/test/integration/user_access_test.rb @@ -86,7 +86,7 @@ class UserAccessTest < ActionDispatch::IntegrationTest test "users should not be able to edit endpoints" do login @user - put "/endpoints/#{@new_endpoint.id}", 'endpoint[name]' => 'new name', 'endpoint[base_url]' => 'http://example.com/' + put "/endpoints/#{@new_endpoint.id}", 'endpoint[name]' => 'new name', 'endpoint[base_url]' => 'https://example.com/' assert_response :redirect endpoint_updated = Endpoint.find(@new_endpoint.id); assert_equal @new_endpoint.id, endpoint_updated.id @@ -96,12 +96,12 @@ class UserAccessTest < ActionDispatch::IntegrationTest test "admin should be able to edit endpoints" do login @admin - put "/endpoints/#{@new_endpoint.id}", 'endpoint[name]' => 'new name', 'endpoint[base_url]' => 'http://example.com/' + put "/endpoints/#{@new_endpoint.id}", 'endpoint[name]' => 'new name', 'endpoint[base_url]' => 'https://example.com/' assert_response :redirect endpoint_updated = Endpoint.find(@new_endpoint.id) assert_equal @new_endpoint.id, endpoint_updated.id assert_equal 'new name', endpoint_updated.name - assert_equal 'http://example.com/queries', endpoint_updated.submit_url.to_s + assert_equal 'https://example.com/queries', endpoint_updated.submit_url.to_s end def login(user) diff --git a/test/unit/endpoint_cron_test.rb b/test/unit/endpoint_cron_test.rb index 91b1d5c..99add53 100644 --- a/test/unit/endpoint_cron_test.rb +++ b/test/unit/endpoint_cron_test.rb @@ -17,9 +17,9 @@ class EndpointCronTest < ActiveSupport::TestCase job = Delayed::Job.enqueue payload_object: cronJob, run_at: 2.from_now - FakeWeb.register_uri(:get, "http://127.0.0.1:3001/queries", + FakeWeb.register_uri(:get, "https://127.0.0.1:3001/queries", :body => File.read(File.expand_path('../../fixtures/query_feed.xml', __FILE__))) - FakeWeb.register_uri(:get, "http://localhost:3000/queries/4e4c08b5431a5f5dc1000001", + FakeWeb.register_uri(:get, "https://localhost:3000/queries/4e4c08b5431a5f5dc1000001", :body => '{"status": "queued"}') endpoint = FactoryGirl.create(:endpoint) result = FactoryGirl.create(:result_waiting, endpoint: endpoint) diff --git a/test/unit/endpoint_test.rb b/test/unit/endpoint_test.rb index ec65d5e..e9e0546 100755 --- a/test/unit/endpoint_test.rb +++ b/test/unit/endpoint_test.rb @@ -6,7 +6,7 @@ class EndpointTest < ActiveSupport::TestCase end test "monitoring queries that have not been modified" do - FakeWeb.register_uri(:get, "http://127.0.0.1:3001/queries", + FakeWeb.register_uri(:get, "https://127.0.0.1:3001/queries", :status => [304, "Not Modified"]) endpoint = FactoryGirl.create(:endpoint) @@ -21,9 +21,9 @@ class EndpointTest < ActiveSupport::TestCase end test "monitoring queries that have changed" do - FakeWeb.register_uri(:get, "http://127.0.0.1:3001/queries", + FakeWeb.register_uri(:get, "https://127.0.0.1:3001/queries", :body => File.read(File.expand_path('../../fixtures/query_feed.xml', __FILE__))) - FakeWeb.register_uri(:get, "http://localhost:3000/queries/4e4c08b5431a5f5dc1000001", + FakeWeb.register_uri(:get, "https://localhost:3000/queries/4e4c08b5431a5f5dc1000001", :body => '{"status": "queued"}') endpoint = FactoryGirl.create(:endpoint) result = FactoryGirl.create(:result_waiting, endpoint: endpoint) @@ -41,7 +41,7 @@ class EndpointTest < ActiveSupport::TestCase end test "monitoring queries with incomprehensible responses" do - FakeWeb.register_uri(:get, "http://127.0.0.1:3001/queries", :body => 'bacon is delicious') + FakeWeb.register_uri(:get, "https://127.0.0.1:3001/queries", :body => 'bacon is delicious') endpoint = FactoryGirl.create(:endpoint) endpoint.check assert_equal 2, endpoint.endpoint_logs.count @@ -59,7 +59,7 @@ class EndpointTest < ActiveSupport::TestCase end test "should gracefully handle errors in check" do - FakeWeb.register_uri(:get, "http://127.0.0.1:3001/queries", :exception => Net::HTTPError) + FakeWeb.register_uri(:get, "https://127.0.0.1:3001/queries", :exception => Net::HTTPError) endpoint = FactoryGirl.create(:endpoint) endpoint.check assert_equal 1, endpoint.endpoint_logs.count diff --git a/test/unit/execution_test.rb b/test/unit/execution_test.rb index dec294b..0715af5 100644 --- a/test/unit/execution_test.rb +++ b/test/unit/execution_test.rb @@ -44,9 +44,9 @@ class ExecutionTest < ActiveSupport::TestCase end test "query submission" do - FakeWeb.register_uri(:post, "http://127.0.0.1:3001/queries", :body => "Query Created", - :status => [201, "Created"], :location => "http://127.0.0.1:3001/query/1234") - FakeWeb.register_uri(:post, "http://127.0.0.1:3001/library_functions", :body => "yay", + FakeWeb.register_uri(:post, "https://127.0.0.1:3001/queries", :body => "Query Created", + :status => [201, "Created"], :location => "https://127.0.0.1:3001/query/1234") + FakeWeb.register_uri(:post, "https://127.0.0.1:3001/library_functions", :body => "yay", :status => [200, "OK"]) user = FactoryGirl.create(:user) @@ -70,7 +70,7 @@ class ExecutionTest < ActiveSupport::TestCase result = query.last_execution.results[0] assert result - assert_equal "http://127.0.0.1:3001/query/1234", result.query_url + assert_equal "https://127.0.0.1:3001/query/1234", result.query_url assert_equal Result::QUEUED, result.status end @@ -80,7 +80,7 @@ class ExecutionTest < ActiveSupport::TestCase test "query should log failures for endpoint on failure" do - FakeWeb.register_uri(:post, "http://127.0.0.1:3001/queries", :status => ["500", "Internal Server Error"]) + FakeWeb.register_uri(:post, "https://127.0.0.1:3001/queries", :status => ["500", "Internal Server Error"]) query = Query.find(@user_with_functions.queries[3].id) endpoint = FactoryGirl.create(:endpoint) diff --git a/test/unit/result_test.rb b/test/unit/result_test.rb index 2f8673a..08eec3a 100644 --- a/test/unit/result_test.rb +++ b/test/unit/result_test.rb @@ -6,9 +6,9 @@ class ResultTest < ActiveSupport::TestCase end test "check a result that has changed" do - FakeWeb.register_uri(:get, "http://localhost:3000/queries/4e4c08b5431a5f5dc1000001", - :body => '{"status": "'+Result::COMPLETE+'", "result_url": "http://localhost/results/1234"}') - FakeWeb.register_uri(:get, "http://localhost/results/1234", + FakeWeb.register_uri(:get, "https://localhost:3000/queries/4e4c08b5431a5f5dc1000001", + :body => '{"status": "'+Result::COMPLETE+'", "result_url": "https://localhost/results/1234"}') + FakeWeb.register_uri(:get, "https://localhost/results/1234", :body => '{"foo": "bar"}') result = FactoryGirl.create(:result_waiting) @@ -21,18 +21,18 @@ class ResultTest < ActiveSupport::TestCase end test "fetch a result" do - FakeWeb.register_uri(:get, "http://localhost/results/1234", + FakeWeb.register_uri(:get, "https://localhost/results/1234", :body => '{"foo": "bar"}') - result = FactoryGirl.create(:result, :result_url => "http://localhost/results/1234") + result = FactoryGirl.create(:result, :result_url => "https://localhost/results/1234") result.fetch_result assert_equal Result::COMPLETE, result.status assert_equal 'bar', result.value['foo'] end test "checking a result" do - FakeWeb.register_uri(:get, "http://localhost:3000/queries/4e4c08b5431a5f5dc1000001", - :body => '{"status": "complete", "result_url": "http://localhost/results/1234"}') - FakeWeb.register_uri(:get, "http://localhost/results/1234", + FakeWeb.register_uri(:get, "https://localhost:3000/queries/4e4c08b5431a5f5dc1000001", + :body => '{"status": "complete", "result_url": "https://localhost/results/1234"}') + FakeWeb.register_uri(:get, "https://localhost/results/1234", :body => '{"foo": "bar", "status": "complete"}') result = FactoryGirl.create(:result_waiting) result.check @@ -41,7 +41,7 @@ class ResultTest < ActiveSupport::TestCase end test "checking a result where there is an error" do - FakeWeb.register_uri(:get, "http://localhost:3000/queries/4e4c08b5431a5f5dc1000001", + FakeWeb.register_uri(:get, "https://localhost:3000/queries/4e4c08b5431a5f5dc1000001", :body => '{"status": "failed", "error_message": "game over, man!"}') result = FactoryGirl.create(:result_waiting) result.check From f0e076463367cb8b03cdeb40091d29a2f042dccc Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Tue, 27 Aug 2013 09:31:45 -0700 Subject: [PATCH 046/117] Updated documentation for ssl --- README.md | 4 ++-- runme.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1045a9d..fe7bfc1 100755 --- a/README.md +++ b/README.md @@ -237,7 +237,7 @@ run: bundle exec script/delayed_job start sbundle exec rails server -p 3001 -In a browser open the URL: http://localhost:3000/queries/ +In a browser open the URL: https://localhost:3000/queries/ ###7w. WINDOWS - Starting the Application @@ -273,7 +273,7 @@ Finish starting the application by running the following: Run the following in a different terminal: bundle exec rails server -p 3001 - In a browser open the URL: http://localhost:3000/queries/ + In a browser open the URL: https://localhost:3000/queries/ ###8. Adding a User Account diff --git a/runme.sh b/runme.sh index 2c87b29..101ffb0 100755 --- a/runme.sh +++ b/runme.sh @@ -13,7 +13,7 @@ bundle exec rails server -p 3002 # bundle exec script/delayed_job start # bundle exec rails server -p 3001 # -#In a browser open the URL: http://localhost:3000/queries/ +#In a browser open the URL: https://localhost:3000/queries/ # # Adding a User Account (one time operation) # From db668d69983e5bfe2b05f17ae1ba4213b0a6dd15 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Tue, 27 Aug 2013 14:44:45 -0700 Subject: [PATCH 047/117] Reconstruct missing openssl root certificates --- cert/README.cert | 16 +++++ cert/ca | 1 - cert/ca/LeadLab_root_cert_TEST.crt | 36 +++++++++++ cert/ca/LeadLab_root_cert_TEST.pem | 51 ++++++++++++++++ cert/client.crt | 35 +++++++++++ cert/client.csr | 29 +++++++++ cert/client.key | 98 +++++++++++++++--------------- cert/client.pem | 32 ---------- cert/composer.crt | 64 +++++++++---------- cert/composer.csr | 53 ++++++++-------- cert/composer.key | 98 +++++++++++++++--------------- cert/{ => old}/comp-cert | 0 config/initializers/ssl_config.rb | 4 +- 13 files changed, 327 insertions(+), 190 deletions(-) create mode 100644 cert/README.cert delete mode 120000 cert/ca create mode 100644 cert/ca/LeadLab_root_cert_TEST.crt create mode 100644 cert/ca/LeadLab_root_cert_TEST.pem create mode 100644 cert/client.crt create mode 100644 cert/client.csr delete mode 100644 cert/client.pem rename cert/{ => old}/comp-cert (100%) diff --git a/cert/README.cert b/cert/README.cert new file mode 100644 index 0000000..315971b --- /dev/null +++ b/cert/README.cert @@ -0,0 +1,16 @@ +mkdir ca +# Generate 4096-bit long RSA key for our root CA +openssl genrsa -out ca/LeadLab_root_cert_TEST.pem 4096 +# Create a self-signed root CA certificate +openssl req -new -x509 -days 1826 -key ca/LeadLab_root_cert_TEST.pem -out ca/LeadLab_root_cert_TEST.crt +# Create a subordinate CA used for actual signing +openssl genrsa -out composer.key 4096 +# Request a certificate for this subordinate CA +openssl req -new -key composer.key -out composer.csr +# Process request for the subordinate CA and get it signed by the root CA +openssl x509 -req -days 730 -in composer.csr -CA ca/LeadLab_root_cert_TEST.crt -CAkey ca/LeadLab_root_cert_TEST.pem -set_serial 5342365815382548354816354178354176 -out composer.crt +# Make client credentials +openssl genrsa -out client.key 4096 +openssl req -new -key client.key -out client.csr +openssl x509 -req -days 730 -in client.csr -CA ca/LeadLab_root_cert_TEST.crt -CAkey ca/LeadLab_root_cert_TEST.pem -set_serial 5342365815382548354816354178354177 -out client.crt + diff --git a/cert/ca b/cert/ca deleted file mode 120000 index 9f5e199..0000000 --- a/cert/ca +++ /dev/null @@ -1 +0,0 @@ -/home/pierre/scoop/ca \ No newline at end of file diff --git a/cert/ca/LeadLab_root_cert_TEST.crt b/cert/ca/LeadLab_root_cert_TEST.crt new file mode 100644 index 0000000..6c84d40 --- /dev/null +++ b/cert/ca/LeadLab_root_cert_TEST.crt @@ -0,0 +1,36 @@ +-----BEGIN CERTIFICATE----- +MIIGTzCCBDegAwIBAgIJALD43pKdRjenMA0GCSqGSIb3DQEBBQUAMIG9MQswCQYD +VQQGEwJDQTEZMBcGA1UECAwQQnJpdGlzaCBDb2x1bWJpYTERMA8GA1UEBwwIVmlj +dG9yaWExHzAdBgNVBAoMFlVuaXZlcnNpdHkgb2YgVmljdG9yaWExHzAdBgNVBAsM +FklzbGFuZCBNZWRpY2FsIFByb2dyYW0xETAPBgNVBAMMCExlYWQgTGFiMSswKQYJ +KoZIhvcNAQkBFhxzY29vcGhlYWx0aEBnb29nbGVncm91cHMuY29tMB4XDTEzMDgy +NzIxMTYyMloXDTE4MDgyNzIxMTYyMlowgb0xCzAJBgNVBAYTAkNBMRkwFwYDVQQI +DBBCcml0aXNoIENvbHVtYmlhMREwDwYDVQQHDAhWaWN0b3JpYTEfMB0GA1UECgwW +VW5pdmVyc2l0eSBvZiBWaWN0b3JpYTEfMB0GA1UECwwWSXNsYW5kIE1lZGljYWwg +UHJvZ3JhbTERMA8GA1UEAwwITGVhZCBMYWIxKzApBgkqhkiG9w0BCQEWHHNjb29w +aGVhbHRoQGdvb2dsZWdyb3Vwcy5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDlYCSmdrKnENfM7VmMwYSDC72ymYRoZesnNwS5d2bIMVrUsXKcvqjg +tEJGvStkfD8LXJLD4WPIr7EQ8COTO38xgbJ2S/KiZ7wJNTW27/kYJQ6MPw1cevzH +2JJplofqzK0mxtEcOENSDG7Mz0cnWeIlPYS5LSzgA+Nieo6QHVU5EPa33/S0U2E2 +nNXGdZysoNKkIGNfbf3h1FTJ0pEnd5V+/tWci8WztRr6dLbtEsTuDamHCDe2AWzV +Pm/aIXXTZWA/piT7MoZCNcH3MaGHzg1E/8S+IebAgQNknDTQe8PyLISzR1OJfQK6 +kyg+gBxQJSSLVev3rhiY8Te+XX1BlbEj+GQFtdtKv+/dRns6uylqyEBFeRAHn3Of +L7YnHxa5QqIEjxFQMNJ9JnaZ7KgNLRFS6p4AQvxPYyjKw5MBhXWIb7OWrTGSYTuA +Oxpo06/02RzxaW5urxdqxmzGJyqDDLnoYpTENc1Mw4Vchs3IJBvGu+RPPAVPqtOR +lcK8O9whfV59nBnmbCtKD1PhJW7AD5mpVsjIlbkD9GbtC/meTBQ2eHE9iCa8RyF8 +MwD2cPL1edp4Jop1XryQgHkAS5xLS3K0iAQcYBZl4YDUWCNz9o5Ww794CnWBch4D +QzMxxk8tI4qU38G6UmNgZwbhAXgiQe4G6Jw2Q65TQ8XjMWLuDyzS5QIDAQABo1Aw +TjAdBgNVHQ4EFgQUYJ7eqIHmeRBMCHuwmZ3DXB6W8YwwHwYDVR0jBBgwFoAUYJ7e +qIHmeRBMCHuwmZ3DXB6W8YwwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOC +AgEAhe2Fr0mbj97lwoA78/sunCKQtDyTyTz4y5MVCQyyEvZ9Ux4EsjYbsBKNoWdD +JXGERqvx7M2sY9UsevklhG7GyvoNckGmyGbUxzD9H3qZ2gK+6iroBSvXqJK/THfp +vscmvWNjAWnvTTFnQY1Q1nZRLUjLpLOIR0pLn/2NCdFYrNrCg6SSIHehLgepAgW8 +7NdJapca16V7h8lppg9LlqVIlzfXYcl8LbUrYtUtUMTZEyolfGCpSMmXGU3Jxhou +yl3ImSTAoIUWzz3LO1IANGmG9B1FQuSTXdGrxbgFtKld0rdJB4opEqYhLqIRRUqz +mjrp1d+NjY9PE+AOC/YSMowzLTVWMuaVRc3WxijJgj8cvOv/0fRezGrZFSJSowZu +p+gs3rA4/F6XBPU+a6fTF0BQwnuVW+B7EdZK/zZgMz2in9TlWaXES1A5sgyf0HvA +R3E7afcrXtWGge6MC14fjpQ4hdMuODLT0rhx/p5aRm1RLHbQKkd9mK3j8dr/TbXR +pnUR4Yr0khe+XHECHQqGnyk3zMOC+a6gpOeFKQpd1BlXoo+q4N5owv9dHRHqI6Ns +AINmoMC27Pnt3c3xbttKEbEfDDV+tgi1Fy6JGV0G8MuswFYW4/yTwZ2s+HEBKPrh +cEEmarBzqv0g76LJvi4YE9ZjuI8g5NASPHWQaNsIYjx9uKI= +-----END CERTIFICATE----- diff --git a/cert/ca/LeadLab_root_cert_TEST.pem b/cert/ca/LeadLab_root_cert_TEST.pem new file mode 100644 index 0000000..4b30b30 --- /dev/null +++ b/cert/ca/LeadLab_root_cert_TEST.pem @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY----- diff --git a/cert/client.crt b/cert/client.crt new file mode 100644 index 0000000..d981924 --- /dev/null +++ b/cert/client.crt @@ -0,0 +1,35 @@ +-----BEGIN CERTIFICATE----- +MIIF/jCCA+YCDwEHZiLzpoachtLqexzMATANBgkqhkiG9w0BAQUFADCBvTELMAkG +A1UEBhMCQ0ExGTAXBgNVBAgMEEJyaXRpc2ggQ29sdW1iaWExETAPBgNVBAcMCFZp +Y3RvcmlhMR8wHQYDVQQKDBZVbml2ZXJzaXR5IG9mIFZpY3RvcmlhMR8wHQYDVQQL +DBZJc2xhbmQgTWVkaWNhbCBQcm9ncmFtMREwDwYDVQQDDAhMZWFkIExhYjErMCkG +CSqGSIb3DQEJARYcc2Nvb3BoZWFsdGhAZ29vZ2xlZ3JvdXBzLmNvbTAeFw0xMzA4 +MjcyMTM4MTRaFw0xNTA4MjcyMTM4MTRaMIG9MQswCQYDVQQGEwJDQTEZMBcGA1UE +CAwQQnJpdGlzaCBDb2x1bWJpYTERMA8GA1UEBwwIVmljdG9yaWExHzAdBgNVBAoM +FlVuaXZlcnNpdHkgb2YgVmljdG9yaWExHzAdBgNVBAsMFklzbGFuZCBNZWRpY2Fs +IFByb2dyYW0xETAPBgNVBAMMCExlYWQgTGFiMSswKQYJKoZIhvcNAQkBFhxzY29v +cGhlYWx0aEBnb29nbGVncm91cHMuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEAvj523FtDd+M/ChEN1njkbn4jdq7klyzdCCNZfxSFOtA4ol4Ea6Me +PBK29tljDJfCrC2bR8pILntMW/5zDk6ry5Db3qDvFFHUrf/7k8A3K3PHF9C632l3 +Esq+aNBfLunOr9jJsZ53SPB6dIh+laV9jluAYiW9A3t9UJuVcZszz+nt4Uq7Lq9Y +/TvnnMgdhAAu/OIFqKL167GWt2ajWY+wkCUapARAUgpLac+ZnwGu6Nx6s/ITILP6 +jDOe4RIURZNJPulnntT+MDF239EBePZF5V5qRGVX19fyrmKp37mxlSEyabIcPner +M87fMlRz6prEOzrY21vY2nXLTsNzeU45DR+9JsVmiajrQSU9dYJbiI59xMm0Z1Fa +xsnN386YBcmSS69uXs71X0QMU3xMl2tL6blfj7lQs0jWG3PlrCLPN79rBkn9jcZv +L4RraGh+yOWtWXgvNSGzGxHlesWuZ0FUPSjViITzELhCp/RiE4nTujiGTzNqbZpX +M5V6LogZvY/kTY8Kj+c9pE+zPJ9ZWrXEDPzQrSkroYKsUCwT3dARDuVAdRjZaZEa +FD0K47puYOwQXpQBp5DqUihVCrKWBW5lG5L41NBaQiEGXrOEBPmJn1ErfvjU0SZa +UjxjWV6hkTsZiupchovpDUPqh7qbZy0YwJXJqDyYFpWR4JIB+53MnWcCAwEAATAN +BgkqhkiG9w0BAQUFAAOCAgEAuzhecjcdSEiAW43vzcb5U8yAdx/6n6Q5QRVVFztJ +GF48bfijGH3AN5R0yWn+Xrg/ktxg+OvJJjkN4xRNXtvNb61to8MxiIW9vcrjZyyC +IqzwDKptgSZMtFyK3a54nw5DNCXo26kBZ3tY2ohKdeTLnDpyZqZ4OFYltfCSOZH6 +IaDyAOIMiHE0hZLNgB+JTY2BJhIe1ZpWYaF7BrVxH/flhe+nSMe5SXA/X6ZR9+p8 +vBVn+dhaYTm55rmrVaBrrAbwcNYAdkAhhqATQoCnWYQj+UnY/qfRJCg/OSWkcJkw +FTN96jlKE4P/UO6Lkrz6tcXu5XiQz9ybFWy5cmcJ9lwL9SaRZ6e092zu5v5SPSZ9 +QztGRYT+KGInAIDSz3ynwvnfXOkHZoTXNfDHYbzow7gAguDwS7Qb/03ID9QyDDOc +Hd9l+kUUWe6Ysplqq3OY01/C443pacwdQSp5ZGi0yBt6um1UY1r+N7QEbSWE5ygO +DKrJMtWqYrelrejEycUSnNphAtQkD5psgPj8DwbC7kG2f8s2XQPRuNMweUoPCi50 +gg1MxR+OYoJHwqKdc8cGGQBEAcutZbcR/bgGjGowtNBoQLwVUMtBIf6kHrNn89Tc +qlBGpoAt/TYYFTSkWWN3D3EMDZ15yGw9oRPCotB/8bcCXr7fWnuMUnmxLvBDViTW +umM= +-----END CERTIFICATE----- diff --git a/cert/client.csr b/cert/client.csr new file mode 100644 index 0000000..55ba266 --- /dev/null +++ b/cert/client.csr @@ -0,0 +1,29 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIFAzCCAusCAQAwgb0xCzAJBgNVBAYTAkNBMRkwFwYDVQQIDBBCcml0aXNoIENv +bHVtYmlhMREwDwYDVQQHDAhWaWN0b3JpYTEfMB0GA1UECgwWVW5pdmVyc2l0eSBv +ZiBWaWN0b3JpYTEfMB0GA1UECwwWSXNsYW5kIE1lZGljYWwgUHJvZ3JhbTERMA8G +A1UEAwwITGVhZCBMYWIxKzApBgkqhkiG9w0BCQEWHHNjb29waGVhbHRoQGdvb2ds +ZWdyb3Vwcy5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC+Pnbc +W0N34z8KEQ3WeORufiN2ruSXLN0II1l/FIU60DiiXgRrox48Erb22WMMl8KsLZtH +ykgue0xb/nMOTqvLkNveoO8UUdSt//uTwDcrc8cX0LrfaXcSyr5o0F8u6c6v2Mmx +nndI8Hp0iH6VpX2OW4BiJb0De31Qm5VxmzPP6e3hSrsur1j9O+ecyB2EAC784gWo +ovXrsZa3ZqNZj7CQJRqkBEBSCktpz5mfAa7o3Hqz8hMgs/qMM57hEhRFk0k+6Wee +1P4wMXbf0QF49kXlXmpEZVfX1/KuYqnfubGVITJpshw+d6szzt8yVHPqmsQ7Otjb +W9jadctOw3N5TjkNH70mxWaJqOtBJT11gluIjn3EybRnUVrGyc3fzpgFyZJLr25e +zvVfRAxTfEyXa0vpuV+PuVCzSNYbc+WsIs83v2sGSf2Nxm8vhGtoaH7I5a1ZeC81 +IbMbEeV6xa5nQVQ9KNWIhPMQuEKn9GITidO6OIZPM2ptmlczlXouiBm9j+RNjwqP +5z2kT7M8n1latcQM/NCtKSuhgqxQLBPd0BEO5UB1GNlpkRoUPQrjum5g7BBelAGn +kOpSKFUKspYFbmUbkvjU0FpCIQZes4QE+YmfUSt++NTRJlpSPGNZXqGROxmK6lyG +i+kNQ+qHuptnLRjAlcmoPJgWlZHgkgH7ncydZwIDAQABoAAwDQYJKoZIhvcNAQEF +BQADggIBACntvUSwDYZj/L/IOwgbaDCj7hdqiwL3NyBx2uK/5so+OnQSn0qe08Uz +ld6MaKHt/ry4d2QtLztBIk2jO7g3Y61jIFdZpifFTKDDXwXCaEy+Brq9U02gzFpF +J2pseNoZ4M5Y61wBIitES+yE8yeauwtk4kTdASBwoBHCVW/+hTv2B82YzlfmbKP8 +liEjtuc5sAoKJLK2VGY/gY237IfoixwSftRPz5fbIFHzD3XSLnH/+hW7hpKjBfQG +fqwJd1cUHqEmrp21b3yrxT7pyBU+5xyBFjSZ1SYyVx4/syqRw4pP7y+oXZrG1aJ0 +BIQ9NXJ5bAoskYC6XqeJ2UrK4BfhFwP3jJf+pf/QUnY7PvLcaAGeLd212CroHB8s +fOO+QRFUxSAD+cXQOhNky+VY6OwUchTkCN13wOfwYy2CuHPyjZMT4eTGgH1Lr8yT +9Fb9r1ElZkC4N2B+6uXP+qasiDI2/LjK6/JY0sE6SdRAM7+kQzDMhHU0128qlxfI +clsQ2RAUCAnPA2mo5J8g6ztOdz1XdcAbugeLzjg96L+GBANvrTxHyQyiMkfiJiuT +uwjgFZGLd5NRYrHt35nsB4PQJWZ7EAj7SVqOeKng/ZWnVjEl/5pvrIYd93FA8ew4 +d8r9XVJxQS9RZ6KhqCb8EWe/KiB29II89MpAtfpFXJLVXog03FZU +-----END CERTIFICATE REQUEST----- diff --git a/cert/client.key b/cert/client.key index 4943fd5..097f060 100644 --- a/cert/client.key +++ b/cert/client.key @@ -1,51 +1,51 @@ -----BEGIN RSA PRIVATE KEY----- -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 -----END RSA PRIVATE KEY----- diff --git a/cert/client.pem b/cert/client.pem deleted file mode 100644 index d192587..0000000 --- a/cert/client.pem +++ /dev/null @@ -1,32 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFmDCCA4ACBQOqfacEMA0GCSqGSIb3DQEBBQUAMIGhMQswCQYDVQQGEwJCQzET -MBEGA1UECBMKQ2FuZHkgTGFuZDERMA8GA1UEBxMIVmljdG9yaWExEDAOBgNVBAoT -B0xlYWRMYWIxFzAVBgNVBAsTDnd3dy5sZWFkbGFiLmNhMRcwFQYDVQQDEw5QaWVy -cmUgQkVVQ0hFUjEmMCQGCSqGSIb3DQEJARYXYmV1Y2hlci5waWVycmVAZmFrZS5j -b20wHhcNMTMwODA3MTc1ODAyWhcNMTQwNjAzMTc1ODAyWjB+MQswCQYDVQQGEwJD -QTELMAkGA1UECBMCQkMxDDAKBgNVBAcTA1ZpYzEQMA4GA1UEChMHTGVhZExhYjEP -MA0GA1UECxMGT3VyTGFiMRIwEAYDVQQDEwlsb2NhbGhvc3QxHTAbBgkqhkiG9w0B -CQEWDmZha2VAZ21haWwuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC -AgEAn3iD8UdYUidwmVUeqD3Y6yWBcLODaIohlgUWux+18oDygxAb24MBkeQTQZZv -DYvrCx1KqR/dDxgnM9loOWGAPpNG+GaMhJhBDGV5x+kzYZ7B4Ln1KJgWdB3URcwI -qHqnfxrclStI0vEUHsVjHKhx37o+7AOuEbXoEcxchhIIZH/t3JUW8NIxSO/lgIax -lP4Sd79u6d5a8zTvo5roqbzBCckSAhmhWoP3qPztmEAVFt18Ag0ukpP5Kg/Twui2 -YAt9kcKfcUDeEUFV/U6TLdGnVDSC28kU0sdAgRiLy395tpMLtFd5N5T5tGGHG1lL -dFisYI85EjoFmbNqQvG66vItEHt731SfZvPrhW9fto/QdPcbXDhBEaRdWzBIJZHK -InHjVXOOtUxXQtWUpNUdzXv3eMcaANql5lAR1gcFBAdOYkITwo4crvOzyCkS2vDA -lbElrVups/mdphvjG9zNmuELtUpzm9rI8P3HjZIrcRuVBnUQHM4Oqy6Cg2rAtaDd -+ZzcTDHoQDZOzU/clWo/VaA34rNHaZBamqiUiklbg42ldXL+m8jBNp1O+Sl+4KRm -zlZc/oLZFBOtlbxjnVWT8YnhBWU6X/iNNSN715NvyX7B6EJKvR8OoE3hC5k1btQJ -8iGTjmsZ9qNHbalryc/faR9fvl1UUkdo2S88C8LAbPaS5IUCAwEAATANBgkqhkiG -9w0BAQUFAAOCAgEAIVJZ031YODBlRWpK8MK42zXfJT7RCtI/z4AD+/gOYvq2EHdc -ghKFQxKchbLd3Avc9jO8vf2S7RJBgz6MYsTKwKTPZsoDZsso6w1Y9ku0Go824zUX -DFYtTJxAEPweQwFIki/omqAVZNgu34GS6WNnt9iPt8rlfjQDoPG0DGhVqiWzLOvw -aPHmdNo5sJGUUuG9nPfISMAVP0H0egG+nbsOGJRxrHDDb8UWIj4aGDBUONGi/8T0 -yLFbGFeNYU22d1WtQhvZr8N6kY2x2fCUp/mdYZ5dg/c7igZ3QJiiU7gDcs4L2BvE -K1Lq0A0bPEJi4y+zIWTbzI0Nw8I7t3TTeh34TOlHVROtnDvRYCSh0PS3XodYPaS3 -S2U27eZ96FgDK6KflPI6oJejK0VaveOFtorZxJS8cY7LwApbAvUCg2PqV1/LSigw -wUCLnkXdTz/Ba2qzjTOGQ5fOOrwEYoNN5NXvFQVs80jIio9SwP1GThGv5vtb49al -wEzP4uTuKe9a83G+I+E9oEgWAx2lVknXkANZPYhVWOfGMC0x0vtC7/i5CA9fXngR -g13UduBEP0fsXsG1LAt+MhAluvinbBJcdWeHpuMjNuLvOw2JRKf0yXB1w16OMv6l -yg9L5Dj8tT8ytqbYM5rD6kXHPgOdL75u1dWMTClBSRtJHXicgZJ4qOrIu70= ------END CERTIFICATE----- diff --git a/cert/composer.crt b/cert/composer.crt index b1ee07b..c6f4f6a 100644 --- a/cert/composer.crt +++ b/cert/composer.crt @@ -1,33 +1,35 @@ -----BEGIN CERTIFICATE----- -MIIFojCCA4oCDwEHZiLzpoachtLqexzMADANBgkqhkiG9w0BAQUFADCBoTELMAkG -A1UEBhMCQkMxEzARBgNVBAgTCkNhbmR5IExhbmQxETAPBgNVBAcTCFZpY3Rvcmlh -MRAwDgYDVQQKEwdMZWFkTGFiMRcwFQYDVQQLEw53d3cubGVhZGxhYi5jYTEXMBUG -A1UEAxMOUGllcnJlIEJFVUNIRVIxJjAkBgkqhkiG9w0BCQEWF2JldWNoZXIucGll -cnJlQGZha2UuY29tMB4XDTEzMDgwNjIyNTEzN1oXDTE0MDYwMjIyNTEzN1owfjEL -MAkGA1UEBhMCQ0ExCzAJBgNVBAgTAkJDMQwwCgYDVQQHEwNWaWMxEDAOBgNVBAoT -B0xlYWRMYWIxDzANBgNVBAsTBk91ckxhYjESMBAGA1UEAxMJbG9jYWxob3N0MR0w -GwYJKoZIhvcNAQkBFg5mYWtlQGdtYWlsLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQAD -ggIPADCCAgoCggIBAOuolt8as/EYwJx91NNgv0LC+31h2fqb9JSxmipXeVvpBRD9 -G9bfWaeycHS6VI4yLnbKovtcA5MWQsGtok/jn/MMbihdnr8Fi9qAiEx6xheBCeSW -at8tiSl7y6ekKk8HiwUwr1WylRkWRYIj4ydmcs49D4ilZ9hliPuiGEY1k1FZL/Nx -GV2qIsMPD1UNT1utI1m14X4s0S32Y+Al2U35zuXJlJzcJ0vOt219MLxSnQLcB1BL -Cr/JxrmXdSuA8Ahn5DUDo0c57eCFiojH824BOjBGbThg1GzPx2ILgC60L2wfsAke -N/uN8EVHlDM8G+H/zBy1LYxPpSSEz0hJ2kB1BklnC4ZTx+kRWMPyoGGltQHYNmx6 -9q0QpG7uIXmUy/1SVqgZGN8lXqXBm9R+7YetfLzbjhccnAOj0FmkyOtitZVo+Sw1 -hmdmjkbHLD4Y4QubwVnXsOAqq7T25UKoDQbr3lr9XxnQ6lx9bPObjp08tn3dKXUU -wFaDo0bEjmIbLqSBB77x0gj5s3b0gJ4LSLkfBa95Wy4URs8VfSQLuAIBdZ2zbNN0 -9600wOsyRps0MOT2mcsShIT2hOjwjEzc0TZ7Sub5egiqOR5pMAhUG8PSFzp+vmd0 -f80k+EsB0BIR77sDmbWDZ3SB7ufR5T2lx6bNCeY+laNubo+ZfidC6ia9riVJAgMB -AAEwDQYJKoZIhvcNAQEFBQADggIBABKxY5c9IOKfDiXwBx4ZvSeo8QNwMTyyVtBZ -PJyMql78LVhxVYOzDejRfOBWrUvkRY24QxFkpVDcnvz5ouWSiPCv6WxCiFljOuOx -dEmIMDcMWJ0AISnx3Lg7UN6utBBa2ycsp2Y4E04XU4oqCDp9ao78r5gPwzlA0Ckh -1Fs4r8HaC4HXRI/zDKS1JdNyDFHRPz28RqJrRdndLcSvWoTVrPbOZ9nGnTMSpluO -3FSIdh27m30V578oHWxbb35YVySNHe58CfYiYIhphfxJdckXn24vt6yNAvqfG8YV -0MAekg223o3Eefp0bWOHiszeWlSIsUCoXZRZK2tbG812TIiA0g3e+lGZHqSywjpP -O2Z4NEL19HkUE4VmXy6MBXLHZWwmw//5AfFedNYMJydw8+k+UHiV2skGFSJvhd7E -566wtZHbeXkhfCBnC/Kc9FpUWBSSvBEe9AxwLFCqHl4R5uxWBuWg9FAwdipnN5KN -Piv0DQS1nXFEdCyFlOx+jQlo6/zNrhVN5luxam1/AT+zXW+8otKPziVeyGdxKryH -zCbb35Q5S1u5iJXMWJwhQC6nzErwA3VbyzO5t4c/FZbaCHxa93bCOMfNBNHVhKCZ -Uv/w+FYh9bD+PBmTQiHGXYR2kvgl4vfrw98XFxDL5fFFHR1BsPD0esmWjd+0fAxu -j3xNAuir +MIIF/zCCA+cCDwEHZiLzpoachtLqexzMADANBgkqhkiG9w0BAQUFADCBvTELMAkG +A1UEBhMCQ0ExGTAXBgNVBAgMEEJyaXRpc2ggQ29sdW1iaWExETAPBgNVBAcMCFZp +Y3RvcmlhMR8wHQYDVQQKDBZVbml2ZXJzaXR5IG9mIFZpY3RvcmlhMR8wHQYDVQQL +DBZJc2xhbmQgTWVkaWNhbCBQcm9ncmFtMREwDwYDVQQDDAhMZWFkIExhYjErMCkG +CSqGSIb3DQEJARYcc2Nvb3BoZWFsdGhAZ29vZ2xlZ3JvdXBzLmNvbTAeFw0xMzA4 +MjcyMTM4MDFaFw0xNTA4MjcyMTM4MDFaMIG+MQswCQYDVQQGEwJDQTEZMBcGA1UE +CAwQQnJpdGlzaCBDb2x1bWJpYTERMA8GA1UEBwwIVmljdG9yaWExHzAdBgNVBAoM +FlVuaXZlcnNpdHkgb2YgVmljdG9yaWExIDAeBgNVBAsMF0lzbGFuZCBNZWRpY2Fs +IFByb2dyYW1zMREwDwYDVQQDDAhMZWFkIExhYjErMCkGCSqGSIb3DQEJARYcc2Nv +b3BoZWFsdGhAZ29vZ2xlZ3JvdXBzLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBAKMS86FGHv3YZWYGcQWouSxF0g14fjOpVdydMGUHsqRdAyrThh6U +1lvxILZaFMtvPrsNu7qFQtBY0Tutjj+kX3yKrtQNUk+v1M0DcncpmTZFlONZqSIF +AjzmIB/108YZI4Y2CnbAQpF4p1C0gvc+p2Wlsa/ZiE/xoYMeAbe3V8eYfl31W/oe +W95J2K2vbpL7JdSeXxpzLj4l5WoVmExFAqMp7AOVy2EW/S2NHGP1y/+8QnQWjWcP +lfHuyvQqZcxrr0T8vpjHQ88wbGBEjr+ZRMiZPsXVcwXbEld8OATYjw6l5dGbcCKX +3PEzulVbaBWkMBo5bEe5VnxJU9iF5cBDp94ns25bp7EFDTvjblA+NRvtUjFgQYM2 +9ZU9raW9bh9NZG6DFMDgTxYmMuM6D3CXwcCiV78XO9WbdEvX1rYUokShnWg8Y+8O +cPMs7fBU/jsjWAdC+3c1t6vyK/kTXqFP+CUqphX9GmiETXXFDBM1O4imecfd5OoL +bnENL3p5zro/aw/R5Z42XHtqHZgvdQJmI1Qihyu9XgR2xGKs6/hMPTnSd95BPkJ5 +Uv31DgOxMcPPOOAq69GNdVu2cMTyHDVXNZ0gqZVFsktOOgnIYPht1ta3lHvlqN70 +nx3dRGmcUinxWnYZSmfuGh8v6ezWI5viHohvsct0mgTHRMcTAHaE2IpLAgMBAAEw +DQYJKoZIhvcNAQEFBQADggIBAI8RqDC18Gm1SJ5SDCyqzZNNu5+aEVoVmPJlK/Eo +x60w34Twimw53kwpZzYNyPvd/7fYWVj3xrtHenv7GyFjSN4G/xA0BAMI++A3ylxF +xZ5xDv+ME8AI3SrODKJHG3yrbYe4PdzzYYrw+ZnLOK2ZuJZqfG2IgPX+U0AOot0t +DubMVHzRVWzl2uKA5yQz8uEUn0no3HA/Dm/J3039C6R7/DstLA1paFNH26yKhnft +fVedS6bJ0ugA/yO30thn8uCm1AEZftpDvIcFddwg44Qt4CWA+6mmYMjJ62l8fBVr +9XZjJ+lQKR0h0AigB4TpwibwIKUV87TNlHgrtUvINaWidCbBuVCcmEmGNjNfMYJX +lhd6yHgsk6KDD8bc5YUD6t4GvPwmf4jh/4pnZfT4dieZ1NwV1Ohi/TngCiI2ESWA +5/7C05M+faqxCCh/5cxZHj+PKy1KWm/JecoNfIpgHrekaJW7hEC6tqm7D0q8QBpW +vsoaSqDQVD0WBUt4s6DJvC0fPwFk1VITQx2X8y01bLNhASYiMlwzMnhWhtFf8ey8 +VWs2ur1LFirxOGS1X3DW7DOoieOC9UkePBPaBkkM+RvIqh7e+flzYiF6DljJHTvU +/t50/BdT+kIBbTQ0UF0S39qPdCF3IQ1qqYGOinh7njciFFSGBc7L9vHcShyXKSZo +G/Yr -----END CERTIFICATE----- diff --git a/cert/composer.csr b/cert/composer.csr index 9505390..197dd43 100644 --- a/cert/composer.csr +++ b/cert/composer.csr @@ -1,28 +1,29 @@ -----BEGIN CERTIFICATE REQUEST----- -MIIEwzCCAqsCAQAwfjELMAkGA1UEBhMCQ0ExCzAJBgNVBAgTAkJDMQwwCgYDVQQH -EwNWaWMxEDAOBgNVBAoTB0xlYWRMYWIxDzANBgNVBAsTBk91ckxhYjESMBAGA1UE -AxMJbG9jYWxob3N0MR0wGwYJKoZIhvcNAQkBFg5mYWtlQGdtYWlsLmNvbTCCAiIw -DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAOuolt8as/EYwJx91NNgv0LC+31h -2fqb9JSxmipXeVvpBRD9G9bfWaeycHS6VI4yLnbKovtcA5MWQsGtok/jn/MMbihd -nr8Fi9qAiEx6xheBCeSWat8tiSl7y6ekKk8HiwUwr1WylRkWRYIj4ydmcs49D4il -Z9hliPuiGEY1k1FZL/NxGV2qIsMPD1UNT1utI1m14X4s0S32Y+Al2U35zuXJlJzc -J0vOt219MLxSnQLcB1BLCr/JxrmXdSuA8Ahn5DUDo0c57eCFiojH824BOjBGbThg -1GzPx2ILgC60L2wfsAkeN/uN8EVHlDM8G+H/zBy1LYxPpSSEz0hJ2kB1BklnC4ZT -x+kRWMPyoGGltQHYNmx69q0QpG7uIXmUy/1SVqgZGN8lXqXBm9R+7YetfLzbjhcc -nAOj0FmkyOtitZVo+Sw1hmdmjkbHLD4Y4QubwVnXsOAqq7T25UKoDQbr3lr9XxnQ -6lx9bPObjp08tn3dKXUUwFaDo0bEjmIbLqSBB77x0gj5s3b0gJ4LSLkfBa95Wy4U -Rs8VfSQLuAIBdZ2zbNN09600wOsyRps0MOT2mcsShIT2hOjwjEzc0TZ7Sub5egiq -OR5pMAhUG8PSFzp+vmd0f80k+EsB0BIR77sDmbWDZ3SB7ufR5T2lx6bNCeY+laNu -bo+ZfidC6ia9riVJAgMBAAGgADANBgkqhkiG9w0BAQUFAAOCAgEAw0O+72Jlujw5 -jqkAOTsetu85DciQmeFca9uVXXEllJ0wFsrYiS+GQrCTGTHVzZ2uPVutUq9ZhosH -rxGarv6RZaf0A+RWv6RqCLnkQLaSPy8gieBEjrjJdkZCTQrqf6foGG98RI5KFoJp -2RLLkMN6zHaCzTLhf4Yw5YcEHBrfMf5ZWZdfYIrioKvMPVFPmua6Jfx63iW+Lw0U -g8mq8uKFzFCzsNMpiuDPSzhSpDJ99nBBSw9UvIYeM3XSymFeaqgzap58HID5N/XL -SdazEFgiliQHByNEftrt7jtEGe2hcVSwy40FKFD0oUYl0VAYCRgv7Eb0l/pedvsL -vlKpH/H1jWsx7O5bI3NGiUG+FOmNdI+i7K4/iGU1kI7ZqvcXRSsAUAVUgaXegqaf -bVtfBaW7VCWyPgAUBDC5Yu41DdEbM43ShLB+zGeuGbYpZN0mqFRKQNoxfLmqcZF8 -cRTvptwPmNKucOpzPHlz1GF9JWP8Q5n9TuYtM929524CDAVVwFfhDXHDEQe7IIyy -TyiWpOE6lf3RuwtqjAx9Xceyngug+3HjV4A++ZKi3WThrGqOVS3+I/6MpsFFTiER -u5hNVScAcIpDnXp9MqRbveY/OddTfpCx4pAYunIJLJIzb14HZjzo+CJirrxJvFAU -3RcKREA4QStOY6b9B825pOhp56aWQIQ= +MIIFBDCCAuwCAQAwgb4xCzAJBgNVBAYTAkNBMRkwFwYDVQQIDBBCcml0aXNoIENv +bHVtYmlhMREwDwYDVQQHDAhWaWN0b3JpYTEfMB0GA1UECgwWVW5pdmVyc2l0eSBv +ZiBWaWN0b3JpYTEgMB4GA1UECwwXSXNsYW5kIE1lZGljYWwgUHJvZ3JhbXMxETAP +BgNVBAMMCExlYWQgTGFiMSswKQYJKoZIhvcNAQkBFhxzY29vcGhlYWx0aEBnb29n +bGVncm91cHMuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAoxLz +oUYe/dhlZgZxBai5LEXSDXh+M6lV3J0wZQeypF0DKtOGHpTWW/EgtloUy28+uw27 +uoVC0FjRO62OP6RffIqu1A1ST6/UzQNydymZNkWU41mpIgUCPOYgH/XTxhkjhjYK +dsBCkXinULSC9z6nZaWxr9mIT/Ghgx4Bt7dXx5h+XfVb+h5b3knYra9ukvsl1J5f +GnMuPiXlahWYTEUCoynsA5XLYRb9LY0cY/XL/7xCdBaNZw+V8e7K9CplzGuvRPy+ +mMdDzzBsYESOv5lEyJk+xdVzBdsSV3w4BNiPDqXl0ZtwIpfc8TO6VVtoFaQwGjls +R7lWfElT2IXlwEOn3iezblunsQUNO+NuUD41G+1SMWBBgzb1lT2tpb1uH01kboMU +wOBPFiYy4zoPcJfBwKJXvxc71Zt0S9fWthSiRKGdaDxj7w5w8yzt8FT+OyNYB0L7 +dzW3q/Ir+RNeoU/4JSqmFf0aaIRNdcUMEzU7iKZ5x93k6gtucQ0vennOuj9rD9Hl +njZce2odmC91AmYjVCKHK71eBHbEYqzr+Ew9OdJ33kE+QnlS/fUOA7Exw8844Crr +0Y11W7ZwxPIcNVc1nSCplUWyS046Cchg+G3W1reUe+Wo3vSfHd1EaZxSKfFadhlK +Z+4aHy/p7NYjm+IeiG+xy3SaBMdExxMAdoTYiksCAwEAAaAAMA0GCSqGSIb3DQEB +BQUAA4ICAQA0r0NkT3dmqNdUlXTMzQ7V0pvGAwhig3/wVRQM2gvBDRymsWi4YuWm +8WN4DT7xSxLcLaSqaYANapuDQQ3OJdiZv8KCGfKFRe3l47QpfTN8Y2w4WJZXVCKQ +2hf85HcgCLTsAjBjCr+/kmnC7Qu2hk8uVMs0E8sGm4TJO99FbwIxmyxSUVEkREt9 +3I0hg44ic8LJtaBp5V1lN8rsWOi739i9AiAC3bFqoeUSXerGjxaoajkhQbTcM/gj +V7swU/lE5TGqFOOZo/bsJRwWrpaI8BpI76SoQlAwUopGlDE7+mOI+/Ldn6Yyck5Z +MriXtBTp67DmLu8MkNSfld0ssGtnReRTY+19H4r38yIqAVB+SrCk/S1O40uSE8jy +XlQdUsnIjcC0n133HjFu3V8+rRU/R1Snw4NrZT5QN5m56I1ZZ148JXLXkWG3g8SA +E9UJi0XxOgCLZVJctNsla4u2R+NJlAxAc46qu2c2ZfC2VaDiTkHN+DtkNlgPTH5m +kEkTmJQZwgT+68J3Qzykty92iFA8mwTUmOLD/SburoKAdxfcxnVzDu60ribkzxKL +mQTRlmmVhsFpI7Gb9MH+B2rlfSN2AjHR/obKf9KChjrKHvE5ywUcUM1yygYkoJJe +3A7yBntylu78mCDeawsSQDzCT95t1evGPVEkFGiOgXRPaQ2XoaHVhw== -----END CERTIFICATE REQUEST----- diff --git a/cert/composer.key b/cert/composer.key index cae4d35..bb59541 100644 --- a/cert/composer.key +++ b/cert/composer.key @@ -1,51 +1,51 @@ -----BEGIN RSA PRIVATE KEY----- -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 -----END RSA PRIVATE KEY----- diff --git a/cert/comp-cert b/cert/old/comp-cert similarity index 100% rename from cert/comp-cert rename to cert/old/comp-cert diff --git a/config/initializers/ssl_config.rb b/config/initializers/ssl_config.rb index e164377..1f601c5 100644 --- a/config/initializers/ssl_config.rb +++ b/config/initializers/ssl_config.rb @@ -1,9 +1,9 @@ #contains constants for certificate used for SSL -SERVER_CERT_PATH_ = "cert/composer.crt" SERVER_KEY_PATH_ = "cert/composer.key" +SERVER_CERT_PATH_ = "cert/composer.crt" CLIENT_KEY_PATH = "cert/client.key" -CLIENT_CERT_PATH = "cert/client.pem" +CLIENT_CERT_PATH = "cert/client.crt" SERVER_KEY = OpenSSL::PKey::RSA.new(File.open(SERVER_KEY_PATH_).read) SERVER_CERT = OpenSSL::X509::Certificate.new(File.open(SERVER_CERT_PATH_).read) From 900bbd37854be395412b3eb1e5199fd266232e67 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Thu, 29 Aug 2013 13:16:56 -0700 Subject: [PATCH 048/117] Updated openssl self-signed certificates and documentation. --- cert/README | 51 ++++++++++++++++++ cert/ca/LeadLab_root_cert_TEST.crt | 36 ------------- cert/ca/LeadLab_root_cert_TEST.pem | 87 +++++++++++++----------------- cert/client.crt | 35 ------------ cert/client.csr | 29 ---------- cert/client.key | 51 ------------------ cert/composer.crt | 35 ------------ cert/composer.csr | 29 ---------- cert/composer.key | 51 ------------------ cert/{ => old}/README.cert | 0 config/initializers/ssl_config.rb | 18 ++++--- script/rails | 10 ++-- 12 files changed, 105 insertions(+), 327 deletions(-) create mode 100644 cert/README delete mode 100644 cert/ca/LeadLab_root_cert_TEST.crt delete mode 100644 cert/client.crt delete mode 100644 cert/client.csr delete mode 100644 cert/client.key delete mode 100644 cert/composer.crt delete mode 100644 cert/composer.csr delete mode 100644 cert/composer.key rename cert/{ => old}/README.cert (100%) diff --git a/cert/README b/cert/README new file mode 100644 index 0000000..b402b4d --- /dev/null +++ b/cert/README @@ -0,0 +1,51 @@ +# Change into the query-gateway root directory. Make a cert subdirectory. +cd $HOME/query-gateway && mkdir cert && cd cert +# +# Generate a self-signed certificate. You need to answer some questions. +# Most of them can be answered arbitrarily but it is important that the +# Common Name be accurate. For development and test purposes you can +# use something like *.localdomain to cover all hosts in localdomain. +# I used: +# Country Name (2 letter code) [GB]:CA +# State or Province Name (full name): British Columbia +# Locality Name (eg, city): Victoria +# Organization Name (eg, company): University of Victoria +# Organizational Unit Name (eg, section): Island Medical Program +# Common Name (eg, your name or your server's hostname): *.localdomain +# Email Address: scoophealth@googlegroups.com +# +# This will generate the certificate and key in a file named server.pem: +openssl req -new -x509 -keyout server.pem -out server.pem -nodes -days 365 +# +# Copy the self-signed certificate to query-gateway/cert/ca +# [The location and name can be changed but must match +# the entries in query-gateway/script/secure_rails.] +mkdir ca && cp server.pem ca/LeadLab_root_cert_TEST.pem && rm server.pem +# +# Note: We used *.localdomain for the "Common Name" when prompted +# for that information. For this to work, you will need an /etc/hosts +# file that maps IP addresses to entries in the localdomain. For instance, +# $ cat /etc/hosts +# 127.0.0.1 localhost localhost.localdomain +# 127.0.1.1 query-composer query-composer.localdomain +# 192.168.52.100 mysql-host mysql-host.localdomain +# 192.168.52.101 query-gateway0 query-gateway0.localdomain +# 192.168.52.102 query-composer query-composer.localdomain +# 192.168.52.103 query-gateway1 query-gateway1.localdomain +# +# Now find the hash of the self-signed certificate +# $ openssl x509 -hash -noout -in ../cert/ca/LeadLab_root_cert_TEST.pem +# +# 962a3564 +# +# Create a symbolic link from the self-signed certicate to a file in +# /etc/ssl/certs with name matching the hash with suffix '.0'. +# +# /etc/ssl/certs/962a3564.0 ->/home/vagrant/query-gateway/cert/ca/LeadLab_root_cert_TEST.pem +# +# For this particular self-signed certificate's hash, I did this: +# $ sudo ln -s /home/vagrant/query-gateway/cert/ca/LeadLab_root_cert_TEST.pem /etc/ssl/certs/962a3564.0 +# +# To start up the SSL secured version of query-gateway on port 3002 use: +# $ bundle exec script/delayed_job start +# $ bundle exec rails server -p 3002 diff --git a/cert/ca/LeadLab_root_cert_TEST.crt b/cert/ca/LeadLab_root_cert_TEST.crt deleted file mode 100644 index 6c84d40..0000000 --- a/cert/ca/LeadLab_root_cert_TEST.crt +++ /dev/null @@ -1,36 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIGTzCCBDegAwIBAgIJALD43pKdRjenMA0GCSqGSIb3DQEBBQUAMIG9MQswCQYD -VQQGEwJDQTEZMBcGA1UECAwQQnJpdGlzaCBDb2x1bWJpYTERMA8GA1UEBwwIVmlj -dG9yaWExHzAdBgNVBAoMFlVuaXZlcnNpdHkgb2YgVmljdG9yaWExHzAdBgNVBAsM -FklzbGFuZCBNZWRpY2FsIFByb2dyYW0xETAPBgNVBAMMCExlYWQgTGFiMSswKQYJ -KoZIhvcNAQkBFhxzY29vcGhlYWx0aEBnb29nbGVncm91cHMuY29tMB4XDTEzMDgy -NzIxMTYyMloXDTE4MDgyNzIxMTYyMlowgb0xCzAJBgNVBAYTAkNBMRkwFwYDVQQI -DBBCcml0aXNoIENvbHVtYmlhMREwDwYDVQQHDAhWaWN0b3JpYTEfMB0GA1UECgwW -VW5pdmVyc2l0eSBvZiBWaWN0b3JpYTEfMB0GA1UECwwWSXNsYW5kIE1lZGljYWwg -UHJvZ3JhbTERMA8GA1UEAwwITGVhZCBMYWIxKzApBgkqhkiG9w0BCQEWHHNjb29w -aGVhbHRoQGdvb2dsZWdyb3Vwcy5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw -ggIKAoICAQDlYCSmdrKnENfM7VmMwYSDC72ymYRoZesnNwS5d2bIMVrUsXKcvqjg -tEJGvStkfD8LXJLD4WPIr7EQ8COTO38xgbJ2S/KiZ7wJNTW27/kYJQ6MPw1cevzH -2JJplofqzK0mxtEcOENSDG7Mz0cnWeIlPYS5LSzgA+Nieo6QHVU5EPa33/S0U2E2 -nNXGdZysoNKkIGNfbf3h1FTJ0pEnd5V+/tWci8WztRr6dLbtEsTuDamHCDe2AWzV -Pm/aIXXTZWA/piT7MoZCNcH3MaGHzg1E/8S+IebAgQNknDTQe8PyLISzR1OJfQK6 -kyg+gBxQJSSLVev3rhiY8Te+XX1BlbEj+GQFtdtKv+/dRns6uylqyEBFeRAHn3Of -L7YnHxa5QqIEjxFQMNJ9JnaZ7KgNLRFS6p4AQvxPYyjKw5MBhXWIb7OWrTGSYTuA -Oxpo06/02RzxaW5urxdqxmzGJyqDDLnoYpTENc1Mw4Vchs3IJBvGu+RPPAVPqtOR -lcK8O9whfV59nBnmbCtKD1PhJW7AD5mpVsjIlbkD9GbtC/meTBQ2eHE9iCa8RyF8 -MwD2cPL1edp4Jop1XryQgHkAS5xLS3K0iAQcYBZl4YDUWCNz9o5Ww794CnWBch4D -QzMxxk8tI4qU38G6UmNgZwbhAXgiQe4G6Jw2Q65TQ8XjMWLuDyzS5QIDAQABo1Aw -TjAdBgNVHQ4EFgQUYJ7eqIHmeRBMCHuwmZ3DXB6W8YwwHwYDVR0jBBgwFoAUYJ7e -qIHmeRBMCHuwmZ3DXB6W8YwwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOC -AgEAhe2Fr0mbj97lwoA78/sunCKQtDyTyTz4y5MVCQyyEvZ9Ux4EsjYbsBKNoWdD -JXGERqvx7M2sY9UsevklhG7GyvoNckGmyGbUxzD9H3qZ2gK+6iroBSvXqJK/THfp -vscmvWNjAWnvTTFnQY1Q1nZRLUjLpLOIR0pLn/2NCdFYrNrCg6SSIHehLgepAgW8 -7NdJapca16V7h8lppg9LlqVIlzfXYcl8LbUrYtUtUMTZEyolfGCpSMmXGU3Jxhou -yl3ImSTAoIUWzz3LO1IANGmG9B1FQuSTXdGrxbgFtKld0rdJB4opEqYhLqIRRUqz -mjrp1d+NjY9PE+AOC/YSMowzLTVWMuaVRc3WxijJgj8cvOv/0fRezGrZFSJSowZu -p+gs3rA4/F6XBPU+a6fTF0BQwnuVW+B7EdZK/zZgMz2in9TlWaXES1A5sgyf0HvA -R3E7afcrXtWGge6MC14fjpQ4hdMuODLT0rhx/p5aRm1RLHbQKkd9mK3j8dr/TbXR -pnUR4Yr0khe+XHECHQqGnyk3zMOC+a6gpOeFKQpd1BlXoo+q4N5owv9dHRHqI6Ns -AINmoMC27Pnt3c3xbttKEbEfDDV+tgi1Fy6JGV0G8MuswFYW4/yTwZ2s+HEBKPrh -cEEmarBzqv0g76LJvi4YE9ZjuI8g5NASPHWQaNsIYjx9uKI= ------END CERTIFICATE----- diff --git a/cert/ca/LeadLab_root_cert_TEST.pem b/cert/ca/LeadLab_root_cert_TEST.pem index 4b30b30..5af6e59 100644 --- a/cert/ca/LeadLab_root_cert_TEST.pem +++ b/cert/ca/LeadLab_root_cert_TEST.pem @@ -1,51 +1,36 @@ ------BEGIN RSA PRIVATE KEY----- -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 ------END RSA PRIVATE KEY----- +-----BEGIN PRIVATE KEY----- +MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBANEKAbCsoweaNzb1 +An3rPTlF/8lypAz6zReIML6dBrquO/R1fHYrs1qdQCOf8rY3mFU+FCloSFIITiF+ +NeqsVzGAFwRbT2HIwCiWMepLvjumLxCPSfUZiz+yhgXjNnNLu4m+YzDlFJCmMDV+ +m0Q0ViKFyPzPINGVI0xtPFTKX1fpAgMBAAECgYBsdQepdfjkUeRB9F9Fm87ZL3Nm +Pr/VKC9O/U9lJq2+H/ZlgKuB2GynIB2OHkfcuP2lhJ8LWNrlDQAUqpoo1yApUydz +u98QLFw7+7V5B8igC+mxjImc9XGdWtB+/sAQk3aQuEMLskmpvZHkCgzIWylvRvmb +ATBFvethNnqRC5PrgQJBAPZvYoDub4nm9Lyb+7Pc8ZSKmmltngbYEFXhrld21WIn +wL95ZeiJqyleZxsXth86fSWd+Fgv8KmYYrw7DMjIibkCQQDZJwyy1tibX6nTaou5 +TYBVAvlTuYA5iVOh1Q/a9T/Ko/4/dX8lm/Lm7MrMRxqIGok1IIexNhsfloN/TUew +XJexAkArozupIw+jNr99qo1eozAwIn8HTj7ebWIvIwBxQny0nd92yHNwQviJIctW +M9OvIfdJMvjn/M076t0JAdfYshIZAkA4wy9blDN8sc3nmKM7ZdnU3vkjfIra/12g +INyLJK5vHtz345O/1frxiBYevbtetmkFPSKbHQSMBkELRr0liZ6RAkBzhur1fRhr +RjJR38o684Z4Sx0iflyWFVe/08EVXBqCaj6Bb9/unQmYC+dWhmJqAOUS/FiaEmvC +EaE6hG7QkARE +-----END PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIDVDCCAr2gAwIBAgIJAOWAnoqQBfNbMA0GCSqGSIb3DQEBBQUAMIHCMQswCQYD +VQQGEwJDQTEZMBcGA1UECAwQQnJpdGlzaCBDb2x1bWJpYTERMA8GA1UEBwwIVmlj +dG9yaWExHzAdBgNVBAoMFlVuaXZlcnNpdHkgb2YgVmljdG9yaWExHzAdBgNVBAsM +FklzbGFuZCBNZWRpY2FsIFByb2dyYW0xFjAUBgNVBAMMDSoubG9jYWxkb21haW4x +KzApBgkqhkiG9w0BCQEWHHNjb29waGVhbHRoQGdvb2dsZWdyb3Vwcy5jb20wHhcN +MTMwODI4MjAwMjEwWhcNMTQwODI4MjAwMjEwWjCBwjELMAkGA1UEBhMCQ0ExGTAX +BgNVBAgMEEJyaXRpc2ggQ29sdW1iaWExETAPBgNVBAcMCFZpY3RvcmlhMR8wHQYD +VQQKDBZVbml2ZXJzaXR5IG9mIFZpY3RvcmlhMR8wHQYDVQQLDBZJc2xhbmQgTWVk +aWNhbCBQcm9ncmFtMRYwFAYDVQQDDA0qLmxvY2FsZG9tYWluMSswKQYJKoZIhvcN +AQkBFhxzY29vcGhlYWx0aEBnb29nbGVncm91cHMuY29tMIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQDRCgGwrKMHmjc29QJ96z05Rf/JcqQM+s0XiDC+nQa6rjv0 +dXx2K7NanUAjn/K2N5hVPhQpaEhSCE4hfjXqrFcxgBcEW09hyMAoljHqS747pi8Q +j0n1GYs/soYF4zZzS7uJvmMw5RSQpjA1fptENFYihcj8zyDRlSNMbTxUyl9X6QID +AQABo1AwTjAdBgNVHQ4EFgQUltQ6g39ZWulvvY/kTFqqQnJGXY0wHwYDVR0jBBgw +FoAUltQ6g39ZWulvvY/kTFqqQnJGXY0wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0B +AQUFAAOBgQB6V+HzYlW9qgu/xliFIu1EjJmLGOtBf4aRkdg6gSaxDB84SggoKKG0 +YzrTuYN9vv70zqGTDc76FKQSjuSugnmn6eCKkTi9/9Xvc0ZMdT3Hr3KQfgseTEpA +URHghVEJCn1s1OmW8Eb/I99FbhN6L8sibl9eWBSUZffTKiIJY3JX0g== +-----END CERTIFICATE----- diff --git a/cert/client.crt b/cert/client.crt deleted file mode 100644 index d981924..0000000 --- a/cert/client.crt +++ /dev/null @@ -1,35 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIF/jCCA+YCDwEHZiLzpoachtLqexzMATANBgkqhkiG9w0BAQUFADCBvTELMAkG -A1UEBhMCQ0ExGTAXBgNVBAgMEEJyaXRpc2ggQ29sdW1iaWExETAPBgNVBAcMCFZp -Y3RvcmlhMR8wHQYDVQQKDBZVbml2ZXJzaXR5IG9mIFZpY3RvcmlhMR8wHQYDVQQL -DBZJc2xhbmQgTWVkaWNhbCBQcm9ncmFtMREwDwYDVQQDDAhMZWFkIExhYjErMCkG -CSqGSIb3DQEJARYcc2Nvb3BoZWFsdGhAZ29vZ2xlZ3JvdXBzLmNvbTAeFw0xMzA4 -MjcyMTM4MTRaFw0xNTA4MjcyMTM4MTRaMIG9MQswCQYDVQQGEwJDQTEZMBcGA1UE -CAwQQnJpdGlzaCBDb2x1bWJpYTERMA8GA1UEBwwIVmljdG9yaWExHzAdBgNVBAoM -FlVuaXZlcnNpdHkgb2YgVmljdG9yaWExHzAdBgNVBAsMFklzbGFuZCBNZWRpY2Fs -IFByb2dyYW0xETAPBgNVBAMMCExlYWQgTGFiMSswKQYJKoZIhvcNAQkBFhxzY29v -cGhlYWx0aEBnb29nbGVncm91cHMuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A -MIICCgKCAgEAvj523FtDd+M/ChEN1njkbn4jdq7klyzdCCNZfxSFOtA4ol4Ea6Me -PBK29tljDJfCrC2bR8pILntMW/5zDk6ry5Db3qDvFFHUrf/7k8A3K3PHF9C632l3 -Esq+aNBfLunOr9jJsZ53SPB6dIh+laV9jluAYiW9A3t9UJuVcZszz+nt4Uq7Lq9Y -/TvnnMgdhAAu/OIFqKL167GWt2ajWY+wkCUapARAUgpLac+ZnwGu6Nx6s/ITILP6 -jDOe4RIURZNJPulnntT+MDF239EBePZF5V5qRGVX19fyrmKp37mxlSEyabIcPner -M87fMlRz6prEOzrY21vY2nXLTsNzeU45DR+9JsVmiajrQSU9dYJbiI59xMm0Z1Fa -xsnN386YBcmSS69uXs71X0QMU3xMl2tL6blfj7lQs0jWG3PlrCLPN79rBkn9jcZv -L4RraGh+yOWtWXgvNSGzGxHlesWuZ0FUPSjViITzELhCp/RiE4nTujiGTzNqbZpX -M5V6LogZvY/kTY8Kj+c9pE+zPJ9ZWrXEDPzQrSkroYKsUCwT3dARDuVAdRjZaZEa -FD0K47puYOwQXpQBp5DqUihVCrKWBW5lG5L41NBaQiEGXrOEBPmJn1ErfvjU0SZa -UjxjWV6hkTsZiupchovpDUPqh7qbZy0YwJXJqDyYFpWR4JIB+53MnWcCAwEAATAN -BgkqhkiG9w0BAQUFAAOCAgEAuzhecjcdSEiAW43vzcb5U8yAdx/6n6Q5QRVVFztJ -GF48bfijGH3AN5R0yWn+Xrg/ktxg+OvJJjkN4xRNXtvNb61to8MxiIW9vcrjZyyC -IqzwDKptgSZMtFyK3a54nw5DNCXo26kBZ3tY2ohKdeTLnDpyZqZ4OFYltfCSOZH6 -IaDyAOIMiHE0hZLNgB+JTY2BJhIe1ZpWYaF7BrVxH/flhe+nSMe5SXA/X6ZR9+p8 -vBVn+dhaYTm55rmrVaBrrAbwcNYAdkAhhqATQoCnWYQj+UnY/qfRJCg/OSWkcJkw -FTN96jlKE4P/UO6Lkrz6tcXu5XiQz9ybFWy5cmcJ9lwL9SaRZ6e092zu5v5SPSZ9 -QztGRYT+KGInAIDSz3ynwvnfXOkHZoTXNfDHYbzow7gAguDwS7Qb/03ID9QyDDOc -Hd9l+kUUWe6Ysplqq3OY01/C443pacwdQSp5ZGi0yBt6um1UY1r+N7QEbSWE5ygO -DKrJMtWqYrelrejEycUSnNphAtQkD5psgPj8DwbC7kG2f8s2XQPRuNMweUoPCi50 -gg1MxR+OYoJHwqKdc8cGGQBEAcutZbcR/bgGjGowtNBoQLwVUMtBIf6kHrNn89Tc -qlBGpoAt/TYYFTSkWWN3D3EMDZ15yGw9oRPCotB/8bcCXr7fWnuMUnmxLvBDViTW -umM= ------END CERTIFICATE----- diff --git a/cert/client.csr b/cert/client.csr deleted file mode 100644 index 55ba266..0000000 --- a/cert/client.csr +++ /dev/null @@ -1,29 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIIFAzCCAusCAQAwgb0xCzAJBgNVBAYTAkNBMRkwFwYDVQQIDBBCcml0aXNoIENv -bHVtYmlhMREwDwYDVQQHDAhWaWN0b3JpYTEfMB0GA1UECgwWVW5pdmVyc2l0eSBv -ZiBWaWN0b3JpYTEfMB0GA1UECwwWSXNsYW5kIE1lZGljYWwgUHJvZ3JhbTERMA8G -A1UEAwwITGVhZCBMYWIxKzApBgkqhkiG9w0BCQEWHHNjb29waGVhbHRoQGdvb2ds -ZWdyb3Vwcy5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC+Pnbc -W0N34z8KEQ3WeORufiN2ruSXLN0II1l/FIU60DiiXgRrox48Erb22WMMl8KsLZtH -ykgue0xb/nMOTqvLkNveoO8UUdSt//uTwDcrc8cX0LrfaXcSyr5o0F8u6c6v2Mmx -nndI8Hp0iH6VpX2OW4BiJb0De31Qm5VxmzPP6e3hSrsur1j9O+ecyB2EAC784gWo -ovXrsZa3ZqNZj7CQJRqkBEBSCktpz5mfAa7o3Hqz8hMgs/qMM57hEhRFk0k+6Wee -1P4wMXbf0QF49kXlXmpEZVfX1/KuYqnfubGVITJpshw+d6szzt8yVHPqmsQ7Otjb -W9jadctOw3N5TjkNH70mxWaJqOtBJT11gluIjn3EybRnUVrGyc3fzpgFyZJLr25e -zvVfRAxTfEyXa0vpuV+PuVCzSNYbc+WsIs83v2sGSf2Nxm8vhGtoaH7I5a1ZeC81 -IbMbEeV6xa5nQVQ9KNWIhPMQuEKn9GITidO6OIZPM2ptmlczlXouiBm9j+RNjwqP -5z2kT7M8n1latcQM/NCtKSuhgqxQLBPd0BEO5UB1GNlpkRoUPQrjum5g7BBelAGn -kOpSKFUKspYFbmUbkvjU0FpCIQZes4QE+YmfUSt++NTRJlpSPGNZXqGROxmK6lyG -i+kNQ+qHuptnLRjAlcmoPJgWlZHgkgH7ncydZwIDAQABoAAwDQYJKoZIhvcNAQEF -BQADggIBACntvUSwDYZj/L/IOwgbaDCj7hdqiwL3NyBx2uK/5so+OnQSn0qe08Uz -ld6MaKHt/ry4d2QtLztBIk2jO7g3Y61jIFdZpifFTKDDXwXCaEy+Brq9U02gzFpF -J2pseNoZ4M5Y61wBIitES+yE8yeauwtk4kTdASBwoBHCVW/+hTv2B82YzlfmbKP8 -liEjtuc5sAoKJLK2VGY/gY237IfoixwSftRPz5fbIFHzD3XSLnH/+hW7hpKjBfQG -fqwJd1cUHqEmrp21b3yrxT7pyBU+5xyBFjSZ1SYyVx4/syqRw4pP7y+oXZrG1aJ0 -BIQ9NXJ5bAoskYC6XqeJ2UrK4BfhFwP3jJf+pf/QUnY7PvLcaAGeLd212CroHB8s -fOO+QRFUxSAD+cXQOhNky+VY6OwUchTkCN13wOfwYy2CuHPyjZMT4eTGgH1Lr8yT -9Fb9r1ElZkC4N2B+6uXP+qasiDI2/LjK6/JY0sE6SdRAM7+kQzDMhHU0128qlxfI -clsQ2RAUCAnPA2mo5J8g6ztOdz1XdcAbugeLzjg96L+GBANvrTxHyQyiMkfiJiuT -uwjgFZGLd5NRYrHt35nsB4PQJWZ7EAj7SVqOeKng/ZWnVjEl/5pvrIYd93FA8ew4 -d8r9XVJxQS9RZ6KhqCb8EWe/KiB29II89MpAtfpFXJLVXog03FZU ------END CERTIFICATE REQUEST----- diff --git a/cert/client.key b/cert/client.key deleted file mode 100644 index 097f060..0000000 --- a/cert/client.key +++ /dev/null @@ -1,51 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -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 ------END RSA PRIVATE KEY----- diff --git a/cert/composer.crt b/cert/composer.crt deleted file mode 100644 index c6f4f6a..0000000 --- a/cert/composer.crt +++ /dev/null @@ -1,35 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIF/zCCA+cCDwEHZiLzpoachtLqexzMADANBgkqhkiG9w0BAQUFADCBvTELMAkG -A1UEBhMCQ0ExGTAXBgNVBAgMEEJyaXRpc2ggQ29sdW1iaWExETAPBgNVBAcMCFZp -Y3RvcmlhMR8wHQYDVQQKDBZVbml2ZXJzaXR5IG9mIFZpY3RvcmlhMR8wHQYDVQQL -DBZJc2xhbmQgTWVkaWNhbCBQcm9ncmFtMREwDwYDVQQDDAhMZWFkIExhYjErMCkG -CSqGSIb3DQEJARYcc2Nvb3BoZWFsdGhAZ29vZ2xlZ3JvdXBzLmNvbTAeFw0xMzA4 -MjcyMTM4MDFaFw0xNTA4MjcyMTM4MDFaMIG+MQswCQYDVQQGEwJDQTEZMBcGA1UE -CAwQQnJpdGlzaCBDb2x1bWJpYTERMA8GA1UEBwwIVmljdG9yaWExHzAdBgNVBAoM -FlVuaXZlcnNpdHkgb2YgVmljdG9yaWExIDAeBgNVBAsMF0lzbGFuZCBNZWRpY2Fs -IFByb2dyYW1zMREwDwYDVQQDDAhMZWFkIExhYjErMCkGCSqGSIb3DQEJARYcc2Nv -b3BoZWFsdGhAZ29vZ2xlZ3JvdXBzLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP -ADCCAgoCggIBAKMS86FGHv3YZWYGcQWouSxF0g14fjOpVdydMGUHsqRdAyrThh6U -1lvxILZaFMtvPrsNu7qFQtBY0Tutjj+kX3yKrtQNUk+v1M0DcncpmTZFlONZqSIF -AjzmIB/108YZI4Y2CnbAQpF4p1C0gvc+p2Wlsa/ZiE/xoYMeAbe3V8eYfl31W/oe -W95J2K2vbpL7JdSeXxpzLj4l5WoVmExFAqMp7AOVy2EW/S2NHGP1y/+8QnQWjWcP -lfHuyvQqZcxrr0T8vpjHQ88wbGBEjr+ZRMiZPsXVcwXbEld8OATYjw6l5dGbcCKX -3PEzulVbaBWkMBo5bEe5VnxJU9iF5cBDp94ns25bp7EFDTvjblA+NRvtUjFgQYM2 -9ZU9raW9bh9NZG6DFMDgTxYmMuM6D3CXwcCiV78XO9WbdEvX1rYUokShnWg8Y+8O -cPMs7fBU/jsjWAdC+3c1t6vyK/kTXqFP+CUqphX9GmiETXXFDBM1O4imecfd5OoL -bnENL3p5zro/aw/R5Z42XHtqHZgvdQJmI1Qihyu9XgR2xGKs6/hMPTnSd95BPkJ5 -Uv31DgOxMcPPOOAq69GNdVu2cMTyHDVXNZ0gqZVFsktOOgnIYPht1ta3lHvlqN70 -nx3dRGmcUinxWnYZSmfuGh8v6ezWI5viHohvsct0mgTHRMcTAHaE2IpLAgMBAAEw -DQYJKoZIhvcNAQEFBQADggIBAI8RqDC18Gm1SJ5SDCyqzZNNu5+aEVoVmPJlK/Eo -x60w34Twimw53kwpZzYNyPvd/7fYWVj3xrtHenv7GyFjSN4G/xA0BAMI++A3ylxF -xZ5xDv+ME8AI3SrODKJHG3yrbYe4PdzzYYrw+ZnLOK2ZuJZqfG2IgPX+U0AOot0t -DubMVHzRVWzl2uKA5yQz8uEUn0no3HA/Dm/J3039C6R7/DstLA1paFNH26yKhnft -fVedS6bJ0ugA/yO30thn8uCm1AEZftpDvIcFddwg44Qt4CWA+6mmYMjJ62l8fBVr -9XZjJ+lQKR0h0AigB4TpwibwIKUV87TNlHgrtUvINaWidCbBuVCcmEmGNjNfMYJX -lhd6yHgsk6KDD8bc5YUD6t4GvPwmf4jh/4pnZfT4dieZ1NwV1Ohi/TngCiI2ESWA -5/7C05M+faqxCCh/5cxZHj+PKy1KWm/JecoNfIpgHrekaJW7hEC6tqm7D0q8QBpW -vsoaSqDQVD0WBUt4s6DJvC0fPwFk1VITQx2X8y01bLNhASYiMlwzMnhWhtFf8ey8 -VWs2ur1LFirxOGS1X3DW7DOoieOC9UkePBPaBkkM+RvIqh7e+flzYiF6DljJHTvU -/t50/BdT+kIBbTQ0UF0S39qPdCF3IQ1qqYGOinh7njciFFSGBc7L9vHcShyXKSZo -G/Yr ------END CERTIFICATE----- diff --git a/cert/composer.csr b/cert/composer.csr deleted file mode 100644 index 197dd43..0000000 --- a/cert/composer.csr +++ /dev/null @@ -1,29 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIIFBDCCAuwCAQAwgb4xCzAJBgNVBAYTAkNBMRkwFwYDVQQIDBBCcml0aXNoIENv -bHVtYmlhMREwDwYDVQQHDAhWaWN0b3JpYTEfMB0GA1UECgwWVW5pdmVyc2l0eSBv -ZiBWaWN0b3JpYTEgMB4GA1UECwwXSXNsYW5kIE1lZGljYWwgUHJvZ3JhbXMxETAP -BgNVBAMMCExlYWQgTGFiMSswKQYJKoZIhvcNAQkBFhxzY29vcGhlYWx0aEBnb29n -bGVncm91cHMuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAoxLz -oUYe/dhlZgZxBai5LEXSDXh+M6lV3J0wZQeypF0DKtOGHpTWW/EgtloUy28+uw27 -uoVC0FjRO62OP6RffIqu1A1ST6/UzQNydymZNkWU41mpIgUCPOYgH/XTxhkjhjYK -dsBCkXinULSC9z6nZaWxr9mIT/Ghgx4Bt7dXx5h+XfVb+h5b3knYra9ukvsl1J5f -GnMuPiXlahWYTEUCoynsA5XLYRb9LY0cY/XL/7xCdBaNZw+V8e7K9CplzGuvRPy+ -mMdDzzBsYESOv5lEyJk+xdVzBdsSV3w4BNiPDqXl0ZtwIpfc8TO6VVtoFaQwGjls -R7lWfElT2IXlwEOn3iezblunsQUNO+NuUD41G+1SMWBBgzb1lT2tpb1uH01kboMU -wOBPFiYy4zoPcJfBwKJXvxc71Zt0S9fWthSiRKGdaDxj7w5w8yzt8FT+OyNYB0L7 -dzW3q/Ir+RNeoU/4JSqmFf0aaIRNdcUMEzU7iKZ5x93k6gtucQ0vennOuj9rD9Hl -njZce2odmC91AmYjVCKHK71eBHbEYqzr+Ew9OdJ33kE+QnlS/fUOA7Exw8844Crr -0Y11W7ZwxPIcNVc1nSCplUWyS046Cchg+G3W1reUe+Wo3vSfHd1EaZxSKfFadhlK -Z+4aHy/p7NYjm+IeiG+xy3SaBMdExxMAdoTYiksCAwEAAaAAMA0GCSqGSIb3DQEB -BQUAA4ICAQA0r0NkT3dmqNdUlXTMzQ7V0pvGAwhig3/wVRQM2gvBDRymsWi4YuWm -8WN4DT7xSxLcLaSqaYANapuDQQ3OJdiZv8KCGfKFRe3l47QpfTN8Y2w4WJZXVCKQ -2hf85HcgCLTsAjBjCr+/kmnC7Qu2hk8uVMs0E8sGm4TJO99FbwIxmyxSUVEkREt9 -3I0hg44ic8LJtaBp5V1lN8rsWOi739i9AiAC3bFqoeUSXerGjxaoajkhQbTcM/gj -V7swU/lE5TGqFOOZo/bsJRwWrpaI8BpI76SoQlAwUopGlDE7+mOI+/Ldn6Yyck5Z -MriXtBTp67DmLu8MkNSfld0ssGtnReRTY+19H4r38yIqAVB+SrCk/S1O40uSE8jy -XlQdUsnIjcC0n133HjFu3V8+rRU/R1Snw4NrZT5QN5m56I1ZZ148JXLXkWG3g8SA -E9UJi0XxOgCLZVJctNsla4u2R+NJlAxAc46qu2c2ZfC2VaDiTkHN+DtkNlgPTH5m -kEkTmJQZwgT+68J3Qzykty92iFA8mwTUmOLD/SburoKAdxfcxnVzDu60ribkzxKL -mQTRlmmVhsFpI7Gb9MH+B2rlfSN2AjHR/obKf9KChjrKHvE5ywUcUM1yygYkoJJe -3A7yBntylu78mCDeawsSQDzCT95t1evGPVEkFGiOgXRPaQ2XoaHVhw== ------END CERTIFICATE REQUEST----- diff --git a/cert/composer.key b/cert/composer.key deleted file mode 100644 index bb59541..0000000 --- a/cert/composer.key +++ /dev/null @@ -1,51 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -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 ------END RSA PRIVATE KEY----- diff --git a/cert/README.cert b/cert/old/README.cert similarity index 100% rename from cert/README.cert rename to cert/old/README.cert diff --git a/config/initializers/ssl_config.rb b/config/initializers/ssl_config.rb index 1f601c5..9044b8d 100644 --- a/config/initializers/ssl_config.rb +++ b/config/initializers/ssl_config.rb @@ -1,12 +1,16 @@ #contains constants for certificate used for SSL -SERVER_KEY_PATH_ = "cert/composer.key" -SERVER_CERT_PATH_ = "cert/composer.crt" - -CLIENT_KEY_PATH = "cert/client.key" -CLIENT_CERT_PATH = "cert/client.crt" - +#SERVER_KEY_PATH_ = "cert/composer.key" +#SERVER_CERT_PATH_ = "cert/composer.crt" +SERVER_KEY_PATH_ = "cert/ca/LeadLab_root_cert_TEST.pem" +SERVER_CERT_PATH_ = "cert/ca/LeadLab_root_cert_TEST.pem" +# +#CLIENT_KEY_PATH = "cert/client.key" +#CLIENT_CERT_PATH = "cert/client.crt" +CLIENT_KEY_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" +CLIENT_CERT_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" +# SERVER_KEY = OpenSSL::PKey::RSA.new(File.open(SERVER_KEY_PATH_).read) SERVER_CERT = OpenSSL::X509::Certificate.new(File.open(SERVER_CERT_PATH_).read) - +# CLIENT_KEY = OpenSSL::PKey::RSA.new(File.open(CLIENT_KEY_PATH).read) CLIENT_CERT = OpenSSL::X509::Certificate.new(File.open(CLIENT_CERT_PATH).read) diff --git a/script/rails b/script/rails index 0913237..fc77b24 100755 --- a/script/rails +++ b/script/rails @@ -9,9 +9,13 @@ require 'webrick/https' #override default option of server to use SSL -SERVER_CERT_PATH = "cert/composer.crt" -SERVER_KEY_PATH = "cert/composer.key" -CA_CERT_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" +#SERVER_CERT_PATH = "cert/composer.crt" +#SERVER_KEY_PATH = "cert/composer.key" +CA_CERT_PATH ="cert/ca/LeadLab_root_cert_TEST.pem" +SERVER_CERT_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" +SERVER_KEY_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" +CLIENT_CERT_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" +CLIENT_KEY_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" SERVER_KEY = File.open(SERVER_KEY_PATH) SERVER_CERT = File.open(SERVER_CERT_PATH) From e04b7a774bab32b4fefc820aa212d8e0a2ca2e0d Mon Sep 17 00:00:00 2001 From: Jeremy Ho Date: Tue, 3 Sep 2013 13:28:55 -0700 Subject: [PATCH 049/117] Tweaked runme.sh Signed-off-by: Jeremy Ho --- runme.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/runme.sh b/runme.sh index 101ffb0..0431fe7 100755 --- a/runme.sh +++ b/runme.sh @@ -1,8 +1,14 @@ #!/bin/sh # To start query-composer + +echo "Installing Dependencies" bundle install +echo "Starting Delayed Job" bundle exec script/delayed_job start +echo "Starting Composer" bundle exec rails server -p 3002 +echo "Stopping Delayed Job" +bundle exec script/delayed_job stop # # To start query-gateway # In a second terminal, change directory to the query-gateway directory From 3b47563cdcc4a143d1464085d2673f2cf3dac298 Mon Sep 17 00:00:00 2001 From: Jeremy Ho Date: Tue, 3 Sep 2013 16:07:16 -0700 Subject: [PATCH 050/117] Removed some duplicate variable warnings Signed-off-by: Jeremy Ho --- cert/README | 8 ++++---- config/initializers/ssl_config.rb | 4 ++-- script/rails | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/cert/README b/cert/README index b402b4d..2992b3d 100644 --- a/cert/README +++ b/cert/README @@ -1,5 +1,5 @@ -# Change into the query-gateway root directory. Make a cert subdirectory. -cd $HOME/query-gateway && mkdir cert && cd cert +# Change into the query-composer root directory. Make a cert subdirectory. +cd $HOME/query-composer && mkdir cert && cd cert # # Generate a self-signed certificate. You need to answer some questions. # Most of them can be answered arbitrarily but it is important that the @@ -41,10 +41,10 @@ mkdir ca && cp server.pem ca/LeadLab_root_cert_TEST.pem && rm server.pem # Create a symbolic link from the self-signed certicate to a file in # /etc/ssl/certs with name matching the hash with suffix '.0'. # -# /etc/ssl/certs/962a3564.0 ->/home/vagrant/query-gateway/cert/ca/LeadLab_root_cert_TEST.pem +# /etc/ssl/certs/962a3564.0 ->/home/vagrant/query-composer/cert/ca/LeadLab_root_cert_TEST.pem # # For this particular self-signed certificate's hash, I did this: -# $ sudo ln -s /home/vagrant/query-gateway/cert/ca/LeadLab_root_cert_TEST.pem /etc/ssl/certs/962a3564.0 +# $ sudo ln -s /home/vagrant/query-composer/cert/ca/LeadLab_root_cert_TEST.pem /etc/ssl/certs/962a3564.0 # # To start up the SSL secured version of query-gateway on port 3002 use: # $ bundle exec script/delayed_job start diff --git a/config/initializers/ssl_config.rb b/config/initializers/ssl_config.rb index 9044b8d..6e177a1 100644 --- a/config/initializers/ssl_config.rb +++ b/config/initializers/ssl_config.rb @@ -9,8 +9,8 @@ CLIENT_KEY_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" CLIENT_CERT_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" # -SERVER_KEY = OpenSSL::PKey::RSA.new(File.open(SERVER_KEY_PATH_).read) -SERVER_CERT = OpenSSL::X509::Certificate.new(File.open(SERVER_CERT_PATH_).read) +SERVER_KEY_ = OpenSSL::PKey::RSA.new(File.open(SERVER_KEY_PATH_).read) +SERVER_CERT_ = OpenSSL::X509::Certificate.new(File.open(SERVER_CERT_PATH_).read) # CLIENT_KEY = OpenSSL::PKey::RSA.new(File.open(CLIENT_KEY_PATH).read) CLIENT_CERT = OpenSSL::X509::Certificate.new(File.open(CLIENT_CERT_PATH).read) diff --git a/script/rails b/script/rails index fc77b24..dac2f6c 100755 --- a/script/rails +++ b/script/rails @@ -14,8 +14,8 @@ require 'webrick/https' CA_CERT_PATH ="cert/ca/LeadLab_root_cert_TEST.pem" SERVER_CERT_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" SERVER_KEY_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" -CLIENT_CERT_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" -CLIENT_KEY_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" +#CLIENT_CERT_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" +#CLIENT_KEY_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" SERVER_KEY = File.open(SERVER_KEY_PATH) SERVER_CERT = File.open(SERVER_CERT_PATH) From e8e277e7dcbc5693467a96b7fe46cfb275444654 Mon Sep 17 00:00:00 2001 From: Jeremy Ho Date: Tue, 3 Sep 2013 16:17:05 -0700 Subject: [PATCH 051/117] Indentation cleanup Signed-off-by: Jeremy Ho --- script/rails | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/script/rails b/script/rails index dac2f6c..3d5799f 100755 --- a/script/rails +++ b/script/rails @@ -11,8 +11,8 @@ require 'webrick/https' #override default option of server to use SSL #SERVER_CERT_PATH = "cert/composer.crt" #SERVER_KEY_PATH = "cert/composer.key" -CA_CERT_PATH ="cert/ca/LeadLab_root_cert_TEST.pem" -SERVER_CERT_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" +CA_CERT_PATH ="cert/ca/LeadLab_root_cert_TEST.pem" +SERVER_CERT_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" SERVER_KEY_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" #CLIENT_CERT_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" #CLIENT_KEY_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" @@ -21,20 +21,20 @@ SERVER_KEY = File.open(SERVER_KEY_PATH) SERVER_CERT = File.open(SERVER_CERT_PATH) module Rails - class Server < ::Rack::Server - def default_options - super.merge({ - :SSLEnable => true, - :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, - :SSLPrivateKey => OpenSSL::PKey::RSA.new(SERVER_KEY.read), - :SSLCertificate => OpenSSL::X509::Certificate.new(SERVER_CERT.read), - :SSLCACertificateFile => CA_CERT_PATH, - :SSLCertName => [["CN", WEBrick::Utils::getservername]], - }) - end - end + class Server < ::Rack::Server + def default_options + super.merge({ + :SSLEnable => true, + :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, + :SSLPrivateKey => OpenSSL::PKey::RSA.new(SERVER_KEY.read), + :SSLCertificate => OpenSSL::X509::Certificate.new(SERVER_CERT.read), + :SSLCACertificateFile => CA_CERT_PATH, + :SSLCertName => [["CN", WEBrick::Utils::getservername]], + }) + end + end end -APP_PATH = File.expand_path('../../config/application', __FILE__) -require File.expand_path('../../config/boot', __FILE__) +APP_PATH = File.expand_path('../../config/application', __FILE__) +require File.expand_path('../../config/boot', __FILE__) require 'rails/commands' From 08003bbfb00349c7647297ebfb3dc2281ae44b85 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Mon, 9 Sep 2013 13:17:40 -0700 Subject: [PATCH 052/117] Modify so ssl can be toggled on or off --- app/helpers/endpoints_helper.rb | 2 +- app/models/endpoint.rb | 2 +- app/models/result.rb | 4 ++-- config/initializers/ssl_config.rb | 2 ++ lib/gateway_utils.rb | 2 +- script/rails | 3 ++- 6 files changed, 9 insertions(+), 6 deletions(-) diff --git a/app/helpers/endpoints_helper.rb b/app/helpers/endpoints_helper.rb index a136ea4..34356ee 100755 --- a/app/helpers/endpoints_helper.rb +++ b/app/helpers/endpoints_helper.rb @@ -5,7 +5,7 @@ def fetch_endpoint_statuses url = endpoint.status_url begin #use ssl - response = Net::HTTP.start(url.host, url.port, :use_ssl => true, :key => CLIENT_KEY, :cert => CLIENT_CERT) do |http| + response = Net::HTTP.start(url.host, url.port, :use_ssl => USE_SSL, :key => CLIENT_KEY, :cert => CLIENT_CERT) do |http| headers = {} headers['Accept'] = 'application/atom+xml' http.get(url.path, headers) diff --git a/app/models/endpoint.rb b/app/models/endpoint.rb index ddff83d..720f514 100755 --- a/app/models/endpoint.rb +++ b/app/models/endpoint.rb @@ -37,7 +37,7 @@ def check check_time = Time.now #use ssl - response = Net::HTTP.start(url.host, url.port, :use_ssl => true, :key => CLIENT_KEY, :cert => CLIENT_CERT) do |http| + response = Net::HTTP.start(url.host, url.port, :use_ssl => USE_SSL, :key => CLIENT_KEY, :cert => CLIENT_CERT) do |http| headers = {} if last_check headers['If-Modified-Since'] = last_check.to_formatted_s(:rfc822) diff --git a/app/models/result.rb b/app/models/result.rb index d3acacd..b0bbd1f 100755 --- a/app/models/result.rb +++ b/app/models/result.rb @@ -31,7 +31,7 @@ def check url = URI.parse(query_url) #use ssl - response = Net::HTTP.start(url.host, url.port, :use_ssl => true, :key => CLIENT_KEY, :cert => CLIENT_CERT) do |http| + response = Net::HTTP.start(url.host, url.port, :use_ssl => USE_SSL, :key => CLIENT_KEY, :cert => CLIENT_CERT) do |http| http.get(url.path, 'If-Modified-Since' => updated_at.to_formatted_s(:rfc822), 'Accept' => 'application/json') end @@ -68,7 +68,7 @@ def check def fetch_result url = URI.parse(self.result_url) #use ssl - response = Net::HTTP.start(url.host, url.port, :use_ssl => true, :key => CLIENT_KEY, :cert => CLIENT_CERT) do |http| + response = Net::HTTP.start(url.host, url.port, :use_ssl => USE_SSL, :key => CLIENT_KEY, :cert => CLIENT_CERT) do |http| http.get(url.path, 'Accept' => 'application/json') end self.value = JSON.parse(response.body) diff --git a/config/initializers/ssl_config.rb b/config/initializers/ssl_config.rb index 6e177a1..1abd6b7 100644 --- a/config/initializers/ssl_config.rb +++ b/config/initializers/ssl_config.rb @@ -1,4 +1,6 @@ #contains constants for certificate used for SSL +# +USE_SSL = true #SERVER_KEY_PATH_ = "cert/composer.key" #SERVER_CERT_PATH_ = "cert/composer.crt" SERVER_KEY_PATH_ = "cert/ca/LeadLab_root_cert_TEST.pem" diff --git a/lib/gateway_utils.rb b/lib/gateway_utils.rb index a73b7ec..13b4c22 100644 --- a/lib/gateway_utils.rb +++ b/lib/gateway_utils.rb @@ -66,7 +66,7 @@ def submit(endpoint) request = query_request(full_map(query), full_reduce(query), build_library_functions(query), query.filter, query_url) begin #use ssl - Net::HTTP.start(query_url.host, query_url.port, :use_ssl => true, :key => CLIENT_KEY, :cert => CLIENT_CERT) do |http| + Net::HTTP.start(query_url.host, query_url.port, :use_ssl => USE_SSL, :key => CLIENT_KEY, :cert => CLIENT_CERT) do |http| response = http.request(request) if response.code == '201' query_url = response['Location'] diff --git a/script/rails b/script/rails index 3d5799f..23b4628 100755 --- a/script/rails +++ b/script/rails @@ -19,12 +19,13 @@ SERVER_KEY_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" SERVER_KEY = File.open(SERVER_KEY_PATH) SERVER_CERT = File.open(SERVER_CERT_PATH) +USE_SSL = true module Rails class Server < ::Rack::Server def default_options super.merge({ - :SSLEnable => true, + :SSLEnable => USE_SSL, :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, :SSLPrivateKey => OpenSSL::PKey::RSA.new(SERVER_KEY.read), :SSLCertificate => OpenSSL::X509::Certificate.new(SERVER_CERT.read), From 72b0ae525411acc99946700e8299bb221e701522 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Wed, 11 Sep 2013 10:32:11 -0700 Subject: [PATCH 053/117] Refactor ssl config --- config/environment.rb | 3 ++- config/initializers/ssl_config.rb | 38 ++++++++++++++++------------- config/ssl_config.rb | 40 +++++++++++++++++++++++++++++++ script/rails | 17 ++++++------- tmp/pids/.gitkeep | 0 5 files changed, 70 insertions(+), 28 deletions(-) create mode 100644 config/ssl_config.rb create mode 100644 tmp/pids/.gitkeep diff --git a/config/environment.rb b/config/environment.rb index e2b79db..11ac8fb 100755 --- a/config/environment.rb +++ b/config/environment.rb @@ -1,5 +1,6 @@ # Load the rails application require File.expand_path('../application', __FILE__) +require File.expand_path('../../config/ssl_config', __FILE__) # Initialize the rails application QueryComposer::Application.initialize! @@ -16,4 +17,4 @@ ActionMailer::Base.default_url_options = { :host => "localhost", # TODO: This should be localhost in test.rb but a real host for production env :port => 3000 -} \ No newline at end of file +} diff --git a/config/initializers/ssl_config.rb b/config/initializers/ssl_config.rb index 1abd6b7..123ecbe 100644 --- a/config/initializers/ssl_config.rb +++ b/config/initializers/ssl_config.rb @@ -1,18 +1,22 @@ -#contains constants for certificate used for SSL +include SslConfig + +#sets constants for certificate used for SSL # -USE_SSL = true -#SERVER_KEY_PATH_ = "cert/composer.key" -#SERVER_CERT_PATH_ = "cert/composer.crt" -SERVER_KEY_PATH_ = "cert/ca/LeadLab_root_cert_TEST.pem" -SERVER_CERT_PATH_ = "cert/ca/LeadLab_root_cert_TEST.pem" -# -#CLIENT_KEY_PATH = "cert/client.key" -#CLIENT_CERT_PATH = "cert/client.crt" -CLIENT_KEY_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" -CLIENT_CERT_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" -# -SERVER_KEY_ = OpenSSL::PKey::RSA.new(File.open(SERVER_KEY_PATH_).read) -SERVER_CERT_ = OpenSSL::X509::Certificate.new(File.open(SERVER_CERT_PATH_).read) -# -CLIENT_KEY = OpenSSL::PKey::RSA.new(File.open(CLIENT_KEY_PATH).read) -CLIENT_CERT = OpenSSL::X509::Certificate.new(File.open(CLIENT_CERT_PATH).read) +#if !USE_SSL + #USE_SSL = SslConfig::getUseSsl #USE_SSL #true + #SERVER_KEY_PATH_ = "cert/composer.key" + #SERVER_CERT_PATH_ = "cert/composer.crt" + #SERVER_KEY_PATH_ = SslConfig::getServerKeyPath #"cert/ca/LeadLab_root_cert_TEST.pem" + #SERVER_CERT_PATH_ = SslConfig::getServerCertPath #"cert/ca/LeadLab_root_cert_TEST.pem" + # + #CLIENT_KEY_PATH = "cert/client.key" + #CLIENT_CERT_PATH = "cert/client.crt" + #CLIENT_KEY_PATH = SslConfig::getClientKeyPath #"cert/ca/LeadLab_root_cert_TEST.pem" + #CLIENT_CERT_PATH = SslConfig::getClientCertPath #"cert/ca/LeadLab_root_cert_TEST.pem" + # + #SERVER_KEY_ = OpenSSL::PKey::RSA.new(File.open(SERVER_KEY_PATH_).read) + #SERVER_CERT_ = OpenSSL::X509::Certificate.new(File.open(SERVER_CERT_PATH_).read) + # + #CLIENT_KEY = OpenSSL::PKey::RSA.new(File.open(CLIENT_KEY_PATH).read) + #CLIENT_CERT = OpenSSL::X509::Certificate.new(File.open(CLIENT_CERT_PATH).read) +#end diff --git a/config/ssl_config.rb b/config/ssl_config.rb new file mode 100644 index 0000000..ffd8fdc --- /dev/null +++ b/config/ssl_config.rb @@ -0,0 +1,40 @@ +module SslConfig + #contains constants for certificate used for SSL + # + USE_SSL = true + #SERVER_KEY_PATH_ = "cert/composer.key" + #SERVER_CERT_PATH_ = "cert/composer.crt" + SERVER_KEY_PATH_ = "cert/ca/LeadLab_root_cert_TEST.pem" + SERVER_CERT_PATH_ = "cert/ca/LeadLab_root_cert_TEST.pem" + # + #CLIENT_KEY_PATH = "cert/client.key" + #CLIENT_CERT_PATH = "cert/client.crt" + CLIENT_KEY_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" + CLIENT_CERT_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" + # + #SERVER_KEY_ = OpenSSL::PKey::RSA.new(File.open(SERVER_KEY_PATH_).read) + #SERVER_CERT_ = OpenSSL::X509::Certificate.new(File.open(SERVER_CERT_PATH_).read) + # + CLIENT_KEY = OpenSSL::PKey::RSA.new(File.open(CLIENT_KEY_PATH).read) + CLIENT_CERT = OpenSSL::X509::Certificate.new(File.open(CLIENT_CERT_PATH).read) + + def self.getUseSsl + USE_SSL + end + + def self.getServerKeyPath + SERVER_KEY_PATH_ + end + + def self.getServerCertPath + SERVER_CERT_PATH_ + end + + def self.getClientKeyPath + CLIENT_KEY_PATH + end + + def self.getClientCertPath + CLIENT_CERT_PATH + end +end \ No newline at end of file diff --git a/script/rails b/script/rails index 23b4628..3e0ac98 100755 --- a/script/rails +++ b/script/rails @@ -6,20 +6,17 @@ require 'rails/commands/server' require 'rack' require 'webrick' require 'webrick/https' - +require File.expand_path('../../config/ssl_config', __FILE__) #override default option of server to use SSL -#SERVER_CERT_PATH = "cert/composer.crt" -#SERVER_KEY_PATH = "cert/composer.key" -CA_CERT_PATH ="cert/ca/LeadLab_root_cert_TEST.pem" -SERVER_CERT_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" -SERVER_KEY_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" -#CLIENT_CERT_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" -#CLIENT_KEY_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" - +USE_SSL = SslConfig::getUseSsl +CA_CERT_PATH =SslConfig::getServerKeyPath +# +SERVER_CERT_PATH = SslConfig::getServerCertPath +SERVER_KEY_PATH = SslConfig::getServerKeyPath +# SERVER_KEY = File.open(SERVER_KEY_PATH) SERVER_CERT = File.open(SERVER_CERT_PATH) -USE_SSL = true module Rails class Server < ::Rack::Server diff --git a/tmp/pids/.gitkeep b/tmp/pids/.gitkeep new file mode 100644 index 0000000..e69de29 From 63af1ffddf62312ea06ac4e473cd9cf6ce84828c Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Wed, 11 Sep 2013 16:04:59 -0700 Subject: [PATCH 054/117] Fixed unit tests so they work with and without ssl --- config/ssl_config.rb | 2 +- test/factories/factory.rb | 10 ++++- test/fixtures/query_feed_no_ssl.xml | 46 ++++++++++++++++++++ test/functional/endpoints_controller_test.rb | 4 +- test/functional/queries_controller_test.rb | 10 ++--- test/unit/endpoint_cron_test.rb | 4 +- test/unit/endpoint_test.rb | 17 +++++--- test/unit/execution_test.rb | 12 ++--- test/unit/result_test.rb | 23 ++++++---- 9 files changed, 96 insertions(+), 32 deletions(-) create mode 100644 test/fixtures/query_feed_no_ssl.xml diff --git a/config/ssl_config.rb b/config/ssl_config.rb index ffd8fdc..058f249 100644 --- a/config/ssl_config.rb +++ b/config/ssl_config.rb @@ -37,4 +37,4 @@ def self.getClientKeyPath def self.getClientCertPath CLIENT_CERT_PATH end -end \ No newline at end of file +end diff --git a/test/factories/factory.rb b/test/factories/factory.rb index 325e850..427b8f8 100755 --- a/test/factories/factory.rb +++ b/test/factories/factory.rb @@ -1,5 +1,11 @@ require 'factory_girl' +if SslConfig::getUseSsl + HTTP_PROTO='https' +else + HTTP_PROTO='http' +end + # ========== # = USERS = # ========== @@ -190,7 +196,7 @@ FactoryGirl.define do factory :endpoint do |e| e.sequence(:name) {|n| "Endpoint#{n}"} - e.base_url 'https://127.0.0.1:3001' + e.base_url HTTP_PROTO+'://127.0.0.1:3001' end end @@ -272,7 +278,7 @@ r.value nil r.result_url nil r.status Result::QUEUED - r.query_url 'https://localhost:3000/queries/4e4c08b5431a5f5dc1000001' + r.query_url HTTP_PROTO+'://localhost:3000/queries/4e4c08b5431a5f5dc1000001' r.created_at Time.new(2011, 1, 1) r.updated_at Time.new(2011, 1, 1) end diff --git a/test/fixtures/query_feed_no_ssl.xml b/test/fixtures/query_feed_no_ssl.xml new file mode 100644 index 0000000..e2383aa --- /dev/null +++ b/test/fixtures/query_feed_no_ssl.xml @@ -0,0 +1,46 @@ + + + Distributed Queries + + 2011-08-17T14:30:19-04:00 + + hQuery Gateway + + http://localhost:3000/queries + + Query Result + + + http://localhost:3000/queries/4e4c08b5431a5f5dc1000001 + Query Result + + 2011-08-17T14:30:13-04:00 + + 2011-08-17T14:30:19-04:00 + + + + + + http://localhost:3000/queries/4e4c08b5431a5f5dc1000001 + 2011-08-17T14:30:19-04:00 + + + Query Result + + + http://localhost:3000/queries/4e4c0738431a5f5d14000001 + Query Result + + 2011-08-17T14:23:52-04:00 + + 2011-08-17T14:23:55-04:00 + + + + + + http://localhost:3000/queries/4e4c0738431a5f5d14000001 + 2011-08-17T14:23:55-04:00 + + \ No newline at end of file diff --git a/test/functional/endpoints_controller_test.rb b/test/functional/endpoints_controller_test.rb index 99ac1cf..a2f3d2b 100755 --- a/test/functional/endpoints_controller_test.rb +++ b/test/functional/endpoints_controller_test.rb @@ -94,7 +94,7 @@ class EndpointsControllerTest < ActionController::TestCase end test "should refresh endpoint statuses" do - FakeWeb.register_uri(:get, "https://127.0.0.1:3001/queries", :body => + FakeWeb.register_uri(:get, HTTP_PROTO+"://127.0.0.1:3001/queries", :body => %{ Distributed Queries @@ -114,7 +114,7 @@ class EndpointsControllerTest < ActionController::TestCase test "should gracefully refresh downed endpoint status" do Endpoint.all.each do |endpoint| - endpoint.base_url = "https://something.totally.invalid:9999" + endpoint.base_url = HTTP_PROTO+"://something.totally.invalid:9999" endpoint.save! end get :refresh_endpoint_statuses diff --git a/test/functional/queries_controller_test.rb b/test/functional/queries_controller_test.rb index 113d944..2a9f595 100755 --- a/test/functional/queries_controller_test.rb +++ b/test/functional/queries_controller_test.rb @@ -15,7 +15,7 @@ class QueriesControllerTest < ActionController::TestCase @endpoints_for_execution = [] @endpoints_for_execution << FactoryGirl.create(:endpoint) - @endpoints_for_execution << FactoryGirl.create(:endpoint, base_url: 'https://127.0.0.1:3002') + @endpoints_for_execution << FactoryGirl.create(:endpoint, base_url: HTTP_PROTO+'://127.0.0.1:3002') @unattached_query = FactoryGirl.create(:query) @@ -131,7 +131,7 @@ class QueriesControllerTest < ActionController::TestCase test "should execute query with notification" do sign_in @user - FakeWeb.register_uri(:post, "https://127.0.0.1:3001/queries", :body => "FORCE ERROR") + FakeWeb.register_uri(:post, HTTP_PROTO+"://127.0.0.1:3001/queries", :body => "FORCE ERROR") query_from_db = Query.find(@ids[2]) endpoint_ids = [@endpoints_for_execution[0].id.to_s] @@ -161,7 +161,7 @@ class QueriesControllerTest < ActionController::TestCase test "should execute query without notification" do sign_in @user - FakeWeb.register_uri(:post, "https://127.0.0.1:3001/queries", :body => "FORCE ERROR") + FakeWeb.register_uri(:post, HTTP_PROTO+"://127.0.0.1:3001/queries", :body => "FORCE ERROR") query_from_db = Query.find(@ids[2]) endpoint_ids = [@endpoints_for_execution[0].id.to_s] @@ -249,7 +249,7 @@ class QueriesControllerTest < ActionController::TestCase test "should cancel endpoint results" do sign_in @user - FakeWeb.register_uri(:post, "https://127.0.0.1:3001/queries", :body => "{}", :status => ["304"], :location=>"https://localhost:3001/queries") + FakeWeb.register_uri(:post, HTTP_PROTO+"://127.0.0.1:3001/queries", :body => "{}", :status => ["304"], :location=>HTTP_PROTO+"://localhost:3001/queries") query_from_db = Query.find(@ids[2]) endpoint_ids = [@endpoints_for_execution[0].id.to_s] @@ -275,7 +275,7 @@ class QueriesControllerTest < ActionController::TestCase test "should cancel execution" do sign_in @user - FakeWeb.register_uri(:post, "https://127.0.0.1:3001/queries", :body => "{}", :status => ["304"], :location=>"https://localhost:3001/queries") + FakeWeb.register_uri(:post, HTTP_PROTO+"://127.0.0.1:3001/queries", :body => "{}", :status => ["304"], :location=>HTTP_PROTO+"://localhost:3001/queries") query_from_db = Query.find(@ids[2]) endpoint_ids = [@endpoints_for_execution[0].id.to_s] diff --git a/test/unit/endpoint_cron_test.rb b/test/unit/endpoint_cron_test.rb index 99add53..f20914b 100644 --- a/test/unit/endpoint_cron_test.rb +++ b/test/unit/endpoint_cron_test.rb @@ -17,9 +17,9 @@ class EndpointCronTest < ActiveSupport::TestCase job = Delayed::Job.enqueue payload_object: cronJob, run_at: 2.from_now - FakeWeb.register_uri(:get, "https://127.0.0.1:3001/queries", + FakeWeb.register_uri(:get, HTTP_PROTO+"://127.0.0.1:3001/queries", :body => File.read(File.expand_path('../../fixtures/query_feed.xml', __FILE__))) - FakeWeb.register_uri(:get, "https://localhost:3000/queries/4e4c08b5431a5f5dc1000001", + FakeWeb.register_uri(:get, HTTP_PROTO+"://localhost:3000/queries/4e4c08b5431a5f5dc1000001", :body => '{"status": "queued"}') endpoint = FactoryGirl.create(:endpoint) result = FactoryGirl.create(:result_waiting, endpoint: endpoint) diff --git a/test/unit/endpoint_test.rb b/test/unit/endpoint_test.rb index e9e0546..151280e 100755 --- a/test/unit/endpoint_test.rb +++ b/test/unit/endpoint_test.rb @@ -6,7 +6,7 @@ class EndpointTest < ActiveSupport::TestCase end test "monitoring queries that have not been modified" do - FakeWeb.register_uri(:get, "https://127.0.0.1:3001/queries", + FakeWeb.register_uri(:get, HTTP_PROTO+"://127.0.0.1:3001/queries", :status => [304, "Not Modified"]) endpoint = FactoryGirl.create(:endpoint) @@ -21,9 +21,14 @@ class EndpointTest < ActiveSupport::TestCase end test "monitoring queries that have changed" do - FakeWeb.register_uri(:get, "https://127.0.0.1:3001/queries", - :body => File.read(File.expand_path('../../fixtures/query_feed.xml', __FILE__))) - FakeWeb.register_uri(:get, "https://localhost:3000/queries/4e4c08b5431a5f5dc1000001", + if HTTP_PROTO == "https" + FakeWeb.register_uri(:get, HTTP_PROTO+"://127.0.0.1:3001/queries", + :body => File.read(File.expand_path('../../fixtures/query_feed.xml', __FILE__))) + else + FakeWeb.register_uri(:get, HTTP_PROTO+"://127.0.0.1:3001/queries", + :body => File.read(File.expand_path('../../fixtures/query_feed_no_ssl.xml', __FILE__))) + end + FakeWeb.register_uri(:get, HTTP_PROTO+"://localhost:3000/queries/4e4c08b5431a5f5dc1000001", :body => '{"status": "queued"}') endpoint = FactoryGirl.create(:endpoint) result = FactoryGirl.create(:result_waiting, endpoint: endpoint) @@ -41,7 +46,7 @@ class EndpointTest < ActiveSupport::TestCase end test "monitoring queries with incomprehensible responses" do - FakeWeb.register_uri(:get, "https://127.0.0.1:3001/queries", :body => 'bacon is delicious') + FakeWeb.register_uri(:get, HTTP_PROTO+"://127.0.0.1:3001/queries", :body => 'bacon is delicious') endpoint = FactoryGirl.create(:endpoint) endpoint.check assert_equal 2, endpoint.endpoint_logs.count @@ -59,7 +64,7 @@ class EndpointTest < ActiveSupport::TestCase end test "should gracefully handle errors in check" do - FakeWeb.register_uri(:get, "https://127.0.0.1:3001/queries", :exception => Net::HTTPError) + FakeWeb.register_uri(:get, HTTP_PROTO+"://127.0.0.1:3001/queries", :exception => Net::HTTPError) endpoint = FactoryGirl.create(:endpoint) endpoint.check assert_equal 1, endpoint.endpoint_logs.count diff --git a/test/unit/execution_test.rb b/test/unit/execution_test.rb index 0715af5..8dacf72 100644 --- a/test/unit/execution_test.rb +++ b/test/unit/execution_test.rb @@ -1,7 +1,9 @@ require 'test_helper' require 'webrick' require 'logger' + include GatewayUtils + class ExecutionTest < ActiveSupport::TestCase setup do @@ -44,9 +46,9 @@ class ExecutionTest < ActiveSupport::TestCase end test "query submission" do - FakeWeb.register_uri(:post, "https://127.0.0.1:3001/queries", :body => "Query Created", - :status => [201, "Created"], :location => "https://127.0.0.1:3001/query/1234") - FakeWeb.register_uri(:post, "https://127.0.0.1:3001/library_functions", :body => "yay", + FakeWeb.register_uri(:post, HTTP_PROTO+"://127.0.0.1:3001/queries", :body => "Query Created", + :status => [201, "Created"], :location => HTTP_PROTO+"://127.0.0.1:3001/query/1234") + FakeWeb.register_uri(:post, HTTP_PROTO+"://127.0.0.1:3001/library_functions", :body => "yay", :status => [200, "OK"]) user = FactoryGirl.create(:user) @@ -70,7 +72,7 @@ class ExecutionTest < ActiveSupport::TestCase result = query.last_execution.results[0] assert result - assert_equal "https://127.0.0.1:3001/query/1234", result.query_url + assert_equal HTTP_PROTO+"://127.0.0.1:3001/query/1234", result.query_url assert_equal Result::QUEUED, result.status end @@ -80,7 +82,7 @@ class ExecutionTest < ActiveSupport::TestCase test "query should log failures for endpoint on failure" do - FakeWeb.register_uri(:post, "https://127.0.0.1:3001/queries", :status => ["500", "Internal Server Error"]) + FakeWeb.register_uri(:post, HTTP_PROTO+"://127.0.0.1:3001/queries", :status => ["500", "Internal Server Error"]) query = Query.find(@user_with_functions.queries[3].id) endpoint = FactoryGirl.create(:endpoint) diff --git a/test/unit/result_test.rb b/test/unit/result_test.rb index 08eec3a..2efd38a 100644 --- a/test/unit/result_test.rb +++ b/test/unit/result_test.rb @@ -1,14 +1,19 @@ require 'test_helper' +#HTTP_PROTO='http' +#if SslConfig::getUseSsl +# HTTP_PROTO='https' +#end + class ResultTest < ActiveSupport::TestCase setup do dump_database end test "check a result that has changed" do - FakeWeb.register_uri(:get, "https://localhost:3000/queries/4e4c08b5431a5f5dc1000001", - :body => '{"status": "'+Result::COMPLETE+'", "result_url": "https://localhost/results/1234"}') - FakeWeb.register_uri(:get, "https://localhost/results/1234", + FakeWeb.register_uri(:get, HTTP_PROTO+"://localhost:3000/queries/4e4c08b5431a5f5dc1000001", + :body => '{"status": "'+Result::COMPLETE+'", "result_url": "'+HTTP_PROTO+'://localhost/results/1234"}') + FakeWeb.register_uri(:get, HTTP_PROTO+"://localhost/results/1234", :body => '{"foo": "bar"}') result = FactoryGirl.create(:result_waiting) @@ -21,18 +26,18 @@ class ResultTest < ActiveSupport::TestCase end test "fetch a result" do - FakeWeb.register_uri(:get, "https://localhost/results/1234", + FakeWeb.register_uri(:get, HTTP_PROTO+"://localhost/results/1234", :body => '{"foo": "bar"}') - result = FactoryGirl.create(:result, :result_url => "https://localhost/results/1234") + result = FactoryGirl.create(:result, :result_url => HTTP_PROTO+"://localhost/results/1234") result.fetch_result assert_equal Result::COMPLETE, result.status assert_equal 'bar', result.value['foo'] end test "checking a result" do - FakeWeb.register_uri(:get, "https://localhost:3000/queries/4e4c08b5431a5f5dc1000001", - :body => '{"status": "complete", "result_url": "https://localhost/results/1234"}') - FakeWeb.register_uri(:get, "https://localhost/results/1234", + FakeWeb.register_uri(:get, HTTP_PROTO+"://localhost:3000/queries/4e4c08b5431a5f5dc1000001", + :body => '{"status": "complete", "result_url": "'+HTTP_PROTO+'://localhost/results/1234"}') + FakeWeb.register_uri(:get, HTTP_PROTO+"://localhost/results/1234", :body => '{"foo": "bar", "status": "complete"}') result = FactoryGirl.create(:result_waiting) result.check @@ -41,7 +46,7 @@ class ResultTest < ActiveSupport::TestCase end test "checking a result where there is an error" do - FakeWeb.register_uri(:get, "https://localhost:3000/queries/4e4c08b5431a5f5dc1000001", + FakeWeb.register_uri(:get, HTTP_PROTO+"://localhost:3000/queries/4e4c08b5431a5f5dc1000001", :body => '{"status": "failed", "error_message": "game over, man!"}') result = FactoryGirl.create(:result_waiting) result.check From 34f7a055687365da8759225dd2f2044518e54444 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Wed, 11 Sep 2013 16:07:48 -0700 Subject: [PATCH 055/117] Changed default to no ssl --- config/ssl_config.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/ssl_config.rb b/config/ssl_config.rb index 058f249..4fc3d92 100644 --- a/config/ssl_config.rb +++ b/config/ssl_config.rb @@ -1,7 +1,7 @@ module SslConfig #contains constants for certificate used for SSL # - USE_SSL = true + USE_SSL = false #SERVER_KEY_PATH_ = "cert/composer.key" #SERVER_CERT_PATH_ = "cert/composer.crt" SERVER_KEY_PATH_ = "cert/ca/LeadLab_root_cert_TEST.pem" From 6cfc2bf5011fbd5439890ac0faeaa3de54bc0312 Mon Sep 17 00:00:00 2001 From: Jeremy Ho Date: Fri, 13 Sep 2013 11:00:23 -0700 Subject: [PATCH 056/117] Update some documentation links and typos Signed-off-by: Jeremy Ho --- README.md | 10 +++++----- runme.sh | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index fe7bfc1..2e95936 100755 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Dependencies * Webrick = 1.3.1 added to eliminate nuisance messages in log regarding: WARN Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true - Based on information gotten from http://stackoverflow.com/questions/9612618/warn-could-not-determine-content-length-of-response-body-set-content-length-of adding Webrick explicitely to Gemfile (even though it is the version already being used) resolves the problem. + Based on information gotten from http://stackoverflow.com/questions/9612618/warn-could-not-determine-content-length-of-response-body-set-content-length-of adding Webrick explicitly to Gemfile (even though it is the version already being used) resolves the problem. Dependencies on old gems (to be remedied in future) --------------------------------------------------- @@ -44,7 +44,7 @@ To eliminate these warnings from Firefox, the following configuration change can Install Instructions -------------------- - Once you get a copy of the hQuery code from GitHub (http://github.com/hQuery), + Once you get a copy of the hQuery code from GitHub (https://github.com/scoophealth), these are step-by-step instructions to get hQuery installed on your local machine. These steps are the steps required to get both the Query Composer and Query Gateway up and running @@ -147,12 +147,12 @@ d) Install the ruby dev kit, also available at [http://rubyinstaller.org/downloa ruby dk.rb init - 5. Veryify the new file config.yml contains a reference to Ruby192 + 5. Verify the new file config.yml contains a reference to Ruby192 6. run ruby dk.rb install - 7. Next you will want to run pi.bat in the postinstall directory + 7. Next you will want to run pi.bat in the post install directory ###1j. JRuby @@ -183,7 +183,7 @@ command in the terminal once ruby has been installed. ###Getting the latest released version -See: [http://github.com/hquery/](http://github.com/hquery/) +See: [https://github.com/scoophealth](https://github.com/scoophealth) Getting the latest source code (skip to "Installing Mongo" if you are using the latest stable release) diff --git a/runme.sh b/runme.sh index 0431fe7..cbf24a7 100755 --- a/runme.sh +++ b/runme.sh @@ -1,5 +1,5 @@ #!/bin/sh -# To start query-composer +# Toggle the USE_SSL variable in config/ssl_config.rb to enable/disable SSL support echo "Installing Dependencies" bundle install @@ -9,7 +9,7 @@ echo "Starting Composer" bundle exec rails server -p 3002 echo "Stopping Delayed Job" bundle exec script/delayed_job stop -# + # To start query-gateway # In a second terminal, change directory to the query-gateway directory # and run: From f622e07e149b1066c7919b00973ace2e69e57a42 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Fri, 4 Oct 2013 14:14:24 -0700 Subject: [PATCH 057/117] Independent configuration of SSL usage for web access to hub and hub access to gateways --- app/helpers/endpoints_helper.rb | 2 +- app/models/endpoint.rb | 2 +- app/models/result.rb | 4 ++-- config/initializers/ssl_config.rb | 21 ------------------ config/ssl_config.rb | 11 +++++++--- lib/gateway_utils.rb | 2 +- runme.sh | 5 ++++- script/rails | 4 ++-- test/factories/factory.rb | 18 ++++++++++----- test/fixtures/query_feed_no_ssl.xml | 2 +- test/functional/endpoints_controller_test.rb | 18 +++++++++++++-- test/functional/queries_controller_test.rb | 10 ++++----- test/unit/endpoint_cron_test.rb | 4 ++-- test/unit/endpoint_test.rb | 14 ++++++------ test/unit/execution_test.rb | 12 +++++----- test/unit/result_test.rb | 23 ++++++++------------ 16 files changed, 78 insertions(+), 74 deletions(-) diff --git a/app/helpers/endpoints_helper.rb b/app/helpers/endpoints_helper.rb index 34356ee..d886b68 100755 --- a/app/helpers/endpoints_helper.rb +++ b/app/helpers/endpoints_helper.rb @@ -5,7 +5,7 @@ def fetch_endpoint_statuses url = endpoint.status_url begin #use ssl - response = Net::HTTP.start(url.host, url.port, :use_ssl => USE_SSL, :key => CLIENT_KEY, :cert => CLIENT_CERT) do |http| + response = Net::HTTP.start(url.host, url.port, :use_ssl => USE_SSL_CLIENT, :key => CLIENT_KEY, :cert => CLIENT_CERT) do |http| headers = {} headers['Accept'] = 'application/atom+xml' http.get(url.path, headers) diff --git a/app/models/endpoint.rb b/app/models/endpoint.rb index 720f514..e84906b 100755 --- a/app/models/endpoint.rb +++ b/app/models/endpoint.rb @@ -37,7 +37,7 @@ def check check_time = Time.now #use ssl - response = Net::HTTP.start(url.host, url.port, :use_ssl => USE_SSL, :key => CLIENT_KEY, :cert => CLIENT_CERT) do |http| + response = Net::HTTP.start(url.host, url.port, :use_ssl => USE_SSL_CLIENT, :key => CLIENT_KEY, :cert => CLIENT_CERT) do |http| headers = {} if last_check headers['If-Modified-Since'] = last_check.to_formatted_s(:rfc822) diff --git a/app/models/result.rb b/app/models/result.rb index b0bbd1f..e589194 100755 --- a/app/models/result.rb +++ b/app/models/result.rb @@ -31,7 +31,7 @@ def check url = URI.parse(query_url) #use ssl - response = Net::HTTP.start(url.host, url.port, :use_ssl => USE_SSL, :key => CLIENT_KEY, :cert => CLIENT_CERT) do |http| + response = Net::HTTP.start(url.host, url.port, :use_ssl => USE_SSL_CLIENT, :key => CLIENT_KEY, :cert => CLIENT_CERT) do |http| http.get(url.path, 'If-Modified-Since' => updated_at.to_formatted_s(:rfc822), 'Accept' => 'application/json') end @@ -68,7 +68,7 @@ def check def fetch_result url = URI.parse(self.result_url) #use ssl - response = Net::HTTP.start(url.host, url.port, :use_ssl => USE_SSL, :key => CLIENT_KEY, :cert => CLIENT_CERT) do |http| + response = Net::HTTP.start(url.host, url.port, :use_ssl => USE_SSL_CLIENT, :key => CLIENT_KEY, :cert => CLIENT_CERT) do |http| http.get(url.path, 'Accept' => 'application/json') end self.value = JSON.parse(response.body) diff --git a/config/initializers/ssl_config.rb b/config/initializers/ssl_config.rb index 123ecbe..3339c37 100644 --- a/config/initializers/ssl_config.rb +++ b/config/initializers/ssl_config.rb @@ -1,22 +1 @@ include SslConfig - -#sets constants for certificate used for SSL -# -#if !USE_SSL - #USE_SSL = SslConfig::getUseSsl #USE_SSL #true - #SERVER_KEY_PATH_ = "cert/composer.key" - #SERVER_CERT_PATH_ = "cert/composer.crt" - #SERVER_KEY_PATH_ = SslConfig::getServerKeyPath #"cert/ca/LeadLab_root_cert_TEST.pem" - #SERVER_CERT_PATH_ = SslConfig::getServerCertPath #"cert/ca/LeadLab_root_cert_TEST.pem" - # - #CLIENT_KEY_PATH = "cert/client.key" - #CLIENT_CERT_PATH = "cert/client.crt" - #CLIENT_KEY_PATH = SslConfig::getClientKeyPath #"cert/ca/LeadLab_root_cert_TEST.pem" - #CLIENT_CERT_PATH = SslConfig::getClientCertPath #"cert/ca/LeadLab_root_cert_TEST.pem" - # - #SERVER_KEY_ = OpenSSL::PKey::RSA.new(File.open(SERVER_KEY_PATH_).read) - #SERVER_CERT_ = OpenSSL::X509::Certificate.new(File.open(SERVER_CERT_PATH_).read) - # - #CLIENT_KEY = OpenSSL::PKey::RSA.new(File.open(CLIENT_KEY_PATH).read) - #CLIENT_CERT = OpenSSL::X509::Certificate.new(File.open(CLIENT_CERT_PATH).read) -#end diff --git a/config/ssl_config.rb b/config/ssl_config.rb index 4fc3d92..f6c784e 100644 --- a/config/ssl_config.rb +++ b/config/ssl_config.rb @@ -1,12 +1,13 @@ module SslConfig #contains constants for certificate used for SSL # - USE_SSL = false + USE_SSL_SERVER = true # encrypt browser access to hub #SERVER_KEY_PATH_ = "cert/composer.key" #SERVER_CERT_PATH_ = "cert/composer.crt" SERVER_KEY_PATH_ = "cert/ca/LeadLab_root_cert_TEST.pem" SERVER_CERT_PATH_ = "cert/ca/LeadLab_root_cert_TEST.pem" # + USE_SSL_CLIENT = false # don't use SSL to access endpoints #CLIENT_KEY_PATH = "cert/client.key" #CLIENT_CERT_PATH = "cert/client.crt" CLIENT_KEY_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" @@ -18,8 +19,12 @@ module SslConfig CLIENT_KEY = OpenSSL::PKey::RSA.new(File.open(CLIENT_KEY_PATH).read) CLIENT_CERT = OpenSSL::X509::Certificate.new(File.open(CLIENT_CERT_PATH).read) - def self.getUseSsl - USE_SSL + def self.getUseSslServer + USE_SSL_SERVER + end + + def self.getUseSslClient + USE_SSL_CLIENT end def self.getServerKeyPath diff --git a/lib/gateway_utils.rb b/lib/gateway_utils.rb index 13b4c22..efe306b 100644 --- a/lib/gateway_utils.rb +++ b/lib/gateway_utils.rb @@ -66,7 +66,7 @@ def submit(endpoint) request = query_request(full_map(query), full_reduce(query), build_library_functions(query), query.filter, query_url) begin #use ssl - Net::HTTP.start(query_url.host, query_url.port, :use_ssl => USE_SSL, :key => CLIENT_KEY, :cert => CLIENT_CERT) do |http| + Net::HTTP.start(query_url.host, query_url.port, :use_ssl => USE_SSL_CLIENT, :key => CLIENT_KEY, :cert => CLIENT_CERT) do |http| response = http.request(request) if response.code == '201' query_url = response['Location'] diff --git a/runme.sh b/runme.sh index cbf24a7..4ab862e 100755 --- a/runme.sh +++ b/runme.sh @@ -1,5 +1,8 @@ #!/bin/sh -# Toggle the USE_SSL variable in config/ssl_config.rb to enable/disable SSL support +# Toggle the USE_SSL_SERVER and USE_SSL_CLEINT variables in config/ssl_config.rb to enable/disable SSL support. +# The variable USE_SSL_SERVER configures encrypted browser access to the query-composer. +# The variable USE_SSL_CLIENT configures whether traffic between composer and gateway is SSL encrypted. If it is +# being tunnelled through ssh, then is isn't necessary to also SSL encrypt it. echo "Installing Dependencies" bundle install diff --git a/script/rails b/script/rails index 3e0ac98..4e70626 100755 --- a/script/rails +++ b/script/rails @@ -9,7 +9,7 @@ require 'webrick/https' require File.expand_path('../../config/ssl_config', __FILE__) #override default option of server to use SSL -USE_SSL = SslConfig::getUseSsl +USE_SSL_SERVER = SslConfig::getUseSslServer CA_CERT_PATH =SslConfig::getServerKeyPath # SERVER_CERT_PATH = SslConfig::getServerCertPath @@ -22,7 +22,7 @@ module Rails class Server < ::Rack::Server def default_options super.merge({ - :SSLEnable => USE_SSL, + :SSLEnable => USE_SSL_SERVER, :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, :SSLPrivateKey => OpenSSL::PKey::RSA.new(SERVER_KEY.read), :SSLCertificate => OpenSSL::X509::Certificate.new(SERVER_CERT.read), diff --git a/test/factories/factory.rb b/test/factories/factory.rb index 427b8f8..2610152 100755 --- a/test/factories/factory.rb +++ b/test/factories/factory.rb @@ -1,9 +1,17 @@ require 'factory_girl' -if SslConfig::getUseSsl - HTTP_PROTO='https' +# server to hub web access +if SslConfig::getUseSslServer + HTTP_PROTO_SERVER='https' else - HTTP_PROTO='http' + HTTP_PROTO_SERVER='http' +end + +# hub is client of endpoints +if SslConfig::getUseSslClient + HTTP_PROTO_CLIENT='https' +else + HTTP_PROTO_CLIENT='http' end # ========== @@ -196,7 +204,7 @@ FactoryGirl.define do factory :endpoint do |e| e.sequence(:name) {|n| "Endpoint#{n}"} - e.base_url HTTP_PROTO+'://127.0.0.1:3001' + e.base_url HTTP_PROTO_CLIENT+'://127.0.0.1:3001' end end @@ -278,7 +286,7 @@ r.value nil r.result_url nil r.status Result::QUEUED - r.query_url HTTP_PROTO+'://localhost:3000/queries/4e4c08b5431a5f5dc1000001' + r.query_url HTTP_PROTO_CLIENT+'://localhost:3000/queries/4e4c08b5431a5f5dc1000001' r.created_at Time.new(2011, 1, 1) r.updated_at Time.new(2011, 1, 1) end diff --git a/test/fixtures/query_feed_no_ssl.xml b/test/fixtures/query_feed_no_ssl.xml index e2383aa..a0daa99 100644 --- a/test/fixtures/query_feed_no_ssl.xml +++ b/test/fixtures/query_feed_no_ssl.xml @@ -1,7 +1,7 @@ Distributed Queries - + 2011-08-17T14:30:19-04:00 hQuery Gateway diff --git a/test/functional/endpoints_controller_test.rb b/test/functional/endpoints_controller_test.rb index a2f3d2b..b7c32b5 100755 --- a/test/functional/endpoints_controller_test.rb +++ b/test/functional/endpoints_controller_test.rb @@ -94,7 +94,8 @@ class EndpointsControllerTest < ActionController::TestCase end test "should refresh endpoint statuses" do - FakeWeb.register_uri(:get, HTTP_PROTO+"://127.0.0.1:3001/queries", :body => + if SslConfig::getUseSslClient + FakeWeb.register_uri(:get, "https://127.0.0.1:3001/queries", :body => %{ Distributed Queries @@ -105,6 +106,19 @@ class EndpointsControllerTest < ActionController::TestCase https://localhost:3001/queries }) + else + FakeWeb.register_uri(:get, "http://127.0.0.1:3001/queries", :body => + %{ + + Distributed Queries + + 2011-12-15T16:02:13-05:00 + + hQuery Gateway + + http://localhost:3001/queries + }) + end get :refresh_endpoint_statuses assert_equal "GET", FakeWeb.last_request.method @@ -114,7 +128,7 @@ class EndpointsControllerTest < ActionController::TestCase test "should gracefully refresh downed endpoint status" do Endpoint.all.each do |endpoint| - endpoint.base_url = HTTP_PROTO+"://something.totally.invalid:9999" + endpoint.base_url = HTTP_PROTO_CLIENT+"://something.totally.invalid:9999" endpoint.save! end get :refresh_endpoint_statuses diff --git a/test/functional/queries_controller_test.rb b/test/functional/queries_controller_test.rb index 2a9f595..6b7c90b 100755 --- a/test/functional/queries_controller_test.rb +++ b/test/functional/queries_controller_test.rb @@ -15,7 +15,7 @@ class QueriesControllerTest < ActionController::TestCase @endpoints_for_execution = [] @endpoints_for_execution << FactoryGirl.create(:endpoint) - @endpoints_for_execution << FactoryGirl.create(:endpoint, base_url: HTTP_PROTO+'://127.0.0.1:3002') + @endpoints_for_execution << FactoryGirl.create(:endpoint, base_url: HTTP_PROTO_CLIENT+'://127.0.0.1:3002') @unattached_query = FactoryGirl.create(:query) @@ -131,7 +131,7 @@ class QueriesControllerTest < ActionController::TestCase test "should execute query with notification" do sign_in @user - FakeWeb.register_uri(:post, HTTP_PROTO+"://127.0.0.1:3001/queries", :body => "FORCE ERROR") + FakeWeb.register_uri(:post, HTTP_PROTO_CLIENT+"://127.0.0.1:3001/queries", :body => "FORCE ERROR") query_from_db = Query.find(@ids[2]) endpoint_ids = [@endpoints_for_execution[0].id.to_s] @@ -161,7 +161,7 @@ class QueriesControllerTest < ActionController::TestCase test "should execute query without notification" do sign_in @user - FakeWeb.register_uri(:post, HTTP_PROTO+"://127.0.0.1:3001/queries", :body => "FORCE ERROR") + FakeWeb.register_uri(:post, HTTP_PROTO_CLIENT+"://127.0.0.1:3001/queries", :body => "FORCE ERROR") query_from_db = Query.find(@ids[2]) endpoint_ids = [@endpoints_for_execution[0].id.to_s] @@ -249,7 +249,7 @@ class QueriesControllerTest < ActionController::TestCase test "should cancel endpoint results" do sign_in @user - FakeWeb.register_uri(:post, HTTP_PROTO+"://127.0.0.1:3001/queries", :body => "{}", :status => ["304"], :location=>HTTP_PROTO+"://localhost:3001/queries") + FakeWeb.register_uri(:post, HTTP_PROTO_CLIENT+"://127.0.0.1:3001/queries", :body => "{}", :status => ["304"], :location=>HTTP_PROTO_CLIENT+"://localhost:3001/queries") query_from_db = Query.find(@ids[2]) endpoint_ids = [@endpoints_for_execution[0].id.to_s] @@ -275,7 +275,7 @@ class QueriesControllerTest < ActionController::TestCase test "should cancel execution" do sign_in @user - FakeWeb.register_uri(:post, HTTP_PROTO+"://127.0.0.1:3001/queries", :body => "{}", :status => ["304"], :location=>HTTP_PROTO+"://localhost:3001/queries") + FakeWeb.register_uri(:post, HTTP_PROTO_CLIENT+"://127.0.0.1:3001/queries", :body => "{}", :status => ["304"], :location=>HTTP_PROTO_CLIENT+"://localhost:3001/queries") query_from_db = Query.find(@ids[2]) endpoint_ids = [@endpoints_for_execution[0].id.to_s] diff --git a/test/unit/endpoint_cron_test.rb b/test/unit/endpoint_cron_test.rb index f20914b..ac34bc2 100644 --- a/test/unit/endpoint_cron_test.rb +++ b/test/unit/endpoint_cron_test.rb @@ -17,9 +17,9 @@ class EndpointCronTest < ActiveSupport::TestCase job = Delayed::Job.enqueue payload_object: cronJob, run_at: 2.from_now - FakeWeb.register_uri(:get, HTTP_PROTO+"://127.0.0.1:3001/queries", + FakeWeb.register_uri(:get, HTTP_PROTO_CLIENT+"://127.0.0.1:3001/queries", :body => File.read(File.expand_path('../../fixtures/query_feed.xml', __FILE__))) - FakeWeb.register_uri(:get, HTTP_PROTO+"://localhost:3000/queries/4e4c08b5431a5f5dc1000001", + FakeWeb.register_uri(:get, HTTP_PROTO_CLIENT+"://localhost:3000/queries/4e4c08b5431a5f5dc1000001", :body => '{"status": "queued"}') endpoint = FactoryGirl.create(:endpoint) result = FactoryGirl.create(:result_waiting, endpoint: endpoint) diff --git a/test/unit/endpoint_test.rb b/test/unit/endpoint_test.rb index 151280e..0247a0b 100755 --- a/test/unit/endpoint_test.rb +++ b/test/unit/endpoint_test.rb @@ -6,7 +6,7 @@ class EndpointTest < ActiveSupport::TestCase end test "monitoring queries that have not been modified" do - FakeWeb.register_uri(:get, HTTP_PROTO+"://127.0.0.1:3001/queries", + FakeWeb.register_uri(:get, HTTP_PROTO_CLIENT+"://127.0.0.1:3001/queries", :status => [304, "Not Modified"]) endpoint = FactoryGirl.create(:endpoint) @@ -21,14 +21,14 @@ class EndpointTest < ActiveSupport::TestCase end test "monitoring queries that have changed" do - if HTTP_PROTO == "https" - FakeWeb.register_uri(:get, HTTP_PROTO+"://127.0.0.1:3001/queries", + if HTTP_PROTO_CLIENT == "https" + FakeWeb.register_uri(:get, HTTP_PROTO_CLIENT+"://127.0.0.1:3001/queries", :body => File.read(File.expand_path('../../fixtures/query_feed.xml', __FILE__))) else - FakeWeb.register_uri(:get, HTTP_PROTO+"://127.0.0.1:3001/queries", + FakeWeb.register_uri(:get, HTTP_PROTO_CLIENT+"://127.0.0.1:3001/queries", :body => File.read(File.expand_path('../../fixtures/query_feed_no_ssl.xml', __FILE__))) end - FakeWeb.register_uri(:get, HTTP_PROTO+"://localhost:3000/queries/4e4c08b5431a5f5dc1000001", + FakeWeb.register_uri(:get, HTTP_PROTO_SERVER+"://localhost:3000/queries/4e4c08b5431a5f5dc1000001", :body => '{"status": "queued"}') endpoint = FactoryGirl.create(:endpoint) result = FactoryGirl.create(:result_waiting, endpoint: endpoint) @@ -46,7 +46,7 @@ class EndpointTest < ActiveSupport::TestCase end test "monitoring queries with incomprehensible responses" do - FakeWeb.register_uri(:get, HTTP_PROTO+"://127.0.0.1:3001/queries", :body => 'bacon is delicious') + FakeWeb.register_uri(:get, HTTP_PROTO_CLIENT+"://127.0.0.1:3001/queries", :body => 'bacon is delicious') endpoint = FactoryGirl.create(:endpoint) endpoint.check assert_equal 2, endpoint.endpoint_logs.count @@ -64,7 +64,7 @@ class EndpointTest < ActiveSupport::TestCase end test "should gracefully handle errors in check" do - FakeWeb.register_uri(:get, HTTP_PROTO+"://127.0.0.1:3001/queries", :exception => Net::HTTPError) + FakeWeb.register_uri(:get, HTTP_PROTO_CLIENT+"://127.0.0.1:3001/queries", :exception => Net::HTTPError) endpoint = FactoryGirl.create(:endpoint) endpoint.check assert_equal 1, endpoint.endpoint_logs.count diff --git a/test/unit/execution_test.rb b/test/unit/execution_test.rb index 8dacf72..dc2da40 100644 --- a/test/unit/execution_test.rb +++ b/test/unit/execution_test.rb @@ -46,9 +46,9 @@ class ExecutionTest < ActiveSupport::TestCase end test "query submission" do - FakeWeb.register_uri(:post, HTTP_PROTO+"://127.0.0.1:3001/queries", :body => "Query Created", - :status => [201, "Created"], :location => HTTP_PROTO+"://127.0.0.1:3001/query/1234") - FakeWeb.register_uri(:post, HTTP_PROTO+"://127.0.0.1:3001/library_functions", :body => "yay", + FakeWeb.register_uri(:post, HTTP_PROTO_CLIENT+"://127.0.0.1:3001/queries", :body => "Query Created", + :status => [201, "Created"], :location => HTTP_PROTO_CLIENT+"://127.0.0.1:3001/query/1234") + FakeWeb.register_uri(:post, HTTP_PROTO_CLIENT+"://127.0.0.1:3001/library_functions", :body => "yay", :status => [200, "OK"]) user = FactoryGirl.create(:user) @@ -72,7 +72,7 @@ class ExecutionTest < ActiveSupport::TestCase result = query.last_execution.results[0] assert result - assert_equal HTTP_PROTO+"://127.0.0.1:3001/query/1234", result.query_url + assert_equal HTTP_PROTO_CLIENT+"://127.0.0.1:3001/query/1234", result.query_url assert_equal Result::QUEUED, result.status end @@ -80,9 +80,9 @@ class ExecutionTest < ActiveSupport::TestCase - test "query should log failures for endpoint on failure" do + test "query should log failures for endpoint on failure" do - FakeWeb.register_uri(:post, HTTP_PROTO+"://127.0.0.1:3001/queries", :status => ["500", "Internal Server Error"]) + FakeWeb.register_uri(:post, HTTP_PROTO_CLIENT+"://127.0.0.1:3001/queries", :status => ["500", "Internal Server Error"]) query = Query.find(@user_with_functions.queries[3].id) endpoint = FactoryGirl.create(:endpoint) diff --git a/test/unit/result_test.rb b/test/unit/result_test.rb index 2efd38a..c91a9e5 100644 --- a/test/unit/result_test.rb +++ b/test/unit/result_test.rb @@ -1,19 +1,14 @@ require 'test_helper' -#HTTP_PROTO='http' -#if SslConfig::getUseSsl -# HTTP_PROTO='https' -#end - class ResultTest < ActiveSupport::TestCase setup do dump_database end test "check a result that has changed" do - FakeWeb.register_uri(:get, HTTP_PROTO+"://localhost:3000/queries/4e4c08b5431a5f5dc1000001", - :body => '{"status": "'+Result::COMPLETE+'", "result_url": "'+HTTP_PROTO+'://localhost/results/1234"}') - FakeWeb.register_uri(:get, HTTP_PROTO+"://localhost/results/1234", + FakeWeb.register_uri(:get, HTTP_PROTO_CLIENT+"://localhost:3000/queries/4e4c08b5431a5f5dc1000001", + :body => '{"status": "'+Result::COMPLETE+'", "result_url": "'+HTTP_PROTO_CLIENT+'://localhost/results/1234"}') + FakeWeb.register_uri(:get, HTTP_PROTO_CLIENT+"://localhost/results/1234", :body => '{"foo": "bar"}') result = FactoryGirl.create(:result_waiting) @@ -26,18 +21,18 @@ class ResultTest < ActiveSupport::TestCase end test "fetch a result" do - FakeWeb.register_uri(:get, HTTP_PROTO+"://localhost/results/1234", + FakeWeb.register_uri(:get, HTTP_PROTO_CLIENT+"://localhost/results/1234", :body => '{"foo": "bar"}') - result = FactoryGirl.create(:result, :result_url => HTTP_PROTO+"://localhost/results/1234") + result = FactoryGirl.create(:result, :result_url => HTTP_PROTO_CLIENT+"://localhost/results/1234") result.fetch_result assert_equal Result::COMPLETE, result.status assert_equal 'bar', result.value['foo'] end test "checking a result" do - FakeWeb.register_uri(:get, HTTP_PROTO+"://localhost:3000/queries/4e4c08b5431a5f5dc1000001", - :body => '{"status": "complete", "result_url": "'+HTTP_PROTO+'://localhost/results/1234"}') - FakeWeb.register_uri(:get, HTTP_PROTO+"://localhost/results/1234", + FakeWeb.register_uri(:get, HTTP_PROTO_CLIENT+"://localhost:3000/queries/4e4c08b5431a5f5dc1000001", + :body => '{"status": "complete", "result_url": "'+HTTP_PROTO_CLIENT+'://localhost/results/1234"}') + FakeWeb.register_uri(:get, HTTP_PROTO_CLIENT+"://localhost/results/1234", :body => '{"foo": "bar", "status": "complete"}') result = FactoryGirl.create(:result_waiting) result.check @@ -46,7 +41,7 @@ class ResultTest < ActiveSupport::TestCase end test "checking a result where there is an error" do - FakeWeb.register_uri(:get, HTTP_PROTO+"://localhost:3000/queries/4e4c08b5431a5f5dc1000001", + FakeWeb.register_uri(:get, HTTP_PROTO_CLIENT+"://localhost:3000/queries/4e4c08b5431a5f5dc1000001", :body => '{"status": "failed", "error_message": "game over, man!"}') result = FactoryGirl.create(:result_waiting) result.check From b10a6f71048da724d8a23320c1d5c4051b9391ee Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Fri, 4 Oct 2013 14:47:53 -0700 Subject: [PATCH 058/117] Fixed typo in unit test. None of the client tests exercise USE_SSL_SERVER --- test/unit/endpoint_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/endpoint_test.rb b/test/unit/endpoint_test.rb index 0247a0b..a2e3742 100755 --- a/test/unit/endpoint_test.rb +++ b/test/unit/endpoint_test.rb @@ -28,7 +28,7 @@ class EndpointTest < ActiveSupport::TestCase FakeWeb.register_uri(:get, HTTP_PROTO_CLIENT+"://127.0.0.1:3001/queries", :body => File.read(File.expand_path('../../fixtures/query_feed_no_ssl.xml', __FILE__))) end - FakeWeb.register_uri(:get, HTTP_PROTO_SERVER+"://localhost:3000/queries/4e4c08b5431a5f5dc1000001", + FakeWeb.register_uri(:get, HTTP_PROTO_CLIENT+"://localhost:3000/queries/4e4c08b5431a5f5dc1000001", :body => '{"status": "queued"}') endpoint = FactoryGirl.create(:endpoint) result = FactoryGirl.create(:result_waiting, endpoint: endpoint) From 7431d423bf1f51fc85608d397e6c3454fbb9ab43 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Mon, 7 Oct 2013 12:13:20 -0700 Subject: [PATCH 059/117] Create PID file for server --- script/rails | 1 + 1 file changed, 1 insertion(+) diff --git a/script/rails b/script/rails index 4e70626..f1cb5bc 100755 --- a/script/rails +++ b/script/rails @@ -22,6 +22,7 @@ module Rails class Server < ::Rack::Server def default_options super.merge({ + :pid => File.expand_path("tmp/pids/server.pid"), :SSLEnable => USE_SSL_SERVER, :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, :SSLPrivateKey => OpenSSL::PKey::RSA.new(SERVER_KEY.read), From 579671838e607760e5c059491d8741ee4314ca40 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Thu, 10 Oct 2013 12:09:51 -0700 Subject: [PATCH 060/117] Remove If-Modified-Since and query_update_time checks - they cause jobs to stay in the queue even though they have been completed on the endpoints. --- app/models/endpoint.rb | 11 ++++++----- app/models/result.rb | 7 ++++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/app/models/endpoint.rb b/app/models/endpoint.rb index e84906b..3d7ca45 100755 --- a/app/models/endpoint.rb +++ b/app/models/endpoint.rb @@ -35,13 +35,13 @@ def check url = submit_url begin check_time = Time.now - + #use ssl response = Net::HTTP.start(url.host, url.port, :use_ssl => USE_SSL_CLIENT, :key => CLIENT_KEY, :cert => CLIENT_CERT) do |http| headers = {} - if last_check - headers['If-Modified-Since'] = last_check.to_formatted_s(:rfc822) - end + #if last_check + # headers['If-Modified-Since'] = last_check.to_formatted_s(:rfc822) + #end headers['Accept'] = 'application/atom+xml' http.get(url.path, headers) end @@ -67,7 +67,8 @@ def update_results(atom_feed) parsed_feed.entries.each do |atom_entry| query_url = atom_entry.id.try(:content) query_update_time = atom_entry.updated.try(:content) - result = active_results_for_this_endpoint.where(:query_url => query_url, :updated_at.lt => query_update_time).first + #result = active_results_for_this_endpoint.where(:query_url => query_url, :updated_at.lt => query_update_time).first + result = active_results_for_this_endpoint.where(:query_url => query_url).first if result result.check() if (result.status == Result::COMPLETE) diff --git a/app/models/result.rb b/app/models/result.rb index e589194..0c5d75a 100755 --- a/app/models/result.rb +++ b/app/models/result.rb @@ -32,8 +32,9 @@ def check #use ssl response = Net::HTTP.start(url.host, url.port, :use_ssl => USE_SSL_CLIENT, :key => CLIENT_KEY, :cert => CLIENT_CERT) do |http| - http.get(url.path, 'If-Modified-Since' => updated_at.to_formatted_s(:rfc822), - 'Accept' => 'application/json') + #http.get(url.path, 'If-Modified-Since' => updated_at.to_formatted_s(:rfc822), + # 'Accept' => 'application/json') + http.get(url.path, 'Accept' => 'application/json') end case response @@ -54,7 +55,7 @@ def check self.status = query_status save! else - self.update_attribute(:created_at, Time.now) + self.update_attribute(:created_at, Time.now) end end when Net::HTTPNotModified From faa3bc7e5dbf43b681c5087dea4b4668ca53a186 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Thu, 5 Jun 2014 14:26:56 -0700 Subject: [PATCH 061/117] Added file describing system testing --- HUB-Test-Plan.md | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 HUB-Test-Plan.md diff --git a/HUB-Test-Plan.md b/HUB-Test-Plan.md new file mode 100644 index 0000000..084a302 --- /dev/null +++ b/HUB-Test-Plan.md @@ -0,0 +1,42 @@ +##SCOOPHEALTH Infrastructure Testing Methodology + +#Infrastructure Overview + +There are 4 major components in the SCOOPHEALTH infrastructure. These consist of the: + + - Importer Library (health-data-standards) + - Endpoint (query-gateway) + - Patient API (patientapi) + - Hub (query-composer) + +## Importer Library +The health-data-standards ([HDS]) library used by SCOOPHEALTH is a fork of [Project Cypress] which is still undergoing rapid development. The SCOOPHEALTH fork was made on Nov 15, 2012. Since then the major changes to the SCOOPHEALTH fork have been migration from Ruby 1.9.2 to 1.9.3 and the addition of E2E importer code. + +The health-data-standards library uses the Ruby Gem "minitest" to support test-driven development (TDD) and a mock-object framework. The E2E importer has extensive unit testing of all the sections of the E2E document. These tests are ran against test patient data, verifying that known information is imported correctly. This makes refactoring of the HDS E2E importer code much easier and ensures that code changes required for consistency with changing E2E document specifications are made. + +## Endpoint +Ongoing [endpoint] code development is taking place in the Scoophealth fork of [query-gateway]. Visitors to the hquery site are now advised to use the Scoophealth fork for updated code. Major changes include migration from Ruby 1.9.2 to 1.9.3 and mongoid 2.0 to mongoid 3.0.6 (for consistentancy with health-data-standards). The query-gateway code also uses the "minitest" framework which makes refactoring and tracking of the evolving E2E standard easier. Testing consists of 1) functional testing to verify that E2E test patient documents can be loaded into the MongoDB records collection and that information from the patient records can be retrieved successfully, and 2) integration testing of the E2E importer verifying that data loaded into the database can be retrieved using Javascript methods provided by the patientapi library. Each section of the E2E document imported by the HDS E2E importer is tested. All code relevant to E2E has 100% code coverage. Test scripts based on PDC and scoophealth queries are ran to ensure that output remains consistent with past results. + +## Patient API +The SCOOPHEALTH [patientapi] library code is a fork of the [pophealth-patientapi] branch which was forked from the [hquery-patientapi] code base. The hquery codebase is no longer updated and the pophealth code base is updated infrequently. The scoophealth fork tracks any changes relevant to E2E. The primary difference from the pophealth codebase is support for regular expressions in coded values and the addition of tests specific to E2E documents. All "minitest"-based tests performed on imported CDA documents are also executed against E2E documents and the results are compared with expected E2E test patient information. + +## Hub +The [hub] code is a fork of [query-composer]. The hquery site now redirects visitors to the scoophealth fork for updated code. Major changes to the code relate to migration from Ruby 1.9.2 to 1.9.3, mongoid from 2.3.4 to 3.1.4, and rails from 3.1.3 to 3.2.7. The query-composer code has extensive "minitest" code coverage based on functional testing of the Rails controllers, unit tests of hub functionality, and integration tests of query aggregation and user access control. None of these tests are specific to E2E because once the data is stored in the endpoint database in a format queryable by the patientapi, the details of which importer was used to obtain the data is hidden. + +[HDS]:https://github.com/scoophealth/health-data-standards "health-data-standards" + +[Project Cypress]: http://projectcypress.org/ + +[Endpoint]: https://github.com/hquery/query-gateway "scoop query-gateway" + +[query-gateway]: https://github.com/hquery/query-gateway "hquery gateway" + +[patientapi]: https://github.com/scoophealth/patientapi "Patient API" + +[pophealth-patientapi]: https://github.com/pophealth/patientapi "Pophealth patientapi" + +[hquery-patientapi]: https://github.com/pophealth/patientapi "hquery patientapi" + +[hub]: https://github.com/scoophealth/query-composer "scoop query-composer" + +[query-composer]: https://github.com/hquery/query-composer "hquery query-composer" From 538ab0194e7c3dbcb1f17490dcebdacc6fd8d343 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Mon, 7 Jul 2014 13:29:39 -0700 Subject: [PATCH 062/117] Changed log level and added more codes to the code system helper --- app/helpers/code_system_helper.rb | 18 +++++++++++++++++- config/environments/development.rb | 2 ++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/app/helpers/code_system_helper.rb b/app/helpers/code_system_helper.rb index eb53eec..e31a242 100644 --- a/app/helpers/code_system_helper.rb +++ b/app/helpers/code_system_helper.rb @@ -16,7 +16,23 @@ class CodeSysHelper '2.16.840.1.113883.6.90' => 'ICD-10-CM', '2.16.840.1.113883.6.14' => 'HCPCS', '2.16.840.1.113883.6.59' => 'CVX', - '2.16.840.1.113883.6.238' => 'CDC-RE' + '2.16.840.1.113883.6.238' => 'CDC-RE', + '2.16.840.1.113883.5.83' => 'HITSP C80 Observation Status', + '2.16.840.1.113883.3.26.1.1' => 'NCI Thesaurus', + '2.16.840.1.113883.3.88.12.80.20' => 'FDA', + '2.16.840.1.113883.5.14' => 'HL7 ActStatus', + '2.16.840.1.113883.6.259' => 'HL7 Healthcare Service Location', + '2.16.840.1.113883.5.4' => 'HL7 Act Code', + '2.16.840.1.113883.1.11.18877' => 'HL7 Relationship Code', + '2.16.840.1.113883.6.238' => 'CDC Race', + '2.16.840.1.113883.5.1105' => 'HC-DIN', + '2.16.840.1.113883.6.63' => 'FDDC', + '2.16.840.1.113883.6.73' => 'whoATC', + '2.16.840.1.113883.6.42' => 'ICD9', + '2.16.840.1.113883.3.1818.10.2.8.2' => 'PITO AllergyClinicalStatus', + '2.16.840.1.113883.2.20.3.78' => 'ObservationInterpretation', + '2.16.840.1.113883.2.20.5.1' => 'pCLOCD', + '2.16.840.1.113883.3.3068.10.6.3' => 'ObservationType-CA-Pending' } # Returns the name of a code system given an oid diff --git a/config/environments/development.rb b/config/environments/development.rb index 35cd16e..f4e9db8 100755 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -9,6 +9,8 @@ # Log error messages when you accidentally call methods on nil. config.whiny_nils = true + config.log_level = :info #:debug + # Show full error reports and disable caching config.consider_all_requests_local = true config.action_controller.perform_caching = false From a7e793a06b52fbbe53d5686ef821e038a1956677 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Tue, 29 Jul 2014 12:31:46 -0700 Subject: [PATCH 063/117] Unwrappered reduce iter behaviour --- app/models/execution.rb | 4 ++-- .../queries/builder/_reduce_function.js.erb | 22 +++++++++---------- test/factories/factory.rb | 4 ++-- test/fixtures/NQF_01_AsthmaAssessment.js | 4 +--- test/fixtures/NQF_31_BreastCancerScreening.js | 4 +--- .../NQF_32_CervicalCancerScreening.js | 4 +--- test/fixtures/NQF_43_Pneumonia.js | 4 +--- 7 files changed, 18 insertions(+), 28 deletions(-) diff --git a/app/models/execution.rb b/app/models/execution.rb index 1013ac8..1e236dc 100755 --- a/app/models/execution.rb +++ b/app/models/execution.rb @@ -48,7 +48,7 @@ def cancel # =============== def aggregate #response = Result.collection.map_reduce(self.map_fn(), _reduce(), :raw => true, :out => {:inline => true}, :query => {:execution_id => id}) - response = Result.where(execution_id: id).map_reduce(self.map_fn(), _reduce()).out(inline: true).raw() + response = Result.where(execution_id: id).map_reduce(self.map_fn(), self.query.reduce).out(inline: true).raw() results = response['results'] if results self.aggregate_result = {} @@ -161,7 +161,7 @@ def map_fn private - def _reduce + def _reduce_deprecated #unwrapped reduce method; its output datatype must match the values datatype exactly "function(k,v){ var iter = function(x){ diff --git a/app/views/queries/builder/_reduce_function.js.erb b/app/views/queries/builder/_reduce_function.js.erb index b33d9f7..c350444 100644 --- a/app/views/queries/builder/_reduce_function.js.erb +++ b/app/views/queries/builder/_reduce_function.js.erb @@ -20,13 +20,12 @@ function reduce(key, values) { rereduced = false ); - while(values.hasNext()) { - var _val = values.next(); - result.sum('target_pop', _val); - result.sum('filtered_pop', _val); - result.sum('unfound_pop', _val); - result.sum('total_pop', _val); - _val.rereduced = true; + for (var i in values) { + result.sum('target_pop', values[i]); + result.sum('filtered_pop', values[i]); + result.sum('unfound_pop', values[i]); + result.sum('total_pop', values[i]); + values[i].rereduced = true; result.rereduced = true; } } else if (key.type == 'group') { @@ -46,8 +45,7 @@ function reduce(key, values) { rereduced = false ); - while(values.hasNext()) { - var _val = values.next(); + for (var i in values) { <% aggregates = [] query_structure['extract']['selections'].each do |select| # TODO - We need to decide on a default action when no aggregate is defined. For now, we'll just sum. @@ -55,7 +53,7 @@ function reduce(key, values) { select['aggregation'] << 'sum' end select['aggregation'].each do |aggregate| - aggregates << "result.#{aggregate}('#{select['title']}', _val);" + aggregates << "result.#{aggregate}('#{select['title']}', values[i]);" end end aggregation = aggregates.join("\n") %> @@ -63,9 +61,9 @@ function reduce(key, values) { <%= raw aggregation %> result.rereduced = true; - _val.rereduced = true; + values[i].rereduced = true; } } return result; -} \ No newline at end of file +} diff --git a/test/factories/factory.rb b/test/factories/factory.rb index 2610152..5d7f32a 100755 --- a/test/factories/factory.rb +++ b/test/factories/factory.rb @@ -129,7 +129,7 @@ FactoryGirl.define do factory :query_with_queued_results, :parent => :query do |query| - query.reduce "function reduce(key, values) {\r\n var result = 0; \r\n while(values.hasNext()){ result += values.next(); }\r\nreturn result; \r\n}" + query.reduce "function reduce(key, values) {\r\n return Array.sum(values); \r\n}" #after(:create) do |query, evaluator| # FactoryGirl.create_list(:queued_execution, 1, query: query) @@ -142,7 +142,7 @@ FactoryGirl.define do factory :query_with_completed_results, :parent => :query do |query| - query.reduce "function reduce(key, values) {\r\n var result = 0; \r\n while(values.hasNext()){ result += values.next(); }\r\nreturn result; \r\n}" + query.reduce "function reduce(key, values) {\r\n return Array.sum(values); \r\n}" #after(:create) do |query, evaluator| # FactoryGirl.create_list(:completed_execution, 1, query: query) diff --git a/test/fixtures/NQF_01_AsthmaAssessment.js b/test/fixtures/NQF_01_AsthmaAssessment.js index 32e5f39..a0ec744 100755 --- a/test/fixtures/NQF_01_AsthmaAssessment.js +++ b/test/fixtures/NQF_01_AsthmaAssessment.js @@ -127,7 +127,5 @@ function map(patient) { } function reduce(criteria, counts) { - var sum = 0; - while(counts.hasNext()){sum += counts.next();} - return sum; + return Array.sum(counts); } \ No newline at end of file diff --git a/test/fixtures/NQF_31_BreastCancerScreening.js b/test/fixtures/NQF_31_BreastCancerScreening.js index 3c25b56..0f74e9b 100644 --- a/test/fixtures/NQF_31_BreastCancerScreening.js +++ b/test/fixtures/NQF_31_BreastCancerScreening.js @@ -127,7 +127,5 @@ function map(patient) { } function reduce(criteria, counts) { - var sum = 0; - while(counts.hasNext()){sum += counts.next();} - return sum; + return Array.sum(counts); } \ No newline at end of file diff --git a/test/fixtures/NQF_32_CervicalCancerScreening.js b/test/fixtures/NQF_32_CervicalCancerScreening.js index d7a401d..e6defad 100755 --- a/test/fixtures/NQF_32_CervicalCancerScreening.js +++ b/test/fixtures/NQF_32_CervicalCancerScreening.js @@ -124,7 +124,5 @@ function map(patient) { } function reduce(criteria, counts) { - var sum = 0; - while(counts.hasNext()){sum += counts.next();} - return sum; + return Array.sum(counts); } \ No newline at end of file diff --git a/test/fixtures/NQF_43_Pneumonia.js b/test/fixtures/NQF_43_Pneumonia.js index dea322b..0a3c576 100755 --- a/test/fixtures/NQF_43_Pneumonia.js +++ b/test/fixtures/NQF_43_Pneumonia.js @@ -73,7 +73,5 @@ function map(patient) { } function reduce(criteria, counts) { - var sum = 0; - while(counts.hasNext()){sum += counts.next();} - return sum; + return Array.sum(counts); } \ No newline at end of file From 8080231904be9c6a88f344d4db014f68c4456a7c Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Wed, 6 Aug 2014 14:01:51 -0700 Subject: [PATCH 064/117] Sort queries by description --- app/views/queries/index.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/queries/index.html.erb b/app/views/queries/index.html.erb index c48d0fe..74a3627 100755 --- a/app/views/queries/index.html.erb +++ b/app/views/queries/index.html.erb @@ -17,7 +17,7 @@ Status <% end %> - <% @queries.each do |query| %> + <% @queries.sort({description:1}).each do |query| %> <%= link_to query.title, query_path(query.id) %> <%= query.description %> From f797b5daf9f1b925cb84bc9b09729a1357331493 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Wed, 6 Aug 2014 15:05:10 -0700 Subject: [PATCH 065/117] New default reduce function --- app/controllers/queries_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/queries_controller.rb b/app/controllers/queries_controller.rb index 7bb4c5d..f876894 100755 --- a/app/controllers/queries_controller.rb +++ b/app/controllers/queries_controller.rb @@ -37,7 +37,7 @@ def edit @query.map = "function map(patient) {\r\n \r\n}" end if (@query.reduce.nil?) - @query.reduce = "function reduce(key, values) {\r\n \r\n}" + @query.reduce = "function reduce(key, values) {\r\n return Array.sum(values); \r\n}" end end From b8c2116a2d48e39cb4c8707a8b66763036ef0a0c Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Wed, 6 Aug 2014 15:21:26 -0700 Subject: [PATCH 066/117] Make handwritten javascript default choice --- app/views/queries/_query_details.html.erb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/queries/_query_details.html.erb b/app/views/queries/_query_details.html.erb index 58b8a50..5f5f8fe 100755 --- a/app/views/queries/_query_details.html.erb +++ b/app/views/queries/_query_details.html.erb @@ -14,8 +14,8 @@ <% else %> Mode - <%= f.radio_button :generated, true, :checked => true %> Graphical Builder - <%= f.radio_button :generated, false, :checked => false %> Handwritten JavaScript (Advanced) + <%= f.radio_button :generated, true, :checked => false %> Graphical Builder + <%= f.radio_button :generated, false, :checked => true %> Handwritten JavaScript (Advanced) <% end %> From 1dbafc4a0807b24a084f5377186f877ca96ae220 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Mon, 18 Aug 2014 14:25:13 -0700 Subject: [PATCH 067/117] Correct patient age for leap years --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index dd426a8..646f0f7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/scoophealth/patientapi.git - revision: 35340bb11c26115bd5e350ad270cb59ac1c3f56b + revision: 36a78993ee10c931f58d004a38b931790bcb0e80 branch: scoop-develop specs: hquery-patient-api (1.0.0) From 5cb90d0a55dab5c7fa4a7e36ded304836edceb12 Mon Sep 17 00:00:00 2001 From: drusk Date: Fri, 22 Aug 2014 15:32:12 -0700 Subject: [PATCH 068/117] Use asc(:description) method instead of sort({description:1}) on queries in index.html. Fixes test cases failing with "wrong number of arguments (1 for 0)" error on the sort method. --- app/views/queries/index.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/queries/index.html.erb b/app/views/queries/index.html.erb index 74a3627..6c6df9d 100755 --- a/app/views/queries/index.html.erb +++ b/app/views/queries/index.html.erb @@ -17,7 +17,7 @@ Status <% end %> - <% @queries.sort({description:1}).each do |query| %> + <% @queries.asc(:description).each do |query| %> <%= link_to query.title, query_path(query.id) %> <%= query.description %> From 4099f42bc88ee19e839ed32c2c689c3e6d82a349 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Mon, 8 Sep 2014 11:57:04 -0700 Subject: [PATCH 069/117] Use master branch of scoophealth patientapi --- Gemfile | 2 +- Gemfile.lock | 6 +- public/patientapi/files.html | 2 +- public/patientapi/index.html | 2 +- public/patientapi/symbols/__hasProp.html | 2 +- public/patientapi/symbols/_global_.html | 2 +- public/patientapi/symbols/hQuery.Actor.html | 2 +- public/patientapi/symbols/hQuery.Address.html | 2 +- .../symbols/hQuery.AdministrationTiming.html | 2 +- public/patientapi/symbols/hQuery.Allergy.html | 4 +- .../symbols/hQuery.CauseOfDeath.html | 2 +- .../patientapi/symbols/hQuery.CodedEntry.html | 54 +- .../symbols/hQuery.CodedEntryList.html | 75 +- .../patientapi/symbols/hQuery.CodedValue.html | 54 +- .../patientapi/symbols/hQuery.Condition.html | 4 +- .../patientapi/symbols/hQuery.DateRange.html | 2 +- .../symbols/hQuery.DoseRestriction.html | 2 +- .../patientapi/symbols/hQuery.Encounter.html | 4 +- .../patientapi/symbols/hQuery.Facility.html | 2 +- .../symbols/hQuery.Fulfillment.html | 2 +- .../symbols/hQuery.FunctionalStatus.html | 4 +- .../symbols/hQuery.Immunization.html | 4 +- .../patientapi/symbols/hQuery.Informant.html | 2 +- .../patientapi/symbols/hQuery.Language.html | 4 +- .../patientapi/symbols/hQuery.Medication.html | 4 +- .../symbols/hQuery.MedicationInformation.html | 2 +- .../symbols/hQuery.NoImmunization.html | 4 +- .../symbols/hQuery.OrderInformation.html | 2 +- .../symbols/hQuery.Organization.html | 2 +- public/patientapi/symbols/hQuery.Patient.html | 2 +- public/patientapi/symbols/hQuery.Person.html | 2 +- .../symbols/hQuery.PhysicalQuantity.html | 2 +- .../patientapi/symbols/hQuery.Pregnancy.html | 4 +- .../patientapi/symbols/hQuery.Procedure.html | 4 +- .../patientapi/symbols/hQuery.Provider.html | 2 +- public/patientapi/symbols/hQuery.Result.html | 4 +- public/patientapi/symbols/hQuery.Scalar.html | 2 +- public/patientapi/symbols/hQuery.Status.html | 4 +- .../symbols/hQuery.StatusOfMedication.html | 4 +- .../patientapi/symbols/hQuery.Supports.html | 2 +- public/patientapi/symbols/hQuery.Telecom.html | 2 +- .../symbols/hQuery.TypeOfMedication.html | 4 +- .../symbols/src/tmp_patient.js.html | 6188 +++++++++-------- 43 files changed, 3400 insertions(+), 3081 deletions(-) diff --git a/Gemfile b/Gemfile index dbfb484..f616127 100755 --- a/Gemfile +++ b/Gemfile @@ -23,7 +23,7 @@ gem 'multipart-post' gem 'delayed_job' gem 'delayed_job_mongoid' -gem 'hquery-patient-api', :git => 'https://github.com/scoophealth/patientapi.git', :branch => 'scoop-develop' +gem 'hquery-patient-api', :git => 'https://github.com/scoophealth/patientapi.git', :branch => 'master' gem 'coderay' diff --git a/Gemfile.lock b/Gemfile.lock index 646f0f7..fab6a41 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,9 +1,9 @@ GIT remote: https://github.com/scoophealth/patientapi.git - revision: 36a78993ee10c931f58d004a38b931790bcb0e80 - branch: scoop-develop + revision: 3a044aaa3fa20091e848a74904ece4e39572bb3a + branch: master specs: - hquery-patient-api (1.0.0) + hquery-patient-api (1.0.5) GEM remote: https://rubygems.org/ diff --git a/public/patientapi/files.html b/public/patientapi/files.html index 7343a7b..8a5e974 100644 --- a/public/patientapi/files.html +++ b/public/patientapi/files.html @@ -284,7 +284,7 @@

    tmp/patient.js

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:50 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT)
    \ No newline at end of file diff --git a/public/patientapi/index.html b/public/patientapi/index.html index 99b4d2a..5754d90 100644 --- a/public/patientapi/index.html +++ b/public/patientapi/index.html @@ -504,7 +504,7 @@

    hQuery.TypeOfMedication
    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:50 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT)
    \ No newline at end of file diff --git a/public/patientapi/symbols/__hasProp.html b/public/patientapi/symbols/__hasProp.html index e4b7c2a..e68b545 100644 --- a/public/patientapi/symbols/__hasProp.html +++ b/public/patientapi/symbols/__hasProp.html @@ -367,7 +367,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/_global_.html b/public/patientapi/symbols/_global_.html index 99d6b25..93b4d51 100644 --- a/public/patientapi/symbols/_global_.html +++ b/public/patientapi/symbols/_global_.html @@ -394,7 +394,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Actor.html b/public/patientapi/symbols/hQuery.Actor.html index 88c929f..8a36a19 100644 --- a/public/patientapi/symbols/hQuery.Actor.html +++ b/public/patientapi/symbols/hQuery.Actor.html @@ -503,7 +503,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Address.html b/public/patientapi/symbols/hQuery.Address.html index 77b86d1..87b7c8b 100644 --- a/public/patientapi/symbols/hQuery.Address.html +++ b/public/patientapi/symbols/hQuery.Address.html @@ -599,7 +599,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.AdministrationTiming.html b/public/patientapi/symbols/hQuery.AdministrationTiming.html index 9efe19a..976fddb 100644 --- a/public/patientapi/symbols/hQuery.AdministrationTiming.html +++ b/public/patientapi/symbols/hQuery.AdministrationTiming.html @@ -523,7 +523,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Allergy.html b/public/patientapi/symbols/hQuery.Allergy.html index ce505a5..0d12ed0 100644 --- a/public/patientapi/symbols/hQuery.Allergy.html +++ b/public/patientapi/symbols/hQuery.Allergy.html @@ -406,7 +406,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, regex_includesCodeFrom, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    @@ -722,7 +722,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.CauseOfDeath.html b/public/patientapi/symbols/hQuery.CauseOfDeath.html index f7a0577..0dc7ed9 100644 --- a/public/patientapi/symbols/hQuery.CauseOfDeath.html +++ b/public/patientapi/symbols/hQuery.CauseOfDeath.html @@ -517,7 +517,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.CodedEntry.html b/public/patientapi/symbols/hQuery.CodedEntry.html index 182f256..2671f2a 100644 --- a/public/patientapi/symbols/hQuery.CodedEntry.html +++ b/public/patientapi/symbols/hQuery.CodedEntry.html @@ -421,6 +421,15 @@

    + +   + + +
    Returns true if any of this entry codes match a code in the supplied codeSet.
    + + +   @@ -866,6 +875,49 @@

    +
    + + +
    + + {boolean} + regex_includesCodeFrom(codeSet) + +
    +
    + Returns true if any of this entry codes match a code in the supplied codeSet. + + +
    + + + + +
    +
    Parameters:
    + +
    + {Object} codeSet + +
    +
    a hash with code system names as keys and an array of codes (provided as regular expressions) as values
    + +
    + + + + + +
    +
    Returns:
    + +
    {boolean}
    + +
    + + + +
    @@ -1110,7 +1162,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.CodedEntryList.html b/public/patientapi/symbols/hQuery.CodedEntryList.html index f5fdb99..e59fd62 100644 --- a/public/patientapi/symbols/hQuery.CodedEntryList.html +++ b/public/patientapi/symbols/hQuery.CodedEntryList.html @@ -368,6 +368,16 @@

    + +   + +
    regex_match(codeSet, start, end, includeNegated) +
    +
    Return the number of entries that match the + supplied code set where those entries occur between the supplied time bounds
    + + +   @@ -618,6 +628,69 @@

    +
    + + +
    + + {CodedEntryList} + regex_match(codeSet, start, end, includeNegated) + +
    +
    + Return the number of entries that match the + supplied code set where those entries occur between the supplied time bounds + + +
    + + + + +
    +
    Parameters:
    + +
    + {Object} codeSet + +
    +
    a hash with code system names as keys and an array of codes (provided as regular expressions) as values
    + +
    + {Date} start + +
    +
    the start of the period during which the entry must occur, a null value will match all times
    + +
    + {Date} end + +
    +
    the end of the period during which the entry must occur, a null value will match all times
    + +
    + {boolean} includeNegated + +
    +
    whether the returned list of entries should include those that have been negated
    + +
    + + + + + +
    +
    Returns:
    + +
    {CodedEntryList} the matching entries + TODO - decide on what to do with includeNegated parameter
    + +
    + + + +
    @@ -756,7 +829,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.CodedValue.html b/public/patientapi/symbols/hQuery.CodedValue.html index 15b4ff8..87b7d8a 100644 --- a/public/patientapi/symbols/hQuery.CodedValue.html +++ b/public/patientapi/symbols/hQuery.CodedValue.html @@ -375,6 +375,15 @@

    + +   + +
    regex_includedIn(codeSet) +
    +
    Returns true if the contained code and codeSystemName match a code in the supplied codeSet.
    + + + @@ -606,6 +615,49 @@

    +
    + + +
    + + {boolean} + regex_includedIn(codeSet) + +
    +
    + Returns true if the contained code and codeSystemName match a code in the supplied codeSet. + + +
    + + + + +
    +
    Parameters:
    + +
    + {Object} codeSet + +
    +
    a hash with code system names as keys and an array of codes (provided as regular expressions) as values
    + +
    + + + + + +
    +
    Returns:
    + +
    {boolean}
    + +
    + + + + @@ -620,7 +672,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Condition.html b/public/patientapi/symbols/hQuery.Condition.html index 40fe94c..a658316 100644 --- a/public/patientapi/symbols/hQuery.Condition.html +++ b/public/patientapi/symbols/hQuery.Condition.html @@ -423,7 +423,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, regex_includesCodeFrom, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    @@ -784,7 +784,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.DateRange.html b/public/patientapi/symbols/hQuery.DateRange.html index 8900104..a204d55 100644 --- a/public/patientapi/symbols/hQuery.DateRange.html +++ b/public/patientapi/symbols/hQuery.DateRange.html @@ -503,7 +503,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.DoseRestriction.html b/public/patientapi/symbols/hQuery.DoseRestriction.html index 3140367..7b800a2 100644 --- a/public/patientapi/symbols/hQuery.DoseRestriction.html +++ b/public/patientapi/symbols/hQuery.DoseRestriction.html @@ -503,7 +503,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Encounter.html b/public/patientapi/symbols/hQuery.Encounter.html index 4ab1962..a046e12 100644 --- a/public/patientapi/symbols/hQuery.Encounter.html +++ b/public/patientapi/symbols/hQuery.Encounter.html @@ -458,7 +458,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, regex_includesCodeFrom, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    @@ -939,7 +939,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Facility.html b/public/patientapi/symbols/hQuery.Facility.html index 7ebc576..192ee39 100644 --- a/public/patientapi/symbols/hQuery.Facility.html +++ b/public/patientapi/symbols/hQuery.Facility.html @@ -446,7 +446,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Fulfillment.html b/public/patientapi/symbols/hQuery.Fulfillment.html index b64e63e..f4e9c3e 100644 --- a/public/patientapi/symbols/hQuery.Fulfillment.html +++ b/public/patientapi/symbols/hQuery.Fulfillment.html @@ -435,7 +435,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.FunctionalStatus.html b/public/patientapi/symbols/hQuery.FunctionalStatus.html index d331f18..bf78e83 100644 --- a/public/patientapi/symbols/hQuery.FunctionalStatus.html +++ b/public/patientapi/symbols/hQuery.FunctionalStatus.html @@ -365,7 +365,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, setTimestamp, startDate, status, statusCode, timeStamp, values
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, regex_includesCodeFrom, setTimestamp, startDate, status, statusCode, timeStamp, values
    @@ -552,7 +552,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Immunization.html b/public/patientapi/symbols/hQuery.Immunization.html index 8b83982..1dbf301 100644 --- a/public/patientapi/symbols/hQuery.Immunization.html +++ b/public/patientapi/symbols/hQuery.Immunization.html @@ -412,7 +412,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, regex_includesCodeFrom, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    @@ -715,7 +715,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Informant.html b/public/patientapi/symbols/hQuery.Informant.html index d8f1d2c..60156d4 100644 --- a/public/patientapi/symbols/hQuery.Informant.html +++ b/public/patientapi/symbols/hQuery.Informant.html @@ -518,7 +518,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Language.html b/public/patientapi/symbols/hQuery.Language.html index 3ca37ed..8e73b8e 100644 --- a/public/patientapi/symbols/hQuery.Language.html +++ b/public/patientapi/symbols/hQuery.Language.html @@ -365,7 +365,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, regex_includesCodeFrom, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    @@ -534,7 +534,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Medication.html b/public/patientapi/symbols/hQuery.Medication.html index 39c9cf3..ce58f1a 100644 --- a/public/patientapi/symbols/hQuery.Medication.html +++ b/public/patientapi/symbols/hQuery.Medication.html @@ -546,7 +546,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, regex_includesCodeFrom, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    @@ -1358,7 +1358,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.MedicationInformation.html b/public/patientapi/symbols/hQuery.MedicationInformation.html index 13597d2..f954c3a 100644 --- a/public/patientapi/symbols/hQuery.MedicationInformation.html +++ b/public/patientapi/symbols/hQuery.MedicationInformation.html @@ -612,7 +612,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.NoImmunization.html b/public/patientapi/symbols/hQuery.NoImmunization.html index e070772..c78f343 100644 --- a/public/patientapi/symbols/hQuery.NoImmunization.html +++ b/public/patientapi/symbols/hQuery.NoImmunization.html @@ -421,7 +421,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, regex_includesCodeFrom, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    @@ -773,7 +773,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.OrderInformation.html b/public/patientapi/symbols/hQuery.OrderInformation.html index 2d1aa81..bf4e892 100644 --- a/public/patientapi/symbols/hQuery.OrderInformation.html +++ b/public/patientapi/symbols/hQuery.OrderInformation.html @@ -605,7 +605,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Organization.html b/public/patientapi/symbols/hQuery.Organization.html index a5c450a..7ae6860 100644 --- a/public/patientapi/symbols/hQuery.Organization.html +++ b/public/patientapi/symbols/hQuery.Organization.html @@ -599,7 +599,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Patient.html b/public/patientapi/symbols/hQuery.Patient.html index 5e97672..69fd060 100644 --- a/public/patientapi/symbols/hQuery.Patient.html +++ b/public/patientapi/symbols/hQuery.Patient.html @@ -1615,7 +1615,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Person.html b/public/patientapi/symbols/hQuery.Person.html index e6de242..a375685 100644 --- a/public/patientapi/symbols/hQuery.Person.html +++ b/public/patientapi/symbols/hQuery.Person.html @@ -640,7 +640,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.PhysicalQuantity.html b/public/patientapi/symbols/hQuery.PhysicalQuantity.html index 9db4747..bb3b62c 100644 --- a/public/patientapi/symbols/hQuery.PhysicalQuantity.html +++ b/public/patientapi/symbols/hQuery.PhysicalQuantity.html @@ -503,7 +503,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Pregnancy.html b/public/patientapi/symbols/hQuery.Pregnancy.html index b366ecc..0a24007 100644 --- a/public/patientapi/symbols/hQuery.Pregnancy.html +++ b/public/patientapi/symbols/hQuery.Pregnancy.html @@ -357,7 +357,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, regex_includesCodeFrom, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    @@ -495,7 +495,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Procedure.html b/public/patientapi/symbols/hQuery.Procedure.html index 214799d..f6e2011 100644 --- a/public/patientapi/symbols/hQuery.Procedure.html +++ b/public/patientapi/symbols/hQuery.Procedure.html @@ -393,7 +393,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, regex_includesCodeFrom, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    @@ -660,7 +660,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Provider.html b/public/patientapi/symbols/hQuery.Provider.html index 41a692d..fd8aad6 100644 --- a/public/patientapi/symbols/hQuery.Provider.html +++ b/public/patientapi/symbols/hQuery.Provider.html @@ -722,7 +722,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Result.html b/public/patientapi/symbols/hQuery.Result.html index f64e6b3..349cf5b 100644 --- a/public/patientapi/symbols/hQuery.Result.html +++ b/public/patientapi/symbols/hQuery.Result.html @@ -385,7 +385,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, regex_includesCodeFrom, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    @@ -623,7 +623,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Scalar.html b/public/patientapi/symbols/hQuery.Scalar.html index 9c9b864..621aa1b 100644 --- a/public/patientapi/symbols/hQuery.Scalar.html +++ b/public/patientapi/symbols/hQuery.Scalar.html @@ -503,7 +503,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Status.html b/public/patientapi/symbols/hQuery.Status.html index 44dd1d0..dedf3b9 100644 --- a/public/patientapi/symbols/hQuery.Status.html +++ b/public/patientapi/symbols/hQuery.Status.html @@ -438,7 +438,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, regex_includesCodeFrom, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    @@ -783,7 +783,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.StatusOfMedication.html b/public/patientapi/symbols/hQuery.StatusOfMedication.html index 2fc2c04..6db9d46 100644 --- a/public/patientapi/symbols/hQuery.StatusOfMedication.html +++ b/public/patientapi/symbols/hQuery.StatusOfMedication.html @@ -384,7 +384,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, regex_includesCodeFrom, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    @@ -607,7 +607,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:50 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Supports.html b/public/patientapi/symbols/hQuery.Supports.html index 251a10e..79f8d0a 100644 --- a/public/patientapi/symbols/hQuery.Supports.html +++ b/public/patientapi/symbols/hQuery.Supports.html @@ -640,7 +640,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:50 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Telecom.html b/public/patientapi/symbols/hQuery.Telecom.html index 3bd98dc..5a532c2 100644 --- a/public/patientapi/symbols/hQuery.Telecom.html +++ b/public/patientapi/symbols/hQuery.Telecom.html @@ -600,7 +600,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:50 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.TypeOfMedication.html b/public/patientapi/symbols/hQuery.TypeOfMedication.html index 47c1e9a..86d8b01 100644 --- a/public/patientapi/symbols/hQuery.TypeOfMedication.html +++ b/public/patientapi/symbols/hQuery.TypeOfMedication.html @@ -368,7 +368,7 @@

    -
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    +
    Methods borrowed from class hQuery.CodedEntry:
    date, endDate, freeTextType, includesCodeFrom, isTimeRange, isUsable, negationInd, negationReason, reason, regex_includesCodeFrom, setTimestamp, startDate, status, statusCode, timeStamp, type, values
    @@ -528,7 +528,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 02 2013 14:27:50 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/src/tmp_patient.js.html b/public/patientapi/symbols/src/tmp_patient.js.html index 8a159be..c3b4740 100644 --- a/public/patientapi/symbols/src/tmp_patient.js.html +++ b/public/patientapi/symbols/src/tmp_patient.js.html @@ -9,3304 +9,3446 @@ 2 @namespace scoping into the hquery namespace 3 */ 4 - 5 var _ref, - 6 __hasProp = {}.hasOwnProperty, - 7 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, - 8 __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - 9 - 10 this.hQuery || (this.hQuery = {}); - 11 - 12 /** - 13 Converts a a number in UTC Seconds since the epoch to a date. - 14 @param {number} utcSeconds seconds since the epoch in UTC - 15 @returns {Date} - 16 @function - 17 @exports dateFromUtcSeconds as hQuery.dateFromUtcSeconds - 18 */ + 5 var __hasProp = {}.hasOwnProperty, + 6 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }, + 7 __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; + 8 + 9 this.hQuery || (this.hQuery = {}); + 10 + 11 /** + 12 Converts a a number in UTC Seconds since the epoch to a date. + 13 @param {number} utcSeconds seconds since the epoch in UTC + 14 @returns {Date} + 15 @function + 16 @exports dateFromUtcSeconds as hQuery.dateFromUtcSeconds + 17 */ + 18 19 - 20 - 21 hQuery.dateFromUtcSeconds = function(utcSeconds) { - 22 return new Date(utcSeconds * 1000); - 23 }; - 24 - 25 /** - 26 @class Scalar - a representation of a unit and value - 27 @exports Scalar as hQuery.Scalar - 28 */ + 20 hQuery.dateFromUtcSeconds = function(utcSeconds) { + 21 return new Date(utcSeconds * 1000); + 22 }; + 23 + 24 /** + 25 @class Scalar - a representation of a unit and value + 26 @exports Scalar as hQuery.Scalar + 27 */ + 28 29 - 30 - 31 hQuery.Scalar = (function() { - 32 function Scalar(json) { - 33 this.json = json; - 34 } - 35 - 36 Scalar.prototype.unit = function() { - 37 return this.json['unit']; - 38 }; - 39 - 40 Scalar.prototype.value = function() { - 41 return this.json['value']; - 42 }; - 43 - 44 return Scalar; + 30 hQuery.Scalar = (function() { + 31 + 32 Scalar.name = 'Scalar'; + 33 + 34 function Scalar(json) { + 35 this.json = json; + 36 } + 37 + 38 Scalar.prototype.unit = function() { + 39 return this.json['unit']; + 40 }; + 41 + 42 Scalar.prototype.value = function() { + 43 return this.json['value']; + 44 }; 45 - 46 })(); + 46 return Scalar; 47 - 48 /** - 49 @class PhysicalQuantity - a representation of a physical quantity - 50 @exports PhysicalQuantity as hQuery.PhysicalQuantity - 51 */ - 52 - 53 - 54 hQuery.PhysicalQuantity = (function() { - 55 function PhysicalQuantity(json) { - 56 this.json = json; - 57 } - 58 - 59 PhysicalQuantity.prototype.units = function() { - 60 return this.json['units']; - 61 }; - 62 - 63 PhysicalQuantity.prototype.scalar = function() { - 64 return parseFloat(this.json['scalar']); - 65 }; - 66 - 67 return PhysicalQuantity; - 68 - 69 })(); - 70 - 71 /** - 72 @class A code with its corresponding code system - 73 @exports CodedValue as hQuery.CodedValue - 74 */ + 48 })(); + 49 + 50 /** + 51 @class PhysicalQuantity - a representation of a physical quantity + 52 @exports PhysicalQuantity as hQuery.PhysicalQuantity + 53 */ + 54 + 55 + 56 hQuery.PhysicalQuantity = (function() { + 57 + 58 PhysicalQuantity.name = 'PhysicalQuantity'; + 59 + 60 function PhysicalQuantity(json) { + 61 this.json = json; + 62 } + 63 + 64 PhysicalQuantity.prototype.units = function() { + 65 return this.json['units']; + 66 }; + 67 + 68 PhysicalQuantity.prototype.scalar = function() { + 69 return parseFloat(this.json['scalar']); + 70 }; + 71 + 72 return PhysicalQuantity; + 73 + 74 })(); 75 - 76 - 77 hQuery.CodedValue = (function() { - 78 /** - 79 @param {String} c value of the code - 80 @param {String} csn name of the code system that the code belongs to - 81 @constructs - 82 */ - 83 function CodedValue(c, csn) { - 84 this.c = c; - 85 this.csn = csn; - 86 } - 87 - 88 /** - 89 @returns {String} the code + 76 /** + 77 @class A code with its corresponding code system + 78 @exports CodedValue as hQuery.CodedValue + 79 */ + 80 + 81 + 82 hQuery.CodedValue = (function() { + 83 + 84 CodedValue.name = 'CodedValue'; + 85 + 86 /** + 87 @param {String} c value of the code + 88 @param {String} csn name of the code system that the code belongs to + 89 @constructs 90 */ 91 92 - 93 CodedValue.prototype.code = function() { - 94 return this.c; - 95 }; - 96 - 97 /** - 98 @returns {String} the code system name - 99 */ -100 + 93 function CodedValue(c, csn) { + 94 this.c = c; + 95 this.csn = csn; + 96 } + 97 + 98 /** + 99 @returns {String} the code +100 */ 101 -102 CodedValue.prototype.codeSystemName = function() { -103 return this.csn; -104 }; -105 -106 CodedValue.normalize = function(val) { -107 return String(val).toLowerCase(); -108 }; -109 -110 /** -111 Returns true if the contained code and codeSystemName match a code in the supplied codeSet. -112 @param {Object} codeSet a hash with code system names as keys and an array of codes as values -113 @returns {boolean} -114 */ +102 +103 CodedValue.prototype.code = function() { +104 return this.c; +105 }; +106 +107 /** +108 @returns {String} the code system name +109 */ +110 +111 +112 CodedValue.prototype.codeSystemName = function() { +113 return this.csn; +114 }; 115 -116 -117 CodedValue.prototype.includedIn = function(codeSet) { -118 var c1, c2, code, codeSystemName, codes, _i, _len; +116 CodedValue.normalize = function(val) { +117 return String(val).toLowerCase(); +118 }; 119 -120 for (codeSystemName in codeSet) { -121 codes = codeSet[codeSystemName]; -122 if (this.csn === codeSystemName) { -123 for (_i = 0, _len = codes.length; _i < _len; _i++) { -124 code = codes[_i]; -125 c1 = hQuery.CodedValue.normalize(code); -126 c2 = hQuery.CodedValue.normalize(this.c); -127 if (c1 === c2) { -128 return true; -129 } -130 } -131 } -132 } -133 return false; -134 }; -135 -136 return CodedValue; -137 -138 })(); -139 -140 /** -141 Status as defined by value set 2.16.840.1.113883.5.14, -142 the ActStatus vocabulary maintained by HL7 -143 -144 @class Status -145 @augments hQuery.CodedEntry -146 @exports Status as hQuery.Status -147 */ -148 -149 -150 hQuery.Status = (function(_super) { -151 var ABORTED, ACTIVE, CANCELLED, COMPLETED, HELD, NEW, NORMAL, NULLIFIED, OBSOLETE, SUSPENDED; -152 -153 __extends(Status, _super); -154 -155 function Status() { -156 _ref = Status.__super__.constructor.apply(this, arguments); -157 return _ref; -158 } -159 -160 NORMAL = "normal"; -161 -162 ABORTED = "aborted"; -163 -164 ACTIVE = "active"; -165 -166 CANCELLED = "cancelled"; -167 -168 COMPLETED = "completed"; -169 -170 HELD = "held"; -171 -172 NEW = "new"; -173 -174 SUSPENDED = "suspended"; -175 -176 NULLIFIED = "nullified"; -177 -178 OBSOLETE = "obsolete"; -179 -180 Status.prototype.isNormal = function() { -181 return this.c === NORMAL; -182 }; -183 -184 Status.prototype.isAborted = function() { -185 return this.c === ABORTED; -186 }; +120 /** +121 Returns true if the contained code and codeSystemName match a code in the supplied codeSet. +122 @param {Object} codeSet a hash with code system names as keys and an array of codes as values +123 @returns {boolean} +124 */ +125 +126 +127 CodedValue.prototype.includedIn = function(codeSet) { +128 var c1, c2, code, codeSystemName, codes, _i, _len; +129 for (codeSystemName in codeSet) { +130 codes = codeSet[codeSystemName]; +131 if (this.csn === codeSystemName) { +132 for (_i = 0, _len = codes.length; _i < _len; _i++) { +133 code = codes[_i]; +134 c1 = hQuery.CodedValue.normalize(code); +135 c2 = hQuery.CodedValue.normalize(this.c); +136 if (c1 === c2) { +137 return true; +138 } +139 } +140 } +141 } +142 return false; +143 }; +144 +145 /** +146 Returns true if the contained code and codeSystemName match a code in the supplied codeSet. +147 @param {Object} codeSet a hash with code system names as keys and an array of codes (provided as regular expressions) as values +148 @returns {boolean} +149 */ +150 +151 +152 CodedValue.prototype.regex_includedIn = function(codeSet) { +153 var code, codeSystemName, codes, regex, _i, _len; +154 for (codeSystemName in codeSet) { +155 codes = codeSet[codeSystemName]; +156 if (this.csn === codeSystemName) { +157 for (_i = 0, _len = codes.length; _i < _len; _i++) { +158 code = codes[_i]; +159 regex = RegExp(code, "i"); +160 if (regex.test(this.c)) { +161 return true; +162 } +163 } +164 } +165 } +166 return false; +167 }; +168 +169 return CodedValue; +170 +171 })(); +172 +173 /** +174 Status as defined by value set 2.16.840.1.113883.5.14, +175 the ActStatus vocabulary maintained by HL7 +176 +177 @class Status +178 @augments hQuery.CodedEntry +179 @exports Status as hQuery.Status +180 */ +181 +182 +183 hQuery.Status = (function(_super) { +184 var ABORTED, ACTIVE, CANCELLED, COMPLETED, HELD, NEW, NORMAL, NULLIFIED, OBSOLETE, SUSPENDED; +185 +186 __extends(Status, _super); 187 -188 Status.prototype.isActive = function() { -189 return this.c === ACTIVE; -190 }; -191 -192 Status.prototype.isCancelled = function() { -193 return this.c === CANCELLED; -194 }; +188 Status.name = 'Status'; +189 +190 function Status() { +191 return Status.__super__.constructor.apply(this, arguments); +192 } +193 +194 NORMAL = "normal"; 195 -196 Status.prototype.isCompleted = function() { -197 return this.c === COMPLETED; -198 }; +196 ABORTED = "aborted"; +197 +198 ACTIVE = "active"; 199 -200 Status.prototype.isHeld = function() { -201 return this.c === HELD; -202 }; +200 CANCELLED = "cancelled"; +201 +202 COMPLETED = "completed"; 203 -204 Status.prototype.isNew = function() { -205 return this.c === NEW; -206 }; +204 HELD = "held"; +205 +206 NEW = "new"; 207 -208 Status.prototype.isSuspended = function() { -209 return this.c === SUSPENDED; -210 }; +208 SUSPENDED = "suspended"; +209 +210 NULLIFIED = "nullified"; 211 -212 Status.prototype.isNullified = function() { -213 return this.c === NULLIFIED; -214 }; -215 -216 Status.prototype.isObsolete = function() { -217 return this.c === OBSOLETE; -218 }; -219 -220 return Status; +212 OBSOLETE = "obsolete"; +213 +214 Status.prototype.isNormal = function() { +215 return this.c === NORMAL; +216 }; +217 +218 Status.prototype.isAborted = function() { +219 return this.c === ABORTED; +220 }; 221 -222 })(hQuery.CodedValue); -223 -224 /** -225 @class an Address for a person or organization -226 @exports Address as hQuery.Address -227 */ -228 +222 Status.prototype.isActive = function() { +223 return this.c === ACTIVE; +224 }; +225 +226 Status.prototype.isCancelled = function() { +227 return this.c === CANCELLED; +228 }; 229 -230 hQuery.Address = (function() { -231 function Address(json) { -232 this.json = json; -233 } -234 -235 /** -236 @returns {Array[String]} the street addresses -237 */ -238 -239 -240 Address.prototype.street = function() { -241 return this.json['street']; -242 }; -243 -244 /** -245 @returns {String} the city -246 */ -247 -248 -249 Address.prototype.city = function() { -250 return this.json['city']; -251 }; -252 -253 /** -254 @returns {String} the State -255 */ -256 +230 Status.prototype.isCompleted = function() { +231 return this.c === COMPLETED; +232 }; +233 +234 Status.prototype.isHeld = function() { +235 return this.c === HELD; +236 }; +237 +238 Status.prototype.isNew = function() { +239 return this.c === NEW; +240 }; +241 +242 Status.prototype.isSuspended = function() { +243 return this.c === SUSPENDED; +244 }; +245 +246 Status.prototype.isNullified = function() { +247 return this.c === NULLIFIED; +248 }; +249 +250 Status.prototype.isObsolete = function() { +251 return this.c === OBSOLETE; +252 }; +253 +254 return Status; +255 +256 })(hQuery.CodedValue); 257 -258 Address.prototype.state = function() { -259 return this.json['state']; -260 }; -261 -262 /** -263 @returns {String} the postal code -264 */ +258 /** +259 @class an Address for a person or organization +260 @exports Address as hQuery.Address +261 */ +262 +263 +264 hQuery.Address = (function() { 265 -266 -267 Address.prototype.postalCode = function() { -268 return this.json['zip']; -269 }; -270 -271 return Address; -272 -273 })(); -274 -275 /** -276 @class An object that describes a means to contact an entity. This is used to represent -277 phone numbers, email addresses, instant messaging accounts etc. -278 @exports Telecom as hQuery.Telecom -279 */ +266 Address.name = 'Address'; +267 +268 function Address(json) { +269 this.json = json; +270 } +271 +272 /** +273 @returns {Array[String]} the street addresses +274 */ +275 +276 +277 Address.prototype.street = function() { +278 return this.json['street']; +279 }; 280 -281 -282 hQuery.Telecom = (function() { -283 function Telecom(json) { -284 this.json = json; -285 } -286 -287 /** -288 @returns {String} the type of telecom entry, phone, sms, email .... -289 */ -290 -291 -292 Telecom.prototype.type = function() { -293 return this.json['type']; -294 }; -295 -296 /** -297 @returns {String} the value of the entry - the actual phone number , email address , .... -298 */ -299 -300 -301 Telecom.prototype.value = function() { -302 return this.json['value']; -303 }; -304 -305 /** -306 @returns {String} the use of the entry. Is it a home, office, .... type of contact -307 */ -308 +281 /** +282 @returns {String} the city +283 */ +284 +285 +286 Address.prototype.city = function() { +287 return this.json['city']; +288 }; +289 +290 /** +291 @returns {String} the State +292 */ +293 +294 +295 Address.prototype.state = function() { +296 return this.json['state']; +297 }; +298 +299 /** +300 @returns {String} the postal code +301 */ +302 +303 +304 Address.prototype.postalCode = function() { +305 return this.json['zip']; +306 }; +307 +308 return Address; 309 -310 Telecom.prototype.use = function() { -311 return this.json['use']; -312 }; -313 -314 /** -315 @returns {Boolean} is this a preferred form of contact -316 */ +310 })(); +311 +312 /** +313 @class An object that describes a means to contact an entity. This is used to represent +314 phone numbers, email addresses, instant messaging accounts etc. +315 @exports Telecom as hQuery.Telecom +316 */ 317 318 -319 Telecom.prototype.preferred = function() { -320 return this.json['preferred']; -321 }; +319 hQuery.Telecom = (function() { +320 +321 Telecom.name = 'Telecom'; 322 -323 return Telecom; -324 -325 })(); +323 function Telecom(json) { +324 this.json = json; +325 } 326 -327 /** -328 @class an object that describes a person. includes a persons name, addresses, and contact information -329 @exports Person as hQuery.Person -330 */ +327 /** +328 @returns {String} the type of telecom entry, phone, sms, email .... +329 */ +330 331 -332 -333 hQuery.Person = (function() { -334 function Person(json) { -335 this.json = json; -336 } -337 -338 /** -339 @returns {String} the given name of the person -340 */ -341 -342 -343 Person.prototype.given = function() { -344 return this.json['first']; -345 }; -346 -347 /** -348 @returns {String} the last/family name of the person -349 */ -350 -351 -352 Person.prototype.last = function() { -353 return this.json['last']; -354 }; -355 -356 /** -357 @returns {String} the display name of the person -358 */ -359 -360 -361 Person.prototype.name = function() { -362 if (this.json['name']) { -363 return this.json['name']; -364 } else { -365 return this.json['first'] + ' ' + this.json['last']; -366 } -367 }; -368 -369 /** -370 @returns {Array} an array of {@link hQuery.Address} objects associated with the patient -371 */ +332 Telecom.prototype.type = function() { +333 return this.json['type']; +334 }; +335 +336 /** +337 @returns {String} the value of the entry - the actual phone number , email address , .... +338 */ +339 +340 +341 Telecom.prototype.value = function() { +342 return this.json['value']; +343 }; +344 +345 /** +346 @returns {String} the use of the entry. Is it a home, office, .... type of contact +347 */ +348 +349 +350 Telecom.prototype.use = function() { +351 return this.json['use']; +352 }; +353 +354 /** +355 @returns {Boolean} is this a preferred form of contact +356 */ +357 +358 +359 Telecom.prototype.preferred = function() { +360 return this.json['preferred']; +361 }; +362 +363 return Telecom; +364 +365 })(); +366 +367 /** +368 @class an object that describes a person. includes a persons name, addresses, and contact information +369 @exports Person as hQuery.Person +370 */ +371 372 -373 -374 Person.prototype.addresses = function() { -375 var address, list, _i, _len, _ref1; +373 hQuery.Person = (function() { +374 +375 Person.name = 'Person'; 376 -377 list = []; -378 if (this.json['addresses']) { -379 _ref1 = this.json['addresses']; -380 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -381 address = _ref1[_i]; -382 list.push(new hQuery.Address(address)); -383 } -384 } -385 return list; -386 }; -387 -388 /** -389 @returns {Array} an array of {@link hQuery.Telecom} objects associated with the person -390 */ -391 -392 -393 Person.prototype.telecoms = function() { -394 var tel, _i, _len, _ref1, _results; -395 -396 _ref1 = this.json['telecoms']; -397 _results = []; -398 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -399 tel = _ref1[_i]; -400 _results.push(new hQuery.Telecom(tel)); -401 } -402 return _results; -403 }; -404 -405 return Person; -406 -407 })(); -408 -409 /** -410 @class an actor is either a person or an organization -411 @exports Actor as hQuery.Actor -412 */ -413 -414 -415 hQuery.Actor = (function() { -416 function Actor(json) { -417 this.json = json; -418 } -419 -420 Actor.prototype.person = function() { -421 if (this.json['person']) { -422 return new hQuery.Person(this.json['person']); -423 } -424 }; -425 -426 Actor.prototype.organization = function() { -427 if (this.json['organization']) { -428 return new hQuery.Organization(this.json['organization']); -429 } -430 }; -431 -432 return Actor; +377 function Person(json) { +378 this.json = json; +379 } +380 +381 /** +382 @returns {String} the given name of the person +383 */ +384 +385 +386 Person.prototype.given = function() { +387 return this.json['first']; +388 }; +389 +390 /** +391 @returns {String} the last/family name of the person +392 */ +393 +394 +395 Person.prototype.last = function() { +396 return this.json['last']; +397 }; +398 +399 /** +400 @returns {String} the display name of the person +401 */ +402 +403 +404 Person.prototype.name = function() { +405 if (this.json['name']) { +406 return this.json['name']; +407 } else { +408 return this.json['first'] + ' ' + this.json['last']; +409 } +410 }; +411 +412 /** +413 @returns {Array} an array of {@link hQuery.Address} objects associated with the patient +414 */ +415 +416 +417 Person.prototype.addresses = function() { +418 var address, list, _i, _len, _ref; +419 list = []; +420 if (this.json['addresses']) { +421 _ref = this.json['addresses']; +422 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +423 address = _ref[_i]; +424 list.push(new hQuery.Address(address)); +425 } +426 } +427 return list; +428 }; +429 +430 /** +431 @returns {Array} an array of {@link hQuery.Telecom} objects associated with the person +432 */ 433 -434 })(); -435 -436 /** -437 @class an Organization -438 @exports Organization as hQuery.Organization -439 */ -440 -441 -442 hQuery.Organization = (function() { -443 function Organization(json) { -444 this.json = json; -445 } -446 -447 /** -448 @returns {String} the id for the organization -449 */ -450 -451 -452 Organization.prototype.organizationId = function() { -453 return this.json['organizationId']; -454 }; +434 +435 Person.prototype.telecoms = function() { +436 var tel, _i, _len, _ref, _results; +437 _ref = this.json['telecoms']; +438 _results = []; +439 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +440 tel = _ref[_i]; +441 _results.push(new hQuery.Telecom(tel)); +442 } +443 return _results; +444 }; +445 +446 return Person; +447 +448 })(); +449 +450 /** +451 @class an actor is either a person or an organization +452 @exports Actor as hQuery.Actor +453 */ +454 455 -456 /** -457 @returns {String} the name of the organization -458 */ +456 hQuery.Actor = (function() { +457 +458 Actor.name = 'Actor'; 459 -460 -461 Organization.prototype.organizationName = function() { -462 return this.json['name']; -463 }; -464 -465 /** -466 @returns {Array} an array of {@link hQuery.Address} objects associated with the organization -467 */ -468 +460 function Actor(json) { +461 this.json = json; +462 } +463 +464 Actor.prototype.person = function() { +465 if (this.json['person']) { +466 return new hQuery.Person(this.json['person']); +467 } +468 }; 469 -470 Organization.prototype.addresses = function() { -471 var address, list, _i, _len, _ref1; -472 -473 list = []; -474 if (this.json['addresses']) { -475 _ref1 = this.json['addresses']; -476 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -477 address = _ref1[_i]; -478 list.push(new hQuery.Address(address)); -479 } -480 } -481 return list; -482 }; -483 -484 /** -485 @returns {Array} an array of {@link hQuery.Telecom} objects associated with the organization -486 */ +470 Actor.prototype.organization = function() { +471 if (this.json['organization']) { +472 return new hQuery.Organization(this.json['organization']); +473 } +474 }; +475 +476 return Actor; +477 +478 })(); +479 +480 /** +481 @class an Organization +482 @exports Organization as hQuery.Organization +483 */ +484 +485 +486 hQuery.Organization = (function() { 487 -488 -489 Organization.prototype.telecoms = function() { -490 var tel, _i, _len, _ref1, _results; -491 -492 _ref1 = this.json['telecoms']; -493 _results = []; -494 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -495 tel = _ref1[_i]; -496 _results.push(new hQuery.Telecom(tel)); -497 } -498 return _results; -499 }; -500 -501 return Organization; +488 Organization.name = 'Organization'; +489 +490 function Organization(json) { +491 this.json = json; +492 } +493 +494 /** +495 @returns {String} the id for the organization +496 */ +497 +498 +499 Organization.prototype.organizationId = function() { +500 return this.json['organizationId']; +501 }; 502 -503 })(); -504 -505 /** -506 @class a Facility -507 @exports Organization as hQuery.Facility -508 */ -509 -510 -511 hQuery.Facility = (function(_super) { -512 __extends(Facility, _super); -513 -514 function Facility(json) { -515 this.json = json; -516 if (this.json['code'] != null) { -517 Facility.__super__.constructor.call(this, this.json['code']['code'], this.json['code']['code_system']); -518 } -519 if (this.json['start_time']) { -520 this._startDate = hQuery.dateFromUtcSeconds(this.json['start_time']); -521 } -522 if (this.json['end_time']) { -523 this._endDate = hQuery.dateFromUtcSeconds(this.json['end_time']); -524 } -525 } -526 -527 /** -528 @returns {String} the name of the facility -529 */ -530 -531 -532 Facility.prototype.name = function() { -533 return this.json['name']; -534 }; -535 -536 /** -537 Date and time at which the coded entry started -538 @returns {Date} -539 */ -540 -541 -542 Facility.prototype.startDate = function() { -543 return this._startDate; +503 /** +504 @returns {String} the name of the organization +505 */ +506 +507 +508 Organization.prototype.organizationName = function() { +509 return this.json['name']; +510 }; +511 +512 /** +513 @returns {Array} an array of {@link hQuery.Address} objects associated with the organization +514 */ +515 +516 +517 Organization.prototype.addresses = function() { +518 var address, list, _i, _len, _ref; +519 list = []; +520 if (this.json['addresses']) { +521 _ref = this.json['addresses']; +522 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +523 address = _ref[_i]; +524 list.push(new hQuery.Address(address)); +525 } +526 } +527 return list; +528 }; +529 +530 /** +531 @returns {Array} an array of {@link hQuery.Telecom} objects associated with the organization +532 */ +533 +534 +535 Organization.prototype.telecoms = function() { +536 var tel, _i, _len, _ref, _results; +537 _ref = this.json['telecoms']; +538 _results = []; +539 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +540 tel = _ref[_i]; +541 _results.push(new hQuery.Telecom(tel)); +542 } +543 return _results; 544 }; 545 -546 /** -547 Date and time at which the coded entry ended -548 @returns {Date} -549 */ -550 -551 -552 Facility.prototype.endDate = function() { -553 return this._endDate; -554 }; +546 return Organization; +547 +548 })(); +549 +550 /** +551 @class a Facility +552 @exports Organization as hQuery.Facility +553 */ +554 555 -556 /** -557 @returns {Array} an array of {@link hQuery.Address} objects associated with the facility -558 */ +556 hQuery.Facility = (function(_super) { +557 +558 __extends(Facility, _super); 559 -560 -561 Facility.prototype.addresses = function() { -562 var address, list, _i, _len, _ref1; -563 -564 list = []; -565 if (this.json['addresses']) { -566 _ref1 = this.json['addresses']; -567 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -568 address = _ref1[_i]; -569 list.push(new hQuery.Address(address)); -570 } -571 } -572 return list; -573 }; +560 Facility.name = 'Facility'; +561 +562 function Facility(json) { +563 this.json = json; +564 if (this.json['code'] != null) { +565 Facility.__super__.constructor.call(this, this.json['code']['code'], this.json['code']['codeSystem']); +566 } +567 if (this.json['start_time']) { +568 this._startDate = hQuery.dateFromUtcSeconds(this.json['start_time']); +569 } +570 if (this.json['end_time']) { +571 this._endDate = hQuery.dateFromUtcSeconds(this.json['end_time']); +572 } +573 } 574 575 /** -576 @returns {Array} an array of {@link hQuery.Telecom} objects associated with the facility +576 @returns {String} the name of the facility 577 */ 578 579 -580 Facility.prototype.telecoms = function() { -581 var tel, _i, _len, _ref1, _results; -582 -583 _ref1 = this.json['telecoms']; -584 _results = []; -585 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -586 tel = _ref1[_i]; -587 _results.push(new hQuery.Telecom(tel)); -588 } -589 return _results; -590 }; -591 -592 return Facility; +580 Facility.prototype.name = function() { +581 return this.json['name']; +582 }; +583 +584 /** +585 Date and time at which the coded entry started +586 @returns {Date} +587 */ +588 +589 +590 Facility.prototype.startDate = function() { +591 return this._startDate; +592 }; 593 -594 })(hQuery.CodedValue); -595 -596 /** -597 @class represents a DateRange in the form of hi and low date values. -598 @exports DateRange as hQuery.DateRange -599 */ -600 -601 -602 hQuery.DateRange = (function() { -603 function DateRange(json) { -604 this.json = json; -605 } -606 -607 DateRange.prototype.hi = function() { -608 if (this.json['hi']) { -609 return hQuery.dateFromUtcSeconds(this.json['hi']); -610 } -611 }; -612 -613 DateRange.prototype.low = function() { -614 return hQuery.dateFromUtcSeconds(this.json['low']); -615 }; -616 -617 return DateRange; -618 -619 })(); -620 -621 /** -622 @class Class used to describe an entity that is providing some form of information. This does not mean that they are -623 providing any treatment just that they are providing information. -624 @exports Informant as hQuery.Informant -625 */ +594 /** +595 Date and time at which the coded entry ended +596 @returns {Date} +597 */ +598 +599 +600 Facility.prototype.endDate = function() { +601 return this._endDate; +602 }; +603 +604 /** +605 @returns {Array} an array of {@link hQuery.Address} objects associated with the facility +606 */ +607 +608 +609 Facility.prototype.addresses = function() { +610 var address, list, _i, _len, _ref; +611 list = []; +612 if (this.json['addresses']) { +613 _ref = this.json['addresses']; +614 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +615 address = _ref[_i]; +616 list.push(new hQuery.Address(address)); +617 } +618 } +619 return list; +620 }; +621 +622 /** +623 @returns {Array} an array of {@link hQuery.Telecom} objects associated with the facility +624 */ +625 626 -627 -628 hQuery.Informant = (function() { -629 function Informant(json) { -630 this.json = json; -631 } -632 -633 /** -634 an array of hQuery.Person objects as points of contact -635 @returns {Array} -636 */ +627 Facility.prototype.telecoms = function() { +628 var tel, _i, _len, _ref, _results; +629 _ref = this.json['telecoms']; +630 _results = []; +631 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +632 tel = _ref[_i]; +633 _results.push(new hQuery.Telecom(tel)); +634 } +635 return _results; +636 }; 637 -638 -639 Informant.prototype.contacts = function() { -640 var contact, _i, _len, _ref1, _results; +638 return Facility; +639 +640 })(hQuery.CodedValue); 641 -642 _ref1 = this.json['contacts']; -643 _results = []; -644 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -645 contact = _ref1[_i]; -646 _results.push(new hQuery.Person(contact)); -647 } -648 return _results; -649 }; -650 -651 /** -652 @returns {hQuery.Organization} the organization providing the information -653 */ -654 +642 /** +643 @class represents a DateRange in the form of hi and low date values. +644 @exports DateRange as hQuery.DateRange +645 */ +646 +647 +648 hQuery.DateRange = (function() { +649 +650 DateRange.name = 'DateRange'; +651 +652 function DateRange(json) { +653 this.json = json; +654 } 655 -656 Informant.prototype.organization = function() { -657 return new hQuery.Organization(this.json['organization']); -658 }; -659 -660 return Informant; +656 DateRange.prototype.hi = function() { +657 if (this.json['hi']) { +658 return hQuery.dateFromUtcSeconds(this.json['hi']); +659 } +660 }; 661 -662 })(); -663 -664 /** -665 @class -666 @exports CodedEntry as hQuery.CodedEntry -667 */ -668 +662 DateRange.prototype.low = function() { +663 return hQuery.dateFromUtcSeconds(this.json['low']); +664 }; +665 +666 return DateRange; +667 +668 })(); 669 -670 hQuery.CodedEntry = (function() { -671 function CodedEntry(json) { -672 this.json = json; -673 if (this.json['time']) { -674 this._date = hQuery.dateFromUtcSeconds(this.json['time']); -675 } -676 if (this.json['start_time']) { -677 this._startDate = hQuery.dateFromUtcSeconds(this.json['start_time']); -678 } -679 if (this.json['end_time']) { -680 this._endDate = hQuery.dateFromUtcSeconds(this.json['end_time']); -681 } -682 this._type = hQuery.createCodedValues(this.json['codes']); -683 this._statusCode = this.json['status_code']; -684 this.id = "" + this.json['_id']; -685 this.source_id = this.json['id']; -686 this._freeTextType = this.json['description']; -687 } -688 -689 /** -690 Adjust the start and end times of this event to the supplied timestamp -691 */ -692 -693 -694 CodedEntry.prototype.setTimestamp = function(timestamp) { -695 return this._date = this._startDate = this._endDate = timestamp; -696 }; -697 -698 /** -699 Date and time at which the coded entry took place -700 @returns {Date} -701 */ -702 -703 -704 CodedEntry.prototype.date = function() { -705 return this._date; -706 }; -707 -708 /** -709 Date and time at which the coded entry started -710 @returns {Date} -711 */ +670 /** +671 @class Class used to describe an entity that is providing some form of information. This does not mean that they are +672 providing any treatment just that they are providing information. +673 @exports Informant as hQuery.Informant +674 */ +675 +676 +677 hQuery.Informant = (function() { +678 +679 Informant.name = 'Informant'; +680 +681 function Informant(json) { +682 this.json = json; +683 } +684 +685 /** +686 an array of hQuery.Person objects as points of contact +687 @returns {Array} +688 */ +689 +690 +691 Informant.prototype.contacts = function() { +692 var contact, _i, _len, _ref, _results; +693 _ref = this.json['contacts']; +694 _results = []; +695 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +696 contact = _ref[_i]; +697 _results.push(new hQuery.Person(contact)); +698 } +699 return _results; +700 }; +701 +702 /** +703 @returns {hQuery.Organization} the organization providing the information +704 */ +705 +706 +707 Informant.prototype.organization = function() { +708 return new hQuery.Organization(this.json['organization']); +709 }; +710 +711 return Informant; 712 -713 -714 CodedEntry.prototype.startDate = function() { -715 return this._startDate; -716 }; -717 -718 /** -719 Date and time at which the coded entry ended -720 @returns {Date} -721 */ +713 })(); +714 +715 /** +716 @class +717 @exports CodedEntry as hQuery.CodedEntry +718 */ +719 +720 +721 hQuery.CodedEntry = (function() { 722 -723 -724 CodedEntry.prototype.endDate = function() { -725 return this._endDate; -726 }; -727 -728 /** -729 Tries to find a single point in time for this entry. Will first return date if it is present, -730 then fall back to startDate and finally endDate -731 @returns {Date} -732 */ -733 -734 -735 CodedEntry.prototype.timeStamp = function() { -736 return this._date || this._startDate || this._endDate; -737 }; -738 -739 /** -740 Determines whether the entry specifies a time range or not -741 @returns {boolean} -742 */ -743 -744 -745 CodedEntry.prototype.isTimeRange = function() { -746 return (this._startDate != null) && (this._endDate != null); -747 }; -748 -749 /** -750 Determines whether a coded entry contains sufficient information (code and at least -751 one time stamp) to be usable -752 @returns {boolean} -753 */ -754 -755 -756 CodedEntry.prototype.isUsable = function() { -757 return this._type.length > 0 && (this._date || this._startDate || this._endDate); -758 }; -759 -760 /** -761 An Array of CodedValues which describe what kind of coded entry took place -762 @returns {Array} -763 */ -764 -765 -766 CodedEntry.prototype.type = function() { -767 return this._type; -768 }; -769 -770 /** -771 A free text description of the type of coded entry -772 @returns {String} -773 */ -774 -775 -776 CodedEntry.prototype.freeTextType = function() { -777 return this._freeTextType; -778 }; -779 -780 /** -781 Status for this coded entry -782 @returns {String} -783 */ -784 -785 -786 CodedEntry.prototype.status = function() { -787 if (this._statusCode != null) { -788 if (this._statusCode['HL7 ActStatus'] != null) { -789 return this._statusCode['HL7 ActStatus'][0]; -790 } else if (this._statusCode['SNOMED-CT'] != null) { -791 switch (this._statusCode['SNOMED-CT'][0]) { -792 case '55561003': -793 return 'active'; -794 case '73425007': -795 return 'inactive'; -796 case '413322009': -797 return 'resolved'; -798 } -799 } -800 } +723 CodedEntry.name = 'CodedEntry'; +724 +725 function CodedEntry(json) { +726 this.json = json; +727 if (this.json['time']) { +728 this._date = hQuery.dateFromUtcSeconds(this.json['time']); +729 } +730 if (this.json['start_time']) { +731 this._startDate = hQuery.dateFromUtcSeconds(this.json['start_time']); +732 } +733 if (this.json['end_time']) { +734 this._endDate = hQuery.dateFromUtcSeconds(this.json['end_time']); +735 } +736 this._type = hQuery.createCodedValues(this.json['codes']); +737 this._statusCode = this.json['status_code']; +738 this.id = "" + this.json['_id']; +739 this.source_id = this.json['id']; +740 this._freeTextType = this.json['description']; +741 } +742 +743 /** +744 Adjust the start and end times of this event to the supplied timestamp +745 */ +746 +747 +748 CodedEntry.prototype.setTimestamp = function(timestamp) { +749 return this._date = this._startDate = this._endDate = timestamp; +750 }; +751 +752 /** +753 Date and time at which the coded entry took place +754 @returns {Date} +755 */ +756 +757 +758 CodedEntry.prototype.date = function() { +759 return this._date; +760 }; +761 +762 /** +763 Date and time at which the coded entry started +764 @returns {Date} +765 */ +766 +767 +768 CodedEntry.prototype.startDate = function() { +769 return this._startDate; +770 }; +771 +772 /** +773 Date and time at which the coded entry ended +774 @returns {Date} +775 */ +776 +777 +778 CodedEntry.prototype.endDate = function() { +779 return this._endDate; +780 }; +781 +782 /** +783 Tries to find a single point in time for this entry. Will first return date if it is present, +784 then fall back to startDate and finally endDate +785 @returns {Date} +786 */ +787 +788 +789 CodedEntry.prototype.timeStamp = function() { +790 return this._date || this._startDate || this._endDate; +791 }; +792 +793 /** +794 Determines whether the entry specifies a time range or not +795 @returns {boolean} +796 */ +797 +798 +799 CodedEntry.prototype.isTimeRange = function() { +800 return (this._startDate != null) && (this._endDate != null); 801 }; 802 803 /** -804 Status for this coded entry -805 @returns {Hash} keys are code systems, values are arrays of codes -806 */ -807 +804 Determines whether a coded entry contains sufficient information (code and at least +805 one time stamp) to be usable +806 @returns {boolean} +807 */ 808 -809 CodedEntry.prototype.statusCode = function() { -810 return this._statusCode; -811 }; -812 -813 /** -814 Returns true if any of this entry codes match a code in the supplied codeSet. -815 @param {Object} codeSet a hash with code system names as keys and an array of codes as values -816 @returns {boolean} +809 +810 CodedEntry.prototype.isUsable = function() { +811 return this._type.length > 0 && (this._date || this._startDate || this._endDate); +812 }; +813 +814 /** +815 An Array of CodedValues which describe what kind of coded entry took place +816 @returns {Array} 817 */ 818 819 -820 CodedEntry.prototype.includesCodeFrom = function(codeSet) { -821 var codedValue, _i, _len, _ref1; -822 -823 _ref1 = this._type; -824 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -825 codedValue = _ref1[_i]; -826 if (codedValue.includedIn(codeSet)) { -827 return true; -828 } -829 } -830 return false; -831 }; -832 -833 /** -834 @returns {Boolean} whether the entry was negated -835 */ -836 -837 -838 CodedEntry.prototype.negationInd = function() { -839 return this.json['negationInd'] || false; -840 }; -841 -842 /** -843 Returns the values of the result. This will return an array that contains -844 PhysicalQuantity or CodedValue objects depending on the result type. -845 @returns {Array} containing either PhysicalQuantity and/or CodedValues -846 */ -847 -848 -849 CodedEntry.prototype.values = function() { -850 var value, values, _i, _len, _ref1; -851 -852 values = []; -853 if (this.json['values']) { -854 _ref1 = this.json['values']; -855 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -856 value = _ref1[_i]; -857 if (value['scalar'] != null) { -858 values.push(new hQuery.PhysicalQuantity(value)); -859 } else { -860 values = values.concat(hQuery.createCodedValues(value.codes)); -861 } -862 } -863 } -864 return values; +820 CodedEntry.prototype.type = function() { +821 return this._type; +822 }; +823 +824 /** +825 A free text description of the type of coded entry +826 @returns {String} +827 */ +828 +829 +830 CodedEntry.prototype.freeTextType = function() { +831 return this._freeTextType; +832 }; +833 +834 /** +835 Status for this coded entry +836 @returns {String} +837 */ +838 +839 +840 CodedEntry.prototype.status = function() { +841 if (this._statusCode != null) { +842 if (this._statusCode['HL7 ActStatus'] != null) { +843 return this._statusCode['HL7 ActStatus'][0]; +844 } else if (this._statusCode['SNOMED-CT'] != null) { +845 switch (this._statusCode['SNOMED-CT'][0]) { +846 case '55561003': +847 return 'active'; +848 case '73425007': +849 return 'inactive'; +850 case '413322009': +851 return 'resolved'; +852 } +853 } +854 } +855 }; +856 +857 /** +858 Status for this coded entry +859 @returns {Hash} keys are code systems, values are arrays of codes +860 */ +861 +862 +863 CodedEntry.prototype.statusCode = function() { +864 return this._statusCode; 865 }; 866 867 /** -868 Indicates the reason an entry was negated. -869 @returns {hQuery.CodedValue} Used to indicate reason an immunization was not administered. -870 */ -871 +868 Returns true if any of this entry codes match a code in the supplied codeSet. +869 @param {Object} codeSet a hash with code system names as keys and an array of codes as values +870 @returns {boolean} +871 */ 872 -873 CodedEntry.prototype.negationReason = function() { -874 return hQuery.createCodedValue(this.json['negationReason']); -875 }; -876 -877 /** -878 Explains the reason for an entry. -879 @returns {hQuery.CodedValue} Used to explain the rationale for a given entry. -880 */ -881 -882 -883 CodedEntry.prototype.reason = function() { -884 return hQuery.createCodedValue(this.json['reason']); -885 }; -886 -887 return CodedEntry; -888 -889 })(); -890 -891 /** -892 @class Represents a list of hQuery.CodedEntry instances. Offers utility methods for matching -893 entries based on codes and date ranges -894 @exports CodedEntryList as hQuery.CodedEntryList -895 */ -896 -897 -898 hQuery.CodedEntryList = (function(_super) { -899 __extends(CodedEntryList, _super); -900 -901 function CodedEntryList() { -902 this.push.apply(this, arguments); -903 } +873 +874 CodedEntry.prototype.includesCodeFrom = function(codeSet) { +875 var codedValue, _i, _len, _ref; +876 _ref = this._type; +877 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +878 codedValue = _ref[_i]; +879 if (codedValue.includedIn(codeSet)) { +880 return true; +881 } +882 } +883 return false; +884 }; +885 +886 /** +887 Returns true if any of this entry codes match a code in the supplied codeSet. +888 @param {Object} codeSet a hash with code system names as keys and an array of codes (provided as regular expressions) as values +889 @returns {boolean} +890 */ +891 +892 +893 CodedEntry.prototype.regex_includesCodeFrom = function(codeSet) { +894 var codedValue, _i, _len, _ref; +895 _ref = this._type; +896 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +897 codedValue = _ref[_i]; +898 if (codedValue.regex_includedIn(codeSet)) { +899 return true; +900 } +901 } +902 return false; +903 }; 904 905 /** -906 Push the supplied entry onto this list if it is usable -907 @param {CodedEntry} a coded entry that should be added to the list if it is usable -908 */ +906 @returns {Boolean} whether the entry was negated +907 */ +908 909 -910 -911 CodedEntryList.prototype.pushIfUsable = function(entry) { -912 if (entry.isUsable()) { -913 return this.push(entry); -914 } -915 }; -916 -917 /** -918 Return the number of entries that match the -919 supplied code set where those entries occur between the supplied time bounds -920 @param {Object} codeSet a hash with code system names as keys and an array of codes as values -921 @param {Date} start the start of the period during which the entry must occur, a null value will match all times -922 @param {Date} end the end of the period during which the entry must occur, a null value will match all times -923 @param {boolean} includeNegated whether the returned list of entries should include those that have been negated -924 @return {CodedEntryList} the matching entries -925 */ -926 -927 -928 CodedEntryList.prototype.match = function(codeSet, start, end, includeNegated) { -929 var afterStart, beforeEnd, cloned, entry, matchesCode, _i, _len; -930 -931 if (includeNegated == null) { -932 includeNegated = false; -933 } -934 cloned = new hQuery.CodedEntryList(); -935 for (_i = 0, _len = this.length; _i < _len; _i++) { -936 entry = this[_i]; -937 afterStart = !start || entry.timeStamp() >= start; -938 beforeEnd = !end || entry.timeStamp() <= end; -939 matchesCode = codeSet === null || entry.includesCodeFrom(codeSet); -940 if (afterStart && beforeEnd && matchesCode && (includeNegated || !entry.negationInd())) { -941 cloned.push(entry); -942 } -943 } -944 return cloned; -945 }; -946 -947 /** -948 Return a new list of entries that is the result of concatenating the passed in entries with this list -949 @return {CodedEntryList} the set of concatenated entries -950 */ -951 +910 CodedEntry.prototype.negationInd = function() { +911 return this.json['negationInd'] || false; +912 }; +913 +914 /** +915 Returns the values of the result. This will return an array that contains +916 PhysicalQuantity or CodedValue objects depending on the result type. +917 @returns {Array} containing either PhysicalQuantity and/or CodedValues +918 */ +919 +920 +921 CodedEntry.prototype.values = function() { +922 var value, values, _i, _len, _ref; +923 values = []; +924 if (this.json['values']) { +925 _ref = this.json['values']; +926 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +927 value = _ref[_i]; +928 if (value['scalar'] != null) { +929 values.push(new hQuery.PhysicalQuantity(value)); +930 } else { +931 values = values.concat(hQuery.createCodedValues(value.codes)); +932 } +933 } +934 } +935 return values; +936 }; +937 +938 /** +939 Indicates the reason an entry was negated. +940 @returns {hQuery.CodedValue} Used to indicate reason an immunization was not administered. +941 */ +942 +943 +944 CodedEntry.prototype.negationReason = function() { +945 return hQuery.createCodedValue(this.json['negationReason']); +946 }; +947 +948 /** +949 Explains the reason for an entry. +950 @returns {hQuery.CodedValue} Used to explain the rationale for a given entry. +951 */ 952 -953 CodedEntryList.prototype.concat = function(otherEntries) { -954 var cloned, entry, _i, _j, _len, _len1; -955 -956 cloned = new hQuery.CodedEntryList(); -957 for (_i = 0, _len = this.length; _i < _len; _i++) { -958 entry = this[_i]; -959 cloned.push(entry); -960 } -961 for (_j = 0, _len1 = otherEntries.length; _j < _len1; _j++) { -962 entry = otherEntries[_j]; -963 cloned.push(entry); -964 } -965 return cloned; -966 }; +953 +954 CodedEntry.prototype.reason = function() { +955 return hQuery.createCodedValue(this.json['reason']); +956 }; +957 +958 return CodedEntry; +959 +960 })(); +961 +962 /** +963 @class Represents a list of hQuery.CodedEntry instances. Offers utility methods for matching +964 entries based on codes and date ranges +965 @exports CodedEntryList as hQuery.CodedEntryList +966 */ 967 -968 /** -969 Match entries with the specified statuses -970 @return {CodedEntryList} the matching entries -971 */ +968 +969 hQuery.CodedEntryList = (function(_super) { +970 +971 __extends(CodedEntryList, _super); 972 -973 -974 CodedEntryList.prototype.withStatuses = function(statuses, includeUndefined) { -975 var cloned, entry, _i, _len, _ref1; -976 -977 if (includeUndefined == null) { -978 includeUndefined = true; -979 } -980 if (includeUndefined) { -981 statuses = statuses.concat([void 0, null]); -982 } -983 cloned = new hQuery.CodedEntryList(); -984 for (_i = 0, _len = this.length; _i < _len; _i++) { -985 entry = this[_i]; -986 if (_ref1 = entry.status(), __indexOf.call(statuses, _ref1) >= 0) { -987 cloned.push(entry); -988 } -989 } -990 return cloned; -991 }; -992 -993 /** -994 Filter entries based on negation -995 @param {Object} codeSet a hash with code system names as keys and an array of codes as values -996 @return {CodedEntryList} negated entries -997 */ -998 -999 -1000 CodedEntryList.prototype.withNegation = function(codeSet) { -1001 var cloned, entry, _i, _len; -1002 -1003 cloned = new hQuery.CodedEntryList(); -1004 for (_i = 0, _len = this.length; _i < _len; _i++) { -1005 entry = this[_i]; -1006 if (entry.negationInd() && (!codeSet || (entry.negationReason() && entry.negationReason().includedIn(codeSet)))) { -1007 cloned.push(entry); -1008 } -1009 } -1010 return cloned; -1011 }; -1012 -1013 /** -1014 Filter entries based on negation -1015 @return {CodedEntryList} non-negated entries -1016 */ -1017 -1018 -1019 CodedEntryList.prototype.withoutNegation = function() { -1020 var cloned, entry, _i, _len; -1021 -1022 cloned = new hQuery.CodedEntryList(); -1023 for (_i = 0, _len = this.length; _i < _len; _i++) { -1024 entry = this[_i]; -1025 if (!entry.negationInd()) { -1026 cloned.push(entry); -1027 } -1028 } -1029 return cloned; -1030 }; +973 CodedEntryList.name = 'CodedEntryList'; +974 +975 function CodedEntryList() { +976 this.push.apply(this, arguments); +977 } +978 +979 /** +980 Push the supplied entry onto this list if it is usable +981 @param {CodedEntry} a coded entry that should be added to the list if it is usable +982 */ +983 +984 +985 CodedEntryList.prototype.pushIfUsable = function(entry) { +986 if (entry.isUsable()) { +987 return this.push(entry); +988 } +989 }; +990 +991 /** +992 Return the number of entries that match the +993 supplied code set where those entries occur between the supplied time bounds +994 @param {Object} codeSet a hash with code system names as keys and an array of codes as values +995 @param {Date} start the start of the period during which the entry must occur, a null value will match all times +996 @param {Date} end the end of the period during which the entry must occur, a null value will match all times +997 @param {boolean} includeNegated whether the returned list of entries should include those that have been negated +998 @return {CodedEntryList} the matching entries +999 */ +1000 +1001 +1002 CodedEntryList.prototype.match = function(codeSet, start, end, includeNegated) { +1003 var afterStart, beforeEnd, cloned, entry, matchesCode, _i, _len; +1004 if (includeNegated == null) { +1005 includeNegated = false; +1006 } +1007 cloned = new hQuery.CodedEntryList(); +1008 for (_i = 0, _len = this.length; _i < _len; _i++) { +1009 entry = this[_i]; +1010 afterStart = !start || entry.timeStamp() >= start; +1011 beforeEnd = !end || entry.timeStamp() <= end; +1012 matchesCode = codeSet === null || entry.includesCodeFrom(codeSet); +1013 if (afterStart && beforeEnd && matchesCode && (includeNegated || !entry.negationInd())) { +1014 cloned.push(entry); +1015 } +1016 } +1017 return cloned; +1018 }; +1019 +1020 /** +1021 Return the number of entries that match the +1022 supplied code set where those entries occur between the supplied time bounds +1023 @param {Object} codeSet a hash with code system names as keys and an array of codes (provided as regular expressions) as values +1024 @param {Date} start the start of the period during which the entry must occur, a null value will match all times +1025 @param {Date} end the end of the period during which the entry must occur, a null value will match all times +1026 @param {boolean} includeNegated whether the returned list of entries should include those that have been negated +1027 @return {CodedEntryList} the matching entries +1028 TODO - decide on what to do with includeNegated parameter +1029 */ +1030 1031 -1032 return CodedEntryList; -1033 -1034 })(Array); -1035 -1036 /** -1037 @private -1038 @function -1039 */ -1040 -1041 -1042 hQuery.createCodedValues = function(jsonCodes) { -1043 var code, codeSystem, codedValues, codes, _i, _len; -1044 -1045 codedValues = []; -1046 for (codeSystem in jsonCodes) { -1047 codes = jsonCodes[codeSystem]; -1048 for (_i = 0, _len = codes.length; _i < _len; _i++) { -1049 code = codes[_i]; -1050 codedValues.push(new hQuery.CodedValue(code, codeSystem)); -1051 } -1052 } -1053 return codedValues; -1054 }; +1032 CodedEntryList.prototype.regex_match = function(codeSet, start, end, includeNegated) { +1033 var afterStart, beforeEnd, cloned, entry, matchesCode, _i, _len; +1034 if (includeNegated == null) { +1035 includeNegated = false; +1036 } +1037 cloned = new hQuery.CodedEntryList(); +1038 for (_i = 0, _len = this.length; _i < _len; _i++) { +1039 entry = this[_i]; +1040 afterStart = !start || entry.timeStamp() >= start; +1041 beforeEnd = !end || entry.timeStamp() <= end; +1042 matchesCode = codeSet === null || entry.regex_includesCodeFrom(codeSet); +1043 if (afterStart && beforeEnd && matchesCode && (includeNegated || !entry.negationInd())) { +1044 cloned.push(entry); +1045 } +1046 } +1047 return cloned; +1048 }; +1049 +1050 /** +1051 Return a new list of entries that is the result of concatenating the passed in entries with this list +1052 @return {CodedEntryList} the set of concatenated entries +1053 */ +1054 1055 -1056 hQuery.createCodedValue = function(json) { -1057 if (json != null) { -1058 return new hQuery.CodedValue(json['code'], json['code_system']); -1059 } -1060 }; -1061 /** -1062 @namespace scoping into the hquery namespace -1063 */ -1064 -1065 var _ref, _ref1, -1066 __hasProp = {}.hasOwnProperty, -1067 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; -1068 -1069 this.hQuery || (this.hQuery = {}); -1070 -1071 /** -1072 @class MedicationInformation -1073 @exports MedicationInformation as hQuery.MedicationInformation -1074 */ +1056 CodedEntryList.prototype.concat = function(otherEntries) { +1057 var cloned, entry, _i, _j, _len, _len1; +1058 cloned = new hQuery.CodedEntryList(); +1059 for (_i = 0, _len = this.length; _i < _len; _i++) { +1060 entry = this[_i]; +1061 cloned.push(entry); +1062 } +1063 for (_j = 0, _len1 = otherEntries.length; _j < _len1; _j++) { +1064 entry = otherEntries[_j]; +1065 cloned.push(entry); +1066 } +1067 return cloned; +1068 }; +1069 +1070 /** +1071 Match entries with the specified statuses +1072 @return {CodedEntryList} the matching entries +1073 */ +1074 1075 -1076 -1077 hQuery.MedicationInformation = (function() { -1078 function MedicationInformation(json) { -1079 this.json = json; -1080 } -1081 -1082 /** -1083 An array of hQuery.CodedValue describing the medication -1084 @returns {Array} -1085 */ -1086 -1087 -1088 MedicationInformation.prototype.codedProduct = function() { -1089 return hQuery.createCodedValues(this.json['codes']); -1090 }; -1091 -1092 MedicationInformation.prototype.freeTextProductName = function() { -1093 return this.json['description']; -1094 }; -1095 -1096 MedicationInformation.prototype.codedBrandName = function() { -1097 return this.json['codedBrandName']; -1098 }; +1076 CodedEntryList.prototype.withStatuses = function(statuses, includeUndefined) { +1077 var cloned, entry, _i, _len, _ref; +1078 if (includeUndefined == null) { +1079 includeUndefined = true; +1080 } +1081 if (includeUndefined) { +1082 statuses = statuses.concat([void 0, null]); +1083 } +1084 cloned = new hQuery.CodedEntryList(); +1085 for (_i = 0, _len = this.length; _i < _len; _i++) { +1086 entry = this[_i]; +1087 if (_ref = entry.status(), __indexOf.call(statuses, _ref) >= 0) { +1088 cloned.push(entry); +1089 } +1090 } +1091 return cloned; +1092 }; +1093 +1094 /** +1095 Filter entries based on negation +1096 @param {Object} codeSet a hash with code system names as keys and an array of codes as values +1097 @return {CodedEntryList} negated entries +1098 */ 1099 -1100 MedicationInformation.prototype.freeTextBrandName = function() { -1101 return this.json['brandName']; -1102 }; -1103 -1104 MedicationInformation.prototype.drugManufacturer = function() { -1105 if (this.json['drugManufacturer']) { -1106 return new hQuery.Organization(this.json['drugManufacturer']); -1107 } -1108 }; -1109 -1110 return MedicationInformation; -1111 -1112 })(); -1113 -1114 /** -1115 @class AdministrationTiming - the -1116 @exports AdministrationTiming as hQuery.AdministrationTiming -1117 */ +1100 +1101 CodedEntryList.prototype.withNegation = function(codeSet) { +1102 var cloned, entry, _i, _len; +1103 cloned = new hQuery.CodedEntryList(); +1104 for (_i = 0, _len = this.length; _i < _len; _i++) { +1105 entry = this[_i]; +1106 if (entry.negationInd() && (!codeSet || (entry.negationReason() && entry.negationReason().includedIn(codeSet)))) { +1107 cloned.push(entry); +1108 } +1109 } +1110 return cloned; +1111 }; +1112 +1113 /** +1114 Filter entries based on negation +1115 @return {CodedEntryList} non-negated entries +1116 */ +1117 1118 -1119 -1120 hQuery.AdministrationTiming = (function() { -1121 function AdministrationTiming(json) { -1122 this.json = json; -1123 } -1124 -1125 /** -1126 Provides the period of medication administration as a Scalar. An example -1127 Scalar that would be returned would be with value = 8 and units = hours. This would -1128 mean that the medication should be taken every 8 hours. -1129 @returns {hQuery.Scalar} -1130 */ -1131 +1119 CodedEntryList.prototype.withoutNegation = function() { +1120 var cloned, entry, _i, _len; +1121 cloned = new hQuery.CodedEntryList(); +1122 for (_i = 0, _len = this.length; _i < _len; _i++) { +1123 entry = this[_i]; +1124 if (!entry.negationInd()) { +1125 cloned.push(entry); +1126 } +1127 } +1128 return cloned; +1129 }; +1130 +1131 return CodedEntryList; 1132 -1133 AdministrationTiming.prototype.period = function() { -1134 if (this.json['period']) { -1135 return new hQuery.Scalar(this.json['period']); -1136 } -1137 }; -1138 -1139 /** -1140 Indicates whether it is the interval (time between dosing), or frequency -1141 (number of doses in a time period) that is important. If instititutionSpecified is not -1142 present or is set to false, then the time between dosing is important (every 8 hours). -1143 If true, then the frequency of administration is important (e.g., 3 times per day). -1144 @returns {Boolean} -1145 */ -1146 -1147 -1148 AdministrationTiming.prototype.institutionSpecified = function() { -1149 return this.json['institutionSpecified']; -1150 }; -1151 -1152 return AdministrationTiming; +1133 })(Array); +1134 +1135 /** +1136 @private +1137 @function +1138 */ +1139 +1140 +1141 hQuery.createCodedValues = function(jsonCodes) { +1142 var code, codeSystem, codedValues, codes, _i, _len; +1143 codedValues = []; +1144 for (codeSystem in jsonCodes) { +1145 codes = jsonCodes[codeSystem]; +1146 for (_i = 0, _len = codes.length; _i < _len; _i++) { +1147 code = codes[_i]; +1148 codedValues.push(new hQuery.CodedValue(code, codeSystem)); +1149 } +1150 } +1151 return codedValues; +1152 }; 1153 -1154 })(); -1155 -1156 /** -1157 @class DoseRestriction - restrictions on the medications dose, represented by a upper and lower dose -1158 @exports DoseRestriction as hQuery.DoseRestriction -1159 */ -1160 -1161 -1162 hQuery.DoseRestriction = (function() { -1163 function DoseRestriction(json) { -1164 this.json = json; -1165 } -1166 -1167 DoseRestriction.prototype.numerator = function() { -1168 if (this.json['numerator']) { -1169 return new hQuery.Scalar(this.json['numerator']); -1170 } -1171 }; +1154 hQuery.createCodedValue = function(json) { +1155 if (json != null) { +1156 return new hQuery.CodedValue(json['code'], json['codeSystem']); +1157 } +1158 }; +1159 /** +1160 @namespace scoping into the hquery namespace +1161 */ +1162 +1163 var __hasProp = {}.hasOwnProperty, +1164 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; +1165 +1166 this.hQuery || (this.hQuery = {}); +1167 +1168 /** +1169 @class MedicationInformation +1170 @exports MedicationInformation as hQuery.MedicationInformation +1171 */ 1172 -1173 DoseRestriction.prototype.denominator = function() { -1174 if (this.json['denominator']) { -1175 return new hQuery.Scalar(this.json['denominator']); -1176 } -1177 }; -1178 -1179 return DoseRestriction; -1180 -1181 })(); -1182 -1183 /** -1184 @class Fulfillment - information about when and who fulfilled an order for the medication -1185 @exports Fulfillment as hQuery.Fullfilement -1186 */ +1173 +1174 hQuery.MedicationInformation = (function() { +1175 +1176 MedicationInformation.name = 'MedicationInformation'; +1177 +1178 function MedicationInformation(json) { +1179 this.json = json; +1180 } +1181 +1182 /** +1183 An array of hQuery.CodedValue describing the medication +1184 @returns {Array} +1185 */ +1186 1187 -1188 -1189 hQuery.Fulfillment = (function() { -1190 function Fulfillment(json) { -1191 this.json = json; -1192 } -1193 -1194 Fulfillment.prototype.dispenseDate = function() { -1195 return hQuery.dateFromUtcSeconds(this.json['dispenseDate']); -1196 }; -1197 -1198 Fulfillment.prototype.dispensingPharmacyLocation = function() { -1199 if (this.json['dispensingPharmacyLocation']) { -1200 return new hQuery.Address(this.json['dispensingPharmacyLocation']); -1201 } +1188 MedicationInformation.prototype.codedProduct = function() { +1189 return hQuery.createCodedValues(this.json['codes']); +1190 }; +1191 +1192 MedicationInformation.prototype.freeTextProductName = function() { +1193 return this.json['description']; +1194 }; +1195 +1196 MedicationInformation.prototype.codedBrandName = function() { +1197 return this.json['codedBrandName']; +1198 }; +1199 +1200 MedicationInformation.prototype.freeTextBrandName = function() { +1201 return this.json['brandName']; 1202 }; 1203 -1204 Fulfillment.prototype.quantityDispensed = function() { -1205 if (this.json['quantityDispensed']) { -1206 return new hQuery.Scalar(this.json['quantityDispensed']); +1204 MedicationInformation.prototype.drugManufacturer = function() { +1205 if (this.json['drugManufacturer']) { +1206 return new hQuery.Organization(this.json['drugManufacturer']); 1207 } 1208 }; 1209 -1210 Fulfillment.prototype.prescriptionNumber = function() { -1211 return this.json['prescriptionNumber']; -1212 }; +1210 return MedicationInformation; +1211 +1212 })(); 1213 -1214 Fulfillment.prototype.fillNumber = function() { -1215 return this.json['fillNumber']; -1216 }; -1217 -1218 Fulfillment.prototype.fillStatus = function() { -1219 if (this.json['fillStatus']) { -1220 return new hQuery.Status(this.json['fillStatus']); -1221 } -1222 }; +1214 /** +1215 @class AdministrationTiming - the +1216 @exports AdministrationTiming as hQuery.AdministrationTiming +1217 */ +1218 +1219 +1220 hQuery.AdministrationTiming = (function() { +1221 +1222 AdministrationTiming.name = 'AdministrationTiming'; 1223 -1224 return Fulfillment; -1225 -1226 })(); +1224 function AdministrationTiming(json) { +1225 this.json = json; +1226 } 1227 -1228 /** -1229 @class OrderInformation - information abour an order for a medication -1230 @exports OrderInformation as hQuery.OrderInformation -1231 */ -1232 -1233 -1234 hQuery.OrderInformation = (function() { -1235 function OrderInformation(json) { -1236 this.json = json; -1237 } -1238 -1239 OrderInformation.prototype.orderNumber = function() { -1240 return this.json['orderNumber']; -1241 }; -1242 -1243 OrderInformation.prototype.fills = function() { -1244 return this.json['fills']; -1245 }; -1246 -1247 OrderInformation.prototype.quantityOrdered = function() { -1248 if (this.json['quantityOrdered']) { -1249 return new hQuery.Scalar(this.json['quantityOrdered']); -1250 } -1251 }; -1252 -1253 OrderInformation.prototype.orderExpirationDateTime = function() { -1254 return hQuery.dateFromUtcSeconds(this.json['orderExpirationDateTime']); -1255 }; +1228 /** +1229 Provides the period of medication administration as a Scalar. An example +1230 Scalar that would be returned would be with value = 8 and units = hours. This would +1231 mean that the medication should be taken every 8 hours. +1232 @returns {hQuery.Scalar} +1233 */ +1234 +1235 +1236 AdministrationTiming.prototype.period = function() { +1237 if (this.json['period']) { +1238 return new hQuery.Scalar(this.json['period']); +1239 } +1240 }; +1241 +1242 /** +1243 Indicates whether it is the interval (time between dosing), or frequency +1244 (number of doses in a time period) that is important. If instititutionSpecified is not +1245 present or is set to false, then the time between dosing is important (every 8 hours). +1246 If true, then the frequency of administration is important (e.g., 3 times per day). +1247 @returns {Boolean} +1248 */ +1249 +1250 +1251 AdministrationTiming.prototype.institutionSpecified = function() { +1252 return this.json['institutionSpecified']; +1253 }; +1254 +1255 return AdministrationTiming; 1256 -1257 OrderInformation.prototype.orderDateTime = function() { -1258 return hQuery.dateFromUtcSeconds(this.json['orderDateTime']); -1259 }; -1260 -1261 return OrderInformation; -1262 -1263 })(); +1257 })(); +1258 +1259 /** +1260 @class DoseRestriction - restrictions on the medications dose, represented by a upper and lower dose +1261 @exports DoseRestriction as hQuery.DoseRestriction +1262 */ +1263 1264 -1265 /** -1266 TypeOfMedication as defined by value set 2.16.840.1.113883.3.88.12.3221.8.19 -1267 which pulls two values from SNOMED to describe whether a medication is -1268 prescription or over the counter -1269 -1270 @class TypeOfMedication - describes whether a medication is prescription or -1271 over the counter -1272 @augments hQuery.CodedEntry -1273 @exports TypeOfMedication as hQuery.TypeOfMedication -1274 */ -1275 -1276 -1277 hQuery.TypeOfMedication = (function(_super) { -1278 var OTC, PRESECRIPTION; -1279 -1280 __extends(TypeOfMedication, _super); -1281 -1282 function TypeOfMedication() { -1283 _ref = TypeOfMedication.__super__.constructor.apply(this, arguments); -1284 return _ref; -1285 } +1265 hQuery.DoseRestriction = (function() { +1266 +1267 DoseRestriction.name = 'DoseRestriction'; +1268 +1269 function DoseRestriction(json) { +1270 this.json = json; +1271 } +1272 +1273 DoseRestriction.prototype.numerator = function() { +1274 if (this.json['numerator']) { +1275 return new hQuery.Scalar(this.json['numerator']); +1276 } +1277 }; +1278 +1279 DoseRestriction.prototype.denominator = function() { +1280 if (this.json['denominator']) { +1281 return new hQuery.Scalar(this.json['denominator']); +1282 } +1283 }; +1284 +1285 return DoseRestriction; 1286 -1287 PRESECRIPTION = "73639000"; +1287 })(); 1288 -1289 OTC = "329505003"; -1290 -1291 /** -1292 @returns {Boolean} -1293 */ +1289 /** +1290 @class Fulfillment - information about when and who fulfilled an order for the medication +1291 @exports Fulfillment as hQuery.Fullfilement +1292 */ +1293 1294 -1295 -1296 TypeOfMedication.prototype.isPrescription = function() { -1297 return this.c === PRESECRIPTION; -1298 }; -1299 -1300 /** -1301 @returns {Boolean} -1302 */ -1303 -1304 -1305 TypeOfMedication.prototype.isOverTheCounter = function() { -1306 return this.c === OTC; -1307 }; -1308 -1309 return TypeOfMedication; -1310 -1311 })(hQuery.CodedValue); +1295 hQuery.Fulfillment = (function() { +1296 +1297 Fulfillment.name = 'Fulfillment'; +1298 +1299 function Fulfillment(json) { +1300 this.json = json; +1301 } +1302 +1303 Fulfillment.prototype.dispenseDate = function() { +1304 return hQuery.dateFromUtcSeconds(this.json['dispenseDate']); +1305 }; +1306 +1307 Fulfillment.prototype.dispensingPharmacyLocation = function() { +1308 if (this.json['dispensingPharmacyLocation']) { +1309 return new hQuery.Address(this.json['dispensingPharmacyLocation']); +1310 } +1311 }; 1312 -1313 /** -1314 StatusOfMedication as defined by value set 2.16.840.1.113883.1.11.20.7 -1315 The terms come from SNOMED and are managed by HL7 -1316 -1317 @class StatusOfMedication - describes the status of the medication -1318 @augments hQuery.CodedEntry -1319 @exports StatusOfMedication as hQuery.StatusOfMedication -1320 */ -1321 +1313 Fulfillment.prototype.quantityDispensed = function() { +1314 if (this.json['quantityDispensed']) { +1315 return new hQuery.Scalar(this.json['quantityDispensed']); +1316 } +1317 }; +1318 +1319 Fulfillment.prototype.prescriptionNumber = function() { +1320 return this.json['prescriptionNumber']; +1321 }; 1322 -1323 hQuery.StatusOfMedication = (function(_super) { -1324 var ACTIVE, NO_LONGER_ACTIVE, ON_HOLD, PRIOR_HISTORY; -1325 -1326 __extends(StatusOfMedication, _super); -1327 -1328 function StatusOfMedication() { -1329 _ref1 = StatusOfMedication.__super__.constructor.apply(this, arguments); -1330 return _ref1; -1331 } +1323 Fulfillment.prototype.fillNumber = function() { +1324 return this.json['fillNumber']; +1325 }; +1326 +1327 Fulfillment.prototype.fillStatus = function() { +1328 if (this.json['fillStatus']) { +1329 return new hQuery.Status(this.json['fillStatus']); +1330 } +1331 }; 1332 -1333 ON_HOLD = "392521001"; +1333 return Fulfillment; 1334 -1335 NO_LONGER_ACTIVE = "421139008"; +1335 })(); 1336 -1337 ACTIVE = "55561003"; -1338 -1339 PRIOR_HISTORY = "73425007"; -1340 -1341 /** -1342 @returns {Boolean} -1343 */ +1337 /** +1338 @class OrderInformation - information abour an order for a medication +1339 @exports OrderInformation as hQuery.OrderInformation +1340 */ +1341 +1342 +1343 hQuery.OrderInformation = (function() { 1344 -1345 -1346 StatusOfMedication.prototype.isOnHold = function() { -1347 return this.c === ON_HOLD; -1348 }; -1349 -1350 /** -1351 @returns {Boolean} -1352 */ -1353 +1345 OrderInformation.name = 'OrderInformation'; +1346 +1347 function OrderInformation(json) { +1348 this.json = json; +1349 } +1350 +1351 OrderInformation.prototype.orderNumber = function() { +1352 return this.json['orderNumber']; +1353 }; 1354 -1355 StatusOfMedication.prototype.isNoLongerActive = function() { -1356 return this.c === NO_LONGER_ACTIVE; +1355 OrderInformation.prototype.fills = function() { +1356 return this.json['fills']; 1357 }; 1358 -1359 /** -1360 @returns {Boolean} -1361 */ -1362 -1363 -1364 StatusOfMedication.prototype.isActive = function() { -1365 return this.c === ACTIVE; -1366 }; -1367 -1368 /** -1369 @returns {Boolean} -1370 */ -1371 +1359 OrderInformation.prototype.quantityOrdered = function() { +1360 if (this.json['quantityOrdered']) { +1361 return new hQuery.Scalar(this.json['quantityOrdered']); +1362 } +1363 }; +1364 +1365 OrderInformation.prototype.orderExpirationDateTime = function() { +1366 return hQuery.dateFromUtcSeconds(this.json['orderExpirationDateTime']); +1367 }; +1368 +1369 OrderInformation.prototype.orderDateTime = function() { +1370 return hQuery.dateFromUtcSeconds(this.json['orderDateTime']); +1371 }; 1372 -1373 StatusOfMedication.prototype.isPriorHistory = function() { -1374 return this.c === PRIOR_HISTORY; -1375 }; +1373 return OrderInformation; +1374 +1375 })(); 1376 -1377 return StatusOfMedication; -1378 -1379 })(hQuery.CodedValue); -1380 -1381 /** -1382 @class represents a medication entry for a patient. -1383 @augments hQuery.CodedEntry -1384 @exports Medication as hQuery.Medication -1385 */ -1386 +1377 /** +1378 TypeOfMedication as defined by value set 2.16.840.1.113883.3.88.12.3221.8.19 +1379 which pulls two values from SNOMED to describe whether a medication is +1380 prescription or over the counter +1381 +1382 @class TypeOfMedication - describes whether a medication is prescription or +1383 over the counter +1384 @augments hQuery.CodedEntry +1385 @exports TypeOfMedication as hQuery.TypeOfMedication +1386 */ 1387 -1388 hQuery.Medication = (function(_super) { -1389 __extends(Medication, _super); -1390 -1391 function Medication(json) { -1392 this.json = json; -1393 Medication.__super__.constructor.call(this, this.json); -1394 } +1388 +1389 hQuery.TypeOfMedication = (function(_super) { +1390 var OTC, PRESECRIPTION; +1391 +1392 __extends(TypeOfMedication, _super); +1393 +1394 TypeOfMedication.name = 'TypeOfMedication'; 1395 -1396 /** -1397 @returns {String} -1398 */ +1396 function TypeOfMedication() { +1397 return TypeOfMedication.__super__.constructor.apply(this, arguments); +1398 } 1399 -1400 -1401 Medication.prototype.freeTextSig = function() { -1402 return this.json['freeTextSig']; -1403 }; -1404 -1405 /** -1406 The actual or intended start of a medication. Slight deviation from greenCDA for C32 since -1407 it combines this with medication stop -1408 @returns {Date} -1409 */ -1410 -1411 -1412 Medication.prototype.indicateMedicationStart = function() { -1413 return hQuery.dateFromUtcSeconds(this.json['start_time']); -1414 }; -1415 -1416 /** -1417 The actual or intended stop of a medication. Slight deviation from greenCDA for C32 since -1418 it combines this with medication start -1419 @returns {Date} -1420 */ +1400 PRESECRIPTION = "73639000"; +1401 +1402 OTC = "329505003"; +1403 +1404 /** +1405 @returns {Boolean} +1406 */ +1407 +1408 +1409 TypeOfMedication.prototype.isPrescription = function() { +1410 return this.c === PRESECRIPTION; +1411 }; +1412 +1413 /** +1414 @returns {Boolean} +1415 */ +1416 +1417 +1418 TypeOfMedication.prototype.isOverTheCounter = function() { +1419 return this.c === OTC; +1420 }; 1421 -1422 -1423 Medication.prototype.indicateMedicationStop = function() { -1424 return hQuery.dateFromUtcSeconds(this.json['end_time']); -1425 }; -1426 -1427 Medication.prototype.administrationTiming = function() { -1428 if (this.json['administrationTiming']) { -1429 return new hQuery.AdministrationTiming(this.json['administrationTiming']); -1430 } -1431 }; -1432 -1433 /** -1434 @returns {CodedValue} Contains routeCode or adminstrationUnitCode information. -1435 Route code shall have a a value drawn from FDA route of adminstration, -1436 and indicates how the medication is received by the patient. -1437 See http://www.fda.gov/Drugs/DevelopmentApprovalProcess/UCM070829 -1438 The administration unit code shall have a value drawn from the FDA -1439 dosage form, source NCI thesaurus and represents the physical form of the -1440 product as presented to the patient. -1441 See http://www.fda.gov/Drugs/InformationOnDrugs/ucm142454.htm -1442 */ -1443 -1444 -1445 Medication.prototype.route = function() { -1446 return hQuery.createCodedValue(this.json['route']); -1447 }; +1422 return TypeOfMedication; +1423 +1424 })(hQuery.CodedValue); +1425 +1426 /** +1427 StatusOfMedication as defined by value set 2.16.840.1.113883.1.11.20.7 +1428 The terms come from SNOMED and are managed by HL7 +1429 +1430 @class StatusOfMedication - describes the status of the medication +1431 @augments hQuery.CodedEntry +1432 @exports StatusOfMedication as hQuery.StatusOfMedication +1433 */ +1434 +1435 +1436 hQuery.StatusOfMedication = (function(_super) { +1437 var ACTIVE, NO_LONGER_ACTIVE, ON_HOLD, PRIOR_HISTORY; +1438 +1439 __extends(StatusOfMedication, _super); +1440 +1441 StatusOfMedication.name = 'StatusOfMedication'; +1442 +1443 function StatusOfMedication() { +1444 return StatusOfMedication.__super__.constructor.apply(this, arguments); +1445 } +1446 +1447 ON_HOLD = "392521001"; 1448 -1449 /** -1450 @returns {hQuery.Scalar} the dose -1451 */ +1449 NO_LONGER_ACTIVE = "421139008"; +1450 +1451 ACTIVE = "55561003"; 1452 -1453 -1454 Medication.prototype.dose = function() { -1455 if (this.json['dose']) { -1456 return new hQuery.Scalar(this.json['dose']); -1457 } -1458 }; +1453 PRIOR_HISTORY = "73425007"; +1454 +1455 /** +1456 @returns {Boolean} +1457 */ +1458 1459 -1460 /** -1461 @returns {CodedValue} -1462 */ +1460 StatusOfMedication.prototype.isOnHold = function() { +1461 return this.c === ON_HOLD; +1462 }; 1463 -1464 -1465 Medication.prototype.site = function() { -1466 if (this.json['site']) { -1467 return hQuery.createCodedValue(this.json['site']); -1468 } -1469 }; -1470 -1471 /** -1472 @returns {hQuery.DoseRestriction} -1473 */ -1474 -1475 -1476 Medication.prototype.doseRestriction = function() { -1477 if (this.json['doseRestriction']) { -1478 return new hQuery.DoseRestriction(this.json['doseRestriction']); -1479 } +1464 /** +1465 @returns {Boolean} +1466 */ +1467 +1468 +1469 StatusOfMedication.prototype.isNoLongerActive = function() { +1470 return this.c === NO_LONGER_ACTIVE; +1471 }; +1472 +1473 /** +1474 @returns {Boolean} +1475 */ +1476 +1477 +1478 StatusOfMedication.prototype.isActive = function() { +1479 return this.c === ACTIVE; 1480 }; 1481 1482 /** -1483 @returns {String} +1483 @returns {Boolean} 1484 */ 1485 1486 -1487 Medication.prototype.doseIndicator = function() { -1488 return this.json['doseIndicator']; +1487 StatusOfMedication.prototype.isPriorHistory = function() { +1488 return this.c === PRIOR_HISTORY; 1489 }; 1490 -1491 /** -1492 @returns {String} -1493 */ +1491 return StatusOfMedication; +1492 +1493 })(hQuery.CodedValue); 1494 -1495 -1496 Medication.prototype.fulfillmentInstructions = function() { -1497 return this.json['fulfillmentInstructions']; -1498 }; -1499 -1500 /** -1501 @returns {CodedValue} -1502 */ +1495 /** +1496 @class represents a medication entry for a patient. +1497 @augments hQuery.CodedEntry +1498 @exports Medication as hQuery.Medication +1499 */ +1500 +1501 +1502 hQuery.Medication = (function(_super) { 1503 -1504 -1505 Medication.prototype.indication = function() { -1506 return hQuery.createCodedValue(this.json['indication']); -1507 }; -1508 -1509 /** -1510 @returns {CodedValue} -1511 */ +1504 __extends(Medication, _super); +1505 +1506 Medication.name = 'Medication'; +1507 +1508 function Medication(json) { +1509 this.json = json; +1510 Medication.__super__.constructor.call(this, this.json); +1511 } 1512 -1513 -1514 Medication.prototype.productForm = function() { -1515 return hQuery.createCodedValue(this.json['productForm']); -1516 }; +1513 /** +1514 @returns {String} +1515 */ +1516 1517 -1518 /** -1519 @returns {CodedValue} -1520 */ +1518 Medication.prototype.freeTextSig = function() { +1519 return this.json['freeTextSig']; +1520 }; 1521 -1522 -1523 Medication.prototype.vehicle = function() { -1524 return hQuery.createCodedValue(this.json['vehicle']); -1525 }; -1526 -1527 /** -1528 @returns {CodedValue} -1529 */ -1530 -1531 -1532 Medication.prototype.reaction = function() { -1533 return hQuery.createCodedValue(this.json['reaction']); -1534 }; -1535 -1536 /** -1537 @returns {CodedValue} -1538 */ +1522 /** +1523 The actual or intended start of a medication. Slight deviation from greenCDA for C32 since +1524 it combines this with medication stop +1525 @returns {Date} +1526 */ +1527 +1528 +1529 Medication.prototype.indicateMedicationStart = function() { +1530 return hQuery.dateFromUtcSeconds(this.json['start_time']); +1531 }; +1532 +1533 /** +1534 The actual or intended stop of a medication. Slight deviation from greenCDA for C32 since +1535 it combines this with medication start +1536 @returns {Date} +1537 */ +1538 1539 -1540 -1541 Medication.prototype.deliveryMethod = function() { -1542 return hQuery.createCodedValue(this.json['deliveryMethod']); -1543 }; -1544 -1545 /** -1546 @returns {hQuery.MedicationInformation} -1547 */ -1548 +1540 Medication.prototype.indicateMedicationStop = function() { +1541 return hQuery.dateFromUtcSeconds(this.json['end_time']); +1542 }; +1543 +1544 Medication.prototype.administrationTiming = function() { +1545 if (this.json['administrationTiming']) { +1546 return new hQuery.AdministrationTiming(this.json['administrationTiming']); +1547 } +1548 }; 1549 -1550 Medication.prototype.medicationInformation = function() { -1551 return new hQuery.MedicationInformation(this.json); -1552 }; -1553 -1554 /** -1555 @returns {hQuery.TypeOfMedication} Indicates whether this is an over the counter or prescription medication -1556 */ -1557 -1558 -1559 Medication.prototype.typeOfMedication = function() { -1560 var _ref2, _ref3; +1550 /** +1551 @returns {CodedValue} Contains routeCode or adminstrationUnitCode information. +1552 Route code shall have a a value drawn from FDA route of adminstration, +1553 and indicates how the medication is received by the patient. +1554 See http://www.fda.gov/Drugs/DevelopmentApprovalProcess/UCM070829 +1555 The administration unit code shall have a value drawn from the FDA +1556 dosage form, source NCI thesaurus and represents the physical form of the +1557 product as presented to the patient. +1558 See http://www.fda.gov/Drugs/InformationOnDrugs/ucm142454.htm +1559 */ +1560 1561 -1562 return new hQuery.TypeOfMedication((_ref2 = this.json['typeOfMedication']) != null ? _ref2['code'] : void 0, (_ref3 = this.json['typeOfMedication']) != null ? _ref3['code_system'] : void 0); -1563 }; -1564 -1565 /** -1566 Values conform to value set 2.16.840.1.113883.1.11.20.7 - Medication Status -1567 Values may be: On Hold, No Longer Active, Active, Prior History -1568 @returns {hQuery.StatusOfMedication} Used to indicate the status of the medication. -1569 */ +1562 Medication.prototype.route = function() { +1563 return hQuery.createCodedValue(this.json['route']); +1564 }; +1565 +1566 /** +1567 @returns {hQuery.Scalar} the dose +1568 */ +1569 1570 -1571 -1572 Medication.prototype.statusOfMedication = function() { -1573 var _ref2, _ref3; -1574 -1575 return new hQuery.StatusOfMedication((_ref2 = this.json['statusOfMedication']) != null ? _ref2['code'] : void 0, (_ref3 = this.json['statusOfMedication']) != null ? _ref3['code_system'] : void 0); -1576 }; -1577 -1578 /** -1579 @returns {String} free text instructions to the patient -1580 */ +1571 Medication.prototype.dose = function() { +1572 if (this.json['dose']) { +1573 return new hQuery.Scalar(this.json['dose']); +1574 } +1575 }; +1576 +1577 /** +1578 @returns {CodedValue} +1579 */ +1580 1581 -1582 -1583 Medication.prototype.patientInstructions = function() { -1584 return this.json['patientInstructions']; -1585 }; -1586 -1587 /** -1588 The duration over which this medication has been active. For example, 5 days. -1589 @returns {Hash} with two keys: unit and scalar +1582 Medication.prototype.site = function() { +1583 if (this.json['site']) { +1584 return hQuery.createCodedValue(this.json['site']); +1585 } +1586 }; +1587 +1588 /** +1589 @returns {hQuery.DoseRestriction} 1590 */ 1591 1592 -1593 Medication.prototype.cumulativeMedicationDuration = function() { -1594 return this.json['cumulativeMedicationDuration']; -1595 }; -1596 -1597 /** -1598 @returns {Array} an array of {@link FulFillment} objects -1599 */ -1600 -1601 -1602 Medication.prototype.fulfillmentHistory = function() { -1603 var order, _i, _len, _ref2, _results; -1604 -1605 _ref2 = this.json['fulfillmentHistory']; -1606 _results = []; -1607 for (_i = 0, _len = _ref2.length; _i < _len; _i++) { -1608 order = _ref2[_i]; -1609 _results.push(new hQuery.Fulfillment(order)); -1610 } -1611 return _results; -1612 }; -1613 -1614 /** -1615 @returns {Array} an array of {@link OrderInformation} objects -1616 */ -1617 -1618 -1619 Medication.prototype.orderInformation = function() { -1620 var order, _i, _len, _ref2, _results; +1593 Medication.prototype.doseRestriction = function() { +1594 if (this.json['doseRestriction']) { +1595 return new hQuery.DoseRestriction(this.json['doseRestriction']); +1596 } +1597 }; +1598 +1599 /** +1600 @returns {String} +1601 */ +1602 +1603 +1604 Medication.prototype.doseIndicator = function() { +1605 return this.json['doseIndicator']; +1606 }; +1607 +1608 /** +1609 @returns {String} +1610 */ +1611 +1612 +1613 Medication.prototype.fulfillmentInstructions = function() { +1614 return this.json['fulfillmentInstructions']; +1615 }; +1616 +1617 /** +1618 @returns {CodedValue} +1619 */ +1620 1621 -1622 _ref2 = this.json['orderInformation']; -1623 _results = []; -1624 for (_i = 0, _len = _ref2.length; _i < _len; _i++) { -1625 order = _ref2[_i]; -1626 _results.push(new hQuery.OrderInformation(order)); -1627 } -1628 return _results; -1629 }; +1622 Medication.prototype.indication = function() { +1623 return hQuery.createCodedValue(this.json['indication']); +1624 }; +1625 +1626 /** +1627 @returns {CodedValue} +1628 */ +1629 1630 -1631 return Medication; -1632 -1633 })(hQuery.CodedEntry); -1634 /** -1635 @namespace scoping into the hquery namespace -1636 */ -1637 -1638 var __hasProp = {}.hasOwnProperty, -1639 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; -1640 -1641 this.hQuery || (this.hQuery = {}); -1642 -1643 /** -1644 @class CauseOfDeath -1645 @exports CauseOfDeath as hQuery.CauseOfDeath -1646 */ +1631 Medication.prototype.productForm = function() { +1632 return hQuery.createCodedValue(this.json['productForm']); +1633 }; +1634 +1635 /** +1636 @returns {CodedValue} +1637 */ +1638 +1639 +1640 Medication.prototype.vehicle = function() { +1641 return hQuery.createCodedValue(this.json['vehicle']); +1642 }; +1643 +1644 /** +1645 @returns {CodedValue} +1646 */ 1647 1648 -1649 hQuery.CauseOfDeath = (function() { -1650 function CauseOfDeath(json) { -1651 this.json = json; -1652 } -1653 -1654 /** -1655 @returns {hQuery.Date} -1656 */ +1649 Medication.prototype.reaction = function() { +1650 return hQuery.createCodedValue(this.json['reaction']); +1651 }; +1652 +1653 /** +1654 @returns {CodedValue} +1655 */ +1656 1657 -1658 -1659 CauseOfDeath.prototype.timeOfDeath = function() { -1660 return new hQuery.dateFromUtcSeconds(this.json['timeOfDeath']); -1661 }; -1662 -1663 /** -1664 @returns {int} -1665 */ +1658 Medication.prototype.deliveryMethod = function() { +1659 return hQuery.createCodedValue(this.json['deliveryMethod']); +1660 }; +1661 +1662 /** +1663 @returns {hQuery.MedicationInformation} +1664 */ +1665 1666 -1667 -1668 CauseOfDeath.prototype.ageAtDeath = function() { -1669 return this.json['ageAtDeath']; -1670 }; -1671 -1672 return CauseOfDeath; -1673 -1674 })(); +1667 Medication.prototype.medicationInformation = function() { +1668 return new hQuery.MedicationInformation(this.json); +1669 }; +1670 +1671 /** +1672 @returns {hQuery.TypeOfMedication} Indicates whether this is an over the counter or prescription medication +1673 */ +1674 1675 -1676 /** -1677 @class hQuery.Condition -1678 -1679 This section is used to describe a patients problems/conditions. The types of conditions -1680 described have been constrained to the SNOMED CT Problem Type code set. An unbounded -1681 number of treating providers for the particular condition can be supplied. -1682 @exports Condition as hQuery.Condition -1683 @augments hQuery.CodedEntry -1684 */ -1685 +1676 Medication.prototype.typeOfMedication = function() { +1677 var _ref, _ref1; +1678 return new hQuery.TypeOfMedication((_ref = this.json['typeOfMedication']) != null ? _ref['code'] : void 0, (_ref1 = this.json['typeOfMedication']) != null ? _ref1['codeSystem'] : void 0); +1679 }; +1680 +1681 /** +1682 Values conform to value set 2.16.840.1.113883.1.11.20.7 - Medication Status +1683 Values may be: On Hold, No Longer Active, Active, Prior History +1684 @returns {hQuery.StatusOfMedication} Used to indicate the status of the medication. +1685 */ 1686 -1687 hQuery.Condition = (function(_super) { -1688 __extends(Condition, _super); -1689 -1690 function Condition(json) { -1691 this.json = json; -1692 Condition.__super__.constructor.call(this, this.json); -1693 } -1694 -1695 /** -1696 @returns {Array, hQuery.Provider} an array of providers for the condition -1697 */ -1698 -1699 -1700 Condition.prototype.providers = function() { -1701 var provider, _i, _len, _ref, _results; -1702 -1703 _ref = this.json['treatingProviders']; -1704 _results = []; -1705 for (_i = 0, _len = _ref.length; _i < _len; _i++) { -1706 provider = _ref[_i]; -1707 _results.push(new Provider(provider)); -1708 } -1709 return _results; +1687 +1688 Medication.prototype.statusOfMedication = function() { +1689 var _ref, _ref1; +1690 return new hQuery.StatusOfMedication((_ref = this.json['statusOfMedication']) != null ? _ref['code'] : void 0, (_ref1 = this.json['statusOfMedication']) != null ? _ref1['codeSystem'] : void 0); +1691 }; +1692 +1693 /** +1694 @returns {String} free text instructions to the patient +1695 */ +1696 +1697 +1698 Medication.prototype.patientInstructions = function() { +1699 return this.json['patientInstructions']; +1700 }; +1701 +1702 /** +1703 The duration over which this medication has been active. For example, 5 days. +1704 @returns {Hash} with two keys: unit and scalar +1705 */ +1706 +1707 +1708 Medication.prototype.cumulativeMedicationDuration = function() { +1709 return this.json['cumulativeMedicationDuration']; 1710 }; 1711 1712 /** -1713 Diagnosis Priority -1714 @returns {int} -1715 */ +1713 @returns {Array} an array of {@link FulFillment} objects +1714 */ +1715 1716 -1717 -1718 Condition.prototype.diagnosisPriority = function() { -1719 return this.json['priority']; -1720 }; -1721 -1722 /** -1723 Ordinality -1724 @returns {CodedValue} -1725 */ -1726 +1717 Medication.prototype.fulfillmentHistory = function() { +1718 var order, _i, _len, _ref, _results; +1719 _ref = this.json['fulfillmentHistory']; +1720 _results = []; +1721 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +1722 order = _ref[_i]; +1723 _results.push(new hQuery.Fulfillment(order)); +1724 } +1725 return _results; +1726 }; 1727 -1728 Condition.prototype.ordinality = function() { -1729 return hQuery.createCodedValue(this.json['ordinality']); -1730 }; +1728 /** +1729 @returns {Array} an array of {@link OrderInformation} objects +1730 */ 1731 -1732 /** -1733 age at onset -1734 @returns {int} -1735 */ -1736 -1737 -1738 Condition.prototype.ageAtOnset = function() { -1739 return this.json['ageAtOnset']; -1740 }; -1741 -1742 /** -1743 cause of death -1744 @returns {hQuery.CauseOfDeath} -1745 */ -1746 -1747 -1748 Condition.prototype.causeOfDeath = function() { -1749 if (this.json['causeOfDeath']) { -1750 return new hQuery.CauseOfDeath(this.json['causeOfDeath']); -1751 } -1752 }; +1732 +1733 Medication.prototype.orderInformation = function() { +1734 var order, _i, _len, _ref, _results; +1735 _ref = this.json['orderInformation']; +1736 _results = []; +1737 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +1738 order = _ref[_i]; +1739 _results.push(new hQuery.OrderInformation(order)); +1740 } +1741 return _results; +1742 }; +1743 +1744 return Medication; +1745 +1746 })(hQuery.CodedEntry); +1747 /** +1748 @namespace scoping into the hquery namespace +1749 */ +1750 +1751 var __hasProp = {}.hasOwnProperty, +1752 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; 1753 -1754 /** -1755 problem status -1756 @returns {hQuery.CodedValue} -1757 */ -1758 -1759 -1760 Condition.prototype.problemStatus = function() { -1761 return hQuery.createCodedValue(this.json['problemStatus']); -1762 }; +1754 this.hQuery || (this.hQuery = {}); +1755 +1756 /** +1757 @class CauseOfDeath +1758 @exports CauseOfDeath as hQuery.CauseOfDeath +1759 */ +1760 +1761 +1762 hQuery.CauseOfDeath = (function() { 1763 -1764 /** -1765 comment -1766 @returns {String} -1767 */ -1768 +1764 CauseOfDeath.name = 'CauseOfDeath'; +1765 +1766 function CauseOfDeath(json) { +1767 this.json = json; +1768 } 1769 -1770 Condition.prototype.comment = function() { -1771 return this.json['comment']; -1772 }; +1770 /** +1771 @returns {hQuery.Date} +1772 */ 1773 -1774 /** -1775 This is a description of the level of the severity of the condition. -1776 @returns {CodedValue} -1777 */ +1774 +1775 CauseOfDeath.prototype.timeOfDeath = function() { +1776 return new hQuery.dateFromUtcSeconds(this.json['timeOfDeath']); +1777 }; 1778 -1779 -1780 Condition.prototype.severity = function() { -1781 return hQuery.createCodedValue(this.json['severity']); -1782 }; +1779 /** +1780 @returns {int} +1781 */ +1782 1783 -1784 return Condition; -1785 -1786 })(hQuery.CodedEntry); -1787 /** -1788 @namespace scoping into the hquery namespace -1789 */ -1790 -1791 var __hasProp = {}.hasOwnProperty, -1792 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; -1793 -1794 this.hQuery || (this.hQuery = {}); -1795 -1796 /** -1797 An Encounter is an interaction, regardless of the setting, between a patient and a -1798 practitioner who is vested with primary responsibility for diagnosing, evaluating, -1799 or treating the patients condition. It may include visits, appointments, as well -1800 as non face-to-face interactions. It is also a contact between a patient and a -1801 practitioner who has primary responsibility for assessing and treating the -1802 patient at a given contact, exercising independent judgment. -1803 @class An Encounter is an interaction, regardless of the setting, between a patient and a -1804 practitioner -1805 @augments hQuery.CodedEntry -1806 @exports Encounter as hQuery.Encounter -1807 */ +1784 CauseOfDeath.prototype.ageAtDeath = function() { +1785 return this.json['ageAtDeath']; +1786 }; +1787 +1788 return CauseOfDeath; +1789 +1790 })(); +1791 +1792 /** +1793 @class hQuery.Condition +1794 +1795 This section is used to describe a patients problems/conditions. The types of conditions +1796 described have been constrained to the SNOMED CT Problem Type code set. An unbounded +1797 number of treating providers for the particular condition can be supplied. +1798 @exports Condition as hQuery.Condition +1799 @augments hQuery.CodedEntry +1800 */ +1801 +1802 +1803 hQuery.Condition = (function(_super) { +1804 +1805 __extends(Condition, _super); +1806 +1807 Condition.name = 'Condition'; 1808 -1809 -1810 hQuery.Encounter = (function(_super) { -1811 __extends(Encounter, _super); -1812 -1813 function Encounter(json) { -1814 this.json = json; -1815 Encounter.__super__.constructor.call(this, this.json); -1816 if (this.json['admitTime']) { -1817 this._admitTime = hQuery.dateFromUtcSeconds(this.json['admitTime']); -1818 } -1819 if (this.json['dischargeTime']) { -1820 this._dischargeTime = hQuery.dateFromUtcSeconds(this.json['dischargeTime']); -1821 } -1822 if (this.json['facility']) { -1823 this._facility = new hQuery.Facility(this.json['facility']); -1824 } -1825 } -1826 -1827 /** -1828 @returns {String} -1829 */ -1830 -1831 -1832 Encounter.prototype.dischargeDisposition = function() { -1833 return this.json['dischargeDisposition']; -1834 }; +1809 function Condition(json) { +1810 this.json = json; +1811 Condition.__super__.constructor.call(this, this.json); +1812 } +1813 +1814 /** +1815 @returns {Array, hQuery.Provider} an array of providers for the condition +1816 */ +1817 +1818 +1819 Condition.prototype.providers = function() { +1820 var provider, _i, _len, _ref, _results; +1821 _ref = this.json['treatingProviders']; +1822 _results = []; +1823 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +1824 provider = _ref[_i]; +1825 _results.push(new Provider(provider)); +1826 } +1827 return _results; +1828 }; +1829 +1830 /** +1831 Diagnosis Priority +1832 @returns {int} +1833 */ +1834 1835 -1836 /** -1837 A code indicating the priority of the admission (e.g., Emergency, Urgent, Elective, et cetera) from -1838 National Uniform Billing Committee (NUBC) -1839 @returns {CodedValue} -1840 */ -1841 -1842 -1843 Encounter.prototype.admitType = function() { -1844 return hQuery.createCodedValue(this.json['admitType']); -1845 }; -1846 -1847 /** -1848 Date and time at which the patient was admitted for the encounter -1849 @returns {Date} -1850 */ -1851 -1852 -1853 Encounter.prototype.admitTime = function() { -1854 return this._admitTime; -1855 }; -1856 -1857 /** -1858 Date and time at which the patient was discharged for the encounter -1859 @returns {Date} -1860 */ -1861 -1862 -1863 Encounter.prototype.dischargeTime = function() { -1864 return this._dischargeTime; -1865 }; -1866 -1867 /** -1868 @returns {hQuery.Actor} -1869 */ -1870 +1836 Condition.prototype.diagnosisPriority = function() { +1837 return this.json['priority']; +1838 }; +1839 +1840 /** +1841 Ordinality +1842 @returns {CodedValue} +1843 */ +1844 +1845 +1846 Condition.prototype.ordinality = function() { +1847 return hQuery.createCodedValue(this.json['ordinality']); +1848 }; +1849 +1850 /** +1851 age at onset +1852 @returns {int} +1853 */ +1854 +1855 +1856 Condition.prototype.ageAtOnset = function() { +1857 return this.json['ageAtOnset']; +1858 }; +1859 +1860 /** +1861 cause of death +1862 @returns {hQuery.CauseOfDeath} +1863 */ +1864 +1865 +1866 Condition.prototype.causeOfDeath = function() { +1867 if (this.json['causeOfDeath']) { +1868 return new hQuery.CauseOfDeath(this.json['causeOfDeath']); +1869 } +1870 }; 1871 -1872 Encounter.prototype.performer = function() { -1873 if (this.json['performer']) { -1874 return new hQuery.Actor(this.json['performer']); -1875 } -1876 }; +1872 /** +1873 problem status +1874 @returns {hQuery.CodedValue} +1875 */ +1876 1877 -1878 /** -1879 @returns {hQuery.Organization} -1880 */ +1878 Condition.prototype.problemStatus = function() { +1879 return hQuery.createCodedValue(this.json['problemStatus']); +1880 }; 1881 -1882 -1883 Encounter.prototype.facility = function() { -1884 return this._facility; -1885 }; +1882 /** +1883 comment +1884 @returns {String} +1885 */ 1886 -1887 Encounter.prototype.facilityArrival = function() { -1888 var _ref; -1889 -1890 return (_ref = this._facility) != null ? _ref.startDate() : void 0; -1891 }; -1892 -1893 Encounter.prototype.facilityDeparture = function() { -1894 var _ref; -1895 -1896 return (_ref = this._facility) != null ? _ref.endDate() : void 0; -1897 }; -1898 -1899 /** -1900 @returns {hQuery.CodedEntry} -1901 */ -1902 +1887 +1888 Condition.prototype.comment = function() { +1889 return this.json['comment']; +1890 }; +1891 +1892 /** +1893 This is a description of the level of the severity of the condition. +1894 @returns {CodedValue} +1895 */ +1896 +1897 +1898 Condition.prototype.severity = function() { +1899 return hQuery.createCodedValue(this.json['severity']); +1900 }; +1901 +1902 return Condition; 1903 -1904 Encounter.prototype.reasonForVisit = function() { -1905 if (this.json['reason']) { -1906 return new hQuery.CodedEntry(this.json['reason']); -1907 } -1908 }; -1909 -1910 /** -1911 @returns {Integer} -1912 */ +1904 })(hQuery.CodedEntry); +1905 /** +1906 @namespace scoping into the hquery namespace +1907 */ +1908 +1909 var __hasProp = {}.hasOwnProperty, +1910 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; +1911 +1912 this.hQuery || (this.hQuery = {}); 1913 -1914 -1915 Encounter.prototype.lengthOfStay = function() { -1916 if (!((this.startDate() != null) && (this.endDate() != null))) { -1917 return 0; -1918 } -1919 return Math.floor((this.endDate() - this.startDate()) / (1000 * 60 * 60 * 24)); -1920 }; -1921 -1922 /** -1923 @returns {CodedValue} -1924 */ -1925 +1914 /** +1915 An Encounter is an interaction, regardless of the setting, between a patient and a +1916 practitioner who is vested with primary responsibility for diagnosing, evaluating, +1917 or treating the patients condition. It may include visits, appointments, as well +1918 as non face-to-face interactions. It is also a contact between a patient and a +1919 practitioner who has primary responsibility for assessing and treating the +1920 patient at a given contact, exercising independent judgment. +1921 @class An Encounter is an interaction, regardless of the setting, between a patient and a +1922 practitioner +1923 @augments hQuery.CodedEntry +1924 @exports Encounter as hQuery.Encounter +1925 */ 1926 -1927 Encounter.prototype.transferTo = function() { -1928 return hQuery.createCodedValue(this.json['transferTo']); -1929 }; -1930 -1931 /** -1932 @returns {CodedValue} -1933 */ -1934 -1935 -1936 Encounter.prototype.transferFrom = function() { -1937 return hQuery.createCodedValue(this.json['transferFrom']); -1938 }; -1939 -1940 return Encounter; -1941 -1942 })(hQuery.CodedEntry); -1943 /** -1944 @namespace scoping into the hquery namespace -1945 */ -1946 -1947 var __hasProp = {}.hasOwnProperty, -1948 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; -1949 -1950 this.hQuery || (this.hQuery = {}); +1927 +1928 hQuery.Encounter = (function(_super) { +1929 +1930 __extends(Encounter, _super); +1931 +1932 Encounter.name = 'Encounter'; +1933 +1934 function Encounter(json) { +1935 this.json = json; +1936 Encounter.__super__.constructor.call(this, this.json); +1937 if (this.json['admitTime']) { +1938 this._admitTime = hQuery.dateFromUtcSeconds(this.json['admitTime']); +1939 } +1940 if (this.json['dischargeTime']) { +1941 this._dischargeTime = hQuery.dateFromUtcSeconds(this.json['dischargeTime']); +1942 } +1943 if (this.json['facility']) { +1944 this._facility = new hQuery.Facility(this.json['facility']); +1945 } +1946 } +1947 +1948 /** +1949 @returns {String} +1950 */ 1951 -1952 /** -1953 This represents all interventional, surgical, diagnostic, or therapeutic procedures or -1954 treatments pertinent to the patient. -1955 @class -1956 @augments hQuery.CodedEntry -1957 @exports Procedure as hQuery.Procedure -1958 */ -1959 -1960 -1961 hQuery.Procedure = (function(_super) { -1962 __extends(Procedure, _super); +1952 +1953 Encounter.prototype.dischargeDisposition = function() { +1954 return this.json['dischargeDisposition']; +1955 }; +1956 +1957 /** +1958 A code indicating the priority of the admission (e.g., Emergency, Urgent, Elective, et cetera) from +1959 National Uniform Billing Committee (NUBC) +1960 @returns {CodedValue} +1961 */ +1962 1963 -1964 function Procedure(json) { -1965 this.json = json; -1966 Procedure.__super__.constructor.call(this, this.json); -1967 } -1968 -1969 /** -1970 @returns {hQuery.Actor} The provider that performed the procedure +1964 Encounter.prototype.admitType = function() { +1965 return hQuery.createCodedValue(this.json['admitType']); +1966 }; +1967 +1968 /** +1969 Date and time at which the patient was admitted for the encounter +1970 @returns {Date} 1971 */ 1972 1973 -1974 Procedure.prototype.performer = function() { -1975 if (this.json['performer']) { -1976 return new hQuery.Actor(this.json['performer']); -1977 } -1978 }; -1979 -1980 /** -1981 @returns {hQuery.CodedValue} A SNOMED code indicating the body site on which the -1982 procedure was performed -1983 */ -1984 -1985 -1986 Procedure.prototype.site = function() { -1987 var _ref, _ref1; -1988 -1989 return new hQuery.CodedValue((_ref = this.json['site']) != null ? _ref['code'] : void 0, (_ref1 = this.json['site']) != null ? _ref1['code_system'] : void 0); -1990 }; +1974 Encounter.prototype.admitTime = function() { +1975 return this._admitTime; +1976 }; +1977 +1978 /** +1979 Date and time at which the patient was discharged for the encounter +1980 @returns {Date} +1981 */ +1982 +1983 +1984 Encounter.prototype.dischargeTime = function() { +1985 return this._dischargeTime; +1986 }; +1987 +1988 /** +1989 @returns {hQuery.Actor} +1990 */ 1991 -1992 /** -1993 @returns {hQuery.CodedValue} A SNOMED code indicating where the procedure was performed. -1994 */ -1995 -1996 -1997 Procedure.prototype.source = function() { -1998 return hQuery.createCodedValue(this.json['source']); -1999 }; -2000 -2001 /** -2002 @returns {Date} The actual or intended start of an incision. -2003 */ -2004 -2005 -2006 Procedure.prototype.incisionTime = function() { -2007 if (this.json['incisionTime']) { -2008 return hQuery.dateFromUtcSeconds(this.json['incisionTime']); -2009 } -2010 }; -2011 -2012 /** -2013 Ordinality -2014 @returns {CodedValue} -2015 */ -2016 +1992 +1993 Encounter.prototype.performer = function() { +1994 if (this.json['performer']) { +1995 return new hQuery.Actor(this.json['performer']); +1996 } +1997 }; +1998 +1999 /** +2000 @returns {hQuery.Organization} +2001 */ +2002 +2003 +2004 Encounter.prototype.facility = function() { +2005 return this._facility; +2006 }; +2007 +2008 Encounter.prototype.facilityArrival = function() { +2009 var _ref; +2010 return (_ref = this._facility) != null ? _ref.startDate() : void 0; +2011 }; +2012 +2013 Encounter.prototype.facilityDeparture = function() { +2014 var _ref; +2015 return (_ref = this._facility) != null ? _ref.endDate() : void 0; +2016 }; 2017 -2018 Procedure.prototype.ordinality = function() { -2019 return hQuery.createCodedValue(this.json['ordinality']); -2020 }; +2018 /** +2019 @returns {hQuery.CodedEntry} +2020 */ 2021 -2022 return Procedure; -2023 -2024 })(hQuery.CodedEntry); -2025 /** -2026 @namespace scoping into the hquery namespace -2027 */ +2022 +2023 Encounter.prototype.reasonForVisit = function() { +2024 if (this.json['reason']) { +2025 return new hQuery.CodedEntry(this.json['reason']); +2026 } +2027 }; 2028 -2029 var __hasProp = {}.hasOwnProperty, -2030 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; -2031 -2032 this.hQuery || (this.hQuery = {}); +2029 /** +2030 @returns {Integer} +2031 */ +2032 2033 -2034 /** -2035 Observations generated by laboratories, imaging procedures, and other procedures. The scope -2036 includes hematology, chemistry, serology, virology, toxicology, microbiology, plain x-ray, -2037 ultrasound, CT, MRI, angiography, cardiac echo, nuclear medicine, pathology, and procedure -2038 observations. -2039 @class -2040 @augments hQuery.CodedEntry -2041 @exports Result as hQuery.Result -2042 */ -2043 +2034 Encounter.prototype.lengthOfStay = function() { +2035 if (!((this.startDate() != null) && (this.endDate() != null))) { +2036 return 0; +2037 } +2038 return Math.floor((this.endDate() - this.startDate()) / (1000 * 60 * 60 * 24)); +2039 }; +2040 +2041 /** +2042 @returns {CodedValue} +2043 */ 2044 -2045 hQuery.Result = (function(_super) { -2046 __extends(Result, _super); -2047 -2048 function Result(json) { -2049 this.json = json; -2050 Result.__super__.constructor.call(this, this.json); -2051 } -2052 -2053 /** -2054 ASTM CCR defines a restricted set of required result Type codes (see ResultTypeCode in section 7.3 -2055 Summary of CCD value sets), used to categorize a result into one of several commonly accepted values -2056 (e.g. Hematology, Chemistry, Nuclear Medicine). -2057 @returns {CodedValue} -2058 */ -2059 +2045 +2046 Encounter.prototype.transferTo = function() { +2047 return hQuery.createCodedValue(this.json['transferTo']); +2048 }; +2049 +2050 /** +2051 @returns {CodedValue} +2052 */ +2053 +2054 +2055 Encounter.prototype.transferFrom = function() { +2056 return hQuery.createCodedValue(this.json['transferFrom']); +2057 }; +2058 +2059 return Encounter; 2060 -2061 Result.prototype.resultType = function() { -2062 return this.type(); -2063 }; -2064 -2065 /** -2066 @returns {CodedValue} -2067 */ +2061 })(hQuery.CodedEntry); +2062 /** +2063 @namespace scoping into the hquery namespace +2064 */ +2065 +2066 var __hasProp = {}.hasOwnProperty, +2067 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; 2068 -2069 -2070 Result.prototype.interpretation = function() { -2071 return hQuery.createCodedValue(this.json['interpretation']); -2072 }; -2073 -2074 /** -2075 @returns {String} -2076 */ -2077 +2069 this.hQuery || (this.hQuery = {}); +2070 +2071 /** +2072 This represents all interventional, surgical, diagnostic, or therapeutic procedures or +2073 treatments pertinent to the patient. +2074 @class +2075 @augments hQuery.CodedEntry +2076 @exports Procedure as hQuery.Procedure +2077 */ 2078 -2079 Result.prototype.referenceRange = function() { -2080 return this.json['referenceRange']; -2081 }; -2082 -2083 /** -2084 @returns {String} -2085 */ -2086 -2087 -2088 Result.prototype.comment = function() { -2089 return this.json['comment']; -2090 }; -2091 -2092 return Result; -2093 -2094 })(hQuery.CodedEntry); -2095 /** -2096 @namespace scoping into the hquery namespace -2097 */ -2098 -2099 var _ref, -2100 __hasProp = {}.hasOwnProperty, -2101 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; -2102 -2103 this.hQuery || (this.hQuery = {}); -2104 -2105 /** -2106 NoImmunzation as defined by value set 2.16.840.1.113883.1.11.19717 -2107 The terms come from Health Level Seven (HL7) Version 3.0 Vocabulary and are managed by HL7 -2108 It indicates the reason an immunization was not administered. -2109 -2110 @class NoImmunization - describes the status of the medication -2111 @augments hQuery.CodedEntry -2112 @exports NoImmunization as hQuery.NoImmunization -2113 */ -2114 -2115 -2116 hQuery.NoImmunization = (function(_super) { -2117 var IMMUNITY, MED_PRECAUTION, OUT_OF_STOCK, PAT_OBJ, PHIL_OBJ, REL_OBJ, VAC_EFF, VAC_SAFETY; -2118 -2119 __extends(NoImmunization, _super); -2120 -2121 function NoImmunization() { -2122 _ref = NoImmunization.__super__.constructor.apply(this, arguments); -2123 return _ref; -2124 } +2079 +2080 hQuery.Procedure = (function(_super) { +2081 +2082 __extends(Procedure, _super); +2083 +2084 Procedure.name = 'Procedure'; +2085 +2086 function Procedure(json) { +2087 this.json = json; +2088 Procedure.__super__.constructor.call(this, this.json); +2089 } +2090 +2091 /** +2092 @returns {hQuery.Actor} The provider that performed the procedure +2093 */ +2094 +2095 +2096 Procedure.prototype.performer = function() { +2097 if (this.json['performer']) { +2098 return new hQuery.Actor(this.json['performer']); +2099 } +2100 }; +2101 +2102 /** +2103 @returns {hQuery.CodedValue} A SNOMED code indicating the body site on which the +2104 procedure was performed +2105 */ +2106 +2107 +2108 Procedure.prototype.site = function() { +2109 var _ref, _ref1; +2110 return new hQuery.CodedValue((_ref = this.json['site']) != null ? _ref['code'] : void 0, (_ref1 = this.json['site']) != null ? _ref1['codeSystem'] : void 0); +2111 }; +2112 +2113 /** +2114 @returns {hQuery.CodedValue} A SNOMED code indicating where the procedure was performed. +2115 */ +2116 +2117 +2118 Procedure.prototype.source = function() { +2119 return hQuery.createCodedValue(this.json['source']); +2120 }; +2121 +2122 /** +2123 @returns {Date} The actual or intended start of an incision. +2124 */ 2125 -2126 IMMUNITY = "IMMUNE"; -2127 -2128 MED_PRECAUTION = "MEDPREC"; -2129 -2130 OUT_OF_STOCK = "OSTOCK"; -2131 -2132 PAT_OBJ = "PATOBJ"; -2133 -2134 PHIL_OBJ = "PHILISOP"; -2135 -2136 REL_OBJ = "RELIG"; +2126 +2127 Procedure.prototype.incisionTime = function() { +2128 if (this.json['incisionTime']) { +2129 return hQuery.dateFromUtcSeconds(this.json['incisionTime']); +2130 } +2131 }; +2132 +2133 /** +2134 Ordinality +2135 @returns {CodedValue} +2136 */ 2137 -2138 VAC_EFF = "VACEFF"; -2139 -2140 VAC_SAFETY = "VACSAF"; -2141 -2142 /** -2143 @returns {Boolean} -2144 */ -2145 -2146 -2147 NoImmunization.prototype.isImmune = function() { -2148 return this.c === IMMUNITY; -2149 }; -2150 -2151 /** -2152 @returns {Boolean} -2153 */ +2138 +2139 Procedure.prototype.ordinality = function() { +2140 return hQuery.createCodedValue(this.json['ordinality']); +2141 }; +2142 +2143 return Procedure; +2144 +2145 })(hQuery.CodedEntry); +2146 /** +2147 @namespace scoping into the hquery namespace +2148 */ +2149 +2150 var __hasProp = {}.hasOwnProperty, +2151 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; +2152 +2153 this.hQuery || (this.hQuery = {}); 2154 -2155 -2156 NoImmunization.prototype.isMedPrec = function() { -2157 return this.c === MED_PRECAUTION; -2158 }; -2159 -2160 /** -2161 @returns {Boolean} -2162 */ -2163 +2155 /** +2156 Observations generated by laboratories, imaging procedures, and other procedures. The scope +2157 includes hematology, chemistry, serology, virology, toxicology, microbiology, plain x-ray, +2158 ultrasound, CT, MRI, angiography, cardiac echo, nuclear medicine, pathology, and procedure +2159 observations. +2160 @class +2161 @augments hQuery.CodedEntry +2162 @exports Result as hQuery.Result +2163 */ 2164 -2165 NoImmunization.prototype.isOstock = function() { -2166 return this.c === OUT_OF_STOCK; -2167 }; -2168 -2169 /** -2170 @returns {Boolean} -2171 */ -2172 -2173 -2174 NoImmunization.prototype.isPatObj = function() { -2175 return this.c === PAT_OBJ; -2176 }; -2177 -2178 /** -2179 @returns {Boolean} -2180 */ -2181 -2182 -2183 NoImmunization.prototype.isPhilisop = function() { -2184 return this.c === PHIL_OBJ; -2185 }; -2186 -2187 /** -2188 @returns {Boolean} -2189 */ -2190 -2191 -2192 NoImmunization.prototype.isRelig = function() { -2193 return this.c === REL_OBJ; -2194 }; -2195 -2196 /** -2197 @returns {Boolean} -2198 */ -2199 -2200 -2201 NoImmunization.prototype.isVacEff = function() { -2202 return this.c === VAC_EFF; -2203 }; -2204 -2205 /** -2206 @returns {Boolean} -2207 */ -2208 -2209 -2210 NoImmunization.prototype.isVacSaf = function() { -2211 return this.c === VAC_SAFETY; -2212 }; -2213 -2214 return NoImmunization; +2165 +2166 hQuery.Result = (function(_super) { +2167 +2168 __extends(Result, _super); +2169 +2170 Result.name = 'Result'; +2171 +2172 function Result(json) { +2173 this.json = json; +2174 Result.__super__.constructor.call(this, this.json); +2175 } +2176 +2177 /** +2178 ASTM CCR defines a restricted set of required result Type codes (see ResultTypeCode in section 7.3 +2179 Summary of CCD value sets), used to categorize a result into one of several commonly accepted values +2180 (e.g. Hematology, Chemistry, Nuclear Medicine). +2181 @returns {CodedValue} +2182 */ +2183 +2184 +2185 Result.prototype.resultType = function() { +2186 return this.type(); +2187 }; +2188 +2189 /** +2190 @returns {CodedValue} +2191 */ +2192 +2193 +2194 Result.prototype.interpretation = function() { +2195 return hQuery.createCodedValue(this.json['interpretation']); +2196 }; +2197 +2198 /** +2199 @returns {String} +2200 */ +2201 +2202 +2203 Result.prototype.referenceRange = function() { +2204 return this.json['referenceRange']; +2205 }; +2206 +2207 /** +2208 @returns {String} +2209 */ +2210 +2211 +2212 Result.prototype.comment = function() { +2213 return this.json['comment']; +2214 }; 2215 -2216 })(hQuery.CodedValue); +2216 return Result; 2217 -2218 /** -2219 @class represents a immunization entry for a patient. -2220 @augments hQuery.CodedEntry -2221 @exports Immunization as hQuery.Immunization -2222 */ -2223 -2224 -2225 hQuery.Immunization = (function(_super) { -2226 __extends(Immunization, _super); +2218 })(hQuery.CodedEntry); +2219 /** +2220 @namespace scoping into the hquery namespace +2221 */ +2222 +2223 var __hasProp = {}.hasOwnProperty, +2224 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; +2225 +2226 this.hQuery || (this.hQuery = {}); 2227 -2228 function Immunization(json) { -2229 this.json = json; -2230 Immunization.__super__.constructor.call(this, this.json); -2231 } +2228 /** +2229 NoImmunzation as defined by value set 2.16.840.1.113883.1.11.19717 +2230 The terms come from Health Level Seven (HL7) Version 3.0 Vocabulary and are managed by HL7 +2231 It indicates the reason an immunization was not administered. 2232 -2233 /** -2234 @returns{hQuery.Scalar} -2235 */ -2236 +2233 @class NoImmunization - describes the status of the medication +2234 @augments hQuery.CodedEntry +2235 @exports NoImmunization as hQuery.NoImmunization +2236 */ 2237 -2238 Immunization.prototype.medicationSeriesNumber = function() { -2239 if (this.json['medicationSeriesNumber']) { -2240 return new hQuery.Scalar(this.json['medicationSeriesNumber']); -2241 } -2242 }; +2238 +2239 hQuery.NoImmunization = (function(_super) { +2240 var IMMUNITY, MED_PRECAUTION, OUT_OF_STOCK, PAT_OBJ, PHIL_OBJ, REL_OBJ, VAC_EFF, VAC_SAFETY; +2241 +2242 __extends(NoImmunization, _super); 2243 -2244 /** -2245 @returns{hQuery.MedicationInformation} -2246 */ -2247 -2248 -2249 Immunization.prototype.medicationInformation = function() { -2250 return new hQuery.MedicationInformation(this.json); -2251 }; -2252 -2253 /** -2254 @returns{Date} Date immunization was administered -2255 */ -2256 +2244 NoImmunization.name = 'NoImmunization'; +2245 +2246 function NoImmunization() { +2247 return NoImmunization.__super__.constructor.apply(this, arguments); +2248 } +2249 +2250 IMMUNITY = "IMMUNE"; +2251 +2252 MED_PRECAUTION = "MEDPREC"; +2253 +2254 OUT_OF_STOCK = "OSTOCK"; +2255 +2256 PAT_OBJ = "PATOBJ"; 2257 -2258 Immunization.prototype.administeredDate = function() { -2259 return dateFromUtcSeconds(this.json['administeredDate']); -2260 }; +2258 PHIL_OBJ = "PHILISOP"; +2259 +2260 REL_OBJ = "RELIG"; 2261 -2262 /** -2263 @returns{hQuery.Actor} Performer of immunization -2264 */ +2262 VAC_EFF = "VACEFF"; +2263 +2264 VAC_SAFETY = "VACSAF"; 2265 -2266 -2267 Immunization.prototype.performer = function() { -2268 if (this.json['performer']) { -2269 return new hQuery.Actor(this.json['performer']); -2270 } -2271 }; -2272 -2273 /** -2274 @returns {comment} human readable description of event -2275 */ -2276 -2277 -2278 Immunization.prototype.comment = function() { -2279 return this.json['comment']; -2280 }; -2281 -2282 /** -2283 @returns {Boolean} whether the immunization has been refused by the patient. -2284 */ -2285 -2286 -2287 Immunization.prototype.refusalInd = function() { -2288 return this.json['negationInd']; -2289 }; -2290 -2291 /** -2292 NoImmunzation as defined by value set 2.16.840.1.113883.1.11.19717 -2293 The terms come from Health Level Seven (HL7) Version 3.0 Vocabulary and are managed by HL7 -2294 It indicates the reason an immunization was not administered. -2295 @returns {hQuery.NoImmunization} Used to indicate reason an immunization was not administered. -2296 */ +2266 /** +2267 @returns {Boolean} +2268 */ +2269 +2270 +2271 NoImmunization.prototype.isImmune = function() { +2272 return this.c === IMMUNITY; +2273 }; +2274 +2275 /** +2276 @returns {Boolean} +2277 */ +2278 +2279 +2280 NoImmunization.prototype.isMedPrec = function() { +2281 return this.c === MED_PRECAUTION; +2282 }; +2283 +2284 /** +2285 @returns {Boolean} +2286 */ +2287 +2288 +2289 NoImmunization.prototype.isOstock = function() { +2290 return this.c === OUT_OF_STOCK; +2291 }; +2292 +2293 /** +2294 @returns {Boolean} +2295 */ +2296 2297 -2298 -2299 Immunization.prototype.refusalReason = function() { -2300 var _ref1, _ref2; +2298 NoImmunization.prototype.isPatObj = function() { +2299 return this.c === PAT_OBJ; +2300 }; 2301 -2302 return new hQuery.NoImmunization((_ref1 = this.json['negationReason']) != null ? _ref1['code'] : void 0, (_ref2 = this.json['negationReason']) != null ? _ref2['code_system'] : void 0); -2303 }; -2304 -2305 return Immunization; +2302 /** +2303 @returns {Boolean} +2304 */ +2305 2306 -2307 })(hQuery.CodedEntry); -2308 /** -2309 @namespace scoping into the hquery namespace -2310 */ -2311 -2312 var __hasProp = {}.hasOwnProperty, -2313 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; +2307 NoImmunization.prototype.isPhilisop = function() { +2308 return this.c === PHIL_OBJ; +2309 }; +2310 +2311 /** +2312 @returns {Boolean} +2313 */ 2314 -2315 this.hQuery || (this.hQuery = {}); -2316 -2317 /** -2318 @class -2319 @augments hQuery.CodedEntry -2320 @exports Allergy as hQuery.Allergy -2321 */ -2322 +2315 +2316 NoImmunization.prototype.isRelig = function() { +2317 return this.c === REL_OBJ; +2318 }; +2319 +2320 /** +2321 @returns {Boolean} +2322 */ 2323 -2324 hQuery.Allergy = (function(_super) { -2325 __extends(Allergy, _super); -2326 -2327 function Allergy(json) { -2328 this.json = json; -2329 Allergy.__super__.constructor.call(this, this.json); -2330 } -2331 -2332 /** -2333 Food and substance allergies use the Unique Ingredient Identifier(UNII) from the FDA -2334 http://www.fda.gov/ForIndustry/DataStandards/StructuredProductLabeling/ucm162523.htm -2335 -2336 Allegies to a class of medication Shall contain a value descending from the NDF-RT concept types -2337 of Mechanism of Action - N0000000223, Physiologic Effect - N0000009802 or -2338 Chemical Structure - N0000000002. NUI will be used as the concept code. -2339 For more information, please see the Web Site -2340 http://www.cancer.gov/cancertopics/terminologyresources/page5 -2341 -2342 Allergies to a specific medication shall use RxNorm for the values. -2343 @returns {CodedValue} -2344 */ -2345 -2346 -2347 Allergy.prototype.product = function() { -2348 return this.type(); -2349 }; +2324 +2325 NoImmunization.prototype.isVacEff = function() { +2326 return this.c === VAC_EFF; +2327 }; +2328 +2329 /** +2330 @returns {Boolean} +2331 */ +2332 +2333 +2334 NoImmunization.prototype.isVacSaf = function() { +2335 return this.c === VAC_SAFETY; +2336 }; +2337 +2338 return NoImmunization; +2339 +2340 })(hQuery.CodedValue); +2341 +2342 /** +2343 @class represents a immunization entry for a patient. +2344 @augments hQuery.CodedEntry +2345 @exports Immunization as hQuery.Immunization +2346 */ +2347 +2348 +2349 hQuery.Immunization = (function(_super) { 2350 -2351 /** -2352 Date of allergy or adverse event -2353 @returns{Date} -2354 */ -2355 -2356 -2357 Allergy.prototype.adverseEventDate = function() { -2358 return dateFromUtcSeconds(this.json['adverseEventDate']); -2359 }; -2360 -2361 /** -2362 Adverse event types SHALL be coded as specified in HITSP/C80 Section 2.2.3.4.2 Allergy/Adverse Event Type -2363 @returns {CodedValue} -2364 */ -2365 -2366 -2367 Allergy.prototype.adverseEventType = function() { -2368 return hQuery.createCodedValue(this.json['type']); +2351 __extends(Immunization, _super); +2352 +2353 Immunization.name = 'Immunization'; +2354 +2355 function Immunization(json) { +2356 this.json = json; +2357 Immunization.__super__.constructor.call(this, this.json); +2358 } +2359 +2360 /** +2361 @returns{hQuery.Scalar} +2362 */ +2363 +2364 +2365 Immunization.prototype.medicationSeriesNumber = function() { +2366 if (this.json['medicationSeriesNumber']) { +2367 return new hQuery.Scalar(this.json['medicationSeriesNumber']); +2368 } 2369 }; 2370 2371 /** -2372 This indicates the reaction that may be caused by the product or agent. -2373 It is defined by 2.16.840.1.113883.3.88.12.3221.6.2 and are SNOMED-CT codes. -2374 420134006 Propensity to adverse reactions (disorder) -2375 418038007 Propensity to adverse reactions to substance (disorder) -2376 419511003 Propensity to adverse reactions to drug (disorder) -2377 418471000 Propensity to adverse reactions to food (disorder) -2378 419199007 Allergy to substance (disorder) -2379 416098002 Drug allergy (disorder) -2380 414285001 Food allergy (disorder) -2381 59037007 Drug intolerance (disorder) -2382 235719002 Food intolerance (disorder) -2383 @returns {CodedValue} -2384 */ -2385 -2386 -2387 Allergy.prototype.reaction = function() { -2388 return hQuery.createCodedValue(this.json['reaction']); -2389 }; -2390 -2391 /** -2392 This is a description of the level of the severity of the allergy or intolerance. -2393 Use SNOMED-CT Codes as defined by 2.16.840.1.113883.3.88.12.3221.6.8 -2394 255604002 Mild -2395 371923003 Mild to Moderate -2396 6736007 Moderate -2397 371924009 Moderate to Severe -2398 24484000 Severe -2399 399166001 Fatal -2400 @returns {CodedValue} -2401 */ -2402 +2372 @returns{hQuery.MedicationInformation} +2373 */ +2374 +2375 +2376 Immunization.prototype.medicationInformation = function() { +2377 return new hQuery.MedicationInformation(this.json); +2378 }; +2379 +2380 /** +2381 @returns{Date} Date immunization was administered +2382 */ +2383 +2384 +2385 Immunization.prototype.administeredDate = function() { +2386 return dateFromUtcSeconds(this.json['administeredDate']); +2387 }; +2388 +2389 /** +2390 @returns{hQuery.Actor} Performer of immunization +2391 */ +2392 +2393 +2394 Immunization.prototype.performer = function() { +2395 if (this.json['performer']) { +2396 return new hQuery.Actor(this.json['performer']); +2397 } +2398 }; +2399 +2400 /** +2401 @returns {comment} human readable description of event +2402 */ 2403 -2404 Allergy.prototype.severity = function() { -2405 return hQuery.createCodedValue(this.json['severity']); -2406 }; -2407 -2408 /** -2409 Additional comment or textual information -2410 @returns {String} +2404 +2405 Immunization.prototype.comment = function() { +2406 return this.json['comment']; +2407 }; +2408 +2409 /** +2410 @returns {Boolean} whether the immunization has been refused by the patient. 2411 */ 2412 2413 -2414 Allergy.prototype.comment = function() { -2415 return this.json['comment']; +2414 Immunization.prototype.refusalInd = function() { +2415 return this.json['negationInd']; 2416 }; 2417 -2418 return Allergy; -2419 -2420 })(hQuery.CodedEntry); -2421 /** -2422 @namespace scoping into the hquery namespace -2423 */ -2424 this.hQuery || (this.hQuery = {}); +2418 /** +2419 NoImmunzation as defined by value set 2.16.840.1.113883.1.11.19717 +2420 The terms come from Health Level Seven (HL7) Version 3.0 Vocabulary and are managed by HL7 +2421 It indicates the reason an immunization was not administered. +2422 @returns {hQuery.NoImmunization} Used to indicate reason an immunization was not administered. +2423 */ +2424 2425 -2426 /** -2427 @class -2428 -2429 @exports Provider as hQuery.Provider -2430 */ -2431 +2426 Immunization.prototype.refusalReason = function() { +2427 var _ref, _ref1; +2428 return new hQuery.NoImmunization((_ref = this.json['negationReason']) != null ? _ref['code'] : void 0, (_ref1 = this.json['negationReason']) != null ? _ref1['codeSystem'] : void 0); +2429 }; +2430 +2431 return Immunization; 2432 -2433 hQuery.Provider = (function() { -2434 function Provider(json) { -2435 this.json = json; -2436 } +2433 })(hQuery.CodedEntry); +2434 /** +2435 @namespace scoping into the hquery namespace +2436 */ 2437 -2438 /** -2439 @returns {hQuery.Person} -2440 */ -2441 +2438 var __hasProp = {}.hasOwnProperty, +2439 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; +2440 +2441 this.hQuery || (this.hQuery = {}); 2442 -2443 Provider.prototype.providerEntity = function() { -2444 if (this.json['providerEntity']) { -2445 return new hQuery.Person(this.json['providerEntity']); -2446 } -2447 }; +2443 /** +2444 @class +2445 @augments hQuery.CodedEntry +2446 @exports Allergy as hQuery.Allergy +2447 */ 2448 -2449 /** -2450 @returns {hQuery.DateRange} -2451 */ -2452 +2449 +2450 hQuery.Allergy = (function(_super) { +2451 +2452 __extends(Allergy, _super); 2453 -2454 Provider.prototype.careProvisionDateRange = function() { -2455 if (this.json['careProvisionDateRange']) { -2456 return new hQuery.DateRange(this.json['careProvisionDateRange']); -2457 } -2458 }; -2459 -2460 /** -2461 @returns {hQuery.CodedValue} -2462 */ -2463 -2464 -2465 Provider.prototype.role = function() { -2466 return hQuery.createCodedValue(this.json['role']); -2467 }; -2468 -2469 /** -2470 @returns {String} -2471 */ -2472 -2473 -2474 Provider.prototype.patientID = function() { -2475 return this.json['patientID']; -2476 }; -2477 -2478 /** -2479 @returns {hQuery.CodedValue} -2480 */ -2481 -2482 -2483 Provider.prototype.providerType = function() { -2484 return hQuery.createCodedValue(this.json['providerType']); -2485 }; -2486 -2487 /** -2488 @returns {String} -2489 */ -2490 -2491 -2492 Provider.prototype.providerID = function() { -2493 return this.json['providerID']; -2494 }; +2454 Allergy.name = 'Allergy'; +2455 +2456 function Allergy(json) { +2457 this.json = json; +2458 Allergy.__super__.constructor.call(this, this.json); +2459 } +2460 +2461 /** +2462 Food and substance allergies use the Unique Ingredient Identifier(UNII) from the FDA +2463 http://www.fda.gov/ForIndustry/DataStandards/StructuredProductLabeling/ucm162523.htm +2464 +2465 Allegies to a class of medication Shall contain a value descending from the NDF-RT concept types +2466 of Mechanism of Action - N0000000223, Physiologic Effect - N0000009802 or +2467 Chemical Structure - N0000000002. NUI will be used as the concept code. +2468 For more information, please see the Web Site +2469 http://www.cancer.gov/cancertopics/terminologyresources/page5 +2470 +2471 Allergies to a specific medication shall use RxNorm for the values. +2472 @returns {CodedValue} +2473 */ +2474 +2475 +2476 Allergy.prototype.product = function() { +2477 return this.type(); +2478 }; +2479 +2480 /** +2481 Date of allergy or adverse event +2482 @returns{Date} +2483 */ +2484 +2485 +2486 Allergy.prototype.adverseEventDate = function() { +2487 return dateFromUtcSeconds(this.json['adverseEventDate']); +2488 }; +2489 +2490 /** +2491 Adverse event types SHALL be coded as specified in HITSP/C80 Section 2.2.3.4.2 Allergy/Adverse Event Type +2492 @returns {CodedValue} +2493 */ +2494 2495 -2496 /** -2497 @returns {hQuery.Organization} -2498 */ +2496 Allergy.prototype.adverseEventType = function() { +2497 return hQuery.createCodedValue(this.json['type']); +2498 }; 2499 -2500 -2501 Provider.prototype.organizationName = function() { -2502 return new hQuery.Organization(this.json); -2503 }; -2504 -2505 return Provider; -2506 -2507 })(); -2508 /** -2509 @namespace scoping into the hquery namespace -2510 */ -2511 -2512 var __hasProp = {}.hasOwnProperty, -2513 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; +2500 /** +2501 This indicates the reaction that may be caused by the product or agent. +2502 It is defined by 2.16.840.1.113883.3.88.12.3221.6.2 and are SNOMED-CT codes. +2503 420134006 Propensity to adverse reactions (disorder) +2504 418038007 Propensity to adverse reactions to substance (disorder) +2505 419511003 Propensity to adverse reactions to drug (disorder) +2506 418471000 Propensity to adverse reactions to food (disorder) +2507 419199007 Allergy to substance (disorder) +2508 416098002 Drug allergy (disorder) +2509 414285001 Food allergy (disorder) +2510 59037007 Drug intolerance (disorder) +2511 235719002 Food intolerance (disorder) +2512 @returns {CodedValue} +2513 */ 2514 -2515 this.hQuery || (this.hQuery = {}); -2516 -2517 /** -2518 @class -2519 @augments hQuery.CodedEntry -2520 @exports Language as hQuery.Language -2521 */ -2522 -2523 -2524 hQuery.Language = (function(_super) { -2525 __extends(Language, _super); -2526 -2527 function Language(json) { -2528 this.json = json; -2529 Language.__super__.constructor.call(this, this.json); -2530 } +2515 +2516 Allergy.prototype.reaction = function() { +2517 return hQuery.createCodedValue(this.json['reaction']); +2518 }; +2519 +2520 /** +2521 This is a description of the level of the severity of the allergy or intolerance. +2522 Use SNOMED-CT Codes as defined by 2.16.840.1.113883.3.88.12.3221.6.8 +2523 255604002 Mild +2524 371923003 Mild to Moderate +2525 6736007 Moderate +2526 371924009 Moderate to Severe +2527 24484000 Severe +2528 399166001 Fatal +2529 @returns {CodedValue} +2530 */ 2531 -2532 /** -2533 @returns {hQuery.CodedValue} -2534 */ -2535 +2532 +2533 Allergy.prototype.severity = function() { +2534 return hQuery.createCodedValue(this.json['severity']); +2535 }; 2536 -2537 Language.prototype.modeCode = function() { -2538 return hQuery.createCodedValue(this.json['modeCode']); -2539 }; -2540 -2541 /** -2542 @returns {String} -2543 */ -2544 -2545 -2546 Language.prototype.preferenceIndicator = function() { -2547 return this.json['preferenceIndicator']; -2548 }; -2549 -2550 return Language; -2551 -2552 })(hQuery.CodedEntry); -2553 /** -2554 @namespace scoping into the hquery namespace -2555 */ -2556 -2557 var __hasProp = {}.hasOwnProperty, -2558 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; -2559 -2560 this.hQuery || (this.hQuery = {}); +2537 /** +2538 Additional comment or textual information +2539 @returns {String} +2540 */ +2541 +2542 +2543 Allergy.prototype.comment = function() { +2544 return this.json['comment']; +2545 }; +2546 +2547 return Allergy; +2548 +2549 })(hQuery.CodedEntry); +2550 /** +2551 @namespace scoping into the hquery namespace +2552 */ +2553 +2554 this.hQuery || (this.hQuery = {}); +2555 +2556 /** +2557 @class +2558 +2559 @exports Provider as hQuery.Provider +2560 */ 2561 -2562 /** -2563 This includes information about the patients current and past pregnancy status -2564 The Coded Entry code system should be SNOMED-CT -2565 @class -2566 @augments hQuery.CodedEntry -2567 @exports Pregnancy as hQuery.Pregnancy -2568 */ -2569 +2562 +2563 hQuery.Provider = (function() { +2564 +2565 Provider.name = 'Provider'; +2566 +2567 function Provider(json) { +2568 this.json = json; +2569 } 2570 -2571 hQuery.Pregnancy = (function(_super) { -2572 __extends(Pregnancy, _super); -2573 -2574 function Pregnancy(json) { -2575 this.json = json; -2576 Pregnancy.__super__.constructor.call(this, this.json); -2577 } -2578 -2579 /** -2580 @returns {String} -2581 */ -2582 -2583 -2584 Pregnancy.prototype.comment = function() { -2585 return this.json['comment']; -2586 }; -2587 -2588 return Pregnancy; -2589 -2590 })(hQuery.CodedEntry); -2591 /** -2592 @namespace scoping into the hquery namespace -2593 */ -2594 -2595 var __hasProp = {}.hasOwnProperty, -2596 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; +2571 /** +2572 @returns {hQuery.Person} +2573 */ +2574 +2575 +2576 Provider.prototype.providerEntity = function() { +2577 if (this.json['providerEntity']) { +2578 return new hQuery.Person(this.json['providerEntity']); +2579 } +2580 }; +2581 +2582 /** +2583 @returns {hQuery.DateRange} +2584 */ +2585 +2586 +2587 Provider.prototype.careProvisionDateRange = function() { +2588 if (this.json['careProvisionDateRange']) { +2589 return new hQuery.DateRange(this.json['careProvisionDateRange']); +2590 } +2591 }; +2592 +2593 /** +2594 @returns {hQuery.CodedValue} +2595 */ +2596 2597 -2598 this.hQuery || (this.hQuery = {}); -2599 -2600 /** +2598 Provider.prototype.role = function() { +2599 return hQuery.createCodedValue(this.json['role']); +2600 }; 2601 -2602 The Social History Observation is used to define the patient's occupational, personal (e.g. lifestyle), -2603 social, and environmental history and health risk factors, as well as administrative data such as -2604 marital status, race, ethnicity and religious affiliation. The types of conditions -2605 described have been constrained to the SNOMED CT code system using constrained code set, 2.16.840.1.113883.3.88.12.80.60: -2606 229819007 Tobacco use and exposure -2607 256235009 Exercise -2608 160573003 Alcohol Intake -2609 364393001 Nutritional observable -2610 364703007 Employment detail -2611 425400000 Toxic exposure status -2612 363908000 Details of drug misuse behavior -2613 228272008 Health-related behavior -2614 105421008 Educational achievement +2602 /** +2603 @returns {String} +2604 */ +2605 +2606 +2607 Provider.prototype.patientID = function() { +2608 return this.json['patientID']; +2609 }; +2610 +2611 /** +2612 @returns {hQuery.CodedValue} +2613 */ +2614 2615 -2616 note: Social History is not part of the existing green c32. -2617 @exports Socialhistory as hQuery.Socialhistory -2618 @augments hQuery.CodedEntry -2619 */ -2620 -2621 -2622 hQuery.Socialhistory = (function(_super) { -2623 __extends(Socialhistory, _super); +2616 Provider.prototype.providerType = function() { +2617 return hQuery.createCodedValue(this.json['providerType']); +2618 }; +2619 +2620 /** +2621 @returns {String} +2622 */ +2623 2624 -2625 function Socialhistory(json) { -2626 this.json = json; -2627 Socialhistory.__super__.constructor.call(this, this.json); -2628 } -2629 -2630 /** -2631 Value returns the value of the result. This will return an object. The properties of this -2632 object are dependent on the type of result. -2633 */ -2634 -2635 -2636 Socialhistory.prototype.value = function() { -2637 return this.json['value']; -2638 }; +2625 Provider.prototype.providerID = function() { +2626 return this.json['providerID']; +2627 }; +2628 +2629 /** +2630 @returns {hQuery.Organization} +2631 */ +2632 +2633 +2634 Provider.prototype.organizationName = function() { +2635 return new hQuery.Organization(this.json); +2636 }; +2637 +2638 return Provider; 2639 -2640 return Socialhistory; -2641 -2642 })(hQuery.CodedEntry); -2643 /** -2644 @namespace scoping into the hquery namespace -2645 */ -2646 -2647 var __hasProp = {}.hasOwnProperty, -2648 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; +2640 })(); +2641 /** +2642 @namespace scoping into the hquery namespace +2643 */ +2644 +2645 var __hasProp = {}.hasOwnProperty, +2646 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; +2647 +2648 this.hQuery || (this.hQuery = {}); 2649 -2650 this.hQuery || (this.hQuery = {}); -2651 -2652 /** -2653 -2654 The plan of care contains data defining prospective or intended orders, interventions, encounters, services, and procedures for the patient. +2650 /** +2651 @class +2652 @augments hQuery.CodedEntry +2653 @exports Language as hQuery.Language +2654 */ 2655 -2656 @exports CareGoal as hQuery.CareGoal -2657 @augments hQuery.CodedEntry -2658 */ -2659 +2656 +2657 hQuery.Language = (function(_super) { +2658 +2659 __extends(Language, _super); 2660 -2661 hQuery.CareGoal = (function(_super) { -2662 __extends(CareGoal, _super); -2663 -2664 function CareGoal(json) { -2665 this.json = json; -2666 CareGoal.__super__.constructor.call(this, this.json); -2667 } -2668 -2669 return CareGoal; -2670 -2671 })(hQuery.CodedEntry); -2672 /** -2673 @namespace scoping into the hquery namespace -2674 */ -2675 -2676 var __hasProp = {}.hasOwnProperty, -2677 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; -2678 -2679 this.hQuery || (this.hQuery = {}); +2661 Language.name = 'Language'; +2662 +2663 function Language(json) { +2664 this.json = json; +2665 Language.__super__.constructor.call(this, this.json); +2666 } +2667 +2668 /** +2669 @returns {hQuery.CodedValue} +2670 */ +2671 +2672 +2673 Language.prototype.modeCode = function() { +2674 return hQuery.createCodedValue(this.json['modeCode']); +2675 }; +2676 +2677 /** +2678 @returns {String} +2679 */ 2680 -2681 /** -2682 -2683 The Medical Equipment section contains information describing a patients implanted and external medical devices and equipment that their health status depends on, as well as any pertinent equipment or device history. -2684 -2685 The template identifier for this section is 2.16.840.1.113883.3.88.11.83.128 -2686 -2687 C83-[CT-128-1] This section shall conform to the HL7 CCD section, and shall contain a templateId element whose root attribute is 2.16.840.1.113883.10.20.1.7. -2688 C83-[CT-128-2] This section SHALL conform to the IHE Medical Devices Section, and shall contain a templateId element whose root attribute is 1.3.6.1.4.1.19376.1.5.3.1.1.5.3.5 -2689 -2690 @exports MedicalEquipment as hQuery.MedicalEquipment -2691 @augments hQuery.CodedEntry -2692 */ -2693 -2694 -2695 hQuery.MedicalEquipment = (function(_super) { -2696 __extends(MedicalEquipment, _super); +2681 +2682 Language.prototype.preferenceIndicator = function() { +2683 return this.json['preferenceIndicator']; +2684 }; +2685 +2686 return Language; +2687 +2688 })(hQuery.CodedEntry); +2689 /** +2690 @namespace scoping into the hquery namespace +2691 */ +2692 +2693 var __hasProp = {}.hasOwnProperty, +2694 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; +2695 +2696 this.hQuery || (this.hQuery = {}); 2697 -2698 function MedicalEquipment(json) { -2699 this.json = json; -2700 MedicalEquipment.__super__.constructor.call(this, this.json); -2701 } -2702 -2703 /** -2704 @returns {CodedValue} -2705 */ +2698 /** +2699 This includes information about the patients current and past pregnancy status +2700 The Coded Entry code system should be SNOMED-CT +2701 @class +2702 @augments hQuery.CodedEntry +2703 @exports Pregnancy as hQuery.Pregnancy +2704 */ +2705 2706 -2707 -2708 MedicalEquipment.prototype.anatomicalStructure = function() { -2709 return hQuery.createCodedValue(this.json['anatomicalStructure']); -2710 }; -2711 -2712 /** -2713 @returns {Date} The actual or intended removal time of the device. -2714 */ -2715 -2716 -2717 MedicalEquipment.prototype.removalTime = function() { -2718 if (this.json['removalTime']) { -2719 return hQuery.dateFromUtcSeconds(this.json['removalTime']); -2720 } -2721 }; +2707 hQuery.Pregnancy = (function(_super) { +2708 +2709 __extends(Pregnancy, _super); +2710 +2711 Pregnancy.name = 'Pregnancy'; +2712 +2713 function Pregnancy(json) { +2714 this.json = json; +2715 Pregnancy.__super__.constructor.call(this, this.json); +2716 } +2717 +2718 /** +2719 @returns {String} +2720 */ +2721 2722 -2723 return MedicalEquipment; -2724 -2725 })(hQuery.CodedEntry); -2726 /** -2727 @namespace scoping into the hquery namespace -2728 */ -2729 -2730 var __hasProp = {}.hasOwnProperty, -2731 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; -2732 -2733 this.hQuery || (this.hQuery = {}); -2734 -2735 /** -2736 This class can be used to represnt a functional status for a patient. Currently, -2737 it is not a very close representation of functional status as it is represented -2738 in the HL7 CCD, HITSP C32 or Consolidated CDA. -2739 -2740 In the previously mentioned specifications, functional status may represented -2741 using either a condition or result. Having "mixed" types of entries in a section -2742 is currently not well supported in the existing Record class -2743 -2744 Additionally, there is a mismatch between the data needed to calculate Stage 2 -2745 Meaningful Use Quailty Measures and the data contained in patient summary -2746 standards. The CQMs are checking to see if a functional status represented by -2747 a result was patient supplied. Right now, results do not have a source, and -2748 even if we were to use Provider as a source, it would need to be extended -2749 to support patients. -2750 -2751 To avoid this, the patient sumamry style functional status has been "flattened" -2752 into this class. This model supports the information needed to calculate -2753 Stage 2 MU CQMs. If importers are created from C32 or CCDA, the information -2754 can be stored here, but it will be a lossy transformation. -2755 @class -2756 @augments hQuery.CodedEntry -2757 @exports FunctionalStatus as hQuery.FunctionalStatus +2723 Pregnancy.prototype.comment = function() { +2724 return this.json['comment']; +2725 }; +2726 +2727 return Pregnancy; +2728 +2729 })(hQuery.CodedEntry); +2730 /** +2731 @namespace scoping into the hquery namespace +2732 */ +2733 +2734 var __hasProp = {}.hasOwnProperty, +2735 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; +2736 +2737 this.hQuery || (this.hQuery = {}); +2738 +2739 /** +2740 +2741 The Social History Observation is used to define the patient's occupational, personal (e.g. lifestyle), +2742 social, and environmental history and health risk factors, as well as administrative data such as +2743 marital status, race, ethnicity and religious affiliation. The types of conditions +2744 described have been constrained to the SNOMED CT code system using constrained code set, 2.16.840.1.113883.3.88.12.80.60: +2745 229819007 Tobacco use and exposure +2746 256235009 Exercise +2747 160573003 Alcohol Intake +2748 364393001 Nutritional observable +2749 364703007 Employment detail +2750 425400000 Toxic exposure status +2751 363908000 Details of drug misuse behavior +2752 228272008 Health-related behavior +2753 105421008 Educational achievement +2754 +2755 note: Social History is not part of the existing green c32. +2756 @exports Socialhistory as hQuery.Socialhistory +2757 @augments hQuery.CodedEntry 2758 */ 2759 2760 -2761 hQuery.FunctionalStatus = (function(_super) { -2762 __extends(FunctionalStatus, _super); -2763 -2764 function FunctionalStatus(json) { -2765 this.json = json; -2766 FunctionalStatus.__super__.constructor.call(this, this.json); -2767 } -2768 -2769 /** -2770 Either "condition" or "result" -2771 @returns {String} -2772 */ -2773 -2774 -2775 FunctionalStatus.prototype.type = function() { -2776 return this.json["type"]; -2777 }; -2778 -2779 /** -2780 A coded value. Like a code for patient supplied. -2781 @returns {hQuery.CodedValue} -2782 */ +2761 hQuery.Socialhistory = (function(_super) { +2762 +2763 __extends(Socialhistory, _super); +2764 +2765 Socialhistory.name = 'Socialhistory'; +2766 +2767 function Socialhistory(json) { +2768 this.json = json; +2769 Socialhistory.__super__.constructor.call(this, this.json); +2770 } +2771 +2772 /** +2773 Value returns the value of the result. This will return an object. The properties of this +2774 object are dependent on the type of result. +2775 */ +2776 +2777 +2778 Socialhistory.prototype.value = function() { +2779 return this.json['value']; +2780 }; +2781 +2782 return Socialhistory; 2783 -2784 -2785 FunctionalStatus.prototype.source = function() { -2786 return hQuery.createCodedValue(this.json["source"]); -2787 }; +2784 })(hQuery.CodedEntry); +2785 /** +2786 @namespace scoping into the hquery namespace +2787 */ 2788 -2789 return FunctionalStatus; -2790 -2791 })(hQuery.CodedEntry); -2792 /** -2793 @namespace scoping into the hquery namespace -2794 */ +2789 var __hasProp = {}.hasOwnProperty, +2790 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; +2791 +2792 this.hQuery || (this.hQuery = {}); +2793 +2794 /** 2795 -2796 var _ref, -2797 __hasProp = {}.hasOwnProperty, -2798 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; -2799 -2800 this.hQuery || (this.hQuery = {}); +2796 The plan of care contains data defining prospective or intended orders, interventions, encounters, services, and procedures for the patient. +2797 +2798 @exports CareGoal as hQuery.CareGoal +2799 @augments hQuery.CodedEntry +2800 */ 2801 -2802 /** -2803 @class Supports -2804 @exports Supports as hQuery.Supports -2805 */ +2802 +2803 hQuery.CareGoal = (function(_super) { +2804 +2805 __extends(CareGoal, _super); 2806 -2807 -2808 hQuery.Supports = (function() { -2809 function Supports(json) { +2807 CareGoal.name = 'CareGoal'; +2808 +2809 function CareGoal(json) { 2810 this.json = json; -2811 } -2812 -2813 /** -2814 @returns {DateRange} -2815 */ -2816 -2817 -2818 Supports.prototype.supportDate = function() { -2819 return new hQuery.DateRange(this.json['supportDate']); -2820 }; -2821 -2822 /** -2823 @returns {Person} -2824 */ +2811 CareGoal.__super__.constructor.call(this, this.json); +2812 } +2813 +2814 return CareGoal; +2815 +2816 })(hQuery.CodedEntry); +2817 /** +2818 @namespace scoping into the hquery namespace +2819 */ +2820 +2821 var __hasProp = {}.hasOwnProperty, +2822 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; +2823 +2824 this.hQuery || (this.hQuery = {}); 2825 -2826 -2827 Supports.prototype.guardian = function() { -2828 return new hQuery.Person(this.json['guardian']); -2829 }; -2830 -2831 /** -2832 @returns {String} -2833 */ +2826 /** +2827 +2828 The Medical Equipment section contains information describing a patients implanted and external medical devices and equipment that their health status depends on, as well as any pertinent equipment or device history. +2829 +2830 The template identifier for this section is 2.16.840.1.113883.3.88.11.83.128 +2831 +2832 C83-[CT-128-1] This section shall conform to the HL7 CCD section, and shall contain a templateId element whose root attribute is 2.16.840.1.113883.10.20.1.7. +2833 C83-[CT-128-2] This section SHALL conform to the IHE Medical Devices Section, and shall contain a templateId element whose root attribute is 1.3.6.1.4.1.19376.1.5.3.1.1.5.3.5 2834 -2835 -2836 Supports.prototype.guardianSupportType = function() { -2837 return this.json['guardianSupportType']; -2838 }; +2835 @exports MedicalEquipment as hQuery.MedicalEquipment +2836 @augments hQuery.CodedEntry +2837 */ +2838 2839 -2840 /** -2841 @returns {Person} -2842 */ +2840 hQuery.MedicalEquipment = (function(_super) { +2841 +2842 __extends(MedicalEquipment, _super); 2843 -2844 -2845 Supports.prototype.contact = function() { -2846 return new hQuery.Person(this.json['contact']); -2847 }; -2848 -2849 /** -2850 @returns {String} -2851 */ -2852 -2853 -2854 Supports.prototype.contactSupportType = function() { -2855 return this.json['guardianSupportType']; -2856 }; -2857 -2858 return Supports; +2844 MedicalEquipment.name = 'MedicalEquipment'; +2845 +2846 function MedicalEquipment(json) { +2847 this.json = json; +2848 MedicalEquipment.__super__.constructor.call(this, this.json); +2849 } +2850 +2851 /** +2852 @returns {CodedValue} +2853 */ +2854 +2855 +2856 MedicalEquipment.prototype.anatomicalStructure = function() { +2857 return hQuery.createCodedValue(this.json['anatomicalStructure']); +2858 }; 2859 -2860 })(); -2861 -2862 /** -2863 @class Representation of a patient -2864 @augments hQuery.Person -2865 @exports Patient as hQuery.Patient -2866 */ -2867 -2868 -2869 hQuery.Patient = (function(_super) { -2870 __extends(Patient, _super); -2871 -2872 function Patient() { -2873 _ref = Patient.__super__.constructor.apply(this, arguments); -2874 return _ref; -2875 } -2876 -2877 /** -2878 @returns {String} containing M or F representing the gender of the patient -2879 */ +2860 /** +2861 @returns {Date} The actual or intended removal time of the device. +2862 */ +2863 +2864 +2865 MedicalEquipment.prototype.removalTime = function() { +2866 if (this.json['removalTime']) { +2867 return hQuery.dateFromUtcSeconds(this.json['removalTime']); +2868 } +2869 }; +2870 +2871 return MedicalEquipment; +2872 +2873 })(hQuery.CodedEntry); +2874 /** +2875 @namespace scoping into the hquery namespace +2876 */ +2877 +2878 var __hasProp = {}.hasOwnProperty, +2879 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; 2880 -2881 -2882 Patient.prototype.gender = function() { -2883 return this.json['gender']; -2884 }; -2885 -2886 /** -2887 @returns {Date} containing the patients birthdate -2888 */ -2889 -2890 -2891 Patient.prototype.birthtime = function() { -2892 return hQuery.dateFromUtcSeconds(this.json['birthdate']); -2893 }; -2894 -2895 /** -2896 @param (Date) date the date at which the patient age is calculated, defaults to now. -2897 @returns {number} the patient age in years -2898 */ -2899 -2900 -2901 Patient.prototype.age = function(date) { -2902 var oneDay, oneYear; -2903 -2904 if (date == null) { -2905 date = new Date(); -2906 } -2907 oneDay = 24 * 60 * 60 * 1000; -2908 oneYear = 365 * oneDay; -2909 return (date.getTime() - this.birthtime().getTime()) / oneYear; -2910 }; -2911 -2912 /** -2913 @returns {CodedValue} the domestic partnership status of the patient -2914 The following HL7 codeset is used: -2915 A Annulled -2916 D Divorced -2917 I Interlocutory -2918 L Legally separated -2919 M Married -2920 P Polygamous -2921 S Never Married -2922 T Domestic Partner -2923 W Widowed -2924 */ +2881 this.hQuery || (this.hQuery = {}); +2882 +2883 /** +2884 This class can be used to represnt a functional status for a patient. Currently, +2885 it is not a very close representation of functional status as it is represented +2886 in the HL7 CCD, HITSP C32 or Consolidated CDA. +2887 +2888 In the previously mentioned specifications, functional status may represented +2889 using either a condition or result. Having "mixed" types of entries in a section +2890 is currently not well supported in the existing Record class +2891 +2892 Additionally, there is a mismatch between the data needed to calculate Stage 2 +2893 Meaningful Use Quailty Measures and the data contained in patient summary +2894 standards. The CQMs are checking to see if a functional status represented by +2895 a result was patient supplied. Right now, results do not have a source, and +2896 even if we were to use Provider as a source, it would need to be extended +2897 to support patients. +2898 +2899 To avoid this, the patient sumamry style functional status has been "flattened" +2900 into this class. This model supports the information needed to calculate +2901 Stage 2 MU CQMs. If importers are created from C32 or CCDA, the information +2902 can be stored here, but it will be a lossy transformation. +2903 @class +2904 @augments hQuery.CodedEntry +2905 @exports FunctionalStatus as hQuery.FunctionalStatus +2906 */ +2907 +2908 +2909 hQuery.FunctionalStatus = (function(_super) { +2910 +2911 __extends(FunctionalStatus, _super); +2912 +2913 FunctionalStatus.name = 'FunctionalStatus'; +2914 +2915 function FunctionalStatus(json) { +2916 this.json = json; +2917 FunctionalStatus.__super__.constructor.call(this, this.json); +2918 } +2919 +2920 /** +2921 Either "condition" or "result" +2922 @returns {String} +2923 */ +2924 2925 -2926 -2927 Patient.prototype.maritalStatus = function() { -2928 if (this.json['maritalStatus']) { -2929 return hQuery.createCodedValue(this.json['maritalStatus']); -2930 } -2931 }; -2932 -2933 /** -2934 @returns {CodedValue} of the spiritual faith affiliation of the patient -2935 It uses the HL7 codeset. http://www.hl7.org/memonly/downloads/v3edition.cfm#V32008 -2936 */ -2937 -2938 -2939 Patient.prototype.religiousAffiliation = function() { -2940 if (this.json['religiousAffiliation']) { -2941 return hQuery.createCodedValue(this.json['religiousAffiliation']); -2942 } -2943 }; -2944 -2945 /** -2946 @returns {CodedValue} of the race of the patient -2947 CDC codes: http://phinvads.cdc.gov/vads/ViewCodeSystemConcept.action?oid=2.16.840.1.113883.6.238&code=1000-9 -2948 */ +2926 FunctionalStatus.prototype.type = function() { +2927 return this.json["type"]; +2928 }; +2929 +2930 /** +2931 A coded value. Like a code for patient supplied. +2932 @returns {hQuery.CodedValue} +2933 */ +2934 +2935 +2936 FunctionalStatus.prototype.source = function() { +2937 return hQuery.createCodedValue(this.json["source"]); +2938 }; +2939 +2940 return FunctionalStatus; +2941 +2942 })(hQuery.CodedEntry); +2943 /** +2944 @namespace scoping into the hquery namespace +2945 */ +2946 +2947 var __hasProp = {}.hasOwnProperty, +2948 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; 2949 -2950 -2951 Patient.prototype.race = function() { -2952 if (this.json['race']) { -2953 return hQuery.createCodedValue(this.json['race']); -2954 } -2955 }; +2950 this.hQuery || (this.hQuery = {}); +2951 +2952 /** +2953 @class Supports +2954 @exports Supports as hQuery.Supports +2955 */ 2956 -2957 /** -2958 @returns {CodedValue} of the ethnicity of the patient -2959 CDC codes: http://phinvads.cdc.gov/vads/ViewCodeSystemConcept.action?oid=2.16.840.1.113883.6.238&code=1000-9 -2960 */ +2957 +2958 hQuery.Supports = (function() { +2959 +2960 Supports.name = 'Supports'; 2961 -2962 -2963 Patient.prototype.ethnicity = function() { -2964 if (this.json['ethnicity']) { -2965 return hQuery.createCodedValue(this.json['ethnicity']); -2966 } -2967 }; -2968 -2969 /** -2970 @returns {CodedValue} This is the code specifying the level of confidentiality of the document. -2971 HL7 Confidentiality Code (2.16.840.1.113883.5.25) -2972 */ -2973 +2962 function Supports(json) { +2963 this.json = json; +2964 } +2965 +2966 /** +2967 @returns {DateRange} +2968 */ +2969 +2970 +2971 Supports.prototype.supportDate = function() { +2972 return new hQuery.DateRange(this.json['supportDate']); +2973 }; 2974 -2975 Patient.prototype.confidentiality = function() { -2976 if (this.json['confidentiality']) { -2977 return hQuery.createCodedValue(this.json['confidentiality']); -2978 } -2979 }; -2980 -2981 /** -2982 @returns {Address} of the location where the patient was born -2983 */ -2984 -2985 -2986 Patient.prototype.birthPlace = function() { -2987 return new hQuery.Address(this.json['birthPlace']); -2988 }; -2989 -2990 /** -2991 @returns {Supports} information regarding key support contacts relative to healthcare decisions, including next of kin -2992 */ -2993 -2994 -2995 Patient.prototype.supports = function() { -2996 return new hQuery.Supports(this.json['supports']); -2997 }; -2998 -2999 /** -3000 @returns {Organization} -3001 */ -3002 -3003 -3004 Patient.prototype.custodian = function() { -3005 return new hQuery.Organization(this.json['custodian']); -3006 }; -3007 -3008 /** -3009 @returns {Provider} the providers associated with the patient -3010 */ -3011 +2975 /** +2976 @returns {Person} +2977 */ +2978 +2979 +2980 Supports.prototype.guardian = function() { +2981 return new hQuery.Person(this.json['guardian']); +2982 }; +2983 +2984 /** +2985 @returns {String} +2986 */ +2987 +2988 +2989 Supports.prototype.guardianSupportType = function() { +2990 return this.json['guardianSupportType']; +2991 }; +2992 +2993 /** +2994 @returns {Person} +2995 */ +2996 +2997 +2998 Supports.prototype.contact = function() { +2999 return new hQuery.Person(this.json['contact']); +3000 }; +3001 +3002 /** +3003 @returns {String} +3004 */ +3005 +3006 +3007 Supports.prototype.contactSupportType = function() { +3008 return this.json['guardianSupportType']; +3009 }; +3010 +3011 return Supports; 3012 -3013 Patient.prototype.provider = function() { -3014 return new hQuery.Provider(this.json['provider']); -3015 }; -3016 -3017 /** -3018 @returns {hQuery.CodedEntryList} A list of {@link hQuery.LanguagesSpoken} objects -3019 Code from http://www.ietf.org/rfc/rfc4646.txt representing the name of the human language -3020 */ +3013 })(); +3014 +3015 /** +3016 @class Representation of a patient +3017 @augments hQuery.Person +3018 @exports Patient as hQuery.Patient +3019 */ +3020 3021 -3022 -3023 Patient.prototype.languages = function() { -3024 var language, list, _i, _len, _ref1; +3022 hQuery.Patient = (function(_super) { +3023 +3024 __extends(Patient, _super); 3025 -3026 list = new hQuery.CodedEntryList; -3027 if (this.json['languages']) { -3028 _ref1 = this.json['languages']; -3029 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -3030 language = _ref1[_i]; -3031 list.push(new hQuery.Language(language)); -3032 } -3033 } -3034 return list; -3035 }; +3026 Patient.name = 'Patient'; +3027 +3028 function Patient() { +3029 return Patient.__super__.constructor.apply(this, arguments); +3030 } +3031 +3032 /** +3033 @returns {String} containing M or F representing the gender of the patient +3034 */ +3035 3036 -3037 /** -3038 @returns {Boolean} returns true if the patient has died -3039 */ +3037 Patient.prototype.gender = function() { +3038 return this.json['gender']; +3039 }; 3040 -3041 -3042 Patient.prototype.expired = function() { -3043 return this.json['expired']; -3044 }; +3041 /** +3042 @returns {Date} containing the patients birthdate +3043 */ +3044 3045 -3046 /** -3047 @returns {Boolean} returns true if the patient participated in a clinical trial -3048 */ -3049 -3050 -3051 Patient.prototype.clinicalTrialParticipant = function() { -3052 return this.json['clinicalTrialParticipant']; -3053 }; -3054 -3055 /** -3056 @returns {hQuery.CodedEntryList} A list of {@link hQuery.Encounter} objects -3057 */ -3058 -3059 -3060 Patient.prototype.encounters = function() { -3061 var encounter, list, _i, _len, _ref1; -3062 -3063 list = new hQuery.CodedEntryList; -3064 if (this.json['encounters']) { -3065 _ref1 = this.json['encounters']; -3066 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -3067 encounter = _ref1[_i]; -3068 list.pushIfUsable(new hQuery.Encounter(encounter)); -3069 } -3070 } -3071 return list; -3072 }; -3073 -3074 /** -3075 @returns {hQuery.CodedEntryList} A list of {@link Medication} objects -3076 */ -3077 -3078 -3079 Patient.prototype.medications = function() { -3080 var list, medication, _i, _len, _ref1; +3046 Patient.prototype.birthtime = function() { +3047 if (this.json['birthdate']) { +3048 return hQuery.dateFromUtcSeconds(this.json['birthdate']); +3049 } +3050 }; +3051 +3052 /** +3053 @param (Date) date the date at which the patient age is calculated, defaults to now. +3054 @returns {number} the patient age in years +3055 */ +3056 +3057 +3058 Patient.prototype.age = function(date) { +3059 var oneDay, oneYear; +3060 if (date == null) { +3061 date = new Date(); +3062 } +3063 oneDay = 24 * 60 * 60 * 1000; +3064 oneYear = 365.25 * oneDay; +3065 return (date.getTime() - this.birthtime().getTime()) / oneYear; +3066 }; +3067 +3068 /** +3069 @returns {CodedValue} the domestic partnership status of the patient +3070 The following HL7 codeset is used: +3071 A Annulled +3072 D Divorced +3073 I Interlocutory +3074 L Legally separated +3075 M Married +3076 P Polygamous +3077 S Never Married +3078 T Domestic Partner +3079 W Widowed +3080 */ 3081 -3082 list = new hQuery.CodedEntryList; -3083 if (this.json['medications']) { -3084 _ref1 = this.json['medications']; -3085 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -3086 medication = _ref1[_i]; -3087 list.pushIfUsable(new hQuery.Medication(medication)); -3088 } -3089 } -3090 return list; -3091 }; -3092 -3093 /** -3094 @returns {hQuery.CodedEntryList} A list of {@link Condition} objects -3095 */ -3096 -3097 -3098 Patient.prototype.conditions = function() { -3099 var condition, list, _i, _len, _ref1; +3082 +3083 Patient.prototype.maritalStatus = function() { +3084 if (this.json['maritalStatus']) { +3085 return hQuery.createCodedValue(this.json['maritalStatus']); +3086 } +3087 }; +3088 +3089 /** +3090 @returns {CodedValue} of the spiritual faith affiliation of the patient +3091 It uses the HL7 codeset. http://www.hl7.org/memonly/downloads/v3edition.cfm#V32008 +3092 */ +3093 +3094 +3095 Patient.prototype.religiousAffiliation = function() { +3096 if (this.json['religiousAffiliation']) { +3097 return hQuery.createCodedValue(this.json['religiousAffiliation']); +3098 } +3099 }; 3100 -3101 list = new hQuery.CodedEntryList; -3102 if (this.json['conditions']) { -3103 _ref1 = this.json['conditions']; -3104 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -3105 condition = _ref1[_i]; -3106 list.pushIfUsable(new hQuery.Condition(condition)); -3107 } -3108 } -3109 return list; -3110 }; -3111 -3112 /** -3113 @returns {hQuery.CodedEntryList} A list of {@link Procedure} objects -3114 */ -3115 -3116 -3117 Patient.prototype.procedures = function() { -3118 var list, procedure, _i, _len, _ref1; -3119 -3120 list = new hQuery.CodedEntryList; -3121 if (this.json['procedures']) { -3122 _ref1 = this.json['procedures']; -3123 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -3124 procedure = _ref1[_i]; -3125 list.pushIfUsable(new hQuery.Procedure(procedure)); -3126 } -3127 } -3128 return list; -3129 }; +3101 /** +3102 @returns {CodedValue} of the race of the patient +3103 CDC codes: http://phinvads.cdc.gov/vads/ViewCodeSystemConcept.action?oid=2.16.840.1.113883.6.238&code=1000-9 +3104 */ +3105 +3106 +3107 Patient.prototype.race = function() { +3108 if (this.json['race']) { +3109 return hQuery.createCodedValue(this.json['race']); +3110 } +3111 }; +3112 +3113 /** +3114 @returns {CodedValue} of the ethnicity of the patient +3115 CDC codes: http://phinvads.cdc.gov/vads/ViewCodeSystemConcept.action?oid=2.16.840.1.113883.6.238&code=1000-9 +3116 */ +3117 +3118 +3119 Patient.prototype.ethnicity = function() { +3120 if (this.json['ethnicity']) { +3121 return hQuery.createCodedValue(this.json['ethnicity']); +3122 } +3123 }; +3124 +3125 /** +3126 @returns {CodedValue} This is the code specifying the level of confidentiality of the document. +3127 HL7 Confidentiality Code (2.16.840.1.113883.5.25) +3128 */ +3129 3130 -3131 /** -3132 @returns {hQuery.CodedEntryList} A list of {@link Result} objects -3133 */ -3134 -3135 -3136 Patient.prototype.results = function() { -3137 var list, result, _i, _len, _ref1; -3138 -3139 list = new hQuery.CodedEntryList; -3140 if (this.json['results']) { -3141 _ref1 = this.json['results']; -3142 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -3143 result = _ref1[_i]; -3144 list.pushIfUsable(new hQuery.Result(result)); -3145 } -3146 } -3147 return list; -3148 }; +3131 Patient.prototype.confidentiality = function() { +3132 if (this.json['confidentiality']) { +3133 return hQuery.createCodedValue(this.json['confidentiality']); +3134 } +3135 }; +3136 +3137 /** +3138 @returns {Address} of the location where the patient was born +3139 */ +3140 +3141 +3142 Patient.prototype.birthPlace = function() { +3143 return new hQuery.Address(this.json['birthPlace']); +3144 }; +3145 +3146 /** +3147 @returns {Supports} information regarding key support contacts relative to healthcare decisions, including next of kin +3148 */ 3149 -3150 /** -3151 @returns {hQuery.CodedEntryList} A list of {@link Result} objects -3152 */ -3153 +3150 +3151 Patient.prototype.supports = function() { +3152 return new hQuery.Supports(this.json['supports']); +3153 }; 3154 -3155 Patient.prototype.vitalSigns = function() { -3156 var list, vital, _i, _len, _ref1; -3157 -3158 list = new hQuery.CodedEntryList; -3159 if (this.json['vital_signs']) { -3160 _ref1 = this.json['vital_signs']; -3161 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -3162 vital = _ref1[_i]; -3163 list.pushIfUsable(new hQuery.Result(vital)); -3164 } -3165 } -3166 return list; -3167 }; +3155 /** +3156 @returns {Organization} +3157 */ +3158 +3159 +3160 Patient.prototype.custodian = function() { +3161 return new hQuery.Organization(this.json['custodian']); +3162 }; +3163 +3164 /** +3165 @returns {Provider} the providers associated with the patient +3166 */ +3167 3168 -3169 /** -3170 @returns {hQuery.CodedEntryList} A list of {@link Immunization} objects -3171 */ +3169 Patient.prototype.provider = function() { +3170 return new hQuery.Provider(this.json['provider']); +3171 }; 3172 -3173 -3174 Patient.prototype.immunizations = function() { -3175 var immunization, list, _i, _len, _ref1; -3176 -3177 list = new hQuery.CodedEntryList; -3178 if (this.json['immunizations']) { -3179 _ref1 = this.json['immunizations']; -3180 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -3181 immunization = _ref1[_i]; -3182 list.pushIfUsable(new hQuery.Immunization(immunization)); -3183 } -3184 } -3185 return list; -3186 }; -3187 -3188 /** -3189 @returns {hQuery.CodedEntryList} A list of {@link Allergy} objects -3190 */ +3173 /** +3174 @returns {hQuery.CodedEntryList} A list of {@link hQuery.LanguagesSpoken} objects +3175 Code from http://www.ietf.org/rfc/rfc4646.txt representing the name of the human language +3176 */ +3177 +3178 +3179 Patient.prototype.languages = function() { +3180 var language, list, _i, _len, _ref; +3181 list = new hQuery.CodedEntryList; +3182 if (this.json['languages']) { +3183 _ref = this.json['languages']; +3184 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +3185 language = _ref[_i]; +3186 list.push(new hQuery.Language(language)); +3187 } +3188 } +3189 return list; +3190 }; 3191 -3192 -3193 Patient.prototype.allergies = function() { -3194 var allergy, list, _i, _len, _ref1; +3192 /** +3193 @returns {Boolean} returns true if the patient has died +3194 */ 3195 -3196 list = new hQuery.CodedEntryList; -3197 if (this.json['allergies']) { -3198 _ref1 = this.json['allergies']; -3199 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -3200 allergy = _ref1[_i]; -3201 list.pushIfUsable(new hQuery.Allergy(allergy)); -3202 } -3203 } -3204 return list; -3205 }; -3206 -3207 /** -3208 @returns {hQuery.CodedEntryList} A list of {@link Pregnancy} objects -3209 */ -3210 -3211 -3212 Patient.prototype.pregnancies = function() { -3213 var list, pregnancy, _i, _len, _ref1; +3196 +3197 Patient.prototype.expired = function() { +3198 return this.json['expired']; +3199 }; +3200 +3201 /** +3202 @returns {Boolean} returns true if the patient participated in a clinical trial +3203 */ +3204 +3205 +3206 Patient.prototype.clinicalTrialParticipant = function() { +3207 return this.json['clinicalTrialParticipant']; +3208 }; +3209 +3210 /** +3211 @returns {hQuery.CodedEntryList} A list of {@link hQuery.Encounter} objects +3212 */ +3213 3214 -3215 list = new hQuery.CodedEntryList; -3216 if (this.json['pregnancies']) { -3217 _ref1 = this.json['pregnancies']; -3218 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -3219 pregnancy = _ref1[_i]; -3220 list.pushIfUsable(new hQuery.Pregnancy(pregnancy)); -3221 } -3222 } -3223 return list; -3224 }; -3225 -3226 /** -3227 @returns {hQuery.CodedEntryList} A list of {@link Socialhistory} objects -3228 */ -3229 -3230 -3231 Patient.prototype.socialHistories = function() { -3232 var list, socialhistory, _i, _len, _ref1; -3233 -3234 list = new hQuery.CodedEntryList; -3235 if (this.json['socialhistories']) { -3236 _ref1 = this.json['socialhistories']; -3237 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -3238 socialhistory = _ref1[_i]; -3239 list.pushIfUsable(new hQuery.Socialhistory(socialhistory)); -3240 } -3241 } -3242 return list; -3243 }; -3244 -3245 /** -3246 @returns {hQuery.CodedEntryList} A list of {@link CareGoal} objects -3247 */ -3248 +3215 Patient.prototype.encounters = function() { +3216 var encounter, list, _i, _len, _ref; +3217 list = new hQuery.CodedEntryList; +3218 if (this.json['encounters']) { +3219 _ref = this.json['encounters']; +3220 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +3221 encounter = _ref[_i]; +3222 list.pushIfUsable(new hQuery.Encounter(encounter)); +3223 } +3224 } +3225 return list; +3226 }; +3227 +3228 /** +3229 @returns {hQuery.CodedEntryList} A list of {@link Medication} objects +3230 */ +3231 +3232 +3233 Patient.prototype.medications = function() { +3234 var list, medication, _i, _len, _ref; +3235 list = new hQuery.CodedEntryList; +3236 if (this.json['medications']) { +3237 _ref = this.json['medications']; +3238 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +3239 medication = _ref[_i]; +3240 list.pushIfUsable(new hQuery.Medication(medication)); +3241 } +3242 } +3243 return list; +3244 }; +3245 +3246 /** +3247 @returns {hQuery.CodedEntryList} A list of {@link Condition} objects +3248 */ 3249 -3250 Patient.prototype.careGoals = function() { -3251 var caregoal, list, _i, _len, _ref1; -3252 +3250 +3251 Patient.prototype.conditions = function() { +3252 var condition, list, _i, _len, _ref; 3253 list = new hQuery.CodedEntryList; -3254 if (this.json['care_goals']) { -3255 _ref1 = this.json['care_goals']; -3256 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -3257 caregoal = _ref1[_i]; -3258 list.pushIfUsable(new hQuery.CareGoal(caregoal)); +3254 if (this.json['conditions']) { +3255 _ref = this.json['conditions']; +3256 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +3257 condition = _ref[_i]; +3258 list.pushIfUsable(new hQuery.Condition(condition)); 3259 } 3260 } 3261 return list; 3262 }; 3263 3264 /** -3265 @returns {hQuery.CodedEntryList} A list of {@link MedicalEquipment} objects +3265 @returns {hQuery.CodedEntryList} A list of {@link Procedure} objects 3266 */ 3267 3268 -3269 Patient.prototype.medicalEquipment = function() { -3270 var equipment, list, _i, _len, _ref1; -3271 -3272 list = new hQuery.CodedEntryList; -3273 if (this.json['medical_equipment']) { -3274 _ref1 = this.json['medical_equipment']; -3275 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -3276 equipment = _ref1[_i]; -3277 list.pushIfUsable(new hQuery.MedicalEquipment(equipment)); -3278 } -3279 } -3280 return list; -3281 }; -3282 -3283 /** -3284 @returns {hQuery.CodedEntryList} A list of {@link FunctionalStatus} objects -3285 */ +3269 Patient.prototype.procedures = function() { +3270 var list, procedure, _i, _len, _ref; +3271 list = new hQuery.CodedEntryList; +3272 if (this.json['procedures']) { +3273 _ref = this.json['procedures']; +3274 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +3275 procedure = _ref[_i]; +3276 list.pushIfUsable(new hQuery.Procedure(procedure)); +3277 } +3278 } +3279 return list; +3280 }; +3281 +3282 /** +3283 @returns {hQuery.CodedEntryList} A list of {@link Result} objects +3284 */ +3285 3286 -3287 -3288 Patient.prototype.functionalStatuses = function() { -3289 var fs, list, _i, _len, _ref1; -3290 -3291 list = new hQuery.CodedEntryList; -3292 if (this.json['functional_statuses']) { -3293 _ref1 = this.json['functional_statuses']; -3294 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { -3295 fs = _ref1[_i]; -3296 list.pushIfUsable(new hQuery.FunctionalStatus(fs)); -3297 } -3298 } -3299 return list; -3300 }; -3301 -3302 return Patient; +3287 Patient.prototype.results = function() { +3288 var list, result, _i, _len, _ref; +3289 list = new hQuery.CodedEntryList; +3290 if (this.json['results']) { +3291 _ref = this.json['results']; +3292 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +3293 result = _ref[_i]; +3294 list.pushIfUsable(new hQuery.Result(result)); +3295 } +3296 } +3297 return list; +3298 }; +3299 +3300 /** +3301 @returns {hQuery.CodedEntryList} A list of {@link Result} objects +3302 */ 3303 -3304 })(hQuery.Person); -3305 \ No newline at end of file +3304 +3305 Patient.prototype.vitalSigns = function() { +3306 var list, vital, _i, _len, _ref; +3307 list = new hQuery.CodedEntryList; +3308 if (this.json['vital_signs']) { +3309 _ref = this.json['vital_signs']; +3310 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +3311 vital = _ref[_i]; +3312 list.pushIfUsable(new hQuery.Result(vital)); +3313 } +3314 } +3315 return list; +3316 }; +3317 +3318 /** +3319 @returns {hQuery.CodedEntryList} A list of {@link Immunization} objects +3320 */ +3321 +3322 +3323 Patient.prototype.immunizations = function() { +3324 var immunization, list, _i, _len, _ref; +3325 list = new hQuery.CodedEntryList; +3326 if (this.json['immunizations']) { +3327 _ref = this.json['immunizations']; +3328 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +3329 immunization = _ref[_i]; +3330 list.pushIfUsable(new hQuery.Immunization(immunization)); +3331 } +3332 } +3333 return list; +3334 }; +3335 +3336 /** +3337 @returns {hQuery.CodedEntryList} A list of {@link Allergy} objects +3338 */ +3339 +3340 +3341 Patient.prototype.allergies = function() { +3342 var allergy, list, _i, _len, _ref; +3343 list = new hQuery.CodedEntryList; +3344 if (this.json['allergies']) { +3345 _ref = this.json['allergies']; +3346 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +3347 allergy = _ref[_i]; +3348 list.pushIfUsable(new hQuery.Allergy(allergy)); +3349 } +3350 } +3351 return list; +3352 }; +3353 +3354 /** +3355 @returns {hQuery.CodedEntryList} A list of {@link Pregnancy} objects +3356 */ +3357 +3358 +3359 Patient.prototype.pregnancies = function() { +3360 var list, pregnancy, _i, _len, _ref; +3361 list = new hQuery.CodedEntryList; +3362 if (this.json['pregnancies']) { +3363 _ref = this.json['pregnancies']; +3364 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +3365 pregnancy = _ref[_i]; +3366 list.pushIfUsable(new hQuery.Pregnancy(pregnancy)); +3367 } +3368 } +3369 return list; +3370 }; +3371 +3372 /** +3373 @returns {hQuery.CodedEntryList} A list of {@link Socialhistory} objects +3374 */ +3375 +3376 +3377 Patient.prototype.socialHistories = function() { +3378 var list, socialhistory, _i, _len, _ref; +3379 list = new hQuery.CodedEntryList; +3380 if (this.json['socialhistories']) { +3381 _ref = this.json['socialhistories']; +3382 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +3383 socialhistory = _ref[_i]; +3384 list.pushIfUsable(new hQuery.Socialhistory(socialhistory)); +3385 } +3386 } +3387 return list; +3388 }; +3389 +3390 /** +3391 @returns {hQuery.CodedEntryList} A list of {@link CareGoal} objects +3392 */ +3393 +3394 +3395 Patient.prototype.careGoals = function() { +3396 var caregoal, list, _i, _len, _ref; +3397 list = new hQuery.CodedEntryList; +3398 if (this.json['care_goals']) { +3399 _ref = this.json['care_goals']; +3400 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +3401 caregoal = _ref[_i]; +3402 list.pushIfUsable(new hQuery.CareGoal(caregoal)); +3403 } +3404 } +3405 return list; +3406 }; +3407 +3408 /** +3409 @returns {hQuery.CodedEntryList} A list of {@link MedicalEquipment} objects +3410 */ +3411 +3412 +3413 Patient.prototype.medicalEquipment = function() { +3414 var equipment, list, _i, _len, _ref; +3415 list = new hQuery.CodedEntryList; +3416 if (this.json['medical_equipment']) { +3417 _ref = this.json['medical_equipment']; +3418 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +3419 equipment = _ref[_i]; +3420 list.pushIfUsable(new hQuery.MedicalEquipment(equipment)); +3421 } +3422 } +3423 return list; +3424 }; +3425 +3426 /** +3427 @returns {hQuery.CodedEntryList} A list of {@link FunctionalStatus} objects +3428 */ +3429 +3430 +3431 Patient.prototype.functionalStatuses = function() { +3432 var fs, list, _i, _len, _ref; +3433 list = new hQuery.CodedEntryList; +3434 if (this.json['functional_statuses']) { +3435 _ref = this.json['functional_statuses']; +3436 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +3437 fs = _ref[_i]; +3438 list.pushIfUsable(new hQuery.FunctionalStatus(fs)); +3439 } +3440 } +3441 return list; +3442 }; +3443 +3444 return Patient; +3445 +3446 })(hQuery.Person); +3447 \ No newline at end of file From fff6217991a5d3dd5eda790a5c0b5a85052e7191 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Wed, 10 Sep 2014 09:58:07 -0700 Subject: [PATCH 070/117] Bumped rails to 3.2.13 for security reasons --- Gemfile | 2 +- Gemfile.lock | 158 +++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 116 insertions(+), 44 deletions(-) diff --git a/Gemfile b/Gemfile index f616127..1c64ec0 100755 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source 'https://rubygems.org' -gem 'rails', '=3.2.7' +gem 'rails', '=3.2.13' # Gems used only for assets and not required # in production environments by default. group :assets do diff --git a/Gemfile.lock b/Gemfile.lock index fab6a41..4d34b3c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,35 +8,35 @@ GIT GEM remote: https://rubygems.org/ specs: - actionmailer (3.2.7) - actionpack (= 3.2.7) - mail (~> 2.4.4) - actionpack (3.2.7) - activemodel (= 3.2.7) - activesupport (= 3.2.7) + actionmailer (3.2.13) + actionpack (= 3.2.13) + mail (~> 2.5.3) + actionpack (3.2.13) + activemodel (= 3.2.13) + activesupport (= 3.2.13) builder (~> 3.0.0) erubis (~> 2.7.0) journey (~> 1.0.4) - rack (~> 1.4.0) + rack (~> 1.4.5) rack-cache (~> 1.2) rack-test (~> 0.6.1) - sprockets (~> 2.1.3) - activemodel (3.2.7) - activesupport (= 3.2.7) + sprockets (~> 2.2.1) + activemodel (3.2.13) + activesupport (= 3.2.13) builder (~> 3.0.0) - activerecord (3.2.7) - activemodel (= 3.2.7) - activesupport (= 3.2.7) + activerecord (3.2.13) + activemodel (= 3.2.13) + activesupport (= 3.2.13) arel (~> 3.0.2) tzinfo (~> 0.3.29) - activeresource (3.2.7) - activemodel (= 3.2.7) - activesupport (= 3.2.7) - activesupport (3.2.7) - i18n (~> 0.6) + activeresource (3.2.13) + activemodel (= 3.2.13) + activesupport (= 3.2.13) + activesupport (3.2.13) + i18n (= 0.6.1) multi_json (~> 1.0) ansi (1.4.3) - arel (3.0.2) + arel (3.0.3) bcrypt-ruby (3.1.1) builder (3.0.4) cancan (1.6.10) @@ -77,7 +77,7 @@ GEM hashie (2.0.5) headless (1.0.1) hike (1.2.3) - i18n (0.6.4) + i18n (0.6.1) jasmine (1.3.2) jasmine-core (~> 1.3.1) rack (~> 1.0) @@ -88,16 +88,15 @@ GEM jquery-rails (1.0.19) railties (~> 3.0) thor (~> 0.14) - json (1.8.0) + json (1.8.1) kramdown (1.1.0) libv8 (3.11.8.17) - mail (2.4.4) - i18n (>= 0.4.0) + mail (2.5.4) mime-types (~> 1.16) treetop (~> 1.4.8) metaclass (0.0.1) method_source (0.8.1) - mime-types (1.23) + mime-types (1.25.1) minitest (4.7.5) mocha (0.14.0) metaclass (~> 0.0.1) @@ -112,11 +111,11 @@ GEM rails (>= 3.2.0) railties (>= 3.2.0) moped (1.5.0) - multi_json (1.7.7) + multi_json (1.10.1) multipart-post (1.2.0) origin (1.1.0) orm_adapter (0.4.0) - polyglot (0.3.3) + polyglot (0.3.5) pry (0.9.12.2) coderay (~> 1.0.5) method_source (~> 0.8) @@ -124,26 +123,26 @@ GEM rack (1.4.5) rack-cache (1.2) rack (>= 0.4) - rack-ssl (1.3.3) + rack-ssl (1.3.4) rack rack-test (0.6.2) rack (>= 1.0) - rails (3.2.7) - actionmailer (= 3.2.7) - actionpack (= 3.2.7) - activerecord (= 3.2.7) - activeresource (= 3.2.7) - activesupport (= 3.2.7) + rails (3.2.13) + actionmailer (= 3.2.13) + actionpack (= 3.2.13) + activerecord (= 3.2.13) + activeresource (= 3.2.13) + activesupport (= 3.2.13) bundler (~> 1.0) - railties (= 3.2.7) - railties (3.2.7) - actionpack (= 3.2.7) - activesupport (= 3.2.7) + railties (= 3.2.13) + railties (3.2.13) + actionpack (= 3.2.13) + activesupport (= 3.2.13) rack-ssl (~> 1.3.2) rake (>= 0.8.7) rdoc (~> 3.4) thor (>= 0.14.6, < 2.0) - rake (10.1.0) + rake (10.3.2) rdoc (3.12.2) json (~> 1.4) ref (1.0.5) @@ -170,21 +169,94 @@ GEM actionpack (~> 3.0) activemodel (~> 3.0) slop (3.4.5) - sprockets (2.1.3) + sprockets (2.2.2) hike (~> 1.2) + multi_json (~> 1.0) rack (~> 1.0) tilt (~> 1.1, != 1.3.0) therubyracer (0.11.4) libv8 (~> 3.11.8.12) ref - thor (0.18.1) + thor (0.19.1) tilt (1.4.1) - treetop (1.4.14) + treetop (1.4.15) + polyglot + polyglot + polyglot + polyglot + polyglot + polyglot + polyglot + polyglot + polyglot polyglot + polyglot + polyglot + polyglot + polyglot + polyglot + polyglot + polyglot + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) + polyglot (>= 0.3.1) polyglot (>= 0.3.1) turn (0.9.6) ansi - tzinfo (0.3.37) + tzinfo (0.3.41) uglifier (2.1.1) execjs (>= 0.3.0) multi_json (~> 1.0, >= 1.0.2) @@ -219,7 +291,7 @@ DEPENDENCIES mongoid_rails_migrations multipart-post pry - rails (= 3.2.7) + rails (= 3.2.13) sass-rails simple_form sprockets From a1a5ee164d9cb1c84d0667be1c9d125a5cf4f391 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Wed, 17 Sep 2014 12:07:50 -0700 Subject: [PATCH 071/117] Use patientapi that tests for undefined birthtime --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 4d34b3c..c2deca9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/scoophealth/patientapi.git - revision: 3a044aaa3fa20091e848a74904ece4e39572bb3a + revision: 2379718fd5c4a813443f12a23331779f7557f7cd branch: master specs: hquery-patient-api (1.0.5) From 4b10956776e082bfd7a312fbceb1f4783543e03b Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Wed, 29 Oct 2014 12:31:13 -0700 Subject: [PATCH 072/117] Document adding non-administrative users --- README.md | 13 ++++++++++++- runme.sh | 14 +++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2e95936..1c07f17 100755 --- a/README.md +++ b/README.md @@ -275,7 +275,7 @@ Run the following in a different terminal: In a browser open the URL: https://localhost:3000/queries/ -###8. Adding a User Account +###8. Adding an Administrative User Account When the application opens, you should be presented with a login page. You should see a sign up Link, click it. @@ -287,6 +287,17 @@ In the root of the query-composer project run the command: where <USERNAME> is replaced with the username for the user you just created. +###9. Adding a Non-administrative User Account + +When the application opens, the user will be presented with a login page. +They will see a sign up Link which they should click. +They then need to fill out the form to create their user account. +Next you need to approve the user +In the root of the query-composer project run the command: + + bundle exec rake hquery:users:approve USER_ID= + +where <USERNAME> is replaced with the username for the user you just created. License ------- diff --git a/runme.sh b/runme.sh index 4ab862e..d5da33d 100755 --- a/runme.sh +++ b/runme.sh @@ -24,7 +24,7 @@ bundle exec script/delayed_job stop # #In a browser open the URL: https://localhost:3000/queries/ # -# Adding a User Account (one time operation) +# Adding an Administrative User Account (one time operation) # # When the web application opens, you should be presented with a login page. # You should see a sign up Link, click it. @@ -35,3 +35,15 @@ bundle exec script/delayed_job stop # bundle exec rake hquery:users:grant_admin USER_ID= # # where is replaced with the username for the user you just created. +# +# Adding a non-administrative user account +# When the web application opens, users will be presented with a login page. +# They will see a sign up Link which they click. +# The user then needs to fill out the form. +# Next you need to approve this new user +# In the root of the query-composer project run the command: +## +# bundle exec rake hquery:users:approve USER_ID= +# +# where is replaced with the username for the user created. +# From 4df5609e5454a017146dd0edc5533832df070291 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Wed, 29 Oct 2014 12:39:48 -0700 Subject: [PATCH 073/117] Cosmetic fix to README --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1c07f17..df73b8e 100755 --- a/README.md +++ b/README.md @@ -280,7 +280,7 @@ Run the following in a different terminal: When the application opens, you should be presented with a login page. You should see a sign up Link, click it. Fill out the form to create a user. -Next you need to approve the user and set the user as an admin +Next you need to approve the user and set the user as an admin. In the root of the query-composer project run the command: bundle exec rake hquery:users:grant_admin USER_ID= @@ -292,12 +292,12 @@ where <USERNAME> is replaced with the username for the user you just creat When the application opens, the user will be presented with a login page. They will see a sign up Link which they should click. They then need to fill out the form to create their user account. -Next you need to approve the user +Next you need to approve the user. In the root of the query-composer project run the command: bundle exec rake hquery:users:approve USER_ID= -where <USERNAME> is replaced with the username for the user you just created. +where <USERNAME> is replaced with the username for the user account that is being approved. License ------- From b513abca70b4c64d5b394eeaf4850f0c07474e9d Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Mon, 24 Nov 2014 10:46:24 -0800 Subject: [PATCH 074/117] Guard against result.endpoint being nil --- app/views/queries/_execution_results.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/queries/_execution_results.html.erb b/app/views/queries/_execution_results.html.erb index 1d5bd20..e3f9dd5 100755 --- a/app/views/queries/_execution_results.html.erb +++ b/app/views/queries/_execution_results.html.erb @@ -13,7 +13,7 @@ execution.results.each do |result| %> - <%= result.endpoint.base_url %> + <%= result.endpoint && result.endpoint.base_url %> <%= result.status %><%= result.error_msg if result.status == Result::FAILED %> <%= result.result_url %> From 651b615e6fe2e17265b09b91cf5480fd2f060d33 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Tue, 3 Feb 2015 14:26:28 -0800 Subject: [PATCH 075/117] Added UML diagrams generated by railroady --- doc/controllers.png | Bin 0 -> 344689 bytes doc/controllers_without_engines.png | Bin 0 -> 168523 bytes doc/full_models.png | Bin 0 -> 196070 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 doc/controllers.png create mode 100644 doc/controllers_without_engines.png create mode 100644 doc/full_models.png diff --git a/doc/controllers.png b/doc/controllers.png new file mode 100644 index 0000000000000000000000000000000000000000..005e69b88e109c64ff30ee8733d6c29e77e28001 GIT binary patch literal 344689 zcmb@u2{cyi`aixELK7J?Bvg1P5mJOiM3R}5k|-oY$dI8ji&CZ}LNbNO5SfypXh0-n zRwNlJlJWo9z30?9-}U`ZYyCRwthWr$v!8w6_jP@yYX==Zq`I1clYt(G|M6{G{kXyQN2g^xrbW+nmH0h=EK}+_xy;SYEkj0% zNq@)k<;!DYW0Rb}yn9$!xIaPO^KNQt>X^~rOQ0n4`7+u$p4hvWY7MuH&mGwd{og(| z5Jb8jgNB9%2M33us;X+r-k>!1Qx+C{va(#-+S+PrYCe}PQSHCBA#~UIPj^j<&W(hr z{&`6~{k?WhL(hMGAL{Gxzbt!U>_l}S6CDG?743B&Im3jO;`Tn8V#MG3^ZE4$XOL_hb zzOW5@f@xN=_11*2<6Fz`AG(tL%Vjvsvzad*RM0? zTeoKH&STPE?L5)D_uwrF8qe7uPn(ie6Eib2|MQ*e88RNqd>d`w@&5h$%Brem6-$e< zS3^THMYx$-Peh9yukC$$rLVWwXOG8pn(UfC?--s}@BP5Qz<|wv)%s5{EUc`2d-m{HT3T|*UzCZvb0;w;XUSl;sGvXvyXqnK zUXkNs-e~)y6U9v&Xlw6x2JBZX&!9-V&E zpHs0|70R`9;$!sjs=B%rxXsvUt|AM!V`B~GcqE@(827(v8ucUdMfUh^_*c;#1_n3y~;DO!`Bo^F>i z{{FpDWL)aLfHf(>JA*sAX}-M6+Gk|MfvuK0CiM4;S#?~8o@bd9HKywd&QEvRaY&zy z+3gsqv2WkLzSJ??(%@_Ivvlt6?vFj^q`N)F_egElyHoBt*FXR3yV`*R;U?cdViUQ} zOz=gC8Yk5{*{Pm8w{7=@v8z9RIDL3>VeQnHHnD;?#pj0}n%CiA+bgDc;vk!U8+`HD zzVCAV>-6ENBkyb;OW&4rlQ{R`@ukipyG&VzKU-1TjiqN-|M>W|pFQ5Z`}|j>k16Um z=UeHzy1DV;Mto_@F}%PX+1S`f5TYi9tNi@@@}_YRl0E09M}nseXsD@s$GV;vm0v8b zs-l}13AZ+{3)8o%(2AFP`q1ndxzdsGMcFufdrzI(lxC;YMJ6K&@Tpl}rVIwwTo30C@=H%owDsf65 zjrrPHv`<50O~P8@eV)b2+3Bw#E7ooxi2Q;AoY=c9QU(zP4{R-tT{v=t z6C3WK>*UGDB_$^t@9wpCc2-eWXYgg5nQA+ZUAW4~$Y`UuIMbRnYqm>D`i6#v>f8$B zk)UMsU zpkQ?8X^Y6I@0mjTG@G+bcIKaL*O~q3S%q z>iAqCI5OH5UY=BnuI}!^F)(=oTfgAR?>&bYbA+Zt4mX`Mq`%`w5d1dX|wX455 zMMFtTON(I4G|XWW)QV@(O+CaqIXU@p`qqsbNfU9w9rbg+HgDMyb&F3xU|;%V`k~ja zUst_;eW*+PZ+EF@Hp-B3?5m=oQmn46%@DY*L!pF8+Ppg`d8Sd3ZqmCgc{uYi$Bo;! zMMSr5t!Yf$XE8J}F~R7)v`{oUmz0#Gv%tnKdePHU#mp=bugYj;Wu-nP?92G;*RPa3 z5o>0pz=#Nz+!IfiC1z!9B?568LfFMjg*-zoEV9m+y!hgB;Q~9MeDPxG(Q+Rjf=cmm zaWNL+OlM)1YuU7cp5CT|nwoxLVTb$%+E9L}6z5U>8S0WY>09dj=(wStvdl+KT|L7o z!Q#&MDQOEYuV9H5WqEn|B;!YxBVl|06dJwwN}V^aC|-J61GS+d-dyUduSZ7*`1(?- zrRWfq=(;B?ENJ+Y({uW3J~=x%ZMW-|<5uwEUb{g~(bROqSa;b<8ylN;w~)3)*DlmB zvlAzL&~htlYiW&*jj^xwGPHVIlXKN|T4;&d+FG&?S3P^yl%X$jwAc|pDSCL8v!VV- zQ{jy^&(F=93B@b4s|Pzmc%L}``exx*XLaUG<@@&>z$>g_$0v_aE{u2U%dl-um$=Da zb1nL&+NQ`c-SzeJ^DGu=L7Y3!UBxX-lcoJzri#^BRUI822?A}Tb;Ewv*Kxb9%+FuE z$|=QAnOVS{l$;zM8L4mG)5b27AZ^RJYSpUVp`n1@-V-Toa~n`s&UKdtU0S}Pzc!R> zxHXe~eqkYU>=D2B!W7vjx3yVXSorNY{hA;EH8OrkMMV}Q*=}a7IKa!yEYNn&+M0pb zE+L^aJ6k`}*4@2YA}5$$?09)~M}f`9>CmfJeG?KAMm+=s1PrrabbyFXDFL|-Bv7P+foTC2I`0(MwBXK!JQfC^8@1I`n^YSYHAive5&^J9@_~olt zk>#~{c?S7e_xfc8l$4YPJIu|^sT2*~AKq`guvFGRYso*^qXAYz2GKh)g=q%h%O!-t1CxVS=aUPM}l>?#(vV9ly02kI<_MB1aGqP7r$4g(K!x>v+BIYD8~qeD`iYK-3zZ-M+Xs5wad_wKFkp^ZZ!PithgO#S41g zixX7&`T32H9n9n8Jvlo%I^LH!i=ZA;6BFOQRh7DZf9Ub^Ty zu=LAr@3gBOY0VTr|LLI7kt0fmhV0J*)~X&p%n0~PMU0pIjIWpQocmftHcNc9+k46L z?E8m%r-vW-tzbwSGVA{&QvWYJ z>;LGto3`0p@%P{F{AuIAn>YTO!DhjxiiOJDv4W{=dG^ubWyg;ncdq;UBNW41HQ}Hz z2B+8XyRV?*YvH-{XXB+Q9X?MRR-X zI+>*YdaCfzx<9v#p+iganmcV}5 z7_QccqPA21P3QC3t_wYVx9!UJR(LHmmU&!IR#8bGEY)XXXJ6s%?R}MN=bEl37sLwo zY~DE%Z1F;8tgF1Vyy@=Vo*eI^3z|KdP{k^oZE7mFw z_W;KyCMSi9G)+vnwr$%+Vrqt!D|^(}fY<3~8tm25%26NEc76xkX#VsvjZyANnlSEN zm+x!dCgEZIP!?t7%9S!QG8=`2=!AuZ9Xs+(EUcS8Sfl;o~JC{!{*N^s8@RqqxT`nk)@|vGibjss-B6%CMW|yANDRTwfMleH6c4|a}; zNl2`_vSO`&Zmzid&#}4G}!Lu1cHU~g10>Z-9u!$ON^muz*-+0H49l6%66d76B zWZ>C{j~+b(Zz2d3`ezS}A6>t5C-n52c(Zp8jANv1*d%uB2#<=Q1-2J8E#=70&gPIj z!+7-AvG5x=E~C@L$zE9VedvuUia8T6?={rSB)9LM)D9imR-~nW;LxF{IlJ8bp`3g> zb}(xt$ZvH%sIAQuwbg`{mzVc!Px-MFw?FqUFm0?cJM0hx?#SoVgsPSn7Ah*L#+H`q z3q76z>vve*#h&BX<+usU+zL4g+xwAPoNnQ{I4U;902!IBh~ey!agf0546 z(D27t7gy1_E~U;w+lH?iw;tqZ96GcgI|)c6?9iRv>5`df{?I~bE?l^fZ`ZSd*nXyQ zfVweq8X9c7g zy?yOj8n#FJsKE^Ojjp%>QFwx8xiN79d-}i<^QDL$7(xSeKU=TcCWC%?I3;AXc(( zi?Ds$+^qD>f3?HX;=<0cw{PDv11%9gfFLgu6nK{w#=R#Oe)dFnMoSon05>ppcXvbn z$!ebEv#_`$VZksx))fL-C~Eg7Y&nuYSAEYienk6oyr&Li&caqRR`Ti2o{P%`1qC51 z^j0h_hylvu-8^5$h%X0SB-tYh2G^9aF|MatOJTtmQc^Oy{!ClNq90gA-y4M`->4|I zSZP~IkvCbSvX9Be?K)2z!nU;v0znYj&_`O*DKGv?GRn@X1uUunqRR;o%3BYzaNlq) zqC6GQ6j4Ua-rm<#)6`S}U&rR@e*C8Y%0{{2{q6FmXSxx9F~zyCET74Y1AxZ0*X&+hy;^|&5p>=(by z8c`=EdY_)@Dv`ojBKW9he~z!Uwfz-+KPZU);K73=@+U!Nyxe+^pJNvPDJ)X5j=bYO zpsv2m$8nsx*uHPsZkJKIbUl*2C3`K*Qoi(HzY{0UoijB%UVmz9q1S>tx11{@j;E&x zd0v@#ctRgMc%U;Ed2zJmOK`{rkV=L(wx>?%eaf}#7`jbXM6mu~D1KO9d3Ljmjg0|p*8xLj#yvV^AR;1Cdhu7D-sEOfATKX3 zi}>W3HDI-jenW*tMPlFI@BI2GLqbBL_tPi;?lKQ^aN&<*T)ez%2`FDPCJq0w(&O3I zZV#fKJdp)63cz`P`ug>nWYuf6(3|YPc1Ur{U*xFF^m~PUZV&E*=Ek>m>uQ3Llam3B zL-Oo<#>z~oUBMQoPe)senBJA$wQD_gr4k)ZR~6_4plHrRF;&$%hDV=1exxFTgM%MB zepDxU6|>->YN!ZiwzgS69_vLE+`UWaq_dcsng)i1JVPg9WM%b3MdjY@q_#~1d|Ns@H5-w`8v2L_g-Zvs6&Yiwi$aq+!L2^8g6Gy^|9O z3%4#fKVK64Y%dBJ8jhnaT6SFkuU8q}@zqRjF{f}?!n_j=u zeGHoFc4=vY3s*Te^YKv)y}t7dm;vIQ_U8ec`WSilA9TPkDlRV4XxcRCdjF;WxB6cQ zE3JL^j_uqz7!-*Hkd7v%r}zIH>uLhsEViu=d-G&>82pThA3v&3CwTg!nbg~gjK?-` z=~_Sme%jN+3lg#qzo22uuGEWNRyoo4Eceulb?-Yn&Bs0zt7&M66xe~9v28m_2iABI z+sG*YO!$NC-@bj+Acav7vMX1vEGMlJD6EFN#r}L`ZB4_|`^p?)bTDMxREt3zgs zUDvt_nlIRq-?eLNao`6Fg*g*SB*S=iJNe)%U|9y%CT?vfpB1G zJqK}dqSf$t9}wKk#Iv<1X#^}BIk#`r74zRh&Q`Rv=&f2WK@HaU*zqF+r%mA5THx@Pk(=Z zVxpFY=g+I+!*v7;K)|yc-4eMY6;w&UJ4z}Y9v%q{_X1I<>V z@JUNcLwk-ImAiH8mQjHBCB|JHSv5m0ORK~E1IIyC$?b*+z~&5rpW zZ?$5!n=NzyF?@;a9Une$lP`(d0!f5~cBpcRz;A(9uSR@H&Dce?@qfeE&o{ifmm&VD zq2U>drntxSSyxxr%2%&eL!Ha}8eFT|?x1J!8UphwPD!;WZCzdF_3PKGhgztq(QR5s zPZo8j&pO6)=wFE`DSpSExKI&LURL0bsBs?k%`KWrD2GfNHkf{LYbf~?T&oue$&*y~ zM2#L2=)HN1UW>m@x61?j5~h2S8gSZHb4n`W$T*CB*wrrYz4%LzP0UnuZV{J95NKva zH*Wta3u?B?^#907nVa_PIR;5G_u?-{V-qE%%h%OYlEBRPckMEUJR3Ya^#xMV+qb&a z)zyLM)l`ZcH*Ca2MOko3 z%!F@lZZ7J%uj~9wF0rvA-%0?qK|n`WSH;LEhS*5EnsbwEG{y1L(9lZwN8(n^o3xFL zph}$t{95KC<2V>tUz-nwY8AK4VVPaKf|8Q>VV^=QWkjQK%(-%7AbC_KgObXqWMphi zAEeCRu5J9W3QclB-d&lH9 z=a@9vsNNFK5>**ECd$XR*J-@_*zo7iL9le9I=b&`a#1Ocekj(xmzo*^JRgXoORuS^ ziSnXty@bnZdUC-IzN*j@T8q-q9^Svw2ZhaOYYh`91a$AZx`u)k)YNoD)vH&UxS3!c zA7{5g>c5Y+2D^xkuNtxpHQ{$Wr=sr|lZu@LJ1c9XwP6eH+9RC-b8Bk~4*02_O#aks z*RBy8Q4$4g8X6jy7Z(@Fm9sD}flx%H=o=8wa7UFA8MXV+t$wu^3wn{dbbMq1BIuxT zkhd6Tk)qGi@ah#SG`^F=jfr{EC{2@apBl=0a?JzY7uZBI_Unfy!+KMK-!>-4T6QRc z=WRVDM`j%l&sI35{EJ`=D~XeRRepI%v5ZQ%S@eLS#pd7%A_U#((?dE#bFgM=24CD% z*}HddibS5wUv0BMQPS>o)W5R;Cko^YGG`{`u$QmfhozpF`o$7dC%U-eA3B`*xvL%d=-ii?&^%IL3o45RDIvcNm+1koS&`u3~0pjtu<_ z9fu%*LdrjQ#m2^_gz4@lZws^Q6rCtQ0C~Dl44&85-^dC{T*bq~^YZr2wRP8c>(Ks4 z0UrWNRY%8>!Z(0#;^#idobAY`2mE{f>ecU$mTlZFt{(||BnjXm23(1xeGu>}>*`d; zCe5~N*#fE;|G}Xq@zbnYgNj)PI26_c{6H9PeqRXlZ;wP`1_Ta&U?FQ^*>Vkzzplf*5{D1-$+`G z;6rGw6*_LfK(zRVf4UDq(@8f5$=X!|ED6amhOB0W%W7juM%k^n@xyiFFqYLQX!!9^sEqYH!m}FdNn#rgRV`Fp{DBfnMFQf=e+K;`x z8;iQy+t*_YaY&q^^H~zHEHl+hQ`4`@&jUK7Qgk^Tn3A$NR?>?9LTY`Qb}|ro$is)* zjXTlgsK~wGIP|uyt?u4|o82yF|Ev#xL3&jG^CXp!#$0n%67NE^h%B({Dj|jMY7kX| z0O}zIdjin|2x9Q#M>D{C)K*f*1+mYy>yf|s{nbvAdZK?tzJ3dj7iB>}POel>0jr!> z2$NICEx0GpApiIz*XNAqpU1}5U<-p<(1Aab!f@2KW5IBp%${H8qj0@lnjcbVY;LZ? zMcIEFJOHY-4y}0a#fx%8Z-V!t@cD}o>s7HU2%P+Ou36}{0g!->y zYGD@860Y9{>9HTgz2;rp35o^e z=?&0bNqw;jGB~LTkhk`Km%)`_07Hlu^4Qn@?AdZS4lRw~z!jKY&}&lbcOm%_jCjQf=od&xROMMTFv2RqQdd@1Dq5J&=6ElxByTqQ zxw!j}Go(m_->oL;(XAb)`C;6{g-xkVeVmo#ASxtu_`qv~QTT<0>9M~^5DaC%5!c)< zaF3FV<_lZmDMSuq>rS*^vs0&hK{=CAC5(z4H>2)9JlifI=Q+y)Uz3)Q0~9YWFURda zkZyAh?b6Tu$gR4{JK#6)VQ3~s3Lcw1qb-(Iw0s$JiBzfHyjcr(u<}Fkc@j_;%SMBi zIKYE|J5<%w#ME=~`|8D?6-#}1Yp^KCg^z=S&l$XaALk#R;^o|yDJUqAHXkYlNHdfp zgb{k#D`xbcl>^zp_Y$}7Reb#93HFR$SA|kw;PBSBU_|UJ|1cuM5pfiM!rS{d386wN zi<;cWfEMT*iFQ5ZGsDT(PFPvdlay?DI8BzHDe^irM8qr5%?5DU zU}cHGI;L=I8Y{!8RrT`&BnbzwGAzhE5}6`bu=%vDHdoyvY0KZ`HR)T*{re}|^DN$% zd&-tLfAL4{Fh@|T5g6x!B!9*|(0BBAW{4tBp#$ZDw_lv;3m6GgQC6ntee74$ob`3p ztk;R}xbdhkEp)(`YX>vQEwtN7T?MKU6#+AoL@-{>acOLi;1h+0uKx7;P6z-5*%ge+ z+?~^%WrG6KrZb|X{v9&w)`t|N0zs|`S~fo93giVuuQHYikkJw>kP|>LuPw z@=z5>)QY@QCK6TpH_2uP{sz)jhc#&Z{VTXoimtVFMu|X+3_U%)jO#=%mzI~z{ok8v z+#gxC%I4;EfU*USp5XwI&Z>8Jt2M=yWPCsCOd|F2#aSECBl&bVyT3D7c7ZkFZSOle zNc7Yt-a-)+Tmg-8xVuc2Q~In>k!Jg(n_-s9r7-S!%XJ=aANd*E>!c%e5<#l z3RCQ9T7EGIZmU^$shhpMeI>Y<0}j3V&}Oovxwp~K(DVW3klMqKsj19@aj+~>r^FfY zK{gAB{3`zHcuhDy2dTFcP*=c8-f+Fr?7olSP%<1=@+TpD0ulQH+L!^6k?lKnr`?*> zt5=gIN0)Z1^w3sVr`Vllr%wlXFMK&pwl;2V?p}B_kpE8riM7V3OR&63Z@7KB%?U77 z88i^=>UY}bhyTb~hkJv!>xdIDgoBim{3WFV;DSJ`clbGW41u#3wz`t?&Q{#APQwHQ zc)!m2C!fC6>aAyEW5b75gntONWv~$X*)#BtPoF*^Z?voMZ2M)Z<+P;L>3EY?OiT=- zg&FD*x_B+lS?}0b7zExI)04QJ0N@X;-fkgvy476L=sHrbzHiXBXc67c+P0uh#hrIi%*sW{sBXX_ifG zZK_~!>IKo<2_-UN&=nXuMM^&9)#@1o05Wv$Jp0~f?&r8Ux=EfiL~?Q`K(Hfx@ET7W z8djovM%<~ZuBL_%82~dsLKgZ4YIbv(SSwZJ@Db5I~I#11@R z?9y&SZZ}kA(g?xJWXh^%)jB*_zwPK_qPJDBHn=s@a4n?sz1TRujA+ih(BHSCOB9>0 zSjFKpI(qiv(!x)|bU~Ykn_IN=+?g|UM9P=}A97+v7ON8yT zT}mn|YSFqmZs*301R@YMxbz0mH8@0T|4F<_S*^0pLp|(;as+g)e}M%rcF$TQ3{JpP z@N_g!f7oj{XVkEO?%lhmNO$SD_W~;_sE?l?4WJCLBLRaBQPN&Wwt3%ASz4ZK&CrLX zupiqRM^CV*j9+1KMgUgjBtn%hW2IJBW_Bi_as4axMi6;YlpFzPqfd-ElCm#YW*$Ek+s7?1syg;=_bc#fWi0S59zT#|8zNII1A50ZF zJ7LQ=@v8w|kX(A<*{|F*BP1J^@e=w%5X6%g64t-7b^FqDSJBg7Qs%#ex`Pf&u>s+b zg@^yprfnNh3CXP&L0HnNXufw~xU)zM>7fQWJL9&aO)(kjj*fXByhBJ}4=n0B`$Kq} zX(`=rTjhg1x&yKCNjWwoGj3v(ZH3e4bwp)TllI5r-!7+hGHCGp;@mi7`^P28LMab^ zsppbP2(qw9Dh+o%*{QT|AIN7Q`kL9|{I4_Zd7JwO2AY6?$YAP=7cVSc->R2Ahnm&c z)`tF0Ymj3a3Y(S4VbI*Ydp8{&ozQpAZ{NPze|fj{@#Dt?;WG9?*u;*8Xny;)Z(u;c zCi5ltqtaa$G-JPSKn#oacdjSTd~tE;SUF+)py{``3*f`6^e z3QSD;mxTI|?^N1*J`xOnWx5_EO6>SH8;$>u!MXnq`?+j@n9+3a05hD?`%W8(Bw#p4 zTj+p}Us1FA(SDZsKxJhUJQT-xjaLDAJ9OXbSScH2G)wFbW`c}No*L3od5vt9nVp>& zRF+LJ(ES*dMmq{L2u8#KwcBG*mxB?eVn8j?Mu5$iu^;&XC1{Xi&W9Z@M(_akvnbKQ zf8h&PJGBeHBaD=C1gF-2<`0cc4j#OUW_x+m10VWG(YdX@jQnC^THsSb*tXB_qz*cZ zxPKMeaX&KUOev&9Q6doexndW{6;z63Vu z5y!4b{97zfitWdtUgkqek;vyV46O(jifuqF?hwHU%VZt&tJL? ztV1zf<^u>-AmjG!9wgWdES}K$*AX{w>W(?!{1y-!7kifGyz{tG4p|bsX06h{==`t% zzwAtfgpu-zr^Z%AMMeFUxJc~zXsOzfnD1FVgP z#OrFCxQ(Z8LZoqSw{A4JG-=%J|SLu>?T^JP>58Z*cq$0;y_ zP~+s}gfBt5O?;^kVe0+t34ib+AG97yYjzrJQ_GavItawDVV;*8svJVQrBVd`Q+*c| z9W4kXse+?eU+V-FZJ7_<+O^TL*Yqe`o#P~G!f(u_lY*C|b&DFo2ns+ZxX=#tGK8Z3 zBRpxlVZ(-g=p9j>6|hHgarpVFGx=4~;`|B=3qQC~-0uj<{$A5(&z|`~e>&5VpH5~? zV3o4MJ^C$4VJo3^hG4_4B>F+x9qTMlpT=L4ugOzd+mLXeY{7;=Ri{LT{{s)*qwmPM z=@5)!rlp53u%v_t1b=d@sR@V2Y}^URNJEG_kLdALFTFaB?l$<^uqiJ6!2qJ`ThOvj z4Y4cHX=%ODIX`&A7|Dlf6f0$<oMc8jXe zzQ|iFp_h^pa`QZ+oL{$fM!0FEJZQUBvWjE7;>BMdqkpF}Bbkl1UTdXz$!YzQhqT*Q zcJY@4@%&uK*87QxRLFaPt5XqV)E(!Aj!)ea0Of)DdX4F02DdL=+M6zoA1Urs)(`&< z1&A2r_0!8S-Ghk4GYHfc=0`4ijLnT#h!rK=zi*j75TWg;0LpE;XIVpKB>~#y11^A` zaO%rRp?z?};8Hw;OElU0bUEI(4+=2Ze!uR3VNGUmNGy)Y0mt*_Es8FRc)Y3)OQ$%E zw9w;TDB)MdA+eL$1#nA7rMuosi=@jBG)hIly>YB#tFV0a>XpWwpSVy`#;fvU{9T_% zGQgz>AJ|^8H-&Oai{lX17+peMP?sRtn9tJf3bjq^ip?ppJ0hLq;EzBq@&^ptxNX}S zB|6eLTLM9Bc$Jfq0_P`~oLg{8ccjFc8%PcrOqaHb4{eQq+g0XKbUD+&bBhYg!qv#H z$dZ<(>b(1M@EFWL^;c*VX`eEq`qd^Cj=-UI{93azU3f0Q0wHr)9jw`1hmqkfxK6nj z9EWO2kZ4KdLw1IEXjmBS#E9EHyDJ%v%PM2U&F#N`(u5|=xbxfx#T?VJ-tqC{>2l~B zS1=|6L5Y!@`>6HP5(o-+feIkMeB9<@7+#S4=rMJf2I|-@b`I|R}?o0i!FvfyEVn1?m6;sl3j&kC^Y_HC3WZnM)gqF;LmRpBA+Z`7yhLG25vsGZh|6 zNl95GT&1{7j~cfC-@zG=uxa~8Da+Wp`1117rm*R>fGQ>t@^GU z%K7^!rRD%0BvHaTP1LX-kEqYO+Aq5S?Dmvx%>`K@kFelRA8M?t;@X}*r9!e^93I@3 zx$UM0Agty2ebv83e|T(xS${gc{-+nZL%lvCvUcXLd=QUqf+z=ll<(*K3y|($l$Bug zPbmFckK|w9de`9PhYv>yMgU*rQ4Ob$zCfl^iFAbkf%d`6Ftq*}ggwuINgyURwk-=SRB zsk0_1H%$oWrPO|RCOaB5>#Bx^%ob@#fr&Vqz-21Y0H2H8;{5#^T(8M@!Nrv z9Sl$Zktl|{40IQ}Up;@$NciH$ofV%vi6V0nW@0}y7=B{YJ%f%wyUH-=glqTYx$60SPeda7DT`pB&je|D>86^WhHYcWY~%n-^j=q1fa(d zRItry`KZw(PMDi7M;O!i99{qeC2Qb`RHi0)9Z88J{{~ve$j%;sJH>@|a2Z)+@)!T{ zIA$gX02Z$W2GX7FE?uuMKd~I_&zIy`-(Cpf4k}_^D^ea4s5n-m+~yB2-5E0xg6r zZ68YANSAc`_U%69p{K&z8^e(&;F#eK(7KFwug0#1 zZF9Hfyd@m}$^M#^FbMUnk6tSJ{!hRn?S2})_c(-`^^k)Ap;S@J)@+aq1lbn=d4yTx z50Z_J?+?!nqcTyk$ylpIkP}?^Gb9!5;f;_o79uH|Ub%^LLsfdw%{=|umK6yhiIF0o3OY`3)hCUz~#-rC3R|I*8%pj2I zB%nIj&nHlL-XpdPWRRTnK~~lz0&OSYul%D9XKaRDatW=39ACro zhjL2kT-ZduFR7*Kea1fi?|I0L?5!{GtBIe@CF+eK&pi&-1;%{&LnXB zXZC1Q06t|Bg(4(`ROyO`=Z6j*#l9yno@rr6%ZYg3EiP?+ts6i3KS3$vJ$S+70mmRab|c{+tC6cvFjub51%2mIS9TF3kv)Y z-g=jPY$YsXXI0%NIF2XL6bLv3-UnkPgY2%aD;q!zG#D&{lZ;)VfNw{x4B0GF6Wf9L zhE^VwI&2K#*pW4gQilH}G;b^|E9)6{4g35=0E%f7ha23fIA_R{U{nbH%p`lxU#-U>hPkm}7u^~($(yK-?iDQquB$-$JT1^oBubH*aihCu3R8=fC`qq&%*^oS24GmLBD$n9S_sT*C6pf zRQ&DW7bxBFd|&`i7q$Ik2L|ULFtkLZS>m`{fw+d!au|9ulB#~-`G1Jzc8Yd%CBB-3N0 zSC65)5Tr;kJY(3^lu`2^rbv(1Tvo{dqxNbtP(bGY$oX>!iw<}-F!wascP5WegPm13 zCUFj;W6ms%cDWsm(4SM7c=M1xDeo~O|2Cm*Gd~KN)pVQnMx#tUlii2mT{O&!6)qQcZ3!DE@-!#n@UizCKt?2;K*&d)DWIk7u_ z#+|?O?B&;&yUr&xyndZs{_Mn6@%w!AOxnLLBRWV9I;9tR9wJ z7!M<(aKCoD8rNwfJBcle2MRO}yPd4nd+TDDeKZIr90`n|Qqd3*5fPR3^$cXH7QljK zge*l!Mv`hQ^6Ns?Cvk`IgXEwTaXl{XDs1?tU0vkiVPZ|rPEa77LLdTC>g-us+&P~9 zieou3j~EDq>S{cZ+_|D3rZ1mjugK*5JH>) z2Gcfo!)+u-(U39Uv`JZL32f*thRTkzd1EjE1IOeHCFUC>fR7v&W}PFaGDaSih_^-| zgX_0cUtrzJ0G>hS#SXJUf`m#!rgN>1k+D;ZW!f(xeoOd(v7eD0-EZ}=KJu~0&uw0_ zp9SxHkPgeOz00R{WDS?}DqQ|vjB+fZc({kANPh+Ug}q0nd9l(XvT?g}5uwjN*To4h z8xw~JDO?E%SmD2xHw+j*2{#fRIPA*31tU3D=On~OD7SnVP@V(z<=C#giAMFPaVZI1voeS;1&V? zBnWN+fSIhOD_HAPM`f%<4)OD^Sg|56KcA(aTgsXR(b^zRE&e1l?O37_=hH6_lcTYa zm+gDHyW>IHfXE&{jseI|!-_IY>5UfUwS~oqw?^bm#sk$--31vFiqN_x;YTzgdxaPQ zUMp#0!oF`3A5edN2(AOjKUTsbxN(KJ^}u`+Bl0sh@!$x^yH;7RQMj5>q3H=KG9=yv zIP|%o%{2K!w_AYp+4qVVs5@el!;hnNq}0_RtMzyjj_qEY2!;h73@(*Ty)%)te92J) zmXuX+tj$wDwY*<=>(&%N7tY;ILQ|vdH@iK59^*u-MM;Q;L7@r8o$)5q<-x{iVi29?y&$W-I|Sj zMFPgptiSd&qC+<#Abo%G`(T1VHDXvvOLG-V$(TioL|%sfq8B7BP{VDw@0*|;hnhFK z#ErmC)Z3jZBw{{-0(upLwg(U#NFP6(uWqO?E>UZ32~S(nW%T{*nk(Y9F_zP%Jd49$oQkZE zj073VZk|D&D;ye${c$b_|9}8yf_&CMeQ-#K6^c&8ty}2@;$1MHsP4kI6lpQHvpfFT z?IfEjWkYI~Oi&=;mkNO};$;N7x*j|1OIFE+j*wSSkb=Fl(&FjUr%qtWeO^vZk~P)U zjN0wdZiszLY~Ox3O||Qb@@R~;db{iK3a>k;?9V$oVu5A%0Y5ll%m9^@A4(2ISeWz; z!;zP)Qod7C6OK&OEj+nK9b1*NCN1+g+a5W&=TDzr!X+0RvBL~L)m;R;87y?tBgm*N z1`m_*Zv%H8D-CDCdTU5W(ZpdeG~YZ#eHuZz4`^v!1Ftj^`D)!^XnQD6I5SheHePV+ zm)BThQ0Z%Msf>FP&vfA<9pDdd1U3008{w|q`ehV^5B5utBUp(q5y0;5?uLla*bzfMvxD%#?+bAoiaR8| z-%}$(F6X7Ztq*|(bM5<-WOnZ+O{C``eEv`XFb(AcD76|qb}eo*k`uP2c#SG?xECBd z&v8R26e0axj4zU_GG&Z)eYUjFv($%vd#0y+4-95n9C|tLMQ&wZ6tia_YfvWmNU#c2 zvJs;S$d>>EE+aN=+C)AHC30jB#zN`3uOP#K2?;r^E>yh;V?9NVy1>*#o+ zHE(W1b`0?mZIQ1T8JXF2<@glirQg@UlbpmG_TkR6zcv9zA)B5T0Qr&jS*_ax^yJeU zlIllvF`l;_sUf`Z{qlWHCFA9DYf$${s~Nk5b~EyLD1f_xRz_r5vYI4|K43T6;|`K@ zu&-jJblqQ~(B+r&$_`c9%#dL()OXT_o#J8mr{_eryyy?Sr~`GxIPvJ>W*z-CzQM2- z!XqN?IW0p-_?@WQ*5>_jP+$ljm>DV8Y-|qVQ6xmfN1F829l^{*X=y15pI2eDixhb< z?j(8Wn+&`PJn0J0HerA+_u$9o1r&+l_D6!FU%zI~Up^k$vEgknp5#Q%7YP8sK&kgZ z;4&T$+5u!=E_6GP2jLZD@%cUsdXv=R1gIs$)W@NrWI#6t=4r7-)wOA&Mcj9HFWsIG;3MZW9ADO6T`xeH9;p?ExQ+xKbooRW4Y1Dq@Nj^RBD-s7 z;{^jL^!mSOT5Bfq+&)Gc_5y&Be4>1x*>5QDATPM>MoX;)Dewyt`SAMvz5%DN?A*j8 z+;iye#dZ*RI>OJ_SBU#Oeqk&#SY^vitBBM0i$JVq-7rWmHWOPoUxNfH(k3Pfz`;JP4RJZvGmP?J9ioc1PsG#HF| z^%D9Ep~1mA?yvRQvJY-a20m~{mgGfSTQoWrOQCp6eh!=fY99cN=lG(!hQ?=1h}^{k zQVs*FBa@*ji69EuXs%veRf6&K&<%TH5gfLHIYEAhL`Y29DJ6kw7IJ7P`FQNmEFOJf zg^1N4U>AhYdsyNdFHT{4fDg_+TY+t76h_U?Aa2lt#|OD1vNGnI(j=L>u+x?)0+;DQ4H&e=69E#zNp$h#jpC9L>j)1d>SF=NeGiBx<%wAl z&+$S+BBG+3h!)KCB))w8I*bsySp4~YZt{dhRABzP(~x+!zt{!)6XGZN@Dn&D&xGLR z*qFQHIRwpZZK+7?yv5=Q14|*;bqIoiAfe=_4Yp#*UBD{Hq>VxJ&nQ63deXTVr#*zg zJF`^$M_kr5KnRro2hHY)RUiYRiePUdeqR^*9X)YJ!8;x$V&h;Sknxpz`4Apm&FAN( z;2LGh-GBJ-I%;GZ;84Vk8#)%A`dhYB+Bw8Dr}P_x z@sT6zv|DeAe>>lRCZXwb(kuDjK)GUG`Bq#8y_mS|hTTqqxIe>aLrh`X23yAM$h`|* z@dJSIEo7SKjg8mAN$x-7Esk-)(3u9BPBPFA6H^mfCLOW$=;Mb+JhNtgrdi+k3T=xd z84%=@^`e;TU%tGG>YLcu7VO;_JbC8)sb~qE)Bx>XJg#%{YHnl|EEIW+u%OkDC1I9{l++0rm=HP&xvgNW;l=r-j=<^`N`%w5e|7k}U?N zseK@>h@9M1aQo&V)f#;k{ z9^56brdzjfYh1c?Ny!Atyc5Xkx1T=+2{<&$V2(c$mgZGw^n0+&Nx7G0{d!?JI}AKU z#K#{}z85Jo-t|Nk^B`4&!-$Of(#zR~eFo6P0}c+6)xa7U23K0Ky#* zAB~NSFtWgP?6LhN6c@qjDOjn8)zyQW8%kw6>glsFYQJX3FzcAPC!L;hFdx!m+EEnCAtFv5^O&1TfnzbTGG ze9Fc~0}cZF2;G`B_klj?enx6Wq{mLId%J~+e&wBy!XnERp=1AmbbcKZ1_fuDE(3@e zewGpc3Pyev)0W#EVxpq<6KP0$w~l0HR0L$uXM0r6d~hNu4(JP!9n)> z9)~7Om6rc7IwC@uNJCMgn6sa+$$(k}585?G$F~qaFe0YU$!k$v zYuY6fxhH4KfPU^Mo~E>M#fkvRoY7kmf9Dr?%tY$MxVd>7qr!M?O-&PISr*e&)&_NT z^n+H+0sX#JFKgWl7LP(S*w?og z8*Z?_pNw^6=5ru!uoiVG`+Q2jar&qhcH3>4zyyW~^fc|PcCW}bOaMtpDm z>(}?iD&}uM6VuJZlTl>N40Dg(X7-h{YJa$8D;{Zi0FbtzWB;+{g6|&AX(lhd7Uy@N zw`X|Tl}^@jsk1My5e)-NWh5M(ol^kgnGd@)$o*QY{-LW&A9wzz7*i7_70#f-Qu{z< zu)?KP_2X$<*Xt*Rwa$)q$h~PfRZ5A}yf=ep#l@ZXV8Zu5~bArb=h$kqGcPe8xDx9EGaQ8rj6*ue# zLbUcT(G;y<4mi#JuqwgSu4bG}I3YAo7c9m7Z)(LUcq&?LleHZfhm`I8rkbRc4$^F) z4sr#o=Rpe@0aDSK5^+?W8GkjvxMn0qw(eR$D&w$@&gGxo9%~hizmc4Q&&tjX59OO# zf+0md&IBWsNXXw!Q|?3|dF(z#Ast6K)X+m(tCK!QEuKbRME;AO+Z5Rl%FFa zPJ|DyRRJ(wJkKhonx#?KB!P8V0)LUGD%u+ay!hQV8V--ftVz9 zPEbH#If2Q#t3asB2u!*q*&oD%7zw)Zg;=4jTlF7T;M&j`2f*HD#-5DBg~AgCm*EM5 zKfZRd1NSNG=-g;7L7owXa1GJuKFT_vxBs^7ZW)=oc(4L$l)lilkdS?PdJ)6!9B;S4 zGcT~f)D6-DRh94$!Z5$YhG#X-;PigkYzcMlAbTrLT3|~zH1q6GBQAZ> z62{Z!O&oQP#A{!U7~ovtIjSTbMt5iTnR&qh@9JgTE@pD*0e&VP%#~iaN1xgBWT&3A zxPI={K$bC$P3z8ncuYQ%5?T4;D&NQ$mlPf0#krm(@_b?gq20N;3L&{wYGa z1W{8{V^r!Yj?+U<`5^3(ggc6if+7-$1WAk;rlOCxAj`l(`U1fJW_V5zN!!RUGaCE< z#oU|6^_=hh|L-uw*s>;j2xTjUvL%tFC@qq`Fe=%bv4o7GRFaBhOO*Pw5EV7qq9Tl? z5;3-H6(dX82EY5WnK{>W&UMapyM2G(f4=9B>zXr%K7HQr*YbQmw&%kLbZyWgOW!v&*N-;vhL8EXB|^KF#PJJCM7OFg?r@qaSNIS>0H6BW^u4pzJ0sl z`0?ZUnwlr$9_bKN6ygJ#h1k|hK0`e8Rv{MwYz7l?sUDe zZ*^ykzhT|C`Mf|Qugo96#=ZPXv8rLcJt`}U9Tm#2>G|ST2nRstFdVk^Gn#Q#&PR$O zM>XYy*{=;Vz-dEZXo0ru-QFV;uH%gb!RIKDOM{gmz*STWw&+02(^h_{oNZuaWPdAt z?35`WCpW%I3j=jIj>Q$Wb!(^0!-yf!{aC=-?O*rp^Zn&$r+~?<$IM6^JJa8fb$XG; zd-kqOT6^6qY1rOJ@K%?TD^-%UvVYpb-@sD&4Ftv=SE16J2uLMBB)?CK^jkX-i=%3r zIsX`aRvptZ=@ZNgrSAT^BQZm@7VNF2!@zKsiW^3^PoGvL!->(Q#Jfg8nARcm*6S8` zVvoMJ%rVeE+}?hjt;eIc`+pZY+iH(VxcAY!MqH^d5CfO~^wS}H9_p(r7L}xqb^mxT zf6>*J?b}%Z=+m+$VW)w^qGl4I1LdYtXPE{!JYLf%QBRzBihh zt?^~irQ;xLA(T#>f7ih>TBPrsRJ=XYQE#ChVNfOphK5~1V(~eIJ=fQ0Ucs)SD+r98 zxNidYZY(EngMIr@WLbh;{iD6aqhH3;4BNBEia#Gqrx`&)#TY3}>EVGkQwk*?=7BK|RY0{V7k%NP03PS%88zE;T0(;vt3uVl)2V z4=-}G8sBpWpcv@(t8unwL5Jys*A>oNhup}DaF*=H{!~8DC)fQnx;#Jm{@#JOxE?Vx zx7b5{Wfxtf1*1_)KKg>=h&0w-`+tKC#J973an_L6 z)q01s%&uR*9(~87AU4SQ&>!ybZr!>`A066#Vyjk~z;x;gEhA(; z=+Q;`K0iMyrHg;HDAvI`0bRhd_k-l1MS_Bx^0;g5R^8#ZIb76|Dy*MiXxH;rtW_ke9AO%R7b>wMbv3y>1LYIAau_frXO zqi$7;`fq(P>$Z=|N}oR&2g)qXH*nVEm3N7*BFbw*cJPQ(AD_0J(aF{O&l0WM45`qh z9$B6=JaZl(UJDJ4&Ubf=i=i_#1F96r_NL36z_NQEM;3o7(4?CwXelRD&{s51&6S4@ zoT878@(22|L87XmG0MWi*3z<}M);biDaVd=;imIlWjLi>$hQyPe$TP?byW;WK2G!S z_qV^7%TC2XV)3NO%0ipg74%GcU&f4HJJ{>Pk$imu;kA_plM|YKd6j1Z8)|Nz9Ucef zm#y!7r$v{ZJ^d-d%J%$pue0*_)vLa}28Hj~xpOQVA{xPjfxdocB^5_xP>FL|aBB-q zmqeSA9~5rP#E>a)R9GdpusQczPMp|;p6DFabP&~bvCHy6eTQXFmbqglC|YJ1m{PL* z(fRs{DK2jx11vV3H#JhoUedifU%Olt@e(Iw^mcQ_nMyBf^Vj}TFG-M0b!LJxbuk5^*VZWvMkik zU2e-NRS4d)d7_V+W;D==sP!NK4}jq~x!;F&SFUk%*SyVzAQQrjBaxY^mx9+$Y{PUp z;aft-#pqUS?YoL3XT795JohKd67I~C7y=PK0R~^gc_IoH#T$)+?!JL;g*_B+q&?5m zHRW#9>bnIF-F-Ph@4i?tXL0R`sUPGH@s%&9wEUar;N)vIUC?wXx`Fh;>+8p7owS>3 zNFr($JY-e-RxXLHs>%xLDN=`Cm}9Vih_P`SCk$+t7%R>hb zDvE$1e||9x@hnC&s3-ETk89;k(RYA`5cbN+%m2@^FW=;|$f^H}$sx zdJs8k);|_CQZRr<<0#C|4$^(&`i3MJkL$Wx@ti-uXw;X&ic){AoQhZ00%98;BD6HO^&+acyvyEnGM0tv)p6S^5)H(iuYet zS;XL<`Y1IqkJe634Qg*V8ZT;|I1k%ER4b*d$3b2n`o&uA{Fy-4M;rhGb}zQ1{YR*y zPooS@Qj7KoCzYfdNt*WY9C@)LJLu{S$Ylco7 zHiAlDY*!2RrNW>`?A-YfGl&`cPEyw3twd@Hd#?|cs-_SPNQ+&EpD-=H7dk8yuoBUj zyQO^qP0u6#rVOc&81#oKUsVYQfNdLh%5140(C4WsVgM6`1Gc4hyjuT#n4@kA_Tqz?8k>7Zvv> zj3ew*{W}Xke*Roa5~mWCZk00Z!-Luq@MFMAfiT>b|+ z`$!-Fp|N)ywqrI2FYN0-%c0cmwP?U3B=;?=7b|3jZKV(i%ZjE$&I zxgr8wcDQ&H`QQ+KMLLDVX&KG#;g2T&Xxg-CVwu=~k1Oa5!H*o563gl{c_jgEy_KDh^gCgB16=;^glkcb|cc_jJ-aHGK6PkpT@)C%a@B#aP=zBdXC3TtVI zXdpzK(Okz;@|U?YH&T^ky~)=j1*NX__D&O~@A;ENSw-zoKDbV234x%5Pz&q5 zSebj;DeT*}U;YU1>Rdi2P~R%vB$!8|>*f31pDQX*|K<@o?XJi}S69C{3ydJD8cD5T z{hh#83QcOENI;tRQQwA~ayk})nrave*rpGq^#dZqIJyMPUvyf^R@OTps#uhuK{zPX zlxbNjG&r|?IltgGL}>J`ylA}LpQ}b*RG+bky!p7-Kxdr>4RV~@M&V_gxqLbCrZdq1 zXVHZBV~UDavHhKt0i)$01A7Oh<~>_>e_oVYi`+KR*h&UuaByDteO^B^f8YfP5{f`T zz$}V4*?(w6YclJz5i;p>5ld<(jH6g#VBsEzAy~PshI>ptsr=&mgFohXOYi2?H$Xc7tss?Lz zE4FQ$Lim0gU`H_@OJ*A!1u$|!vhG$H`lf~K?hu9 zTPV-$_YiB}H60(^to859E`x_J5WM4OXFL9WO- z1PGIbF7|EqDz3&4pp#12^!242UeNXpt}?Yil8z;mZ|45~EhU-4`>nkJXTq`5xp&b|*P|J=Sc1*al0YM_3Vu`3V$(()`Cz^8@#GJV zQ>WGzd)PHXz(7k<_mW~)qB6e& zNDRc*CaF+Xla8z=oT-#{0mQ4xeQ;C#x6|u7GE3;xIcwT~HRS_V8YRqQZ1wZ&U5JuX zS2~4WJc3t3qVqXY{zr8#r|8f!)VM8=`6sZL5XVVD#<`t&J^triNRyLQk#Pe`7-*ijlp-Pwy zI>YOSCU%rh=gLsL#emO>7!72Ee)MMu78iDhglmzPT&q^Crew%~Rn_?STlF?008#>= z{=?NbW$rHLQRe1R0Htz49)e>^Uz`Kkd&oe%%Lbq4$ie6Q|C_P38zpMUP#McOLAc=MbGAy_S2nD}D56 zKFhU^H@$OgrKA0tWH-wk85iUMcSFH59!+7=yAMDS^}TQ0LBUR}t-;Pf(lg9h(}d)V zAtxOh{18y~R^{CHhq&<~!FGh0mN4*7uhxA_ut}s^m>>5Ac0BH#Nur~JwY6|AXooM8dn@J-MAQi(UnxCJq4elzOa!^IlMw*3~XH7Ej0hA+$_k39r4q=!uy@|V~ zR{6&Rng7(6>!AHJH;2Bc;|<2gZ9&y4AeOl~6)qUuXr3A>tlOXWJ5OPwLpDx1>VwXF z9C$$?kQ_8fG{9(r$9T)cHv|0q`0uD~#xCb54$2!fJ&`X@p=!oCmc5J;I-ZgqH}`?1 z4FxOWvreL=pqYn zVnfiQ@H|pVY{3=FDk_>QFih9u+B*!C_kd0#=~X}8v+KN$&*;`uc1)wB1&C>x&mN}; zm@-krs3AW_mmtZxQm^Hb_P+^K%eE(bY0gaS?)W8UU9&+yp9F=evnFijA!@8}F-J4a= zG)UkEn4_!ReGWD?1-52#j~#t~7g4;@sn?{iZ`Un6?<774fRo4}64W;!jAHJ((Z~7K(rB5u_FDa;}nMZ*rtpPaF}_ z6+L;3ELgNU<#{_7heiRMP^X_c?iTs5Cv$=dMX>gh?_*=~+~R$`Hfi0=-Oy=#g|j zl0-ddE`WD?lL@-vs>G3}o)ZL+n7WW+C;V#C!d)#nN;^X)A(l1cdrI(~HU385h4Rtnj}p;zPD-9{Xd*Ow=X+M_PEVp2f>2IoaAFX3aBa06`F|!r2NOAYjlWY`UD!|`)n*9{AWF<>U zA)tA^^%^fCLgjiC6UG9GAp=Ck)-9B#)BxOjgNc2gZFkB!VD6DuwJ zMN)Wp>bry5vK_ng%YTw!lH3QV2Sb`p`YyR5YuC$t@4kA5IeNHY(KYw0# zAfaXSm7QrSPSec>l_qK?&}vCIMekGeww;;6Hn;tot39!**f=iAKc%-phZ3u;BOhrHYr;(GK{~lUEdJ|QOlG*ITq&M znr4tQI7mX`cUkWk@W^h*2ivJGy5ZwoVa5%?FOZ#?o4?~ESHIZTJ}CHBjljbf~v_6Tju9hiGx7m~>OY~`|g22f9{TL_eG-ili_&CAp zxp-QX+f=WLbJUqwK9y|Qur;J^)bWPV+n+AC%pI|4eEjg?8bnQkQJ-?>p%Bw*)~ocs z?M)see&agc^k^+h?qIG_iy~Y`TX*%V+EKK*4>eOf+{}tT<0gujvGPev-=jPj4dqRB zbt{UNK_9&0W=PNbWhG-5$S)g3b8`TDtPP_cG&DpZ1A({4c-h7Qi|$#nZ*-L9RD2=> zdIB4$l%wRbK78~jg|uE)-duw=YY6;? z;QSgP)jFy$E8UB8j*fehpD)dls}}{&1wz+O91a>(WHrvs-IDWhg7Ta?szKF-)5>I{ zR?fLLQtL+JxeFMA0}lw@5|W| zAA8<%BNG&C7`H}4J2kumq0rhSAg_A1=O=XqlEFYD(WT^>)*DrS)3ly*J)8XNCauHjgU|8qr2<{yt_#(^Bexm9tStNzsL)Jv!FJgz^I0j8u9sZ!UkBhJA+Ah-E0h5371 zZ>+*q5LNm8+7vkjXy)oGB5{LSnXpH@ZQHgcOCPIi_^%$Wt7luCMTS@{2|t*0XM2R> zle}+SQFXjQl9Lvys}e2j6M0yjh){@mcK%Jkik5jY#ifonXi0qKZghjSOo7mJ@3g)X zt7CUEc+Z|a@sP?50><;C>v&5Lc4mj0iz`2F)vq>qkfT9S7FO-r?U`T1m-9t0jSsth zd$)OYM#A`3Q;OF9u83tHRz@TfT-K;%zEiwVW%mPj*k%f3;So2s)`d5z;SG(M3)92Qa9B!o_5$ zn}Jcr>x9}qaa|TY?$nrRZBsQ4WsV)|5#$O$sf2ZVo!r<{*4p}`DM(84kQP-k>}-T? zxNcX5;xVI1Oyra`62VN7s5>M%Xlz;J7FSQS(T~`&;jO%sE6t)JBO=7up4Rro_+FF} zXo00Y06#}+To?3S%$C^|eJGy5+eIcp2d~{Lbvk$>dxTh^dNO*TL6xo^u$0*v)7uq; z7}E!f#jvdHCF!)h(E}KZ;;hWw7X$^W&)fmY9)-&+nm?^D$Aq{8q*Gn6tddB0hATuK z7wyH_J9nmbZuPOEy~6zApZWLNC;U;n~yWd&3|4ppmy5zjw$s! z5gTf%v`BA>^Q*U76k9r}+lJKibRBjUa{5T?YAlbnOlg_Tc6yBurIu|l7cp{py8pKB z$zh9*MRS65>sfR&Vn)`A5Clx|{MO5v9-a>t!kV&0B3WM%tDJ70#pN37VYG;GR!_z5 zXfSZ#p|xK=`DQ%f1hq9FNu4|KS{gC3K5+?TvyiTUld7o6WO>#n=2 zk}!mWkaOEOkJ+bsUS)FvT_+Tu>UGm$ohov-wl*|CGo3?Vz&!^K-i5T<=O}oZEhB{- zbX0gcCa@qyq+~v~`Bjk8|EN_Km!@z1RJ7nWr0-N_;nkbO6iN-(AIz+NtD{QKmGTh= zxx3rFEMpRU_VS5Ti2kBv0qmDtJy$P;BIZFZ6DDlA`KXR5t%PJGNAkEtL@mkl*CX+i(JpX;8nujnk&gI&n{~>^8P_-BMfsgBPUo z+`pk?*Lp%mJ03`#Xm;?#@LWW6{Rk4jerKK>Qdra9kA5)qZ!N$GDsrS!zVe1k*~p!Q zwVTZ;itl6-n=$(>Wi?-0E$n6YZx1(hd<6YQj-&X1*^i#S28gB9jS)i39%fA*937ZeJUheAiW9=RZf>5tx#B z!2MYhtIu8TYpHZWvHBL>)c$iDIV|h@S#E=+|3u@h3;M^RD6gK_`dIfq$? za=CmZ!WJ)QT2=pCM|-VFwQ@JM2ji=O{j2=mPdjY>4_*rxpkTVujCNE0 zSFvC8wn3xK%{wtiUXkaDNK&#A6b0^rK}wG}U(J5W-!^KqmEn}HAJ`#7XlfiEgNc>9 zjR_susAsF`e#cVg2bSK}bO8*_)rusf8Dgk4n33veLxuI>X0#oc5zcJ1o@ddIiTokW z)fsR*kFN~8546%cjR(tB4PB9JuISAl1oitPT<|0x6X?X_2Q!&Cq&?c}aRGx?q z8#g*r=JP8?AJMBTAD?;vHdX5ww}R-TB|HfApws<_{cb)lD-oU0|DcIcJ43b;&=kEj z;h6IjEIq&<&|p*CUpLp_y4=9VFNy;T{=|Fe)Txt#hY2`ch8#i6lLg>-V3oU80q;$m zeOc8d?h@9-;B2~l39ju-(D31t)mq5jwn&Wr8BW@!En4_c=e7kUJAC}s&ZWDT)ris~ zpS5$n3}_>_w!|mYJWc(Z^TBEV!L_&>G59k&JYi^R8+V8gepkY06pW~nzE+jlua@bF z?7Wf^Erk(zzT}j2f>u-{98Q>FDxU0Ryv&Vg=wxi4XNSH#wAh3hn0eVdk7j=R)SCGd zKjZx%SRwAzNMYd-uAEu@qT&>ilrGd(Xo^Siuu5FoxFkmN?@*{fem1~Up(yxfzV|-b z`yxQ04`8L5BH>*~rTqRYMq=HDUzYmwL){bQLpcwk4jvTYEqd)v6!Z4?JInw0;Qx|- z={uxDn>GxwiC&D3A|aqpKLnR?L5hOhemzyZWaz_Uo@3Mn z!&wjixEi5@ByAwFlrUoCD-D9<-N#Q)Y?(CkbcfNSM?;D1?^kv>$&sg@0*!%O=Kz@# zGI{{uPfd|BLYa9PdAaj?r}ZKqW9mX!nqnGTBdj zlyvfxQK}$f~Ub%wjZjY0PkR#NGl}_Q!7X1{w#Q7$v$-9;|`zuXX^pBv+$aiY_3f6KdfGA}2hdY$qutm~mkJ?fAD>~m}S>1V$4JxUT+IE=a4s-o%A z%RRfL*-hw{Vt1kQ3%A}kn-2}h8FtnAWgn+!Eyo+b&>c1P#`0?!^G=-}zUs=Ch)CCY zZYDvmK37E+FD$LBTq?GI_!>^=vVsDdkc_U+r9tOSlDE&m*6ZS4|>F|{Zvqox{y zD^L(Mvw3o#Oi_&~Q>R`k?DFcB%54fjaZQ(BK&92w#3YjQXe1dM?$XV2kt-FoGC1uCwZWME}bX8cj29 zgOV@x`61g@F6320VznF8$(BZLg3<%A zc9LV_SI9`#^;DNbh$}3ITC7~^qaUkZa&z7MJ5@cjUp;lZdtyl{Xwv8lv95sW+Ac1o zZr>U|PP@A6=9V{gWBkKr9*Z7eZ*R3hg4g(%L-Z2 zZ3i7E%5QCzmxshfuwiztDlBUPB;#|GozYB*MDTONQT13i=(TuCVVa(^(bC*n&&`;T zx!hm5ux7W3=eXHz+5Alvl)XFreS{S^Xo?LMpxf($R zj);4=T;pCMzm~C{%x@1w?(ML82F*IaFz)Ug;D_(QkVF!6|Drzp>b~I}k!oVvY0JT8qa30dH=%WPAtguH1EJ>_C8{k7q<8OD^bo$Sz-QpXs~ViS z;Z*S(X_~e5^b%5RU2mRfzpL@wUAu;@u5O4O(%>1yNHkz5OhAUU&Tl&`^9h7d+=lKy z*P_&@+I@%nvgs}}Th?pbPEk-*Npzm%Ho&UBreUkCurWm{CJ_R3x;Ye{5{U;bAM`BS zaU>`*18s;Bf2dC{Zw6pDn>qj}JPHs~D`3&Qd36;8sR=c!G>y|66^1i!q-vWxGtY5V z5-RWba!`t6;*rK>2Q6?x-pvfc2EKRdoe2ByxU(4KCrl$(wXbCNDBei<8{{!p@Bwl^ z%z9@iPbKY=M2}gBI&|}-jEQJwe|mhh$IR83NZNT+3@@)(#oKhnUiI$w5BmrdX##$@ zjsJ%lblaG&B5juDNLY11a#xa<3Qw(BtuUg7OpASY%=%S6y2;8QIYd$S!R}r`aa%Do1v4*-w{FmtLx^QvJ4@E(Lol@-L z_3I(1%oy}KVmYg3=OE83p?+~Vl0{h{p9KL4j@k&Ys{Z&U^Ho-4de?aC@h7kkgk>*h z@m9Vvo$)!YWJ~1bw>WMdGsy07+<^ll!3uTLp0E{t=O%H-`MlwUgd`{Td3pO7GhyH! z$FQ8EDAKP9bjT_dzl&|_8B=4;t{dsO7nCTE`{upn;O9BF7K=Px|7hYkNfo!iHZaL? zhq-oV`fGAZ!>lF$War!)5^GyaG~$ztEq-qj&hmOvP;FG*@=5n9GOwB|CG_v`Fa@AW zanPy<6B4GrOe11qhnbm~BpTE)b*$@W)cbBn-Q!rKYKcAAtm8<#j2AbMj`_#ES#*HE zmA!1;=R5b+y)W;bQvPn!;nnyt)S`r-=Yp!L(&Wh;NQ z{&FmK!wxaf&+~sTPJu0)`Bh7X=GQ%BuB`#dXT#T4SAf%P(Ig0SpGSU3tn+FjF zZx%)alg-V~aZXv>r34qrC%RlNvvB1aihC={jDz%W7>hb71{*F%Ua-9#buhNXu2-u9 z)|xqRQq#IxUq6&KnSIU5rsiGevr@#?fR^xa*^3vJIAV0ux@%mgcuPnM;x;xDf5zJ6 zD^aOg>jtY*<1&X}&kVZa1T%SkdG}m2^KDGw_U2 zny>E5xcDLdez;h=dL6alWpkDlWp?gMXca&SR<}^=R+^eU`p>u7HKI&aoanYol@NO| zByzyOBvn?{Zt%m=m@mS!9no1IWT)GX8s+O`ymVdMZd`I|P3so4xOnACjMUI@Mi;ZQ zqn$dGTW-nf)2$l`T~K1-xs$q0b`7MoLERHt7-<TH`9>OX`BU@%s*p z=b)~yAY`|k?Pc$x8hQPG3iPKSaj|q5Kh*f^9^bU*1SB|BENnqfFBoq4JhF&B#77iD zh?ZHZW-R2bA0M2<3n+eL;k`2Hn33BCuvBWiyNm*NIy%R{vV$JUQo#6Ak}SJ6BaHXi zd?L6Exg#lg2FNOb7wpwv&Dxf-yq9kVvkh#C25Pzt>jke;C##s*)I&XP9U1ZTPBSB$ zZj8{eTl(XV;z#9xKfupx5Ly5@k9EOZ8Dn9w34E@P*EwUdCs58^;9#cyK-0EXj(v`6 zJH%SFKiQs4NV=G1q3Ri{LNqH!DGl+3J9l=0GSBC(mb8pz)6C3ji9<{@QqXs9IkOrC zbQkB%lt&jeawDG3pZd+FW3layv+>2342`T~<}X&IZwRu#WEgVj=!mgaX=Nx<%@i(z zBf0L{s(YzY5ttHp*=Y3GQhwWs8iTTLnK zn@6`7LWAw|#L@2K>afW=ud)C*YMJ7MALkOkE#ch<=-}qo8NKX1dR#JsK9$)c$0vHN zX?EDHEmw0>MWhjPf0fc(F{F6&eU0L(@u+oqtfxXI;_kdCzfLVvl&jW`GvO^h?&@OI z;{B$;_*Znq@=~~4i?$ohwQ4?5K*nRsQzx`N+FS$Opg%p|S;jfT5_%I?%l(OsxXZDz zE>^n+%{Z}Gjc#RradLZ+4sxO*7-_`#8JYV<-2hDEB!=n>}4=wcrn@`yNi=y1RCb+k+U14dHlt?aAy<)R7|cLOP|ow{&eNf#B*g z-d^`u{7NninB}?(8X|Ip8{-GB{b1dfx*A2sYk{qm2RK|Dw8n=|i^1q4id%Sg(Xo2| zddw}E1wRttAg$3BuzE3N`+7F)IINx6!rNqc4mL5-9dbNf-@SC-w?DeWLNn>QQy9KY zHHC%ycyH+5y<6VBTTW{4*aI2;V(as)#&u*y@B9~rZNml}_m53ZqUa;>SO!7WZK!!o z*(v_1MX@GUTa+`b!zDyUB4Bcnd|^C=g2;-RiV2BztXJA*fE=92%#>-0z->NMA7a{~ zBM;QnuSMeCh*6`y+g<<9-Dz=&L^b|$BE=gOJ7K0o~k^B3s(Ujw3<_G;xq0pRuo z0Lus4lql=j5xz8fm)}Neh9$dmu4ZMmQ!uBGS7acw41uw<9Q%bKTRFfe61>h}L-i+I zo!gA1rHKIK8~VeSr}#X*F&;8WTQD?{kb|%OOd3Jus|j73bq2i!UKV+ckAFID4U~?J z5E&@mtp5EoR?fX~|JazWwX8qBB6*@2q#Yii)3|(NnnjYzMc_EpMyQbBze^QVJGWm)zAU@$!(;+d=hd`nD1;E63*Ur9{8)Q?BvZ zzN=Ui7O2NHZrTiA`KBx0$b|5=E{PB4-!Z676{T9Jd_=CSq3oPHihF;Y5|^54=dx=A zLNp2SnR_ak=?oJUQ9Ser?c;ibp%(iu)5et;*xU%xi@B6IUwh)*U14r2D>P;kFr-BB zp#ow^YKB-6+_(fLN?`mOE5{-_+umTuMo1>FH02RAs7=ax?e(_aHU;r49I z`7irbD}uh1r>+cwkpdBgF0anLG1!JfWZ0t&4<_% z$%z}`2a>}@@@^R@wA-_@T8%j(QwFN_6}|eEZS$(zT`w&8fOtr5Qu-Lt*-97BXH1G{ zy2R7dKGU_kOXBPKcdj_EnLg2KgRQwa`2kJqO4gEvH1uTQg!P_zYB%4+(7?JS@uA$y zqG&b`uYFZ?2+oWVxj{cJNnFZSq^T&KwnzrTB#=ZOwNz5&CK2|qm?_)45J3d^8TOBg zU7*<8dVE6ZwiSz*FjRP^NAMcE5ECQ1=shGdiDn=TJN({pFC%vBIFvF(&6+br1Q!z6 z#a$hXpjA~AJBiXEhEH+OoBWftN$=iPztf!9dRFUM4~SDOSXKb^@5b?RBTAd1)E zwFvu5JJd6J_;oAU!>&`m?e{1?r&-W&ujqy6mBlpe#i^cjIm0UU(fpFa~8Y#R;N+QRQ(Wo)v2#vz6sE;TE3yyv#Cuy><-_l~~e5q+gNxBPdjS54ZuEZPXiQY-F7 z7Z?nqwt3}Q&-`@lrY~Ddog-EfaTu`L-!b%trc0(B3TDef8(^M^tWwX)b=k$(uz&%N zZ%;GKt6s3hxc?Ks;%SFR@492Y>u``ju^_M~-x=EYFF!Y4yV)?~>hdBzCA_WKsZ;)? z?03N%@af6SSP+xXGYv>NTC!gf*MolGP0r%8bQ;3>urZbVv91>!4^2wwbGq!+Z%B>lhz(%q5tedETtgoL|T9Z@gX`^AGj3IOv6cwJQ$=~qroKWL#TVAi#vg`mMj4! z%A*9(U-HNt4fO!CSULE9OnCcP=1cn=zC?el1z^wckXHE|s)1~`11LEdgg#BRlTx*0&G6LF8?6ynkjiHy`;mWWSU zyoCsca8DUd%9Za>?Y4DjjUT1vK{^b7Y&FKNH&fcTepVZ0bpt%|!ttSoJKgQVQF-(zoA+JG8d3Sos5gU{B#& zcVXY?4;QQ|s6( z7b!qPD5iHWZa2r#B7rP$q@9}iy9LHK2pQA$?aX*m-uDwEv+hgPjuMaa@_3x0bqUoO zJ3-$iuxE_Nmrd!@n`qboBoH|V6e3#j!R>QXw+p6SwTdu@gsLCxFG;Aw`SS;7yd^*h z!03=k-nBW&KpxRV%}=5?XRBWhoRcsyFkDZ{kZ~3xcd2&WS>T@rtsw_e?@~66- zj<-%<`xSnQ=Z|X>Vq({rDa7My;#iDI1TFj3*X$N_p?(g-;$e z22S)rQH$iWu~JD2_+EE>*0hF>hhm-rDqp85Q%o@>Bh`M*Jz9z~GEQGGZW+Bo2994~ zU}C}7&YPElZ0TV0?cue$(o+Ve!_Gaqc^uo4?0fE&*7>|X4ftjzQAjic8h>NSE8-Y; zp_G@C3&qwFpjf9IuRR>>BGCYatWok0ewDR>pHT{^AU<$9HG2;&If{xjqz}B+cJ#ej z+MFUU-*9g%r%p;Ku)f2cC}Wkldo)FcUj2tmTuKrN0H2u$)TpIBD%bFLr~$u?cN-XO2w3o;d#FX<0U>wjv|b?%lhG{F#Crf`#SnLxhgquFHjX z{|V}!W|Hw1c_#xxKf17;+S%TTI1G;ee(_&kHOi=sELlh-Q*$~}@4X$G6cFd&(#Tf; zMY+3zelEUsczW`cB|&TK+lxIGL*aTdE~4N|Wv~XjJ+X2(?SL9}(uTCOwA{C|6FXz= zs%;u{zfK1BTZ(=;&?q(Q0;?1_dI3QxrZiPGSWi4(T?l#tlvO*XF{e?+KtLe6PH37G|2OqvzbI)?==|mYYJZfg8-c z#2LGCZ105%`UPXFQ#5~uhUBWJh2vB*#K zI}3lKcWiJq$>VZl)~c!oToy-;9ZM*1uc?R%4^@7Sr1t;GcrTFg zL%!j)qM{rTZ{c5rV-qz3zo9Qz3#uC%?qjMn7gUup=d5nyc7B}2a-E3zo2q6Byanmh zXUQd?(H-X!*l~CVS{-v!Q-%3R-z%C77Lb;ook-<&BxEX54BgjSpVKa-WhAE@R`Jvh zP~ekw(LtGoMS^S%8Ro%fn z*xuU0>8sgI$V9x}nFJ89Jxb8pij1D&WF19upk`OydJ;8JQNGM~{X`6*sX51*_(LIc zVe|mOZ%l(#R}>~ohJSt}JVLrf; zz?){UeTt(cRXf#m_jdQ`m3KyvA&Dbu3|_bxO;C(UA66R^leM_9QeJQ!@YPFve z!6G9SfZAiJj;>R23X-3_`V@OPllmgf06HDz`T>@70r^_<5dxG2IO70q`Uj#H~Npr=joVQ4Fb;8Ms~4+;L$KA>p0M7k|o=KjKv6%zj}E*n%?({@KqzZtAk_tWD> z<4(?q?KRq?9tdY-RV+_YlK~iNaZ9#7<57tX0_d`{_Qy4IJi1#@*kPv_JXkL%W?b@( zQtE3frAMz`mQ$J+I>H7ppik7iOJ~+&{;|)u!zFdW8|rwkCDv`{GGGIBC5Z8qf6)RJ zTd9UIoQ#{dH2&a0ALSYkTh;y*@&`&1nO zOyJIYi+qe+{}sX1Ep~v!$B-?f!>Bid_83q=RFAej@eEE!ze*hXa>Ws6$ARr@v;i@~ z;?mqkCo(dM27S<(J~^Y0{)~=i8Z>U)>eum>mghO+kKo<2nmK@~q`~2ozV~+>$z5wz z!AUl}BUq3GsVpH@5WMgKv_6og3>Lkda(~VH_V-p*^roSo`Ldm+dymM7%S8kJ3pN|@ zXi?2qN2+lKownwXJIqniZLb{7nv=4-})mW1mJkqb}0D zEO|+72P`nH!P5a&;6fs(9%=PC5Q5SE5F4Q?1kWr&PfGcwj{QeMfr#gm0-|xpVGZGz z5w-pL)mL4dL3ZJfm6qDd08rB1ei49?s&mqETj9g3+ejo*U9%pE69@L4S zUUdM}km1i+-@bkpOQ$l63eGWec~9h*4^Va}Qr%F9Q^DA{1ftay?JM=Q50D#P#$aF% z@PamydBwG>f#6u7QaOW@boPP;iD$RF1TI;}g%O^b^zB-D1@v?-Kma$MhBVqiE?J4K zaLr5HpDJniw@f_Sv!PA1uTn=j9+|bi@+~T@Ia}UWS8pV}(@9?nc9dcl*8F> zg;sXYqU1~X-hSA{ePLlfR15=52Uu-@BN#BVEgOk)&~kMRPs%?Q^!RG->G_Yv%`v6_ zvgq;qb|J}mSLMG*?U+&yYNXM&Z2-fIwJv#oI-S?2Z{Ixn9ivIDgX`J7=jzOzuwH(c zmer3-=U^ew9OgBMmgUy1_#Q^6z>!rN{iyZVTgtuHj}w@9>wiLh;@+=bKy`>(5aZ4n z=C0kWDzr$3iyq1GBM7cI;CuEQ+okHJ1924$EePbSlU!99F2^2IwI^frI|#O&77SkN zGUqbCxa%PuBjY!pcCANhRf-y~X+Ta;gpKE$dq;@WI!lkNarAE~ZMDv^^z_jPi-P7N zIhAlQwD&U?y}v~|j6eYRFU#$MW0#>a8Aw|oDIsEDCyiqT>YzOpNl92S8n!X0LkW|^ zD?(`QE864-XVxQWYPm&^Cx$+X)Eb>3QoC~V4RHFMM-q|lYOs0>CIJ@&bP~&>MEygE zHKEH7)x+(Vg?*yi*6P_s-i5r7MJ6koH?zOQuXK&sr+((qt1gYSu&9T3;5;k5!Y){6 z8DkrM1~meWV#HKEfki!&kM+UnP>BE(o~OZF2wsWK5%99c`Afp^&s2=FnY|DcuFD6- zRz;p4Xz@>iC7U?o$5QL)SL-}9ss{b)`IhdE^V9H0ty*Q9dL!`Y90sJ_jLY#n440`n z1HNP&m_&^UdIIH=joLv=Z>}stch@;fAG2FU7E4>9kLgwdjVWUlZ_IM)?k=K#8wLhH zH(#dLbk)(J+^h}!P*gsVLlI1gDKmaJJW7Gp+@46>3Nc-xFP8uw0^Y^e17zmyw-`Ym zU{W+}qRbD0bQkc4D+&J8X7(2FV*#4M!TNzbhLGjko6}z}$#c1BSE=#zFMsdwD2-eLCj z)R{9sNfNSs@}`uhvHuCTiu<_tmjTV1Hy1G%dI>eQ{)x3;GAnlYH*1st@ zcw(BpW_hHjvm^qB|HutVvEAbLcQR%D3~ocMj9+*fW`KnlUq&f+6)Px z7TaozV$JM}n1cteVTE9#8^?I|O1Rf9^u#bP=H`$865-4o?9wP{0Ht)S@DA>SxGD^b zDth+mlUyyuGgfT!FbdtjQjnwjuzRK%dD)ZpTtpLSDi0y@{TJo${mE4D!LX#J%t4Bc zh|qlau&ivXc<1x0j>N{qS9eUaM@=we#sr!`v6wdt$T2q;-DoXS(xW?RKY4%G{LQP$ z3ERiMO8N5TOBvvbGzwgzosj_%aJTs+PCkWWg3v<{FmDG;m6|p?Rx4axGpvS6g$3Gt55)Y zB9)z<+{HVquEZQVbSX^avfi5-Lg2QFHJj* zU=28gsQ=da2M6BfPjzh-P{tgciPLUfDIMQ)G1yRLBbnrRdNZEtq)kG;Fb zocwy^;6d{q627YzMZfcB$*sBW>&Nb-Fa&TY*d+XDvt5Em)V=TKfwHzpU!UnxhsGpZ zUzMA9kw-lSK^3@I*_$Vq#4AjnDSlc@?L|Vo zacuYr+C`+_pJ>-L^CCr=K7IPb)BNbsOO~YMKg-R_tF17OsIP6G>2)h85ySnNAltWH ze_TjP+-tp~_Qiedjb;?RrHhtp05rG$TqvW_6u+WT<@m$EmrcPkyANdLWU4>7>l?RR zCAm~PvPA2%>H`fmrtI!Jk5bE1@lBgo>YST;1;|EGD2tls(=65JBQpd-TO?a#~mtca| zFqaos1Q!yuFHK9(9;SQ6`~HpeeJK$wpcveMUy4`v%GDZ=k6tMp^nCih_jhlswlDj# z$V#;Lazqn_D3dJ9yA`7@<$6DWNT_6qbBg2a_MRC(9QL@Z;(LiNNRC?8tH7-oN%}D= z#P^vbh*EfN-ME%AbL|+L^Z)&MZse6>`x+VXK;ML+%t|U0k8N4B){|}8ZiTHzWt0@vV%Ieal ze-JE>*_cd@n^qBlUil1rAO&*h5A=WlUJ}Y0hN7*wm`yLU>^VfejwU#(ka<(~2?$;@4A|7PtX`VB7Qw`cu&uH{K{j877sCtLgq<&StUIliz%lA*1Yw!OvgZ@C}*R)tiZe!a> zcUmQ%lOr!(x^$5NlM-2uf50{Yzl#&C?K>K%E77nGHV8M6k~etu6I#^z-j&0gO8Tho z9(zy3zjEP)TJ$(ePo^?&7@0LSXiUAd89;-Orhe2W`cC2_$AgUQVKb;muw z(FB+~IJ5#`M5M2Y*SYiAV)`1wUq zb~)%Z_cy2iHr4|22-4L5S?V3aQ=@pSmn@YYznq>N=FX|jpr{7=nE56$tT4Ol0vb(M z@(LvzZ_=)~ZSJVb0NO%%D?pgnVe))0mJzeX64h2jvreboT4$)^oV-!VAewu zkc&AwKe}y>-vYy-#c*hXs(oRH=j^?Mor~EK`(y=h4t1w4H(B>Jt3==N+(W?w-M1U| zH;!)f_&0Tf+`STAqhC3b$i*t6fUG5YXE+tQVQk- zp6pzBJL-+6YQc-R-*t9Jmh{>NkM#ZFl$pOwOPd?CW-gEKZ}e}q*Hx!IKob86^eb?G zQK#Ij`M}&sZ0}mu88%s9O}XWB15X;)ZKUM`NQoGs1rX4+qNLsHCX5|>7Sg{(KLRx>x&s?J93o8E-4fryAQHU)k^)MWwq&~V_bW+%Y-{=? z_bI+2@@6gmO#D?8)`g3>1SE2ir;WK0zi6G?xY-jfUZ(n~3zcXq|GKVnNuo)mTQH)!F3PignA2e;+ zZp%JICz+ij!WO{~6M9t+8INt;QA@V6GgWp?EPaCyfxx0a~fe8&bA*V}V&M#tqM@&^731e`>PdZKE zC*sn6jkowh!xHM(vkd%1^gvCpC7q`#2*PDs0gY<04?mC?bDi$0#t1zN z1t>m~{hUVf3^`v@&~}PMQsfoN1DJbChV%RoRXCKdXl79MZo)B(u55$km;#8gz)$uI znQq%l{0AApp3ZFY8ZW!hmS71Gq~>JQQ66cKCyWd^yo7gyGFd=MvDk`Qm@WiS(-}HX zfg9j*I#HD?LdYW81eAy-?<3pi3h2Ruii+=X!wde0fbl@(*rybsiZ?|$AYD-6}$U$W#+B(u3rfZNn2ydA-LdPa}5A6BxMWDXR+{=;9N(X`zKZIG6+ z7jRXK_*7KfF6T}xDXl~WaDZMxP)3?`HA$}ly^XDOee@sEN#zJklnl3}*fwQ>QGjj& z&S(fdN^V9j4>twqL<%vqu#@8_^CaA7y?Uw=IYgnF)qyC72PajMq0>p zUC*IcdE{?`jgiS>UqVm<0#k_58JLC+E9;UT*|bJnYbiHyn9LXQ;6=mODU+ z@GWV7LXUeYTsI4n8E*96{ZD&6kJRw>&^RxVro&1}3?&uw+ud2!D?>|C(p?OU(&7!E z#-$FY7LZJAN}bLoCR$E0v@X!wF}EjxE)irYLm_OG*+}9c{|XH&t8tQEM;6?b ziJ|wFJ^tm@DdbUDdV>lJ!u|`B+-A9Q*(n`amhxP!n&01WGw~lF<=<{m`E@pz*tIDe zXh(4h!JAEHp`5`*TdrKZcow(7b=Ja=Rqw_;&7donHs(lr`bL!IKm@|Rg#@Tsx+*v?vhS&S zMGY6`Z3Jj<_+VXVU+oZe(f@7gxVFc#b{f)4L%0`hFRUevv~;r{Zi~UPaBm_o@XbHw z&so|P&O#Ie6pN^;qi8)S!qgNARALYV@bD}wfD*AJteRhr^B;)N&<>79bif>|#-yhU zkwEJ>Xw|zOGHr`PPKNi5NN6(@ezRO$Hqb=YQvMk(HJTB6bOlu2`K*<1 zMW@1Xc7_$n7{VhdDIpo@k!yD_Hm3A!S8m6>sh%DyJb^Jc8|7+|X-%Bai~FZL!ZDz> zOv)}L5#wP+g>+<(p!@$n-rhW{$9?VpzF6i=$&kz;2_-5rBxH&PDswDls$_^llnha% zSc-&FG$Nu}d+&Sieee7JJ1^@_Z$1; zjbPqi;FLK+E@`nz>X9SX%cf2HYH(sjCCB=o7cbV}+ULRwu|A7qrnJ;d+-vSl)o(e= zH6elA4-P980-Xd~wZ6?4ni&X*Asx0ccTcAi;Y_(5E^Taa1=p>c zab95rnLcF;UoCbF)S<`5sa#^(K@A*{{u9`NO6Fvm**pVyB{L-KAB7QbjBrjDnLBI6$=>Z{y9Z^B?_-8)m`1=E^0DO8jO*^}C z6jl&T621OAWZLE8Vb6hY6Gu%Nz?hvISHh^Pi(E>45oOY>yk{<`Qrh*4eXp2}h40&0 zOtL>5d-7x`0JD{-j@UO12=Q~NI5}uuI2`x`A(TylOx?5V+%@O{WrOslsV|FGb3o-5 zCY?Mv@vjvgvu+=Zv#{&j#Q$kVNaoe69gud5VvlCUZpFiE*EWeo0bF;;lX}GuXVL_x z>+@EELqiePL;3%2@_j@IVQCS$7teIx>ilUhe?q!rC615x9!@YQrVesN9PC&oBS9`{ zk%5m%n;c>vcI6miJPI`@YH<+7Ukv^lK6nvFCK)x`bO}08yIb7j>sCDF{$4vdd2WYy zuS_3)9=7<@4n7zJL6DBRv+y7@SpIfq@f?eQt8s-f31p9T;#>9V*^@7E*f~qA@0zx4 ztNZOfD7VHFv>~E1W(9Q^WXH4`KZISLS5fD<%o_ognghO8-SodOPG0y3QGP0J?Q&X7 zh44__6j-sByLqQSob?j^%V}URQ`;)1fp-bvHYshvfO-CAw#$b?tC%1zkZ}z5{YFOb z4yjwG4pQ0ha9tbkzncp5x;>5VxV2i#mZOxp96xS{M?5r)*Eozizt_1b|4>Tm1y?PF zdS@#SB_{sX?(LOUOB@13_G>gq(!3g(e5UZ9n-knXTlGxp%Za(2hFRD;7kErIhw=RxQ+%-Y9>ZKe(6Y__7DOEN-iyfC$JmcCHfH?Ti0vY;pfulX#Ct32{hi z=I0k)#s`$T&o{zw>zw}t)oQrp0(g?qL&euSsqbek!%`9Uh7sq}{iQg;^jp2W`9 z9pvILW_UhE5@4LLAlCnQ6SRuG1ie!0x@;JVlP2C;;~u`E+4)0a=qS&fOU?^9xuAQS z{3}N%|0mqE@!y;TOwID!a!b{;PCedH0nfaW*L6XgD-3`fA$f~I0e3S}9w3B`8jBB1 z4njGG4zGcN2k;QucFAIaKTyrb+_+oE@AYQWjLyo8p576;>-1TP_MGy4XQMSxte;HS zcwpMLgf~x9hH=<~Yim`#o($&^X{mc-E-_1(`ouYNpnKK=9O>OuXw zc8a;HdAUb&=b@O}w|?Z;bE5W*J|5=-=IC^mg&CWkGje^d4$7 z`}#wzdn1~3+o<*4=G>~?rJsV%mWJgTyC+^4wa4?}f)n%aEw?|s*gord`P&@#Gl|ca z$Gd>h+Bh9UM$~Wi64g00UGzCOE$3q5y9T&p|G4;@ZsM?nRpI;ceR)=kbbo&SbaC#@ z(zhsJkW;0z**DSpM;$%dga+y|Jfn3cX(zQh8pS$HMQ4cdbvlz2(Z7i`0@&mbry~*( z%XNYw(@+i!PBJ>WYKpi|K!c4xdXugM;;v{Io-d>9C~voCOdyKVV#;oHbUSd`*KxHw z(h_Ow>LMUmUs$-+(9m%5f>M5!T!Xka@|?4ozIO?%lsb{WYTUA=|Bh*%qvqZoc75Zj zyafc*N8NUb5$NG0K1Yr}$%6$!7h{?IRY|2ay{@nCeZ#@DHi5iT!WraMj# zKzIC`0#jQU3OJ2j;2IbI9OZXx0m^csH)Vd(>DEmj=dI%2w~JR9Epa!Aeg5uMM%1Rh z^pDjP7OeHDsS}KET)CoH_n&RJ{+WmFAozsL!#lv#liHt&Tgdk3kHZ3V7i;|Li2^hX z>(O7(&8@7aq<{9JDLMV6;s9nrO}(3@dMsHYHE?jj1Xegita^R2h|6%PSz$8zZKt5R zwC|HY|3vo@plrb*K>`SsY^J>-U#6e&41pzTX4YU(j$gkZ$B*D{h&e{%w8}2dj3d5)&j>+i~D6ksTgOtOYVS0(0 z9=9lS@k%GkA{5fiT)2dCq??%mM5|V8I&6Pxym})@XI3m5A;YzqxizW4|MJiqCo@cL z-znAjYBkOA+}W2pxbra}g3lq!xSJ7!BvhXIBG|ih*?mS*SFvk`cedA~a$7-h=^N|b z_It9*A5Yyr^1kt0FIR_~#_pY0@ zo|VE(K(GASo{k7(#O_ON>`T2L^w^TL&G9+p!4(vovH`RQ4A{+sShr1_Hk&BXqv}N! zZqrh*+US;y)v?Ioa6`K#T54un_(x;=D{-Dx!ebiLxTOQ#Qg_Rz17zGsPa8R%DW%uz z^R=TK3ifl!L8Z1r6=^p^rXeFYy$1vUV-Hkpe7A+iK=pXVL&~&ZKi^ZG05|e&DHT?Me zUg8=iqFjB$;$0!b*YKgcu>CT@&Q81zG*0V39`*e7yJc}Z6K|F-S)@C<(_gKF<327O zt4N%Ax?cLpL=}g*09|a1nDcjGn%(xteEU@sU8&7*3DY9c-}ph;=U7P ztcv@oy}ghg+fJTrPC2N__OEUVcj{oDL0>#|BM6gau8pmN-S%?!`kmbylU(l^RX1gg z;+~CCzq%>x;Dev~H?RnV=#~vzUf1($&=UbHb4RD`Y+bF&&zLG2VeMYYe??yEANTRn zc`^nxNi`u*Pa;CnAS3g+Y(#lD4!>FL-Rtls%H$d{DXv*CKW7b;Kdgx6Ql&(g>K;iV6svatPuI z@$ZC;#{9g;>Cb!0Uabl~;d*a4{BI%SX44Xm1pOKk0a(i~qgZ?R`+NgeJu(PBTT=Zu zYudDq-m2QB0>jgi*ZSGLW$ylzh;JKHUw3%+c;e6&o_Y2)#vX*I=(4$GKXn^X6nUXGN!yOF_r;SHO9Og1&A0F0 zi$iMhY#VnCjiseGc8xfE_DjOaPWe^ETFj0my^Yhuujhu>*DtuAocw0!z3-}vi-%sn zl(b&=ecY)!QS-a2t|(@qHY5_bBLs?uS4-S926`rE=B|YLmi+OJbpXYZnj%5M!G+CQ zEJFa`H}YN0w_tq|K;3`F-WzTH+C0#hD|JKtmP3>>)^gPwV+?e(u&#%_MPQkZr7y>n z2z;xIZLwR~5cVSPFqZ@4dS1`q_gtpgT$aJxBUtj>=i&$ZA!BcO-&?<46!T9Znna(v z-fU^*?K7{JLR8%t5HRmZ@E8E-g>#M{Up8Q7KuWDDiJoWIv0e0LF0gI?YiY&B}sU_j~d`gRj0xa3c7mFBk?5Jd4osaQwv_u9^vzc7NW=pM_p zT}=^G#r9{KLCM$&i>jxj61&qE5xMZckXC7*nQC7j+eOiy5O+X_zYYO@jvHfAj)p(! z@c%6OIZbVAnd<;o%M?ReEL=L;8yioWy8?JX`Sb4GNpmp~ezmalW*gCV0E-Rz%2gOr zFvr=s-hu_Mh6kq2a<(iDy3uv}_QtVivoEi#aJ&v?^d57Hx&D3zKi)HV%1aYGMu|Ik zaNhMTEgiG`LRH#1=mt8aWp{k`c#lzwa5$A>205?jY#UBju(iMp{9^Cq3Nc)y`bcwx z9Mz-{?!ZRW0v+17R}|}M(;Avq4tf9N+)xXwrhDzIFSs05RhY5|34n7eY8Y~SwKi5v z61MKyvzZLoxOw!}6Xzm&wf2uqNJx0-y-}q+&965T^l^|v8n%&0z$C=BqF{taq{~`d zvOQM-MQ|%f1{c_qv;pg>Rz+H*h$hnWT}Q2;w2f+tkfb;LVB#c(0qD9r=tKmm)UR&_ zED1+RVfjbT0`%E5SGB)NB0!;9& zZ_lUyZ1Pr?Ba91y)RcvIaut8t3YH_`mc)&wuc@i>`W((fI+ZO4d7m!O@AV*j(DD5f zClA^EWk|bs@j?3ZzPUE;5uJ-KuWMDr#ireV!!-%2a&Fi0)!k!Vr~|;dew#UKR#n6+ zhhq{YVU60gpWw?f0;;=^Md3kLi#u~*F=7byp1&(Tg{Q_t?BEUwXfbVBHDEkiyWgnj zBwHus4gwk#VOxLxT-JU?K+609ZJD?n+HT~XoJ@{jc?PKqN?xGQjo)Vs*42UL+s^>S zmB^FgE%cX13c-a~;QbHX4VD}QfSq?eeBhMNr`<|2JzWlPI*36@tY4hVwQcuFw&I>r z&5wY%{`T`Jm5RkwXmiFj*=Kwyr?Hp6&Ga%ylMng;MgrWvZz&Qq^`R?Q4tTiiNdrpX z#Q32z0#cM4<$)E?nvNd&zO$uQWKd<^<fAY1r`w@COo_!wg(~_9XER}i&NdrF z9}9bS8q7u?XofZ$ZXJ}IPcHU98TI1ln)u;U#4t-t12(h3q9C~QYSxd@a>;v1d+hSC zlSLZ^YI6)fu#v5u9r3G=aOYU|S88ckKX6cfc)=J(*y_{}7Hx)agYkEnB_k1<0JdFw zsO^f_9(I|pK;lik1!q1qr+Yb&d@#~$zIJR_V^uMlVQyBX99^CBu*VT*$m zTvE|H?SrXtUA2w?VKP>up+HIO&!F)2X8G;rd0(IU?b>zkSioBSg6bmtcCRx=<&5Wt z^bgN(@9HNRnf$5itei;D5_4AyE?|8}wPAS!fFMZQRHxJ3a;?PtT3$)4VF{;^Du3hi z=O;mS+YOVm8kE>>qp2%qnF*EqP0nb&4u}OHbzPw36@pK_@6=cldc;@^Ue>gdm?P|) z>xd_yFY<#$m93AR1xJ2s9&v$=ObEV2KfJ0MZ~LYDlizu>6f+iWs>_Q~cYM)x=FFK@ z+EF>N3#q>g%~TEbsL5pxiud}s6%W28XAB@4AkOu6a@L0uTeVASI#et*t^3z?#H$bt zTKmH;$Z_74B`wg*TE5JEE233SMO>_zjEFn2jC1J#ev`E}QDwrbrz0I49{+lVjOrYK z5G>kM`9W*cy?tlGCBu)CM!RvHh>Dc{-J;FLX-@{2wA#4KlMg5%onn9uD0XRGUA1*4 zFi!g}DQhe#a&W!PUV1j2wO+QHA{$VdJ8;qkdZM4N`-_ECOIGIGipIR9_*>&#F1XMS z+&`Mu?Z zDB9RhtR_i|$48+jU<8nzrS^^e2X-^6alo<)u|hSN+wwJ7^)ph_zWLqQr~8EJWi{%( z#{0}P&$DREO5U<&WgJEAB4e~j_>e#P;1#9Xu3aMqcxElszac}167bsqNzBw#x9Eo- z3QlB&x#^6DdF=V2!dJ-sP$AOOB>65fi&17ZiJ4NzzL7yxF*_C+?%=X_taL{p@$^!T z-)agZ{^US3j-la^{cx={bq;IkIA$NGq`}7@5G8K`0Z6`#G~C;vg5(n0+RF7_KvKq~ zCz0NCr?yVJus=U!f9iPMD5q)oHH{*Dt#$2+x4DIHCt?k&TseP!aJ+r4$?Y9BNz8Hb z=1;)yJ3?>_&Lpy^*4Dc14qHfSO8;4c5dguPnXv|?ZGt!w#if30(edOr`}9A?f&c(0 z5x7~$6g4#2UGlu32dWG8YJ1^pH&NX>RksVwAu;DW(iS0_ z*!nVmx%DQle# zzjFZ|A52KlcwmIBiNBx8m$Hu4O-a&9$@buDgy}o3e?5s@B~)sv zs&?bY{{i{}@k!@U>|fpo5IQ`yJ;)dg0(J)`sPrSYlOCd;tZoW3CYFH_1e*c$$Xg+d z3CSh;+*I9II2J@r1T~IO=XMq^ALllMxB;|6t_aM#$I0o*`R8{xj zSfs>#U;b^)39X92ZmClfa}pD8fQNP-#0lRi#N0QF3QrFczyf+T?8%jNQ36;#jU{9 z-92Ue*Y5u#C~Y2no*EMVV({76WmnVEdadTRfrYez2UYNf!YOx9RXKE{_4IiT0V%ds zm@o(v4xpPl#AKLQe+}QtNc;j@{H5o~hCh!*p448+R*Lo@h(d|`logwZH6V9z+`z=J z+)d|!2SL%4M?fo8?JLhfalU*oWAA~!)&7LZ0DCrrJ7HmYPG_;HW0B?Qgo~x$_3QO% zi-bYN}Z&L9jys$eNgS3(9-+6NRV*&tftj$_s-dElq}iyDq!F$qrrz8E<8&f}(PN-q?02o4GQ5t`xl<>DlU8O4 zsg1XdkbP=?d$RP(RRKOa_ioRmY0QJU9|m`WLr|y3a|WlJYjq>OVw|r8XVkE`>~Cb8 zKNIx7h7bB>UnAy)9P~|07Cbz?Q_&8ojY?iq5d-4r46c@L#6Y}Cz0xZTV&t6K;kR%Xl9UqXBBD7Bmj&kk2)Ho zvdwDph6s>r;vM5w;o$1xa^U?ZO-zWy@YK%E&de;2@;XH278Cv&KHyVOmxuI?f%G#} zY-TxhxQKEqUWu2W%*vS*`X1-_t}Z5TL#6<~R@=*&TF+J7O@#&BDH)#XHl@zxK;6eE zf0{qM*9Vc*#!Z{{3A)c1B94Z7j`111N?U4ZjH8<@2l9_)B#4BkDex1vw#dxSRI2`Z z-V8gs2t=uxA87Xry4Ivi7G^RdQ1-3PHTER&X*feilx?#ziDYugk62h-ox@-p+}&z> z`BZtQvK$ucWUzqI%!q08kMQ>r0g)ZcxEXGl6F1_JA9BUX9ZWeL{h{W6!&K#cP*}ry zU*3F|rw$jpl+I&#H1|4j}Zqm&Z>twzc|O-OZX~CrI>l)F2!`Co?^-f4Cufr z#NDmUkBnSM0iwfzL_r*}p4e&8s6X1=0%8M?(Rhhg64I?$y$Ke?^SXm)HT)S65=3s|DHL`zgWnZqxH_zfSz|h&0PhcSf_GqvQwrb$Fk+)?%lc#l`|a zMTNQwy>Lns_t?=I?{2m=c+x*2H#b*2z@>}vJd{$@l0`q9jG%<2mBC$Y>L^$iXs2xQ z>V7UYFd{(TP9_nKaFS~Hh$(gSM|MJ$KeXBY)Zmd2|3oV$Vj`pD)C*_ME*fvY;(?KV ziRBX2(k&f^)=})wuAKDJ&A#M4{oweoGcV_UTk&Dpsl>;&ROb8eL}{$_B5Dh6T-;Sl zX&2+Lzd_JqHhtxrnxZUos)Xbx*%y4F@eAsQ1**BaC2aok_9aFGe0#gJYf~5P_<7*) zS^0m5K8?~cO=$`x{+|HOZ(`_N9zEyX(~*lW>-C=;+ii^U)tYe z4v;s=vYAz%|7*-rFCgafw7(8q&3$G&1(abpUa4}D8C^;Z#DD@xja~TfZVMMG)~BXZ zCfH7nz_b(lrif85dTf5|^mx5DdvS_=_Z}Vo3I8aM)!Nf~)PLxIYARw$2e(eNP;@qt z3;+0lRsQ)qchuo1)UsZ&RUcFi?c@k#ko0cor@9C0-#P1b>NQn5icsu&hR3^d;)0=_ z$EWKxh^onRgPs|a>sYintMQf7KcIY@YHDfpHzbN z%m#VBucKH`n&c1CF+^*d&<;5yF0t2>Sj%EGKs6Zkq`WYto1|A14Qp3q$y&>f(LV8J z*#NGG4JWB^JwX;MMK2tA`N7f>05De5e0X;dM&;~w`mB~m-Rl>)}&nvb#*^Vp8D!NO`}`eLG$HPEJ7L} z`9|p$4H=Y~!M>n%3wdmJf)hNU!KEAOK~}+C;n!Yx_^|EIFSpOF`_{%}rTQ-$nOmMy z=+N;}I9*WWXg$UJ@LyKMNKF3s7Z;zF^~Zo~M<@5%8Nk`ksA1M07%hq0fA^m#Kk6v7 zxZfkPw=;s1Y-ZK`vv)>oZ5xZV;E@4fl=OK*H zI}5!Xc^_o)-Tn%}gBq_pnn^m;%%)fCFL-xOFa-40C{d-*e$`24)jqybXi+5Ip%ZY01ZlZ9?}AgSmVTc*7>2yu8GLcBWs-r}^v8KEzJywN z1&9+Wn50+C+ncJF)YL)uT;Few7`UQ28qf`6w1%=13$KR$hk2QYNYIn&M^+XHqo&s`I#w}c>&J8ePaK0)WPqH$+FcNfyvSa`sqgi1e?z;`sbmS z-ocgMR7*gvF5J70}`rg4TWjY*w9Cc0M)1*)mg}8m{5&dL3m6OR+&|G&sQFYXi{Ja zC<+a?l6Us-Q<_SoD{9BxzkOZ=+PIhHEpsNIi6v=80V&O)naEqmMIk>gQk?Z@`xRjUH5O> zjHQ6!gNo1J>Ntom0wiOfDslzP^4qgqnahc9IF#$xUU)^p6|KeVx0}3xg|-m)K+p^| zurDzX5vn%r!V`LoA(e+X$GIOh2(eadC}YP z&<&Co#6O9XI$owERWFtlwguyDVa*Q*bl%lI?AZlK&aihm9r`_WOU>!!Ug>199JROE zm@xr`e|tJJL3G5mjn?-K@?{60UZEs1cuKBNYuh#u_s8Ek=ssty`mt8H=%^TZHOb?D zK@PRvFSC#TsfX#J>^{iW>qc#kvE|O^^R<*4l)zr#Kh6+@oTL zrym!*=y2A*OuAC60$ECRSt6nu;Ph!VbuHI76x#wJWK5PxnIS~g)#5Z^UWG> z&4{35acXl%=3dgu07eZ)>x}78%Cy?Jgu_m0Pu{V3cs_i^$RQx5X^#}6(?%yVyuXJ< zWtb@Z))suMi#z}(R^t|&`|pFN!CKq=|GMD*Ibsi&twb)f^qDfO$J0;DjUpl%X{L(= zeCfmGwQ0sr(j+7Nx&;`~w|{@Jk8WIGgV8+BQx`zagkuSiAF|!$DC0{wS&v}ENCj6- z0nwI0Kb<7@f_3+PJb9N?Fp)-xsR*x?6|(uF%muN9;PTBinmmroT{K_0k zvGBMoQ7;oA>@3+=pnqb27xiQwd(iQP6$Zv6FA^TvxR4fdBvmMMO>I5BAaDw4 z;wY^uVUNDRu8_9U;4uDYWzfMGhr=a zxqzeo=ZjuVLF5H6q%B|f`C@24cO5+c?GD_b7dK2b+x+t_*UCnQR3SfB&kWGl#G7Cc z!xQnxG<4VA92LFidhd+zJ-Rzc%coqCkx-(D8V?rM8qyqFjLkpZHbLah%|k9V!(Iz@NK zHmWK}T0AADt95+}+qvE>&2KZoEp=+Nz5OmyvCO?$am=XdMF9MQrHI$DZRDY&NB_X{ zaunq{4;-u4YJ1_OfcR@|i(hGV{pm=-zPI_6rIvbKY5ZgA7_-BtvItWuG~q7=HK_Nlnvx2*M1>w*x1j5`%o|CYFL@BQc%5rkFx zzmE#?wx@;noRMyGY2wm*AO3YzV6(_I{eR=6Yi^BOX%&$6eMz$})>Eoq10qL;wVq=Q zWOUuRV-EPEh}9p4xIKtU^3TjP=c;S-Tdn$yztC(-34I5LORi|jo7FNk`8bIub`qRX z)Xu!pCu|9^hIDXn2sU5qU;ggoe`Ba`{`rNrL&RE;$CmMww`|$+y8C1F8aA{*p(bAa z(CPTF3DfW0J5}}EVq*VJIWD|?r-dUkDMdlYA}Uaf&BT_A8)&axyTl7W=V|NKD@t=8 z9si&zL71p6=YdT35l&mLn3|uLH^6>Nzy1FM$-I{RrMe77f9$@w#f_-tUIZT zW5>S{E*Pm?RErll4)t+0iY}o68b*oPVcXTls;aBS(JsZ?^n`H(6%_&L#CnU@PgKiU zMVaxf`MnX5RIpf%nNjIP^fQu1WXOx&S}aw-$>EU13?Q*U>I$FVj@r*~1wTHTvBFj$ zVKcBw=Zb|IdyHnOvFF(q3@a#{NHsZ)6`Yn2} z9OfhIN`zetnMw`-f+n`oxI0n0*6`tT4ukkuTUFJbgiqqxhVc1vzXx(OXzbW}>))mh zL!brMRa}eC?g5f5!|xhG*9g2~KkpejCgSoyr#9Yg8yRA9@XxgOS%3KD?U=FR^h>VM z8j{uoSiZ1;lqbB z@%ut{9gBHgOvCb>*&c3Y6I#3xcOYkspQ(KskA0~!<f5#c zjt3XLxn%n9JbDo4stIKw6rIruwi#AS{_#M&5f=CR%9UjN^*hOwR` zKUYUrx4?Z%K+>ESJmB|Kj5!p|PP{33zf`ohDl~0IzwXrKT-r&$rSxUhO`$P0E9gy9 zhchNl3)4U6PniD3relDi<4S$&-jF{+ROXtkI`?`xU76Yb%K3MZ9s;xG+FZ6N8aCVh zLDxf@`r=+~rBry!V;?|X8>-o_p1>+gryY9!}P4If61cOG54 z{QTIA3$>UV?XQ1ps+qn3K=0Og(Z4w^`82eFQy$yJMlu zASiojkyn=i4Vn=IBq`ibQ|lB>!KQEEve!O-BfBh$iH+Tc-GGShpoWa3H8r;iEZ2#J zE!0se946@TOqYlk8YRda(~*Agb#d!Scp8hK*0wFh5^#!A0dxgkHx5M!RxbY7862{+ z6wX>1r?$?^|1*c*&xL-8wH56VVOV1OqSHYb8EmC(+>uzK`O#Z+H82R~>!noe6Nhup z5BU=!w0|)GJQuC%U-4S$0L; zr9qY1%KLE+tp?PLx82AARijp|C=$?s?=MgWjvYV#qrrh$0fzeVw)I4Pj-;6j&!Uax zrnjF}v~OI$9=x5~`A?C#OCFurknpI6vAhIY)a=(!LyiW@(?I5!aVsHmzP~D|4`1Fp zweIgxpK|GRc6dlgO$A&#>_-{4zJTk@we^GH+?k4O-x!=i-#PFY$2=p^^&-DuX}z-9Ryh zU;-e_>oRxRK`|$xTIfPovTnx*9ZWaRgAee^lpo$R3{?Gp3@mqAoNx$>fhXiio55KV zg0mu;@+#8!l6EzDsemngJn#3|8tV8IjXJZz=?6AOclgrepLyc8Hda~i1{de6TLt=g zRhwmJ*Nk!dEhzKS^O%_};ki_W-M;5@nq1Y@&j{bT-D8ga-?+!;D)a74KoF>Y2uwFZ^@m<5l6Y9=2v`AjOAAWR%|o*#kn-za=W3JASq|0L>t{^fggKy+vUHmc zP6_|#=}P)iO2^;WwJYhhWk8}x1|nSs$wC{>ocZ4SemC&qGjx%~loYsvXwgk25m3~9 z%JKS4mNU3ovSTb-NxB2ciM14XHaOKa2BsPU9IeP(p^lQlua-sFIvlGVvD_6fKxpj* zg7^i_;p`XlI+Q8Z6nHUJp2^~9cL(EFq%NzO@+&D;F1ztm<#=x4P`^>55tMP*?<|C# zqL}{wKG;ndP}yNPjqVXL4^J}?*SSVvtZ>kEpLj%2Cy5%c)wu-N^_smhUH*hoJhyfQHFjc3^Fe}7oO6$s^Y<;@KMY#K*ky22w7{&pFqblpaw~D zV2cT=4+ROJf5Go~AC}!uJ(lx@A-T8Ej?**5@BP3ZNz8Te;S+tn`L&DB$jW)c zCKsfSlEfE$P^X8>+=y10@mj#TV&cbKthw$~KaLv0*hj}VQk?;&DxE&Hoj&)^%8z&F zn0sYrW*%X{&jBaF8F1at19+uu^o2L-EfKL*z%~C>w_@7wwG@a}l3E5K)C4S7yk!v3 z4AtGyt%uEyh=O47;t{0M#n~5RoAe3JT~GY21CTcW7^ws`aCToqFWgKTnc1^rvh_Hd zsT^Q{3Gw{(;Z@&Nn3K{b9?R~+uEf7tlG5Hl#;=V4Gac3QLJp@}Rj{p96;tdNXsoZG zfv7e6=I;0$Z(*%%EryRnH8GzGeC;qzy)hR<#>L~=b9nQdDQTq5!Y z)<=NTpDz#kQB7g4WkiQ6L0num3KLt2p(B%K%dTB2%4eh}k_V&sm}!dFEM+;;##)CQ z@XUx=RdtQY!_umEd+mhiMus1Sm`}CxJ6DM?81^j)DnI<+kkrku0EZPH4ignu?r(K$ z)u`Xl1b2FbXM?@9%At6g5qOS+@(!YU+Admp9a-RTZevws_Mx zC^7R=@(N!UKGOL5!DS=>FXUAT1V2HL7=%S)O8!fLygIz6f3d`*Wo3(KQM z?BaB|H%aKGBMr7Cx?wuv&q&7M{F<6|IF$Jo0#}q&yzOWdlorstbLW~+&xZs6UDFIT z3Ax5FHKfb7l+kchLKi&!%m164m9a!nI=t4{WfvPsELRHOJ$9ZIQDTW(n z96fk208b^0q3i2+@HflJEAE+LHdpt_hD5Y2@m6db^Lv12Vn%4u*y7zdw6AbFOZr-~ z{kC6b98_gCY5p?oV=76ST+gu{r|R*p1pMQ%MnegS>;4moL|tLN?DX^FHH={4JuNTq z`hF6Lq1Z|{Rvim4Nu3@6S5q5H`X#&3D$Nb}E*Z)@#|&3hRUIO#b%0fR@fNg#6lu*R zoJ3*H)D*}}*gbSxXa>y8AW2`ne0c*@D6NB+$sA)(5+`lFWI#pW0U?Tggs)3c+)7?_CS?^qSn;>H{p!q_fO}?UjPWF+1lk%I*1eLs{f4qum-v#ohV(sB^eB4*w zeO<+O-8x=4W1o=YJ$O}xg<)K{(AqhdYM8#vdeY*wA-FeBG{nQ*6-Y#OvTGa4iu;F_gz^{-3mc>xsJ(dQ!h7bNtQORw0j){3YP=8xT_pjwJ4KU)`_;LhiTV2{(vyn00MQb9$*?nW!AiAOK4gN&m8(A`kL7G)F#|N&rZ_}j58z2KY`*dF!~VxK53?29aR5coI(&G zlM$^U;h#`vsLWsuPd*^1h{cc6RX=Lel$e2x>d(L5SF*4n4z|~nNiNX#VCX+e+;*+; zt%E=eb)H+8n-AeEWH6Ajal=1K1eevHt2c8T({AD4xR@yilJp8#T>nv}qDIUH*q8)R zom}=NsCN^*pH)L1KtJ~f>l*hU=&4F4d7tVr(CwPu(*+1Gkz%85|dg*QgKqQ zxrgNP50%fWUeFpeo%5;BYrRcTHA15Nn${fKJ#>K9*d)y+H6!+BtRH32%Joc{|s`8t6LgBYh&i6dyug6%hsh z<$koNb_0!0x5MFx^2~(BbGQu&CrO@BM&T0(5&mNO;AmYyS2gqMja3C_ftI}PI7>nl z5La*C-qF2B4{`TJltbQD1lq8nlJIooAePbbA5v&HGa`Qd5f=;KMG^XTo} zJ1EH%ys01gOp#-nY<=8o-mH6c@aBp(OyK$96jIp~hr=#+>>tzBS?}DrkOel)_QgDY z&#@?~S)JC6{LM$7gW5LH(fB*w7IhWu=uhRiY9@rL=r7N+Wwa)l(mz%))UIyIR%}*q zI1?|wc%-NX>;xqH!Mh3|Pm?y**!vZY$LoP3Zhh?PY||ySV#{~eq!TAveDr72GTKVU zIWKkjZ8SwdYKN@XFu5>0^kmAUDm_R==eE*r1jlFYnC{~8yx!rhDNy-u(aOi8HK^f3 z7h)>>7MYP^$2A!6DH1Bhtrpg{_6NKEykut6qH#;d1mK+fzt1u%Zr{? zrzgWjG#q#k)RqCElIHnA2UC@i>Sg!gmy{bJ@$SdW;%a_=h|DM$54+_OffUcgI{j=2 z$>(D40s+WwVj$p|#A!Gmj_|9JIEFvgms?_67$KF(7E`9Q!q?G^r(I299bcrd)>ee%gLh6V>DCxdibR#B zCo@F7+otEQCq(plxa_wHiBr#mxjrIQN?f{VrA402U*6h3N=>j3BpQkj3^08499Ty~ zmhT06!?@%LD2hY}Q^Bq0k4x1}mumfdvCzN`7CdY{BCvHe>&fF5LQGS9xH^Pd^S4l` zYQfvrf$F!mj4t=oAYufMJpvdQ-a4OZ3+QbF`&RQ5`G99@yE_&Ccb)Cf(}~PwZ+ZQpvfF)T{xH^ zbJ~EMlw{-DARLnZHSFB0UJ@CE?pqvWCxjlSU6TM!GzDc)cBS)S`N#*rgSXk)T_T^Q zO==|BzDIaX3uJYil*ObJ8efp4k&)!yzH%Zi;es(uok!kn% zi5vPYJ-K7h?C}ND&RSegny$78!>Ax7oBOG$YuOIJ4# z6|A{3a>|rlOvdBe_s^7h8LiV5>U80KkQ}t-{(I=992Le$GPO4k&i9V8w9Jp}Uc|G_ zJ2Z$9qmR5?`!tDL4ukBCeP93kA$m!Q?`wqs6;O&RT1+2us!)^o3>bPG4dshbT zv6=E&FogpNL%R3UERgdhYo)_FItw}V@fIRmq_4aHmrXNo=%#HrWvvhhCIY2W{5fzP|Asud(gkb=7*t&C7w&o>@800|#H?&k>MsbKe;2SB*~H_CZV1 zOTL=9%GN`*GySF_gxfFGH->I9oTX>&^tL*Q!)FpXC88KH3UfWid`n>7Jd)^U3I ztO|;q732z}tC$BJ#^`komSm_fdol=ZO^Ppb9I@;`P;PeF(b;(;blLj=F6o|_&}D0N zJ2BR%?cHIshrPQRcq7cOH?|+p(#7eOx?(-Iye6H$sAe{8+LYmz25E4vi;EmCeOG+! z&h!HNx30kpm%o0rI_I0;Rj%V2KCFqlExr#z86*ZMoX55%*O1jhAiG4uvQ1=bJLY-7 zili{lk`%A>8!90GL!mLl_%3;DmwW@-dc(Un8qVsUIg=U6407mUVyjd#kWnu@?y3Sa zMQPlxKm6*t3OiSyD(Vd;mtC)C!Mx53+&Xwh*E4Si(b>5yNita1_xYwTp;=$lds9Sx z@s~4x%v#K8ss$GuKSMGeh1BYd z>D~vuM#JgAMZ^T5AssawxHZuAA{qQkEDHmdo_H-Oe~NJ+6OPvSeJeg}Xjyhlqk%Mp zIkyn005W?AS`u-c6{!_?=w9e0RicQ>(snY7;cV;+Ho-8qCZ-$L!wgj@oD}QHM`yyr z76JzcBTi-Qeg_WWk||hOy`{^=1h;Q-*E9-0_RMg$910|x{8DlN@vf+|_r3ag(9MT^ z)Aw`)I5Ttis)WSUih*I}XhX*a6NjE!7W3D~E9UjbLsp6zZtjp5JyFMI`s0Io6^1uDyzNpFHA< z9dufS4I^)I$egE!MVgib6{=_d#09eS@S*r?}+-WV?X%yuoGNk>=VhSLfcdOt*wgWGm#X z`ciJp;PHi`Qec4l^cj`#d4!dCpfwU7U#7?Mp`L~pkor;8>4CJ9H|Ky$rg+RxPJ&W= zAmXG%Ddul!-eYoAgyV_%_O2U#c}RyM-5WI*Bw*?;Y}xp#&RwI@A}Kh9b`Qn}4E8jp zYo?WBrjTM(H8eKj_mh^MoOwL;=8b1|TcHy}2v|XbfbkDU^(2wjj}s^diC-es%g?L(by{G(GM%=XKr?K_pTzL0rQJ zEMEi9cHyv^8KK&qo}P?aRx>9S4+!DuzzA6Nvc&D5Aaq56ewNnh8_5 z55-&m^vcR{iDy=NYdE$IvEM%~K#>d(B%gq0 zr`|hhf0+PXmM-e%)}P;Bty;KfP0jnu|IP(iG?<6Q+(QP9R2IMEcXr=6su~@$)Eh~( zIFW90;NpSRXyCwsW##4hZtFN`+Jp6rqIl8c8YG91^|XPq?E(^H-g7)rS<)a>VaMj6 zHOMSjR{a<>)dWWDhNF5ArCG}KEaO@3SE(N)Je&*cwuklyjnbqqSNrXmY2~MwQn<(~ z!q=vT5M%j+5*UuH^Z^M}q}z=@)4i&(k9$+W!*geUNhp zEPq>rN1M)e_XEeC5c=1nM+$|m?;zailt0}+KMw=slOZSR)C}wwdU&h{wZo>iu4Xz? ztJk9TB2WPix_W<)?vqoTYxeKo|2|dF#6a#1GGN8Dh4<;m$8^iJt3=<`n5ux&Zw8DR z#Ron?YeY?8yW)}IlXI#M63rlfvV(BHxz4CNq+aCW*TmfhRyTQrBO*+^_$fV3gx}t* zrrqNJ`OB~q8i|xd_5ve{bva|gGM!+C!5`L#amDGF4(QAiPG2&tQgzn|i;R|S+B6_K zw!?6|T3|AcO%3q#Bb`e%IXRhWN%!PcKswn41>|t{Rodf63fO!}{6%mAgMTkEQRX`i z%-dyGVjFtwtEpSNvWOQj5p z35{z`sLJqv4d#TA$Z5d!qH|XCxo%$vSBg1I%;Qd)kZn4{k?C+#s8JBWtN6T(QSj&v zAJ8=!xqLSGzHgE1ym?o^V*UJ(0gM8=;VjiXvHR`4LvxE%x7paqD5%QIa;wYI#fv*C z^?o*og?D<{RxaZ*Q2BbXBuz*HHqCzBH~#uF(rbkEoUx{?vei*$EuIuw@jQp7u)yvy zVbEAD_8#@?cVd$Y0}Ncp{Ke=-iv=3B8SD|;)G@&S12|oQN1ZVio0E)A_dA(!*3EE| z`b&MLZ; z{mGI28U~D_prWgbNeYBh`(=l;9)H7}W8udalSCuXWR%n305~CH;K^BVgsK%?jflS` zWqJGd=86nd5u9YuMFc+^vGeUa0rtRSXN%p*`-p0zSjrH8cQkIN_DWh#sD|9z((B8}^*A(O!|GgympT4kLkOCI6SmZP zBB7w%j9=MfsW6M{%{q6G+Q4PmNu$%V7q)%A9wEcYAydG}rK1P6And33u;a|mD>3`) zdRw>K&`z!XJo(LcGOwNry*;;%vhe#Cck06Nqsw~_YvJE4rK`royMO+v;AWcsimm{W zkg3z0fHCY&Skcu?7aI?RJ)zWTGq~5$hHH)(nL>YMHaKG9#L&ql zn^>L_F-_4f78$_yrpyB5s-Mx8)F{A+$D+&Q76dO6(Nck+H#(9DC&j8LZn>W~{1VvJ z)?9;S0P>+_sV<-k3l}c*fpecz!Z=Hl2g|c|zI4GyE(K06abWWPQr@Ml)h7M%Po$tu zUQpClE_)PCqO}S+TwI0q)YN?3PN-L7pOD1{;%C68*MR`wk)dO<^O%s!8#ol&1`t>kWor6?B(e}zQwK3it6ja;V^Lj!< z9*-guL||-j>|XW#Lkpona~8)p%c6veq(q>{g`hNMS>YJT!Gi8poAXX4w-ks&4wd{C zb|apzpE&JIJ?;mXh3Btasl$y)TC}4d>TY8WcxwI4?urNgG0lO91lL@^soJQ%Fp~f;Ks3Mo9(1n?O~sm zoU=UPKoy`k1r1oWy-=I3q+HI(Xrgdesi{h)UP^k}wc~9DdIn2U?UDNfAeBV2bT1QYPpf0c zeZy}PpV#{f#a&6D|HeXR&Ex!@G>9rGiTg~fO9$TCFYdIMB#Dox(Y@mJi?`E2XcT0h zMITYs`Pg3mh;Fd40)KY9OA-DJ)!MW8H8pXN-E=>VUw`G|#dYiozqt2nbQRx0v-Fl7 zh$?fC3(ePKm@89|W^Wxa-lY$(+I&z5m24KDuY3{+AT3Cqb?F{UC4;T>yJr@uB@7yD zm+c9?2~V4&Ofw2WW}Oy|x#Y@0AD!Jd3cyR}C`8pEQ;322PGgh)iXnoym1yd`e9CDU z0~hK_j}iIaxFS_F$u*`yA1b-7RF>L%N@0i?EPP}tq20kZ7c*u2LNShq_sB!)mCNEL zGa80>yB6YQiAf9S&hlqxSdabxf-y5`HlJH%>@t%ToLo{`s;0;j%bxA(YEfk{HTT%j zqnb+k*?sAJCofY8X0b$hd?yD~GoJRV zhL2#ntAnO{S9X?!U7EH|eGdN@;2gJTX&~I0s+y;J z_k%f=@^8UdZG3apdR%yA7(+L|>j$bXi6iVvtY_ilBU~B+?ZP&aW0+1!>(N7zP*Cac5+IJ-OVXbc;$`LV~&IQP{tC7mDxET2XcHE z6uM!DdiU!W#>LWkskiOfmwZv@OXHg%BSWj+{(jlJeg+}C3N@b%jJK3;29e{$kl5ud zt8lDLgJivT0ZC!G*@5lylLmqqHq+g!8uIXiicpeAnkBs2j+t{uc;sh224q^^G<1(m z)_NRlZw=w5UaX5w?B79Bn{p%7u4io~+f@w%Zcz)MHw#j%nOT&9uGCv>vs1Pow>TRj zh#P~WBqe>ozXGcVt`Ds=a(7E;s6SmN2yT~K(GL`%E0C2aHmGT(J{pHc-aJXxP@qz2q@lF8wFtCtu4KnS@y6uKMw=ohO>eZIpm=Jc}!3O9GOPKk)yX5;QxIgTt{bEH?}`+Z04nM|aZ`RJ?6 z=WIVlA077}5qAxj(kno>b(VdPb@w-qsKX*_gOP&W$(?)8GLaQFIQb6y(*^mKaHA*D zu?ZJAHJs=--CPrHE@m&p^DoVGcAi`u({d*Vm~Ryz=@4I0c`D}2&3*~p`Z#ElPO~HQ z)BZH#f9yQ=WzT54Wlt5Tk>B^OY5xBkI3J^raW3BOb2V?$+5e^>_UT&x&xXMbpRT}n zadSyB<2uE>_M60db~3&-b<(9AlA^FRE){fQZfg&0A{;yj!m2=8;@*bWO1C}_Fx@66 z7p+&d*ROnTMHiJ{T>fD9_z+ti${;h}!6CD}@zxvQ{Y_m2Z8Xi<-U2IC0w?J&fBV#V zb4ny#;<(Di{LtYoMi2Enb~Y}kvZ>l)N@~EP#<=6Lc?vwPYz7!PB_ikI1y7$-<%_$; z|3lk*$MxLrfBf&_B0I%pk4VTWWF#SxG8)>5N>p}ak6aa%5-qzFX=o@ywxlSdQlYFU zQbr;X@w>m`I^%oJx&8k5-G2X^bFOnypU-=|p3moFJ%y|l(y5iMg$NPY&J+(|U|7O~ z9QA@aL`c%6R(i**=+-jOq<>%)S&Ge>g?GCX_G0&2EReR2<3Hk))-k2y@sCVvF2-f^ zQo1uHBOWj-S@o{#FYCON2irg;*j;dh}=l~|F20tfLY69~`*)iIi-lIo%5?Or$%;r#&u5c#q z!UhR#oVvFCl9LY(#`dPSl}a_Uvc3@jz)$iPsKwsZ9JApk2NO2VDgK42Pz})LJH3j_ z$MsgC6>oSN_ z`Y_RqYgVSiU^ZH^WQhn1BU6Hd9MAdre^(>H>Y< z7gS}cOU?tROV9ZF#%C`!%orsa;7boKZyBdDO^@?OMQg3$#aIjbR#QEhb+_C#T4}I zJY!mHCxq{bJ8_79R7|9_+nxxLp7AtG2DLpTh|$Ao-*0fGY)s?K+5*DS!e3)pq$Zsu zIHBB?QYk{Bd9VcWgk@|814F;DBa2C%pzjp~NXg`O4&Q9eTmtv)Yeoqc;Y7%C0bBs9 zuLI~zdf&V3X*QtVch-)HpF&MzIcdwLO`EPl1&jS9IAP|TEbTS1c1DrV6~rwoxL8jx z>!FWCX4}qe6}8WGozr?hH_N3X`8)9MoSFSNwls*{Y*I9h5^!JaiAO~MpkiHI`=Uk3 zV#euY?>E7I;PD#XOxf{F1}Ci(-F-|nlUH_)$Xn3`rEEVHmC1YG{S#K|)r-YJiK;=L z4W>*v%zbEnIVv*J%rX&84~Kj+hdvN@(?Rt7TTsX2Pym%;G-nU~n++FK1ZTJ!SvZQHlcWRw{_YLpR*HMSX@ zvo4(33DDU3#JmZ9i59!hwVP_?s*zA9coL!P1RUr*Yr&i^kGu+U28U`0da9wyJ31C$ z>v+#MuJkoBD}&MyA zKeVRJmt{r!iklV@w^Dbtee1TlU`Wj*F68vGbI31H5fId|b`$6|^Z5=y+OonAsd-qU8 z$Moi{TJ>Sn{(TdUJ3Za_u@%2@JD$JifT5!Pp$0NqbnzJO)GIe`L{GloY<$V;Li2&K z`2}YyVw2y;Gi>~TV+=ocmWrI+8#5*7g~F$98)1rKmATRnTwK0MA%pp`^I z49mB61qQm)XnI@sm4-Xz9ZegWea7|ulWuHLMFzbs?d_(TiuQ0c0%0@jd^|MN#&blY zM()koJ9gQ8>QrGp(;02zkX=jMj-WT_RTZeBB%$Y&TW(BFUWAk!DJENL8cE?=HiVLu zJ2+_;GDkK0*#m8zBuVTG+yDx5cNc8ub6V=g9dyS8sd^XW|wDU%z{2EkC+m^6s7Js{A z-qB`M)~YS+ZxZq!1VPTjcXHmyFnz}6x@Kf%4tR8@$ZL}Cxy}}IOn+R&2{DPWP~-H* zNnu@hd;A84IfX<77FCa%ZGU-lhSl8s%#DQ&%L_DYl9Ntn+05QNhswT|Yeuu%^zf>d zf03+gdoVsZ>xqZPrn*%yU`mu<(0xUXDJhII!Y)Pg`y940?eGNm6J)96R<^r#^{R{{ z&k~E}b<}o&`?<{au2{_*$bi)d$UnHXl;A`ZhUCWh?Y()rYlgF(ovcJ1oSBL;ezTizgOXo<6A_>s@>L`zsu4Fv27HpI5w~&gu0}s`!$M3qk%~ z!r{RS6*1U3dH+l!BR94<;O7(Z!jf=B;74!XA(&kjY~NP-p70<2>2a4$V6q;Zk3d%2 z8J`HX>qz~HxF1vQO1Wg8G+z_H;+C zZsTW9qgruGLdH7vJkZqWU|^Q8c;G&{hWgl#`{MbLm)f3@Ey8|Nw`2o3CXGv3uEe2t z8UK2->1ydSyb1K7?$T6Xhw;clNkXhbYmha4=II`>2f94G*O}td{EU9#!(JhKYfS>mj@XNqfETO;h`{z8 zME;?~dqG z-4{ZrZ-W08Uyy~Lh3Pzt#vjGQ7^BoL;Pd~Or0aH(g{?z(hI zyXN)1?ZP!`Txq;;bnwMmpC_{-wk(R%UjNC9xK@Ex<%23Tch51K{P2|u)_QWK9C5TX ztXN{^ zg)ID~`Y((p@`4#>zLU!ChLP*-@e;L@_yv(Z@6P8(Gb!J^r^jwJ$!t} zg+j=33X((sC0th9<*W7y!~=khP><%7#4GfY8nC|yvQ;f|{?-DB2LbMi zY{(Wgc5NkrEE9t6HEsHIeXRWN>f8{|$sA_mRQPRzXqL{RYXW2P0Tz7?u^{%s=|+Cb zVhR-d{6yGLZjx$IX1f%ar0Gk)`v?&?W&$iv`fI~fXWi$^D$PE_O3Hsx)3$JrUW4Vb z!Dt|i+hsmGQ!6zEao)F-`OZ6JDz;N_tsezGMxW}7S4kUvDrL=Qy#2+$;sc19NTrhmgOP$r` zxkbO-K>48T<#I@P26_WRhu<6j@bn(PNiT`bja7R#hd<87DPxDtSz*c+8D#A;YI!KS z|7KA0&f;vC#;!lHhgw&cu@~htQ$Co$WWYVxV5Z zrTFrTG*&SBCiolR5qu=z5BK~m&xo>x|Gj}lzV{|&T;Iea;d8VWiMH|hXlUx(oYQ)p zCUw}WM>YyMda<646(J0&C4X63`BdL~P`wvRR@FhHf)N9b!Fp8@Xn-)q#@6a@T3q$wsL@0{IYYB}?kEffp(+?`b76{rxR!n)eYYpV zgU)PFN9?i_a=l$>6#2DY0t@C)6U+NJA&o|z&}h3G;InGZ^vMJ=ARsvLgeK8=!2%VT zoCH$Yj#m z`btNS9GNKMXW;+$0W~+180hbTtO(L2?Q`6m^C5hx8O-B4#mNrY{a7FYII4UK2Z9^_ zB0){0x;1QfB#vRu+2va=k#Yqn5Y%nvSF^80C zaMZEhk;#n4c`_BgU12Kp6)37g6V+uvxADYlp?9%*y*Ya6Qb14u8vla_58lACfviky z3%hZ0?B%ho99l^uf&S?Id zTGDyt6LFTDg&Cl2Y2DiM-5Vs&QRdyR?{XbzTBuUobp8kV-OF8u@et=$DxBZqreo*MWtFq?TnXBLx=plr5p-~Q+Vc~O+|2GU?pLBgCd%$RXi z8+g-YdIIC-erULe1#>t7s`d(1;sl&7UvQ0lz&X~7uxaK!=lkq4f#$nbSZH1{FAkAZ zN%=iq7zF@-dqH?OS7!PRif&-yi~t`=o0g+x$egx2JP2n3El zg?*5bVB+PAa5?y3Gb#a!O#9M^#=b%MOLE5M`nvwJLs)2p1kvNE!_%hoU)7^!&u zeQX6G+KU7r876xXhYwL0o##US55U6iz`&Wd`xncfC^CBZnO;D~Eu+bZgAfGZ`SL7Z zM)P2c{4{O&^s-EH9eAIwP#iyqR07UlA&1EO>h3P2kFCWvDca$x+S*KtjEH!s8IjPL z`C2CWfm7AF?A-iI@%@u$_|wIvuI7=JBHf1yv1iRBe0Iy1mQ+@@;1I!@@thLWv)92< zD`dkqeeOg(7Fz=N4G~y>PMka$cwR|IHQ0_`sj8}KJY;~#eoa}r_sjoLnHk)TZ{0&% z-5-6RMT8aV+@1D*BM)U;kYHnB@zi2$AdM8@PA zy>M2I;=v)RQY8I~@CET2tTg)nUtuQere>K$*CIeVPD7z+{ld)Qd0$9Z1d;VV`M`28 zuY4cYN?DFIeS0^aD3P&d!I>U-U39@P)80d9sEpryVnDzC#|v;zmDGX}D@e^-w+=b* zo+(B+9(tMl%>7uMm8o>hccw$}tG_h>{f_9G)>+o^TDM;sm25fx<()%QIVMHt)y&<$ zt#`J6$A5Qh8N5K+(EjU}FE_?snj5-T%SWk8&%r~67&->FDpx5EYd5HtkxpmM%%t?+ z1-`&^@cir{-)wkDJ)|6lz|xmH{QTM*L|(j8XJavOz%Zkyr}ZAri-Wtgc)GJkEZlu` zXT1Sq$Ii(=yI_Ck!0EZ`tiC2a0DAeqdNJjLZBROG;~eX!s_G-{I(hQsiGkD8W1Qp0 zOfNe{?<-^JhLS@$zbIMDa|1V&dUeM&ddc-h0aAj87+)O)fTRl_#d5uHVQ zaUkf z#E(dq#^aY>QA?ss$w^pMS}cJjX|L%5*I1en5xw|ZgW10)D{J%+s~v$!=nPU!xRYmb z%)meY+1AUau2%orRw$*?dai}B5yh9QVbS?Moqzx;FV%mZ)v$*I;j~ygo|>cyQ{das zdjF4hd&=3Wxu&Md7kD=>9RY7MUb-})+|}D^XY8g~xf>QipGo~lzi=F;q0vWjZsn6u zz7n~>MC@V0zLvT|5B}AO0O_<>&t0`eFSp4m&an8N<)RD2%qLxJK2+D(3~VB_UY3uq+l&8d^$;i><&lu2GDo!Mymu$}_0J(T zzOcQRO(cnvSj1U}r(YrSCFjDrl|m*w{`G@4u+5pYdMi)`i#T@_5JKzEXJD;euOP+! z-ef~*s;Yiew9-l zm$)U-0tnrO&^nkd3IYp?(dj}ds zTAo>Y$msbzL}mbeMxDfMZohe{*zw7_zCTFr|BFyzVio%HE4*p?AgX4vmO>X%Hh zLE!D<^Lr4)%z5#_F?PP`lHgG18=Z?j98oP6@6LZgQBIuLB{o(!byS}=#0s0Y} zpb?A&9Xd1}h;%qwKDC*j^YcwWm7em)q zLZc)GgHoF?u9C38<(>Q5;C4IT;C5T2OoM3p16Aso)7Row7wm4ZE8f1{N<@&LZ`}&T zK&R&h3RPge*wuDUD|KyiSG)xs!Ht2@P9W6~Z=QJmk&Fu=KYq%2z*AGmA%`<(4@yfq z9BzC&((wOcK3o0%i66s@BA_(LsA8yU7sMExlAgc?f+RmnLba-Er_SfTbfz97A=ajv(Eos7Lz3`VFoL0?d{!R^Glf6h!P9w!p`jf z7bjkx%>Au-ms9L6E}ap4^Uj@ZVPQQ${yaa*N*#fn0B_{mx9@Z6W~f>U{oAZ<2?>MI zXUFA=jRgfOG>Q$05U*+awAr;RA@4c7N`CFbp062#1nPn;S|`%|l*OJ{Uk8&z*|tBO z9W&dwp3yTKv=$U@2kc$5k6tko6Jwu@&U%~_8`Jr_Z&Iw&o6L#o={t`^I?o<9-S4K# zYTr>0AJ+mLwJqY@8{j)grOVH$pH00~gb6xfmFNOKF&7?sR_7pd7T7=F!Ceitpq)C{jeZvXITE7!W!stCZ62?GRbb^# zl-}?O1*5ESthd!juwwDe!zS~D*AgIv)62YFM<{@cG73rl(2n~C$ zz;@8T+f>6jSsaY2J>1_xkun)HmHvx|H!E~X+ZPmse>L&0Y$G`q#&sg2MAlnZ7JC3A zUI|j^E8rIW*R+Hn?e&NOTbH(>C zr6a{?7+s2&U5;NK%2!YtF~WT5K2ALmf7F2D7(Io*#x3~*E$?3Ts&W*wxYfjVG}AI> z&7hjo3WrDi*?%d)b$$A+TE&h15 zOmBbw2FF`#SNsh^62(PZ5Aj z5fljfg2=&RZB6#r#Z24e-5|}0^H(3aAZzJ*YTLPp`)Se()ETQfcX^umVA$(^rih%Pj5L6fqTPD;3C00Klf zw=fYD+cpz}5|zsyk|m{^!NrpR&msiyvdGSN*FAnD;r$Tb{&~c=hr35yAUlh#=K~HF zVipz)xn8@FtL#I&-TZQKadCF5&SR*M)AkLW6wl!+Tve#}H#S^e=LbSj!W4*jZ9Fe1 z&^cDS$rNfz?A+oK8Hq5qc?jEzZS%W0JRL)@87pn9J2owG?O#0i*N+lE&$8f`vGD{r z`4#+CyturUGC$t`{Lu!SOqdY?6fMOM+|0Ha+>uX2IGgA>FRVcW;|Qou8x^y=Y(UY! z{MZMT4a)hrZGBW!bg2Jd>VHvb%HqM_VVo2j?OmJj{f9sulIpf+Vqxa19pBLK)rM05 z{)-7pa-$g%UM{g<6TndoX_2rIf*ay#`m<<0=mOh*WbkK+AOworH4ZmplDD85+H>f5 z1_!sNA1!(I%ndPJPewS?gVZaWW|M(vfY^HOo+5VF^HToPDRx3_Tw7bj9r8PtUQ&r(9t6OJ9g3e z;W%+mKi44vIl&_*T#|IZg*S#m25e>g67DYsD?LE^$sySt?ORPEZ;i{~!RInBYGS%2 zvxfFv>^=1xxMR%2PRCW)H9rknw)O6F+x0qI>0jd)0jrBZu8iuPZXU8a{lX{Iov~$}bEG z$a>iIeCx=OHLn-8KGW4@O5)7FW^Rp8?sr4$=4je`t%a|)HagfyPi0)vRCul@P?YZrsQjFoTw{sJM7$ym_E9ffcCg zbpz&8?UU9LUGC)UoW;qqTlq4E9@)d}Y$|ZpKm+Rp$01<`(k8oDY&Vge$2n8;Ry$xm z1i4Sm`D1ZJ8Pn%k6m{>|@rEEIx#3YF#Q65@l)5qxJ$k zYB4{_oM13%QsbFW$1cOyFJES`aH^jJksGU4uCxcv|4Qf6e9Ji9>%j}ZN8fRtwZTI^ zIO?=tk8P)+!nVVdO@8g3c&W~ZQMrsM2_U!ia;>e3%eo>=<@#DB=W2JT|uS-~B z7^~@PVAd_O7QGfcs7+36Qlo~{Tfq8>kUp^*tU{hq!ZK~ z2L%Zb`*<-X$DHZKjn0IrT#lNAz`&JBwFH@s!Z-$OvxnKUl#;TezKgIZ%jSGtL*JR@ z>=S*=pi|;%vqa-*a!RqgtG_>(MZx1DP7N@PFi89rH`Bua&IF&1N8p zFPQ6`vL7A5Da^VH5{hN}i~f;@V;wdfi=4hQ+EmqH98C@( zfUmpF(yzIT>Rw{&)!~%KbOX)Y$U?AQGT?6QMAO->T2^shMTOm!bjxCvywF=$bfogk z^mT06Il(PxpAa=dI3}}Q?|IAL^_jNQvJRSh77j z)ZjqZ-3}=p@@ZaTMPM84FA}ZDXm}h%`P+ft-7CK$5PbIfb+dr$Kk91Vw~^E|26at) z%i8#apUAc+qiiC%(jRXEd7mxFNN6e@`Z|c$wt2v)wN*W(em65NUc4B*#OK{Yv=gF{ zfAy+M*SS{1mz*JwFH3;TQjh^O| zoZI7ivR%4Vh<7&rtgpqDb;P(LfsNr~4wZrKUEzA+4?7a{6}`sc!xAU?A4Y56ZAJn7 z%WP}-HJggSL$BIw66q;zq1yH2&&E=f3I48Q&A}!X$s5Ah3i1OZfiEE(W;V zmbp8)jg?boz6F`XW)hkk!V6wH_zNjo%kqAE>y^D{Vs(#1rB!YK= zfVa`g+Y!Zy(B}B^fs>pz$MKC-9ri~V8dPR-q)2Xi_E>oCoO`PKChdFGTHQ=-_V?8t zZur3wReqzK&HMGdD$?@u6hIz{Ky8xmoPy|L<9ko}2o(VsA%qn${&)7lP81gl`_is- z#A9@(?r@SK&{^onfZ%tBhVEoWvB!77ue4d;Oc+Rc949CU3n5Q_5}vF$%OqLm*J}Vn zIrLZ}UK&VRgmk}ql4HcXf`J#?Zq?B-h&DqE?>R{v z{QgjP^T_59NzaHBeW{VM5`vLab+S8@`W*RN3ow4)rhXpLqYd`2D)_!_;F9W7S_TKs z4z9FxxNe;fmPywlLxOc##N{Nr_?W;q4%GbIy19PD4D_PUMQF0;PQ9qlEY!HlO5o@Z zUe?hHAvFp*UY%pK7DX2!Rv~+fuqD&NtBtQ9$gSe6zLlNbTk3Q5j99|Lu86gi^MLs_ zHlYE-L^9zc@)IFWUcY@CU)qFq9i3#Vh#YHjCLX$Unt?$ttG#VtvO;)rm8|wwb&9W*YNb+ zzQunNG6VxFKrI>AmfZDa`+NHx*goy4eTYi0UVlkzv9LxCL|V!jJD*|MbLSGrJ0tB+ z>3R9=I@mjd7fulg_)6}(!H*0yX9`m7+hV=s<+F1S_P`Q!4^|$TsdY`eZoO9pJ7v6N zy!=QX{G4a*D@mVuX=#6fE%p0oS(je-Y1va=g&&o3e+p)))w?~(c4o&5Xe&oy+zZ+y z96sgc(X+?p6f{MmLksW%J|#%_u+OEYvN`f4e6EZk+9OU(*=ImIYuPJJ*4=*o^!jf1 zkiBzW9P!tFPMOYbzdd@BveJ2ZouG;9HosZ&;KWu^ zIv0bA;wrc!x(NR94Z-w=2S;7S(jiBoDP`td{^3D8vckb-u?%JE02AK#79?n74`?d@ryGHNzcM$ML@Jt{%TD^$$xdAwv zO!L&0EhTibq(ICr%PbLBojt64_gyq*cFxYR6Y38ej*Z-O41->N-5XQY_In1+I(BLU zo@lzkXKb4b8p<0NzoT~_x~~2oz6FGa-k~$*o)c;$Du2rsE$rb6j4$c*%fpZ+vc7{8y^Yk(yo=+tiBI-g(_SiX;310to~E zOv?_Ie(O4%mp44#(BH5!Ba?@Lele6=X~#^|MZ@{1nIR@O+|A{$US(2nPFf_|TyQD# zss6zmQqD>8W|^H`8j^r*o}O(b5(?N%ZOI#7b@^xgkf>?<($GCub4gb)6y2KWq&6U{w3wPhej# zGmS`htF3!Hw&2(g)tbF!L!eI;mId6REYb1UN(Qm}^F4n7q$Vsx+3)ZU0cVLAGL ze2*HWNrCvtEqiEp70XEWkwcCu#{+XvL&)Htvs_1+FYz_>@-aDHAojPz&4|Q%bWgrr zM$T9?eO^V9_IElQ5jH3C`ngos;FJ+A&s==*E7C-T`={?_XAf|l{sZNe_%-AJ%1A7M zmeBl4Zop>3Ka$(|Cmlh@;iCheATD%ywg32(?nCWM&ul=}DAVp`@`m-B>d~*gAr(_6 zbHwmh#V7CF@9PoWb^mvN@<>%z9H8YtjE0c_t81KB^DwlWdNF47Xc>tx(JZYH?Ih=c zb1!v;TNpTEa;E`>ICF3<(Rv<#uzLT8nH^@{OUq89W74cVos`sn#nbBUC$+e9-c&DS znuL3o2=-MR;~`&WR6OHlb|pv^xRVy(*$n#a)kH1>{c7`$ z&v_l#91Ua3=FLq8A4Wo0jT^+w++V&Av(WbNx1Gq)kx_$1J^uZ*;($%vuRp!GVI%) zUl-i^EN5&pbhKU9x@qS^G}d7!og^(TIu&D*n2?;Tl8~)g$gj-yO`)nb9v^IQou26g zWAmw`B=u2!=Px-le~YzHy5-!y9iP60gt^x*UR=Y=G>p84S0lu5fByW2)IDm7DS`hu zRoDF*3b_zp*%A=`(aA5W?~qS(di>zty@Ak@$+>mQ7gDTe%+FGy7UgF zB66-ya?_4IS@Ne&`DZSHj@K)9jvzz*z=Y0`(?hw#A<%~=Dhn*)EU$`nrvng~=Pu$* z@-7OnL&LdX?b@?0w@@6b@e$X#q%ywDW(9VSahu~T!t!70uTEBrx>3p7Psb8}76K zn3Is?b4B$R4Vs6vg{2>jls`OP^YkjYnoLS8M7WeZomH(!Uqr5oSf7GiU2-F|`%mHI z<8WC1^T#GkABPbxZzoZ{3<&;^w4&U3-UixSPGUU#wW- z&MfEE!Dg+DFx!G|SQIFEca9GF;Cx1Teh0p-hx}wVNXelO7lDu9_>+;xibNFDLedqq zwOhq50z#Bvw5~yji!3jgbD>hk6re1La68&ECAYL@9hhAO$0j`^eVe~N8yVl|rKD3z zZeOrdA_wrEl@b=c< zw}o{*i4|%C%$B@Uv`>lWa`90nPMP90&DU#T+J)Fg@{E_?jvhOfR#n#GjY5r81{o0by#=%m;*AfsfOX7BL28s|V5kgpT zKe3I3H&bj}7SUo_8^6fom;OSRD@hb+U2uKDBVwAdMH7X4u#xmziX~PsR`KVa!|?E7 z-9?5Mdl`iC3FLqm+%q-x^Icm3(z3OQ_c*v{VZ*&h*{5Y|GJDCpz@kSZjL+W?Q@rU` zkd_h(_$an>p;bSD=^XsU)YYl#5(uo)$`wen z;AE*!+wrCXhYWBKB0Wn|6F?`tfsVTI^D|(e!%bqUfYroW1i{7Om3~GtBC!I55JleV zc%SX)q83JMM0pEl5;Qbm6dTnk^xMSK%&_wJ>Ji>!=Q4RDw0aPWa9wVKYWd?2B}&$N z?XQR`TRNZDZs~nlE6IubCg7RqxtFztc!FlRynPR&>NQHdm<%oO;A!LmiF`jH)g%9u zAu6G2;Si4;@kR;|LtFxSIdj)hzwTmw#|8vUCnXR!5GOx)(1qFGriPjKYOdswZVjQ2PO~ zj`ja@Se@WGZiDgYtYMo?7pBCI)$z)jS)Ad&zc3W(wYjUDj#dX8>uL09rmh`>V~_c5 z&k!4oan6~$b~IB3;Km+4kLv;|A6pZ8seb0HZ^DN{>c{_w>fSAt;zq<&Ly#T!E z2<9zY=Fj0k8{J%-&qg zE1GQ`R&fp0me_bs$;c(tExwk}|6JspWH#Ee`c-lRUOqx{*(hS$(V5Fig69@#-884q z#kL}(VHkpZIc!SMA~cm?K3_29;?r%)^DYhtR)n|0#ifHEt<}!+vA>~QjOn{WLbi#_ zT3#!ZWE07vzgqL108;jsr!$8dJes`H_@`C<-kkizeU=iFQIjhi&$O{-AuEU|48Bu8 zyyaWPO+`z6dB6`O)J>m0UC@9Gq^A9B4llQplNxaBC-4~36?}-Xu5XIIOf>Nd_(yH! z^zS?&aLn{b6EoL-R9*Yv;WxiuYctN&ShrvY#3G^GAE0F7t0U?^YJEO}tocrLa?xy) zu!?L}C@=g)g_Ac111;Mr8T$J*t68xR%MZ zltB(C0(N=yuJOz)DlPRY?b=pHuD2!(qzF3(uoX$2g@uJ>v8+&66@JUED&*5`qLIARTxIu6XTk zM$gL|G?}0m<{sIspI-=iQr-!ad>zKJ6$?Swt{|s^Z0y+{|P6Hv}JDhJYZ7sN^k<@ zB8Ec8&`5%+`CllqBn`RvNr7!otqxb!PPcMx&IbSk6nW8XA=*k~L1WdFdcKxi>nYF2 z{ruWS96pG4dU3|^e(G@e<#M*h-+baTqe?WnrywdL!s_e9kC!_`GO_?p z%gYOubZ^frc(FaHQ&A}Aw(K*G-r!_bP@~J;jmbti=KDMS88ggJ3zdRQ`S)U)Vtp5g z667?4^i3j7k|yo=b2vt#it)R3Pt@i2_vqI{|Hjg;|Gl~+C%45GgGjWQ8{_CgmN%2x zJ4JfKzJ!};NAsZE7eeQm__G478(FuSQ3Ex13ZgyPJQc8o5Qk^|<57fj3=y-UL1ZG$^e|2@~&F@ct{#a;qkh2~1 zpf7IkNeGa3a~0>)oQ%SZ^6o*BJLg{3^&522ANd9wnM{Qsf~y=EDr5>M1Qyc&Jz&|# zodYBN`NvmO)^*URz_md|ed#ENN59>c(|7YkyO}YjvrjMHm-ikR(H8u7&p@k)AQoJ( zXz9$Y2X=OL2HyvBk`3$E&x>=jrJUS6&L==()G&*J?%J5{d{u9EI7!rR4GS~>9vKT9 zH;6z_S;Acxco&yR*) z`cpn@qcZ<%v(--7P<^!PYoF4zljn(9;A>Try_gNYm+;J6hd)(LrNY16*lH zcoc^6oBYWW^hl=13m&l#M(7vLojpqc`fhZ@-AP!@z;b(eLCPusFtvl3?8(OfE; z=|9J$LUqhz5oP`N?+o%AK35b>jd=l?Nu?SobAr}#BU{-`^m4~UddS~>@=?3H(0WK~ z0bvx*^_U|?(11U7C9M5em z3$_p|H1XCa^V70MkZ-ks@^==f3dlQ|aI(hDExP48K>w_N+|#;1Xekc%rgPgtD-rZ{ z4P`R6^+}!B4PB0J*r;RLgx5{T#(-rf@bXEA>10L3{q9}68WuGpb0rn^@&_8T{*`Tx z7dQ((9f6#ekB<()-E^-}aa&s)zNPVz6JR@k8Pc{94d^6@XoiGVU0D)GghF({4|yG} z%Qjo;U8V8Bc;@ep{s!FB>p$JRYJRBtTr(vP^}YN5v^nOxW5+$!H7+i)5@UY38H*lO zAedZVF3s@`F4(I6JioMnixqOGmPed}L2CZ-FRd0Cq{xzxuw3M10I+lzJbOGRgg{Q* zpHn^pSmQ1#F0)28J_8~3IaktBMB+*3|7FW|&QUY>>* zUPj`kTxHl5%YlW7Pq-H$;9Eo{{GQ1$9CV_@={j^EJh1@NW_wnuBDw*HeNpmsNu zyJAzWkW(C1i*W}0=TY>e@($==0Yz7G^<6k}?Av!F&uzT=oaDQb3u8bDpr6eO zY+uJ8%N*joy=cVdpfh9Dmami9)P2y%`Cqrj7Zif zWa#k82Wg|I1-&IfCu3;ixU?k&lHS4Tl=fKMGORbFQ@nz`&YS)bc}PD_SUu?iP_K9W zk>7P9=kV6*Wd{r*BM9s|zv^{_#TM0+`Z{U`~>$;?220 zStpTJPVBoGlytl9bBq$Ylc8hA z6!#0fI;rnI(S_j6F0%v{E2WhiO^Ac+VK5B=K>e)!`J)GyFv$Bo$nFXn7)B- zqu+U9-npatYwc@a^M0j)%$mR*7+PEJx2fM760+db zD47#HS_esHA`bKhAYwHySCg8U3>J@k0ei43i+p@oM7ht{KV08?5%4pl_Wg%1lk4(# z9TacLi+^K24levZ%*XW#qvHj$5daBg0Yj_{o?_@273`TimW)B{bE&3q*7{6~U&VIEU;1$5!duAQ3A7eLT4Olfs72e%#~SY0gh*Pvl_VG( zP5J!xUa{Cwk7aEFz!Pq;#Kl5v#r3hLE=g`U&W?aK0p{w`8h>ENh2TTlm;a%pyY9x? zejaPPZxm+k=9ylv5V+{%cjcUaKu)gB+LAvme0z5uquU&_?WQq8aCyLD()b4WF=F+- z(t7eog$FdXhpi19hu#{p9{0@&$8H_z(vvC!O8$QyZm~ zNFQX}Ybps7IDS7O-&GZRFqf_UTDC{H5zn4KZ_ny*);(u(s(m0+&yI%(_CeSH5XboN zwAgVSMSi6)7V;7kZPSBoXWgE#@eJi*zrKo0B0K=X_rWbP)i}iXs3Z5GYj3NUa~bFELro(J^f>}m&^yVc;QiuJ3AYJ=9 za!;&gS0&#BIus!rL^yTSOdF&i{ywGZI)5Z33s?MBCWJ-7w?oIys&qwLo`j$CP-b^1 zRfw86v(s#%aYzP<{6z{#r8nDhK!>0S2>v;4#dBSu#iJAiZ(iIAX)v(kxQ{QihKTPk zd|k{0|H3Em>`rX}Q3|F(h>3{SvXozF)$!5?oyUEznwT`^QrPtsp&bx$NzM1vfh_(0 zz4F0^4Qz*VDHv+`)5}{T$M!L4pP7&~!n^|~+8@$zQU{$IiNBy5jJ+dH8looLl!z{0|*G7-#n5f6U@h7USBDo#FHW3taG%*M=WHeL70D7kq*X zx*Rz9fx}(`Y9L};!NFlL=U?>g<+;5fC&HMf8(-ll`axvWBe+Ij1t*AcsE&)pZF}^% z3-ez2c(C!upnsRaXE+)Hry#fREgC|M{ z`@g?WVR)c@F3Vsj6Zqc!`-OuREGrW)uOtEQr|~J1=s4`YiO2|i72DYjC|DqbDbjeb zdhWFcr{helK7JIVdi5%Ot9m0-rw{Pn zO6Xo0H*$`59`zXLm$88x5L|4)uFjEV0WgyT-228^KLhYw$I ztXVYp&2P0hnn+3dH?ZE~>5i#v(5#;erNW6 zwYYUqMeUtp<Cr1%G3 z8|rkPt?gEtJqw%6W=hVH=(*aRm*E+S#ppnJXzRxz%%2xZHMh${yaGY+Uy?2wLz$q*Z6^8K$9+NO z{O{9_T&q@thAp_Q*ozGx`LRRrKT6NuzMb=2T|;pQZ+Vjx!8ffxGu7+WZ8+ps+;)*y z4aeY4H)oSQsH5F)+WmOh<3bJ|abm-`oXQwzzka<_^NEfblk8Ou58dt6S}F986l*_J zgG&4o1_j=wOj^1ser*5Z|1CgoEr}(GgJ++0Lya>J`9Vjuc@hpI?wzb8x`7jf*U~YN z>nTgMyb2e5f*zmEykdo-pt7L5#H=b7&I+#s)6Q~^Zn1|3u1lmVvr}94aMf$el^@ft ztB?!v*P18mnhM>-BX=FIqUX@;f?9`*3vTupph1wD_5@u3z|P) zSa_I%8ebuEdXU+u3U7#6md{}uvU;W>MV5rH$TzeF_ib9O8A0SY1gZ4I zum>fIo^>X{rrzk&C|J74jKoAbFcxREr7~wSPKuTk@%mF7po2ADc9^@dt?1-1b2lc| zQhX?o$?Z(@wAQhYG-5=Cq%e@s_orbg^`x=Al9grfel?~k5^f}H%j#dosHA@!A2KU? z^YC@8xBqNFRRnawrSiOKq7P4?^dQji#qA~e}n_Y;wt*B$VFnGkI z-c-hEOU~aj#s_zP$1KyiDNDYq9UaSyBAhwdsQj>cAG^T4-SDaWDsRfL(WCbXy(nQn z_)`U}OL6`HOs#yA-bM`jjmP66rM86FXZV(&oyaDOUHA&Xu%O8v%N?Qgy`7|?&mxC=NOgYGVb zkm!nZ0{Ke98ehyh)?qu84C-1M#D3(aJ1Prb(|uUwzo6{PTnVmhz3(FJ3=w$MYA((v#}O@9u?ewyyaP(df6q zi|1Un`iG|7d>yT?%n9gkgNOfBNBVr7vf<8h!~1(D{rO{?x36z0V{~w^VpdV2 z@gGZm5iW-A#l1YDI~imL$Cvc|sIl**tcBAS!*R0paR~2nECe6n(}S8E6d7+(j>H-%-3R)Ef&rpCnr?ZT$p)w9Dc128zLUmvm>BfAQ+e#kxJZpvZ)X+_ z?d)*fxM*SY-P$QZ@78s1qhIabM!TmZtd%I0pSEkrF(>-cdC5w0J_zayQ0_3$@^H|5 z=rgJO`E#A*s>|LuBtk4NXZ%B1t$G=7Cwcz;dw9ehmn^vrzV(qpu>Opd*Q?#r#D%}i z9M~g@Iwy!xliH4-2lmzbbm-`xI{DKYrtb!|^`z_VZ|C;X)psubVjTLp-1@yum}`xG z{r$U%<(l>T1MR6<$;$)MkT+8~*Podg*0I6fy5*m2SIpcQe?`q5H?~PUej4cucC5-n zhU4SSJ5;_%wo}d?H`>lI!Go!n@0Oz6Vq75bL(Zc|7xG7aO6_Q3(zShkckjHh?_ZR# zm(g*-g2_#rHvPfoi(7Z@yrjlhCEARYea4-s$+9vxvC%MDbLT8osjXYUNWY^`Mi&l` zIC7+!n`pag1Lf~_+1E8UEMZIL-!k^ZSu9-}KW6SR?ZDo^VU4e#%!rIbA7}0Qy6*Pj zyP~mp86XH4CEY*R)naZOztV%b?>m1<#5Izoea;mSbng^`(f@y1QO@W12_nv9a=x}iMAgr?@WB`?`(b=6pY3OCHJnOm$iBvh9G#=48>$<6UL>COdJizCr4Q%;@ ze{uu8#lm*6k%ofAiqA&lOV;h1%-byWgnjS-@zbZqMtc{Ehl&2!qyqV&JiaBQuG09* zGuO#46Y3type=SbQ6ABGskv5|0)pg4Z$hDIb1VA^Q<%rvOIEXH+0*S%VV%sj_tNzX z`Nv!m&g5wQKE_lP4Q{84+JMd?)JFu$3CM_lDUy3SYB-yE79UyG(!tx$kF<@*$P(D| z;pJZ%U?KdQeZS({5I|h;5+dLvi8SCQ1xp5Q+uVeyNaQmnkp&<)G4SfQ!~BkDZuHlE zTPT7*nr#vu^_p`ur@|iL?Ye8=hp_}#2r4O&P%0Kp$F3|!B=Nd_g9>vDuh11J$C@G= zW;CRHu7Z3SU$QKWD8_IYHKF<9d?f_YtC^z8JV0j=<1cp2Q1=Ow{S(rwu_QA8X&eMc zC3YT5S48WLshr=c)T@^)63)rc&O5t~{)^QkSMJ?Yq#wS92vv|^@i*=Hd>1|!EfOn5 zc{S9X@{|Q*#$lF@xa^cljHi4`U<1s>^Q`I_71fufU+iIwul^-O8XH(A(p>(HyXj*y zd|(^1?QB`!c7qRiCf%`Ee0auVHMjA!~-Dyu{=jfDA(yHO+qUULU7q^sxjO6;d%#y zeH25sBM4ZFrIRg56C1@E4)L!A=mAc09U0UKFgb@X@t!4K{JdWwY(W59s{au85XC(j zJ0r8leLSL-tA(DM2UYD{)SiJk0}HA@1vCi1W-Ytu3G{Pt%>TpMn?U8bx9$H|W|_Jr zLxeI_=9!4pEo7>cDH)QXD2mJ}o0L+tE4G;in#`4XOd@lVEi#j`GiOTtKWDM``@GNd z{C?~IU;lfp{jT@1w|ls*?{yBxc^t<%zb2ts!}^_PwP(9$F_ZuNG;H`oD0;}Rvvp5i1{XlgsjH0?fLxX@Muvu6Q$?}l|fXam9g$P8=z_ik-NI`8DNT`)U1j0j$_l8 zE^-Mx;Don;FBCoK$ii*r`Pp;%_s=PJ!^ zj$7R^g#jB-mNqL@r?>;Bd>!Hh5Ai^F%KZ~lFaGv>_O09F?p69e-u)4lNUi64`@Zt} zDs~?zPM=U<0q1UK3~-L|zqsyc7>;{q*;#+Y#sg0B6Fu^->M4FNCxGPXvrl=$XE7Hg z36GmPtlX8G+KRY{{D*3H?~-yHgtT=#0Sjz4bVP+U{aM!zD^4D%-DO?-2{kG4hWyb% z0~6pgxX_Ee3EG=fs^q*rG?_2pu85=>z6x$aHBe6qW4v+SrK?54_Qde@r-3&s>AQw8 z4SWp35AQV%?D+=haeU1|f=fT%&~cJW(0Waj5~x`n#g2EdrCjuXGaU4k9+s*>U^7fSET{}IQ zFn|+0ouk#&idx83%s9@!{aawtsj;TMYake6Zt1bEzl?$fiuwwUMFTh6vllN`#jZn9 zApfGh2|s#*4N$C2m<)_#B zZTmpvhl$@0U>kD=J7&UGH>>K*D|#om&o{4oMZ@-1yu%NR7YPoxW=W2X-{rX;43Q$DWN7pT*p=J=FeX zjO`$wKk8*EQ>v--`)i!(r_tc*>spQ9k6C%QdX?&rUw&C|`H3p;{f74ow{?EvGWBZS z@meaI8MB{N;jXG|>a|>dNtRg@YCO)%^Cz+lx@4mYO_@EbCmj9Ak7q8b3?gf;B_j#J z7YdN%5#;+dm4Q}PzuN{YW(ybglm$W=bu=qdEBXPL3$?lJ_+3Yj%6y% zeqq`|o2NAdx*qwBMFQ;o^&?MYT)L#85MWa`be_gUtCN^|LRvdV3)uMplfg2lt$oitN9Pejldj zxUp9}NON^`bRNNYQ+%-;3l9&M6)jvwzacG`V|Yb>w2YD!%IV!;LA%dZ%_BO~1O$3=G_!JguU#sZ8~_{=);gZpuSo6WzWOdfvJ5JJNYYk@bGI zdp5V3UgO!Ef(JJieEr~pkEfN(xPrb6UGW;}Hq$pWR7KR3K|^4mCY+|GQfgj@VjS_( z@aBr-mZO%A*sllcNV!hi8<$8C#_BW#MMo_6Yu|_p?)hmIw`AZ5{$K%XGNVuRd^AL@ zl-`KVOb8W$w;f+%)l>1hM^D>lo;?{RZ@QPNUO4{>CrC_8@K$*Q&4De7XL#bGtI9ks zzW4Au^$>X1(s5w%y+ZxI>xz7wKOgtP=H~47J@qTdxQ{YSmJLEa5Fb{0N`6Q5fxa7C zF20nUls*>9AtwPh^W~Iytke(-S4NP1k%ixnD=||?4@DX0zkYo^%Ga1e>wwsxN2Ql^ zM7!LQOB24Ad+3v3Zrr+c%$)dy1P#T!O7KhjJ@uJUx~=cg&=V_IPWIc2t+vI6Pn$Z` zpkqgsq6KdiTcAdLmeiM74RMIb6|Ez{v)#fy2io&(l%x~w$3wi#|626keFE-&U<28P z^Kd!uJ>+W1SC={*;lU#oUp(>VY&A)+HtePXR-veS0vYry(Lnf1W(Q9^%PQR84N5!U zWi2Li5}zhHJFj3k`UIEt1;vGjk~5pAKP;$i{*bn$O4X{%;GHnSTuBnwBYHxMvK{2T z1j}dH)kop>8^l{C`W$$Dy=xeRftPl1NlZux;v1$cfbZ=lBrXzKv`5NGSi(}-g8iO> zC?SG!!#bMZNTkR(`!KfTYgZvmigcXBY5R4mV%Wa@0G3u+HBgxvR8Xn9ihe0FIW-z9 z5v3`{*M1oNWM>B=sTqzsuZo|!B3vqgnW7HR?C5l^ zihMG@)G;P~+1&7USKpFBM?+eA->{p>mplt}s%Qb3X*0Z(jhl~?Z;#jZJTflo&s8S2 z4(HeGNlZwdhD*rqz&z?MZ8{{q`dpS>3BgTjCA2M!+r67FNX-&`fVwX}YlMSCYf!xv zVD@|~rY)KZHIPM2yJvX~^;h&*`t7iC{pn<4SLU4XZ4H1$+Y(nY3%Y5CE+Qst^UuwB z^|!=#eKKk2&|u_^r!dLTQqKKWv6|R%7{UYA2Z-qp45h{nQ!CPaGs6#U@OwwcwulbW zKz?J6B2VF``4R5`eWaZcW1Zx5-H=rCZ?8K~fr*H#o(?2rEoB9}8)6d^>!1j;z0461 z+ejydxsL(m&R)H`$EJ9baWjL$8Iz9Zq(wASs|yXWb(M4h7Ww9Cuh&iadH}|sKb`u~ zHfCdBaBv!f6fIb9P`F_Dou-Td@-uAPwmtjXo9_Qr@OU=Ypn#{R9 zHns{xA77X&zDGZdgc>ZRAf+iIzd&Z0n!|g)tuSnB?^TEHFRI2Y!yL6NZIi4Eg><)_ zZ{S+|n2Hh6$IMPCXg!4zDKtQg&-Y=bCfl<}NgX=TP7PdL zUH47BqN{j4C=P$%UG(9@b!hStb2A8;hDJtb=&o!W9I9;?QVHNRIelzx9i58QLf@XX z_Yu=zVeJ5nN`Vr1hxsYZj<_pvP;O9WSQd4$w^Tbi)N-qArq0>|0Fs)Udm?QPkAF;! zvJ`O-ghdcH!OD*Pcrf> zVo&j<45VYWa;d}7C*Jyk?N&E)-1;59gKP>t%vuVRd0NPyr)~32(Ow)F5bIL(Y2D(- zt6FXBz3Y498B{vP>BN7QQ7Bo#M}CyN_PKG&$4B_6pIPm~EO&2+o1(JO4%a@8FM{nI z2Ixp(nisBT#o3wz2RaD^!T6$|y}b_iF#0``MFr4B#HVz|#FWe$v)k(3Y~GHE*66Wg zMFB8>8#*1Ryc}+nkK1BM}w@V z`K=5xyAA!g?&jPz$z0IK!QJnlCZ7vV00V2@kn3u-8%`fJw!eCAvi;T6BajA8-@o6O zY{M41kv)Bo>dM0hfp|6^#ysH@8N9fzAtL&PaYAxOk8r80+XqwZB)yg@FN?M@y4SlT zpQSGK5C^x)l?NM57ur*&x8-7opSo_%4acOjBSR{e$j^ixLt|stB;7RuFD4mv*Iak$ zne7-#Y~_~y;f(hj2cZQ0TqwvS^{iB^Ovvd7$|*t$kY1EtZ0$woKRQpVNvK?g;n_q; z?vz3m6*+HEraFKBc<7W|HX+y}nD#^Zzkfu|Fm?1WsbNmjTPVy{2YbFM@73D={*w1Y<+ya(kZAMOZ)KM&H;1b~>?5q{7PhFTt-T!GlHxn0rNx*r z4G57jtJYu$)BFA9&aR)?0_@X!b&`c;S91RKYGjosH_u68vUUTB> z;>paR>SH)agI`IZ@ZG*|pBBMg;sLw96@}hHbkgI-ZBAN$kFEtD=#}K-a%Ms4VrC1> z3IS^1?UBRAwr;gcV_-r+M0$LDywYXsXqKN>utnrs=_D-U{)DhMhG8Z?#60LJKUTZ(R1ZXZy-;!ALtObC%K5#+TGiU}xG zf`(G*;^Zw?xdJZR-^rVLnEn@HDzYdBa9M*4&La#I$nnm{B z3GHKM)u8mEcgH^2xTFyOxxU}uu2Fnpd$7RC0G@zYMxYfSw@zZMBSlMAR@R%&Ep9aP zm4i?9|Ege@F4-m)bVB&(V<1e0}qxDR_&#a!#Al?9mM7rm@f*mjs$ce<@(cjeGdwMHPw! zqg%e2^lu);AKf5`IkZSVOQD+e{N5mfuif8s>r zd(?E;*bJT~UWLPt9P;<<+L5#40bXI#N|!mf_-TSCyY#99GI498UHP^#a!^km{ZOsO zO+%$^9#K)Ci)H{D*vRkxE~G66oA4o$8&L?q>e16&owbU(4yw$K!VdC_c$xTND#Plw zRRmI3-rGQDb0d9&0<{PjQ!JYPd?0S$zU|pXzM5M7p~s`GWoIQ0;DXA-&bGB|BOe?o`4&39OfIqe@zPx(Eqx3phznguq$7>YE-?7$6eEW8E= zSNMV~ryQ1+fixo03i^(&A+1>y9j~oWkEPMP3a8WA*>!pERN%ClFf4lX z?AbNr6Va(dc%04(EiLnjbQPC-4lVl?TLN8@0|Ih{OD8B7V?gr(11dASmf=4$=Nh=i zh{p<)fv~GT_<3OdV*E|8sqFJPwF%Df0Wco$iV}lQs>8LHo&gP+!-SU|630=60@a#9 z61Vg~g(eV;Y(`gRwxdTt} zn3ui0S_%%69Q6+*@cH5LT2z&6?NXEu-Mi14`yDvBvVH~m8H!YX3@bgjM)=r?AQ@*- z0c_w!XedJd;Y5gm#UbMqXcFBVcJA6$nJoN)K|hxRpXzn*e$>;^VL5OW;R7*CcJLZ1 z&mzI{R-HO4Xl|OfY$`B4 z9m@`uH*eNnb@|+zBt@_Di07xU@u@xTjwxwh8#aT5qJr7C+v>^BhcI^=F+~ofYv)&T zkVA0X2?QLHEI94z=4Fi6r3v}#3s*^eF7ftQ4z*DVbU{;Bum0;?tix1_0wuGcu6%jh z;Z=6L{qEs;q!G!#)bxc;nYwatI(>;IY7mgKCxqj}nBFqs*g!d9KJ1t$*U7Xbj6oyxLoY9&ekp@Hu0?4 z>iuzykR<8L`)%vvEi`7MWc$)mr)u>nj%;BzHrhA#@rxG$Y%aXu+zDlQQ;q=pW))v} zmk~`&b;@d1g{-uau8Hh+_g;H-mT8yd`L$IxgA06KExb4VsL!~v0t?Ihd$A!@*=JZw zEKV5RX8!4`*K3|!fDT={oD;tzXzAhW*QavoN~Lc!bSLgK94~QcppF1VIX2WsOap~m z%{WNb`p8s?`eh%x2^F)l&Q8X1_@`770|P+8DBCrJY?-7mfPgNlq0sDbT>a^cBdJUj zt;UT*$b|J73kJ9C)~zn3jo^t4-9y<({4!8_#(t(}RZvH#$3qG#tg;$IiH8AGr;^2>O2G5^AxX5EVjZ~_L9oB~E z3(7A6o@Q~x0OoV>@v=jQGBGqL7+D(fLsn>AX&kg_l~6LR?!bH#)q+69inW7-)Jj5& zlYylBgOkC~oFnptxn**yE4`JJrV$62W_4faUNW=@?Zcl1Gb9d$P9^w*uL139&{joE zE*kZo{YJ%qbef_$Y+IjTE{zj0k1|#sMlxjwm>8DVN>kKx4~uyQ25nc-*3z1GLi?KB{Yk3K*T$gs{|J-ABhtDwNwaD0x8Po zaeM~E^_P&>k(TCaO+j&AgqA*!V?7_AtEzYvhYNL)w5w(QP)vtl({8-nD>r=I$b_Vk z4j((orHgzXcek%QEB(X{fO3{|AyY(}6@61vJvzS7f_&^DY3%pYQcK6eNWUPE48H@a zH|zIaK3yl5$u#FMh4jF|(jVaY0#h20QkP<~lY}oRt7xzQX$zA^mnGBa6GO;+Z*C6n z>y=X^59LwWG#2+)lTjl_uB0Q3D0xDsCqrQP-IHir>8|>*8kR;u1LQs8D`Oim?U$Nc zDHy5cgSZD~=<9nc8G0PD9XWDmp_U!`7Ht@^YU~nHEb{9(?*7rF)i{D`bPH%4vLz}d zRZ)Hp4lp;1NwFwBPTjbuU32>Gq4Q@fzAfkL)+O%-u`tdu=JM^^pB|NOVNhVsxM~GG zfFK|C_Vz*oW0&Th!hI&WJf6Z;0I82p-6PIovT3ky$p>v(&YYO5DaV%<-NgvckKsV# zgj0=4yf3r6D{~{h`)rmX=-1077r$XiFl+jJtpbi=fjCYee_)Lny^@Bp<+ftAYC-e% z9$Gp<&SM#d-Tzot?!A}0hLxni91}%SVeR3gvUG}nc$6NDvXVd@?L}V-kFXyJ0NM9S zpOTjoWOIW|e0cc#9y=fSxfYyAXFq3^(;-o;ok?RNU?1+BNRFPMmnX z-P^fc9g}}FnI@O@Llt6ZNQ%Yv`1BJcWuKKh2F2i9wjiI{JK;rhm0^m zz$$T;#6yZZ0{z8miq*g6N?8MAZCHmh)n}O1K6WIfTl609 zg7Kf8-*3N>@bKTj?6b^JqUSicCZv2l74vD%;%|!=KCMc3l8FYb|ELBnU*{fc#qh^L z?;2xr6T`@>x3WLZ*Fj2A53J@f4lZN^J8sOFZ>JC>o`bh4{E%e5@nNsSLIT?w8V=-w zgD!JzA0zA4LDp6WV9)K-43`n3bo=I5%%4$9<+b%yx21CrebllkMn1Mt{z*xFVdvJM z7H;}}a4NxW3kqB(A(E75(6gq(6nkIYOZ3}m#9d6~*V#RP^hkf}q5>luwhwZKSFlJ$ zX$ppRj!NMiY_fB(VsD)vJ$`&U7FG3kc8<222MQ|?HX7dMR)YuoneWg-f~itgQ0}9{ z(4hj?R?a~VLFU-{92Ayw(CR8G%q)%4wrtzh9z3t2A`Oc4s5Kk+HdLx0M$O+y6&#$i zd(RK(8@eZ2*0{8>-~rLJs)7;OIHp>G44JAZXVcR9yZLm@vMVWg>>j^+=&f6}#njE4 zymN7p-{gHNJR%~_ZNyK|+3wSS0Gy+b-bzkBSUe%O_zRh|R?+KcHaE^LNDkUo5D>8O z#;udzjDPsY#Yyus^hf8y__24t?{WV8=8@Bj>pOC4Mh)6h(q|#SVj7nx`V{($ib}_& z-#!lu+R=G#^4lkqyyR}=<-0!_AU7zv*07N2&ru<2%&_nF-3~AZ- zcW8m*l-K+eTI5Zb03|Zx#m4Xg!sGUcj}UEw})PFjbG~J z(fwBT&VtNn@1ZANZ9G1q%Z|ij@$pv1;OE>l$Xf|E4!w^3=<40~P|<@+QIRnhRqhvt zsk3Sr%^71{N7K#UJoZxY9k4|={~H0_?ze)V{^zmz?I}7nq_I)1yEnWpSha!$1 zzB^~l>Yd}~553=hcbo%2it#3N$;=+3>p0eWuj{4$G2`n}_m`*Ezw%uy&6KuR&kp@t zzq1=TY81oHay$j(OtImkFtpoqd)>HowKh!~5%w*1qaRB7Q_F(6d6sz6d z+q$fOpKSWIydt8&iI2|uWj@HLH3Ob@*5_ot%A$K->rL+jym;%0vxSs56zudeEB5dA z*i;aD=^5$C?Sr1`w8ewZG2cQz!zwg>Mh;h$5hHH;$N!j=H0p;}H@EcM(AV{F)l+_K zT5^4!L&JiM*Lm%tIkl77 zdp1H3)l?az?q~Nww{1PQq3tfMdw0O~_h}<;ev2*G6ZPuw&cgX~=YnC@&Fl$vt2S~D zySp_Z`LW`gHcyNGI5YDWWviy*M80-?@3}5KeER0rBLjA>znXn5A;)%U7CEfjvxD}o zgRkCP*>l3(V|~LVP*L}`VTqB^iICj>^9LWx%+0Y-Z`pM$xQSz&>6+rLbJdPjZ@Rin zr3Q|qwat8hwoawkovhZSs6_oGcYq7NY~?VD3$X6_8ilzE;ktQ1%C0FPt5?@i&Jm&P zGFT?oMhO4}o;vwf^TH7`GIX=|?)d@uTS4)_0ycj$a>uyMH}|!7&|cGW6_P&2phNGyh};Hy>Z9muRQy*SLXxBKUXtJrEl7tG_^;cSq`mX34O6f5Xll%_N#E$Bj8 z0-07&@}IYhVNN1wl?=R?P4WO|&foQ~1I*~xD^Mwy^Of~O2~LTzv06y^v_RmDANa_s z`O<-9{N4ixY!&M}4z>#?JC_6}MtEfXxY}9zg0S)su#Hb?)4Nqu&YnMS`Q&>sM0H~& z0K_KQ_Xt8Lw92ANzrv9vTT=;-K_^F=Pb z-A-=PqTH?vPfa)f^5fpuz0YWlRxkv{mvQT_n{_YSr~R71bu9<{F)}D1HmvLVU9}b2 zu=0!5kooj|ICcJ83^<+OU(nIG5)9wZ)YR8Ch1t+0>kb>+UM@d#q*OsdS_-8 znZ)-MrYjGO`S9U;(-ue%^T_CvF3O#C6yuTUSv=_^_CVS-(MtjUcjO(V7ok7x*OCpk z^k%?GO=GI#BGeN-DF!|6Oy*+nDE<$v12a83bfaKvhKbZLyF6C^U#E;1PqlQ7ER(+O01I*YKOwkTG9>d;5r-r8pS6e=M3| z^eQJO$I{Kz=lk*Sz@7}A$gqrY-S&F}u?=8G5Vm*m;Metr`dGxyLd1m6b2n*%ANc&x zgN^qa6pow}U0vOIi+&_5?mNof-ZbmfdiNcvyQTt`*ytsDM#s%TK-LaBTi?#{B7PW_4>hbe%=_QTH=* zw{6^f*KW*=2d#!i9GdS_#b$oxOU$V@&73j+`mI-OmX6NdZK}>%c=Yb)8#y1Be7rL) zQ*#U=oYt+i849kGsazUUwdNo%qHO9ve*9K89v+9qsDre%HXaL6cKqxJWV@^W=rw8Y~ph(HdBNLN{wtN)licL7B{txmy zskqSJ+RS*N>Yq+cwTOB-x1uEHm}Xy7uV0t^ zwR>q}mFh;+x&IG?&Hu!FGdp_F?jksrxE(RJ##AM6_3G;ArphbQ*eRz$0D?;=!MS($HQ?xcA=b5A@tx~TZ*q9tpNHqNQ( z8xY%zkyrS-&N$utLf;CO{wpv>yuf3Hn_ zE%G+#w3%L**-QdUBsWOUM_LnyacqkfNJ-ptB%}|;LKVjh{!6iK489w?`LoJ=U|2sO zl8V;dRnf0ZKw;W8o+aL#a%>(VoYSp3nsszQ$^(2r{N}v(E17gq|-ej z684oPtB9>CD#V+bK3{KcdxPu5jI4T8#+gt5=MY*R9?9FfoN`4DrD}=8P;RQ#M!*E18_(` z6Lqqc9uU<07G=C!??a5I!an9k57-v+@PoF>CQMkg+|@(HZBBp%v!?3u9iK?|#HjPN z-16NE^&_v|%ssy*C23dOwWV~2CcEf)NEcL>W&{c`H>T5ZsW@%KwO&iV^$_DxvZoXN z3Be&R*)I+G$@XiF4MSE!-IuAVa3(x%PgrH8Zo3%4g+^AeYE96qZYQ;EKHZ`p+|(Md zxQf}Qi<9p-=JX@Yx7Oyq8k+-l`@^palR+!#Inb(U%Gnu{|9qcROF zi)I~$x8Q%>c(Uu*>p=t5(KSTjOlDQ->6Kjf!p3};9+zc+s)P_s%`TrwQPb(^aBY`5a68Q)shc41_0zWVPxJqW~=)uIFxPLv{4io zez52MvPhdWaiW-zk2|@f0ZV#n*^jc|NH`v7XW+V8+NRQ%i_NIqu#kY*6D^uI7aLa7 zMIS`j`MqebkIRSSc0*!T|+ zH}xYr$~Q4S7dJHyg1}f9 z(O!7wIZjsHw;Fz);XT6q8k~R107d!VG;RyZ3P#b8F4BV9pR7XUp)a>F8Sm&A%)zKo zsgf+rqduU(o9^X+(~AHcw|-7Joyz!&;W@iN=W$#X`i2O>C}5f8bewovI1NdEzFO(! zl4Ge~K`6=?-O1NQZulEW_Xh&P${joOK?t=VRS>L{)8s4-rcz73f63eZs#fHH1~*+* zsyN0=I|{V|Ua01P%eeVp*YDA|w#^K$+i%wf1dL55!JvL)Om+5WIvMip5Az+TX;t4c zG=Rz@Tk&K;E8$F}Wy~EYCll{{_0uBVw}T5=9U7bB`}bg}JVq_TC=t*d37F(#SyfBy z-t8{R-hZE^u4^;qH?CNmH*Lf9+qVb6J^-sz{Yf#E51 zDCTx`baZy$H^8LzyDvp9RHRABofKba1QkUV%);=1#-;^JbsGbJiZ>x$Yr?IPejg0w zaD?h&sF+i8SwQ2Cupsa1&#e;Tug)5q>(#qC6LM{=4jgljKJ5l^Q*3h(LPbB>xTMlh zOp6(yfYmpog!`+$l!8#|nnHcFdfBxsipPx`to;w4O#~KZEyKDVscf}({0UjAK-@#| zT^TE9@C@H$$BtPRy1O+zas2ojaJ+t1mT~FJD-vV*QCPIvnsk@B>g_%Kv8ZLMSaoIK zph0H<-p1alrOwrmkyRERH~)JybmP_kxXn3h{taNUJ=#jqEwu40BVj+L^L2Um84k3D zLVs*yGzz=X^T6ors9a7Q0EmSQqXNLWvUTrqwqp5N9XUF$d-R^*(&Zq`>KgT4pv6P8 zuG^-)r^?;KdP8Q5SQouP&zZ_VgM!&qjH7IdR~^-s@$9eHSaIb1SKK1uC8Kh|Ej(+f z{LGgT2Nbh0WA0d_v!lvRR8^>EB@r<*!gylc$lEt_<|WK%Cbho!2MQ|+RmFZBr%*37 zMF;fk8|S5pz7XV4zdymw?|0joD$`+~_sFz~mutmWXVmHV2R8Z{f?KNUIy@)+!V&QnKVRj4$MaHKx(4k~)gPgLvn4k0f*6%W1>qAkI zeGXcimB>#XK>`iV3|5)8lhI`9D@*g<@>Kx^l7*A?%-65SkdvoR`PslKs7cWgNXI9; zH<&;PNdgveeIg&yQ6t%ygZ84l0vQU*?wV2K7xuTB98pHeW#s&jI_z_L-|x#{WIqO$ zmaW)7hh?G?0aZ_fT-X8D7EZvEA)zjKbtF#?0}T>8YU&arT<_YB8&{p-#OJSH9~1T1 za*{@v(%kOuY0#rbedgllS#&0K9~M43X1SIAf++R*Ns}K{l(s30@%JNVZ;SiLb%ORaVc^(=2wGfX0w z+qV~g7elYI8ymPb$+#Gr?(#VN$)wxizyJOla+}Fy8^t##XDqi&%z*}AbWA8~yTyUz z#lW*M?70PyN0W3q+4u`58usO?0F%5&-u(SfxEXny=|vDieyNhNSI%G|Q*BAptd6ucj(Adp6-$rcdfB zJ3b<`++NsWlUM0Tc5$TPCnuHpLk^vI(D4`Ek~SZ1n6~u{R~BxIR-;CVSJtjd3K5#x zmgyk!-~_kk)pupfzI(P*M(FOc)HO3N;;ao^$g`L?EyY1c! z-Y7q@YnfrX`45e@zqfV^O(^CH(|fI`i`m&@Mt$dLHk0)euOsfKz(GMM3LwQKW;d}CApFY6<5*r)*jCU|kQ<42*V?f(bQEA?y z#h^_WH2zkifo-j%1C}j548gbL)=;Z|e(QkP5yIz;t@h^KJ7hccq^4j%FVA!5sh1T+ zmc;^pun~!Qy6K{4$dE@=@#Tvk)TxXGM&{dHTNi0!;n@!;Q}mq53!urU z8Qr0a*TM)hSU*=I-NL{%;Z-+I$c@yy&=I62Ax>1p)}tR&u$;V~VmQV3Ur%i>lW_(G z=SxWx)hT=wGcv#bgiAmGvrc|#$vPy+>?@IU7&%tAKD0ka^kbM2L_r8MuOg(1&tUpw z^udG6D;PC9#N20W2+NlNQq5WARV8c2wVU~CRVVL5r;Ak5;v_2JO6W&H-M z9Hd@Twe-uR!fdApIE^sRipY$xk4V|3PD-wQY ztnI9y@JspAKWv`}87j|i)Tr)9N0uB*S`}L)Js!*@%e#}38cI1gGS^MYIe%FKIyXq2 zHKp{7Hvm$Qk@)x5KfdpEe0hQmJj$&mPZ>sAqi({ZQ#_VSIY=bY{K}?^to$0+E}cPb z2j>e~5$_<2H$@%-JLj0)N%vfnZ~4Q0&JspzDR`b%P=Ge13;qo9@HV6M-s!!<=cT?~`$XTyVQ#vV|N1S)+HfD{;4+XoT6L!pmrUr9Eyw?&J{tWu85B%ciY%c81Dd^Mx0&EY z*lcDU_NIH6#}|5&l&hf8LP!CrhE#i=NiA(mRg5eoH8RjOzBX!p2{C2CqD4RZ9rTwG znW4#Z6Jt(REO6Hx3k&(zk`IjA3p!7k&}ZfYEiV^p{*5|JFW?}yW%!p9bCN#6{u@bA zOR1pjCs*2_iTM8InvdAn$;LLZOBF!?d)3>q?k$Y~Wmmx3PHj@!EW7!j{CKPBU|~Vd z9W67_4MSR%3g$q%1u;ISJ-oL*)UI=&Wg-Zo(yEIv&QF9vP`z~M2xO_1W6qEdhrb|p z^FzyhcwXVg6bqM8#L3v?qfZvV^&56(?+ta`Wb~DWHo5MyF0okv) z`-k2F7-x+b?(*#p6s`a!91OR)(C|3VbY*z#w4CInk(_bM>9;GR9p-V_`Y=UI^m}cq|$2HXI z=tu;LqJV)TB9*k8|8kfDy>Y|_F-Ye^?kJoc5W9>T0v7EVDe#32oLY9Fx*mPGKs@V( z9{WvqsJiF`%gL02^8xAo9nvjm*<~UDb<1`Pg)YOTx37-9j)dpR=#uNLi*Kj0-Q8>X zo;~hSd0i7P5ih`!N3M#SbcgILP$m)=7GUR z#2;Iiesv)_L`6rdpS*NHlmhIH-$`oaCQC}2MEZYONEno!RaCg`$G2&s&g;kIoN5%Z zLxt9@TMNq0nm*@aMKwaZC3hHKICX4WgUGtV@I|3002!_(V|yR^o_X_mOP<+#6!v$rk| zC+?QiiQimb!akMof|u|B}708vF^a=mcABhR_r7nfmz0 z(UV^D=B?B+&)GY?!FtbaCqEW6jNB6_wTG+lpIK2)1=M!y?JR%4m9;8Y_8&Rn2dgnp zcfQtpIUC4mRP}rGIJ|qPeq_zLFd31`2)QKUWWtt(`H2OS8 zY#EZd=B-*yrtsLZw1jd(crk<*@lSY*mBze9)zw)CfIb8im+B}mFmqlHy_HY&RdMeR zuO?Y$E&Z2~z?xTXgYHyRaH+B#l{BML&9;4XQ0v6b;Np{EQPGSj}g+m4GxfR}Js z)&O)pky;BR+*S{%x>S*|Ug6q0871w) zB_%=XBPBsAl-ZcF7J~uC^su2dVja@9<9TAL#B1yGxc`gfA?B!bqmLdfqx4X`!oEy}ZRF@IN$kS&KSP`^5$L+1%aTJuBd-@gAn#nbsK8PyvgLVKDWEwWd5`O_$pb?cGp9mml~#fxGX9c%bqS83Y0o5^USbuRVLExF@owpabibi3#?%prVBv?+8J|82w22PePd%y4)bz6 zwQ!tmjl!|OfvF#v_W6&4^YbRzj4b(a`oZ!5!*&l>23B(oFn_-8aEs}yo^5^JY|6&C zm|M$dJbtpV+QWBUV>}NX7Emp>eCpb-OaB%&>O214pTB*7lm7IAQvT}f zTB*fej^jsdJ(9QilXv~TH9j4wCl*L_mHn`r6(f-(_gvi?x?N7=$T~Uvh<>MO#zy&F zUDaxxKgRApFB>MPL7cc&^?S`r%nS_}s4p`dDyOC2-VP|eRaCGMA$B`Q*IH#bp?|zT zl2u&cjo$7aA8_G7FkF<=QMxuZ`x=j3Nzp4#*djGhnlfdDVA*5Ao2CSTm5kL4H?Mt> zuVb^Q+RB2QFrM^ld zk%!&+i=DCkejlXSk#jHCcEDa38>?Uh($nuEV7ShTRIvzRIiXz#J)1iZAInF9i|Zrp z6_Tl_uV6Vk;k^V)&E7;;wc$_1h#g@~Qrtws>=!1!h~;A@8?7u_8~fPFl;SebTpd_) zll_S?lh=*r-un)?*5;zmyr6)GplJg7&~)u|?j70bOd5TREq;btOfID3bfOENo)xQ- z#kosZRxUEmEZ5{r)v6apj7gpV;(tE%qqr}h4y&yqW^A%zK;~p!X5Al`A24-U(b@~| z_DfegW}P4>xWb(#$K7D-i1=cN44+0vfK>JjTjd9+TTa_OS22ium&p1+iCTz|f8#Gs zLi;W&Mz`OX9v)(;wsa=&N%KQjVaZ9cjo`s6{aehSsrs*9VL>?@Cwcs0VpIgD8Q!`{PBTasD;`>~<2en1#tFHW> z(w9}!=FQdlRn*RwmaFUUm|G!jA1UxiHS}{R)9&B?zkRE}-$&jo*8CCY?Vp#u;W(n< z->*nbzrVkmCegzJ!*hVFh!8TNVYY>V@!-GzbK8MLP+65J#tBRjMwoz`$oG#;^zbNE zWHP_e7q21+yb&QbiHx&inrVglO*U;FdEh*UuxqfI|cF(tP6QYs=NR(yrg5@Xvh##TeYEJ)nV zwxoz4lxruuQZdIoabRmD0|Tx~rv?!L0h#(`cPrqsBg_<}MH2%jMA;kbFh&vLgkpvb z76*GaB_UmzxNFNZ$L~`V`FKdRZ$Z4I`#BwT_k?^6I1SB6pRxv2jQRg|UK4W|ItdTf zbdW})Wa~E;idXxX-udX<%^=#+KsRCGoF>+^iYj=*BZAAnp0i2 z6UeF_MV=}mL}l2pH&6Cq0SVM-18BW>Q+QrWCAs2S!*078l(|_a$Ddm2Ev~iPE^$a# zwxdO_cs~2KrP@zh<>no0C@0{!VZ7y>Ux(m=LME%M;La4brYkk6VC69onVihrE5?oPAPhE zy9C8c!SQs;UBx+vON?#2` zP$+I}Fz21JmLgx)c+q(6V2Tv>QV2bZ&3NU+Jl&Vr=vwQA#%Wm9vi6mt;0e&>4Hu?{ z=@7LpJh}(R1a|ef;g4+y-uxabB1wJ z=%!885D3IXg&SpC5T)NW?bWLxX;sa{>BGtKF4Wi6E_EsU$|{?l5$tc~MwM>3inoh< zmsP_0Z~+8mBRRmT4YxopEhYwO2$V$NBj^`y3*s*+!~vB5b_pYEDAu@ZiYggi0!v%A zq&y(xOolX(bDRwf>3lPrWAohDJ*R@^r}#4Ic!(O{Pj)|$#^1smZ72j^CWo?Fmockk z6}mUHF{#wtpRww~KfB!KnCI+`E}MNmU__JYQyJ zP*HdwmWWP-3}~#^zcl+?70Cd-{5;0{^c{kti`ZlHAT*e%J`jGQ=10GOm<|c>v7xxbrwykKngH;&mO0s?)Mjz zH;&NcYq#@s_⪚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 ~>P9=>A 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 literal 0 HcmV?d00001 diff --git a/doc/controllers_without_engines.png b/doc/controllers_without_engines.png new file mode 100644 index 0000000000000000000000000000000000000000..b5be8525d2680abc78a99a9ab36c393dbd045c93 GIT binary patch literal 168523 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 aCk}nEb!CWrGXtTLG}XdZacZ*jxBmscA}{p- literal 0 HcmV?d00001 diff --git a/doc/full_models.png b/doc/full_models.png new file mode 100644 index 0000000000000000000000000000000000000000..c279dfaa30b38e570bd9249fc8347528059c74bb GIT binary patch literal 196070 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

    H=tNj zq0VZ72*e3BiO~;sjwD6j7}DGoSK~|D+by}Edat-Rzi`va_zqJ+;WTKc+5j4UMlP2S zbT;PDA%E>I+b^CYE0jb#c<>j2eo$}KKY4PVm5r_8<;zPlTep^d#a&@%Ypa6qB_f;# z{3-@^uTDJ@Fpvc7BGkBo+xUXm8Mj?_N&$OE=Mp>~O^;8d1bsNZ|5IDti0P&3sOJcj zcLcjPVw!HU-`rdW$Cx;R+a)C=qAZ3`Pe4H@*zxNCr;Vlw%wKybiFNBVbALk*Ts&D3 z8x!M*Y-q_&hxSVsmkV-UsY^!-pWyl;!Y9}^mNl}xhG{jc#`BCV>*x|yt7M!=*Z7Bmf@ofr2Bl+|$JsBhRG~VKeF8`uepvAe9_AC1mX=hw z9P=#VO<$txDciGbTdHG=iYqO@;K=dg`jjJinX&zYgM(A3!tz8#wrz`t2gv@JeB`r3 zSPD}O7`hU7|0XLdQ!v2f_ga9ORn*@+JpJHB2^P^Ij0bma&K>^neYUx!CAvXdXvxZZ z5FqB9P{esbl-{L}yuZ9T8yQLJfQESGzCSYCcXQSH3yTDfCyg0N!`qs@o9uU~bG4t~xP6s%;F1Q}F>8tW-) z>C&$tgQ*}gukii*H4qytqL>-!OG`^>qC)^`p)7q2q!>+NTKP?3jZK8?05ESi8CR&y z^!HivzGRBlIuEfrk$#35({-#m;EN%&DLB1|faQf8P6brrB8rNZ&kk0hwzw3Wlz7uk zSQVTHu)+)ICxM?X!Z~ujs!9p!;&5yiclS8?p4`+k_C5d70=(JO^epkq9X)WyI52S2 zN}1frtwlf|_K5r7&#&)zsDY8g&d%ZZBwQ<39s=3Q&T@fe+PLG@+-G9mfW~IGjg274 z1!(?$r=EtcY*zdKK*FEJY>XgxvV#B z^7#mVpvk&obA_00&TUqsk)N7SO9TV|?+1RmnIa{S^Xt&+nTzLcUu$MJ)_d*3+(j+i zxVth!yV~z#8xP)NM3JH9F?ZJ-u*oZT; zp|LR>aI(bCoj0J1(8blv7=-!E!$5GkI5>7IC@6@sGfQmQ5{*YdE&*tzXeqQZUjUzc9Z)( zN7}<8BO|%C({p%zd1IKRXCeU2A2S6aU1#h^*PDYVcfNjs8HGqUfW{aA9@E;tKNd?? zT{Sfdx~hyjy7phqtgZF%L1Yp0Io7>K!84RPG0~pan5Q#6dPnJJkmBPSv2F5;7A+cp zfZ%C|w}(e;!QpDknz)XR&1<@#|bDV}RIlL$M8Bv+wECu_{7+?tAPV9P&15M%%n}^g$u8 zBxvvahEIDccW123G&1LisII5&I@VlmTeR1FL^Sxo#;fj}CMRuO()?od(gLk*hXw`= zKq2K|(~EMkgwZDVOkiE%HH!vI>Uo>|$^Envqd*5^R&VgQ>T=|PqQJ_xJ@*~-b@cSI zFiyH0VvJ2d17x>tYk2q0!Y!sban%{&*%izkTefZ$QBzanvl0z`dKmN)KV4r;XoHJ| z$(P#^N-?MIB&K+yld*KS3A=1kfLFn@YSqTrN^=P=BT%W{_|6Rmy{A(Yj>Vj z(ZL9$`$4G?v&<=!YdP-PKG~rAw1&;L6_DvO6h&r4 zpk9EgdDC{q$k^EZ`CqO&qzhLpqNjs3{4#6>HJCGK<3F)TY2mjAw5^B1GRREhf5;Sc z#5q8RPmi)6GKWtki|E6Zb(BXQTRiEQ1v0vGYMiq*7Z-!V1{h16msk7?=ao6#!n z-JAQ|R^n&VzeV{&u$VP_QOlEb0kf0cf$~}#O&>HyZs(2GGEOge z<;aVglAZ(s;&ogazkgSOg$Z1?6JOqLEnBO!N0a~L;T`$Q{=OT@^l%0X zK>$T`Ypz^GVGYuHIowLL!YWC<2g2o^!}KZc=TsB!cfUDh_7wfnW97@0xyzI(Db3x7 z52sna1#w5C(F_tD^~}t8i1r|Y&tW7jy^cq$10m3F&AIC0V( zYXTLTxbmnNg}HkoQ+&I)|Ev-h5}DAiJadbF-`7(!wqe^%ZGrAvU^$N*owrRUFD76jq)AU3t2KyG~u7Srv}-nVa&fxOe&gTLJ;KJK|t2S8f` zp9m9;q)cw%p2WgY#Ro-AALo0pCtY(n#vXZ`DV34ul$4a@8mV#geE;e?>$Nv84 zt5=y|-o7Kn(NMqt>9Fbffv5K$K7458P$qZkxd+Xq-%gjaC?PSCKBy7T5Y<*SBIFll zn*s+K-$P!A5pjeDzjND9K#R;f!Zs(Fu4Y#yPrcqF=&RM`0eHmy!3LK{C=(g}!fYqw zP0}F2fRw`LlAK9))lVwjt0iVG_{EF8@X;Iw&pKjyq1xw&grAB0`v(czmh=15`CaB+ z@^#tV41`;jt83kQCK|@n4xF0QoGKJdmonjF)mTy8KS8?B&!eNYuU;(!UwSjy#?mqp zq|1(-J3ab^U@#?G{fq&6u?;b$ydqBSMUX1*_eqhrmd>W$jY#%@8bE^4-E|KdetXegFiSkq8!bTo%mxo22- zM8q(dri{EiUFtI$d=~p82m|3+*}O7PcGoT|@oZHL$)=0ajyrbrs0KwtAHQLPq+}YH z^5}$wgt$ncHBp#xc1=Wu^GcEPtzaUhLR&!oU}Ixr>Ge7Ax#{3yLWoTV#Q=`V?0Y?v z$AFm}IG{z@WeF(1_xAv&YLj^*k##oI(2m*T#P}OKDE*77BpP- zZ{A#oB)wKlo;ysv$YV%v1oNz4Y&~EtU<}ivZdR{h$E)(sD76IXRj@iRAMN*2RO;eT zujQP7L*pDZIru9xJDar9bSW53&;}UB3D_@~vK^8eH)7BL+DWu@S%6LU=_G@Z;-KzW z2aM7A1`XOdo}|@or)`EyrpT^=lUt1i75kfGNpNz z{W6(nR9urk>Y(Q`cS^*yipfl=Fk)>$Yx@1J=_AV1zgbyX33NaT7IO%EhQ_xo=09Co z6D6*!oJ`<0emJ*=M@RQV7Uu-wtq3FP8XFp-b4G`T$ip1y?^lDUpNp4QBEI$u3PL*v z2hH;GayvISJ)#YP3(XurBPgf~IHM$>Wdm8d7atE}CiX&?JT*C}s~7S_v!$&q9Zw>b ztX=`RNC1^ z0BZpLimTYCtGg7E3+83Zu9`2(Wr04m4)DzttPBPUQh_agQ;ua`L{sbP>I%%<7WG1N zYin*tA%EiBn};r)QgBppV4a`O%oO9PtGIoe71h%P#1Mi4KuT}zR~U0H!?yJSaN1w3 zW*QIBnI%;YSbe$SBd^C1;C>Y2&!@T+XHQ02hEK3?{9%; zfg-M2H22?7!9ypp^ms$shyIZegQMmPjiF}9Bq!ssRZ+ZxD(Fmf{(K;aQgP?VOI z4uS`ZiItba$&Z0^AkWwIeV>(?1iZZzaF^8Uc`}f`plXhV>Vpy!Ba$&Zl8Nvv5FklI zszSx*wP09v>1kUu`q#G~UjuasQBXg5`V^jVc2pprdmky!_$#5DClGo<={=i(>6PBc z?d|OP;CE_%{hEowkl2;v+d(tTzIrtVk&9!R551qCA7-qD>YOrrV0f#C7{%~xC<-kZ zOnw*c+>vtk@QA)~BLX_L<>Y6+Kl96#3PPKK5en?kVnas8f#&R-ijc~gGga;PRcoLb zn*iqf0s4Siyt1|I%#ZsgY!4qk2X2i)1KDXk_-59*Y^DX)#6Y>;cju`uq+WAArn|?! zxMMMeZ6Az=+!itgyr7`0Eb)z-HkA#9E22PlIi`#!MjA*mwhDe5lBbRh!*V?U(HZKV^|9XJEq*N>9c1|EUAG>E z_>sovou={dhJOIsVPp>(MciBk_~9J^b499rCXeE1OYGfYNhWrvT+xUYEt*qJaEp3e z#PeaNd69(8e78O+r@5ajEAKc`#NPh!p7uTdQYlIZy!FQkpQ)LNBMD#s6VRH=t^RLt z)+By22bF*UAeUFCr=$ptjsFkeR^!W;@hz}bU#9B)^M$xrfa}J`cXT}~|D1m3l%9@G z8ssF6ae2A=R?}`dHZn!riTxfI484Kdc4ilO3ONiK>c;eP8n!QQznV44#?R?nXD_SV z{&gIUQ!~`o+CuEj(D6y2N5$RPo~5rV_I>zBS99+w-?p&zk0`VPDhp>(!6c1(Sn z_5X~3xdG9r+m>%jPo}p^E?_gH0rlzb#UfPE&>+*e2O5(R+60v4E^eI!GWwPz%EMKS zQL#_rA2_u!Q6oi?`AT!LVok})7g5*Y&$j1kdIZ(=um7{lf5xE4S%%lBd12CB>tmmV zxq0sX)f!7P}i=5`rwqZ~U` z)l_!WECg^CZX{C=T$McxV=8Mkk5l-d%*2qzO2|3MW3@QJD6 z{Zx>OP!MW&GyTI&D5M4($Kk%G>N}pcw{xMql#rCH!J&wyw{j#WH)*R)-eKlnF6TJ)bJd`x}lWi{Tb3VUkw%~!? zJ@wU`6r&hcZ>0Szlo{O73@GYCbjgshnmW51#Va7V=OSbRep8>%g7<+}rWPZD3Tz&k z&PAFH&TM;|LKAdk?p0aC_CcV1V4*$hvSQrZ{Lhx09AwxkK~y2C@R^+y!>>!p&c29s ztkYmyw5kf0Dfr3wap)3H_?FW@j&YY~-ule%W%__6lDh_${0M*#1k58BD&Q#{UEPj+ z?%-<29N88#F4k>P8(!pauE~*6H=1tNE~{BJc#ikD;-%@?sXViS45d__Fm+jk;NaZv z=VXUDIc~VYxCXKLN6U4iLYy zaqHGtxK-=nXa}4!3=K|3X67EM9tsGejs%^Pk)Ezbe>Mm>mi9*OHvED0TPBj5uC89S ziUw}#Uj^jt1~;7d_$=uVXtn~8)wZ!oUbaS2BL0c7D#Ga?-VdWtSaL&PTJN9s9`SEb z2^n=WtG7eOl%QbZ3Uk6*s>r!Rvh1D95eKWO=%V}RK1fx(Y}F1GFkK@1_U*$<;sEu5 zMH5>t6<=)Q>nkr0^Af~Mr5>k&PSHOW^9VU-z|m1qG1tv7Y5O6jU2XSnI$(Gw8-5^O zr~Q_}Ekkd>YUH!G=b3Fr!4Xy7;l$qjqDBnx!O0JP0HwXqn$P|C`rNg**oDW*(b3@4 zDLD=fJjW|k)Pn~PbiDAU)?=dOXaNX09Y`s}(JVAJH5E+o6^u;8zcqL$=qP~|Gd;}~ zH>-?BNU|f^p+cs@Md8}v!s{qiv^6!6N(9d#mN8p}qiMW#V}&Y32d#Sq zUn6WCU|t>Ig`tv*i?RI0g=b?~lh4epr%S=M$eF}x&Q4*Bd~9ohv-Md34D>3fSxE@M znEjFIUN~A^?Ee?UY)nOJ-MWil6mgHRQ~X;FGyYV)pf%5^>IHcZAp6hYI*i!_-l@k;Fd|+{Q4=>4-^F&KSr{%+2E_87&|kUTU%%6 zMYyYPDF4cN;M-*Lh{;q?{bf!%W-E+zO%sJx`aZL!T_`S zav*)~YPHZIbTk5fmb_;n#7=yFWJ)!9V~pFd>4RBK6ROrzU*4?U4;zgjVcDUd0MyOS z!?PHruG?wEIz-3EWBPP~9`+rua8kmTy*t||2WnUi2M^q~Ay_LH$~SDtyP^aU$l$y( zJi^pt6q2uo53B_6xncza^%-*i2m1dP$kxJ1WEd#@3gM_DxIbErl`B_vpF)Mi&H-UN zUC`3H{=PngJcSsCoYd5{W?5hO3UZIx%Nb{{4PfwXuiI|$biuGgGdI5{Xwu{0!{kpB zKFyt-4ynWD?9k<$MbAR61W1Uz@*pRlzldy1=##&ZuMZuw!2<KM$e6kf~X7tE!RSh z<9vHFUp**C-FSR*1`0<^%86dA5{kCUpNE_KBesfrzeI$3n#O|)Nz@cn5R7^h?SvQK46&G)eUo9wjB|Mx3$job6Fe-h$TZ&;oWT4c&?-nAPq7?HZ zuIQjwTybxnS$xyG{{ZJAKM~V?Ga_oB$36tsh46-5Rd9*=&kkPu_U&7rJ9Vt5d?j8+ zuE}a&iGOZ@;$3$X0vJqwCzsD@<=!0cx}~e}{0LAXqA9w(O1@@tGi}M92v6Qfcw~8T z8I^LD{P>(S}Fj5j&Xumt;s8Oeue3VWKuF1cyQj%K8}rt#K9 zZlmc@2BDtivKhyPuFTCa<<2O3O-CEc_vYTjlOKfUuoS2hu2W_->0n@P&p`Eh$j**& z&6UMU$;(mlVQ(LT50vP>5nF*@4;zBfx>=yABp;LLMWC0FyZa-aRX~mvAjNbHD>7 z?%k6q+pwQ^pQg&^h3b~KbZyW4&kqGE4>hXQo};7Qe>Xj8-{a?5JCPSX^W)<9-3AAb z*wMzBi;&W&0h7S1c#Hy)3`mEoi4H{Ch-rR{1nN42vRpO_oEnMhg8sku#S2zkKI$N1 zd5ne-?4SyWVz7~f-jIF|fQHBB2%9SZhCdtlb|AK zfBW?5Q_CB;?yIbUFb~TkE&&(oB5(%iCr*6z1S&yh3VFrIV;D#z|27tIHpjF~_#%(K zM70`y?b=185aL*J&-)2w8q_vCumq7uPLK^)Uq}gzrG|6$+)@)>2#<>N4j$wSYUKGA zb3*l>OI>aHjLO@SCeyfLZT?=d5?r|hBHD9ht*u7!O%LvQtdBP7SQe&_dp)zpOeT>B zkkLOuC#>XDH?PFi2nit=6L1t;C#NvvM{2wBL_EDN>lE|iqmW4p-~b>_s1P!_pUH{> z3Nu8$AR34k95EoU5X>2MZ>PvV!7ZKkCR^Jx8`Y4TE)<#C0 zFtWANkjsOR&?Irb$;nA}j4_9PmlKVb50VX}p-Uv0O{h`Tc#_U3{!0sh>p;L*#Ei z{!F#;t9>t0C-0Ywi;*zGwde*(ivu*?79c5k*Qf#D06Ys<&SQA#aU20*x!7$IhHrHN z@DGp60y4WEo7n^`qKE_z>0Hnp1j7d)2+FW~q!djS5Z)8X=K%DtLgyZgTM@#Yi|8G3 z3D+P!3lz;_Z~?%mA*zyGF+PJC7&SnQ=#1~MRH8}Ve&{4t4N_lLW$PuWLi|J=Ti^vg z4-X$gO1$J-s~!#CQ)t%L0J>nHAgX+ffDZtp^)FxUfmncyxb(+F93RNm=_mkQ=;Mj$ z{><+QP0Ute2HJ-Leg|C84p+$Z+WrT~deD#VVLIGANSLP^)?Z*DDMF`}@;LE2n~M8aW>6=H%Hw$5Up!_NrJ1dI&tf{0?@JUA}+sVRAL zaWa5$0<@v6dVRnFY76iN1FFABTaOmzDNfLMrG7e^r$5S|@x^hg%}lVPl4&JXXC>#a zs0bODuUo%9%tGrMUbqNK6#N|%zbZ5$5ctjj2d1MC_Db^Lpgk;WxCVF0TG%r4qmE}; zVmvprLOTNIE1~Hrfe2vq+&@3Yd#|9_(Af1F+vXg)f4LE)UTXB$rkneF>!_2=79PJEaO%#3 zET|xMpfx-(_1O?dBhh@~OV^?kYUg|)D=EoBw&$dAgv0qn z*d`0fm>usfZ42u@FgeI3cS8VW0^wnhIFwRQ&=jw!p&`6}{Surei<)JQ9jf%j_fGCY5liP5%6N5V1mFT3Te50giib}yPtxha~3kYr4ee|d}c0-qA zog*851i~c+V9bb<)Ze>T9bkG3_NiaPalIqgfYg$yj_hITGCw30mPckC0ee6&Mu1Uv z+^4s3UD{=R2uDk>VxZ07O;(6PhV{tBtB;M=ajLVnB05Zt1rb+|#R^3lVo_Z0xmbbz)UNCnnCOr;Ff1F5N7QI~u8Jq`d$LnsdAVL+wQv z=!0-$*|wzZ@lsH3^o)JO4^aSlW`K)Sv1BrzWwFkZE(nqqqfUBMW)kO(`>>JQk@AG* zC7qD$@m5%d4Bt_A$0j83O(P-{qM7!Ly33J~qALY?j*9|+SWD!AS#Bo0(|r(uXCY&v z1@RF}sHab!&@3|jwj#wSQ7OPLB1RB7!4wVOy$D8QVPU9aC7hg`I4G#4h%QlBI6O2o z1*Dn*lutcn9vAW5Xt<@Pur=GxFIhqUrYuxd;6Ee zux*4~(B#wOGWM{?c`HmY24TR(FyyE@IN@kS(AI)_A_qS?4n!Vi45R@PZvmsQ9=JEIw+P=hposyf~^TCCmLB#g98KX94%;2m?^wl3;We# zKM>tyG3Fa(X1&tH>)rnZ?|6R|_{;_f@Fv)$*N&3{AOLNp`4{`nR~c>oh=ph8=%~fO z#F~PQy*<$#(U$Tc7iDc9QzKBd#x8SyD;n&NHx5196_2@|?rsS=Iny5JEhAchd%VWF z69^@Vv=gHT3T&#nH|>OClxbjmw$Y`4b_w2~3ydDI2Q)=3yaQQahB|xq4%ngIBO0vr zn>XvHDiKXH+5iQQPm#vH{|B^oV)NR;w?@$6qRF{=3ny_V-g_)qt(9C{?Y<{oF};fH zYK;-+LxH#(={sv7{E?BCP5~>>iYh^i6s_VvO>)|<*Ws38xb$^gm;0pFoMg!1++Vwe zqeF2n6UA;EgnaRjre9kaxr%c~G=KpH;}aGtftUfR8P!7OfW^Us+F#erR*Y=j1P+pl zf1KuXa<5$*_!*x&&_>mp6KhFw2Uc1I^CZ;t)a z1Dy@hWRN-jx9Y(4PHt61pzgtEupa;f&5e8b=B=gN8-oC7Aop)6WmFjLtGEVOTsRx@C9$I(Imi*K0@kBg=6w6rqJ2q-jBO)ye_^}5YKL-~9s=daG_sn}m% z1;ht@Kv2X}n?C`~aL7`W_gHsy-W5rO*F4(uvi9W=Vw1ER1n3j@9FI;zb#?0QDaV)4 zHKp!3e+=;Dh~^tJy7TzJ9oC)QT+4B$Vc>HX!U{s$vin+SZ)HYBvPXe z-{AXDQytD|BEJ!?f!Xw1LExW=ymZGX*8e6KW6S*=vwtMp@!W3JX&?*u8sueQ;lW9H z7IiDWW~YR1S~kA5v9BxB5J1fh_X`W@IMyPzntJm%foR!YUIwN@h5yTPX^@C2M{=*31#tCyW$jz4~(?>Zsqk#{Rep{i%T~I8nwTm z6z{%s*cYM9_~MgyWI~RT8qN>l zpz$6*z1#^rcvhzVmqDS@5PHVPtkkWtEd{TZf93l~#|A10Ea^{^AiFKW=ONCe*zVI( z=XAg1+ITkxhu(#T0*r;ZSP$;o`I-LZh&SOu`}YJj!(C)`ew+R6H~Nam0CfiRWFT%h zg2aFWCCB(eSovDp6}HLa&>`FAN*%+MIzmUW3kurwD}mPv#&?3`fe>|QDRtZ&8NEmx zRxLDBScd*eg4iUGpw~b`umzL`blAZ_)WpR0^yIn^#ilBddIGLG5(a}`n`f~ak~~L) zf&A+*fz$!JIPtA-HxU}6;NCBpJtFiLoe&%kaQ9UhC!xW?e>1ZW@bvORI+PA53*C-k zBpU7P^M4o}jle|!p#%f46e`1}o`;Kz zqCgU$e6Jq*{sDagj@a~!3`VF2p)Xua{l_#=OmdtH8b-95C&R? z1q2Kb9!Fs9e1N~~32dw1aP8)7R^vM^b=+BSKC7$edQtn+AvUi~^+|TPlNS3Zz86?= zqYJ^Ur_0EBiO%p4HtDvpBgc-hLXiO>J*npcA;!)(-7U8Wy|vcfy^ItzoF5^IB1tMZ zI!TWQQ3OdFli94zFVK*CE?4W-y7W`z7{yz}LIDGupNN{AG}pBV-?lw^^w~Zw9n(#n zi{uKQ*-B`-u-2FdeV_z6?{5n1GvY+O&yaVaQF8D=I32^r4i;{l&UN(us?4&{gAm z(;0^>3XPWNIL~ggV2(*!Vnne@eyNoFC`N1pvE}9feqUyLaz~{-Fj}h5aivKR*SW2}IRH z$VbRELeRIvV5*B6f|embA>fPt!i5V2V1S)yIr7+vHWq%Q(9lrFFIo1qu*A6sb5kF9 zq%4C#IQ+Ek0~o+EN=#DI7*>C|ao-)a!Pc@IJ7*eEu-#8B-jO3K|P56+6D4-viB{pU5i*WywlLJ49 z1JO*v>s!^5SW zOaQWTcGiK^3F&ov_cBvxK3f3f;8Hz{^(sDno93pAD*)^%J4LSoU2h7}P+`6~WP1RU zKa^Yu2{FRa@bf3cDeJdyzlIa5Oa?@bq?A+^?lD7@k7e!+O^+W35vxXg)6V{vbkrUV zjgkYiY}x^T;1W2DO3;x@IY+7-XUgUGfeQi9-wib8URi`KO631jV4XNPzH9Tw%Vs_5 z<(lO4%9elh+);us-7F}a=Ai&2l|7zTCLq9E!~37~byw@NuOIIn!7zIs9uFnN72dD$ zLti0;3YNZ^Hh#=m?f>0zSn%>!9QJPX{||Q|^%*64amoFXIj#4ZdG2}wwc{~ETN7{G zSV7?eGAgwRxU&eQd}JIbsarGtXJV^-+@vaDyJO%zkcwWMA9D;syj* znT;j^$uXe#v$C?Fa1#A_9bO@P7tvy$y=f7U$I+!=-D|t9V7b5;1W~B7>k+FdL$jS5 zCizS{vhVmk|NhgyMhqWx4Y{}r3s1T#hx>>CzX%P-gytIp*Qgvx2rhZSqoQjE#C8#3 zP#{>5r@b1;2^Q^Q6#1A8vE0MMqw>rj{wspYq(UTVxCo`JhJ6c)tAdk{K!>PVSP0+@ z!Cf|}D&-IO4+ZuUG$UMH5RgoOyd?J$MQ-=8t^5>PD$Nroq|G$cXAqNl*S4A-jlu`? z;wMg?JPW9kn6luaIdL!I|C6R9cf$YE;NZ!I4FUfCeV;!wUmeUj_mb{8#Qyn*xT94LTd?Er4lx`b7gZx9EJ{c^QqmF!Seg;F_u{JS$nZ$lRgWwnV_`w?m0 z{K%0*ycPlwI5SbOKImLXtwcRY9wLdhP8!)_zT;aE6~%Yo0O~*k{GgXe;=oTV+ z6niTQ*@pa1SS%F^Or3I21h7+G2z~syqy#?$I~UNE0;o8xm;5q`B92FGWFS0iK_ZJD zpxw;)4Q8#-;X2{1!Y{S*M>Z7PMqQmiAw%)vR7rRQk^7)M{0vN9M0oZLbF}+H>h0T+ zNW|3#z>o?#U>quC;4wB8KA1DN$pTcwFd#PgvnyE5YdCIMnVC~ zU?&W`iU!UML@rd^&!w<3A8=C)=_8eJ)dMW(UC6fo{ zY_G7195Lk0?$Dv#xRhlPeK!Y;au`7Q@wlb~X67G#RIL{@jDIRw8rm!k!nxT1tOqsD zy6NJ*V5%-50F^jM?r=4|d?|(t)EwXpai2krjsMq%;~6@r?QbfUo4~DfWFI+vaoIh) z;E^9LIle!1e)i*9Wo4VOAK>d&Pzfu4aSD*>0{%+LjObdjdJ^iN!Ivam7;QOa_!0Z#52vrT_d=BO57A3(XedZE`;SQwVWEoe zUsE#q>g4qI+2QPDPKr4Ca=qa;p@+oyjO6flaWb0@%If{;4aaZqK3h4On$>V0UAF?} zkZk8bYo&{wlmey*zUj4RRa6i}3SiO+=Otc#eZvWCb=3d+t*vjV1|Xz(UsqR`Cx*S| zOyUT`k6l4WK0gaHb5vONfevo_73WRXy*5sIB9iN$1y`xTf2g*+H#I5t?@JY1#xf8c z7pIQz#SM_KVfF8-^}%+&jXUn=3Z}gX#0~gQ zxgFV@>hY;^C?E3wWOR*WG4H9;HF1tH2`Ib*_!1EiE2!4a&TOniBgii4NDx#jnn($h zWoLeU-A=E9cK7D(@;RHxPjolz&`?i0=JYS|{bOPE>%^Xbe7i>|z&NR{s(_sjzCtFL zPX00a_fOYG?#`nQ4%_Ro_P+jId&mQZ=3C$;GTVR@=m7}v#9jI7S{_-7#6^mRC0yWa zCVel1X;#%#2e&yhD7}gGiL<7ziE3SDoQZOfK>6P27%n5R*9?`Z~*K{eEb$Vj+ zua$4p9M2iNSI?A;J^C+HG3mch#jYnl9!@#I^bj|c;-xd0aOc#I>YEIY#%~(PdC#*U z_TMr&IjyNYw&IR_ajsdZ-1?ZI*!m5z4;o(r@&xZ%`e?L2a7+90|9XdEBLN2kex2|o z@9^f$Rn8E)dwuPS#|6k?QYCS9X3OOJ{W;~OB~{}}&i{+O^ai$~-4DYbN_*b_Z~D00 zjY!(yQ-#q^tnjotQQxY7f6{iLp0g*C5Sj@}IOGWi2=eBlk zwk%}_QHwx@?I2eSA%abRl(F~Ie+llo^wVq**5I}+HFtdTaua_}%CWcV;obx|{)Zx{ z+~OsFotFD{PgmWp3h>z%kdOZWwa)}r`b|Y&PI6tL0+(0TSc8IydVESc>R(!be_CMg zw4$tl1-8>$u(;6T)}`<-+{}!`Vh_3LQpkAxajFw-4+lSgIH2nKcC#N!WLm{c;Ez{I zQn}8*7Lw`I*>*Fjsh2WJgm~s1A6)cw@tyTE_oYPy@7<8&$f0EhEjy%s=E9Rms)EM1 zGI99fIdgI694+Cr5c}B^yPq#*4p*dwDzdz|-7Dzd6vp@J#Z5jHrta}h7wbk?obJC? zazLQb`=Ku;2M>nfvoc#3l$G%zu)+tzl|@$=@_#DAR)dZrs)5`%9TF9HiZ0i;A%|>! zVRO}tFx3Z#US*_fi`T-FnTEr|dzDRBB$*j4&-UWb_%(qLg3)4XzmX9=1?fWWYk!c> zQCgxtV`W2B(DINpU2%%QfCzt@K+4`BG$206&+cm2#5A^hh<+_yAk!I6i)Vk)Xw)8O zjdBLsBErM(!lX2R+=@Zs70rD`&MM1*drLarUs)UB(0%w8M3T-fE`|pVghFp{YPO3> zpmmR_DK`loh?fQ4^u8JTb$!o+Nkni!Y{r=PHF35DXifx%1@@T9156FB{=AVjKzq+# zn}YEO#qvgIA{m2D?Pg<371_+kw;^dT5M(yalDD2m1*M*#I$j&C6$Lp5GHnl|ST_Ie zJuqk<@JXrMe7uBAg?ya+U3Bh6HUw4_5!5bv{t7w>D53!W=b11ex`apqAP({YO2oE5 zW5r<0^kmtcU!4axdoWm`9Vn@PT-(!}n8+W$#64x22_AcPKxV;VVN0Byov9)v)>Yl2 zf1p;T3rZG(S^6p72pt7-gQ59M%pag3cyD_k`K_AyxO6^b=+mdPj12XD-&OFJ(em^6 zz))SWa=qTOxjDc5xzotOr?8>E0cy0x>!@6XLj9a-Y9EhKmz2T@ua@@q^GFNjG0NeB zc;y+057HYUQ*!N&9oKDC3LiYsbaGmcOT6G|^RVn`h_@BEm+esf|P^e<>Ds15#lZxkW5fj1!7(HHxRB(I;ck(S@N6Q0&P zR+=pxHn9?1ES8l%9H^N!aBNil`C$Ph@oqsA??d{1$HM?wzrXb6nsGZvTW5rCbhc}6 ze%{_!O-c}dzxT^cFF4lKd{zI;bJe8Xn!h*WecMWx$6WsLVI*Kv=W&k(47aH6?G*%o zQ+no)f^r=b^UtTNealRf%a#XBaZj$BO6c$VG!B0R-RJGe!q=W3a&d`(&cW#J7u#y*2qm0_k;Yik*hDn-l9ts#?y z!MoBsT7?pZ0Qg)@;2EUQkdR(tlL6LCBzfP!X_JwX#PqQc=7mWy5RQ@ktT;Om%Rl-Z zwIhNF&+Zkk#phiHRU(mY0b-Eey0sR#?4E`;NRZXmEO{1?_BE{yx{Mt6jS$`dP*`cH z*l!@g^_%fD+(I~`F&C2we;?^DYXQ!pIIn~6Edmy*flr?fV{`BizJ+g_=vQ!c971); zi;-kRX^YF@FnERELyo`};DjyH(G<$ieYdEl#O5&bCgTz-*?#U#@1znF5FP`M5P&;! zR2mu>P#~lsUkZI7&#IxHURcNhfhD|a$}mY({Mly)TMf}YV!LUWTunXpu7nM*@}j!% zZZsjinvfxIA)fj6ZhQV<>&W*{iCY90!ne&ih_horQwPF_6@@Z`N~v-ZW(U5in#azj z-MOQIosC1q#Cm{F!PBv#%EBxGWF;XUpz!(7*GB?o$XGZ3cXJ4ukH8rl)@ot%RyK94 zf>!%btE0JD$fqhwzox_coi>Ntxs;NUs|zFNp4ZJDIXt!`81Qv>k1!afUH@S3T)ZPv zw~zdJhn2)SR(oNt3)TI+joUn&r(8rE32krVtn07CZkHwTT5v>YKu<@al&e^$uer#x zCjDX`tzaIOhpL^%#<+Tm3bD88T zyY_N)WW@H+p_WuRA^t6A1$dvm1XBLFux?E{u8A@33oZMm+ErXZA*{_Y)8}? z0vDL*U>m^>C@6Bm;l$Dc%L3kD51z?unl2(Rkb3Z)?lejN0yrcloYvK44!ua<6~w<9 zVP7o#gbrvJC#k>mI;!aKQ+GumKalS?43!`q#y?vW&O3gDqAwGT& z6uIkgi=iw_L($j<^|I54nhOvOtmXY;z^rDsLbcxe1A*{9gDD#t9fyG{71i>5X_WpX zBx!9pgqBd)PHjK}KSP!vgnc`|hG>JJFP-^Ltm|+!rj1-VRM}lH!T1Ydchi;0g;&C{e}!;mY>A^~)M4XBYytAmi4%EE1z|I=uH zV$~!&$7-k{tbIN#@`D=>>_RApo2%ng_=;KrEUOwYS~4a#sIX#Fd`#LnE2 zvI&KjhaBIKUOrV@zAMB1MNiLa+zeF(le`QNJl5fxB3*@^!WP5r^Av)rP!!*I`1fy! z+3^Zk+T6N&^=SLx&jC3rTu7bPr`eEs(6cF=<)3EW+}vCQy1dNJ&dN$lNuiL>!Dw4K zxwZW2ogY8n`kbr&>^t=gZqVw_J9gPCwpa`|^oweoj?)nX>hl4)or@R7a+qg-Z4_5q zK8Vs_X4GaO9Ed(4)bM(GHgN`5i$rUA&ZCLRD2_xYTKTPJ=~r&vHO8PQNqAzsYYPYz zg6AGTK7Kjy^)p-PsZW4+U_;i#vFRPrx@^p&2a+ordx2bpoMV2~>Y$U)n{20y6>1kl zhk#0ME$gTQ-!2Zf=+FqYH!B_ptzfXQ`<$vcSuf(~<`#lFi_{m2kiPx>JZkC+f!(5J z7Eh#Z?Fyx<(!aTbjskyb9M*dRUF$n1EwL8=2G=er764cxXxad^JD|mSI~j7rsGmpj&mkDnA>q?N2;{B6d0z}3tc8Fa zdwB6*{|Cw|@E2-8*MnaFF?x6PsiBn>Tbbo$U^9>}R5vv($J58XPS5cHH&HE2wtcut zaM%Oie%#o|f-NCgz7!c0OVGq1E^ET6n@1n&QG{Do14N{VM-nO+_BfkVgU=?Khwa7j zHAMU3&8(4qDUIeQPlnx2+HXb3oXX!WPTKQ(%Jlu^AGag_vwStaXZ&Ktnc zJ)@jBR1KOW4waBCaNKwHeB2VrbtIx8#X!OlA?G;mv~r9&Ia=_kXC79Cng5hYf{%Z2 zXz2S8B1u|t+UAs(Cx(Wilp}o1W+HJV*zwDkFUc7K)Ku((>TY#)2(c@VL(Hg#(p-cp zf)7;z@itJH81CE01{Hclui$-f`k+c?D+!$kvn>e_VMF99a1@`}l#*<5j-0qX?d83> zfOyEXx+WlDddLtU-vqos7Q}ZXk%BG-H5Jf;G(>;Fq4(p*Yx4qh*O};|+mNAT+=}CK z7^kf`g$V-6;g>IGg@iE0E4mIMoPf(pQzz4?=moCKbs#;;p_Jv|aP2OQrVKDH+Vml> zm8RLRU&j=yZKo9do@4vkdP+T$yX9lx6E&pdCj#faEZi{sD3#!3^nS1->0H#KCT_^I ztSJF5?4`Alt_H+#g-EJbN&B@CD%S71_tdG9XDJ>i57gCvKkb&pZ>?i}M13+cYe607?DbNArsP7XcK!`J@&BYjo; z)vLJ!zee&P^lKP|(h^wm`S5%b$#@dMfml(6QPW*1yqYE^E5Vb3m*x{pxpd=8r|2Uk zFHwz85Zpzn3x60btgM894dtcR$kWgKZ-g0ws|_x~!^axJjxPD$p?|jME50juOzdLQN{6B%X_!VzoqJ zd*Yt28uM$ zU@j3wl0<`fPDqJTrU<1nQ)DQ~lzE=N-)-;xp8cM)&%4(5t?#V8)?S@m`Tw8i9?*%Oq)&frF)js~?`#|A5e;UI_4^JT zVvLYhyb>4D`{Kn5gfOZb8}p*mHMoVh6Y}7J1xn*fm^@6Z(*)fCs-|}C+-6{L3n&no zO8rW6LrTU`1;CkU(oH4G8Dy@YE?e91UuG~vX%LIgBmyqI1caW!rG*XL%|sLRVCu<2M35DNQDMhLAQ zw&a*$w)gEKd5rM{_?rhMhC$`f;2^0QsXXG1hk6+5(`no&XkeAm?kgqcK-IJ%NPG4h z5`i)1GijfF%ZkmA<&LMrshr$?#&pveyTS8FMWH$#$xb$WAYKzF8X{l4I=s#wx)mgi zjC-<2o_|g2sd@!)?+<7xh=c=V$W0ubcx)Fs9ab{8H!z9wc6QjMl)<+Vc1r^Dz{rqzzlkz6gh%zMi`g~YaTwD`bOVH*qPzg_- z6qW=CLX@%yDh4X~0zaM!&M$=B#eCkO{Yy`xccF2OV$R&G6If7luw@huaUDdi?~$-W zKZeJ>kh%m>DI4}XcI8Y^=UTa_i-^sH7aS-gX-ubc=f>th!(Jn<6HKZhzg-e)mkUNh zU0a0MEbS;h*p~n+65SL2M{0|pRP!yHH^ZNM9gRTi{S#qVj))Z_WBtiRml5@;;LuP% zTnYWIjmWu?!25yY#duwKn%_IWfZoT^zkl0cP{<H{#<^?l%p}3Gy1$lk+Lni5Gl9-i9;K% zS;DvZVU{BqivtU1b!DY0ENfCw+n~oG$2laT@u)m8Wl87 z;GG|AJ1?{ZW94weX$b}Hfm^wzwstR^Np|93*Z!fwa&VAVnCytAcPCS<&|DZmzYNMU z7Eh=D8Q><*n7tbzmN_ZfjTMR};XU#ZfK+IS1@FTmk(QA`#Q>eo_<2}Jb)g^o?x8~$ zfjy`1;*xC^iZtC2z(bw5S)A)3ut${G;lmXWJCeT!5x)jDo>|kAwWLkka33-P9e5{B z*PYlIyB8eLYm+jT=<}4LTT6S&=ytiP;11tz2ZLth`2^tj!9)m$82t_2-U%osa1)Rq z2l&+r+ik6^NVLqJx~|1;Z_DM5TE(wl=-T^XbdRZN*_aXDQ&or^-flJU6Ix|pM2@EM zA|2jMxM&3^Kq5u)_)>de2&aia*%>rF>AQ0{O;%kUXV|m?#AB}8591VHL>Xt<@3d1G z2`c9535QmiCL$|K&ad6!=V6JW0ri9B#zV{TcOyIO$Ps#f^u-*M>&J37U+djo6+>); zV+%M}W;yA@t3Mna&%F5MqSs+sq?Y56O?my!su-RKMhXa1VoV>RtluR{ADCEaTM)Xog=^r zl=UkjU_8<5gB6zIN?#!O+zp?!;__33sCiVZgU)~-4lJA$D$o=CJhu%sjlp1bZS465^gFrK)zt|CFa+Qa1?83CU``^smXeiiMVCkZ zAKa!yZi@gLoB=T02q2?t^L=IxAsvd1;8lk()eiEzJqRyEL%$j#Ew~vA!Bx{xK>K!} zS;E!FiX@o`2mjHGV`mKx9#j(xMi>_@E*r$-5VI$GQ)TsW3=kpOAxI%2K#*b9#8ad` z#>dCs=v6&>{5Xjm#qM-A#OX}&ZQQsBeJ!a&s65z^@tdy>iY!~4-KF*9qdFcf{hPrL zA_THRHUd!p@iiV5RaQJk?&e&WR790?Yew5nd%@jrhDk5ulijJW_sM$&M7&>99?w$w z>!Np0A5G89*7BS=PLb%_;`|J{vtC?EyBPURuU5?^#)q-Xp8yI=MVwoziSGx+1ucTf zFz1#;2fz7-sbBec&?JMcy{>J_da&=Vc5FW0dG(G~7f z^E|U&Nv%OyPsPZXCTr?kM0dN$wet96>sB<Yw1q8sxMxyZm1WcU6uL$G< zAah~}@)44@XMpK5>guTOj#^q41QYe8u()_U5OHD%!p|O@I*zFSp-~Y;j9|2{CS?U; z+8$~IV!r}e;_8MddY8NKnQu@~2rYXJ2n{PH3ZQDaI}II4V+>}Y4VTCey_qm_-Uxyc zOjTMQ9*>p)eI>~f#B3T}h{}o8hgKP#52AF{iD5>mptcCr4mlbSh@Ep`to`rJ*6B=6 z8>4MFiFecmfF%(f!e=8Hl|&Sxt_}udEwv0my8Fd7>IV2+n!eqyuCBg)M67*mF6jNy zyMcjKjTR$X_@MvX!hVggUBVTrh8}J5ZtABsFOmL{pr{qx%%724SL1)a!JVsKZ}9}X zh5ndq;rQVPtb^-TyN;V>!kagH;xO&=hK zd!O*R?!lS#iHqnc*9jDK-;U(5zFpx3@v|vfIRz|ddylXvO8Q`U9FD#CI%?s zVDXFh?-axV)Dk@`1oZ1E8xd8nCLl>R0ax-n7H~C05dRLnI{?)9JH7bx!5AEooJOas zr?+0iWytM)@g}uEM0QaLNGV^}44d^13RM9ITLrY|23`9S4ep@%0hrnSqycL+fB5lZ zVQ6L7VeS;IG8s9)eoFd%svfUTz-7p!*Ww6q+$1i(o+3{v)KM~v!E(NjZp{l>v9fTS zE^Crc(p9q|S9)a3V(Kg=Z>y~@sYzXbz*IM3id~h%u?wf#Z5X)cWMy|&$gs9yv0-}0 zf(45{BzK$K9O(NZpjKyY)4C|l-eHPw@;vS9$B#*xc?nWM@NK;l94Z5x6g}~y>X#dj z?mReEp=rm@E8VGpEC7Nq;7CV~0V~FV1Y(sC$uX|U*XQm1b~2~QKH9WOJN6Eu^LA1l zP+Rrf>W)5P_tdSc%viI*T@DR&`Tm0z^+yht9kf#0XH>ObsDMb7;r{bBV9qB4#m>YGC+ z6Tu^@s43(*h|&H;WM!_vz5TZJVk^p*&`h2)BIpIcQ^S9kFG0oFDw(9Ot#2tF3P4srSDbkS3TAEc(ZbBxx5olEEtohUET>esAFIh8b6>k)OX_-@qCOM73(c*ZT(&rT6j~D0_o5- zV$X&sJA|CCg2;1vbqI>CcbKHso3x6cARXJh2Nv4%7xk5^H_XnujUOkM1Nb8@i|E@jm(k=>jkeeha$QfgNCbjzmSz@`o=>8 zKE5)f7{n{;Y|Qcu)pkUwfT;;sqm_SRk(Q;_;+X3Sp_3l10*L?vGdp_wUK z>-B|a#3_%2Rbw@+!qAtenFE6ZE`tTgZ+Aiu z|60M@Qghe@95`u6soRJdQka__B3N;m{17ut^n2jvS@Sbil%%#Qj8yL%hGV)4Fxtc< zKpd;rZ&1yXbmIpQ>gpo10+J}g5}~Rw7{rL5z_3d{7SSrBE<(i{e{LE$1>vZu4!{AC z=u5g{lN1N>0;^E`s1s%mwSVZblTKpWJ@Bh4j0P#F8v;Nuo~LWuS@K-@sIyZ70Mk48 zoN&=qqA*Cz$q9o@S{v(^-W?&Ts@UJHWAe^W=2*eU22y_~xXfwSD@ZzwLSrs)vQeZQ z+4YDSQ3G_jHb{FBrHk3(Sd_|0OIfXZf3qhz4WqHgZ!^O3JO(PQNA3ojIfbmF^tWHH1ntxu?1M@-E0ID92;e#wqKJ{&HFdYZ4-Z}Pck6N7F%6ev7lb1+={hiM*&AQ{v|vJNc*fhm$&Oyl`nhT=^8p{y(x3kj); z{j)jzZ8ve2jHp;lFBNE<$^PQ{t=x5Qg7^xL$&tb?k!xAv`QS%(!h8=rG3J@xdFWIi zYJSaNr(w=qcD5Me@~86MMLvprSd(0EF6HZ;e~ovcKa2hU6kCg9fpxGGQQY3NQ_wlAhtQx4{TxU?J@uI8kZVaw zF2DWC6|69;PwVxGT~ETiN-S+g`^4QQm}pvt9AcI*k_y4tVO`uOhY@E_p=)6(pS@<< z#NF8BuRj;DZT|`^8|U;9j1kcOI%nv(KgoB zk?78zJ$*_X(1}0WS24AeDZjEsOrQI_`k&T^9~au$ppUJvv~~=D+ZR; zALGv}K>z_rvaWl=+A0mPt?AQJO6=X`trD2auVKo6&3Vx+v_a)} z*6r#*5?>546u|4(fji~Ez^AQmK6r{!7aHnyh@f3vjf>;thAu$YIk%+w)EsEE!vgpB3A15p5 zgQgY8sD{_iP&ZovqBiV{jgxX|f--m>SsMQ)EeAbi?;r&{$-4uWrmPD>5UXG z4o{LFIzPZ|A3zniO%f8fv7UUqI{@Ua#lzQAoLEb25eN=Z2Y(4lH~|xx^;3}Fi&fiN z3X#gnn(FFu5FX>{pz4F^+nUg;NUksLJYXMxdExV zfKpQ9B8h583ciX^;D9x1UKnCY)D|$|TE9w3Uq74zgD!Uz?Sn&?SGhe?bk8^IxT!8s zG4UD+P#13|$_~3Zsh&Sug!k}z-zp83*vt$TjXtlhN(>$Yd{u2XnHPJ~LdZcdKxzer z=dKF=3UZUHa6*){oy$+?>G~IT)pH9r(Y*KX7h!3r?B5^s;a})aW>ywA$}ZTPkZ(v_ z`2evo3w(jVTjKG@aNe!kw@1Hx$%T4Z9ya3dot-{-*+XsrjPW^k{wIW_rm9Mj8FT-} z{I?99os>s$bG6NX)i!pD{uq&lqVNHNC;`h8kVWge`<{gH2H?74!C0OvAU1K{`hWX& zgi0=JLy!Lyp*lf%IS@u@HTSmo}a59Ob6)=?CyH7gq%`tq)$;oHtLK%P z#(nkjWjO$xjljtOAQbl{J%FkU!Rry&N4M|aUkNot;NHX-EcZPK88N+u3xwFSAidhr zJ-;H7pF9EYQh}T}ZNvcx0kxb2t7vd_>Dd^}=D_RHp@>Iq882_6nBqI~Ycv86>}X#w zyxdb(b>KR#Zdzq{7C7Zo{8641G`2%JEQhhXM76Qnv4fus|HOYsEz1!q=b+v8s@h== z@I2vDkicJBXA5eYre#dg#>m8|I{fvmbQ=CI?Vr5%?Axb?JF?kBUntPQNqIa>8)8dQ zlQ$vYC$ykz!z93t*kF?=eEH{jWsTlxu1%YciqyC)(7jwUS9|<5X02d=<@LT?=)-pb ze~pA6-|xyNsgX>J$+C=RpiE9?UodhB(q4ygssvVKq#*0thlIa15@|j0qyHhZXjTi# zXWeyhd}{2uvx_;-xpk-qaPjJZ(2Iu~wRgpJes-C#j@2P9UB<&2QzxFZE&>vtO)9Em zL=f?q`Aw$HS5>M5G^+5#%aWcfeU=2Z;dc59&^q9nz745?w6rwap6;Uskc9haT?)9u zR9P)ED9={$7g&{4Qg`94FH@Hcj2j<5fBqFpH)87Om}TO~)S0le4@3hbOKh+JRKVN1 z0lID+f*Ylz3?w4-{-&oW@p<@!kKIIBzZjNv6jt@`-$oh;TSGN~VKJ+=miN9?bmSIb zxftHSkbD?i^&0P+foVPG6T4@T3(pb3{U$3h(P!`8z2oh>eha7(#K?vaL)Ro~Rj%Al zHpqPcVDRx=a_I$*8EYdu7=W}DBXfMTF3xRSn;UnEsdKwUq4x!s#6PgMA#0o<{66Y$ zrv&h^>D@K_SBq-PGI(_48xh$+mN|Kd{MXWMLE51)Ch)VbIXHy5E4;6-Id=^u0TwyP zo`d7;54el1<&Xa(s-hLU*AFuheo_=#IN<7lE83%x8IQe#1UW{@cvY-urS{z0Ck`DGK?J z*R8%vpH&K9K!Bf59nTthcZAOlxsvH9f8s;Vn-XE4wWxW#e{BEKc^|-^TA8g`#{#Z6 zIZdH0X9#Vstc)6zmG#M+>HhVL6anB%f8d}bamqs(t`(7s$KKJ79pKYM_$<|9x9}WC z8Av4jR}yB3133N;x#Uoym+!K3;FXTGCi5LALpn*iWR6)B_iE?QKi5{o^zJWTzb5Lu zDQ!DPRPQJUmu+$aar-ngvzWB)@rliJOJQLlL(1_Ct{(HLsA9c*t);j9Pw>PIaza{) zMEe4lRWgAZ2hw)ynw_DyGOjdffE0)NAPqWI=$)bOqU!4p8)v+ZZtKQX7T&P@9~~8W z)z#^{QcLHxIBITEE`DWZ602=OY|Vx>dP@b=AZ>H6&0Iob29QKTT6zb9?ohv9h29L+ z$)Hi!G%lW+L$y${m}6U^6bsW!!pyk|PAb=h%y8KMxxLBW#>%Rt3S#wvFP8rNu!x60 zTKIPzh`|S|?Ezr{0fZujHj#9daM!DWhQE6C>Ql?&rEf3-2aKYMnOTHYwx|6v?Ndp+ z8r}sW7ZGJaG!{RSPN;IZL>I&he}sFx*^q|%ODM8v62Pqhgcg9AiwU8>$RT#G4}nJ^ zMZiN|h-*B(iS8C6yam^;jWNzTq_8C5dc(ON5Z_aVoWYoqKoWz{3}yx{aQ{3t2C`9A zIEWYwLXi7GU_uOj#ph^!)gDGyo|S-^$v2=^NxW-pYRb}5=2ROXQ(i?JU;{`+{SJlx zc9PZ#n*!<_6|rDCs~J^X5!@sOh14ydDrv!b7a(HK??l*T29z7va`qw6Ur+XHz{vgpH><2nC#U&mU#!@me78uP<5~qo?zVQb|k-%21wd{x* zC-sXvNM0zCurU?_f|wpjb=#5aI)fs7d>dPB(@NjZo?jU>?BYu~SE2}HB_a02UIXK} zKaRp>z&OZg63i08D8^gJHg0j7ZFeI@APnl(-+n}ZY6EfmW2}DePePZ4@2&sJP;+TsQe z9*GPEL+69epaq&Pl5LDzkNo8j(ePpvndm*ZX#jS)(oWmCO+DO@UE{Ey;1KCkD~K}%hyyV>;lKVIas{@?xOnl8J{5o-uct;qZoX*vtmTVxiH_9Y zm%e*)k_50f6Tco3y)inAvjD{W&a&7yDxs+(CY%re?&x#}0DX}FE370BgeJPzz7I!` z$$+U0dHoRQf6tvC%0z0~iZWHbcC5A?P=?Hoxy^Bc7W71<7>aDO6DNxM^c3N@FDx!* z3M;E=m?1+8(Xx;iKyqJE{j@%`%eex`#%?=vKyq>pbCJhKz~&gjMHk`F@Dd&-SRxip zE+z@%x%wDHzkjWeP!wqU(9oLWuOXaA)>(nw^_OT=ropBg9y92>4zQu&!vSEQ1NEwt z=*m_=1+;)7qn**~;77J|hGXh?MR~b9G-|N3tibp?p}5_lH!wfzEpAS{iF_FNeviAoj_th@LduIC}Vd9oO{ivz#HzNcPe3Zfd{jqm)ke-H+gPsFlxtP_+ zlECguD!x}{Rfdy57k$liGw5{Wv|HgtA~ZDO^j+VIz>bq{;Siy$`Bfz`{O(XON2AJ# z7dKNvlqBF>dVQe+<0to5Ru`M9t0U9J9=PVx_az<1PX`LaB^vT<=vwuzO}jk5khIh> z&vs|DAI>4ndA;~^GqXm#syaDmR$qdjwsF&*zBXW~nfs5A?=wYy`s2~M3mU+ySMVqxHvw>n@cbk zgf#5XJn95@C}PV}wlqTpF6BB=W+q=U|KZeRc^y@~wc1l9nCr%)kK7o7%}7vLn9Q5FeY+gh!}B7VgG^JT64zO8wG-ZxVXPka5UD(8s~l* zs39azR&US=lV3@Kuv8=Suv%E*i@>c6(IU|~AoWT(@T@IZ%WL@bP_~UriCxfwy$PM+ znYIthDR*>A$Ty`wR&}8V_}y|BAMfTLpYro*5M>H2ygRl5_ynT$H(4QofzGrhm)n+; zD+(vuw8;mH6_+r;v#%90G0GkEbkO(`=!^4V!SfSHSpsZiaKSake!%KP-VY+Zuz7Y= z7W*&pQFw4L89{~g09CQz0*DpXSaQ{mZ3*|PFiK2K)r3YH&xg1~aIQPU$OBhIZT&6j zugh*h!Nd!Z3<;D*AI5}89mTLaIjyX>pxA^f)EvPa&QrgB40L+%KU)-eniIWT+WA?z<-3>>O(_ixasHm#|$4UQ5PlmSq z)yF+fOk}%j`$xO%hLM}5+l|*iD?zIa0e>_U_9v~Z$~T;{w2ZDjm05Ez(O@sCJEGR7 z^zk|HN-Iz~)Y~?`aGi17EGZd@P*P|DQP?e_z>{}9xyaz*0eQ!35)%a*bRZIufE;6& zugV^-+(kx7V&<{Q#hb+)D)ujOQ}rgihWk($!~(uvG@6at9z~``(t+e3r6SM=fE_${ z_G~1ej%*jN43uh<$f8?BCX`m8Nh9Mvsd6ZvJJ4FkK*Ly$%S3}hev)3BGb%a()#K__izDy5JFFtEmIA9{QcH^2*U zpZIvgYT?7Mbd?qku%AQSTb3q*Z21=sk=X-y1%y{(lf&awn+N4bIqRd6H;qUdY1)LR zOj>fu5>b7|m9Gq5XZfItgT^eH)6B+$c4_42orwnA=_R*ALqCZRC(gkn;gj&9b%8R} ziR|l4Q68H){;Tz*iNL|$PiLv?Xq}aDJ4aB%S3gk?Uk~>pCU1U@Cwvp?5T&z+V4t7} zkrQQaDdFvFNBT=&I!nW&9a?i@cV|&Xuv5Zl=iX1%95iL4;0iM=UFM8H4V{q-Ws04VP(GzvKU-^926!kvxgIH3gV6Ir$%iB*j*32 z`*IhM!jSkwXz9;6^nH&N`%4SpK$IXk%r3?J#B4~}L&(3Jck9Hkis{$%$oFF28+RpS z^PHS2{KnxmU;$d@I1ly(*FvI)(7%~)_U$0^%%)jrpwV5he!KSxazbicfz}qpMo?ns zb7k~x#Akz-30H7FsvcHojb3chty@ufP(fE903!nokBP|qSEqn)n40F~#mHgU^C)-X zLon%mK8pcFCq?%$tGc}Q^xW}U3O^%f?$fh5S8>1cpM!?5>U^D@lOSJ zi#(Jmw7C+sNV12Q^#pk$3~HM`%HSrDFqyY%bg%)XjC%T1|IFOm&x|=Z>pe-t_qtCY zi7#59K(G6LszdE>HvcK@RFn(YQ(39!=1mb5LG~BsJ}>!(OaX(+p5MPI3ddr#Y02)R zsJ_NwR+L1t7b%=b_!+PY%HE{8%$Zxmt_58k<&FSnwbY@)FLxoWCO&txB?XWgNSNih zFAV|~!${%Qsoiyee>f<4eR)mm)*_Du&zImU_y&s^9ffvl_rc|#&`+_}r+kF*p7gSi zlJ9$uK=kVv1Z)4&8EP9M)rQwd_%cdI626A*eo{VD1nfRiUImbnWgv{qdc-B%OqPV!^_Zal70Kj#A(hJ6v3G+(2l32Szr()d~+V zY@-B;FND3ic-W$BOZxQZpFkC(;=>$ogt<;yb7N9;?!vF2;g^V2aSdC1Q}VTC*)I@< zvXqTd+{#vr+inqs2&sN+nC9u-S6}|gruYfmL-CQO!0y#ObYsiLb4E{(QaMs$A0CH=I|7Kkw{OcbyoF(UM5Z z%I?E~4_ae>AoX7^gEm&V)R!+08RSguB&OyFyzC+CKYh&=2wXB4T>L)Or?>XzSvScH z6@W&H_)<>v?zjzRhQjA!=0FJ=7#ZyX9Wt$I2pP`|nu=lMw+>m8Y8Z!iJ%(4{n!e%d z`?FN^pB&!g@et?su}#KVcTsjG?Joj!8;DWyA1qeOUOsW`*bcO7Ymp;{ce&R(Ts=nM zVFo&F2trHekj`}y1KXCu;yq|hOn@j+3Cc}m0mc*||F9}KUBtOqWWc<3h;~%1VKPrh zRaYld_h^-|Rh?U(IBW^Xm%3Qa)n!aYx@u;0}r|(5+ z2zT5KAD_sgA`Ma+;*6~LC%1LZ8#kWIG-S~OExI84*=c^zTJv4ZE3%pnjE z@R)K%Vw`tK40C`kBme8X0hBc5$Xowh*9;I$4V?Y-*~n3Ju(=mYNacuY z()Z76(q2h*Hs|Nu(tcnP=(Q{mmmskWsL_!e=fkOGHoy~M`aA<%!y`4x4|M9A(fU(J zB$sGW`1;L(Tk>?@gDNM ze}?7*xFkbsAQcwdm@9ZjE_ZHrO8AN{Mr8fXOyK;dOB&W-#ZMTTgCMg0(a|E5idlQ) z7+Uk+g-lugX%5&&TPn%LBFyfi-kzGY;;ZAS=4PW23yI;_?LAB$`4T1s^b?YMQ$jpT zz_d0Uent=dEt-%X0gt+Wv;c~4o+jgznhi&a;BCNzZq<5IIdV(SxJrt zN{YcY6i-1zlo{^ClG4)F(z?4WR(_LW!KK)~SCF3$vjIP*Cqa}Db*x++a5tP1WL{zX zS-W9GoaEz`Vh$V)1z4Y-k55_O6`sBS;-0qF&!(Z+_`lCRzu0?r&;IVYIcD~&0v}rz z?72lFxA@ZM&T2^m^~?9KtRK?2-!^9Eyh!}Za)Z5Vhq`Y^-H+1TR5+N@t{k?x;sehO z@6jslJuD`Jj4F4&Eu;S_H#9vP@l{eH_>)8)RW>#9W2ExMm`V5HQ=`wr%M4HTy^yiV z!v&2h?FK|qr{uqId0F$!ce4n5*@4yQ?l^~$xB_sGrvXkHmGUV)ZHq}1R7e2X;Z(r46OScoroCQ+Bqs}=J%$7O*&#!bEcpu)k zlM|@25F`W8RlYrL3PbXW+9m;ky@>`yZI$IZlXWH(6bFzuJxf6rtHbRFvwQoo&_JE+ zL24Yd1nd+f*LOohMQzM}_4Fi<$fZqi)TA~G2bU6&-P>)@#u2L(uCd%swOQjm>{PKbjdCml|aeXw$XJz3d!n#k>O zn`2!G2txL79VXKU+CmJpb91qsHU|6)+>I! z^m-h5C|XYz3NG&(){}z>K`G}^YdiPqsksZV@2?FFn6+{Jww|SexmLS(g?3hXEKh%f zTsI!kFt+u4d@wW|Bn}$3>#b$CQ!e+nTuC^eUSsT=Q&n^CQ-zRDcloMpyIT_%HRMkH z?t3!Q<$K2MsyUZ!h$a3NGOGEo$*y8;0RSsT3Pa3f?5T;))Z0*6FY|Qs zTcNaSX&Sz#C6-kc{)`myDk?7C2S|ghCRgV>8dqos-wqTF)aW0!NWY_)-pN1_-#Ey| zIH)Dbpd8#`cL0bW?TCq|#HT{q;)Pyo)=g_mHQTT33h&aH!;YG9#Yuh(H{;Ua`Sk_= zikqp38xtLI{%Lj_7cTk)=9N(ar_BeZgmuVZY~ZZ3xZp3&{62kyD0L&3&E{NRF-puD79%>v; z+=4~KSWPU@Ab?ermEE7}U}QshzM~{_frKv?^E+a!GaoF z1ujEC-S)pM6P_S>f+|l98jjp0OJep1iV?&B9eW-cIAkf1NoW;-Ah3gPR7!VEFR>0U z^8V{#02lk?pAZ(&`apgW5hiN*^ky`-w;)+dKE)#Yt>eoo{fpy>+Lo^5<>jTJAgmP< z6$h&^A5i-M&xSNF6r{tOtuK2Wg0l+6k{9kSbK74bAzV)mrA6uXm~nZT%ZYng_-(XT z+cijL&jH*-WJMZ`GvK2#5;jR1zBj-SQjWa7NfqA|$pcf~)~&xX*8TbEB$%rttt-}g zOeVj92B1s67DBzBRViLP;t)(QINcSOlu=tBW9BtCEY8P2n|I_%&3ft z6qYF=AJKu;H!O<_wAfG^qAHud)*r#SCjL@R9Utc!FE+o!OGpD)6dApg0%DLKB5BzV1n@?N z3eRAe9oWF2ovXl9RS41_)CI)UnL>i7$65vZUHDWN!xlUGG><`(vXlL<3JINE|~>` zp*altxzm-X4WSA40gv>=B%7NegCL0a8aT)}#-q?s;DksB5B`MbEk__1m<0LY$XNe( zHS*hW?-8PqM)}k%dRt-(2SGNw5O)pvfn+TX_cU-KOYRy%5D~y;QSJp8I=QDN+vy@c zMPy&J!jOs%*~@+;=aX1O0D(pBO?=?c zL%xs0XUxVrGv04bWL5Ceb0I?n-XR~zPor(Ca1Sg56KFT+yfTg-XApjxNh6=oQjs9- z(97t4bWboZa3`);;u!$WF9CxRN!kIQM+gTL2@g6Jsg2&i6@2f^$tOHSf=KjO)a}4P z55R?Hm}0^O)gdHiEHKGTBf$bAM`$U4g9Q;OZ0F(Zxp>XzCh((`u-rq!Rc>UbX8Q^W zThSxS3ewltr-QPv44g5pXLo7KRQFHV1}6kj;*)umrp^Nk2%$`Tp9lvTuL_^NhC-7j zp;_b?CWyZ!`BQsJ8(wI{P$(i(lv5uFvG2s+?bs6UKiG{Z)c5S5jOY|84>UP(F5K&?zI?u}Ui`Ie8u0QpD4p zO0)g6F}O424UlR4BYuDX?5b0^ajk8$n-5QM#8oo%TuF2M2`w=sFzPrAY8~aF3xe!q z7Yvf3Vo9;~KbwnJb!gA{jAm&%RMd}&O(|8ee@s(~TylP>`oHz3YiOa3Epq%9R0m+p-VzCXLK400-2eq7CctU9ShS>`VK;~ zy#W)Mgoj$os9ysrN5;`0b7cpL1kaJF>iowL=MV-7osA?=77|aV4 z1|m<=2ptGj#Sa|M`1#U@?m>vmP39%oy%}IYjtUa=_@9KQ_`~x8Q71%TH7&3HDEgPx z${!@U10<9HwOEF&c@2j-@)i=(ns0{u)d+0M6|9nOIfR-u*m z80M7H&-PzeGQ;X=Xup@lb-Q8@)NCu#KXmBJ&y{?? zCM?7zRU5YO;gwKNap@vKXI|*h6|Bj`$XI?dH|H#ut?k;{_-@w8=HPfGDsAcJ%m|b3lW_raL^5a z;kuxbIa3CPhR8sXJ>Z$zV8}uK3Jo8~6~wI(S2L}0Q&SVe5IT?u2sL1+6{41LaHx?~ zJ`{4eLIqzP5!g!Q%t`U}?q83hnyAnZAWObabYDS^!L#}GZ}5wZ0+NFD!d zXBzdheY8#(JvI>DgJt9x0;@MpkRo|2oFI>;-xb~m>qKTmz}5E%pVb z-qbO*yYY2q(YCI2BIE)@?l~8roP8LhN@5p@=Nj-MT)q>>JC{i2MrJf$XY+qGvRa3&oerfHn0IGj78}D-q|q;;{E(UC?Oj<} z$>?62i^2^tR|wzMc!fm+sN+2@cl*_NC6xZzvuR!~SaEl6-&R&1QGExx4!D|Us~=r< zTBCO4DLj7iiLF-1|>4R2Za}jYJun$e4n5|6f7rf6t4QJ zm#!f9>D^)WQxAL;Kv!Z>Lt3u+-**{xE63(MI*&$e1RP+OQC_RNC zRdf_4p~ap}o~-%+-q=U3IK+|8tD&;IuLRwqy>VgTO6n3uaHhdZNT#W|O_Z8G2+{;@ zPUU_5didop@ChXU4|%^gf7`8UEi5wH_pYdDBE--iKQ!X$Q&wE6I~=bh zy{#6NjAYV4Wd+5F3A6~;CB4BaLQ2ba6fSO;C0w6`aSo1 z&X`Sd>{Up6G06xOd(^Fp>8g9yI@>tZrd}aHd^xh{6i_QgU zdjg$rWpNv)GjSQ&5BKHG&%`=G^+O-^LUoChq)gL;#rwM1MjmwHJg;+{h9)>6DX9Q0 z+wiaGlsU-5(^t#JH{X_I!TDq5qm`C@L#)S z9`{L#q`U(-K6xY z{YJUEIjJZlr3%T)aw^aK&OrsiALsWjeI5v~QbTktiZGJbVbh$$i{qoJ!+`sPC1#vc z?ub}diQT)X7>{}Y4G-P;jHuj5+%R=bw!_|<&X$YEPS+EMJ8BKomN$_Yq0>EqZ6FEy zhy+(>Pdx6P`*yy}TH*AKX8ngVI>qmnxp>|i_i&7;sH@A=ovvR-D$gmmgUTOW#C}Z> z#Sz>xkG7trMNxGfmJyI2JDTl8Bfk&r@Y~jL(@SQ!tA?o$aow=yNq>e#V!q7ZSx`Hw zq=q~GKHqWO*p#OBy{iJUAEyZO6lMZ7=H^uaYCR)zdL= z5(RZM8G}Otus|oq;}By!)d4P%se3rPW07IUUs?dr59!c=pvgo2nv(gJIC48uj1MK* z0$LtI;1e~79*v*Ut>wJ?{wSGm0|Yo0=Epri6c$k~V~rP)7ovtYLT+%l%2pgpbxiI+ z1Y{+;2xL!b+T&A#ndGF2z{>5mNx~h{_4WCBGJr?b5PD!5M1n9_SI+@@CUbKff2S39 z%+2J^X{xJ3;35TKJonZ!5k=g7L`mtla*G$9(vHyR&rFm8V#A``)~nfCcU(Mb$a3CD z?L~BcmV4)u^o%CE-Ln=yKB6`5gd%;}j}oK|k(4S>)uO`wz&7r@KT7XTyp?#|!%)4F zV5~&Mu6TQsR9yH#?ukaDIH^GKOvd3+iqgwuU}UI$5Nkiuyk8yDHt&D$I3D?J3X^# z{y5V_qm_v8B=4?1YcO~Cy(=7YJGm{(N0}vto%t(W=Q3X8SWPpdpo1dChJkcx=r(DUkubwrNes%wWQu<7)T4)ifr4_) zpk~YQE_IKuFR&t)uev%$3X^(K`m5DWcyG`a_#`w1$LT)Q0FsURfQ%AXjqtyDlOyFY z0N=7a2B?5VnS4#vwkY_dI1`;d?>cwa|DPkw+tblZ6^#o2L7 zysV#neR}A+($SgXS5V`wI}%-HA`k_RjC=cqO-PczNd{u!c8$ThtHd4Gi8spqHtMVq z%JM~Y!NfQN0X0(w%CZMA^S>`Gy@}av+No~_7aM0g?ich2l(iR|9+*`H4$Y0Q#Dcey zmNDL9{~5KYDd8Zmos)&1oRolv>|AUo+~&sIqFgoO93(P#t7u+zpsBhqiODVkGXo>= z84#iXsVmDr`(v&j#ZexeYOu3&(#BpsFp{y5x`dr?H>UlKXc%B6a6BCb+!2{{@&{bZXW5C~oc z1@pY82qAU5qWx-s4?cqWRGXOpJ+ECW$8I1QZn_NI+)Fn<_#s;z*T^*hu>b8cmj#lu z5v%Ea{r%%XPGS~g46ZccjT_l)B!AY`Ph%cyO_Yt)uRrP=5j5ARZ)ENDX!row8{!RT zL-{KO2x<~1tB=;$Oq`vsO0eFI%Q+z)IariL(@et${D-)l$&*G6BR#3<*JF2@$H!&& zjg=@zSJ*n54mQxxfT@H6(fm_i%2hO_XrvKPw^~^^Xfa`7AY54rK8mI~b#4^F76|T2 z&ek~=B7`>YJFwZ)FWRhq-@9RVY!DV!1qJOs`Qk22^k=%NHv(Oc#=XDa<`~zni`8lJ z8#gAZ{b~+-DrP3PB{_NQ^+~s@Z2sD@st{U0x+rRM{C&DO(0?lt;7n)HFFa3A-tu;~ zIjv<@y|ktMrgh7}x*@fPP3;ORUDdLecH>%1O$(?7V!}xB)bfZ38Ms_DhRYb+91XdJ z9MC-U_H4_Rt&M>`2X)X&G*w*km(FZAEC$!bRg0Q7eLcHRVM{YY>FOIk9* zvHB@-0R0=tzMpOWer^s5-wSUG@kL8Wn2kD2h?E(Oz0hJ6A{-qY zDA1OGkpdj2Av5C-9Csps? zSjmtJQL&Py!C`y?L@Eu__EiWTA-n7cVyPw^^cLR@YSxNVoZX<0J}!A|S_{6>@$GZL z0l2hRg8$8f>4K5E)bpaQ{;Pl&4QOp@I_ImCQ^9PRMCiivPC54Kmz)#n_>b$ZvrRA% z2HLf5K8OGkXq=Ruy2{WKd!BDQw+#R@8yg8-{)3%c$W~+b^xV9D0!$pqwZNf7Ki>e6 zadyZ)$#S09Ov48lbP3O2y?7;YT|+SX_PAL6R!D&``yAxjb*W0|Vg9YDI~F*)Czbcm z{{1@uY96(<)ulEF33=UGqqG~|QMiRQ5R&zF;*)hM7StU`TX3I;ovvzm zh*QFNNt$Exk)acEVt6>@5`^R(=?K?GWv*Mhqx-GD3LPmS0&7Q?;s}IBdsHT=3j0b@ zGILg4^GdjQoJVo+M-E%Z+;==mP<0uoZNeizXK%ljl=z~GiYAN#AcILx8eBH554=L{ z1q4o$1;i~26 zx?}@sO^j}++;WOpEVd*Ixq)7P{^P6WM%;$#6ZBB>)UW@lhO=DAd@owyeqj8UFU zSUI{38vx~?&lVC6$Mrk>`zr_JudJ15KQUmN7J$quIs1~eqc@Hr{vGrg1(`X?ivEUy z)F2taoLKGKPJU$3BMA*XL_$&&A>Jz5a036&C*c}Mf4`QrhLBAmtdBmzm6l3qPKaK| zv%(QdPx$4*#(AnnvQ|RMdKTFSgtwDRO-@SUXfphba?TlA5l3%9?*XvmpcI0sOT zJbdHxr9b(7t#YEl52W*xP(}nlmmd(lNxr|_;-U^8xLrV9rKUE$Im`(%F${%TD_EVE zE>kjqH|rZ#{rRY@SBRR3C4T?hbdtL-%yn+o1sZmK1qI%4*U60_#%U-ZhtNui0m^vz zbB~b`Q^f441=3wZ)gFt9(fo**CIsAgFod6(_l_|!;oCml{SZm4%!vj!;1^+_B#xG_ zKH7e9Da4N4yS6x^Vg{L9jLeE_Qb<`OKT%LH+Q-;$;mYcs@~2BJ>QCW%*4n+Bm<-6Y z0P<&L?V5fzcC3sG`T|BR%&}`D@kG5td4l9f*rG5Q$ihC1NU1Y@S86a}ZRb4=)354( z009}Xcmk)bw&oz`WqsiPrrLZzc)UQ5ulr?eWt?S!;zxTSL#g*9cAXd}DR(SwLPFyx z2dYd*LDLE0IQtrxVK!vz3>5L$nW4QVl6~NnWbCuN^SJ&cqxB%NK>6pPZ}4=Ej*8Mp z@+LY&c!KCCV$y<u}m`(!jzhv62K{Bm^uO{?sq2(h7D)IJ&mLe- z;_-x3rW)P67R>>ti7qF?g#WA>TppM2soWT0<#K10L=z?na`^8=smg zXlh!GHz5V2UOFY$p?d`!HLMsTg<>3NJPHmv^=m+cEU{A19IGH~n~b*r)JAe4@CF=v zv=L&5a9Ma=J*7q-=Kudy716PMhYTq70OrkB^T6UQRwf;(rzxc{9S{`!_Kc z)2Yo}_0{*xLz=DM1go5IM~ku?{)sE7LGhP7wfVaF<3m{%GS&{<=e){|I}Iq{bp*S+ z1dbDV2aDo31?v(QLTN~}`w_HCcHf#1#{;?(=LcMLg1=))COY<|Ie?a^F0&F17nyIl zZl?A|Y4^;t7K`@ibvUk0Af6>KK7WuzG!R6oXm)ImOA3$D@MYn8rptr%>~Xv?aMJn3 zi*WIJvo*)F=&Kni%w+wt^}e+r&;d>C2)S2TS$A}V1mW>VuCBfMnJ2K-XTuz@xqLhl^_zB+LQjHch?b z*D8<-(%wOc&T<-*2xLZwFp-sI24k8K)q%_L?F%G|N1~UMO=_C7k&5B-} z<3yKUhtq1D?(A#8DK@JkZl8E0;Qy}rnW1H^ggzafSv1+yKR>{KuP^+#c zr2{I4Lx`Ja4%0?B0(xJ%ph_lLvS7UUbtCl|>wMnb_M5cfW0!reTxjTJ%`3OhP4(lD zvO)qU56>=?sEDrj z3Wc;*hD4?^i$rNOR#Xy7sEkddgbXQ_C_{su_nE!-+V>uw-~GIPf2`Miuf3@2`hL&h zI6l*Ha_QZ+X-~sCavn}pyYq9);SEpro{xX`WooaFsRnjBG?8!jBfjhryJ>FzKUIT| zW*nQmd6Ez+AWc`qi487y>+^5gjh=5L2zdWq%z1^8Oc0@Ah4mY59r>kqRMZf`Pjc)h zdqh+)+W66oeDiPV4g`xLnY3BZtJ#BtTfU`4Ckd+cL!3`@C8R3M#uDO*oX(8-mfgUR ziCYM%Oq+f`kY3E)+oE*$bEHv+nMJj>>V-c^`+xe1&bpz(W%HDjh*dy64N1` zgrOKe(Gmvbe5X%y_;i#$RU(LoL5auzYXKVmBmIguU91hKJI4H*LTH4x9*b^2mg+C1 z+2Q!toGTJ<;V{Lw8)OI^2?b?jZ2WlHUW&vJ5J1oKd+;~nK1AXmXcK0L=)Yg$J?ZS*aO+}`L*GE!&Qw{|D?vpvpO_JOo%+=*Zr{YDWqNw$F zFArJic)aBG>y`*CtzYXrkBea>X&QL?CzM*&pgJPkQY2qI*4c_AAu3faszhA`UfkeZ z*LafKJ1ELHWoy2gRbv~4t~dYE$ECaDeiySn?C*fcG9;$ipgMebXGXJHTrOXFcbbX# z&NTzxd0hBUkaj19Q8|X{Z(0rWFuzzeYS;Q*vL@24>eW(9!?F!W?&>pc?)xlDw8TXI zY^Az8O;I%M(7ykuooWkpa%&u5E779z$aV%t4&AhNl)-f2t@d6nJ+JK}1YJt+BYY-F zxMup|wx3~Wc!x+?RVg_rK%wrs<1MTsr-MT1H3?QnhZ#AadsK2|7 z@~x9Z=tg61Z|Prz#t)-4Iux* zm+HEW-E}AROV@P1P&F#6$~R$fryq_^lNQI`q_%ILwxaOSz9S=TI|$9p`)cmheFjRS zJOiSb=&}zhvKUE7SJ<^HN0S&z5e`ityg084VTc7!ZFW#G$zO5s;5%o2sK4_`aL(c6 zm?)AbTlAx!7x&{P^rty7mSb9K3#4C|TbqIO{lYE_^sA>=!?aI+>*>KK*8d3{s4GaB zd&@?W6eqAs>u$G^Obf)4e-R>VP?hAhB(3j)xGCk-(y?d`dxUX*%ydBJEbN)KyU$FZ z?nhVG0%Hr4ud1pawLL_6yLfzB&ubVlM2sS*!Z52u)3M}J%%UOa`7;HAMPQz zWD)s3QBK^~$C?mrx`?4x0y3gdLTEkuncBD^Lv{+9VxnhFKa9`9=ZU(*2s2|vamq6*Mx)3Zzc)hMj^YG(rFDY^rpbL>BET*AF-F>?ppJ)LU1HAy!;59H2e z&xxqw`0ul)q))(Nb&Ew>==jad>3#9Sg3LV@$AA$-!o%CKuOt%qP{=$Lr zWOT!AJP;ah&q_J{Bu_p6xXm@a{x@*|tfCWDx?|8dv?}`IDGekcE`ANqOTI-%MBFqn zoQUOTcrdTg*?gtlpK%6vLZfO2TkJen*2*gGg;k46L$^*(w;y>IGP~+n)5_(`vxq10 zWxk%-`%BY=Y#U*`7#O_q)6KTdD~hU`Q!XZWTuOg35_Li^x*Tj)H^BS1il8ENQK`?L z_ZHJurkBfX>pF|ovAbHzMvH<+&Alu~shd<;a?hI8RGO$fuN-ucZ<#mJVBXoNI_-He zV^ZCEa)X#W4w)#6pkFomY)1)*K^g#?#uM+lPDU^rU1>W}S z8)Eh>>sJT#14u(;@d1l)l)fZ9MsRS2-xI}*Q+<6MBO_^X?w-ld$yox3BgBraH(+3p zdUptfhd2V9O&uJ-Qd>yG%v_7})t^2|B>qlv@%La|5J0IDkPG2I2m?EI)MX1at7>>#*nPwxe*usMOQX&oBBGr^L?Mnj@|HesCS*llHTWztOpT8 zn=U3>RyZi69^QrY4AH1)U|{P~ML)x2Eyd-2xjoZMg^BNGdU_iw9WbX`a$$mdMeDz| zqF_*>LSpRflEYCCPf(c~yF0JkH6~}8@h;rng4K3$>8Cv$h6p0}c&7H~Z zw6sTzAyFAPa0?){-ZS%s3k@XpAS!x#2&Ej@`t$??pRS?eu`bfs^iLiZ9gBZeE!El< z|KC(g9-WeE<4o|Dk?{L>l~lb>^WcPLgX+F%UIy<|3-gSehw)LA`}fzG-&c*SX#Dff zpAQWn3-JFgO_T2~h+86-S#i@LOD;*D=L{Cpa!O=vW?07RO~&Q5Me>LWXNwavd32F} zxR@8YJM`{<|1cFrXug83yM|_ZdFH&6v)KzdQRCcB%^n=#JgO#Nnv`1l9eSU?6lsw~ zxpGA6`Ekya((1PM#&82{Wae=0g-d1wXyR7){ngJcZZ3^WQAf_cU66!p60T+2`+XHB zLs(SJV2gmioeaOh+Ny*bT~j$0A4_&;yJNeN9*ST@W(Cf* zusHglvmIXJuDREw2gFO($1Yqr#emXUiOk*TIfXOrI4+pwR#4K(wc zmoNJ@EH2XQG-e$0UI(-Yrtyeb+uQN%Kg3OY?S6@yte%eEJy=$245P{VJ2{n`XQm8s z>mU<0YU#?LKbwt5und=`HCuE}sBep%I;$o%d67-aeSg;iZ1{E;Yrb!So*ta+)j2~G zV>|8pdN?Zc*8|@9*sfs3@7eK*_R#@u&%z$2bKUCCn9(n!?vU=^Q24Ru&KKqWh!|`` zDInTHqMsHeCG~$d;oc23gZdi+ABQ)t0~tTu7Gyl&?S9X1mHwDA((es>jSO=Nd%LTG zLT7F|;5fly{j$}Z%`@DMrd%r6OI}Sv8)LsV!9U+{BCgfuVovTu*+?mChlqr&Lc-ml zV@Kn;b3evZ!u6e^BYQkgQ2qIKV2)^L;0W9bT*4+|rJZbG^XjDxksUQKzp6 zWU{=x;!&uxn|1UFhx;<;?<=W0N9|1KJV86Uhk#*W$U%cI516bw-oBzrq`Fy3lYC#HUw){w!EDPr-{bR^`!l`gfBJG9`?y4{ zrC<9SjgXeTY`--oiLvfwfu&M8E`1}%v~A&4yesZ!dHW^g+~L<8OL6|Ss#xfcY0|`4 zSjwYjo6d<}ZHSYXvsCcUKVKmsnPye|X|`6d*WM7smfuOPiapVUcPSOa3{#;VA9Dd` zm%Jp~EZeitXgry|Ewwj|2Vr@&e(hRK0qq8T9Tg--4~oxJ;oK%QRyOSD(B%aOVbfZE zZ_L!u=%mql$$U$`xKPrAwxb{(!m9jK;B;OiX?S9+zuZOjd?PD=|LUbRM>H*-#QQrx znz#F03BVYDrDQu&fm@+T>;q$R?b7IomJQ~1b4 z0XHWz#p>443L$)=Yh`q$cnbX6?o}Ug^PIxS5F382%jAZ=>AU4;@h3)Y{Sl&<1>@y%YuF<{C1t+HqzG&B^ z?BxM6&SBj2GhQ`ogd)je(2YYjc*mHO+pVHa$GKx^Iv7(St>oXQ*x>DQHz|Nilr z$W2iAuBfRsxZ?vMxXB`Q-tD=TmQEw(orga(40Bc!tmmI4qq2`+F+8T{K{dd5g&Hbh zzl_oUUrj(eiAc{SrRf9d^k=}~9+NF;pr^;D7Geycp8;7D$v&t9m|!({tB&GW;lG+q ze8}n249LCgC!w>pmfP6aL?G1`peOO-InZ))qwS?*7AEW$F9FQ^EbrF{y=YzoMej7) zWsAOTgnca;N=J-KJj!t;0Lq#?OPBURFSq?y<%zsp+Z9$7XOPW~9}R?3hA@O1!-&cg zF>}W|>ktehAp$MdyP}w_ewh3V4^Pi{N7+J^N3;30XNMa~{nb#->#|I<@Y9R=3KKmC zN?jefP5sWCoByeulFZ)~ueR0eu$pzt3LGloiRIavoovo2Zb-|?JuGv6MDgGHq&df= z96CFX&YMZ6Uz5^QpQ0m69IX(G_wUcR;;?By*!di|7!poy`YKBk>iK%d;8LLf8V;ra z0BV?gTG5<>O0Wzu9l-zI1Nd&@^keq+R8UyC-_FSHkHNBK#&^!A`z&*ocXEHGxDAPA zH;LA&m)?87!WWT4WEJq<(zQ&(Hlw>mvZwpy3Tv(5@~ijXlv(UNVpvh1#m>V}v2X3w z*0KU=9xKW2N;vyGyGvS~ zqmzyP{o4UjR;^q=8oF&coL+t8!$&xv*f9myD|Gth^?W^YH zXOCRUI~`&Su7v8MAiGa`mT`nBu9Mr)Yw8Re`l@+0vzq2`3H&%7n~#BS)eYg8@LWkr!k?5Hn}ZKv`_nJI+nV;QBxMKjwQ&5yT~83BWmp zvoZNA0H|+d`G4!fjs^}6>s0&94MID}IqEMPkC|I<$A9w!?ZltsQ}JRiap_E*?FtVi zwBD=9tLXVGEw*pj{T)QUSjHWvU@sx}a)2222rWEx;nfTG#s!(#sO=i}d&gx_T)%qdPHM;Y>(}s)XPKS1ScB-SzCU>sD zHuY-YO;3~7jUbu!H{rC#iOA_K(nO&${~)e26_d2^{qYTPPexpJhNfnWwg_~5ja=~7 zMMNl+O-nEZ&nI1q_aK1B33$!kjJTr~vt4ts=9}@nj5IWD{=+?I2C0tqS?6*rsI?i z%ySw@R9cd_w&Lij3fy}lfaQK<(!Vf1?VV1YzB%|70!7aXb<=!mZYb^3Fr}yN18B69 zz?EH?>9MrH=vQ<0EWS>29S*#|)J)aS6W`bUlU6OXfhgNaiO%vl?kRkN%PfX9w3xhk@{5)K;X691&t8%(^ml7;2cF7mm?>H}4 zmMS{G{}m58?Wd!BBU%)pm==ttkbsh7CaxP#3OdqrEG{nHx@tBS2>$;y?(Vts>ux`N zKPda6;E>`s7@n*mZjsEqOVZ!|vy13Obz7UdyM0a`d9X_}`TUp+YPk+lQUlShRqh(K z>j>s(u}p~2_^3JLazao`_eXzqik~0HE7_+ar5YX7Di6(Q_;~Kowu4T=}XweegfCbtcz-v2`ZpYX%7)kYxV+oXP2Z`t%un&i%jlt=}nG z(VrQjjZH-*$zh03G~46)@C{Nz(?iDt03X} z{#Sa^F2?)n+IjhzC_9)pA>1xIE0)qB7AV-1n7Z1yZLo=+X777WX6S#Cv>AW3&vx?9 zM*GFt$bqnB^j}2fttYCSTx}e0yZx5)ZGo}zzEY>7ce} zFS|;F*56pwRY za6Q(@-p8(a-#Gi}^)33{f}9hA6lGySigwL&-LqrIO}`#P3UWH9PcW{^ z1Rm9RoIg7MPNxsEY#csZ4okT1=r_s0709Et1gW03Okvi82YH^mlan_^J-d0hFLG@9 zANl2zN7`((gKCwO4bC&jo&N57mYbQ>oRN~+QEO;yr;*C?vwF|wmy`iE$HxDb>SiWp z14BsKaCbjtm5cux8+mv1Z@55zlk}OiasGhh>eiv2dCAs^p6Nlpj4{~(lN4>0WL}a; zd`sHx+p@7@WIb^cVg^gsUcKycmY0#M_$TA&Vfh8K#tDo!dEwaMUn`V#-R0GnZZSHc zA6nP+v1kKY*`MF5zqK$m81zWWbhNhdnVpNXukF1zT4hdW$9JLCva_a)8gU?a>Cuqi z7OCpaaC@@y=+aTawp$Mw+^!GJ$}u*+A-QeTdTQ6!J?5uO{vI?@Vcd;Zp4yYozpp;B zx*|Eh?xS=4$A>S-R*H2;eY)VvN~;|e2h3b%s=BVI@;?>3R^Or$Q`MZar#CnKywS8@ zvoXW`I^_HLE$Vx-#;LwYHG7dqp}ZxtRz#vZ$_(}ScYr^T zXII?ZanU(Smr-8;WN*+rAc*tDA})Ao)VNV`R>osSJLT=-&0Yj#54fV@qOi!^%V9-t zlLtk9Z$b}@n-}$3A#8#OXIW2e95HOw#f^1i!Ob}21{&3yzM!wC}h!*NCeC{f2GPih_L7pEbO#B z`u069{%0!R9>F9^gkY$R@Sk2Gw@$N>iWqjFB9gN7c=~3{F zYA%8eIwaIDeJ#Tt%ox^Ss;`n8GPPsw1#4ZOgu(iLXQMaGo;lN);9z4B88K%nY0*$pX8dIm9zoV~mdbNyemBx1{q7Ft>QTgv&=IT2H zOgd)~7n#$js-n>7o{S~V;+f5!iD44w*OsAyUz5W6mi!>xcOJ-68BPWx+~USCDD$9v z)Me@|au(%I9PBe!A229_h2`+Y@j&P`kM#?F*iLo*@Z_~x*vR*hiyXeGaRqiTqOHx( zs0lDD4(eF`uo`$QhE)6eOQOHQ(`s1XYMl#0Wd>)-v&(^S<#RdOs*Okmorn>Nvx;xG za*Br;UttWTRou#=f|plPBF)}-g~U3!JG|fRHD`a)!ySBn71D{_IZRZOrXMW7yk1%+ z^IK-4RxE*TP+lSd1IOoaP}tAFxi&5?hA_TPjlJ`9a+dQY5DFiqz>(8%OoKlcsj?pL zj@V_%TO^=v4uFn6$gDs$xF5QR2O^LJ6*>f{o>J2YmJhBIX)fjI#S0gf z@H?*6=2_B(`~e-Mj%1H@zLSy!^q}DEHTqOrwia1X&-xt%PWgPR;|Mj!obV16nQ%)Y z+lL7rm~2Zvd?3PlmPAYiLp&@r9U2OgksxUQCTKIHu`8Ge8NH{sB&xhipF~144|g;aQk^>(+O= z;sH3RW>StxU<8%}Es*fCAC-}Wvt%mh6i3LiXP0aVhsf)?^+A0={Q`SI<$bg_fkgQ+k>F&AnlXP<0aQ3wI zd+;i8{^kW))yI~qLVFU9sS7wk>0;qQ%m|e&qJeJSjARh^#MjCqr*lTPTg^C|-BngL zA}G~8#>;p-MU$8=3@K_f`rtZ8M^({O7Z;~2?Do^|=sdF@UJG!?YLlzVQ#g&aIk&*v zO6i;0twM2`V0oFgapN`3!PDKt%j$PLc@R{vvC1guP2JE)pNkt)o}84QPntPuNS5Qg zXOUZ^LozmfeP$=sXY7Ufe_Cfemtl_4xlsWN+bcTuYINblx&lb$rcaP(>0+jr2$MU5 z7UYhsuxe+lzJJ7FC74ha(;5OZW3s4)f!OJ68I}+ud%9bk*wzdj89a38E`STy?IunK z+`0_Vn~e;MNiSQ-6)|&atLwhk_0HafC#TLH>G0Z4aZ7lIy7sx1L6V3_(Od{I3`a1t z2C^9Z;TLl{Q1#10pPx6heIpTq+@PQk^R`JhWetl-!r5V+*vW&&k3YsFwO1u2x&YQN z*Ij@!9>u3%bAbL}vFxCV?J6y;J!j7D_>BZ3mbz(G{ILX&BJE8ZTM5E%7~s~3-7qPY zzDORAG3*b`k8>BSmZ7WmK@fx}FfXIVr2|cvIKMz0S}-|f>8F=BCD9gfesqaq=q>7i zSrezBUBw?DW*-PTaIPPs`9B1R5otDL_~PqX#Dj3BpAuOi>O(^3<2XXiu%zL8HS;F4 z#}ALI__9vXvG=`R2A45YNH_=LHX5qjrno$U%?53=y50Jao=lQXNAkm$UX4V^VAA%BsZ#x}3^S;RSrGV??b*v^p;YCH|CDwU3 zCv_xHgk!)QFP3EoBT?OhGY{3+y?-P4W+Zdd%20ESR>pH`x@W>?-)>{&K@SFLxDqs*jdiS;*;B0=oQGdbv2S}Dp$v6Bu zLGX@Uvc@Up+ZkK!dRu?sM8K4GtDB-C)GfA3n?-3pxcBJ#rVT($SJ%At)BK~FC$pZJ z9lOr;m6xB*1Xiw2!9C!XkDPB+SFB`H68*v|etq>)e6ShR0pxkMGODpPqXiS9>a%l# zR5f-#QHsdIVUrR0T{)0_F@VjBb{0VE1M*e&H-)s6vYcNiPm!%3mSfX;s*5}(PMPT9 zQ@U-L4;i<~TpwJjBLzSL*pFm${qtgxs)pNG@M%KoN6k)=cawyfS%rgFH|-xMyG8n2 zyWIcx?+OF&c`*P*2(Ioo$pI0q~qu@=d6OKt2?TVJc?au5B$9xj!Em@{t9 zZd8Ad-y}xrAb}$(Z5&%lv0p!L+Ga7P2|CI0^y+r}=yl~e5#0ncMFhD}cCC1E?OCB> z`|2Ci5Mk6n!0#t$lRoiekBuLws3$)tNJ__7>lM=Xcb%uSGoH^=H%k(wt;9tJLfrI9kYSTflg+R8f>YFaEg= zHyHqkn+ROqH}n5;kf6mZ==cp(zoM4V>}26L%LkT-e1+kTqAFa5%whEi4k9G zQ|Ze+-UqD%O0ofjxhhR^5lAgi#^UsQ}LkNVkeSdEX znSg@_)5+UDeSlu+Pwp=at&7UkTax0|#;E4@))Uut-&U%})|P)5KfmYD`Q!zT#@X{0 zA@FP10D%xlMGV{$uC>2cJL5^@7`>((S+8@5H`tXt z3_RIK(C`vYb{FW-18Ofz{=|YK<8tiM;g_Osg=3;wMex zYcJq+iO=>WYZO$E8mY*Fc40&%8|78g&#ES|aL_QbAlYARV9MlO9MYFbSY^qthP8)2 zrxkT2?<>skr~cFbuPoHJJcN$`|bIDi=V)I!3q8#{I^ZnxXWIQ1aH zxaj*28It+(N=rX236kSm;NbQ=_#JnIT2)lqpWdI`{5!M5QEpIAw(`?5XP;yN(8WDC zBq|RKEiBvxOe-M6P{a56g9p1gh=2ZgxY_(?-}%0drYFknY~v$3h*!HBLFhZ&Gh)=X zHKhvqf>IJ(sF#mF)G0Ki$RF$Rd7!XC(ihvHjN_XBLojuPr*bH`?9GCFZZ{g(o9`_Gi)6Ow__u!j<0*YWNgE#0d8@Ol+Qim$){h<1POcR3cV+Py% zLt(<@1l=b&@%1}CPudV3S?=LJ;Y+yv3jCaBjZaUz_Wkuviz7f$zizc@Lps8-B3Gb} zxW+&z_w5%qF225un@0c9o)(kI-4qp;`h)FKvO4TIVRXIm{CU#CZg)B;>Y26c&|xWk zrm%?(xqRUQvp>5MtcRAuDZO-yvendcC*NIvr@yG5Uhe8utCo<*vr9((R^cfQJ@vRB zo{Nq=6*Dq8EHW3m@T%s|zpLEvdh?r+Ay0FG$z+xFcUyy?&R=6%xHK`%>7?{Wjhjch!26OA#J>@|o(f=iwEaaObvP6&)4 z;w6yzJ)%}7^z7MgYy?WUQko=v6@lRjVI%0!RV@Cfe$&&_x1n^AO^Xg(N`x=p|4)>h z+3cr^tA(3ZY?1D=8^FB9R2R9TiJMdZM-{6hnHmta!NbELe-lDth)Ls*brHS#_I*f& zENWe$r_IhbIhLRHR5R>d=RvoPf4|pJ)Cfn-@-(beZu5zcaDLE4iwUg=B&s-ipCGxX z4?CS}mUp?W^5zFEY$rRZg<6@I4%D=%yl*E4A4f-LcnvP%V1tMCnedz6wtMh&;^kpU z6>?r`yP2eA2vHAB7X-pilxl~W4Y`dn-^X*v=jdrUzw5VC%)mq$VbGX>#p3@*ZEOm* zMn%eBjqsX8Rd6nW51E$=cA)FXEURaM4mR8YrXR2?*Es>aH~`7Kz0Gk^-B zz;aZyJ=U+ccV-l*3UA`TzI~?x=Q?t^cQE?-^QUb?)Q)-p#?&1CDO=GP@|jlW47mc~ zjL$iM(Txb5L!JPfxgYXHQ~ZBMKWrB=x1HT`?9h~ zn(M&1`bF0_Sx#*Dlp4vw*ruX5Y4(ByUAnFT9)Dat892DOmyU1b+%kXO%-u zd4!DjnCDFxp&3<=8EFIayd7y=>t6bF$w7^q16|oY80I=QQMHaYJb{{YSyvt3k!Ekg zQgd_7T8JlT@eEp}$C4UD6w&0vgtp9KvHRzR=2QDDtuD0cNv@v69qQZphv*cT4joD~ zsRiXJUGwh8pF!8&R#lzHyVpI~^XtcmqMRXSpLO?d*t2i$)LwZT@+m%(Z%(3(QKhan z10RXuQuWfOw&~J2`^gjj5+;GK!2;r zSpLpUs{c4D)bz1`^v<0-xiv=GH@$Gq$dJ$QJ3VlJFW>sD;s<02385o$v9|^3fli4( zk9vNarNK|@U_=j@c<-S?#xYmZ+)-WFJ$+SY&it`U#a%YjWY+;=p?W@_&PRkxKHHc) z@}Z;NeX2_{?TforWQWgeXFRON=8J}Nf$5O(h*}Zcg@<&W<1?9H7!l3vO@l8RlWB^Q zUBWyoM_Vr9RL-mM*)yKQBWf^*~==* zv+pB{Y7Z%Stw2gAfwHcmw!uGmo8@Nqx=s|0$hPhfp2{C*9=pxuwACYieY?-AU0q8U zZLAy`nH&Rp)bbHEeZa|yfn(l>N7yO!*by^4Jkm}h#4~7u$M4Eoo2!&W8zEOxS&8s` zI6%g!DIO5Kgz4pae&NwsI8Llvw7PL%nD^IrC+7MA&$LuS7U>*f=S?sg1+(bP66)`J zb7={yJ9nwgh1~%G-O!#`{BE=2c^MKpF&cNATd6b&H^S*jmELOBtV~DedA>*YBT55F zqaPWwPFcrSbu>R5&(SmBX`w46DS-$e$IPl^ue$HwgR?)BqPzQ)a_m7;U!y{CmiVYN zpC!^d)Ky4EUxI`68Mh|wjk7^QSnt!DWgj!f;Ei3ExA(_ImL1uyqPoA!fitnSjv=jP zoNr##&qys}IOpx_*AGnTwN=_S@~%t__e}>inden}yMp;X)V&PC&>^aK7V^q@Rw-Uq zVggbI`WX$E7YiFnk0_)3bmS(91ZeJHgpYZ#&=WXn=sK9O>Z(4X1H5qZApM|1{)nEdgCo5YACFC>G;WBypVJ z9r73Cd9}ChELa?zFk!%5(SfRRCQq?H2vw_!Z9|;{M+QJl4uyCQ-|*bgF)rsM?xl|u z-5C{e`g!1i@u=Jn$!%8`r__$Dd;PYkZHHQUTUr_}{GtI@)ZZRGck;C2mfajYJ1M?_Fg8b+TG+HXc-x{F z9BY+yYMy=s9aGf%6C37eI6TqgcTP)Ycu*NKZWF?!w;>Wq%6Ry29^gP3b?v+^6KnRC zL3}Z{BV62{a^u#VsbdHMuJ#jfu}!2D#%hfn ztE^3iQu8ViE6=^^g;mVrlov~$LqVvrfXD}kp1TJsFdh}_w)ml=N1G0te?hyxUPOAa zQ^RIk{1(p7kDyVAq*q%ov99#=ZKWA}XA{N&DK*ybsGsFrv5ZvwjTbLrQVyrp2~0fU z^=Cv`>9X%gdAl!JRp~`!Vg{qIFj6MwT-CQ(k+MbYN zoToFHf@hJbC{|A#G`e%b#R-GhbVLT3wTJ}9q6%;>V-?RO5y9d_0M!q8Ph7>MhEKW& zPMlczq`KR?T9`al?Vz!%L!OQdnyc}>Xs2|@96}~vBkhiO{P2z5kH2ty2}Kr$vP(49 z$mXJKb%q%yb?Q5*kFwTwr&*0G05KzrsIn_MxeU$Qo4AOL84 zK=EkB$VWWzQcxpSHRH|`pRPFqdK;o^ZP&aG;5fpixy|5q2c-cwUPV1 zR^-DK${46>BGYr$8RD8YXp3|YMUOuy!xL{IYy%+?nTFU4vgCI^`{0&1vdOfz<2;?i z{YQ@u1T#B0biq=$=F2c`lNj5f{dmuHua-kYyW^8wj_QO?CjI!U_APEOV}$ukZ-EVW z^_{Gsd^C6{t|t1q$3XAD=MP~NsV00Vb;5Sm?h{ff<{TeuT&778K@D+YjX~y+!9F6{T?nB0#mH9F%=AaZ~%zE zlecO_R9HmFsft;Rr#H9P_dU7>bY2){_~jsy)AE~v!mC~Q*4t2Z{NAZ=S6S^Icq@K^uQ{;cD+T3&upo)O zzm?x7-Mzc%Yfp0xnE+Oo<5CxwhX83=^4p|)ECu5|Re{6iA=k>T>-&=I9xAX({a22$ zf7Fla_QIu+20m1EyHU8ZzR`W*x9EesLiF_9%|px$ecE(lz-usoCRC5w%EGZ|4)ie( zN~Biq1^`3&hR$t2CNR#L7WVK;lqe0rsRfCs1*WJ>MXVwbFNy#Ang;dl1RWjUwg=w) zMln`)6uSEoE^5qm8JO&5Z92SQKi}~SqU&n@G1J|GbQTa@7Pm0(XCoXm&*yxa``cN6 z!;PnImx!r_l*-d4D-MtFnNszlbDN2<2`C`5=rQ1X-tk*W^EqU3XzNsCt=w1#6Q4CU z_3kcU9jVYVFHKegO$5#rLDMHyDPcgy-E zOig_K>eUpc6ha4pdIct4-^h*2UogcdT&>%Iny_66m85=_c;|X8I~Q;kgzQ0H#{P}7_ifSE(9I-o;melcPvDQP^|v;t()yUw$G>t6uY-vpGb{`xg+bJI`G@cc8K z+w2AV*XvYHV;JF5f;8_a#FNl}$;jI!tHMznV5?O$3oKzB0=ZyuS!YLFZLf$ z@VNtQ+E&VSBTvQFq6umrJUe~Dk{c4LT{bKUtLliw4)Q!p-oM|zXOH0yb>CccWV-VA=2dmci=Q&zxS3hWLQy;pgvGRvpP5FoI2EzHo3+D?Q z;(px0x0Ob4rgmn(bch=w7gothLdE5ROx}7qT^S7?r*}5n+QueTxPW;5k3YBxUYTez zF|Gy4EdRs8YwNr2y*7YG!){V%Y)|-9`t;`-gzp%Mx@l$TTPZ(l&pYmLK$b69 z7~mQJ;g&Zzv+#t`9{jL7Qhg}xsaJbNKg+)aCT?XpI|xn!R+rqM)S1a?M&W)tZ&tIe zLdqNbxvQL925avbVP`JMwLJxk0dN6Tz87!+P|Reh6f5Hfa2LtEk|qCDfia}gKZR;! zC}B&qKoY^v@nZ#O`M8l<^)2Uv1lj2*x*_v(3uglSNznB7hnwS(UqWh&HOWc(3J^E= zTm$phqW|37Ua`{UFP#aVfy_8(k8@3C&(2ZjJcn8!i2mm-PMo;jQ-Sa4uTmO5ca$)y z@f2K9fn~`4d|pg=CvXQLxPxzgiD%N5XDBoK4 zB@SsJ9g2&~%@{CX0Et#&2J~CM#l8hA{(%;6Hu`Us)4jWQ)m*oPoa5)>lXrZ-$|@>l zLSb`#Giu!Sh{*EI9?#K)*;q0(MbIIbjB+w|y(-dRzr? zBG7Llvu6{z7}v#CHLX!lwy}=6eqaIn=|!$*?Fh>3zZhU7vXI5gSc2hSx=l05kJ1M{ z_ofaa?={kY^(0Cmny~vl4@v7t7%Zf|u5uwLPo$Vn4ZiBTeS2GKE)5$uox)vlf!V5}<3m5i2cB72QSxJE=n2&dzb=$4(a<4x`uxMx)NU#PfT8vfdK6{zm zKj7DOJIW6X{7*s$W%pw^|NF?xvx}~nhix7;mT3S0_hRN{_f6ZzF(vTyYUs!dPWi*Z zP~2VHD?2B)7xGr#~lrzB{0U5uZok zs|=kv_|%J@4lzXvDO={=7FSoDf;U$RmsTae`08LIGi{Z9ezv~3v1FrW5hj8c?YQ6<4 z;nw))!}W?~T-Gm3Q8uU}uV9IHQn7N;si8>i073tuxOl0MsK>P<0C zr9i>C9tJaayNs&71zt9kc}KTwY0VKjol{>Zh`et;jbqy*G!T3MiCHL#B$Om=fIS6X z=Ujw{H8?PYYC|HhIQ}oo{N@@3Ma5m%V@Dm{pqJyt<;Af1tU~K{#-}N;=Pf+~+x+6i zivo@HW_q-w1S&jMy6h9uzMxjO|5mqLFW8(J*1~wfod$I98!vH8@T1-tLf_{-eRX>9xetIyzO7bYeL~!-v zDBRvT#lIo4s_wV$URoncplK55BxUN=$?VAANeei3>{x;> z41nX~OSZElM@Kv8P$x?;|BP@KsXd>$VM@x%M8WSs3m8#;=z!1Rf^#Yvy)CVb%*GvW zE_cI=&d_xmhatCojC^HnW#NKz6$YE?&qde%2StWbe$g+DMHW|sR37X#E%u@f^Q|2h z9sq~>uR!Sp85FZR$l1U+)z&G03xzh!oo{JY{b{amfkD&3YhIUJwd+4uRVucxa>vRf z0cwaF(Voa13r9<&MabbGD!VjPP5D+-QMjpb#E`b?am@?tNnrdUhdZ&6W=h+;HJ9)1 z+Xb*~@VcVn{*_{{S&&yV%dh-v5$hQh^Q(w$sIpG=ZqaI$yZa!9+c7lo!rBT8M7jR- z!~EVs>B3~h8-;7?Xf!(TCQTtD1<%|(+aU4-Xg7MBTs?CYe(|^NDXYiCFRpu9b$uT^ z@8(rPf5RpG43p#J#+q*AUiBM3{K1kLgA`RAAza0NMl6+4cq&H)U~X`~em6=l{iPup zq9J7la6&Axl8{S@e_+>!0%7L9@ZA zaNRIJB5-Mb(_bt79v512&Eg&iQRJ*v4n6<)z4p5I8g+*>cg37-S{G^Gd9c{Lie)`N zEJJLRmY;tJ+VB!n)dKPsQ|xl-L^GjNIq{Sg|0bar9!#th!5Td*N2sgs6Z3NaCN0MJ zW(^`uK18#*0!_70CL$I>5U8RqDqITO)3eQ;|54`Bu~mc9nH`gO@^}G{GVB{f>U-O^ z0mqL^b)TKJ9+~s+-<;4z3qgvq=aMxlr| zaU>MjN8OHZRa2t65eC@Bi;Fuv-1<5A(v>SCG^_khAV)zcuE_g+(>Z^GkcpE1`#j1a(vNhMh$nShlzD^ggh`d> zLWtjf6l8QD=aRdxTKE1Zp~h2?+Cl!%%++q)1@9Wd1ABfPZ7N2TmP7W-`-7L z_nb%$(Pl`fhwLDCaOi4V^2WsqBdlC9aPZ*E2&vhjk#Dtley<@P88m2`c|gcq?%q}Y z^8HuYQtvY-_szFU)GyBHoB#~he0-|TTC=NMRd$WsEG9mom~G{k{>X6lY+KYRKnU|Z zL!7H$dV<^vNeV;GXp-kyju(pNeyXaG1qI=(UV$SH`L=feKzT6F0+IRF($dnUnVU9k zddAt^zJ2=%@U{mWqb~hZ7vLX1#Btl4vjawsoI8GdxlZFdtzKK!8=;1+&KPq3?l>h; zXm!{(f)iWG64^HjX*lO2;{&xua8pBH<-RO$4~|7GO9WRiRrK;*b8>9C35nX5?$c*s zjJ#AxgP7Vie9^V}uP;nv!ww=uirt#KYT35o3$J>kF9Q}{?yn2QIp^$yblfb-3*qTm40JF8x&wP%?; zjdSXSYM!06@90rKjK|Iev9EYlw&~_ZM%s*~h1CfmNYX-Z$6#^GhzPZqP*z_r) zto2sfyhs0)+1O_!KF*bslvrOtKnGzTc8eUhof{}0t`T8D6XsZc$nAIyfPz^0d?fTH zk7?W|eSg`CK5_x`iP`cC6Ww+IG95}duamQ7!+VX$S%GtHf3iDAtvmb+K{7ooj{S^5 zye6QGmv7(Rra{V*pA!^ENST;1fbf)h=nZ^_4VYvDz(4kJp=ov9u3QFK2{a)@JsVkc zacgE=X7jY7eypfMZDkOol^ZN20@UH=wjgO1@C>1_+3h)J1L zh&X@#4F0T0@L{rdE9Kg;7@>&Xd^l@FavEX+;Xz?Bi#!NAqX41;xcEAGFI3E3m23SG(Zc%MhPwZocvA=(FSR)dZQlkMB<&py3FR-u&lZrNs zmylZBPQYqX8MV%VZ!0^uQI_kh!cjwIC2Q3LV9r>HYHY?mEyJpoNMbja2(QbulHuiJ z3A2*`1B5%9oL@ANG&Vo?Sl{|RzhnVN26X+kp9)7b*M*8fTJEo55JL$p$#BsOA?8G2k2AL&F-WhmEcX9}*`9Xo zPhOs>gOqpPAL6!FjWC>ScZ;URe|QtDEm@)O$sQHL-z_iLw4)QRMVAPNyZ6YHbm?zr z@maUL+eh;2gZiot5E6h6P9WlNrzI|%>wEL81TIF{PHLfb`_;vnz*@=QUXY9#gzQh? zzJR1o6L3I!uA&H_HeLEzv+hb|t!_Lvgf+SA%mogOrjh8c2VxQ#c2BnN)qg^B?S82Y zVm?-OKi%}FH7I6}f=QDn7r(3mOC0U;;yBTIPfF{ACCmPC$ZzB<&55WDJ99?z2@+e* zYEj0`@`RG4s_R3(&9Bh$-4CX+3S@&00z%wjMX*@6_WQ7R?Hev-iQo0s5-~P{eq8V>T$Wh905o@Lws3X` zisWQV<0tZd?QQAL)u0nWjQ54kI^@{pJ5S{YMawgE6f9`wZ%unXtysmClQ1}ZfD+6d z$j)bE485I`qDyKBbAW)k1KJ@PW6qrcp!^&N**HWbgx*d8#AImhh;OUA$IW95Fl-(A{1<6`ECQ>#9=_ntlKq&ObC4g z&q`R%nQk7Qpld_A?nZ)6=n5YrwjP;pIA=~ewKGTGR^c~dgr!g&3mGQ)Bf_eCF+M&W zKQaPwVjn@Gt#LL9Z6-H}7{tOAtjo5N9lNR@%9Qt~wkrtfBRExCZ+fC*?91!~SG$0( z1CR%Eorypk3DBV*lcXrRZTRbAU^^5&g1b`Lg!qrW6Ee1=ATv@rH zNr*8aK1--t(=swT@a(uj*ez^=!X-si3f-7`3^@wDh=jT?mns;a)Vqz3{sG5I0@oj} zsU19MkQgAzue-xvl4Xz$(@XY!EzW^>Jxmg^U=v?l^H7r4HLjmJeflV5_<~`L2?~I* zV3)wIEpm1)95Q0W9_}K!<83u&7GDS3r-r+IknchpU;xl{v(JzoVjY6!qsET@{HiR? zN90oyE->}yvEMmV^tK94Kg2>59kjV?D2{$Md@HmUNky~(ZoR(}&#nGsM zQ_)|4apF;z+FmuYIw>u-HdScG1=S5bPn}^*PdY>nO-DC2DwDoQ3YVjt zS6esZcIoy$sv;4!yio6|z6vZ3%H38sh%m_Nx}yMPgj=1dTyux3a|nhuL#y&7lJ#W~XT=&#f%KI?Ml9bwBgdStuoPfOh=M$DoE`GWycjU?LK-p#XH3MJ$-^y zMzDS7ga2lXQ`UI*54?Dt?b_t5P0R}x66s$iId7h>=DJ;r5ble*62e1BU&Zxyz;9-A zh2rbC_tk#!MU5S>eT4xEQhC8LJ3Ps66|#mtc|oF^iYV+(PD)PO5q#UHf=D4=W)SYo z3-0CS0tsWf!@8?y0Oz>doN46aW=1@Og=P~ma?eFV9^ORwI@pQ6BDEB)6D-~=XqZj~ z$s4YQP(AEFeAr&CA+yLqSufeB@nf_+h)Np_hjk4<@8>^VM8``roQ3OVG0H# z7w#85gsQI4j3>W)UJK*L|S&xJ&Hp<8%%cRl-5dkT9MQNh38@$TGU~@KOnqHN zE{BLmq#Fu-J>eJcP3m=I;d6@xWHnZ9iw@OM8vKHV0Z z)Ei2!w-IMgL_YpHo@nQH*V=p&V>c-emjdqygFD2K?9gJsC9s>ZC;$QE4gn6&(|W+Z zq~S$QsuCX^931?l_E2c_CWeSB!?eBK+H28E1lvTi>;%Y&EGYTCOBmNu-n}0?nm^lk zarCi#B6EPM1!GIEN@?(gk*yq>PL&t7T&-$k%~M`UQSwpY5yrG|B8gXeFbb*e;``kHLsD!yKlXE^7Vz(y7aO4Qt9ZJGlSJR!>`9 z=e2tW!Fh9f1M_s#{k$MuETE47<}N{Rt;N z`G>Y^r6dyR)5;?y5^wcG`}QfGe0Vl7Q7fTnrOtLPInCl+g?{RVlkHP{sx=O7V(8Q52bw zu%NNAasR;c`BB>af@v0K$}Kdaj|-^TG_wv=jZZGK>D=klx`15zvuB$jtM}WvlhEie zl9l)*5f?73x_g|@Z%$AZT8N&>Jv(e2sB*N#u4(P8hV`4Tj?x%CT3JR)f4{(Rz=_b_ zEqU~96A4 (;J8$`+d=laegOG^gQ<+Darc5m)c7I$tD_NE)_YzdlKR+!{S$Vy0Kr zU`_`{jHZ#6eQw-s-SUspke3`hj$A<~3i}3ZYO#61?>p>SxR;)-(DL~F#`gr(kjd=X z{_q~7O6w@p%#4js!LnznNlo->AS=dz?SD=YlqZM>%{!rcJ*Ss1NX%SB$@tIH?!XxscO)wrQDIS{@tPb0)YI@ws z))I+!$X%YC(%y&fP3Fxz1i{-~s!fyU>LF@o_YbSbv{5;tzSN+r?S9(>j=$nwGLem)~je$p_**{L-blbawl59W};xmPmY8?}EDEBMk4q z&$mzK?SNk4yLWefR4 z;x6dGaxjnO(_4nc!ZxGp`9F&;+a2rc>kHAr;tITdhJoR+nxSDJFdKz>dUgVLdxi!F zFD|giDbq>t;%q+*JgN5@u+{-;_lpHyQV;C@ryU16Y%E&;;kR#P zwSRsD0zGvVxFAhLUOvCfL?NyA-=9cZTidG7&w7Cc^%mghIB2(s+3d4#GJu!23M~dD z6ovyP4+|oIdsl$_DJIUduU`ke1bMbBXGbJ3=U)S!h%yCuCL*wrqHSn+@r?&i7uN!? zE|5+Jw^m3PgV+fnpt1@A8Uhz0D*{I}SVm%Mh3EenvY?m*gCq0uKO4GNmW9vR2;zIX L`njxgN@xNA#Uk2% literal 0 HcmV?d00001 From 93c96f1146cd0ea123eca9ff66f4de7c9567d826 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Mon, 9 Feb 2015 10:42:28 -0800 Subject: [PATCH 076/117] Add control scripts --- start-hub.sh | 41 +++++++++++++++++++++++++++++++++++++++++ stop-hub.sh | 27 +++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100755 start-hub.sh create mode 100755 stop-hub.sh diff --git a/start-hub.sh b/start-hub.sh new file mode 100755 index 0000000..bab9c91 --- /dev/null +++ b/start-hub.sh @@ -0,0 +1,41 @@ +#!/bin/bash +source $HOME/.bash_profile +source $HOME/.bashrc +export HUB=$HOME/git/scoophealth/hquery/query-composer +export HB_PIDFILE=$HUB/tmp/pids/server.pid +export DL_PIDFILE=$HUB/tmp/pids/delayed_job.pid + +# +# Make sure mongod is running +if ! pgrep mongod > /dev/null +then + sudo service mongod start +fi +# +# +echo "Starting Query Composer on port 3002" +cd $HUB +if [ -f $DL_PIDFILE ]; +then + bundle exec $HUB/script/delayed_job stop + if [ -f $DL_FILEFILE ]; + then + rm $DL_PIDFILE + fi +fi +# +bundle exec $HUB/script/delayed_job start +# +# Start composer +# If composer is already running (or has a stale server.pid), try to stop it. +if [ -f $HB_PIDFILE ]; +then + kill `cat $HB_PIDFILE` + if [ -f $HB_PIDFILE ]; + then + kill -9 `cat $HB_PIDFILE` + rm $HB_PIDFILE + fi +fi +bundle exec rails server -p 3002 -d +#/bin/ps -ef | grep "rails server -p 3002" | grep -v grep | awk '{print $2}' > tmp/pids/server.pid diff --git a/stop-hub.sh b/stop-hub.sh new file mode 100755 index 0000000..ec65599 --- /dev/null +++ b/stop-hub.sh @@ -0,0 +1,27 @@ +#!/bin/bash +source $HOME/.bash_profile +source $HOME/.bashrc +export HUB=$HOME/git/scoophealth/hquery/query-composer +export HB_PIDFILE=$HUB/tmp/pids/server.pid +export DL_PIDFILE=$HUB/tmp/pids/delayed_job.pid +cd $HUB +if [ -f $DL_PIDFILE ]; +then + bundle exec $HUB/script/delayed_job stop + # pid file should be gone but recheck + if [ -f $DL_PIDFILE ]; + then + rm $DL_PIDFILE + fi +fi +# +# If gateway is running, stop it. +if [ -f $HB_PIDFILE ]; +then + kill `cat $HB_PIDFILE` + if [ -f $HB_PIDFILE ]; + then + kill -9 `cat $HB_PIDFILE` + fi + rm $HB_PIDFILE +fi From bdc4d0f490cd97e7db9ad9b5fb2ed37d40475543 Mon Sep 17 00:00:00 2001 From: drusk Date: Mon, 9 Feb 2015 11:03:07 -0800 Subject: [PATCH 077/117] Work in progress on batch processing of queries. --- app/controllers/queries_controller.rb | 36 +++++++++++++++++++++++++++ config/routes.rb | 3 +++ 2 files changed, 39 insertions(+) diff --git a/app/controllers/queries_controller.rb b/app/controllers/queries_controller.rb index f876894..2bfbe69 100755 --- a/app/controllers/queries_controller.rb +++ b/app/controllers/queries_controller.rb @@ -89,6 +89,42 @@ def execute end end + + def execute_batch + logger.error "Called execute_batch0" + #endpoint_ids = params[:endpoint_ids] + #endpoints = Endpoint.all + endpoints = [] + for endpoint in Endpoint.all + logger.error endpoint.name + if endpoint.name == 'pdc-test' + endpoints.push(endpoint) + end + end + + if (endpoints && !endpoints.empty?) + #if (endpoint_ids && !endpoint_ids.empty?) + + #endpoint_ids = endpoint_ids.map! {|id| Moped::BSON::ObjectId(id)} + #endpoint_ids = [Moped::BSON::ObjectId(endpoint_ids)] + #endpoints = Endpoint.criteria.for_ids(endpoint_ids) + + notify = params[:notification] + + Query.all.each do |eachQuery| + # execute the query, and pass in the endpoints and if the user should be notified by email when execution completes + eachQuery.execute(endpoints, notify) + logger.error "Executed query" + end + + logger.error "Finished queries, redirecting..." + redirect_to :action => 'index' + else + flash[:alert] = "Cannot execute a query if no endpoints are provided." + redirect_to :action => 'show' + end + end + def cancel execution = @query.executions.find(params[:execution_id]) execution.results.find(params[:result_id]).cancel diff --git a/config/routes.rb b/config/routes.rb index 59ae62f..08802f0 100755 --- a/config/routes.rb +++ b/config/routes.rb @@ -30,6 +30,9 @@ get 'edit_code' get 'result' end + collection do + get 'execute_batch' + end end From ba482783d85ec40f5bd27225040688c2e428db32 Mon Sep 17 00:00:00 2001 From: drusk Date: Mon, 9 Feb 2015 12:26:32 -0800 Subject: [PATCH 078/117] Added button to index page which prompts the user for the endpoints and then runs all queries. It now posts the endpoints to the controller. --- app/controllers/queries_controller.rb | 19 ++----- app/views/queries/_execute_all_popup.html.erb | 53 +++++++++++++++++++ app/views/queries/index.html.erb | 12 +++-- config/routes.rb | 2 +- 4 files changed, 66 insertions(+), 20 deletions(-) create mode 100644 app/views/queries/_execute_all_popup.html.erb diff --git a/app/controllers/queries_controller.rb b/app/controllers/queries_controller.rb index 2bfbe69..b57ce12 100755 --- a/app/controllers/queries_controller.rb +++ b/app/controllers/queries_controller.rb @@ -92,22 +92,11 @@ def execute def execute_batch logger.error "Called execute_batch0" - #endpoint_ids = params[:endpoint_ids] - #endpoints = Endpoint.all - endpoints = [] - for endpoint in Endpoint.all - logger.error endpoint.name - if endpoint.name == 'pdc-test' - endpoints.push(endpoint) - end - end - - if (endpoints && !endpoints.empty?) - #if (endpoint_ids && !endpoint_ids.empty?) + endpoint_ids = params[:endpoint_ids] - #endpoint_ids = endpoint_ids.map! {|id| Moped::BSON::ObjectId(id)} - #endpoint_ids = [Moped::BSON::ObjectId(endpoint_ids)] - #endpoints = Endpoint.criteria.for_ids(endpoint_ids) + if (endpoint_ids && !endpoint_ids.empty?) + endpoint_ids = endpoint_ids.map! {|id| Moped::BSON::ObjectId(id)} + endpoints = Endpoint.criteria.for_ids(endpoint_ids) notify = params[:notification] diff --git a/app/views/queries/_execute_all_popup.html.erb b/app/views/queries/_execute_all_popup.html.erb new file mode 100644 index 0000000..7dca954 --- /dev/null +++ b/app/views/queries/_execute_all_popup.html.erb @@ -0,0 +1,53 @@ +<% content_for :head do -%> + +<% end -%> + +

    + <%= simple_form_for :query, :url => url_for(:controller => 'queries', :action => 'execute_batch'), :method => 'post', :html => {id: 'execute-all-popup-form'} do |f| %> +

    Notification:

    + <%= check_box_tag "notification", true, false %> Send email notification when query completes +

    Endpoints:

    + + + + + + + + + + + <% for endpoint in endpoints %> + + + + + + <% end %> + +
    TitleUrl
    <%= check_box_tag "endpoint_ids[]", endpoint.id, endpoints.length == 1 ? true : false %><%= endpoint.name %><%= endpoint.base_url %>
    + <% end %> +
    diff --git a/app/views/queries/index.html.erb b/app/views/queries/index.html.erb index 6c6df9d..edce415 100755 --- a/app/views/queries/index.html.erb +++ b/app/views/queries/index.html.erb @@ -42,10 +42,14 @@ <% end %> + <%= render partial: 'execute_all_popup', locals: { endpoints: Endpoint.all, button_id: 'execute-all-button' } %> + <%= link_to(new_query_path, class: "btn primary m") do %>Add Query<% end %> -
    -
    -
    -
    + + +
    +
    +
    +

    diff --git a/config/routes.rb b/config/routes.rb index 08802f0..361f9ea 100755 --- a/config/routes.rb +++ b/config/routes.rb @@ -31,7 +31,7 @@ get 'result' end collection do - get 'execute_batch' + post 'execute_batch' end end From 5c66270828c40666a53878ed56ffd035bf5bf40d Mon Sep 17 00:00:00 2001 From: drusk Date: Mon, 9 Feb 2015 12:35:35 -0800 Subject: [PATCH 079/117] Only show execute all queries button to non-admin users. Removed some debugging log statements. --- app/controllers/queries_controller.rb | 5 +---- app/views/queries/index.html.erb | 4 +++- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/app/controllers/queries_controller.rb b/app/controllers/queries_controller.rb index b57ce12..f13037f 100755 --- a/app/controllers/queries_controller.rb +++ b/app/controllers/queries_controller.rb @@ -91,7 +91,6 @@ def execute def execute_batch - logger.error "Called execute_batch0" endpoint_ids = params[:endpoint_ids] if (endpoint_ids && !endpoint_ids.empty?) @@ -103,14 +102,12 @@ def execute_batch Query.all.each do |eachQuery| # execute the query, and pass in the endpoints and if the user should be notified by email when execution completes eachQuery.execute(endpoints, notify) - logger.error "Executed query" end - logger.error "Finished queries, redirecting..." redirect_to :action => 'index' else flash[:alert] = "Cannot execute a query if no endpoints are provided." - redirect_to :action => 'show' + redirect_to :action => 'index' end end diff --git a/app/views/queries/index.html.erb b/app/views/queries/index.html.erb index edce415..cd2cdbc 100755 --- a/app/views/queries/index.html.erb +++ b/app/views/queries/index.html.erb @@ -45,7 +45,9 @@ <%= render partial: 'execute_all_popup', locals: { endpoints: Endpoint.all, button_id: 'execute-all-button' } %> <%= link_to(new_query_path, class: "btn primary m") do %>Add Query<% end %> - + <% if !current_user.admin %> + + <% end %>
    From 965cdfcac7abb9cd7fbaf0413b2ac37ae7e0932b Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Tue, 10 Feb 2015 09:49:21 -0800 Subject: [PATCH 080/117] Renamed start/stop scripts as examples, added utility to report mongo data --- start-hub.sh => start-hub-example.sh | 0 stop-hub.sh => stop-hub-example.sh | 0 util/database.py | 70 ++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) rename start-hub.sh => start-hub-example.sh (100%) rename stop-hub.sh => stop-hub-example.sh (100%) create mode 100644 util/database.py diff --git a/start-hub.sh b/start-hub-example.sh similarity index 100% rename from start-hub.sh rename to start-hub-example.sh diff --git a/stop-hub.sh b/stop-hub-example.sh similarity index 100% rename from stop-hub.sh rename to stop-hub-example.sh diff --git a/util/database.py b/util/database.py new file mode 100644 index 0000000..acf301d --- /dev/null +++ b/util/database.py @@ -0,0 +1,70 @@ +__author__ = 'rrusk' + +import datetime +import pymongo + +class MongoDatabase(object): + + DEFAULT_DB_NAME = "query_composer_development" + + ENDPOINTS_COLLECTION = "endpoints" + QUERIES_COLLECTION = "queries" + RESULTS_COLLECTION = "results" + + def __init__(self, db_name=DEFAULT_DB_NAME, host="localhost", port=27017): + self._client = pymongo.MongoClient("mongodb://{host}:{port}".format(host=host, port=port)) + self._db = self._client[db_name] + + def _get_endpoints_collection(self): + return self._db[self.ENDPOINTS_COLLECTION] + + def _get_queries_collection(self): + return self._db[self.QUERIES_COLLECTION] + + def _get_results_collection(self): + return self._db[self.RESULTS_COLLECTION] + + + def get_endpoints(self): + find_query = {} + return list(self._get_endpoints_collection().find(find_query)) + + + def get_queries(self): + find_query = {} + return list(self._get_queries_collection().find(find_query)) + + def get_results(self): + find_query = {} + return list(self._get_results_collection().find(find_query)) + +def main(): + db = MongoDatabase() + print "ENDPOINTS:" + endpoints= db.get_endpoints() + print endpoints + print "\nQUERIES:" + queries = db.get_queries() + for query in queries: + print + print query['description'], query['title'] + executions = query['executions'] + for execution in executions: + jstime = execution['time'] + dt = datetime.datetime.fromtimestamp(jstime) + print dt + try: + aggregate_result = execution['aggregate_result'] + print aggregate_result + except KeyError: continue + print "\nRESULTS:" + results = db.get_results() + for result in results: + print + print result['status'], result['created_at'], result['updated_at'] + print result['endpoint_id'], result['execution_id'] + #print result['value'] + #print results + + +if __name__ == '__main__':main() \ No newline at end of file From 2a570be0d288825696878db70a9e26c463d891ab Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Thu, 12 Feb 2015 09:19:25 -0800 Subject: [PATCH 081/117] Work in progress on STOPP reporting tool --- util/database.py | 90 +++++++++++++++++++++++++++++++++++++++------- util/db.py | 94 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 171 insertions(+), 13 deletions(-) create mode 100644 util/db.py diff --git a/util/database.py b/util/database.py index acf301d..76bb386 100644 --- a/util/database.py +++ b/util/database.py @@ -24,12 +24,10 @@ def _get_queries_collection(self): def _get_results_collection(self): return self._db[self.RESULTS_COLLECTION] - def get_endpoints(self): find_query = {} return list(self._get_endpoints_collection().find(find_query)) - def get_queries(self): find_query = {} return list(self._get_queries_collection().find(find_query)) @@ -38,33 +36,99 @@ def get_results(self): find_query = {} return list(self._get_results_collection().find(find_query)) +def select_endpoint(endpoint_id, endpoints): + for endpoint in endpoints: + if endpoint['_id'] == endpoint_id: + return endpoint + +def select_endpoint_id_by_name(name, endpoints): + for endpoint in endpoints: + if endpoint['name'] == name: + return endpoint['_id'] + +def select_query_id_by_desc(desc, queries): + for query in queries: + if query['description'] == desc: + return query['_id'] + +def select_execution(execution_id, executions): + for execution in executions: + if execution['_id'] == execution_id: + return execution + +def select_results(query_id, endpoint_id, queries, results): + selections = [] + execution_ids = [] + for query in queries: + if query['_id'] == query_id: + executions = query['executions'] + for execution in executions: + execution_ids.append(execution['_id']) + + for result in results: + if result['endpoint_id'] == endpoint_id: + if result['execution_id'] in execution_ids: + selections.append(result) + return selections + +def select_result(execution_id, endpoint_id, results): + for result in results: + if result['execution_id'] == execution_id: + if result['endpoint_id'] == endpoint_id: + return result + def main(): db = MongoDatabase() print "ENDPOINTS:" endpoints= db.get_endpoints() - print endpoints + for endpoint in endpoints: + print + print endpoint['_id'], endpoint['name'] print "\nQUERIES:" queries = db.get_queries() + results = db.get_results() for query in queries: print - print query['description'], query['title'] + print query['description'] executions = query['executions'] for execution in executions: jstime = execution['time'] dt = datetime.datetime.fromtimestamp(jstime) print dt + execution_id = execution['_id'] + #print id try: aggregate_result = execution['aggregate_result'] print aggregate_result except KeyError: continue + for endpoint in endpoints: + endpoint_id = endpoint['_id'] + result = select_result(execution_id, endpoint_id, results) + if result: + try: + print result['created_at'], result['value'] + except KeyError: continue print "\nRESULTS:" - results = db.get_results() for result in results: - print - print result['status'], result['created_at'], result['updated_at'] - print result['endpoint_id'], result['execution_id'] - #print result['value'] - #print results - - -if __name__ == '__main__':main() \ No newline at end of file + #print + #print result['status'], result['created_at'], result['updated_at'] + #print result['endpoint_id'], result['execution_id'] + endpoint = select_endpoint(result['endpoint_id'], endpoints) + #print endpoint['name'] + execution = select_execution(result['execution_id'], endpoints) + #print execution['aggregate_result'] + #print result['query_url'] + #print "RESULT:", result + + print "Selected result" + queryid = select_query_id_by_desc('PDC-009', queries) + print "queryid: ",queryid + endpoint = select_endpoint_id_by_name('Bayswater-02',endpoints) + print "endpoint: ",endpoint + selected = select_results(queryid, endpoint, queries, results) + for item in selected: + try: + print item['created_at'], item['value']['numerator'], item['value']['denominator'] + except KeyError: print "missing key" + +if __name__ == '__main__':main() diff --git a/util/db.py b/util/db.py new file mode 100644 index 0000000..d1de2cd --- /dev/null +++ b/util/db.py @@ -0,0 +1,94 @@ +__author__ = 'rrusk' + +import datetime +import pymongo + +class MongoDatabase(object): + + DEFAULT_DB_NAME = "query_composer_development" + + ENDPOINTS_COLLECTION = "endpoints" + QUERIES_COLLECTION = "queries" + RESULTS_COLLECTION = "results" + + def __init__(self, db_name=DEFAULT_DB_NAME, host="localhost", port=27017): + self._client = pymongo.MongoClient("mongodb://{host}:{port}".format(host=host, port=port)) + self._db = self._client[db_name] + + def _get_endpoints_collection(self): + return self._db[self.ENDPOINTS_COLLECTION] + + def _get_queries_collection(self): + return self._db[self.QUERIES_COLLECTION] + + def _get_results_collection(self): + return self._db[self.RESULTS_COLLECTION] + + def get_endpoints(self): + find_query = {} + return list(self._get_endpoints_collection().find(find_query)) + + def get_queries(self): + find_query = {} + return list(self._get_queries_collection().find(find_query)) + + def get_results(self): + find_query = {} + return list(self._get_results_collection().find(find_query)) + +def select_result(execution_id, endpoint_id, results): + for result in results: + if result['execution_id'] == execution_id: + if result['endpoint_id'] == endpoint_id: + return result + +def main(): + db = MongoDatabase() + endpoints= db.get_endpoints() + queries = db.get_queries() + results = db.get_results() + for query in queries: + if not query['description'].startswith("STOPP Rule "): + continue + print + desc = query['description'].split()[2] + print desc, query['title'] + executions = query['executions'] + for execution in executions: + jstime = execution['time'] + dt = datetime.datetime.fromtimestamp(jstime) + #print dt + execution_id = execution['_id'] + #print id + keys = [] + try: + aggregate_result = execution['aggregate_result'] + for key in aggregate_result: + keys.append(key) + except KeyError: continue + print "keys: ", keys + #sortedkeys = keys.sort() + #print "sortedkeys: ", sortedkeys + try: + aggregate_result = execution['aggregate_result'] + print dt, + for key in keys: + print key, aggregate_result[key], + print + except KeyError: continue + + for endpoint in endpoints: + endpoint_id = endpoint['_id'] + result = select_result(execution_id, endpoint_id, results) + if result: + try: + print ' ', endpoint['name'], + value = result['value'] + for key in value: + if key in keys: + print key, value[key], + print + except KeyError: continue + + +if __name__ == '__main__':main() From 326967c065cfab44101983b65a7df616ba9b0c5d Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Thu, 12 Feb 2015 15:11:55 -0800 Subject: [PATCH 082/117] Mostly functional --- util/db.py | 59 +++++++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/util/db.py b/util/db.py index d1de2cd..68ed71c 100644 --- a/util/db.py +++ b/util/db.py @@ -50,45 +50,44 @@ def main(): for query in queries: if not query['description'].startswith("STOPP Rule "): continue - print desc = query['description'].split()[2] print desc, query['title'] executions = query['executions'] for execution in executions: jstime = execution['time'] dt = datetime.datetime.fromtimestamp(jstime) - #print dt execution_id = execution['_id'] - #print id - keys = [] - try: - aggregate_result = execution['aggregate_result'] - for key in aggregate_result: - keys.append(key) - except KeyError: continue - print "keys: ", keys - #sortedkeys = keys.sort() - #print "sortedkeys: ", sortedkeys + try: aggregate_result = execution['aggregate_result'] - print dt, - for key in keys: - print key, aggregate_result[key], - print except KeyError: continue - - for endpoint in endpoints: - endpoint_id = endpoint['_id'] - result = select_result(execution_id, endpoint_id, results) - if result: - try: - print ' ', endpoint['name'], - value = result['value'] - for key in value: - if key in keys: - print key, value[key], - print - except KeyError: continue - + if aggregate_result: + keys = [] + reportline = " " + reportline += str(dt) + reportline += " aggregate:" + for key in aggregate_result: + reportline += ' '+str(key)+' '+str(int(aggregate_result[key])) + keys.append(key) + print reportline + + for endpoint in endpoints: + endpoint_id = endpoint['_id'] + result = select_result(execution_id, endpoint_id, results) + if result: + reportline = ' '+str(endpoint['name']) + try: + value = result['value'] + except KeyError: continue + for key in keys: + try: + reportline += ' '+ str(key)+' '+str(int(value[key])) + except KeyError: continue + if len(reportline) > 0: + print reportline + else: + print "NO RESULT:" + print + if __name__ == '__main__':main() From 5e63bab79af26f38f81f87a106a2ac6831680514 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Thu, 12 Feb 2015 16:05:56 -0800 Subject: [PATCH 083/117] Sort output by rule numbers --- util/db.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/util/db.py b/util/db.py index 68ed71c..5fe49c7 100644 --- a/util/db.py +++ b/util/db.py @@ -36,6 +36,10 @@ def get_results(self): find_query = {} return list(self._get_results_collection().find(find_query)) + def get_query(self,queryid): + find_query = {'_id': queryid} + return (list(self._get_queries_collection().find(find_query)))[0] + def select_result(execution_id, endpoint_id, results): for result in results: if result['execution_id'] == execution_id: @@ -47,9 +51,17 @@ def main(): endpoints= db.get_endpoints() queries = db.get_queries() results = db.get_results() + + querySet = {} for query in queries: if not query['description'].startswith("STOPP Rule "): continue + querySet[query['description']] = query['_id'] + queryDesc = sorted(querySet) + + for desc in queryDesc: # want queries sorted by description + queryid = querySet[desc] + query = db.get_query(queryid) desc = query['description'].split()[2] print desc, query['title'] executions = query['executions'] From 7136cf249423e320617ce3906f685de010038da5 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Thu, 12 Feb 2015 16:10:04 -0800 Subject: [PATCH 084/117] Removed some print statements --- util/db.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/util/db.py b/util/db.py index 5fe49c7..b4574f9 100644 --- a/util/db.py +++ b/util/db.py @@ -95,10 +95,7 @@ def main(): try: reportline += ' '+ str(key)+' '+str(int(value[key])) except KeyError: continue - if len(reportline) > 0: - print reportline - else: - print "NO RESULT:" + print reportline print From bb815d9afdcf5ad4e281ca00d81c3e31f872b826 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Fri, 13 Feb 2015 10:41:13 -0800 Subject: [PATCH 085/117] Rename STOPP report tool --- util/{db.py => STOPP_report_tool.py} | 0 util/database.py | 134 --------------------------- 2 files changed, 134 deletions(-) rename util/{db.py => STOPP_report_tool.py} (100%) delete mode 100644 util/database.py diff --git a/util/db.py b/util/STOPP_report_tool.py similarity index 100% rename from util/db.py rename to util/STOPP_report_tool.py diff --git a/util/database.py b/util/database.py deleted file mode 100644 index 76bb386..0000000 --- a/util/database.py +++ /dev/null @@ -1,134 +0,0 @@ -__author__ = 'rrusk' - -import datetime -import pymongo - -class MongoDatabase(object): - - DEFAULT_DB_NAME = "query_composer_development" - - ENDPOINTS_COLLECTION = "endpoints" - QUERIES_COLLECTION = "queries" - RESULTS_COLLECTION = "results" - - def __init__(self, db_name=DEFAULT_DB_NAME, host="localhost", port=27017): - self._client = pymongo.MongoClient("mongodb://{host}:{port}".format(host=host, port=port)) - self._db = self._client[db_name] - - def _get_endpoints_collection(self): - return self._db[self.ENDPOINTS_COLLECTION] - - def _get_queries_collection(self): - return self._db[self.QUERIES_COLLECTION] - - def _get_results_collection(self): - return self._db[self.RESULTS_COLLECTION] - - def get_endpoints(self): - find_query = {} - return list(self._get_endpoints_collection().find(find_query)) - - def get_queries(self): - find_query = {} - return list(self._get_queries_collection().find(find_query)) - - def get_results(self): - find_query = {} - return list(self._get_results_collection().find(find_query)) - -def select_endpoint(endpoint_id, endpoints): - for endpoint in endpoints: - if endpoint['_id'] == endpoint_id: - return endpoint - -def select_endpoint_id_by_name(name, endpoints): - for endpoint in endpoints: - if endpoint['name'] == name: - return endpoint['_id'] - -def select_query_id_by_desc(desc, queries): - for query in queries: - if query['description'] == desc: - return query['_id'] - -def select_execution(execution_id, executions): - for execution in executions: - if execution['_id'] == execution_id: - return execution - -def select_results(query_id, endpoint_id, queries, results): - selections = [] - execution_ids = [] - for query in queries: - if query['_id'] == query_id: - executions = query['executions'] - for execution in executions: - execution_ids.append(execution['_id']) - - for result in results: - if result['endpoint_id'] == endpoint_id: - if result['execution_id'] in execution_ids: - selections.append(result) - return selections - -def select_result(execution_id, endpoint_id, results): - for result in results: - if result['execution_id'] == execution_id: - if result['endpoint_id'] == endpoint_id: - return result - -def main(): - db = MongoDatabase() - print "ENDPOINTS:" - endpoints= db.get_endpoints() - for endpoint in endpoints: - print - print endpoint['_id'], endpoint['name'] - print "\nQUERIES:" - queries = db.get_queries() - results = db.get_results() - for query in queries: - print - print query['description'] - executions = query['executions'] - for execution in executions: - jstime = execution['time'] - dt = datetime.datetime.fromtimestamp(jstime) - print dt - execution_id = execution['_id'] - #print id - try: - aggregate_result = execution['aggregate_result'] - print aggregate_result - except KeyError: continue - for endpoint in endpoints: - endpoint_id = endpoint['_id'] - result = select_result(execution_id, endpoint_id, results) - if result: - try: - print result['created_at'], result['value'] - except KeyError: continue - print "\nRESULTS:" - for result in results: - #print - #print result['status'], result['created_at'], result['updated_at'] - #print result['endpoint_id'], result['execution_id'] - endpoint = select_endpoint(result['endpoint_id'], endpoints) - #print endpoint['name'] - execution = select_execution(result['execution_id'], endpoints) - #print execution['aggregate_result'] - #print result['query_url'] - #print "RESULT:", result - - print "Selected result" - queryid = select_query_id_by_desc('PDC-009', queries) - print "queryid: ",queryid - endpoint = select_endpoint_id_by_name('Bayswater-02',endpoints) - print "endpoint: ",endpoint - selected = select_results(queryid, endpoint, queries, results) - for item in selected: - try: - print item['created_at'], item['value']['numerator'], item['value']['denominator'] - except KeyError: print "missing key" - -if __name__ == '__main__':main() From 5565b1207a4c114b3ebad3fef259e78bd20edde8 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Fri, 27 Feb 2015 13:10:52 -0800 Subject: [PATCH 086/117] Script to extract STOPP DQ queries --- util/DQ_report_tool.py | 106 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 util/DQ_report_tool.py diff --git a/util/DQ_report_tool.py b/util/DQ_report_tool.py new file mode 100644 index 0000000..1be9907 --- /dev/null +++ b/util/DQ_report_tool.py @@ -0,0 +1,106 @@ +__author__ = 'rrusk' + +import datetime +import pymongo + +class MongoDatabase(object): + + DEFAULT_DB_NAME = "query_composer_development" + + ENDPOINTS_COLLECTION = "endpoints" + QUERIES_COLLECTION = "queries" + RESULTS_COLLECTION = "results" + + def __init__(self, db_name=DEFAULT_DB_NAME, host="localhost", port=27017): + self._client = pymongo.MongoClient("mongodb://{host}:{port}".format(host=host, port=port)) + self._db = self._client[db_name] + + def _get_endpoints_collection(self): + return self._db[self.ENDPOINTS_COLLECTION] + + def _get_queries_collection(self): + return self._db[self.QUERIES_COLLECTION] + + def _get_results_collection(self): + return self._db[self.RESULTS_COLLECTION] + + def get_endpoints(self): + find_query = {} + return list(self._get_endpoints_collection().find(find_query)) + + def get_queries(self): + find_query = {} + return list(self._get_queries_collection().find(find_query)) + + def get_results(self): + find_query = {} + return list(self._get_results_collection().find(find_query)) + + def get_query(self,queryid): + find_query = {'_id': queryid} + return (list(self._get_queries_collection().find(find_query)))[0] + +def select_result(execution_id, endpoint_id, results): + for result in results: + if result['execution_id'] == execution_id: + if result['endpoint_id'] == endpoint_id: + return result + +def main(): + db = MongoDatabase() + endpoints= db.get_endpoints() + queries = db.get_queries() + results = db.get_results() + + querySet = {} + for query in queries: + if not query['description'].startswith("DQ-"): + continue + querySet[query['description']] = query['_id'] + queryDesc = sorted(querySet) + + for desc in queryDesc: # want queries sorted by description + queryid = querySet[desc] + query = db.get_query(queryid) + desc = query['description'] + print desc, query['title'] + executions = query['executions'] + for execution in executions: + jstime = execution['time'] + dt = datetime.datetime.fromtimestamp(jstime) + if dt < datetime.datetime(2015,2,27,12,0,0): + #print "dt =", dt + #print "date =", datetime.datetime(2015,2,27,12,0,0) + continue + execution_id = execution['_id'] + + try: + aggregate_result = execution['aggregate_result'] + except KeyError: continue + if aggregate_result: + keys = [] + reportline = " " + reportline += str(dt) + reportline += " aggregate:" + for key in aggregate_result: + reportline += ' '+str(key)+' '+str(int(aggregate_result[key])) + keys.append(key) + print reportline + + for endpoint in endpoints: + endpoint_id = endpoint['_id'] + result = select_result(execution_id, endpoint_id, results) + if result: + reportline = ' '+str(endpoint['name']) + try: + value = result['value'] + except KeyError: continue + for key in keys: + try: + reportline += ' '+ str(key)+' '+str(int(value[key])) + except KeyError: continue + print reportline + print + + +if __name__ == '__main__':main() From 26bff8a1ada5884ebb3821e7aced3429c70997af Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Wed, 4 Mar 2015 10:34:08 -0800 Subject: [PATCH 087/117] Modify report for only later than specified date --- util/STOPP_report_tool.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/util/STOPP_report_tool.py b/util/STOPP_report_tool.py index b4574f9..b353088 100644 --- a/util/STOPP_report_tool.py +++ b/util/STOPP_report_tool.py @@ -68,6 +68,10 @@ def main(): for execution in executions: jstime = execution['time'] dt = datetime.datetime.fromtimestamp(jstime) + if dt < datetime.datetime(2015,2,19,12,0,0): + #print "dt =", dt + #print "date =", datetime.datetime(2015,2,19,12,0,0) + continue execution_id = execution['_id'] try: From b3395d225f3b565bb0d697ebf3fcfe314800f07c Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Thu, 26 Mar 2015 12:20:06 -0700 Subject: [PATCH 088/117] Updated patientapi documentation --- public/patientapi/files.html | 2 +- public/patientapi/index.html | 2 +- public/patientapi/symbols/__hasProp.html | 2 +- public/patientapi/symbols/_global_.html | 2 +- public/patientapi/symbols/hQuery.Actor.html | 2 +- public/patientapi/symbols/hQuery.Address.html | 2 +- .../symbols/hQuery.AdministrationTiming.html | 2 +- public/patientapi/symbols/hQuery.Allergy.html | 2 +- .../symbols/hQuery.CauseOfDeath.html | 2 +- .../patientapi/symbols/hQuery.CodedEntry.html | 2 +- .../symbols/hQuery.CodedEntryList.html | 2 +- .../patientapi/symbols/hQuery.CodedValue.html | 2 +- .../patientapi/symbols/hQuery.Condition.html | 2 +- .../patientapi/symbols/hQuery.DateRange.html | 2 +- .../symbols/hQuery.DoseRestriction.html | 2 +- .../patientapi/symbols/hQuery.Encounter.html | 2 +- .../patientapi/symbols/hQuery.Facility.html | 2 +- .../symbols/hQuery.Fulfillment.html | 2 +- .../symbols/hQuery.FunctionalStatus.html | 2 +- .../symbols/hQuery.Immunization.html | 2 +- .../patientapi/symbols/hQuery.Informant.html | 2 +- .../patientapi/symbols/hQuery.Language.html | 2 +- .../patientapi/symbols/hQuery.Medication.html | 84 +- .../symbols/hQuery.MedicationInformation.html | 2 +- .../symbols/hQuery.NoImmunization.html | 2 +- .../symbols/hQuery.OrderInformation.html | 2 +- .../symbols/hQuery.Organization.html | 2 +- public/patientapi/symbols/hQuery.Patient.html | 2 +- public/patientapi/symbols/hQuery.Person.html | 2 +- .../symbols/hQuery.PhysicalQuantity.html | 2 +- .../patientapi/symbols/hQuery.Pregnancy.html | 2 +- .../patientapi/symbols/hQuery.Procedure.html | 2 +- .../patientapi/symbols/hQuery.Provider.html | 2 +- public/patientapi/symbols/hQuery.Result.html | 2 +- public/patientapi/symbols/hQuery.Scalar.html | 2 +- public/patientapi/symbols/hQuery.Status.html | 2 +- .../symbols/hQuery.StatusOfMedication.html | 2 +- .../patientapi/symbols/hQuery.Supports.html | 2 +- public/patientapi/symbols/hQuery.Telecom.html | 2 +- .../symbols/hQuery.TypeOfMedication.html | 2 +- .../symbols/src/tmp_patient.js.html | 3360 +++++++++-------- 41 files changed, 1812 insertions(+), 1710 deletions(-) diff --git a/public/patientapi/files.html b/public/patientapi/files.html index 8a5e974..9af1b54 100644 --- a/public/patientapi/files.html +++ b/public/patientapi/files.html @@ -284,7 +284,7 @@

    tmp/patient.js

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    \ No newline at end of file diff --git a/public/patientapi/index.html b/public/patientapi/index.html index 5754d90..4632901 100644 --- a/public/patientapi/index.html +++ b/public/patientapi/index.html @@ -504,7 +504,7 @@

    hQuery.TypeOfMedication
    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    \ No newline at end of file diff --git a/public/patientapi/symbols/__hasProp.html b/public/patientapi/symbols/__hasProp.html index e68b545..cf29267 100644 --- a/public/patientapi/symbols/__hasProp.html +++ b/public/patientapi/symbols/__hasProp.html @@ -367,7 +367,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:26 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/_global_.html b/public/patientapi/symbols/_global_.html index 93b4d51..e257ced 100644 --- a/public/patientapi/symbols/_global_.html +++ b/public/patientapi/symbols/_global_.html @@ -394,7 +394,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:26 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Actor.html b/public/patientapi/symbols/hQuery.Actor.html index 8a36a19..f73e7c9 100644 --- a/public/patientapi/symbols/hQuery.Actor.html +++ b/public/patientapi/symbols/hQuery.Actor.html @@ -503,7 +503,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:26 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Address.html b/public/patientapi/symbols/hQuery.Address.html index 87b7c8b..0430828 100644 --- a/public/patientapi/symbols/hQuery.Address.html +++ b/public/patientapi/symbols/hQuery.Address.html @@ -599,7 +599,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:26 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.AdministrationTiming.html b/public/patientapi/symbols/hQuery.AdministrationTiming.html index 976fddb..67141e2 100644 --- a/public/patientapi/symbols/hQuery.AdministrationTiming.html +++ b/public/patientapi/symbols/hQuery.AdministrationTiming.html @@ -523,7 +523,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Allergy.html b/public/patientapi/symbols/hQuery.Allergy.html index 0d12ed0..6c562b7 100644 --- a/public/patientapi/symbols/hQuery.Allergy.html +++ b/public/patientapi/symbols/hQuery.Allergy.html @@ -722,7 +722,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.CauseOfDeath.html b/public/patientapi/symbols/hQuery.CauseOfDeath.html index 0dc7ed9..b905179 100644 --- a/public/patientapi/symbols/hQuery.CauseOfDeath.html +++ b/public/patientapi/symbols/hQuery.CauseOfDeath.html @@ -517,7 +517,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.CodedEntry.html b/public/patientapi/symbols/hQuery.CodedEntry.html index 2671f2a..bf5c227 100644 --- a/public/patientapi/symbols/hQuery.CodedEntry.html +++ b/public/patientapi/symbols/hQuery.CodedEntry.html @@ -1162,7 +1162,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.CodedEntryList.html b/public/patientapi/symbols/hQuery.CodedEntryList.html index e59fd62..89fdb15 100644 --- a/public/patientapi/symbols/hQuery.CodedEntryList.html +++ b/public/patientapi/symbols/hQuery.CodedEntryList.html @@ -829,7 +829,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.CodedValue.html b/public/patientapi/symbols/hQuery.CodedValue.html index 87b7d8a..ee30b69 100644 --- a/public/patientapi/symbols/hQuery.CodedValue.html +++ b/public/patientapi/symbols/hQuery.CodedValue.html @@ -672,7 +672,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Condition.html b/public/patientapi/symbols/hQuery.Condition.html index a658316..fd7880a 100644 --- a/public/patientapi/symbols/hQuery.Condition.html +++ b/public/patientapi/symbols/hQuery.Condition.html @@ -784,7 +784,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.DateRange.html b/public/patientapi/symbols/hQuery.DateRange.html index a204d55..1db39f5 100644 --- a/public/patientapi/symbols/hQuery.DateRange.html +++ b/public/patientapi/symbols/hQuery.DateRange.html @@ -503,7 +503,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.DoseRestriction.html b/public/patientapi/symbols/hQuery.DoseRestriction.html index 7b800a2..7e8ee49 100644 --- a/public/patientapi/symbols/hQuery.DoseRestriction.html +++ b/public/patientapi/symbols/hQuery.DoseRestriction.html @@ -503,7 +503,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Encounter.html b/public/patientapi/symbols/hQuery.Encounter.html index a046e12..ef1407c 100644 --- a/public/patientapi/symbols/hQuery.Encounter.html +++ b/public/patientapi/symbols/hQuery.Encounter.html @@ -939,7 +939,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Facility.html b/public/patientapi/symbols/hQuery.Facility.html index 192ee39..71762b2 100644 --- a/public/patientapi/symbols/hQuery.Facility.html +++ b/public/patientapi/symbols/hQuery.Facility.html @@ -446,7 +446,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Fulfillment.html b/public/patientapi/symbols/hQuery.Fulfillment.html index f4e9c3e..82d31a7 100644 --- a/public/patientapi/symbols/hQuery.Fulfillment.html +++ b/public/patientapi/symbols/hQuery.Fulfillment.html @@ -435,7 +435,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.FunctionalStatus.html b/public/patientapi/symbols/hQuery.FunctionalStatus.html index bf78e83..80478f9 100644 --- a/public/patientapi/symbols/hQuery.FunctionalStatus.html +++ b/public/patientapi/symbols/hQuery.FunctionalStatus.html @@ -552,7 +552,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Immunization.html b/public/patientapi/symbols/hQuery.Immunization.html index 1dbf301..6273a46 100644 --- a/public/patientapi/symbols/hQuery.Immunization.html +++ b/public/patientapi/symbols/hQuery.Immunization.html @@ -715,7 +715,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Informant.html b/public/patientapi/symbols/hQuery.Informant.html index 60156d4..963b23e 100644 --- a/public/patientapi/symbols/hQuery.Informant.html +++ b/public/patientapi/symbols/hQuery.Informant.html @@ -518,7 +518,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Language.html b/public/patientapi/symbols/hQuery.Language.html index 8e73b8e..8069547 100644 --- a/public/patientapi/symbols/hQuery.Language.html +++ b/public/patientapi/symbols/hQuery.Language.html @@ -534,7 +534,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Medication.html b/public/patientapi/symbols/hQuery.Medication.html index ce58f1a..5cb394c 100644 --- a/public/patientapi/symbols/hQuery.Medication.html +++ b/public/patientapi/symbols/hQuery.Medication.html @@ -440,6 +440,24 @@

    + +   + + +
    + + + + +   + +
    isPRN() +
    +
    + + + <inner>   @@ -980,6 +998,70 @@

    +
    + + +
    + + {Boolean} + isLongTerm() + +
    +
    + + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {Boolean}
    + +
    + + + + +
    + + +
    + + {Boolean} + isPRN() + +
    +
    + + + +
    + + + + + + + + +
    +
    Returns:
    + +
    {Boolean}
    + +
    + + + +
    @@ -1358,7 +1440,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.MedicationInformation.html b/public/patientapi/symbols/hQuery.MedicationInformation.html index f954c3a..f5fec87 100644 --- a/public/patientapi/symbols/hQuery.MedicationInformation.html +++ b/public/patientapi/symbols/hQuery.MedicationInformation.html @@ -612,7 +612,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:48 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.NoImmunization.html b/public/patientapi/symbols/hQuery.NoImmunization.html index c78f343..ea500d9 100644 --- a/public/patientapi/symbols/hQuery.NoImmunization.html +++ b/public/patientapi/symbols/hQuery.NoImmunization.html @@ -773,7 +773,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.OrderInformation.html b/public/patientapi/symbols/hQuery.OrderInformation.html index bf4e892..ecea83b 100644 --- a/public/patientapi/symbols/hQuery.OrderInformation.html +++ b/public/patientapi/symbols/hQuery.OrderInformation.html @@ -605,7 +605,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Organization.html b/public/patientapi/symbols/hQuery.Organization.html index 7ae6860..a4e6895 100644 --- a/public/patientapi/symbols/hQuery.Organization.html +++ b/public/patientapi/symbols/hQuery.Organization.html @@ -599,7 +599,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Patient.html b/public/patientapi/symbols/hQuery.Patient.html index 69fd060..37f5983 100644 --- a/public/patientapi/symbols/hQuery.Patient.html +++ b/public/patientapi/symbols/hQuery.Patient.html @@ -1615,7 +1615,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Person.html b/public/patientapi/symbols/hQuery.Person.html index a375685..2a8079c 100644 --- a/public/patientapi/symbols/hQuery.Person.html +++ b/public/patientapi/symbols/hQuery.Person.html @@ -640,7 +640,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.PhysicalQuantity.html b/public/patientapi/symbols/hQuery.PhysicalQuantity.html index bb3b62c..3c46c66 100644 --- a/public/patientapi/symbols/hQuery.PhysicalQuantity.html +++ b/public/patientapi/symbols/hQuery.PhysicalQuantity.html @@ -503,7 +503,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Pregnancy.html b/public/patientapi/symbols/hQuery.Pregnancy.html index 0a24007..7a0bcd2 100644 --- a/public/patientapi/symbols/hQuery.Pregnancy.html +++ b/public/patientapi/symbols/hQuery.Pregnancy.html @@ -495,7 +495,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Procedure.html b/public/patientapi/symbols/hQuery.Procedure.html index f6e2011..79f70cc 100644 --- a/public/patientapi/symbols/hQuery.Procedure.html +++ b/public/patientapi/symbols/hQuery.Procedure.html @@ -660,7 +660,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Provider.html b/public/patientapi/symbols/hQuery.Provider.html index fd8aad6..f49cdeb 100644 --- a/public/patientapi/symbols/hQuery.Provider.html +++ b/public/patientapi/symbols/hQuery.Provider.html @@ -722,7 +722,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Result.html b/public/patientapi/symbols/hQuery.Result.html index 349cf5b..8981224 100644 --- a/public/patientapi/symbols/hQuery.Result.html +++ b/public/patientapi/symbols/hQuery.Result.html @@ -623,7 +623,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Scalar.html b/public/patientapi/symbols/hQuery.Scalar.html index 621aa1b..2741e9d 100644 --- a/public/patientapi/symbols/hQuery.Scalar.html +++ b/public/patientapi/symbols/hQuery.Scalar.html @@ -503,7 +503,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Status.html b/public/patientapi/symbols/hQuery.Status.html index dedf3b9..b70a32c 100644 --- a/public/patientapi/symbols/hQuery.Status.html +++ b/public/patientapi/symbols/hQuery.Status.html @@ -783,7 +783,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.StatusOfMedication.html b/public/patientapi/symbols/hQuery.StatusOfMedication.html index 6db9d46..f133ee3 100644 --- a/public/patientapi/symbols/hQuery.StatusOfMedication.html +++ b/public/patientapi/symbols/hQuery.StatusOfMedication.html @@ -607,7 +607,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Supports.html b/public/patientapi/symbols/hQuery.Supports.html index 79f8d0a..7b5023d 100644 --- a/public/patientapi/symbols/hQuery.Supports.html +++ b/public/patientapi/symbols/hQuery.Supports.html @@ -640,7 +640,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.Telecom.html b/public/patientapi/symbols/hQuery.Telecom.html index 5a532c2..201cba1 100644 --- a/public/patientapi/symbols/hQuery.Telecom.html +++ b/public/patientapi/symbols/hQuery.Telecom.html @@ -600,7 +600,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/hQuery.TypeOfMedication.html b/public/patientapi/symbols/hQuery.TypeOfMedication.html index 86d8b01..c12c8c1 100644 --- a/public/patientapi/symbols/hQuery.TypeOfMedication.html +++ b/public/patientapi/symbols/hQuery.TypeOfMedication.html @@ -528,7 +528,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Mon Sep 08 2014 11:44:49 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Thu Mar 26 2015 12:15:27 GMT-0700 (PDT)
    diff --git a/public/patientapi/symbols/src/tmp_patient.js.html b/public/patientapi/symbols/src/tmp_patient.js.html index c3b4740..4148c70 100644 --- a/public/patientapi/symbols/src/tmp_patient.js.html +++ b/public/patientapi/symbols/src/tmp_patient.js.html @@ -1527,116 +1527,116 @@ 1520 }; 1521 1522 /** -1523 The actual or intended start of a medication. Slight deviation from greenCDA for C32 since -1524 it combines this with medication stop -1525 @returns {Date} -1526 */ -1527 -1528 -1529 Medication.prototype.indicateMedicationStart = function() { -1530 return hQuery.dateFromUtcSeconds(this.json['start_time']); -1531 }; -1532 -1533 /** -1534 The actual or intended stop of a medication. Slight deviation from greenCDA for C32 since -1535 it combines this with medication start -1536 @returns {Date} -1537 */ -1538 +1523 @returns {Boolean} +1524 */ +1525 +1526 +1527 Medication.prototype.isPRN = function() { +1528 return this.json['freeTextSig'].indexOf("E2E_PRN_FLAG") !== -1; +1529 }; +1530 +1531 /** +1532 @returns {Boolean} +1533 */ +1534 +1535 +1536 Medication.prototype.isLongTerm = function() { +1537 return this.json['freeTextSig'].indexOf("E2E_LONG_TERM_FLAG") !== -1; +1538 }; 1539 -1540 Medication.prototype.indicateMedicationStop = function() { -1541 return hQuery.dateFromUtcSeconds(this.json['end_time']); -1542 }; -1543 -1544 Medication.prototype.administrationTiming = function() { -1545 if (this.json['administrationTiming']) { -1546 return new hQuery.AdministrationTiming(this.json['administrationTiming']); -1547 } -1548 }; -1549 -1550 /** -1551 @returns {CodedValue} Contains routeCode or adminstrationUnitCode information. -1552 Route code shall have a a value drawn from FDA route of adminstration, -1553 and indicates how the medication is received by the patient. -1554 See http://www.fda.gov/Drugs/DevelopmentApprovalProcess/UCM070829 -1555 The administration unit code shall have a value drawn from the FDA -1556 dosage form, source NCI thesaurus and represents the physical form of the -1557 product as presented to the patient. -1558 See http://www.fda.gov/Drugs/InformationOnDrugs/ucm142454.htm -1559 */ -1560 +1540 /** +1541 The actual or intended start of a medication. Slight deviation from greenCDA for C32 since +1542 it combines this with medication stop +1543 @returns {Date} +1544 */ +1545 +1546 +1547 Medication.prototype.indicateMedicationStart = function() { +1548 return hQuery.dateFromUtcSeconds(this.json['start_time']); +1549 }; +1550 +1551 /** +1552 The actual or intended stop of a medication. Slight deviation from greenCDA for C32 since +1553 it combines this with medication start +1554 @returns {Date} +1555 */ +1556 +1557 +1558 Medication.prototype.indicateMedicationStop = function() { +1559 return hQuery.dateFromUtcSeconds(this.json['end_time']); +1560 }; 1561 -1562 Medication.prototype.route = function() { -1563 return hQuery.createCodedValue(this.json['route']); -1564 }; -1565 -1566 /** -1567 @returns {hQuery.Scalar} the dose -1568 */ -1569 -1570 -1571 Medication.prototype.dose = function() { -1572 if (this.json['dose']) { -1573 return new hQuery.Scalar(this.json['dose']); -1574 } -1575 }; -1576 -1577 /** -1578 @returns {CodedValue} -1579 */ -1580 -1581 -1582 Medication.prototype.site = function() { -1583 if (this.json['site']) { -1584 return hQuery.createCodedValue(this.json['site']); -1585 } -1586 }; +1562 Medication.prototype.administrationTiming = function() { +1563 if (this.json['administrationTiming']) { +1564 return new hQuery.AdministrationTiming(this.json['administrationTiming']); +1565 } +1566 }; +1567 +1568 /** +1569 @returns {CodedValue} Contains routeCode or adminstrationUnitCode information. +1570 Route code shall have a a value drawn from FDA route of adminstration, +1571 and indicates how the medication is received by the patient. +1572 See http://www.fda.gov/Drugs/DevelopmentApprovalProcess/UCM070829 +1573 The administration unit code shall have a value drawn from the FDA +1574 dosage form, source NCI thesaurus and represents the physical form of the +1575 product as presented to the patient. +1576 See http://www.fda.gov/Drugs/InformationOnDrugs/ucm142454.htm +1577 */ +1578 +1579 +1580 Medication.prototype.route = function() { +1581 return hQuery.createCodedValue(this.json['route']); +1582 }; +1583 +1584 /** +1585 @returns {hQuery.Scalar} the dose +1586 */ 1587 -1588 /** -1589 @returns {hQuery.DoseRestriction} -1590 */ -1591 -1592 -1593 Medication.prototype.doseRestriction = function() { -1594 if (this.json['doseRestriction']) { -1595 return new hQuery.DoseRestriction(this.json['doseRestriction']); -1596 } -1597 }; +1588 +1589 Medication.prototype.dose = function() { +1590 if (this.json['dose']) { +1591 return new hQuery.Scalar(this.json['dose']); +1592 } +1593 }; +1594 +1595 /** +1596 @returns {CodedValue} +1597 */ 1598 -1599 /** -1600 @returns {String} -1601 */ -1602 -1603 -1604 Medication.prototype.doseIndicator = function() { -1605 return this.json['doseIndicator']; -1606 }; -1607 -1608 /** -1609 @returns {String} -1610 */ -1611 -1612 -1613 Medication.prototype.fulfillmentInstructions = function() { -1614 return this.json['fulfillmentInstructions']; +1599 +1600 Medication.prototype.site = function() { +1601 if (this.json['site']) { +1602 return hQuery.createCodedValue(this.json['site']); +1603 } +1604 }; +1605 +1606 /** +1607 @returns {hQuery.DoseRestriction} +1608 */ +1609 +1610 +1611 Medication.prototype.doseRestriction = function() { +1612 if (this.json['doseRestriction']) { +1613 return new hQuery.DoseRestriction(this.json['doseRestriction']); +1614 } 1615 }; 1616 1617 /** -1618 @returns {CodedValue} +1618 @returns {String} 1619 */ 1620 1621 -1622 Medication.prototype.indication = function() { -1623 return hQuery.createCodedValue(this.json['indication']); +1622 Medication.prototype.doseIndicator = function() { +1623 return this.json['doseIndicator']; 1624 }; 1625 1626 /** -1627 @returns {CodedValue} +1627 @returns {String} 1628 */ 1629 1630 -1631 Medication.prototype.productForm = function() { -1632 return hQuery.createCodedValue(this.json['productForm']); +1631 Medication.prototype.fulfillmentInstructions = function() { +1632 return this.json['fulfillmentInstructions']; 1633 }; 1634 1635 /** @@ -1644,8 +1644,8 @@ 1637 */ 1638 1639 -1640 Medication.prototype.vehicle = function() { -1641 return hQuery.createCodedValue(this.json['vehicle']); +1640 Medication.prototype.indication = function() { +1641 return hQuery.createCodedValue(this.json['indication']); 1642 }; 1643 1644 /** @@ -1653,8 +1653,8 @@ 1646 */ 1647 1648 -1649 Medication.prototype.reaction = function() { -1650 return hQuery.createCodedValue(this.json['reaction']); +1649 Medication.prototype.productForm = function() { +1650 return hQuery.createCodedValue(this.json['productForm']); 1651 }; 1652 1653 /** @@ -1662,639 +1662,639 @@ 1655 */ 1656 1657 -1658 Medication.prototype.deliveryMethod = function() { -1659 return hQuery.createCodedValue(this.json['deliveryMethod']); +1658 Medication.prototype.vehicle = function() { +1659 return hQuery.createCodedValue(this.json['vehicle']); 1660 }; 1661 1662 /** -1663 @returns {hQuery.MedicationInformation} +1663 @returns {CodedValue} 1664 */ 1665 1666 -1667 Medication.prototype.medicationInformation = function() { -1668 return new hQuery.MedicationInformation(this.json); +1667 Medication.prototype.reaction = function() { +1668 return hQuery.createCodedValue(this.json['reaction']); 1669 }; 1670 1671 /** -1672 @returns {hQuery.TypeOfMedication} Indicates whether this is an over the counter or prescription medication +1672 @returns {CodedValue} 1673 */ 1674 1675 -1676 Medication.prototype.typeOfMedication = function() { -1677 var _ref, _ref1; -1678 return new hQuery.TypeOfMedication((_ref = this.json['typeOfMedication']) != null ? _ref['code'] : void 0, (_ref1 = this.json['typeOfMedication']) != null ? _ref1['codeSystem'] : void 0); -1679 }; -1680 -1681 /** -1682 Values conform to value set 2.16.840.1.113883.1.11.20.7 - Medication Status -1683 Values may be: On Hold, No Longer Active, Active, Prior History -1684 @returns {hQuery.StatusOfMedication} Used to indicate the status of the medication. -1685 */ -1686 -1687 -1688 Medication.prototype.statusOfMedication = function() { -1689 var _ref, _ref1; -1690 return new hQuery.StatusOfMedication((_ref = this.json['statusOfMedication']) != null ? _ref['code'] : void 0, (_ref1 = this.json['statusOfMedication']) != null ? _ref1['codeSystem'] : void 0); -1691 }; +1676 Medication.prototype.deliveryMethod = function() { +1677 return hQuery.createCodedValue(this.json['deliveryMethod']); +1678 }; +1679 +1680 /** +1681 @returns {hQuery.MedicationInformation} +1682 */ +1683 +1684 +1685 Medication.prototype.medicationInformation = function() { +1686 return new hQuery.MedicationInformation(this.json); +1687 }; +1688 +1689 /** +1690 @returns {hQuery.TypeOfMedication} Indicates whether this is an over the counter or prescription medication +1691 */ 1692 -1693 /** -1694 @returns {String} free text instructions to the patient -1695 */ -1696 -1697 -1698 Medication.prototype.patientInstructions = function() { -1699 return this.json['patientInstructions']; -1700 }; -1701 -1702 /** -1703 The duration over which this medication has been active. For example, 5 days. -1704 @returns {Hash} with two keys: unit and scalar -1705 */ -1706 -1707 -1708 Medication.prototype.cumulativeMedicationDuration = function() { -1709 return this.json['cumulativeMedicationDuration']; -1710 }; -1711 -1712 /** -1713 @returns {Array} an array of {@link FulFillment} objects -1714 */ +1693 +1694 Medication.prototype.typeOfMedication = function() { +1695 var _ref, _ref1; +1696 return new hQuery.TypeOfMedication((_ref = this.json['typeOfMedication']) != null ? _ref['code'] : void 0, (_ref1 = this.json['typeOfMedication']) != null ? _ref1['codeSystem'] : void 0); +1697 }; +1698 +1699 /** +1700 Values conform to value set 2.16.840.1.113883.1.11.20.7 - Medication Status +1701 Values may be: On Hold, No Longer Active, Active, Prior History +1702 @returns {hQuery.StatusOfMedication} Used to indicate the status of the medication. +1703 */ +1704 +1705 +1706 Medication.prototype.statusOfMedication = function() { +1707 var _ref, _ref1; +1708 return new hQuery.StatusOfMedication((_ref = this.json['statusOfMedication']) != null ? _ref['code'] : void 0, (_ref1 = this.json['statusOfMedication']) != null ? _ref1['codeSystem'] : void 0); +1709 }; +1710 +1711 /** +1712 @returns {String} free text instructions to the patient +1713 */ +1714 1715 -1716 -1717 Medication.prototype.fulfillmentHistory = function() { -1718 var order, _i, _len, _ref, _results; -1719 _ref = this.json['fulfillmentHistory']; -1720 _results = []; -1721 for (_i = 0, _len = _ref.length; _i < _len; _i++) { -1722 order = _ref[_i]; -1723 _results.push(new hQuery.Fulfillment(order)); -1724 } -1725 return _results; -1726 }; -1727 -1728 /** -1729 @returns {Array} an array of {@link OrderInformation} objects -1730 */ -1731 -1732 -1733 Medication.prototype.orderInformation = function() { -1734 var order, _i, _len, _ref, _results; -1735 _ref = this.json['orderInformation']; -1736 _results = []; -1737 for (_i = 0, _len = _ref.length; _i < _len; _i++) { -1738 order = _ref[_i]; -1739 _results.push(new hQuery.OrderInformation(order)); -1740 } -1741 return _results; -1742 }; -1743 -1744 return Medication; +1716 Medication.prototype.patientInstructions = function() { +1717 return this.json['patientInstructions']; +1718 }; +1719 +1720 /** +1721 The duration over which this medication has been active. For example, 5 days. +1722 @returns {Hash} with two keys: unit and scalar +1723 */ +1724 +1725 +1726 Medication.prototype.cumulativeMedicationDuration = function() { +1727 return this.json['cumulativeMedicationDuration']; +1728 }; +1729 +1730 /** +1731 @returns {Array} an array of {@link FulFillment} objects +1732 */ +1733 +1734 +1735 Medication.prototype.fulfillmentHistory = function() { +1736 var order, _i, _len, _ref, _results; +1737 _ref = this.json['fulfillmentHistory']; +1738 _results = []; +1739 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +1740 order = _ref[_i]; +1741 _results.push(new hQuery.Fulfillment(order)); +1742 } +1743 return _results; +1744 }; 1745 -1746 })(hQuery.CodedEntry); -1747 /** -1748 @namespace scoping into the hquery namespace -1749 */ +1746 /** +1747 @returns {Array} an array of {@link OrderInformation} objects +1748 */ +1749 1750 -1751 var __hasProp = {}.hasOwnProperty, -1752 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; -1753 -1754 this.hQuery || (this.hQuery = {}); -1755 -1756 /** -1757 @class CauseOfDeath -1758 @exports CauseOfDeath as hQuery.CauseOfDeath -1759 */ -1760 +1751 Medication.prototype.orderInformation = function() { +1752 var order, _i, _len, _ref, _results; +1753 _ref = this.json['orderInformation']; +1754 _results = []; +1755 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +1756 order = _ref[_i]; +1757 _results.push(new hQuery.OrderInformation(order)); +1758 } +1759 return _results; +1760 }; 1761 -1762 hQuery.CauseOfDeath = (function() { +1762 return Medication; 1763 -1764 CauseOfDeath.name = 'CauseOfDeath'; -1765 -1766 function CauseOfDeath(json) { -1767 this.json = json; -1768 } -1769 -1770 /** -1771 @returns {hQuery.Date} -1772 */ +1764 })(hQuery.CodedEntry); +1765 /** +1766 @namespace scoping into the hquery namespace +1767 */ +1768 +1769 var __hasProp = {}.hasOwnProperty, +1770 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; +1771 +1772 this.hQuery || (this.hQuery = {}); 1773 -1774 -1775 CauseOfDeath.prototype.timeOfDeath = function() { -1776 return new hQuery.dateFromUtcSeconds(this.json['timeOfDeath']); -1777 }; +1774 /** +1775 @class CauseOfDeath +1776 @exports CauseOfDeath as hQuery.CauseOfDeath +1777 */ 1778 -1779 /** -1780 @returns {int} -1781 */ -1782 +1779 +1780 hQuery.CauseOfDeath = (function() { +1781 +1782 CauseOfDeath.name = 'CauseOfDeath'; 1783 -1784 CauseOfDeath.prototype.ageAtDeath = function() { -1785 return this.json['ageAtDeath']; -1786 }; +1784 function CauseOfDeath(json) { +1785 this.json = json; +1786 } 1787 -1788 return CauseOfDeath; -1789 -1790 })(); +1788 /** +1789 @returns {hQuery.Date} +1790 */ 1791 -1792 /** -1793 @class hQuery.Condition -1794 -1795 This section is used to describe a patients problems/conditions. The types of conditions -1796 described have been constrained to the SNOMED CT Problem Type code set. An unbounded -1797 number of treating providers for the particular condition can be supplied. -1798 @exports Condition as hQuery.Condition -1799 @augments hQuery.CodedEntry -1800 */ +1792 +1793 CauseOfDeath.prototype.timeOfDeath = function() { +1794 return new hQuery.dateFromUtcSeconds(this.json['timeOfDeath']); +1795 }; +1796 +1797 /** +1798 @returns {int} +1799 */ +1800 1801 -1802 -1803 hQuery.Condition = (function(_super) { -1804 -1805 __extends(Condition, _super); -1806 -1807 Condition.name = 'Condition'; -1808 -1809 function Condition(json) { -1810 this.json = json; -1811 Condition.__super__.constructor.call(this, this.json); -1812 } -1813 -1814 /** -1815 @returns {Array, hQuery.Provider} an array of providers for the condition -1816 */ -1817 -1818 -1819 Condition.prototype.providers = function() { -1820 var provider, _i, _len, _ref, _results; -1821 _ref = this.json['treatingProviders']; -1822 _results = []; -1823 for (_i = 0, _len = _ref.length; _i < _len; _i++) { -1824 provider = _ref[_i]; -1825 _results.push(new Provider(provider)); -1826 } -1827 return _results; -1828 }; -1829 -1830 /** -1831 Diagnosis Priority -1832 @returns {int} -1833 */ -1834 +1802 CauseOfDeath.prototype.ageAtDeath = function() { +1803 return this.json['ageAtDeath']; +1804 }; +1805 +1806 return CauseOfDeath; +1807 +1808 })(); +1809 +1810 /** +1811 @class hQuery.Condition +1812 +1813 This section is used to describe a patients problems/conditions. The types of conditions +1814 described have been constrained to the SNOMED CT Problem Type code set. An unbounded +1815 number of treating providers for the particular condition can be supplied. +1816 @exports Condition as hQuery.Condition +1817 @augments hQuery.CodedEntry +1818 */ +1819 +1820 +1821 hQuery.Condition = (function(_super) { +1822 +1823 __extends(Condition, _super); +1824 +1825 Condition.name = 'Condition'; +1826 +1827 function Condition(json) { +1828 this.json = json; +1829 Condition.__super__.constructor.call(this, this.json); +1830 } +1831 +1832 /** +1833 @returns {Array, hQuery.Provider} an array of providers for the condition +1834 */ 1835 -1836 Condition.prototype.diagnosisPriority = function() { -1837 return this.json['priority']; -1838 }; -1839 -1840 /** -1841 Ordinality -1842 @returns {CodedValue} -1843 */ -1844 -1845 -1846 Condition.prototype.ordinality = function() { -1847 return hQuery.createCodedValue(this.json['ordinality']); -1848 }; -1849 -1850 /** -1851 age at onset -1852 @returns {int} -1853 */ -1854 -1855 -1856 Condition.prototype.ageAtOnset = function() { -1857 return this.json['ageAtOnset']; -1858 }; -1859 -1860 /** -1861 cause of death -1862 @returns {hQuery.CauseOfDeath} -1863 */ -1864 -1865 -1866 Condition.prototype.causeOfDeath = function() { -1867 if (this.json['causeOfDeath']) { -1868 return new hQuery.CauseOfDeath(this.json['causeOfDeath']); -1869 } -1870 }; -1871 -1872 /** -1873 problem status -1874 @returns {hQuery.CodedValue} -1875 */ -1876 +1836 +1837 Condition.prototype.providers = function() { +1838 var provider, _i, _len, _ref, _results; +1839 _ref = this.json['treatingProviders']; +1840 _results = []; +1841 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +1842 provider = _ref[_i]; +1843 _results.push(new Provider(provider)); +1844 } +1845 return _results; +1846 }; +1847 +1848 /** +1849 Diagnosis Priority +1850 @returns {int} +1851 */ +1852 +1853 +1854 Condition.prototype.diagnosisPriority = function() { +1855 return this.json['priority']; +1856 }; +1857 +1858 /** +1859 Ordinality +1860 @returns {CodedValue} +1861 */ +1862 +1863 +1864 Condition.prototype.ordinality = function() { +1865 return hQuery.createCodedValue(this.json['ordinality']); +1866 }; +1867 +1868 /** +1869 age at onset +1870 @returns {int} +1871 */ +1872 +1873 +1874 Condition.prototype.ageAtOnset = function() { +1875 return this.json['ageAtOnset']; +1876 }; 1877 -1878 Condition.prototype.problemStatus = function() { -1879 return hQuery.createCodedValue(this.json['problemStatus']); -1880 }; -1881 -1882 /** -1883 comment -1884 @returns {String} -1885 */ -1886 -1887 -1888 Condition.prototype.comment = function() { -1889 return this.json['comment']; -1890 }; -1891 -1892 /** -1893 This is a description of the level of the severity of the condition. -1894 @returns {CodedValue} -1895 */ -1896 -1897 -1898 Condition.prototype.severity = function() { -1899 return hQuery.createCodedValue(this.json['severity']); -1900 }; -1901 -1902 return Condition; -1903 -1904 })(hQuery.CodedEntry); -1905 /** -1906 @namespace scoping into the hquery namespace -1907 */ -1908 -1909 var __hasProp = {}.hasOwnProperty, -1910 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; -1911 -1912 this.hQuery || (this.hQuery = {}); -1913 -1914 /** -1915 An Encounter is an interaction, regardless of the setting, between a patient and a -1916 practitioner who is vested with primary responsibility for diagnosing, evaluating, -1917 or treating the patients condition. It may include visits, appointments, as well -1918 as non face-to-face interactions. It is also a contact between a patient and a -1919 practitioner who has primary responsibility for assessing and treating the -1920 patient at a given contact, exercising independent judgment. -1921 @class An Encounter is an interaction, regardless of the setting, between a patient and a -1922 practitioner -1923 @augments hQuery.CodedEntry -1924 @exports Encounter as hQuery.Encounter +1878 /** +1879 cause of death +1880 @returns {hQuery.CauseOfDeath} +1881 */ +1882 +1883 +1884 Condition.prototype.causeOfDeath = function() { +1885 if (this.json['causeOfDeath']) { +1886 return new hQuery.CauseOfDeath(this.json['causeOfDeath']); +1887 } +1888 }; +1889 +1890 /** +1891 problem status +1892 @returns {hQuery.CodedValue} +1893 */ +1894 +1895 +1896 Condition.prototype.problemStatus = function() { +1897 return hQuery.createCodedValue(this.json['problemStatus']); +1898 }; +1899 +1900 /** +1901 comment +1902 @returns {String} +1903 */ +1904 +1905 +1906 Condition.prototype.comment = function() { +1907 return this.json['comment']; +1908 }; +1909 +1910 /** +1911 This is a description of the level of the severity of the condition. +1912 @returns {CodedValue} +1913 */ +1914 +1915 +1916 Condition.prototype.severity = function() { +1917 return hQuery.createCodedValue(this.json['severity']); +1918 }; +1919 +1920 return Condition; +1921 +1922 })(hQuery.CodedEntry); +1923 /** +1924 @namespace scoping into the hquery namespace 1925 */ 1926 -1927 -1928 hQuery.Encounter = (function(_super) { +1927 var __hasProp = {}.hasOwnProperty, +1928 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; 1929 -1930 __extends(Encounter, _super); +1930 this.hQuery || (this.hQuery = {}); 1931 -1932 Encounter.name = 'Encounter'; -1933 -1934 function Encounter(json) { -1935 this.json = json; -1936 Encounter.__super__.constructor.call(this, this.json); -1937 if (this.json['admitTime']) { -1938 this._admitTime = hQuery.dateFromUtcSeconds(this.json['admitTime']); -1939 } -1940 if (this.json['dischargeTime']) { -1941 this._dischargeTime = hQuery.dateFromUtcSeconds(this.json['dischargeTime']); -1942 } -1943 if (this.json['facility']) { -1944 this._facility = new hQuery.Facility(this.json['facility']); -1945 } -1946 } +1932 /** +1933 An Encounter is an interaction, regardless of the setting, between a patient and a +1934 practitioner who is vested with primary responsibility for diagnosing, evaluating, +1935 or treating the patients condition. It may include visits, appointments, as well +1936 as non face-to-face interactions. It is also a contact between a patient and a +1937 practitioner who has primary responsibility for assessing and treating the +1938 patient at a given contact, exercising independent judgment. +1939 @class An Encounter is an interaction, regardless of the setting, between a patient and a +1940 practitioner +1941 @augments hQuery.CodedEntry +1942 @exports Encounter as hQuery.Encounter +1943 */ +1944 +1945 +1946 hQuery.Encounter = (function(_super) { 1947 -1948 /** -1949 @returns {String} -1950 */ +1948 __extends(Encounter, _super); +1949 +1950 Encounter.name = 'Encounter'; 1951 -1952 -1953 Encounter.prototype.dischargeDisposition = function() { -1954 return this.json['dischargeDisposition']; -1955 }; -1956 -1957 /** -1958 A code indicating the priority of the admission (e.g., Emergency, Urgent, Elective, et cetera) from -1959 National Uniform Billing Committee (NUBC) -1960 @returns {CodedValue} -1961 */ -1962 -1963 -1964 Encounter.prototype.admitType = function() { -1965 return hQuery.createCodedValue(this.json['admitType']); -1966 }; -1967 -1968 /** -1969 Date and time at which the patient was admitted for the encounter -1970 @returns {Date} -1971 */ -1972 -1973 -1974 Encounter.prototype.admitTime = function() { -1975 return this._admitTime; -1976 }; -1977 -1978 /** -1979 Date and time at which the patient was discharged for the encounter -1980 @returns {Date} -1981 */ -1982 -1983 -1984 Encounter.prototype.dischargeTime = function() { -1985 return this._dischargeTime; -1986 }; -1987 -1988 /** -1989 @returns {hQuery.Actor} -1990 */ +1952 function Encounter(json) { +1953 this.json = json; +1954 Encounter.__super__.constructor.call(this, this.json); +1955 if (this.json['admitTime']) { +1956 this._admitTime = hQuery.dateFromUtcSeconds(this.json['admitTime']); +1957 } +1958 if (this.json['dischargeTime']) { +1959 this._dischargeTime = hQuery.dateFromUtcSeconds(this.json['dischargeTime']); +1960 } +1961 if (this.json['facility']) { +1962 this._facility = new hQuery.Facility(this.json['facility']); +1963 } +1964 } +1965 +1966 /** +1967 @returns {String} +1968 */ +1969 +1970 +1971 Encounter.prototype.dischargeDisposition = function() { +1972 return this.json['dischargeDisposition']; +1973 }; +1974 +1975 /** +1976 A code indicating the priority of the admission (e.g., Emergency, Urgent, Elective, et cetera) from +1977 National Uniform Billing Committee (NUBC) +1978 @returns {CodedValue} +1979 */ +1980 +1981 +1982 Encounter.prototype.admitType = function() { +1983 return hQuery.createCodedValue(this.json['admitType']); +1984 }; +1985 +1986 /** +1987 Date and time at which the patient was admitted for the encounter +1988 @returns {Date} +1989 */ +1990 1991 -1992 -1993 Encounter.prototype.performer = function() { -1994 if (this.json['performer']) { -1995 return new hQuery.Actor(this.json['performer']); -1996 } -1997 }; -1998 -1999 /** -2000 @returns {hQuery.Organization} -2001 */ -2002 -2003 -2004 Encounter.prototype.facility = function() { -2005 return this._facility; -2006 }; -2007 -2008 Encounter.prototype.facilityArrival = function() { -2009 var _ref; -2010 return (_ref = this._facility) != null ? _ref.startDate() : void 0; -2011 }; -2012 -2013 Encounter.prototype.facilityDeparture = function() { -2014 var _ref; -2015 return (_ref = this._facility) != null ? _ref.endDate() : void 0; -2016 }; -2017 -2018 /** -2019 @returns {hQuery.CodedEntry} -2020 */ +1992 Encounter.prototype.admitTime = function() { +1993 return this._admitTime; +1994 }; +1995 +1996 /** +1997 Date and time at which the patient was discharged for the encounter +1998 @returns {Date} +1999 */ +2000 +2001 +2002 Encounter.prototype.dischargeTime = function() { +2003 return this._dischargeTime; +2004 }; +2005 +2006 /** +2007 @returns {hQuery.Actor} +2008 */ +2009 +2010 +2011 Encounter.prototype.performer = function() { +2012 if (this.json['performer']) { +2013 return new hQuery.Actor(this.json['performer']); +2014 } +2015 }; +2016 +2017 /** +2018 @returns {hQuery.Organization} +2019 */ +2020 2021 -2022 -2023 Encounter.prototype.reasonForVisit = function() { -2024 if (this.json['reason']) { -2025 return new hQuery.CodedEntry(this.json['reason']); -2026 } -2027 }; -2028 -2029 /** -2030 @returns {Integer} -2031 */ -2032 -2033 -2034 Encounter.prototype.lengthOfStay = function() { -2035 if (!((this.startDate() != null) && (this.endDate() != null))) { -2036 return 0; -2037 } -2038 return Math.floor((this.endDate() - this.startDate()) / (1000 * 60 * 60 * 24)); -2039 }; +2022 Encounter.prototype.facility = function() { +2023 return this._facility; +2024 }; +2025 +2026 Encounter.prototype.facilityArrival = function() { +2027 var _ref; +2028 return (_ref = this._facility) != null ? _ref.startDate() : void 0; +2029 }; +2030 +2031 Encounter.prototype.facilityDeparture = function() { +2032 var _ref; +2033 return (_ref = this._facility) != null ? _ref.endDate() : void 0; +2034 }; +2035 +2036 /** +2037 @returns {hQuery.CodedEntry} +2038 */ +2039 2040 -2041 /** -2042 @returns {CodedValue} -2043 */ -2044 -2045 -2046 Encounter.prototype.transferTo = function() { -2047 return hQuery.createCodedValue(this.json['transferTo']); -2048 }; -2049 -2050 /** -2051 @returns {CodedValue} -2052 */ -2053 -2054 -2055 Encounter.prototype.transferFrom = function() { -2056 return hQuery.createCodedValue(this.json['transferFrom']); +2041 Encounter.prototype.reasonForVisit = function() { +2042 if (this.json['reason']) { +2043 return new hQuery.CodedEntry(this.json['reason']); +2044 } +2045 }; +2046 +2047 /** +2048 @returns {Integer} +2049 */ +2050 +2051 +2052 Encounter.prototype.lengthOfStay = function() { +2053 if (!((this.startDate() != null) && (this.endDate() != null))) { +2054 return 0; +2055 } +2056 return Math.floor((this.endDate() - this.startDate()) / (1000 * 60 * 60 * 24)); 2057 }; 2058 -2059 return Encounter; -2060 -2061 })(hQuery.CodedEntry); -2062 /** -2063 @namespace scoping into the hquery namespace -2064 */ -2065 -2066 var __hasProp = {}.hasOwnProperty, -2067 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; -2068 -2069 this.hQuery || (this.hQuery = {}); -2070 -2071 /** -2072 This represents all interventional, surgical, diagnostic, or therapeutic procedures or -2073 treatments pertinent to the patient. -2074 @class -2075 @augments hQuery.CodedEntry -2076 @exports Procedure as hQuery.Procedure -2077 */ +2059 /** +2060 @returns {CodedValue} +2061 */ +2062 +2063 +2064 Encounter.prototype.transferTo = function() { +2065 return hQuery.createCodedValue(this.json['transferTo']); +2066 }; +2067 +2068 /** +2069 @returns {CodedValue} +2070 */ +2071 +2072 +2073 Encounter.prototype.transferFrom = function() { +2074 return hQuery.createCodedValue(this.json['transferFrom']); +2075 }; +2076 +2077 return Encounter; 2078 -2079 -2080 hQuery.Procedure = (function(_super) { -2081 -2082 __extends(Procedure, _super); +2079 })(hQuery.CodedEntry); +2080 /** +2081 @namespace scoping into the hquery namespace +2082 */ 2083 -2084 Procedure.name = 'Procedure'; -2085 -2086 function Procedure(json) { -2087 this.json = json; -2088 Procedure.__super__.constructor.call(this, this.json); -2089 } -2090 -2091 /** -2092 @returns {hQuery.Actor} The provider that performed the procedure -2093 */ -2094 -2095 -2096 Procedure.prototype.performer = function() { -2097 if (this.json['performer']) { -2098 return new hQuery.Actor(this.json['performer']); -2099 } -2100 }; +2084 var __hasProp = {}.hasOwnProperty, +2085 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; +2086 +2087 this.hQuery || (this.hQuery = {}); +2088 +2089 /** +2090 This represents all interventional, surgical, diagnostic, or therapeutic procedures or +2091 treatments pertinent to the patient. +2092 @class +2093 @augments hQuery.CodedEntry +2094 @exports Procedure as hQuery.Procedure +2095 */ +2096 +2097 +2098 hQuery.Procedure = (function(_super) { +2099 +2100 __extends(Procedure, _super); 2101 -2102 /** -2103 @returns {hQuery.CodedValue} A SNOMED code indicating the body site on which the -2104 procedure was performed -2105 */ -2106 -2107 -2108 Procedure.prototype.site = function() { -2109 var _ref, _ref1; -2110 return new hQuery.CodedValue((_ref = this.json['site']) != null ? _ref['code'] : void 0, (_ref1 = this.json['site']) != null ? _ref1['codeSystem'] : void 0); -2111 }; +2102 Procedure.name = 'Procedure'; +2103 +2104 function Procedure(json) { +2105 this.json = json; +2106 Procedure.__super__.constructor.call(this, this.json); +2107 } +2108 +2109 /** +2110 @returns {hQuery.Actor} The provider that performed the procedure +2111 */ 2112 -2113 /** -2114 @returns {hQuery.CodedValue} A SNOMED code indicating where the procedure was performed. -2115 */ -2116 -2117 -2118 Procedure.prototype.source = function() { -2119 return hQuery.createCodedValue(this.json['source']); -2120 }; -2121 -2122 /** -2123 @returns {Date} The actual or intended start of an incision. -2124 */ +2113 +2114 Procedure.prototype.performer = function() { +2115 if (this.json['performer']) { +2116 return new hQuery.Actor(this.json['performer']); +2117 } +2118 }; +2119 +2120 /** +2121 @returns {hQuery.CodedValue} A SNOMED code indicating the body site on which the +2122 procedure was performed +2123 */ +2124 2125 -2126 -2127 Procedure.prototype.incisionTime = function() { -2128 if (this.json['incisionTime']) { -2129 return hQuery.dateFromUtcSeconds(this.json['incisionTime']); -2130 } -2131 }; -2132 -2133 /** -2134 Ordinality -2135 @returns {CodedValue} -2136 */ -2137 -2138 -2139 Procedure.prototype.ordinality = function() { -2140 return hQuery.createCodedValue(this.json['ordinality']); -2141 }; -2142 -2143 return Procedure; +2126 Procedure.prototype.site = function() { +2127 var _ref, _ref1; +2128 return new hQuery.CodedValue((_ref = this.json['site']) != null ? _ref['code'] : void 0, (_ref1 = this.json['site']) != null ? _ref1['codeSystem'] : void 0); +2129 }; +2130 +2131 /** +2132 @returns {hQuery.CodedValue} A SNOMED code indicating where the procedure was performed. +2133 */ +2134 +2135 +2136 Procedure.prototype.source = function() { +2137 return hQuery.createCodedValue(this.json['source']); +2138 }; +2139 +2140 /** +2141 @returns {Date} The actual or intended start of an incision. +2142 */ +2143 2144 -2145 })(hQuery.CodedEntry); -2146 /** -2147 @namespace scoping into the hquery namespace -2148 */ -2149 -2150 var __hasProp = {}.hasOwnProperty, -2151 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; -2152 -2153 this.hQuery || (this.hQuery = {}); -2154 -2155 /** -2156 Observations generated by laboratories, imaging procedures, and other procedures. The scope -2157 includes hematology, chemistry, serology, virology, toxicology, microbiology, plain x-ray, -2158 ultrasound, CT, MRI, angiography, cardiac echo, nuclear medicine, pathology, and procedure -2159 observations. -2160 @class -2161 @augments hQuery.CodedEntry -2162 @exports Result as hQuery.Result -2163 */ -2164 -2165 -2166 hQuery.Result = (function(_super) { +2145 Procedure.prototype.incisionTime = function() { +2146 if (this.json['incisionTime']) { +2147 return hQuery.dateFromUtcSeconds(this.json['incisionTime']); +2148 } +2149 }; +2150 +2151 /** +2152 Ordinality +2153 @returns {CodedValue} +2154 */ +2155 +2156 +2157 Procedure.prototype.ordinality = function() { +2158 return hQuery.createCodedValue(this.json['ordinality']); +2159 }; +2160 +2161 return Procedure; +2162 +2163 })(hQuery.CodedEntry); +2164 /** +2165 @namespace scoping into the hquery namespace +2166 */ 2167 -2168 __extends(Result, _super); -2169 -2170 Result.name = 'Result'; -2171 -2172 function Result(json) { -2173 this.json = json; -2174 Result.__super__.constructor.call(this, this.json); -2175 } -2176 -2177 /** -2178 ASTM CCR defines a restricted set of required result Type codes (see ResultTypeCode in section 7.3 -2179 Summary of CCD value sets), used to categorize a result into one of several commonly accepted values -2180 (e.g. Hematology, Chemistry, Nuclear Medicine). -2181 @returns {CodedValue} -2182 */ +2168 var __hasProp = {}.hasOwnProperty, +2169 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; +2170 +2171 this.hQuery || (this.hQuery = {}); +2172 +2173 /** +2174 Observations generated by laboratories, imaging procedures, and other procedures. The scope +2175 includes hematology, chemistry, serology, virology, toxicology, microbiology, plain x-ray, +2176 ultrasound, CT, MRI, angiography, cardiac echo, nuclear medicine, pathology, and procedure +2177 observations. +2178 @class +2179 @augments hQuery.CodedEntry +2180 @exports Result as hQuery.Result +2181 */ +2182 2183 -2184 -2185 Result.prototype.resultType = function() { -2186 return this.type(); -2187 }; -2188 -2189 /** -2190 @returns {CodedValue} -2191 */ -2192 -2193 -2194 Result.prototype.interpretation = function() { -2195 return hQuery.createCodedValue(this.json['interpretation']); -2196 }; -2197 -2198 /** -2199 @returns {String} +2184 hQuery.Result = (function(_super) { +2185 +2186 __extends(Result, _super); +2187 +2188 Result.name = 'Result'; +2189 +2190 function Result(json) { +2191 this.json = json; +2192 Result.__super__.constructor.call(this, this.json); +2193 } +2194 +2195 /** +2196 ASTM CCR defines a restricted set of required result Type codes (see ResultTypeCode in section 7.3 +2197 Summary of CCD value sets), used to categorize a result into one of several commonly accepted values +2198 (e.g. Hematology, Chemistry, Nuclear Medicine). +2199 @returns {CodedValue} 2200 */ 2201 2202 -2203 Result.prototype.referenceRange = function() { -2204 return this.json['referenceRange']; +2203 Result.prototype.resultType = function() { +2204 return this.type(); 2205 }; 2206 2207 /** -2208 @returns {String} +2208 @returns {CodedValue} 2209 */ 2210 2211 -2212 Result.prototype.comment = function() { -2213 return this.json['comment']; +2212 Result.prototype.interpretation = function() { +2213 return hQuery.createCodedValue(this.json['interpretation']); 2214 }; 2215 -2216 return Result; -2217 -2218 })(hQuery.CodedEntry); -2219 /** -2220 @namespace scoping into the hquery namespace -2221 */ -2222 -2223 var __hasProp = {}.hasOwnProperty, -2224 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; -2225 -2226 this.hQuery || (this.hQuery = {}); -2227 -2228 /** -2229 NoImmunzation as defined by value set 2.16.840.1.113883.1.11.19717 -2230 The terms come from Health Level Seven (HL7) Version 3.0 Vocabulary and are managed by HL7 -2231 It indicates the reason an immunization was not administered. -2232 -2233 @class NoImmunization - describes the status of the medication -2234 @augments hQuery.CodedEntry -2235 @exports NoImmunization as hQuery.NoImmunization -2236 */ -2237 -2238 -2239 hQuery.NoImmunization = (function(_super) { -2240 var IMMUNITY, MED_PRECAUTION, OUT_OF_STOCK, PAT_OBJ, PHIL_OBJ, REL_OBJ, VAC_EFF, VAC_SAFETY; -2241 -2242 __extends(NoImmunization, _super); +2216 /** +2217 @returns {String} +2218 */ +2219 +2220 +2221 Result.prototype.referenceRange = function() { +2222 return this.json['referenceRange']; +2223 }; +2224 +2225 /** +2226 @returns {String} +2227 */ +2228 +2229 +2230 Result.prototype.comment = function() { +2231 return this.json['comment']; +2232 }; +2233 +2234 return Result; +2235 +2236 })(hQuery.CodedEntry); +2237 /** +2238 @namespace scoping into the hquery namespace +2239 */ +2240 +2241 var __hasProp = {}.hasOwnProperty, +2242 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; 2243 -2244 NoImmunization.name = 'NoImmunization'; +2244 this.hQuery || (this.hQuery = {}); 2245 -2246 function NoImmunization() { -2247 return NoImmunization.__super__.constructor.apply(this, arguments); -2248 } -2249 -2250 IMMUNITY = "IMMUNE"; -2251 -2252 MED_PRECAUTION = "MEDPREC"; -2253 -2254 OUT_OF_STOCK = "OSTOCK"; +2246 /** +2247 NoImmunzation as defined by value set 2.16.840.1.113883.1.11.19717 +2248 The terms come from Health Level Seven (HL7) Version 3.0 Vocabulary and are managed by HL7 +2249 It indicates the reason an immunization was not administered. +2250 +2251 @class NoImmunization - describes the status of the medication +2252 @augments hQuery.CodedEntry +2253 @exports NoImmunization as hQuery.NoImmunization +2254 */ 2255 -2256 PAT_OBJ = "PATOBJ"; -2257 -2258 PHIL_OBJ = "PHILISOP"; +2256 +2257 hQuery.NoImmunization = (function(_super) { +2258 var IMMUNITY, MED_PRECAUTION, OUT_OF_STOCK, PAT_OBJ, PHIL_OBJ, REL_OBJ, VAC_EFF, VAC_SAFETY; 2259 -2260 REL_OBJ = "RELIG"; +2260 __extends(NoImmunization, _super); 2261 -2262 VAC_EFF = "VACEFF"; +2262 NoImmunization.name = 'NoImmunization'; 2263 -2264 VAC_SAFETY = "VACSAF"; -2265 -2266 /** -2267 @returns {Boolean} -2268 */ +2264 function NoImmunization() { +2265 return NoImmunization.__super__.constructor.apply(this, arguments); +2266 } +2267 +2268 IMMUNITY = "IMMUNE"; 2269 -2270 -2271 NoImmunization.prototype.isImmune = function() { -2272 return this.c === IMMUNITY; -2273 }; -2274 -2275 /** -2276 @returns {Boolean} -2277 */ -2278 +2270 MED_PRECAUTION = "MEDPREC"; +2271 +2272 OUT_OF_STOCK = "OSTOCK"; +2273 +2274 PAT_OBJ = "PATOBJ"; +2275 +2276 PHIL_OBJ = "PHILISOP"; +2277 +2278 REL_OBJ = "RELIG"; 2279 -2280 NoImmunization.prototype.isMedPrec = function() { -2281 return this.c === MED_PRECAUTION; -2282 }; +2280 VAC_EFF = "VACEFF"; +2281 +2282 VAC_SAFETY = "VACSAF"; 2283 2284 /** 2285 @returns {Boolean} 2286 */ 2287 2288 -2289 NoImmunization.prototype.isOstock = function() { -2290 return this.c === OUT_OF_STOCK; +2289 NoImmunization.prototype.isImmune = function() { +2290 return this.c === IMMUNITY; 2291 }; 2292 2293 /** @@ -2302,8 +2302,8 @@ 2295 */ 2296 2297 -2298 NoImmunization.prototype.isPatObj = function() { -2299 return this.c === PAT_OBJ; +2298 NoImmunization.prototype.isMedPrec = function() { +2299 return this.c === MED_PRECAUTION; 2300 }; 2301 2302 /** @@ -2311,8 +2311,8 @@ 2304 */ 2305 2306 -2307 NoImmunization.prototype.isPhilisop = function() { -2308 return this.c === PHIL_OBJ; +2307 NoImmunization.prototype.isOstock = function() { +2308 return this.c === OUT_OF_STOCK; 2309 }; 2310 2311 /** @@ -2320,8 +2320,8 @@ 2313 */ 2314 2315 -2316 NoImmunization.prototype.isRelig = function() { -2317 return this.c === REL_OBJ; +2316 NoImmunization.prototype.isPatObj = function() { +2317 return this.c === PAT_OBJ; 2318 }; 2319 2320 /** @@ -2329,8 +2329,8 @@ 2322 */ 2323 2324 -2325 NoImmunization.prototype.isVacEff = function() { -2326 return this.c === VAC_EFF; +2325 NoImmunization.prototype.isPhilisop = function() { +2326 return this.c === PHIL_OBJ; 2327 }; 2328 2329 /** @@ -2338,281 +2338,281 @@ 2331 */ 2332 2333 -2334 NoImmunization.prototype.isVacSaf = function() { -2335 return this.c === VAC_SAFETY; +2334 NoImmunization.prototype.isRelig = function() { +2335 return this.c === REL_OBJ; 2336 }; 2337 -2338 return NoImmunization; -2339 -2340 })(hQuery.CodedValue); +2338 /** +2339 @returns {Boolean} +2340 */ 2341 -2342 /** -2343 @class represents a immunization entry for a patient. -2344 @augments hQuery.CodedEntry -2345 @exports Immunization as hQuery.Immunization -2346 */ -2347 -2348 -2349 hQuery.Immunization = (function(_super) { +2342 +2343 NoImmunization.prototype.isVacEff = function() { +2344 return this.c === VAC_EFF; +2345 }; +2346 +2347 /** +2348 @returns {Boolean} +2349 */ 2350 -2351 __extends(Immunization, _super); -2352 -2353 Immunization.name = 'Immunization'; -2354 -2355 function Immunization(json) { -2356 this.json = json; -2357 Immunization.__super__.constructor.call(this, this.json); -2358 } +2351 +2352 NoImmunization.prototype.isVacSaf = function() { +2353 return this.c === VAC_SAFETY; +2354 }; +2355 +2356 return NoImmunization; +2357 +2358 })(hQuery.CodedValue); 2359 -2360 /** -2361 @returns{hQuery.Scalar} -2362 */ -2363 -2364 -2365 Immunization.prototype.medicationSeriesNumber = function() { -2366 if (this.json['medicationSeriesNumber']) { -2367 return new hQuery.Scalar(this.json['medicationSeriesNumber']); -2368 } -2369 }; +2360 /** +2361 @class represents a immunization entry for a patient. +2362 @augments hQuery.CodedEntry +2363 @exports Immunization as hQuery.Immunization +2364 */ +2365 +2366 +2367 hQuery.Immunization = (function(_super) { +2368 +2369 __extends(Immunization, _super); 2370 -2371 /** -2372 @returns{hQuery.MedicationInformation} -2373 */ -2374 -2375 -2376 Immunization.prototype.medicationInformation = function() { -2377 return new hQuery.MedicationInformation(this.json); -2378 }; -2379 -2380 /** -2381 @returns{Date} Date immunization was administered -2382 */ -2383 -2384 -2385 Immunization.prototype.administeredDate = function() { -2386 return dateFromUtcSeconds(this.json['administeredDate']); +2371 Immunization.name = 'Immunization'; +2372 +2373 function Immunization(json) { +2374 this.json = json; +2375 Immunization.__super__.constructor.call(this, this.json); +2376 } +2377 +2378 /** +2379 @returns{hQuery.Scalar} +2380 */ +2381 +2382 +2383 Immunization.prototype.medicationSeriesNumber = function() { +2384 if (this.json['medicationSeriesNumber']) { +2385 return new hQuery.Scalar(this.json['medicationSeriesNumber']); +2386 } 2387 }; 2388 2389 /** -2390 @returns{hQuery.Actor} Performer of immunization +2390 @returns{hQuery.MedicationInformation} 2391 */ 2392 2393 -2394 Immunization.prototype.performer = function() { -2395 if (this.json['performer']) { -2396 return new hQuery.Actor(this.json['performer']); -2397 } -2398 }; -2399 -2400 /** -2401 @returns {comment} human readable description of event -2402 */ -2403 -2404 -2405 Immunization.prototype.comment = function() { -2406 return this.json['comment']; -2407 }; -2408 -2409 /** -2410 @returns {Boolean} whether the immunization has been refused by the patient. -2411 */ -2412 -2413 -2414 Immunization.prototype.refusalInd = function() { -2415 return this.json['negationInd']; +2394 Immunization.prototype.medicationInformation = function() { +2395 return new hQuery.MedicationInformation(this.json); +2396 }; +2397 +2398 /** +2399 @returns{Date} Date immunization was administered +2400 */ +2401 +2402 +2403 Immunization.prototype.administeredDate = function() { +2404 return dateFromUtcSeconds(this.json['administeredDate']); +2405 }; +2406 +2407 /** +2408 @returns{hQuery.Actor} Performer of immunization +2409 */ +2410 +2411 +2412 Immunization.prototype.performer = function() { +2413 if (this.json['performer']) { +2414 return new hQuery.Actor(this.json['performer']); +2415 } 2416 }; 2417 2418 /** -2419 NoImmunzation as defined by value set 2.16.840.1.113883.1.11.19717 -2420 The terms come from Health Level Seven (HL7) Version 3.0 Vocabulary and are managed by HL7 -2421 It indicates the reason an immunization was not administered. -2422 @returns {hQuery.NoImmunization} Used to indicate reason an immunization was not administered. -2423 */ -2424 -2425 -2426 Immunization.prototype.refusalReason = function() { -2427 var _ref, _ref1; -2428 return new hQuery.NoImmunization((_ref = this.json['negationReason']) != null ? _ref['code'] : void 0, (_ref1 = this.json['negationReason']) != null ? _ref1['codeSystem'] : void 0); -2429 }; +2419 @returns {comment} human readable description of event +2420 */ +2421 +2422 +2423 Immunization.prototype.comment = function() { +2424 return this.json['comment']; +2425 }; +2426 +2427 /** +2428 @returns {Boolean} whether the immunization has been refused by the patient. +2429 */ 2430 -2431 return Immunization; -2432 -2433 })(hQuery.CodedEntry); -2434 /** -2435 @namespace scoping into the hquery namespace -2436 */ -2437 -2438 var __hasProp = {}.hasOwnProperty, -2439 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; -2440 -2441 this.hQuery || (this.hQuery = {}); +2431 +2432 Immunization.prototype.refusalInd = function() { +2433 return this.json['negationInd']; +2434 }; +2435 +2436 /** +2437 NoImmunzation as defined by value set 2.16.840.1.113883.1.11.19717 +2438 The terms come from Health Level Seven (HL7) Version 3.0 Vocabulary and are managed by HL7 +2439 It indicates the reason an immunization was not administered. +2440 @returns {hQuery.NoImmunization} Used to indicate reason an immunization was not administered. +2441 */ 2442 -2443 /** -2444 @class -2445 @augments hQuery.CodedEntry -2446 @exports Allergy as hQuery.Allergy -2447 */ +2443 +2444 Immunization.prototype.refusalReason = function() { +2445 var _ref, _ref1; +2446 return new hQuery.NoImmunization((_ref = this.json['negationReason']) != null ? _ref['code'] : void 0, (_ref1 = this.json['negationReason']) != null ? _ref1['codeSystem'] : void 0); +2447 }; 2448 -2449 -2450 hQuery.Allergy = (function(_super) { -2451 -2452 __extends(Allergy, _super); -2453 -2454 Allergy.name = 'Allergy'; +2449 return Immunization; +2450 +2451 })(hQuery.CodedEntry); +2452 /** +2453 @namespace scoping into the hquery namespace +2454 */ 2455 -2456 function Allergy(json) { -2457 this.json = json; -2458 Allergy.__super__.constructor.call(this, this.json); -2459 } +2456 var __hasProp = {}.hasOwnProperty, +2457 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; +2458 +2459 this.hQuery || (this.hQuery = {}); 2460 -2461 /** -2462 Food and substance allergies use the Unique Ingredient Identifier(UNII) from the FDA -2463 http://www.fda.gov/ForIndustry/DataStandards/StructuredProductLabeling/ucm162523.htm -2464 -2465 Allegies to a class of medication Shall contain a value descending from the NDF-RT concept types -2466 of Mechanism of Action - N0000000223, Physiologic Effect - N0000009802 or -2467 Chemical Structure - N0000000002. NUI will be used as the concept code. -2468 For more information, please see the Web Site -2469 http://www.cancer.gov/cancertopics/terminologyresources/page5 -2470 -2471 Allergies to a specific medication shall use RxNorm for the values. -2472 @returns {CodedValue} -2473 */ -2474 -2475 -2476 Allergy.prototype.product = function() { -2477 return this.type(); -2478 }; -2479 -2480 /** -2481 Date of allergy or adverse event -2482 @returns{Date} -2483 */ -2484 -2485 -2486 Allergy.prototype.adverseEventDate = function() { -2487 return dateFromUtcSeconds(this.json['adverseEventDate']); -2488 }; -2489 -2490 /** -2491 Adverse event types SHALL be coded as specified in HITSP/C80 Section 2.2.3.4.2 Allergy/Adverse Event Type -2492 @returns {CodedValue} -2493 */ -2494 -2495 -2496 Allergy.prototype.adverseEventType = function() { -2497 return hQuery.createCodedValue(this.json['type']); -2498 }; -2499 -2500 /** -2501 This indicates the reaction that may be caused by the product or agent. -2502 It is defined by 2.16.840.1.113883.3.88.12.3221.6.2 and are SNOMED-CT codes. -2503 420134006 Propensity to adverse reactions (disorder) -2504 418038007 Propensity to adverse reactions to substance (disorder) -2505 419511003 Propensity to adverse reactions to drug (disorder) -2506 418471000 Propensity to adverse reactions to food (disorder) -2507 419199007 Allergy to substance (disorder) -2508 416098002 Drug allergy (disorder) -2509 414285001 Food allergy (disorder) -2510 59037007 Drug intolerance (disorder) -2511 235719002 Food intolerance (disorder) -2512 @returns {CodedValue} -2513 */ -2514 -2515 -2516 Allergy.prototype.reaction = function() { -2517 return hQuery.createCodedValue(this.json['reaction']); -2518 }; -2519 -2520 /** -2521 This is a description of the level of the severity of the allergy or intolerance. -2522 Use SNOMED-CT Codes as defined by 2.16.840.1.113883.3.88.12.3221.6.8 -2523 255604002 Mild -2524 371923003 Mild to Moderate -2525 6736007 Moderate -2526 371924009 Moderate to Severe -2527 24484000 Severe -2528 399166001 Fatal -2529 @returns {CodedValue} -2530 */ -2531 +2461 /** +2462 @class +2463 @augments hQuery.CodedEntry +2464 @exports Allergy as hQuery.Allergy +2465 */ +2466 +2467 +2468 hQuery.Allergy = (function(_super) { +2469 +2470 __extends(Allergy, _super); +2471 +2472 Allergy.name = 'Allergy'; +2473 +2474 function Allergy(json) { +2475 this.json = json; +2476 Allergy.__super__.constructor.call(this, this.json); +2477 } +2478 +2479 /** +2480 Food and substance allergies use the Unique Ingredient Identifier(UNII) from the FDA +2481 http://www.fda.gov/ForIndustry/DataStandards/StructuredProductLabeling/ucm162523.htm +2482 +2483 Allegies to a class of medication Shall contain a value descending from the NDF-RT concept types +2484 of Mechanism of Action - N0000000223, Physiologic Effect - N0000009802 or +2485 Chemical Structure - N0000000002. NUI will be used as the concept code. +2486 For more information, please see the Web Site +2487 http://www.cancer.gov/cancertopics/terminologyresources/page5 +2488 +2489 Allergies to a specific medication shall use RxNorm for the values. +2490 @returns {CodedValue} +2491 */ +2492 +2493 +2494 Allergy.prototype.product = function() { +2495 return this.type(); +2496 }; +2497 +2498 /** +2499 Date of allergy or adverse event +2500 @returns{Date} +2501 */ +2502 +2503 +2504 Allergy.prototype.adverseEventDate = function() { +2505 return dateFromUtcSeconds(this.json['adverseEventDate']); +2506 }; +2507 +2508 /** +2509 Adverse event types SHALL be coded as specified in HITSP/C80 Section 2.2.3.4.2 Allergy/Adverse Event Type +2510 @returns {CodedValue} +2511 */ +2512 +2513 +2514 Allergy.prototype.adverseEventType = function() { +2515 return hQuery.createCodedValue(this.json['type']); +2516 }; +2517 +2518 /** +2519 This indicates the reaction that may be caused by the product or agent. +2520 It is defined by 2.16.840.1.113883.3.88.12.3221.6.2 and are SNOMED-CT codes. +2521 420134006 Propensity to adverse reactions (disorder) +2522 418038007 Propensity to adverse reactions to substance (disorder) +2523 419511003 Propensity to adverse reactions to drug (disorder) +2524 418471000 Propensity to adverse reactions to food (disorder) +2525 419199007 Allergy to substance (disorder) +2526 416098002 Drug allergy (disorder) +2527 414285001 Food allergy (disorder) +2528 59037007 Drug intolerance (disorder) +2529 235719002 Food intolerance (disorder) +2530 @returns {CodedValue} +2531 */ 2532 -2533 Allergy.prototype.severity = function() { -2534 return hQuery.createCodedValue(this.json['severity']); -2535 }; -2536 -2537 /** -2538 Additional comment or textual information -2539 @returns {String} -2540 */ -2541 -2542 -2543 Allergy.prototype.comment = function() { -2544 return this.json['comment']; -2545 }; -2546 -2547 return Allergy; -2548 -2549 })(hQuery.CodedEntry); -2550 /** -2551 @namespace scoping into the hquery namespace -2552 */ -2553 -2554 this.hQuery || (this.hQuery = {}); -2555 -2556 /** -2557 @class -2558 -2559 @exports Provider as hQuery.Provider -2560 */ -2561 -2562 -2563 hQuery.Provider = (function() { +2533 +2534 Allergy.prototype.reaction = function() { +2535 return hQuery.createCodedValue(this.json['reaction']); +2536 }; +2537 +2538 /** +2539 This is a description of the level of the severity of the allergy or intolerance. +2540 Use SNOMED-CT Codes as defined by 2.16.840.1.113883.3.88.12.3221.6.8 +2541 255604002 Mild +2542 371923003 Mild to Moderate +2543 6736007 Moderate +2544 371924009 Moderate to Severe +2545 24484000 Severe +2546 399166001 Fatal +2547 @returns {CodedValue} +2548 */ +2549 +2550 +2551 Allergy.prototype.severity = function() { +2552 return hQuery.createCodedValue(this.json['severity']); +2553 }; +2554 +2555 /** +2556 Additional comment or textual information +2557 @returns {String} +2558 */ +2559 +2560 +2561 Allergy.prototype.comment = function() { +2562 return this.json['comment']; +2563 }; 2564 -2565 Provider.name = 'Provider'; +2565 return Allergy; 2566 -2567 function Provider(json) { -2568 this.json = json; -2569 } -2570 -2571 /** -2572 @returns {hQuery.Person} -2573 */ -2574 -2575 -2576 Provider.prototype.providerEntity = function() { -2577 if (this.json['providerEntity']) { -2578 return new hQuery.Person(this.json['providerEntity']); -2579 } -2580 }; -2581 -2582 /** -2583 @returns {hQuery.DateRange} -2584 */ -2585 -2586 -2587 Provider.prototype.careProvisionDateRange = function() { -2588 if (this.json['careProvisionDateRange']) { -2589 return new hQuery.DateRange(this.json['careProvisionDateRange']); -2590 } -2591 }; +2567 })(hQuery.CodedEntry); +2568 /** +2569 @namespace scoping into the hquery namespace +2570 */ +2571 +2572 this.hQuery || (this.hQuery = {}); +2573 +2574 /** +2575 @class +2576 +2577 @exports Provider as hQuery.Provider +2578 */ +2579 +2580 +2581 hQuery.Provider = (function() { +2582 +2583 Provider.name = 'Provider'; +2584 +2585 function Provider(json) { +2586 this.json = json; +2587 } +2588 +2589 /** +2590 @returns {hQuery.Person} +2591 */ 2592 -2593 /** -2594 @returns {hQuery.CodedValue} -2595 */ -2596 -2597 -2598 Provider.prototype.role = function() { -2599 return hQuery.createCodedValue(this.json['role']); -2600 }; -2601 -2602 /** -2603 @returns {String} -2604 */ -2605 -2606 -2607 Provider.prototype.patientID = function() { -2608 return this.json['patientID']; +2593 +2594 Provider.prototype.providerEntity = function() { +2595 if (this.json['providerEntity']) { +2596 return new hQuery.Person(this.json['providerEntity']); +2597 } +2598 }; +2599 +2600 /** +2601 @returns {hQuery.DateRange} +2602 */ +2603 +2604 +2605 Provider.prototype.careProvisionDateRange = function() { +2606 if (this.json['careProvisionDateRange']) { +2607 return new hQuery.DateRange(this.json['careProvisionDateRange']); +2608 } 2609 }; 2610 2611 /** @@ -2620,8 +2620,8 @@ 2613 */ 2614 2615 -2616 Provider.prototype.providerType = function() { -2617 return hQuery.createCodedValue(this.json['providerType']); +2616 Provider.prototype.role = function() { +2617 return hQuery.createCodedValue(this.json['role']); 2618 }; 2619 2620 /** @@ -2629,372 +2629,372 @@ 2622 */ 2623 2624 -2625 Provider.prototype.providerID = function() { -2626 return this.json['providerID']; +2625 Provider.prototype.patientID = function() { +2626 return this.json['patientID']; 2627 }; 2628 2629 /** -2630 @returns {hQuery.Organization} +2630 @returns {hQuery.CodedValue} 2631 */ 2632 2633 -2634 Provider.prototype.organizationName = function() { -2635 return new hQuery.Organization(this.json); +2634 Provider.prototype.providerType = function() { +2635 return hQuery.createCodedValue(this.json['providerType']); 2636 }; 2637 -2638 return Provider; -2639 -2640 })(); -2641 /** -2642 @namespace scoping into the hquery namespace -2643 */ -2644 -2645 var __hasProp = {}.hasOwnProperty, -2646 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; -2647 -2648 this.hQuery || (this.hQuery = {}); -2649 -2650 /** -2651 @class -2652 @augments hQuery.CodedEntry -2653 @exports Language as hQuery.Language -2654 */ +2638 /** +2639 @returns {String} +2640 */ +2641 +2642 +2643 Provider.prototype.providerID = function() { +2644 return this.json['providerID']; +2645 }; +2646 +2647 /** +2648 @returns {hQuery.Organization} +2649 */ +2650 +2651 +2652 Provider.prototype.organizationName = function() { +2653 return new hQuery.Organization(this.json); +2654 }; 2655 -2656 -2657 hQuery.Language = (function(_super) { -2658 -2659 __extends(Language, _super); -2660 -2661 Language.name = 'Language'; +2656 return Provider; +2657 +2658 })(); +2659 /** +2660 @namespace scoping into the hquery namespace +2661 */ 2662 -2663 function Language(json) { -2664 this.json = json; -2665 Language.__super__.constructor.call(this, this.json); -2666 } +2663 var __hasProp = {}.hasOwnProperty, +2664 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; +2665 +2666 this.hQuery || (this.hQuery = {}); 2667 -2668 /** -2669 @returns {hQuery.CodedValue} -2670 */ -2671 -2672 -2673 Language.prototype.modeCode = function() { -2674 return hQuery.createCodedValue(this.json['modeCode']); -2675 }; +2668 /** +2669 @class +2670 @augments hQuery.CodedEntry +2671 @exports Language as hQuery.Language +2672 */ +2673 +2674 +2675 hQuery.Language = (function(_super) { 2676 -2677 /** -2678 @returns {String} -2679 */ +2677 __extends(Language, _super); +2678 +2679 Language.name = 'Language'; 2680 -2681 -2682 Language.prototype.preferenceIndicator = function() { -2683 return this.json['preferenceIndicator']; -2684 }; +2681 function Language(json) { +2682 this.json = json; +2683 Language.__super__.constructor.call(this, this.json); +2684 } 2685 -2686 return Language; -2687 -2688 })(hQuery.CodedEntry); -2689 /** -2690 @namespace scoping into the hquery namespace -2691 */ -2692 -2693 var __hasProp = {}.hasOwnProperty, -2694 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; -2695 -2696 this.hQuery || (this.hQuery = {}); -2697 -2698 /** -2699 This includes information about the patients current and past pregnancy status -2700 The Coded Entry code system should be SNOMED-CT -2701 @class -2702 @augments hQuery.CodedEntry -2703 @exports Pregnancy as hQuery.Pregnancy -2704 */ +2686 /** +2687 @returns {hQuery.CodedValue} +2688 */ +2689 +2690 +2691 Language.prototype.modeCode = function() { +2692 return hQuery.createCodedValue(this.json['modeCode']); +2693 }; +2694 +2695 /** +2696 @returns {String} +2697 */ +2698 +2699 +2700 Language.prototype.preferenceIndicator = function() { +2701 return this.json['preferenceIndicator']; +2702 }; +2703 +2704 return Language; 2705 -2706 -2707 hQuery.Pregnancy = (function(_super) { -2708 -2709 __extends(Pregnancy, _super); +2706 })(hQuery.CodedEntry); +2707 /** +2708 @namespace scoping into the hquery namespace +2709 */ 2710 -2711 Pregnancy.name = 'Pregnancy'; -2712 -2713 function Pregnancy(json) { -2714 this.json = json; -2715 Pregnancy.__super__.constructor.call(this, this.json); -2716 } -2717 -2718 /** -2719 @returns {String} -2720 */ -2721 -2722 -2723 Pregnancy.prototype.comment = function() { -2724 return this.json['comment']; -2725 }; +2711 var __hasProp = {}.hasOwnProperty, +2712 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; +2713 +2714 this.hQuery || (this.hQuery = {}); +2715 +2716 /** +2717 This includes information about the patients current and past pregnancy status +2718 The Coded Entry code system should be SNOMED-CT +2719 @class +2720 @augments hQuery.CodedEntry +2721 @exports Pregnancy as hQuery.Pregnancy +2722 */ +2723 +2724 +2725 hQuery.Pregnancy = (function(_super) { 2726 -2727 return Pregnancy; +2727 __extends(Pregnancy, _super); 2728 -2729 })(hQuery.CodedEntry); -2730 /** -2731 @namespace scoping into the hquery namespace -2732 */ -2733 -2734 var __hasProp = {}.hasOwnProperty, -2735 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; -2736 -2737 this.hQuery || (this.hQuery = {}); -2738 -2739 /** +2729 Pregnancy.name = 'Pregnancy'; +2730 +2731 function Pregnancy(json) { +2732 this.json = json; +2733 Pregnancy.__super__.constructor.call(this, this.json); +2734 } +2735 +2736 /** +2737 @returns {String} +2738 */ +2739 2740 -2741 The Social History Observation is used to define the patient's occupational, personal (e.g. lifestyle), -2742 social, and environmental history and health risk factors, as well as administrative data such as -2743 marital status, race, ethnicity and religious affiliation. The types of conditions -2744 described have been constrained to the SNOMED CT code system using constrained code set, 2.16.840.1.113883.3.88.12.80.60: -2745 229819007 Tobacco use and exposure -2746 256235009 Exercise -2747 160573003 Alcohol Intake -2748 364393001 Nutritional observable -2749 364703007 Employment detail -2750 425400000 Toxic exposure status -2751 363908000 Details of drug misuse behavior -2752 228272008 Health-related behavior -2753 105421008 Educational achievement +2741 Pregnancy.prototype.comment = function() { +2742 return this.json['comment']; +2743 }; +2744 +2745 return Pregnancy; +2746 +2747 })(hQuery.CodedEntry); +2748 /** +2749 @namespace scoping into the hquery namespace +2750 */ +2751 +2752 var __hasProp = {}.hasOwnProperty, +2753 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; 2754 -2755 note: Social History is not part of the existing green c32. -2756 @exports Socialhistory as hQuery.Socialhistory -2757 @augments hQuery.CodedEntry -2758 */ -2759 -2760 -2761 hQuery.Socialhistory = (function(_super) { -2762 -2763 __extends(Socialhistory, _super); -2764 -2765 Socialhistory.name = 'Socialhistory'; -2766 -2767 function Socialhistory(json) { -2768 this.json = json; -2769 Socialhistory.__super__.constructor.call(this, this.json); -2770 } -2771 -2772 /** -2773 Value returns the value of the result. This will return an object. The properties of this -2774 object are dependent on the type of result. -2775 */ -2776 +2755 this.hQuery || (this.hQuery = {}); +2756 +2757 /** +2758 +2759 The Social History Observation is used to define the patient's occupational, personal (e.g. lifestyle), +2760 social, and environmental history and health risk factors, as well as administrative data such as +2761 marital status, race, ethnicity and religious affiliation. The types of conditions +2762 described have been constrained to the SNOMED CT code system using constrained code set, 2.16.840.1.113883.3.88.12.80.60: +2763 229819007 Tobacco use and exposure +2764 256235009 Exercise +2765 160573003 Alcohol Intake +2766 364393001 Nutritional observable +2767 364703007 Employment detail +2768 425400000 Toxic exposure status +2769 363908000 Details of drug misuse behavior +2770 228272008 Health-related behavior +2771 105421008 Educational achievement +2772 +2773 note: Social History is not part of the existing green c32. +2774 @exports Socialhistory as hQuery.Socialhistory +2775 @augments hQuery.CodedEntry +2776 */ 2777 -2778 Socialhistory.prototype.value = function() { -2779 return this.json['value']; -2780 }; -2781 -2782 return Socialhistory; -2783 -2784 })(hQuery.CodedEntry); -2785 /** -2786 @namespace scoping into the hquery namespace -2787 */ -2788 -2789 var __hasProp = {}.hasOwnProperty, -2790 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; -2791 -2792 this.hQuery || (this.hQuery = {}); -2793 -2794 /** +2778 +2779 hQuery.Socialhistory = (function(_super) { +2780 +2781 __extends(Socialhistory, _super); +2782 +2783 Socialhistory.name = 'Socialhistory'; +2784 +2785 function Socialhistory(json) { +2786 this.json = json; +2787 Socialhistory.__super__.constructor.call(this, this.json); +2788 } +2789 +2790 /** +2791 Value returns the value of the result. This will return an object. The properties of this +2792 object are dependent on the type of result. +2793 */ +2794 2795 -2796 The plan of care contains data defining prospective or intended orders, interventions, encounters, services, and procedures for the patient. -2797 -2798 @exports CareGoal as hQuery.CareGoal -2799 @augments hQuery.CodedEntry -2800 */ +2796 Socialhistory.prototype.value = function() { +2797 return this.json['value']; +2798 }; +2799 +2800 return Socialhistory; 2801 -2802 -2803 hQuery.CareGoal = (function(_super) { -2804 -2805 __extends(CareGoal, _super); +2802 })(hQuery.CodedEntry); +2803 /** +2804 @namespace scoping into the hquery namespace +2805 */ 2806 -2807 CareGoal.name = 'CareGoal'; -2808 -2809 function CareGoal(json) { -2810 this.json = json; -2811 CareGoal.__super__.constructor.call(this, this.json); -2812 } +2807 var __hasProp = {}.hasOwnProperty, +2808 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; +2809 +2810 this.hQuery || (this.hQuery = {}); +2811 +2812 /** 2813 -2814 return CareGoal; +2814 The plan of care contains data defining prospective or intended orders, interventions, encounters, services, and procedures for the patient. 2815 -2816 })(hQuery.CodedEntry); -2817 /** -2818 @namespace scoping into the hquery namespace -2819 */ +2816 @exports CareGoal as hQuery.CareGoal +2817 @augments hQuery.CodedEntry +2818 */ +2819 2820 -2821 var __hasProp = {}.hasOwnProperty, -2822 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; -2823 -2824 this.hQuery || (this.hQuery = {}); -2825 -2826 /** -2827 -2828 The Medical Equipment section contains information describing a patients implanted and external medical devices and equipment that their health status depends on, as well as any pertinent equipment or device history. -2829 -2830 The template identifier for this section is 2.16.840.1.113883.3.88.11.83.128 +2821 hQuery.CareGoal = (function(_super) { +2822 +2823 __extends(CareGoal, _super); +2824 +2825 CareGoal.name = 'CareGoal'; +2826 +2827 function CareGoal(json) { +2828 this.json = json; +2829 CareGoal.__super__.constructor.call(this, this.json); +2830 } 2831 -2832 C83-[CT-128-1] This section shall conform to the HL7 CCD section, and shall contain a templateId element whose root attribute is 2.16.840.1.113883.10.20.1.7. -2833 C83-[CT-128-2] This section SHALL conform to the IHE Medical Devices Section, and shall contain a templateId element whose root attribute is 1.3.6.1.4.1.19376.1.5.3.1.1.5.3.5 -2834 -2835 @exports MedicalEquipment as hQuery.MedicalEquipment -2836 @augments hQuery.CodedEntry +2832 return CareGoal; +2833 +2834 })(hQuery.CodedEntry); +2835 /** +2836 @namespace scoping into the hquery namespace 2837 */ 2838 -2839 -2840 hQuery.MedicalEquipment = (function(_super) { +2839 var __hasProp = {}.hasOwnProperty, +2840 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; 2841 -2842 __extends(MedicalEquipment, _super); +2842 this.hQuery || (this.hQuery = {}); 2843 -2844 MedicalEquipment.name = 'MedicalEquipment'; +2844 /** 2845 -2846 function MedicalEquipment(json) { -2847 this.json = json; -2848 MedicalEquipment.__super__.constructor.call(this, this.json); -2849 } -2850 -2851 /** -2852 @returns {CodedValue} -2853 */ -2854 -2855 -2856 MedicalEquipment.prototype.anatomicalStructure = function() { -2857 return hQuery.createCodedValue(this.json['anatomicalStructure']); -2858 }; +2846 The Medical Equipment section contains information describing a patients implanted and external medical devices and equipment that their health status depends on, as well as any pertinent equipment or device history. +2847 +2848 The template identifier for this section is 2.16.840.1.113883.3.88.11.83.128 +2849 +2850 C83-[CT-128-1] This section shall conform to the HL7 CCD section, and shall contain a templateId element whose root attribute is 2.16.840.1.113883.10.20.1.7. +2851 C83-[CT-128-2] This section SHALL conform to the IHE Medical Devices Section, and shall contain a templateId element whose root attribute is 1.3.6.1.4.1.19376.1.5.3.1.1.5.3.5 +2852 +2853 @exports MedicalEquipment as hQuery.MedicalEquipment +2854 @augments hQuery.CodedEntry +2855 */ +2856 +2857 +2858 hQuery.MedicalEquipment = (function(_super) { 2859 -2860 /** -2861 @returns {Date} The actual or intended removal time of the device. -2862 */ +2860 __extends(MedicalEquipment, _super); +2861 +2862 MedicalEquipment.name = 'MedicalEquipment'; 2863 -2864 -2865 MedicalEquipment.prototype.removalTime = function() { -2866 if (this.json['removalTime']) { -2867 return hQuery.dateFromUtcSeconds(this.json['removalTime']); -2868 } -2869 }; -2870 -2871 return MedicalEquipment; +2864 function MedicalEquipment(json) { +2865 this.json = json; +2866 MedicalEquipment.__super__.constructor.call(this, this.json); +2867 } +2868 +2869 /** +2870 @returns {CodedValue} +2871 */ 2872 -2873 })(hQuery.CodedEntry); -2874 /** -2875 @namespace scoping into the hquery namespace -2876 */ +2873 +2874 MedicalEquipment.prototype.anatomicalStructure = function() { +2875 return hQuery.createCodedValue(this.json['anatomicalStructure']); +2876 }; 2877 -2878 var __hasProp = {}.hasOwnProperty, -2879 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; -2880 -2881 this.hQuery || (this.hQuery = {}); +2878 /** +2879 @returns {Date} The actual or intended removal time of the device. +2880 */ +2881 2882 -2883 /** -2884 This class can be used to represnt a functional status for a patient. Currently, -2885 it is not a very close representation of functional status as it is represented -2886 in the HL7 CCD, HITSP C32 or Consolidated CDA. -2887 -2888 In the previously mentioned specifications, functional status may represented -2889 using either a condition or result. Having "mixed" types of entries in a section -2890 is currently not well supported in the existing Record class -2891 -2892 Additionally, there is a mismatch between the data needed to calculate Stage 2 -2893 Meaningful Use Quailty Measures and the data contained in patient summary -2894 standards. The CQMs are checking to see if a functional status represented by -2895 a result was patient supplied. Right now, results do not have a source, and -2896 even if we were to use Provider as a source, it would need to be extended -2897 to support patients. +2883 MedicalEquipment.prototype.removalTime = function() { +2884 if (this.json['removalTime']) { +2885 return hQuery.dateFromUtcSeconds(this.json['removalTime']); +2886 } +2887 }; +2888 +2889 return MedicalEquipment; +2890 +2891 })(hQuery.CodedEntry); +2892 /** +2893 @namespace scoping into the hquery namespace +2894 */ +2895 +2896 var __hasProp = {}.hasOwnProperty, +2897 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; 2898 -2899 To avoid this, the patient sumamry style functional status has been "flattened" -2900 into this class. This model supports the information needed to calculate -2901 Stage 2 MU CQMs. If importers are created from C32 or CCDA, the information -2902 can be stored here, but it will be a lossy transformation. -2903 @class -2904 @augments hQuery.CodedEntry -2905 @exports FunctionalStatus as hQuery.FunctionalStatus -2906 */ -2907 -2908 -2909 hQuery.FunctionalStatus = (function(_super) { -2910 -2911 __extends(FunctionalStatus, _super); -2912 -2913 FunctionalStatus.name = 'FunctionalStatus'; -2914 -2915 function FunctionalStatus(json) { -2916 this.json = json; -2917 FunctionalStatus.__super__.constructor.call(this, this.json); -2918 } -2919 -2920 /** -2921 Either "condition" or "result" -2922 @returns {String} -2923 */ -2924 +2899 this.hQuery || (this.hQuery = {}); +2900 +2901 /** +2902 This class can be used to represnt a functional status for a patient. Currently, +2903 it is not a very close representation of functional status as it is represented +2904 in the HL7 CCD, HITSP C32 or Consolidated CDA. +2905 +2906 In the previously mentioned specifications, functional status may represented +2907 using either a condition or result. Having "mixed" types of entries in a section +2908 is currently not well supported in the existing Record class +2909 +2910 Additionally, there is a mismatch between the data needed to calculate Stage 2 +2911 Meaningful Use Quailty Measures and the data contained in patient summary +2912 standards. The CQMs are checking to see if a functional status represented by +2913 a result was patient supplied. Right now, results do not have a source, and +2914 even if we were to use Provider as a source, it would need to be extended +2915 to support patients. +2916 +2917 To avoid this, the patient sumamry style functional status has been "flattened" +2918 into this class. This model supports the information needed to calculate +2919 Stage 2 MU CQMs. If importers are created from C32 or CCDA, the information +2920 can be stored here, but it will be a lossy transformation. +2921 @class +2922 @augments hQuery.CodedEntry +2923 @exports FunctionalStatus as hQuery.FunctionalStatus +2924 */ 2925 -2926 FunctionalStatus.prototype.type = function() { -2927 return this.json["type"]; -2928 }; -2929 -2930 /** -2931 A coded value. Like a code for patient supplied. -2932 @returns {hQuery.CodedValue} -2933 */ -2934 -2935 -2936 FunctionalStatus.prototype.source = function() { -2937 return hQuery.createCodedValue(this.json["source"]); -2938 }; -2939 -2940 return FunctionalStatus; -2941 -2942 })(hQuery.CodedEntry); -2943 /** -2944 @namespace scoping into the hquery namespace -2945 */ -2946 -2947 var __hasProp = {}.hasOwnProperty, -2948 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; -2949 -2950 this.hQuery || (this.hQuery = {}); -2951 -2952 /** -2953 @class Supports -2954 @exports Supports as hQuery.Supports -2955 */ -2956 +2926 +2927 hQuery.FunctionalStatus = (function(_super) { +2928 +2929 __extends(FunctionalStatus, _super); +2930 +2931 FunctionalStatus.name = 'FunctionalStatus'; +2932 +2933 function FunctionalStatus(json) { +2934 this.json = json; +2935 FunctionalStatus.__super__.constructor.call(this, this.json); +2936 } +2937 +2938 /** +2939 Either "condition" or "result" +2940 @returns {String} +2941 */ +2942 +2943 +2944 FunctionalStatus.prototype.type = function() { +2945 return this.json["type"]; +2946 }; +2947 +2948 /** +2949 A coded value. Like a code for patient supplied. +2950 @returns {hQuery.CodedValue} +2951 */ +2952 +2953 +2954 FunctionalStatus.prototype.source = function() { +2955 return hQuery.createCodedValue(this.json["source"]); +2956 }; 2957 -2958 hQuery.Supports = (function() { +2958 return FunctionalStatus; 2959 -2960 Supports.name = 'Supports'; -2961 -2962 function Supports(json) { -2963 this.json = json; -2964 } -2965 -2966 /** -2967 @returns {DateRange} -2968 */ +2960 })(hQuery.CodedEntry); +2961 /** +2962 @namespace scoping into the hquery namespace +2963 */ +2964 +2965 var __hasProp = {}.hasOwnProperty, +2966 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; +2967 +2968 this.hQuery || (this.hQuery = {}); 2969 -2970 -2971 Supports.prototype.supportDate = function() { -2972 return new hQuery.DateRange(this.json['supportDate']); -2973 }; +2970 /** +2971 @class Supports +2972 @exports Supports as hQuery.Supports +2973 */ 2974 -2975 /** -2976 @returns {Person} -2977 */ -2978 +2975 +2976 hQuery.Supports = (function() { +2977 +2978 Supports.name = 'Supports'; 2979 -2980 Supports.prototype.guardian = function() { -2981 return new hQuery.Person(this.json['guardian']); -2982 }; +2980 function Supports(json) { +2981 this.json = json; +2982 } 2983 2984 /** -2985 @returns {String} +2985 @returns {DateRange} 2986 */ 2987 2988 -2989 Supports.prototype.guardianSupportType = function() { -2990 return this.json['guardianSupportType']; +2989 Supports.prototype.supportDate = function() { +2990 return new hQuery.DateRange(this.json['supportDate']); 2991 }; 2992 2993 /** @@ -3002,8 +3002,8 @@ 2995 */ 2996 2997 -2998 Supports.prototype.contact = function() { -2999 return new hQuery.Person(this.json['contact']); +2998 Supports.prototype.guardian = function() { +2999 return new hQuery.Person(this.json['guardian']); 3000 }; 3001 3002 /** @@ -3011,444 +3011,464 @@ 3004 */ 3005 3006 -3007 Supports.prototype.contactSupportType = function() { +3007 Supports.prototype.guardianSupportType = function() { 3008 return this.json['guardianSupportType']; 3009 }; 3010 -3011 return Supports; -3012 -3013 })(); +3011 /** +3012 @returns {Person} +3013 */ 3014 -3015 /** -3016 @class Representation of a patient -3017 @augments hQuery.Person -3018 @exports Patient as hQuery.Patient -3019 */ -3020 -3021 -3022 hQuery.Patient = (function(_super) { +3015 +3016 Supports.prototype.contact = function() { +3017 return new hQuery.Person(this.json['contact']); +3018 }; +3019 +3020 /** +3021 @returns {String} +3022 */ 3023 -3024 __extends(Patient, _super); -3025 -3026 Patient.name = 'Patient'; -3027 -3028 function Patient() { -3029 return Patient.__super__.constructor.apply(this, arguments); -3030 } -3031 -3032 /** -3033 @returns {String} containing M or F representing the gender of the patient -3034 */ -3035 -3036 -3037 Patient.prototype.gender = function() { -3038 return this.json['gender']; -3039 }; -3040 -3041 /** -3042 @returns {Date} containing the patients birthdate -3043 */ -3044 +3024 +3025 Supports.prototype.contactSupportType = function() { +3026 return this.json['guardianSupportType']; +3027 }; +3028 +3029 return Supports; +3030 +3031 })(); +3032 +3033 /** +3034 @class Representation of a patient +3035 @augments hQuery.Person +3036 @exports Patient as hQuery.Patient +3037 */ +3038 +3039 +3040 hQuery.Patient = (function(_super) { +3041 +3042 __extends(Patient, _super); +3043 +3044 Patient.name = 'Patient'; 3045 -3046 Patient.prototype.birthtime = function() { -3047 if (this.json['birthdate']) { -3048 return hQuery.dateFromUtcSeconds(this.json['birthdate']); -3049 } -3050 }; -3051 -3052 /** -3053 @param (Date) date the date at which the patient age is calculated, defaults to now. -3054 @returns {number} the patient age in years -3055 */ -3056 -3057 -3058 Patient.prototype.age = function(date) { -3059 var oneDay, oneYear; -3060 if (date == null) { -3061 date = new Date(); -3062 } -3063 oneDay = 24 * 60 * 60 * 1000; -3064 oneYear = 365.25 * oneDay; -3065 return (date.getTime() - this.birthtime().getTime()) / oneYear; -3066 }; -3067 -3068 /** -3069 @returns {CodedValue} the domestic partnership status of the patient -3070 The following HL7 codeset is used: -3071 A Annulled -3072 D Divorced -3073 I Interlocutory -3074 L Legally separated -3075 M Married -3076 P Polygamous -3077 S Never Married -3078 T Domestic Partner -3079 W Widowed -3080 */ -3081 -3082 -3083 Patient.prototype.maritalStatus = function() { -3084 if (this.json['maritalStatus']) { -3085 return hQuery.createCodedValue(this.json['maritalStatus']); -3086 } -3087 }; -3088 -3089 /** -3090 @returns {CodedValue} of the spiritual faith affiliation of the patient -3091 It uses the HL7 codeset. http://www.hl7.org/memonly/downloads/v3edition.cfm#V32008 -3092 */ -3093 -3094 -3095 Patient.prototype.religiousAffiliation = function() { -3096 if (this.json['religiousAffiliation']) { -3097 return hQuery.createCodedValue(this.json['religiousAffiliation']); -3098 } -3099 }; -3100 -3101 /** -3102 @returns {CodedValue} of the race of the patient -3103 CDC codes: http://phinvads.cdc.gov/vads/ViewCodeSystemConcept.action?oid=2.16.840.1.113883.6.238&code=1000-9 -3104 */ -3105 -3106 -3107 Patient.prototype.race = function() { -3108 if (this.json['race']) { -3109 return hQuery.createCodedValue(this.json['race']); -3110 } -3111 }; -3112 -3113 /** -3114 @returns {CodedValue} of the ethnicity of the patient -3115 CDC codes: http://phinvads.cdc.gov/vads/ViewCodeSystemConcept.action?oid=2.16.840.1.113883.6.238&code=1000-9 -3116 */ -3117 -3118 -3119 Patient.prototype.ethnicity = function() { -3120 if (this.json['ethnicity']) { -3121 return hQuery.createCodedValue(this.json['ethnicity']); -3122 } -3123 }; -3124 -3125 /** -3126 @returns {CodedValue} This is the code specifying the level of confidentiality of the document. -3127 HL7 Confidentiality Code (2.16.840.1.113883.5.25) -3128 */ -3129 -3130 -3131 Patient.prototype.confidentiality = function() { -3132 if (this.json['confidentiality']) { -3133 return hQuery.createCodedValue(this.json['confidentiality']); -3134 } -3135 }; -3136 -3137 /** -3138 @returns {Address} of the location where the patient was born -3139 */ -3140 -3141 -3142 Patient.prototype.birthPlace = function() { -3143 return new hQuery.Address(this.json['birthPlace']); -3144 }; -3145 -3146 /** -3147 @returns {Supports} information regarding key support contacts relative to healthcare decisions, including next of kin +3046 function Patient() { +3047 return Patient.__super__.constructor.apply(this, arguments); +3048 } +3049 +3050 /** +3051 @returns {String} containing M or F representing the gender of the patient +3052 */ +3053 +3054 +3055 Patient.prototype.gender = function() { +3056 return this.json['gender']; +3057 }; +3058 +3059 /** +3060 @returns {Date} containing the patients birthdate +3061 */ +3062 +3063 +3064 Patient.prototype.birthtime = function() { +3065 if (this.json['birthdate']) { +3066 return hQuery.dateFromUtcSeconds(this.json['birthdate']); +3067 } +3068 }; +3069 +3070 /** +3071 @param (Date) date the date at which the patient age is calculated, defaults to now. +3072 @returns {number} the patient age in years +3073 */ +3074 +3075 +3076 Patient.prototype.age = function(date) { +3077 var oneDay, oneYear; +3078 if (date == null) { +3079 date = new Date(); +3080 } +3081 if (this.birthtime() != null) { +3082 oneDay = 24 * 60 * 60 * 1000; +3083 oneYear = 365.25 * oneDay; +3084 return (date.getTime() - this.birthtime().getTime()) / oneYear; +3085 } +3086 }; +3087 +3088 /** +3089 @returns {CodedValue} the domestic partnership status of the patient +3090 The following HL7 codeset is used: +3091 A Annulled +3092 D Divorced +3093 I Interlocutory +3094 L Legally separated +3095 M Married +3096 P Polygamous +3097 S Never Married +3098 T Domestic Partner +3099 W Widowed +3100 */ +3101 +3102 +3103 Patient.prototype.maritalStatus = function() { +3104 if (this.json['maritalStatus']) { +3105 return hQuery.createCodedValue(this.json['maritalStatus']); +3106 } +3107 }; +3108 +3109 /** +3110 @returns {CodedValue} of the spiritual faith affiliation of the patient +3111 It uses the HL7 codeset. http://www.hl7.org/memonly/downloads/v3edition.cfm#V32008 +3112 */ +3113 +3114 +3115 Patient.prototype.religiousAffiliation = function() { +3116 if (this.json['religiousAffiliation']) { +3117 return hQuery.createCodedValue(this.json['religiousAffiliation']); +3118 } +3119 }; +3120 +3121 /** +3122 @returns {CodedValue} of the race of the patient +3123 CDC codes: http://phinvads.cdc.gov/vads/ViewCodeSystemConcept.action?oid=2.16.840.1.113883.6.238&code=1000-9 +3124 */ +3125 +3126 +3127 Patient.prototype.race = function() { +3128 if (this.json['race']) { +3129 return hQuery.createCodedValue(this.json['race']); +3130 } +3131 }; +3132 +3133 /** +3134 @returns {CodedValue} of the ethnicity of the patient +3135 CDC codes: http://phinvads.cdc.gov/vads/ViewCodeSystemConcept.action?oid=2.16.840.1.113883.6.238&code=1000-9 +3136 */ +3137 +3138 +3139 Patient.prototype.ethnicity = function() { +3140 if (this.json['ethnicity']) { +3141 return hQuery.createCodedValue(this.json['ethnicity']); +3142 } +3143 }; +3144 +3145 /** +3146 @returns {CodedValue} This is the code specifying the level of confidentiality of the document. +3147 HL7 Confidentiality Code (2.16.840.1.113883.5.25) 3148 */ 3149 3150 -3151 Patient.prototype.supports = function() { -3152 return new hQuery.Supports(this.json['supports']); -3153 }; -3154 -3155 /** -3156 @returns {Organization} -3157 */ -3158 -3159 -3160 Patient.prototype.custodian = function() { -3161 return new hQuery.Organization(this.json['custodian']); -3162 }; -3163 -3164 /** -3165 @returns {Provider} the providers associated with the patient -3166 */ -3167 -3168 -3169 Patient.prototype.provider = function() { -3170 return new hQuery.Provider(this.json['provider']); -3171 }; -3172 -3173 /** -3174 @returns {hQuery.CodedEntryList} A list of {@link hQuery.LanguagesSpoken} objects -3175 Code from http://www.ietf.org/rfc/rfc4646.txt representing the name of the human language -3176 */ -3177 +3151 Patient.prototype.confidentiality = function() { +3152 if (this.json['confidentiality']) { +3153 return hQuery.createCodedValue(this.json['confidentiality']); +3154 } +3155 }; +3156 +3157 /** +3158 @returns {Address} of the location where the patient was born +3159 */ +3160 +3161 +3162 Patient.prototype.birthPlace = function() { +3163 return new hQuery.Address(this.json['birthPlace']); +3164 }; +3165 +3166 /** +3167 @returns {Supports} information regarding key support contacts relative to healthcare decisions, including next of kin +3168 */ +3169 +3170 +3171 Patient.prototype.supports = function() { +3172 return new hQuery.Supports(this.json['supports']); +3173 }; +3174 +3175 /** +3176 @returns {Organization} +3177 */ 3178 -3179 Patient.prototype.languages = function() { -3180 var language, list, _i, _len, _ref; -3181 list = new hQuery.CodedEntryList; -3182 if (this.json['languages']) { -3183 _ref = this.json['languages']; -3184 for (_i = 0, _len = _ref.length; _i < _len; _i++) { -3185 language = _ref[_i]; -3186 list.push(new hQuery.Language(language)); -3187 } -3188 } -3189 return list; -3190 }; -3191 -3192 /** -3193 @returns {Boolean} returns true if the patient has died -3194 */ -3195 -3196 -3197 Patient.prototype.expired = function() { -3198 return this.json['expired']; -3199 }; -3200 -3201 /** -3202 @returns {Boolean} returns true if the patient participated in a clinical trial -3203 */ -3204 -3205 -3206 Patient.prototype.clinicalTrialParticipant = function() { -3207 return this.json['clinicalTrialParticipant']; -3208 }; -3209 -3210 /** -3211 @returns {hQuery.CodedEntryList} A list of {@link hQuery.Encounter} objects -3212 */ -3213 -3214 -3215 Patient.prototype.encounters = function() { -3216 var encounter, list, _i, _len, _ref; -3217 list = new hQuery.CodedEntryList; -3218 if (this.json['encounters']) { -3219 _ref = this.json['encounters']; -3220 for (_i = 0, _len = _ref.length; _i < _len; _i++) { -3221 encounter = _ref[_i]; -3222 list.pushIfUsable(new hQuery.Encounter(encounter)); -3223 } -3224 } -3225 return list; -3226 }; -3227 -3228 /** -3229 @returns {hQuery.CodedEntryList} A list of {@link Medication} objects -3230 */ -3231 -3232 -3233 Patient.prototype.medications = function() { -3234 var list, medication, _i, _len, _ref; -3235 list = new hQuery.CodedEntryList; -3236 if (this.json['medications']) { -3237 _ref = this.json['medications']; -3238 for (_i = 0, _len = _ref.length; _i < _len; _i++) { -3239 medication = _ref[_i]; -3240 list.pushIfUsable(new hQuery.Medication(medication)); -3241 } -3242 } -3243 return list; -3244 }; -3245 -3246 /** -3247 @returns {hQuery.CodedEntryList} A list of {@link Condition} objects -3248 */ -3249 -3250 -3251 Patient.prototype.conditions = function() { -3252 var condition, list, _i, _len, _ref; -3253 list = new hQuery.CodedEntryList; -3254 if (this.json['conditions']) { -3255 _ref = this.json['conditions']; -3256 for (_i = 0, _len = _ref.length; _i < _len; _i++) { -3257 condition = _ref[_i]; -3258 list.pushIfUsable(new hQuery.Condition(condition)); -3259 } -3260 } -3261 return list; -3262 }; -3263 -3264 /** -3265 @returns {hQuery.CodedEntryList} A list of {@link Procedure} objects -3266 */ -3267 -3268 -3269 Patient.prototype.procedures = function() { -3270 var list, procedure, _i, _len, _ref; -3271 list = new hQuery.CodedEntryList; -3272 if (this.json['procedures']) { -3273 _ref = this.json['procedures']; -3274 for (_i = 0, _len = _ref.length; _i < _len; _i++) { -3275 procedure = _ref[_i]; -3276 list.pushIfUsable(new hQuery.Procedure(procedure)); -3277 } -3278 } -3279 return list; -3280 }; -3281 -3282 /** -3283 @returns {hQuery.CodedEntryList} A list of {@link Result} objects -3284 */ -3285 -3286 -3287 Patient.prototype.results = function() { -3288 var list, result, _i, _len, _ref; -3289 list = new hQuery.CodedEntryList; -3290 if (this.json['results']) { -3291 _ref = this.json['results']; -3292 for (_i = 0, _len = _ref.length; _i < _len; _i++) { -3293 result = _ref[_i]; -3294 list.pushIfUsable(new hQuery.Result(result)); -3295 } -3296 } -3297 return list; -3298 }; -3299 -3300 /** -3301 @returns {hQuery.CodedEntryList} A list of {@link Result} objects -3302 */ -3303 -3304 -3305 Patient.prototype.vitalSigns = function() { -3306 var list, vital, _i, _len, _ref; -3307 list = new hQuery.CodedEntryList; -3308 if (this.json['vital_signs']) { -3309 _ref = this.json['vital_signs']; -3310 for (_i = 0, _len = _ref.length; _i < _len; _i++) { -3311 vital = _ref[_i]; -3312 list.pushIfUsable(new hQuery.Result(vital)); -3313 } -3314 } -3315 return list; -3316 }; -3317 -3318 /** -3319 @returns {hQuery.CodedEntryList} A list of {@link Immunization} objects -3320 */ -3321 -3322 -3323 Patient.prototype.immunizations = function() { -3324 var immunization, list, _i, _len, _ref; -3325 list = new hQuery.CodedEntryList; -3326 if (this.json['immunizations']) { -3327 _ref = this.json['immunizations']; -3328 for (_i = 0, _len = _ref.length; _i < _len; _i++) { -3329 immunization = _ref[_i]; -3330 list.pushIfUsable(new hQuery.Immunization(immunization)); -3331 } -3332 } -3333 return list; -3334 }; -3335 -3336 /** -3337 @returns {hQuery.CodedEntryList} A list of {@link Allergy} objects -3338 */ -3339 -3340 -3341 Patient.prototype.allergies = function() { -3342 var allergy, list, _i, _len, _ref; -3343 list = new hQuery.CodedEntryList; -3344 if (this.json['allergies']) { -3345 _ref = this.json['allergies']; -3346 for (_i = 0, _len = _ref.length; _i < _len; _i++) { -3347 allergy = _ref[_i]; -3348 list.pushIfUsable(new hQuery.Allergy(allergy)); -3349 } -3350 } -3351 return list; -3352 }; -3353 -3354 /** -3355 @returns {hQuery.CodedEntryList} A list of {@link Pregnancy} objects -3356 */ -3357 -3358 -3359 Patient.prototype.pregnancies = function() { -3360 var list, pregnancy, _i, _len, _ref; -3361 list = new hQuery.CodedEntryList; -3362 if (this.json['pregnancies']) { -3363 _ref = this.json['pregnancies']; -3364 for (_i = 0, _len = _ref.length; _i < _len; _i++) { -3365 pregnancy = _ref[_i]; -3366 list.pushIfUsable(new hQuery.Pregnancy(pregnancy)); -3367 } -3368 } -3369 return list; -3370 }; -3371 -3372 /** -3373 @returns {hQuery.CodedEntryList} A list of {@link Socialhistory} objects -3374 */ -3375 -3376 -3377 Patient.prototype.socialHistories = function() { -3378 var list, socialhistory, _i, _len, _ref; -3379 list = new hQuery.CodedEntryList; -3380 if (this.json['socialhistories']) { -3381 _ref = this.json['socialhistories']; -3382 for (_i = 0, _len = _ref.length; _i < _len; _i++) { -3383 socialhistory = _ref[_i]; -3384 list.pushIfUsable(new hQuery.Socialhistory(socialhistory)); -3385 } -3386 } -3387 return list; -3388 }; -3389 -3390 /** -3391 @returns {hQuery.CodedEntryList} A list of {@link CareGoal} objects -3392 */ -3393 -3394 -3395 Patient.prototype.careGoals = function() { -3396 var caregoal, list, _i, _len, _ref; -3397 list = new hQuery.CodedEntryList; -3398 if (this.json['care_goals']) { -3399 _ref = this.json['care_goals']; -3400 for (_i = 0, _len = _ref.length; _i < _len; _i++) { -3401 caregoal = _ref[_i]; -3402 list.pushIfUsable(new hQuery.CareGoal(caregoal)); -3403 } -3404 } -3405 return list; -3406 }; -3407 -3408 /** -3409 @returns {hQuery.CodedEntryList} A list of {@link MedicalEquipment} objects -3410 */ -3411 -3412 -3413 Patient.prototype.medicalEquipment = function() { -3414 var equipment, list, _i, _len, _ref; -3415 list = new hQuery.CodedEntryList; -3416 if (this.json['medical_equipment']) { -3417 _ref = this.json['medical_equipment']; -3418 for (_i = 0, _len = _ref.length; _i < _len; _i++) { -3419 equipment = _ref[_i]; -3420 list.pushIfUsable(new hQuery.MedicalEquipment(equipment)); -3421 } -3422 } -3423 return list; -3424 }; -3425 -3426 /** -3427 @returns {hQuery.CodedEntryList} A list of {@link FunctionalStatus} objects -3428 */ -3429 -3430 -3431 Patient.prototype.functionalStatuses = function() { -3432 var fs, list, _i, _len, _ref; -3433 list = new hQuery.CodedEntryList; -3434 if (this.json['functional_statuses']) { -3435 _ref = this.json['functional_statuses']; -3436 for (_i = 0, _len = _ref.length; _i < _len; _i++) { -3437 fs = _ref[_i]; -3438 list.pushIfUsable(new hQuery.FunctionalStatus(fs)); -3439 } -3440 } -3441 return list; -3442 }; -3443 -3444 return Patient; +3179 +3180 Patient.prototype.custodian = function() { +3181 return new hQuery.Organization(this.json['custodian']); +3182 }; +3183 +3184 /** +3185 @returns {Provider} the providers associated with the patient +3186 */ +3187 +3188 +3189 Patient.prototype.provider = function() { +3190 return new hQuery.Provider(this.json['provider']); +3191 }; +3192 +3193 /** +3194 @returns {hQuery.CodedEntryList} A list of {@link hQuery.LanguagesSpoken} objects +3195 Code from http://www.ietf.org/rfc/rfc4646.txt representing the name of the human language +3196 */ +3197 +3198 +3199 Patient.prototype.languages = function() { +3200 var language, list, _i, _len, _ref; +3201 list = new hQuery.CodedEntryList; +3202 if (this.json['languages']) { +3203 _ref = this.json['languages']; +3204 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +3205 language = _ref[_i]; +3206 list.push(new hQuery.Language(language)); +3207 } +3208 } +3209 return list; +3210 }; +3211 +3212 /** +3213 @returns {Boolean} returns true if the patient has died +3214 */ +3215 +3216 +3217 Patient.prototype.expired = function() { +3218 return this.json['expired']; +3219 }; +3220 +3221 /** +3222 @returns {Boolean} returns true if the patient participated in a clinical trial +3223 */ +3224 +3225 +3226 Patient.prototype.clinicalTrialParticipant = function() { +3227 return this.json['clinicalTrialParticipant']; +3228 }; +3229 +3230 /** +3231 @returns {hQuery.CodedEntryList} A list of {@link hQuery.Encounter} objects +3232 */ +3233 +3234 +3235 Patient.prototype.encounters = function() { +3236 var encounter, list, _i, _len, _ref; +3237 list = new hQuery.CodedEntryList; +3238 if (this.json['encounters']) { +3239 _ref = this.json['encounters']; +3240 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +3241 encounter = _ref[_i]; +3242 list.pushIfUsable(new hQuery.Encounter(encounter)); +3243 } +3244 } +3245 return list; +3246 }; +3247 +3248 /** +3249 @returns {hQuery.CodedEntryList} A list of {@link Medication} objects +3250 */ +3251 +3252 +3253 Patient.prototype.medications = function() { +3254 var list, medication, _i, _len, _ref; +3255 list = new hQuery.CodedEntryList; +3256 if (this.json['medications']) { +3257 _ref = this.json['medications']; +3258 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +3259 medication = _ref[_i]; +3260 list.pushIfUsable(new hQuery.Medication(medication)); +3261 } +3262 } +3263 return list; +3264 }; +3265 +3266 /** +3267 @returns {hQuery.CodedEntryList} A list of {@link Condition} objects +3268 */ +3269 +3270 +3271 Patient.prototype.conditions = function() { +3272 var condition, list, _i, _len, _ref; +3273 list = new hQuery.CodedEntryList; +3274 if (this.json['conditions']) { +3275 _ref = this.json['conditions']; +3276 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +3277 condition = _ref[_i]; +3278 list.pushIfUsable(new hQuery.Condition(condition)); +3279 } +3280 } +3281 return list; +3282 }; +3283 +3284 /** +3285 @returns {hQuery.CodedEntryList} A list of {@link Procedure} objects +3286 */ +3287 +3288 +3289 Patient.prototype.procedures = function() { +3290 var list, procedure, _i, _len, _ref; +3291 list = new hQuery.CodedEntryList; +3292 if (this.json['procedures']) { +3293 _ref = this.json['procedures']; +3294 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +3295 procedure = _ref[_i]; +3296 list.pushIfUsable(new hQuery.Procedure(procedure)); +3297 } +3298 } +3299 return list; +3300 }; +3301 +3302 /** +3303 @returns {hQuery.CodedEntryList} A list of {@link Result} objects +3304 */ +3305 +3306 +3307 Patient.prototype.results = function() { +3308 var list, result, _i, _len, _ref; +3309 list = new hQuery.CodedEntryList; +3310 if (this.json['results']) { +3311 _ref = this.json['results']; +3312 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +3313 result = _ref[_i]; +3314 list.pushIfUsable(new hQuery.Result(result)); +3315 } +3316 } +3317 return list; +3318 }; +3319 +3320 /** +3321 @returns {hQuery.CodedEntryList} A list of {@link Result} objects +3322 */ +3323 +3324 +3325 Patient.prototype.vitalSigns = function() { +3326 var list, vital, _i, _len, _ref; +3327 list = new hQuery.CodedEntryList; +3328 if (this.json['vital_signs']) { +3329 _ref = this.json['vital_signs']; +3330 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +3331 vital = _ref[_i]; +3332 list.pushIfUsable(new hQuery.Result(vital)); +3333 } +3334 } +3335 return list; +3336 }; +3337 +3338 /** +3339 @returns {hQuery.CodedEntryList} A list of {@link Immunization} objects +3340 */ +3341 +3342 +3343 Patient.prototype.immunizations = function() { +3344 var immunization, list, _i, _len, _ref; +3345 list = new hQuery.CodedEntryList; +3346 if (this.json['immunizations']) { +3347 _ref = this.json['immunizations']; +3348 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +3349 immunization = _ref[_i]; +3350 list.pushIfUsable(new hQuery.Immunization(immunization)); +3351 } +3352 } +3353 return list; +3354 }; +3355 +3356 /** +3357 @returns {hQuery.CodedEntryList} A list of {@link Allergy} objects +3358 */ +3359 +3360 +3361 Patient.prototype.allergies = function() { +3362 var allergy, list, _i, _len, _ref; +3363 list = new hQuery.CodedEntryList; +3364 if (this.json['allergies']) { +3365 _ref = this.json['allergies']; +3366 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +3367 allergy = _ref[_i]; +3368 list.pushIfUsable(new hQuery.Allergy(allergy)); +3369 } +3370 } +3371 return list; +3372 }; +3373 +3374 /** +3375 @returns {hQuery.CodedEntryList} A list of {@link Pregnancy} objects +3376 */ +3377 +3378 +3379 Patient.prototype.pregnancies = function() { +3380 var list, pregnancy, _i, _len, _ref; +3381 list = new hQuery.CodedEntryList; +3382 if (this.json['pregnancies']) { +3383 _ref = this.json['pregnancies']; +3384 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +3385 pregnancy = _ref[_i]; +3386 list.pushIfUsable(new hQuery.Pregnancy(pregnancy)); +3387 } +3388 } +3389 return list; +3390 }; +3391 +3392 /** +3393 @returns {hQuery.CodedEntryList} A list of {@link Socialhistory} objects +3394 */ +3395 +3396 +3397 Patient.prototype.socialHistories = function() { +3398 var list, socialhistory, _i, _len, _ref; +3399 list = new hQuery.CodedEntryList; +3400 if (this.json['socialhistories']) { +3401 _ref = this.json['socialhistories']; +3402 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +3403 socialhistory = _ref[_i]; +3404 list.pushIfUsable(new hQuery.Socialhistory(socialhistory)); +3405 } +3406 } +3407 return list; +3408 }; +3409 +3410 /** +3411 @returns {hQuery.CodedEntryList} A list of {@link CareGoal} objects +3412 */ +3413 +3414 +3415 Patient.prototype.careGoals = function() { +3416 var caregoal, list, _i, _len, _ref; +3417 list = new hQuery.CodedEntryList; +3418 if (this.json['care_goals']) { +3419 _ref = this.json['care_goals']; +3420 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +3421 caregoal = _ref[_i]; +3422 list.pushIfUsable(new hQuery.CareGoal(caregoal)); +3423 } +3424 } +3425 return list; +3426 }; +3427 +3428 /** +3429 @returns {hQuery.CodedEntryList} A list of {@link MedicalEquipment} objects +3430 */ +3431 +3432 +3433 Patient.prototype.medicalEquipment = function() { +3434 var equipment, list, _i, _len, _ref; +3435 list = new hQuery.CodedEntryList; +3436 if (this.json['medical_equipment']) { +3437 _ref = this.json['medical_equipment']; +3438 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +3439 equipment = _ref[_i]; +3440 list.pushIfUsable(new hQuery.MedicalEquipment(equipment)); +3441 } +3442 } +3443 return list; +3444 }; 3445 -3446 })(hQuery.Person); -3447 \ No newline at end of file +3446 /** +3447 @returns {hQuery.CodedEntryList} A list of {@link FunctionalStatus} objects +3448 */ +3449 +3450 +3451 Patient.prototype.functionalStatuses = function() { +3452 var fs, list, _i, _len, _ref; +3453 list = new hQuery.CodedEntryList; +3454 if (this.json['functional_statuses']) { +3455 _ref = this.json['functional_statuses']; +3456 for (_i = 0, _len = _ref.length; _i < _len; _i++) { +3457 fs = _ref[_i]; +3458 list.pushIfUsable(new hQuery.FunctionalStatus(fs)); +3459 } +3460 } +3461 return list; +3462 }; +3463 +3464 return Patient; +3465 +3466 })(hQuery.Person); +3467 \ No newline at end of file From 04ccaea915861c3e95014ce2131ffcdd5ee03307 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Thu, 26 Mar 2015 12:22:10 -0700 Subject: [PATCH 089/117] Use latest patientapi gem --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index c2deca9..9b09a0c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/scoophealth/patientapi.git - revision: 2379718fd5c4a813443f12a23331779f7557f7cd + revision: 8cfb50a53396180b652737f406d5cc2d9e5e3cb5 branch: master specs: hquery-patient-api (1.0.5) From f0e9f4bdea1d972b881b4ab31dc06d900f52ceda Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Sun, 19 Apr 2015 15:06:31 -0700 Subject: [PATCH 090/117] Fixed bug in batch_query so only users queries are ran --- app/controllers/queries_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/queries_controller.rb b/app/controllers/queries_controller.rb index f13037f..1165656 100755 --- a/app/controllers/queries_controller.rb +++ b/app/controllers/queries_controller.rb @@ -99,7 +99,7 @@ def execute_batch notify = params[:notification] - Query.all.each do |eachQuery| + current_user.queries.each do |eachQuery| # execute the query, and pass in the endpoints and if the user should be notified by email when execution completes eachQuery.execute(endpoints, notify) end From ee7a7785d5633ee8fe3b129b619b036c49d97e00 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Mon, 20 Apr 2015 09:53:54 -0700 Subject: [PATCH 091/117] Modified for v2 queries --- util/STOPP_report_tool.py | 54 ++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/util/STOPP_report_tool.py b/util/STOPP_report_tool.py index b353088..a146dde 100644 --- a/util/STOPP_report_tool.py +++ b/util/STOPP_report_tool.py @@ -3,13 +3,14 @@ import datetime import pymongo + class MongoDatabase(object): DEFAULT_DB_NAME = "query_composer_development" ENDPOINTS_COLLECTION = "endpoints" - QUERIES_COLLECTION = "queries" - RESULTS_COLLECTION = "results" + QUERIES_COLLECTION = "queries" + RESULTS_COLLECTION = "results" def __init__(self, db_name=DEFAULT_DB_NAME, host="localhost", port=27017): self._client = pymongo.MongoClient("mongodb://{host}:{port}".format(host=host, port=port)) @@ -36,47 +37,51 @@ def get_results(self): find_query = {} return list(self._get_results_collection().find(find_query)) - def get_query(self,queryid): + def get_query(self, queryid): find_query = {'_id': queryid} return (list(self._get_queries_collection().find(find_query)))[0] + def select_result(execution_id, endpoint_id, results): for result in results: if result['execution_id'] == execution_id: if result['endpoint_id'] == endpoint_id: return result + def main(): db = MongoDatabase() - endpoints= db.get_endpoints() + endpoints = db.get_endpoints() queries = db.get_queries() results = db.get_results() - querySet = {} + query_set = {} for query in queries: - if not query['description'].startswith("STOPP Rule "): + if not query['description'].startswith("STOPP Rule ").endswith(' v2'): continue - querySet[query['description']] = query['_id'] - queryDesc = sorted(querySet) + query_set[query['description']] = query['_id'] + query_desc = sorted(query_set) - for desc in queryDesc: # want queries sorted by description - queryid = querySet[desc] + for desc in query_desc: # want queries sorted by description + queryid = query_set[desc] query = db.get_query(queryid) desc = query['description'].split()[2] - print desc, query['title'] + print(str(desc), query['title']) executions = query['executions'] for execution in executions: jstime = execution['time'] dt = datetime.datetime.fromtimestamp(jstime) - if dt < datetime.datetime(2015,2,19,12,0,0): - #print "dt =", dt - #print "date =", datetime.datetime(2015,2,19,12,0,0) - continue + # if dt < datetime.datetime(2015, 2, 19, 12, 0, 0): + if dt < datetime.datetime(2015, 4, 19, 22, 0, 0): + continue + # print "dt =", dt + # print "date =", datetime.datetime(2015,2,19,12,0,0) execution_id = execution['_id'] try: aggregate_result = execution['aggregate_result'] - except KeyError: continue + except KeyError: + continue if aggregate_result: keys = [] reportline = " " @@ -85,7 +90,7 @@ def main(): for key in aggregate_result: reportline += ' '+str(key)+' '+str(int(aggregate_result[key])) keys.append(key) - print reportline + print(reportline) for endpoint in endpoints: endpoint_id = endpoint['_id'] @@ -94,13 +99,16 @@ def main(): reportline = ' '+str(endpoint['name']) try: value = result['value'] - except KeyError: continue + except KeyError: + continue for key in keys: try: - reportline += ' '+ str(key)+' '+str(int(value[key])) - except KeyError: continue - print reportline - print + reportline += ' ' + str(key)+' '+str(int(value[key])) + except KeyError: + continue + print(reportline) + print() -if __name__ == '__main__':main() +if __name__ == '__main__': + main() From 1232df2277215b4464a5b508df8d4acf8329a202 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Mon, 20 Apr 2015 09:58:40 -0700 Subject: [PATCH 092/117] Fixed bug --- util/STOPP_report_tool.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/util/STOPP_report_tool.py b/util/STOPP_report_tool.py index a146dde..59e1b82 100644 --- a/util/STOPP_report_tool.py +++ b/util/STOPP_report_tool.py @@ -57,7 +57,8 @@ def main(): query_set = {} for query in queries: - if not query['description'].startswith("STOPP Rule ").endswith(' v2'): + if not query['description'].startswith("STOPP Rule ") and\ + query['description'].startswith("STOPP Rule ").endswith(' v2'): continue query_set[query['description']] = query['_id'] query_desc = sorted(query_set) From a5e78df1286906580fad3a17d76cb9dba642be07 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Tue, 28 Jul 2015 14:58:06 -0700 Subject: [PATCH 093/117] Speedup dashboard status response --- Gemfile | 2 ++ Gemfile.lock | 2 ++ app/helpers/endpoints_helper.rb | 5 ++++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 1c64ec0..488cda6 100755 --- a/Gemfile +++ b/Gemfile @@ -34,6 +34,8 @@ gem 'kramdown' gem 'jasmine', :group => [:development, :test] gem 'headless', :group => [:development, :test] +gem 'parallel' + # To use debugger # gem 'ruby-debug19', :require => 'ruby-debug' diff --git a/Gemfile.lock b/Gemfile.lock index 9b09a0c..1ad8d7a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -115,6 +115,7 @@ GEM multipart-post (1.2.0) origin (1.1.0) orm_adapter (0.4.0) + parallel (1.0.0) polyglot (0.3.5) pry (0.9.12.2) coderay (~> 1.0.5) @@ -290,6 +291,7 @@ DEPENDENCIES mongoid mongoid_rails_migrations multipart-post + parallel pry rails (= 3.2.13) sass-rails diff --git a/app/helpers/endpoints_helper.rb b/app/helpers/endpoints_helper.rb index d886b68..859e241 100755 --- a/app/helpers/endpoints_helper.rb +++ b/app/helpers/endpoints_helper.rb @@ -1,7 +1,10 @@ +require 'parallel' + module EndpointsHelper def fetch_endpoint_statuses @endpoint_server_statuses = {} - @endpoints.each do |endpoint| + #@endpoints.each do |endpoint| + Parallel.each(@endpoints, :in_threads=>10) do |endpoint| url = endpoint.status_url begin #use ssl From bd1b94fde4a1e95a6a1e4704571ab38dde0bc6b9 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Tue, 28 Jul 2015 15:55:13 -0700 Subject: [PATCH 094/117] Version 2 of STOPP report --- util/STOPP_report_tool.py | 59 +++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/util/STOPP_report_tool.py b/util/STOPP_report_tool.py index 59e1b82..19a49dc 100644 --- a/util/STOPP_report_tool.py +++ b/util/STOPP_report_tool.py @@ -5,7 +5,6 @@ class MongoDatabase(object): - DEFAULT_DB_NAME = "query_composer_development" ENDPOINTS_COLLECTION = "endpoints" @@ -57,23 +56,23 @@ def main(): query_set = {} for query in queries: - if not query['description'].startswith("STOPP Rule ") and\ - query['description'].startswith("STOPP Rule ").endswith(' v2'): - continue - query_set[query['description']] = query['_id'] + if (query['description'].startswith("STOPP Rule ") or query['description'].startswith("xSTOPP Rule ")) and \ + query['description'].endswith(' v2'): + query_set[query['description']] = query['_id'] query_desc = sorted(query_set) for desc in query_desc: # want queries sorted by description queryid = query_set[desc] query = db.get_query(queryid) desc = query['description'].split()[2] - print(str(desc), query['title']) + print(desc + ':'), + print(query['title']) executions = query['executions'] for execution in executions: jstime = execution['time'] dt = datetime.datetime.fromtimestamp(jstime) # if dt < datetime.datetime(2015, 2, 19, 12, 0, 0): - if dt < datetime.datetime(2015, 4, 19, 22, 0, 0): + if dt < datetime.datetime(2015, 4, 28, 10, 0, 0): continue # print "dt =", dt # print "date =", datetime.datetime(2015,2,19,12,0,0) @@ -84,32 +83,32 @@ def main(): except KeyError: continue if aggregate_result: - keys = [] - reportline = " " - reportline += str(dt) - reportline += " aggregate:" - for key in aggregate_result: - reportline += ' '+str(key)+' '+str(int(aggregate_result[key])) - keys.append(key) - print(reportline) - - for endpoint in endpoints: - endpoint_id = endpoint['_id'] - result = select_result(execution_id, endpoint_id, results) - if result: - reportline = ' '+str(endpoint['name']) + keys = [] + reportline = " " + reportline += str(dt) + reportline += " aggregate:" + for key in aggregate_result: + reportline += ' ' + str(key) + ' ' + str(int(aggregate_result[key])) + keys.append(key) + print(reportline) + + for endpoint in endpoints: + endpoint_id = endpoint['_id'] + result = select_result(execution_id, endpoint_id, results) + if result: + reportline = ' ' + str(endpoint['name']) + try: + value = result['value'] + except KeyError: + continue + for key in keys: try: - value = result['value'] + reportline += ' ' + str(key) + ' ' + str(int(value[key])) except KeyError: continue - for key in keys: - try: - reportline += ' ' + str(key)+' '+str(int(value[key])) - except KeyError: - continue - print(reportline) - print() - + print(reportline) + print("\n") + if __name__ == '__main__': main() From abcce6905090b89af9e45e801f0f714a7bcc7ce0 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Thu, 30 Jul 2015 14:40:30 -0700 Subject: [PATCH 095/117] Start of work on scheduled jobs --- .../javascripts/scheduled_jobs.js.coffee | 3 ++ .../stylesheets/scheduled_jobs.css.scss | 3 ++ app/controllers/scheduled_jobs_controller.rb | 26 +++++++++++ app/helpers/scheduled_jobs_helper.rb | 2 + app/views/scheduled_jobs/batch_query.html.erb | 2 + config/routes.rb | 2 + .../scheduled_jobs_controller_test.rb | 45 +++++++++++++++++++ .../helpers/scheduled_jobs_helper_test.rb | 4 ++ 8 files changed, 87 insertions(+) create mode 100644 app/assets/javascripts/scheduled_jobs.js.coffee create mode 100644 app/assets/stylesheets/scheduled_jobs.css.scss create mode 100644 app/controllers/scheduled_jobs_controller.rb create mode 100644 app/helpers/scheduled_jobs_helper.rb create mode 100644 app/views/scheduled_jobs/batch_query.html.erb create mode 100644 test/functional/scheduled_jobs_controller_test.rb create mode 100644 test/unit/helpers/scheduled_jobs_helper_test.rb diff --git a/app/assets/javascripts/scheduled_jobs.js.coffee b/app/assets/javascripts/scheduled_jobs.js.coffee new file mode 100644 index 0000000..7615679 --- /dev/null +++ b/app/assets/javascripts/scheduled_jobs.js.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ diff --git a/app/assets/stylesheets/scheduled_jobs.css.scss b/app/assets/stylesheets/scheduled_jobs.css.scss new file mode 100644 index 0000000..3b0e189 --- /dev/null +++ b/app/assets/stylesheets/scheduled_jobs.css.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the scheduled_jobs controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/scheduled_jobs_controller.rb b/app/controllers/scheduled_jobs_controller.rb new file mode 100644 index 0000000..107f2fb --- /dev/null +++ b/app/controllers/scheduled_jobs_controller.rb @@ -0,0 +1,26 @@ +require 'cud_actions' +class ScheduledJobsController < ActionController::Base + include CudActions + + creates_updates_destroys :query + + def batch_query + endpoint_ids = params[:endpoint_ids] + + if endpoint_ids && !endpoint_ids.empty? + endpoint_ids = endpoint_ids.map! {|id| Moped::BSON::ObjectId(id)} + endpoints = Endpoint.criteria.for_ids(endpoint_ids) + + notify = params[:notification] + + current_user.queries.each do |eachQuery| + # execute the query, and pass in the endpoints and if the user should be notified by email when execution completes + STDERR.puts "here" + STDERR.puts current_user.inspect + eachQuery.execute(endpoints, notify) + end + else + flash[:alert] = 'Cannot execute a query if no endpoints are provided.' + end + end +end diff --git a/app/helpers/scheduled_jobs_helper.rb b/app/helpers/scheduled_jobs_helper.rb new file mode 100644 index 0000000..c3b616b --- /dev/null +++ b/app/helpers/scheduled_jobs_helper.rb @@ -0,0 +1,2 @@ +module ScheduledJobsHelper +end diff --git a/app/views/scheduled_jobs/batch_query.html.erb b/app/views/scheduled_jobs/batch_query.html.erb new file mode 100644 index 0000000..56fc0b4 --- /dev/null +++ b/app/views/scheduled_jobs/batch_query.html.erb @@ -0,0 +1,2 @@ +

    ScheduledJobs#batch_query

    +

    Find me in app/views/scheduled_jobs/batch_query.html.erb

    diff --git a/config/routes.rb b/config/routes.rb index 361f9ea..57a772f 100755 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,5 +1,7 @@ QueryComposer::Application.routes.draw do + post "scheduled_jobs/batch_query", :constraints => {:ip => /127.0.0.1/} + devise_for :users get "admin/users" diff --git a/test/functional/scheduled_jobs_controller_test.rb b/test/functional/scheduled_jobs_controller_test.rb new file mode 100644 index 0000000..79abac9 --- /dev/null +++ b/test/functional/scheduled_jobs_controller_test.rb @@ -0,0 +1,45 @@ +require 'test_helper' + +class ScheduledJobsControllerTest < ActionController::TestCase + + + setup do + + dump_database + + @user = FactoryGirl.create(:user_with_queries) + @ids = @user.queries.order_by([[:created_at, :desc]]).map {|q| q.id} + @user_ids = [] << @user.id + + @new_endpoint = FactoryGirl.create(:endpoint) + + @endpoints_for_execution = [] + @endpoints_for_execution << FactoryGirl.create(:endpoint) + @endpoints_for_execution << FactoryGirl.create(:endpoint, base_url: HTTP_PROTO_CLIENT+'://127.0.0.1:3002') + + @unattached_query = FactoryGirl.create(:query) + + @admin = FactoryGirl.create(:admin) + + @unapproved_user = FactoryGirl.create(:unapproved_user) + + @template_query = FactoryGirl.create(:template_query) + + end + + test 'should get batch_query' do + sign_in @user + FakeWeb.register_uri(:post, HTTP_PROTO_CLIENT+"://127.0.0.1:3001/queries", :body => "FORCE ERROR") + query_from_db = Query.find(@ids[2]) + + endpoint_ids = [@endpoints_for_execution[0].id.to_s] + + STDERR.puts query_from_db.inspect + post :batch_query, id: @ids[2], endpoint_ids: endpoint_ids, notification: false + #query = assigns(:query) + #assert_not_nil query + #assert query.last_execution.notification + assert_response :success + end + +end diff --git a/test/unit/helpers/scheduled_jobs_helper_test.rb b/test/unit/helpers/scheduled_jobs_helper_test.rb new file mode 100644 index 0000000..b19eac1 --- /dev/null +++ b/test/unit/helpers/scheduled_jobs_helper_test.rb @@ -0,0 +1,4 @@ +require 'test_helper' + +class ScheduledJobsHelperTest < ActionView::TestCase +end From ee08f07e0596cae4b5beb6ec30b6bf2c3c26110d Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Wed, 5 Aug 2015 12:51:14 -0700 Subject: [PATCH 096/117] initial work on scheduled query batch jobs --- app/controllers/scheduled_jobs_controller.rb | 85 +++++++++++++++++-- app/models/base_query.rb | 5 ++ app/models/endpoint.rb | 5 ++ .../scheduled_jobs_controller_test.rb | 6 +- util/scheduled_job_post.py | 25 ++++++ 5 files changed, 116 insertions(+), 10 deletions(-) create mode 100644 util/scheduled_job_post.py diff --git a/app/controllers/scheduled_jobs_controller.rb b/app/controllers/scheduled_jobs_controller.rb index 107f2fb..64e1696 100644 --- a/app/controllers/scheduled_jobs_controller.rb +++ b/app/controllers/scheduled_jobs_controller.rb @@ -4,20 +4,87 @@ class ScheduledJobsController < ActionController::Base creates_updates_destroys :query + def parse_array(string) + string[1..-2].gsub!(/[^0-9A-Za-z,-]/, '').split(',') + end + + # Model constraints: + # usernames are required to be unique in the user model, + # a query must have a title, + # an endpoint must have a name. + # Query titles and descriptions do not have to be unique; A combination + # of title, description and username is more likely to be unique but for + # convenience only description is currently implemented. def batch_query - endpoint_ids = params[:endpoint_ids] + render nothing: true - if endpoint_ids && !endpoint_ids.empty? - endpoint_ids = endpoint_ids.map! {|id| Moped::BSON::ObjectId(id)} - endpoints = Endpoint.criteria.for_ids(endpoint_ids) + # logger.info "params: " + params.inspect + # + # endpoints_all = Endpoint.all + # logger.info "List of all endpoints:" + # endpoints_all.each do |endpoint| + # logger.info ' name: ' + endpoint[:name] + ', url: ' + endpoint[:base_url] + # end + + # Select endpoints using array of endpoint names; + # Unfortunately, they are not necessarily unique + endpoint_names = params[:endpoint_names] + logger.info 'param endpoint_names:' + endpoint_names.inspect + selected_endpoints = [] + if endpoint_names + parse_array(endpoint_names).each do |endpoint_name| + match_ep = Endpoint.find_by_name(endpoint_name) + if match_ep + logger.info endpoint_name + ' matches: ' + match_ep.inspect + selected_endpoints.push(match_ep) + else + logger.info 'WARNING: ' + endpoint_name + ' has no match!' + end + end + end + logger.info 'selected endpoings: ' + selected_endpoints.inspect - notify = params[:notification] - current_user.queries.each do |eachQuery| + # users = User.all + # users.each do |user| + # logger.info 'username: ' + user[:username] + # end + + # queries_all = Query.all + # logger.info "List of all queries:" + # queries_all.each do |query| + # logger.info ' title: ' + query[:title] + ', desc: ' + query[:description] + # end + + # Select query using array of query descriptions; + # Unfortunately, they are not necessarily unique + #query_titles = params[:query_titles] + #user_username = params[:user_username] + query_descriptions = params[:query_descriptions] + logger.info 'param query_descriptions:' + query_descriptions.inspect + selected_queries = [] + if query_descriptions + parse_array(query_descriptions).each do |query_desc| + match_query = Query.find_by_description(query_desc) + if match_query + logger.info query_desc + ' matches: ' + match_query.inspect + selected_queries.push(match_query) + else + logger.info 'WARNING: ' + query_desc + ' has no match!' + end + end + end + logger.info 'selected queries: ' + selected_queries.inspect + + if selected_endpoints && !selected_endpoints.empty? && + selected_queries && !selected_queries.empty? + notify = params[:notification] + selected_queries.each do |eachQuery| # execute the query, and pass in the endpoints and if the user should be notified by email when execution completes - STDERR.puts "here" - STDERR.puts current_user.inspect - eachQuery.execute(endpoints, notify) + logger.info 'title: ' + eachQuery[:title].inspect + logger.info 'desc: ' + eachQuery[:description].inspect + logger.info 'user_id: ' + eachQuery[:user_id].inspect + eachQuery.execute(selected_endpoints, notify) end else flash[:alert] = 'Cannot execute a query if no endpoints are provided.' diff --git a/app/models/base_query.rb b/app/models/base_query.rb index 349e8b2..eaf83fc 100644 --- a/app/models/base_query.rb +++ b/app/models/base_query.rb @@ -12,5 +12,10 @@ class BaseQuery field :generated, type: Boolean validates_presence_of :title + + def self.find_by_description(desc) + where(description: desc).first + end + end diff --git a/app/models/endpoint.rb b/app/models/endpoint.rb index 3d7ca45..68e26f4 100755 --- a/app/models/endpoint.rb +++ b/app/models/endpoint.rb @@ -88,4 +88,9 @@ def get_execution result def active_results_for_this_endpoint results.any_in(status: [Result::RUNNING, Result::QUEUED]) end + + def self.find_by_name(name) + where(name: name).first + end + end diff --git a/test/functional/scheduled_jobs_controller_test.rb b/test/functional/scheduled_jobs_controller_test.rb index 79abac9..af83964 100644 --- a/test/functional/scheduled_jobs_controller_test.rb +++ b/test/functional/scheduled_jobs_controller_test.rb @@ -34,7 +34,11 @@ class ScheduledJobsControllerTest < ActionController::TestCase endpoint_ids = [@endpoints_for_execution[0].id.to_s] - STDERR.puts query_from_db.inspect + puts "endpoints: " + @endpoints_for_execution.inspect + + #STDERR.puts query_from_db.inspect + puts "DRUSK #{endpoint_ids}" + puts "@ids[2]=" + @ids[2].inspect + " endpoint_ids=" + endpoint_ids.inspect post :batch_query, id: @ids[2], endpoint_ids: endpoint_ids, notification: false #query = assigns(:query) #assert_not_nil query diff --git a/util/scheduled_job_post.py b/util/scheduled_job_post.py new file mode 100644 index 0000000..c436d24 --- /dev/null +++ b/util/scheduled_job_post.py @@ -0,0 +1,25 @@ +__author__ = 'rrusk' +import httplib, urllib + +params = urllib.urlencode({'@number': 12524, '@type': 'issue', '@action': 'show'}) +params = urllib.urlencode({"endpoint_names":["ep1","ep2", "ep3"],"query_descriptions":["desc1","desc2"]}) +headers = {"Content-type": "application/x-www-form-urlencoded", + "Accept": "text/plain"} +conn = httplib.HTTPSConnection("localhost", 3002) +conn.request("POST", "/scheduled_jobs/batch_query", params, headers) +response = conn.getresponse() +print response.status, response.reason +data = response.read() +print data +conn.close() + +# import requests +# import json +# url = 'https://localhost:3002/scheduled_jobs/batch_query' +# payload = {"endpoint_names":["ep1","ep2"],"query_desc":["desc1","desc2"]} +# #r = requests.post(url, data=payload, verify=False) +# #r = requests.post(url, data=json.dumps(payload), verify=False) +# r = requests.post(url, params=payload, verify=False) +# print r.status_code +# print "encoding: " + str(r.encoding) +# print r.text \ No newline at end of file From bb29006b07261606fb21c515258b93e67db3700f Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Wed, 5 Aug 2015 13:36:23 -0700 Subject: [PATCH 097/117] Select query by username --- app/controllers/scheduled_jobs_controller.rb | 29 ++++++++++--------- app/models/query.rb | 1 - .../scheduled_jobs_controller_test.rb | 2 +- util/scheduled_job_post.py | 2 +- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/app/controllers/scheduled_jobs_controller.rb b/app/controllers/scheduled_jobs_controller.rb index 64e1696..c5adf9b 100644 --- a/app/controllers/scheduled_jobs_controller.rb +++ b/app/controllers/scheduled_jobs_controller.rb @@ -14,7 +14,7 @@ def parse_array(string) # an endpoint must have a name. # Query titles and descriptions do not have to be unique; A combination # of title, description and username is more likely to be unique but for - # convenience only description is currently implemented. + # convenience only description and username are currently implemented. def batch_query render nothing: true @@ -59,18 +59,21 @@ def batch_query # Select query using array of query descriptions; # Unfortunately, they are not necessarily unique #query_titles = params[:query_titles] - #user_username = params[:user_username] - query_descriptions = params[:query_descriptions] - logger.info 'param query_descriptions:' + query_descriptions.inspect - selected_queries = [] - if query_descriptions - parse_array(query_descriptions).each do |query_desc| - match_query = Query.find_by_description(query_desc) - if match_query - logger.info query_desc + ' matches: ' + match_query.inspect - selected_queries.push(match_query) - else - logger.info 'WARNING: ' + query_desc + ' has no match!' + username = params[:username] + current_user = User.find_by_username(username) + if current_user + query_descriptions = params[:query_descriptions] + logger.info 'param query_descriptions:' + query_descriptions.inspect + selected_queries = [] + if query_descriptions + parse_array(query_descriptions).each do |query_desc| + match_query = current_user.queries.find_by_description(query_desc) + if match_query + logger.info query_desc + ' matches: ' + match_query.inspect + selected_queries.push(match_query) + else + logger.info 'WARNING: ' + query_desc + ' has no match!' + end end end end diff --git a/app/models/query.rb b/app/models/query.rb index 252c18a..cec3ef0 100755 --- a/app/models/query.rb +++ b/app/models/query.rb @@ -83,5 +83,4 @@ def prettify_generated_function function return pretty_function end - end \ No newline at end of file diff --git a/test/functional/scheduled_jobs_controller_test.rb b/test/functional/scheduled_jobs_controller_test.rb index af83964..e514487 100644 --- a/test/functional/scheduled_jobs_controller_test.rb +++ b/test/functional/scheduled_jobs_controller_test.rb @@ -37,7 +37,7 @@ class ScheduledJobsControllerTest < ActionController::TestCase puts "endpoints: " + @endpoints_for_execution.inspect #STDERR.puts query_from_db.inspect - puts "DRUSK #{endpoint_ids}" + puts "ENDPOINT_IDS #{endpoint_ids}" puts "@ids[2]=" + @ids[2].inspect + " endpoint_ids=" + endpoint_ids.inspect post :batch_query, id: @ids[2], endpoint_ids: endpoint_ids, notification: false #query = assigns(:query) diff --git a/util/scheduled_job_post.py b/util/scheduled_job_post.py index c436d24..1ded6ee 100644 --- a/util/scheduled_job_post.py +++ b/util/scheduled_job_post.py @@ -2,7 +2,7 @@ import httplib, urllib params = urllib.urlencode({'@number': 12524, '@type': 'issue', '@action': 'show'}) -params = urllib.urlencode({"endpoint_names":["ep1","ep2", "ep3"],"query_descriptions":["desc1","desc2"]}) +params = urllib.urlencode({"endpoint_names":["ep1","ep2", "ep3"],"query_descriptions":["desc1","desc2"],"username":"stoppuser"}) headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"} conn = httplib.HTTPSConnection("localhost", 3002) From 6d2dd0b94adfa0e699983f6f1dc398228b7a6c7c Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Fri, 7 Aug 2015 15:09:56 -0700 Subject: [PATCH 098/117] Read parameters from file --- util/job_params.json | 12 ++++++++++++ util/scheduled_job_post.py | 20 ++++++++++++++------ 2 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 util/job_params.json mode change 100644 => 100755 util/scheduled_job_post.py diff --git a/util/job_params.json b/util/job_params.json new file mode 100644 index 0000000..2fe5394 --- /dev/null +++ b/util/job_params.json @@ -0,0 +1,12 @@ +{ + "username": "stoppuser", + "endpoint_names": [ + "ep1", + "ep2", + "ep3" + ], + "query_descriptions": [ + "desc1", + "desc2" + ] +} diff --git a/util/scheduled_job_post.py b/util/scheduled_job_post.py old mode 100644 new mode 100755 index 1ded6ee..073917c --- a/util/scheduled_job_post.py +++ b/util/scheduled_job_post.py @@ -1,12 +1,20 @@ +#!/usr/bin/env python __author__ = 'rrusk' -import httplib, urllib - -params = urllib.urlencode({'@number': 12524, '@type': 'issue', '@action': 'show'}) -params = urllib.urlencode({"endpoint_names":["ep1","ep2", "ep3"],"query_descriptions":["desc1","desc2"],"username":"stoppuser"}) +import sys +import httplib +import urllib +import json +if len(sys.argv) != 2: + print "The batch job parameter file must be specified as the sole argument" + print 'Usage: scheduled_job_post.py "job_params_file.json"' + exit(1) +with open(sys.argv[1], "r") as params_file: + params_json = json.load(params_file) +query_params = urllib.urlencode(params_json) headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"} conn = httplib.HTTPSConnection("localhost", 3002) -conn.request("POST", "/scheduled_jobs/batch_query", params, headers) +conn.request("POST", "/scheduled_jobs/batch_query", query_params, headers) response = conn.getresponse() print response.status, response.reason data = response.read() @@ -22,4 +30,4 @@ # r = requests.post(url, params=payload, verify=False) # print r.status_code # print "encoding: " + str(r.encoding) -# print r.text \ No newline at end of file +# print r.text From 4e98cd84cf290d3b18728ba56599dd92ea007f3b Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Mon, 10 Aug 2015 12:46:46 -0700 Subject: [PATCH 099/117] Allow more flexibility in strings describing endpoints and queries --- app/controllers/scheduled_jobs_controller.rb | 18 +++++++++++------- util/scheduled_job_post.py | 13 ++++++++++++- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/app/controllers/scheduled_jobs_controller.rb b/app/controllers/scheduled_jobs_controller.rb index c5adf9b..0778c59 100644 --- a/app/controllers/scheduled_jobs_controller.rb +++ b/app/controllers/scheduled_jobs_controller.rb @@ -5,7 +5,11 @@ class ScheduledJobsController < ActionController::Base creates_updates_destroys :query def parse_array(string) - string[1..-2].gsub!(/[^0-9A-Za-z,-]/, '').split(',') + parray = string[1..-2].gsub!(/[^0-9A-Za-z(), -]/, '').split(',') + parray.each do |element| + element.strip! + end + return parray end # Model constraints: @@ -35,14 +39,14 @@ def batch_query parse_array(endpoint_names).each do |endpoint_name| match_ep = Endpoint.find_by_name(endpoint_name) if match_ep - logger.info endpoint_name + ' matches: ' + match_ep.inspect + logger.info endpoint_name.to_s + ' matches: ' + match_ep[:name].inspect selected_endpoints.push(match_ep) else - logger.info 'WARNING: ' + endpoint_name + ' has no match!' + logger.info 'WARNING: ' + endpoint_name.to_s + ' has no match!' end end end - logger.info 'selected endpoings: ' + selected_endpoints.inspect + # logger.info 'selected endpoings: ' + selected_endpoints.inspect # users = User.all @@ -63,13 +67,13 @@ def batch_query current_user = User.find_by_username(username) if current_user query_descriptions = params[:query_descriptions] - logger.info 'param query_descriptions:' + query_descriptions.inspect + # logger.info 'param query_descriptions:' + query_descriptions.inspect selected_queries = [] if query_descriptions parse_array(query_descriptions).each do |query_desc| match_query = current_user.queries.find_by_description(query_desc) if match_query - logger.info query_desc + ' matches: ' + match_query.inspect + logger.info query_desc + ' matches: ' + match_query[:description].inspect selected_queries.push(match_query) else logger.info 'WARNING: ' + query_desc + ' has no match!' @@ -77,7 +81,7 @@ def batch_query end end end - logger.info 'selected queries: ' + selected_queries.inspect + # logger.info 'selected queries: ' + selected_queries.inspect if selected_endpoints && !selected_endpoints.empty? && selected_queries && !selected_queries.empty? diff --git a/util/scheduled_job_post.py b/util/scheduled_job_post.py index 073917c..a2fef89 100755 --- a/util/scheduled_job_post.py +++ b/util/scheduled_job_post.py @@ -4,13 +4,24 @@ import httplib import urllib import json + +def byteify(input): + if isinstance(input, dict): + return {byteify(key):byteify(value) for key,value in input.iteritems()} + elif isinstance(input, list): + return [byteify(element) for element in input] + elif isinstance(input, unicode): + return input.encode('utf-8') + else: + return input + if len(sys.argv) != 2: print "The batch job parameter file must be specified as the sole argument" print 'Usage: scheduled_job_post.py "job_params_file.json"' exit(1) with open(sys.argv[1], "r") as params_file: params_json = json.load(params_file) -query_params = urllib.urlencode(params_json) +query_params = urllib.urlencode(byteify(params_json)) headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"} conn = httplib.HTTPSConnection("localhost", 3002) From 508514e1da0843dc6772dc00e29e3a9437359b54 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Mon, 10 Aug 2015 15:25:06 -0700 Subject: [PATCH 100/117] Add parallel query execution --- app/controllers/scheduled_jobs_controller.rb | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/app/controllers/scheduled_jobs_controller.rb b/app/controllers/scheduled_jobs_controller.rb index 0778c59..ab6f46f 100644 --- a/app/controllers/scheduled_jobs_controller.rb +++ b/app/controllers/scheduled_jobs_controller.rb @@ -1,4 +1,6 @@ require 'cud_actions' +require 'parallel' + class ScheduledJobsController < ActionController::Base include CudActions @@ -86,11 +88,12 @@ def batch_query if selected_endpoints && !selected_endpoints.empty? && selected_queries && !selected_queries.empty? notify = params[:notification] - selected_queries.each do |eachQuery| + #selected_queries.each do |eachQuery| + Parallel.each(selected_queries, :in_threads=>15) do |eachQuery| # execute the query, and pass in the endpoints and if the user should be notified by email when execution completes - logger.info 'title: ' + eachQuery[:title].inspect - logger.info 'desc: ' + eachQuery[:description].inspect - logger.info 'user_id: ' + eachQuery[:user_id].inspect + # logger.info 'title: ' + eachQuery[:title].inspect + # logger.info 'desc: ' + eachQuery[:description].inspect + # logger.info 'user_id: ' + eachQuery[:user_id].inspect eachQuery.execute(selected_endpoints, notify) end else From 714bc567e0368aa134d2261ed1d8ca50772cfde4 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Tue, 25 Aug 2015 12:51:35 -0700 Subject: [PATCH 101/117] Parallel queries are not working properly --- app/controllers/scheduled_jobs_controller.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/scheduled_jobs_controller.rb b/app/controllers/scheduled_jobs_controller.rb index ab6f46f..508cf21 100644 --- a/app/controllers/scheduled_jobs_controller.rb +++ b/app/controllers/scheduled_jobs_controller.rb @@ -1,5 +1,5 @@ require 'cud_actions' -require 'parallel' +#require 'parallel' class ScheduledJobsController < ActionController::Base include CudActions @@ -88,8 +88,8 @@ def batch_query if selected_endpoints && !selected_endpoints.empty? && selected_queries && !selected_queries.empty? notify = params[:notification] - #selected_queries.each do |eachQuery| - Parallel.each(selected_queries, :in_threads=>15) do |eachQuery| + selected_queries.each do |eachQuery| + #Parallel.each(selected_queries, :in_threads=>15) do |eachQuery| # execute the query, and pass in the endpoints and if the user should be notified by email when execution completes # logger.info 'title: ' + eachQuery[:title].inspect # logger.info 'desc: ' + eachQuery[:description].inspect From 6cef57b008313afa2fbce65f9c525ba83d4ebfd6 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Tue, 15 Sep 2015 13:30:31 -0700 Subject: [PATCH 102/117] Add NRPE configuration used on hub --- .gitignore | 1 + .../check_service_pdc.template | 37 +++++++++++++++ nagios-nrpe-support/generate_plugins.sh | 45 +++++++++++++++++++ nagios-nrpe-support/nagios-nrpe-server.md | 8 ++++ nagios-nrpe-support/nrpe_command.template | 9 ++++ nagios-nrpe-support/nrpe_local_cfg.template | 42 +++++++++++++++++ 6 files changed, 142 insertions(+) create mode 100644 nagios-nrpe-support/check_service_pdc.template create mode 100755 nagios-nrpe-support/generate_plugins.sh create mode 100644 nagios-nrpe-support/nagios-nrpe-server.md create mode 100644 nagios-nrpe-support/nrpe_command.template create mode 100644 nagios-nrpe-support/nrpe_local_cfg.template diff --git a/.gitignore b/.gitignore index fe004b4..102456c 100755 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ spec/javascripts/generated/* log/ spec/generated .idea +nagios-nrpe-support/tmp/ diff --git a/nagios-nrpe-support/check_service_pdc.template b/nagios-nrpe-support/check_service_pdc.template new file mode 100644 index 0000000..4f7dec4 --- /dev/null +++ b/nagios-nrpe-support/check_service_pdc.template @@ -0,0 +1,37 @@ +#!/bin/bash +# Expect two lines of output from call to web server +URL="http://localhost:ep_port/sysinfo/ep_check" +TMPFILE=`/bin/tempfile` +CMD=`/usr/bin/curl -sSf $URL > $TMPFILE 2>&1` +STATUS=$? +if [ $STATUS -ne 0 ]; then + /bin/echo "UNKNOWN - For $URL got $(cat $TMPFILE)" + /bin/rm $TMPFILE + exit 3 +fi +# first line should be Nagios message +NAGIOSMSG=`/usr/bin/head -1 $TMPFILE` +# second line should be Nagios status code +STATUSSTR=`/bin/cat $TMPFILE | /usr/bin/head -2 | /usr/bin/tail -1` +/bin/rm $TMPFILE +NAGIOSSTATUS=-1 +if [ "$STATUSSTR" == "Status Code: 0" ]; then + NAGIOSSTATUS=0 +fi +if [ "$STATUSSTR" == "Status Code: 1" ]; then + NAGIOSSTATUS=1 +fi +if [ "$STATUSSTR" == "Status Code: 2" ]; then + NAGIOSSTATUS=2 +fi +if [ "$STATUSSTR" == "Status Code: 3" ]; then + NAGIOSSTATUS=3 +fi +if [ "$NAGIOSSTATUS" -ge 0 -a "$NAGIOSSTATUS" -le 3 ]; then + echo $NAGIOSMSG + exit $NAGIOSSTATUS +else + # shouldn't get here unless there was a completely unexpected response + /bin/echo "UNKNOWN - Unexpected response from \"$URL\". Return status $STATUS" + exit 3 +fi diff --git a/nagios-nrpe-support/generate_plugins.sh b/nagios-nrpe-support/generate_plugins.sh new file mode 100755 index 0000000..14afe78 --- /dev/null +++ b/nagios-nrpe-support/generate_plugins.sh @@ -0,0 +1,45 @@ +#!/bin/sh +# +generate_service_host_plugin() { + if [ ! -d ./tmp ]; then + /bin/mkdir tmp + fi + ep_name=`/usr/bin/expr 1000 + $1 | cut -d1 -f2-` + ep_port=`/usr/bin/expr 10300 + $1` + /bin/sed "s/ep_port/$ep_port/;s/ep_check/$2/" ./check_service_pdc.template > ./tmp/check_"$2"_"pdc$ep_name".sh + chmod +x ./tmp/check_"$2"_"pdc$ep_name".sh +} + +generate_nrpe_command() { + ep_name=`/usr/bin/expr 1000 + $1 | cut -d1 -f2-` + echo command[check_"$2"_"pdc$ep_name"]=/usr/local/lib/nagios/check_"$2"_"pdc$ep_name".sh +} + +generate_alive_command() { + ep_name=`/usr/bin/expr 1000 + $1 | cut -d1 -f2-` + ep_port=`/usr/bin/expr 10300 + $1` + echo "# pdc$ep_name checks" + echo command[check_alive_"pdc$ep_name"]=/usr/lib/nagios/plugins/check_http -I 127.0.0.1 -p $ep_port + echo command[check_tunnel_"pdc$ep_name"]=/usr/lib/nagios/plugins/check_http -H localhost -p $ep_port +} + +ep_ids="0 1 2 3 4 5 6 7 8 9 11" +ep_checks="diskspace import load processes swap tomcat users" + +cp ./nrpe_local_cfg.template ./nrpe_local.cfg + +echo "Plugins written into ./tmp. Move to /usr/local/lib/nagios once they" +echo "have been checked for correctness." +echo "NRPE commands written into ./nrpe_local.cfg. Use this to replace" +echo "/etc/nagios/nrpe_local.cfg after carefully checking correctness." +echo "Reload nrpe plugins using 'sudo service nagios-nrpe-server reload'" + +for id in $ep_ids +do + generate_alive_command $id >> ./nrpe_local.cfg + for check in $ep_checks + do + generate_service_host_plugin $id $check + generate_nrpe_command $id $check >> ./nrpe_local.cfg + done +done diff --git a/nagios-nrpe-support/nagios-nrpe-server.md b/nagios-nrpe-support/nagios-nrpe-server.md new file mode 100644 index 0000000..3fa92b0 --- /dev/null +++ b/nagios-nrpe-support/nagios-nrpe-server.md @@ -0,0 +1,8 @@ +The local configuration is stored in /etc/nagios/nagios_local.cnf to make +it easier to find non-default behaviour. + +Changes made to nagios_local.cnf do not take effect until nagios-nrpe-server is restarted or the following command is issued: + +$ sudo service nagios-nrpe-server reload + +The PDC specific command definitions execute plugins stored in /usr/local/lib/nagios. diff --git a/nagios-nrpe-support/nrpe_command.template b/nagios-nrpe-support/nrpe_command.template new file mode 100644 index 0000000..05e2c8d --- /dev/null +++ b/nagios-nrpe-support/nrpe_command.template @@ -0,0 +1,9 @@ +# pdc_epid checks +command[check_alive_pdc_epid]=/usr/lib/nagios/plugins/check_http -I 127.0.0.1 -p ep_port +command[check_diskspace_pdc_epid]=/usr/local/lib/nagios/check_diskspace_pdc_epid.sh +command[check_import_pdc_epid]=/usr/local/lib/nagios/check_import_pdc_epid.sh +command[check_load_pdc_epid]=/usr/local/lib/nagios/check_load_pdc_epid.sh +command[check_processes_pdc_epid]=/usr/local/lib/nagios/check_processes_pdc_epid.sh +command[check_swap_pdc_epid]=/usr/local/lib/nagios/check_swap_pdc_epid.sh +command[check_tomcat_pdc_epid]=/usr/local/lib/nagios/check_tomcat_pdc_epid.sh +command[check_users_pdc_epid]=/usr/local/lib/nagios/check_users_pdc_epid.sh diff --git a/nagios-nrpe-support/nrpe_local_cfg.template b/nagios-nrpe-support/nrpe_local_cfg.template new file mode 100644 index 0000000..f689d9c --- /dev/null +++ b/nagios-nrpe-support/nrpe_local_cfg.template @@ -0,0 +1,42 @@ +###################################### +# Do any local nrpe configuration here +###################################### +# +# ALLOWED HOST ADDRESSES +# This is an optional comma-delimited list of IP address or hostnames +# that are allowed to talk to the NRPE daemon. Network addresses with a bit mask +# (i.e. 192.168.1.0/24) are also supported. Hostname wildcards are not currently +# supported. +# +# Note: The daemon only does rudimentary checking of the client's IP +# address. I would highly recommend adding entries in your /etc/hosts.allow +# file to allow only the specified host to connect to the port +# you are running this daemon on. +# +# NOTE: This option is ignored if NRPE is running under either inetd or xinetd + +allowed_hosts=127.0.0.1,142.104.90.77 + +# COMMAND DEFINITIONS +# Command definitions that this daemon will run. Definitions +# are in the following format: +# +# command[]= +# +# When the daemon receives a request to return the results of +# it will execute the command specified by the argument. +# +# Unlike Nagios, the command line cannot contain macros - it must be +# typed exactly as it should be executed. +# +# Note: Any plugins that are used in the command lines must reside +# on the machine that this daemon is running on! The examples below +# assume that you have plugins installed in a /usr/local/lib/nagios +# directory. Also note that you will have to modify the definitions below +# to match the argument format the plugins expect. Remember, these are +# examples only! + +# The following commands use hardcoded arguments... + +command[check_all_disks]=/usr/lib/nagios/plugins/check_disk -w 20% -c 10% -e + From 408bd5b787f879fcebc5dc29270619046b0c1a34 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Tue, 15 Sep 2015 15:37:15 -0700 Subject: [PATCH 103/117] Make temporary files more recognizable. --- nagios-nrpe-support/check_service_pdc.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nagios-nrpe-support/check_service_pdc.template b/nagios-nrpe-support/check_service_pdc.template index 4f7dec4..3b645a7 100644 --- a/nagios-nrpe-support/check_service_pdc.template +++ b/nagios-nrpe-support/check_service_pdc.template @@ -1,7 +1,7 @@ #!/bin/bash # Expect two lines of output from call to web server URL="http://localhost:ep_port/sysinfo/ep_check" -TMPFILE=`/bin/tempfile` +TMPFILE=`/bin/tempfile -p_PDC_` CMD=`/usr/bin/curl -sSf $URL > $TMPFILE 2>&1` STATUS=$? if [ $STATUS -ne 0 ]; then From 1f6854ba780956c373c97297a7af8bb3fd2c667a Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Tue, 15 Sep 2015 16:11:09 -0700 Subject: [PATCH 104/117] Add Osler NRPE support --- nagios-nrpe-support/generate_plugins.sh | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/nagios-nrpe-support/generate_plugins.sh b/nagios-nrpe-support/generate_plugins.sh index 14afe78..20b3d0c 100755 --- a/nagios-nrpe-support/generate_plugins.sh +++ b/nagios-nrpe-support/generate_plugins.sh @@ -23,8 +23,10 @@ generate_alive_command() { echo command[check_tunnel_"pdc$ep_name"]=/usr/lib/nagios/plugins/check_http -H localhost -p $ep_port } -ep_ids="0 1 2 3 4 5 6 7 8 9 11" -ep_checks="diskspace import load processes swap tomcat users" +ep_ids_oscar="0 1 2 3 4 5 6 7 8 9 11" +ep_checks_oscar="diskspace import load processes swap tomcat users" +ep_ids_osler="50" +ep_checks_osler="diskspace load processes swap users" cp ./nrpe_local_cfg.template ./nrpe_local.cfg @@ -34,10 +36,21 @@ echo "NRPE commands written into ./nrpe_local.cfg. Use this to replace" echo "/etc/nagios/nrpe_local.cfg after carefully checking correctness." echo "Reload nrpe plugins using 'sudo service nagios-nrpe-server reload'" -for id in $ep_ids +# generate oscar configuration files +for id in $ep_ids_oscar do generate_alive_command $id >> ./nrpe_local.cfg - for check in $ep_checks + for check in $ep_checks_oscar + do + generate_service_host_plugin $id $check + generate_nrpe_command $id $check >> ./nrpe_local.cfg + done +done +# generate osler configuration files +for id in $ep_ids_osler +do + generate_alive_command $id >> ./nrpe_local.cfg + for check in $ep_checks_osler do generate_service_host_plugin $id $check generate_nrpe_command $id $check >> ./nrpe_local.cfg From a38e0177ede9f5ae03c35b12f77c9a7638098d77 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Wed, 16 Sep 2015 10:13:08 -0700 Subject: [PATCH 105/117] Improve script readability --- nagios-nrpe-support/generate_plugins.sh | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/nagios-nrpe-support/generate_plugins.sh b/nagios-nrpe-support/generate_plugins.sh index 20b3d0c..843366e 100755 --- a/nagios-nrpe-support/generate_plugins.sh +++ b/nagios-nrpe-support/generate_plugins.sh @@ -1,5 +1,13 @@ #!/bin/sh # +print_info() { + echo "Plugins written into ./tmp. Move to /usr/local/lib/nagios once they" + echo "have been checked for correctness." + echo "NRPE commands written into ./nrpe_local.cfg. Use this to replace" + echo "/etc/nagios/nrpe_local.cfg after carefully checking correctness." + echo "Reload nrpe plugins using 'sudo service nagios-nrpe-server reload'" +} + generate_service_host_plugin() { if [ ! -d ./tmp ]; then /bin/mkdir tmp @@ -30,13 +38,7 @@ ep_checks_osler="diskspace load processes swap users" cp ./nrpe_local_cfg.template ./nrpe_local.cfg -echo "Plugins written into ./tmp. Move to /usr/local/lib/nagios once they" -echo "have been checked for correctness." -echo "NRPE commands written into ./nrpe_local.cfg. Use this to replace" -echo "/etc/nagios/nrpe_local.cfg after carefully checking correctness." -echo "Reload nrpe plugins using 'sudo service nagios-nrpe-server reload'" - -# generate oscar configuration files +# generate oscar configuration and plugins for id in $ep_ids_oscar do generate_alive_command $id >> ./nrpe_local.cfg @@ -46,7 +48,7 @@ do generate_nrpe_command $id $check >> ./nrpe_local.cfg done done -# generate osler configuration files +# generate osler configuration and plugins for id in $ep_ids_osler do generate_alive_command $id >> ./nrpe_local.cfg @@ -56,3 +58,5 @@ do generate_nrpe_command $id $check >> ./nrpe_local.cfg done done + +print_info From 45e6b6a2c6e8b7ba2115aab3d43d691e124f621d Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Thu, 17 Sep 2015 09:33:14 -0700 Subject: [PATCH 106/117] Work in progress on nagios3 configuration script --- .../generate_nagios3_config.sh | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100755 nagios-nrpe-support/generate_nagios3_config.sh diff --git a/nagios-nrpe-support/generate_nagios3_config.sh b/nagios-nrpe-support/generate_nagios3_config.sh new file mode 100755 index 0000000..7180b10 --- /dev/null +++ b/nagios-nrpe-support/generate_nagios3_config.sh @@ -0,0 +1,105 @@ +#!/bin/sh +# +service_description() { + if [ "diskspace" = $1 ]; then + echo " service_description Disk Space" + elif [ "import" = $1 ]; then + echo " service_description Current E2E Import" + elif [ "load" = $1 ]; then + echo " service_description Current Load" + elif [ "processes" = $1 ]; then + echo " service_description Total Processes" + elif [ "swap" = $1 ]; then + echo " service_description Swap Usage" + elif [ "tomcat" = $1 ]; then + echo " service_description Tomcat Process" + elif [ "users" = $1 ]; then + echo " service_description Current Users" + else + echo $2 + fi +} + +generate_host_definition() { + ep_name=`/usr/bin/expr 1000 + $1 | cut -d1 -f2-` + echo "define host {" + echo " use noping-host" + echo " host_name pdc$ep_name" + echo " check_command check_alive_pdc$ep_name" + echo "}" + echo +} + +generate_host_service_definition() { + ep_name=`/usr/bin/expr 1000 + $1 | cut -d1 -f2-` + echo "define service {" + echo " use generic-service" + echo " host_name pdc$ep_name" + service_description $2 + echo " check_command $2_pdc$ep_name" + echo "}" + echo +} + +print_info() { + echo "Plugins written into ./tmp. Move to /usr/local/lib/nagios once they" + echo "have been checked for correctness." + echo "NRPE commands written into ./nrpe_local.cfg. Use this to replace" + echo "/etc/nagios/nrpe_local.cfg after carefully checking correctness." + echo "Reload nrpe plugins using 'sudo service nagios-nrpe-server reload'" +} + +generate_service_host_plugin() { + if [ ! -d ./tmp ]; then + /bin/mkdir tmp + fi + ep_name=`/usr/bin/expr 1000 + $1 | cut -d1 -f2-` + ep_port=`/usr/bin/expr 10300 + $1` + /bin/sed "s/ep_port/$ep_port/;s/ep_check/$2/" ./check_service_pdc.template > ./tmp/check_"$2"_"pdc$ep_name".sh + chmod +x ./tmp/check_"$2"_"pdc$ep_name".sh +} + +generate_nrpe_command() { + ep_name=`/usr/bin/expr 1000 + $1 | cut -d1 -f2-` + echo command[check_"$2"_"pdc$ep_name"]=/usr/local/lib/nagios/check_"$2"_"pdc$ep_name".sh +} + +generate_alive_command() { + ep_name=`/usr/bin/expr 1000 + $1 | cut -d1 -f2-` + ep_port=`/usr/bin/expr 10300 + $1` + echo "# pdc$ep_name checks" + echo command[check_alive_"pdc$ep_name"]=/usr/lib/nagios/plugins/check_http -I 127.0.0.1 -p $ep_port + echo command[check_tunnel_"pdc$ep_name"]=/usr/lib/nagios/plugins/check_http -H localhost -p $ep_port +} + +ep_ids_oscar="0 1 2 3 4 5 6 7 8 9 11" +ep_checks_oscar="diskspace import load processes swap tomcat users" +ep_ids_osler="50" +ep_checks_osler="diskspace load processes swap users" + +cp ./nrpe_local_cfg.template ./nrpe_local.cfg + +# generate oscar configuration and plugins +for id in $ep_ids_oscar +do + generate_host_definition $id + generate_alive_command $id >> ./nrpe_local.cfg + for check in $ep_checks_oscar + do + generate_host_service_definition $id $check + generate_service_host_plugin $id $check + generate_nrpe_command $id $check >> ./nrpe_local.cfg + done +done +# generate osler configuration and plugins +for id in $ep_ids_osler +do + generate_alive_command $id >> ./nrpe_local.cfg + for check in $ep_checks_osler + do + generate_service_host_plugin $id $check + generate_nrpe_command $id $check >> ./nrpe_local.cfg + done +done + +print_info From cf60a6bb595072880ec57e1cd134007160e8a095 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Thu, 17 Sep 2015 13:24:44 -0700 Subject: [PATCH 107/117] Generates /etc/nagios3/commands.cfg --- nagios-nrpe-support/commands_cfg.prefix | 50 +++++++++++++++++++ .../generate_nagios3_config.sh | 50 +++++++++++++------ nagios-nrpe-support/generate_plugins.sh | 2 +- ...cal_cfg.template => nrpe_local_cfg.prefix} | 0 4 files changed, 87 insertions(+), 15 deletions(-) create mode 100644 nagios-nrpe-support/commands_cfg.prefix rename nagios-nrpe-support/{nrpe_local_cfg.template => nrpe_local_cfg.prefix} (100%) diff --git a/nagios-nrpe-support/commands_cfg.prefix b/nagios-nrpe-support/commands_cfg.prefix new file mode 100644 index 0000000..e2cabf1 --- /dev/null +++ b/nagios-nrpe-support/commands_cfg.prefix @@ -0,0 +1,50 @@ +############################################################################### +# COMMANDS.CFG - SAMPLE COMMAND DEFINITIONS FOR NAGIOS +############################################################################### + + +################################################################################ +# NOTIFICATION COMMANDS +################################################################################ + + +# 'notify-host-by-email' command definition +define command{ + command_name notify-host-by-email + command_line /usr/bin/printf "%b" "***** Nagios *****\n\nNotification Type: $NOTIFICATIONTYPE$\nHost: $HOSTNAME$\nState: $HOSTSTATE$\nAddress: $HOSTADDRESS$\nInfo: $HOSTOUTPUT$\n\nDate/Time: $LONGDATETIME$\n" | /usr/bin/mail -s "** $NOTIFICATIONTYPE$ Host Alert: $HOSTNAME$ is $HOSTSTATE$ **" $CONTACTEMAIL$ + } + +# 'notify-service-by-email' command definition +define command{ + command_name notify-service-by-email + command_line /usr/bin/printf "%b" "***** Nagios *****\n\nNotification Type: $NOTIFICATIONTYPE$\n\nService: $SERVICEDESC$\nHost: $HOSTALIAS$\nAddress: $HOSTADDRESS$\nState: $SERVICESTATE$\n\nDate/Time: $LONGDATETIME$\n\nAdditional Info:\n\n$SERVICEOUTPUT$\n" | /usr/bin/mail -s "** $NOTIFICATIONTYPE$ Service Alert: $HOSTALIAS$/$SERVICEDESC$ is $SERVICESTATE$ **" $CONTACTEMAIL$ + } + + + + + +################################################################################ +# HOST CHECK COMMANDS +################################################################################ + +# On Debian, check-host-alive is being defined from within the +# nagios-plugins-basic package + +################################################################################ +# PERFORMANCE DATA COMMANDS +################################################################################ + + +# 'process-host-perfdata' command definition +define command{ + command_name process-host-perfdata + command_line /usr/bin/printf "%b" "$LASTHOSTCHECK$\t$HOSTNAME$\t$HOSTSTATE$\t$HOSTATTEMPT$\t$HOSTSTATETYPE$\t$HOSTEXECUTIONTIME$\t$HOSTOUTPUT$\t$HOSTPERFDATA$\n" >> /var/lib/nagios3/host-perfdata.out + } + + +# 'process-service-perfdata' command definition +define command{ + command_name process-service-perfdata + command_line /usr/bin/printf "%b" "$LASTSERVICECHECK$\t$HOSTNAME$\t$SERVICEDESC$\t$SERVICESTATE$\t$SERVICEATTEMPT$\t$SERVICESTATETYPE$\t$SERVICEEXECUTIONTIME$\t$SERVICELATENCY$\t$SERVICEOUTPUT$\t$SERVICEPERFDATA$\n" >> /var/lib/nagios3/service-perfdata.out + } diff --git a/nagios-nrpe-support/generate_nagios3_config.sh b/nagios-nrpe-support/generate_nagios3_config.sh index 7180b10..849ce64 100755 --- a/nagios-nrpe-support/generate_nagios3_config.sh +++ b/nagios-nrpe-support/generate_nagios3_config.sh @@ -1,5 +1,13 @@ #!/bin/sh # +print_info() { + echo "Plugins written into ./tmp. Move to /usr/local/lib/nagios once they" + echo "have been checked for correctness." + echo "NRPE commands written into ./nrpe_local.cfg. Use this to replace" + echo "/etc/nagios/nrpe_local.cfg after carefully checking correctness." + echo "Reload nrpe plugins using 'sudo service nagios-nrpe-server reload'" +} + service_description() { if [ "diskspace" = $1 ]; then echo " service_description Disk Space" @@ -22,12 +30,13 @@ service_description() { generate_host_definition() { ep_name=`/usr/bin/expr 1000 + $1 | cut -d1 -f2-` + echo + echo "# commands to check endpoint pdc-$ep_name" echo "define host {" echo " use noping-host" echo " host_name pdc$ep_name" echo " check_command check_alive_pdc$ep_name" echo "}" - echo } generate_host_service_definition() { @@ -38,15 +47,23 @@ generate_host_service_definition() { service_description $2 echo " check_command $2_pdc$ep_name" echo "}" - echo } -print_info() { - echo "Plugins written into ./tmp. Move to /usr/local/lib/nagios once they" - echo "have been checked for correctness." - echo "NRPE commands written into ./nrpe_local.cfg. Use this to replace" - echo "/etc/nagios/nrpe_local.cfg after carefully checking correctness." - echo "Reload nrpe plugins using 'sudo service nagios-nrpe-server reload'" +generate_nagios_command_definition() { + ep_name=`/usr/bin/expr 1000 + $1 | cut -d1 -f2-` + if [ "alive" = "$2" ]; then + echo + echo "# commands to check endpoint pdc-$ep_name" + echo "define command{" + echo " command_name check_$2_pdc$ep_name" + echo " command_line \$USER1\$/check_nrpe -H 142.104.90.75 -c check_$2_pdc$ep_name" + echo "}" + else + echo "define command{" + echo " command_name $2_pdc$ep_name" + echo " command_line \$USER1\$/check_nrpe -H 142.104.90.75 -c check_$2_pdc$ep_name" + echo "}" + fi } generate_service_host_plugin() { @@ -74,30 +91,35 @@ generate_alive_command() { ep_ids_oscar="0 1 2 3 4 5 6 7 8 9 11" ep_checks_oscar="diskspace import load processes swap tomcat users" -ep_ids_osler="50" +ep_ids_osler="" ep_checks_osler="diskspace load processes swap users" -cp ./nrpe_local_cfg.template ./nrpe_local.cfg +cp ./nrpe_local_cfg.prefix ./nrpe_local.cfg +cp ./commands_cfg.prefix ./commands.cfg # generate oscar configuration and plugins for id in $ep_ids_oscar do - generate_host_definition $id + #generate_host_definition $id >> ./commands.cfg + generate_nagios_command_definition $id "alive" >> ./commands.cfg generate_alive_command $id >> ./nrpe_local.cfg for check in $ep_checks_oscar do - generate_host_service_definition $id $check - generate_service_host_plugin $id $check + generate_nagios_command_definition $id $check >> ./commands.cfg + generate_service_host_plugin $id $check # writes file directly generate_nrpe_command $id $check >> ./nrpe_local.cfg done done # generate osler configuration and plugins for id in $ep_ids_osler do + #generate_host_definition $id >> ./commands.cfg + generate_nagios_command_definition $id "alive" >> ./commands.cfg generate_alive_command $id >> ./nrpe_local.cfg for check in $ep_checks_osler do - generate_service_host_plugin $id $check + generate_nagios_command_definition $id $check >> ./commands.cfg + generate_service_host_plugin $id $check # writes file directly generate_nrpe_command $id $check >> ./nrpe_local.cfg done done diff --git a/nagios-nrpe-support/generate_plugins.sh b/nagios-nrpe-support/generate_plugins.sh index 843366e..a9078bd 100755 --- a/nagios-nrpe-support/generate_plugins.sh +++ b/nagios-nrpe-support/generate_plugins.sh @@ -36,7 +36,7 @@ ep_checks_oscar="diskspace import load processes swap tomcat users" ep_ids_osler="50" ep_checks_osler="diskspace load processes swap users" -cp ./nrpe_local_cfg.template ./nrpe_local.cfg +cp ./nrpe_local_cfg.prefix ./nrpe_local.cfg # generate oscar configuration and plugins for id in $ep_ids_oscar diff --git a/nagios-nrpe-support/nrpe_local_cfg.template b/nagios-nrpe-support/nrpe_local_cfg.prefix similarity index 100% rename from nagios-nrpe-support/nrpe_local_cfg.template rename to nagios-nrpe-support/nrpe_local_cfg.prefix From 7968e213f4e7e7bf1d935504e4ad356888cb6c0a Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Thu, 17 Sep 2015 15:03:51 -0700 Subject: [PATCH 108/117] Reorganize nagios support directory --- .../check_service_pdc.template | 0 .../commands_cfg.prefix | 0 .../generate_nagios3_config.sh | 10 +++++----- .../generate_plugins.sh | 0 .../nagios-nrpe-server.md | 0 .../nrpe_command.template | 0 .../nrpe_local_cfg.prefix | 0 7 files changed, 5 insertions(+), 5 deletions(-) rename {nagios-nrpe-support => monitoring}/check_service_pdc.template (100%) rename {nagios-nrpe-support => monitoring}/commands_cfg.prefix (100%) rename {nagios-nrpe-support => monitoring}/generate_nagios3_config.sh (92%) rename {nagios-nrpe-support => monitoring}/generate_plugins.sh (100%) rename {nagios-nrpe-support => monitoring}/nagios-nrpe-server.md (100%) rename {nagios-nrpe-support => monitoring}/nrpe_command.template (100%) rename {nagios-nrpe-support => monitoring}/nrpe_local_cfg.prefix (100%) diff --git a/nagios-nrpe-support/check_service_pdc.template b/monitoring/check_service_pdc.template similarity index 100% rename from nagios-nrpe-support/check_service_pdc.template rename to monitoring/check_service_pdc.template diff --git a/nagios-nrpe-support/commands_cfg.prefix b/monitoring/commands_cfg.prefix similarity index 100% rename from nagios-nrpe-support/commands_cfg.prefix rename to monitoring/commands_cfg.prefix diff --git a/nagios-nrpe-support/generate_nagios3_config.sh b/monitoring/generate_nagios3_config.sh similarity index 92% rename from nagios-nrpe-support/generate_nagios3_config.sh rename to monitoring/generate_nagios3_config.sh index 849ce64..b193eb4 100755 --- a/nagios-nrpe-support/generate_nagios3_config.sh +++ b/monitoring/generate_nagios3_config.sh @@ -1,7 +1,7 @@ #!/bin/sh # print_info() { - echo "Plugins written into ./tmp. Move to /usr/local/lib/nagios once they" + echo "Plugins written into ./nagios-nrpe-server-config. Move to /usr/local/lib/nagios once they" echo "have been checked for correctness." echo "NRPE commands written into ./nrpe_local.cfg. Use this to replace" echo "/etc/nagios/nrpe_local.cfg after carefully checking correctness." @@ -67,13 +67,13 @@ generate_nagios_command_definition() { } generate_service_host_plugin() { - if [ ! -d ./tmp ]; then - /bin/mkdir tmp + if [ ! -d ./nagios-nrpe-server-config ]; then + /bin/mkdir nagios-nrpe-server-config fi ep_name=`/usr/bin/expr 1000 + $1 | cut -d1 -f2-` ep_port=`/usr/bin/expr 10300 + $1` - /bin/sed "s/ep_port/$ep_port/;s/ep_check/$2/" ./check_service_pdc.template > ./tmp/check_"$2"_"pdc$ep_name".sh - chmod +x ./tmp/check_"$2"_"pdc$ep_name".sh + /bin/sed "s/ep_port/$ep_port/;s/ep_check/$2/" ./check_service_pdc.template > ./nagios-nrpe-server-config/check_"$2"_"pdc$ep_name".sh + chmod +x ./nagios-nrpe-server-config/check_"$2"_"pdc$ep_name".sh } generate_nrpe_command() { diff --git a/nagios-nrpe-support/generate_plugins.sh b/monitoring/generate_plugins.sh similarity index 100% rename from nagios-nrpe-support/generate_plugins.sh rename to monitoring/generate_plugins.sh diff --git a/nagios-nrpe-support/nagios-nrpe-server.md b/monitoring/nagios-nrpe-server.md similarity index 100% rename from nagios-nrpe-support/nagios-nrpe-server.md rename to monitoring/nagios-nrpe-server.md diff --git a/nagios-nrpe-support/nrpe_command.template b/monitoring/nrpe_command.template similarity index 100% rename from nagios-nrpe-support/nrpe_command.template rename to monitoring/nrpe_command.template diff --git a/nagios-nrpe-support/nrpe_local_cfg.prefix b/monitoring/nrpe_local_cfg.prefix similarity index 100% rename from nagios-nrpe-support/nrpe_local_cfg.prefix rename to monitoring/nrpe_local_cfg.prefix From a5f780f2198893b414675262cc3a96bf1e4e8d02 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Thu, 17 Sep 2015 16:26:44 -0700 Subject: [PATCH 109/117] More re-organization of Nagios config --- .gitignore | 4 +- monitoring/generate_nagios3_config.sh | 73 ++++++++++++++------------- 2 files changed, 42 insertions(+), 35 deletions(-) diff --git a/.gitignore b/.gitignore index 102456c..98109f1 100755 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,6 @@ spec/javascripts/generated/* log/ spec/generated .idea -nagios-nrpe-support/tmp/ +monitoring/nagios-config/ +monitoring/nagios-nrpe-server-config/ +generate_nagios3_config.sh~ diff --git a/monitoring/generate_nagios3_config.sh b/monitoring/generate_nagios3_config.sh index b193eb4..f83a2ac 100755 --- a/monitoring/generate_nagios3_config.sh +++ b/monitoring/generate_nagios3_config.sh @@ -1,13 +1,23 @@ #!/bin/sh # +# Endpoint ids (Oscar and Osler specified separately) +ep_ids_oscar="0 1 2 3 4 5 6 7 8 9 11" +ep_checks_oscar="diskspace import load processes swap tomcat users" +ep_ids_osler="" +ep_checks_osler="diskspace load processes swap users" + print_info() { - echo "Plugins written into ./nagios-nrpe-server-config. Move to /usr/local/lib/nagios once they" - echo "have been checked for correctness." - echo "NRPE commands written into ./nrpe_local.cfg. Use this to replace" - echo "/etc/nagios/nrpe_local.cfg after carefully checking correctness." - echo "Reload nrpe plugins using 'sudo service nagios-nrpe-server reload'" + echo "Hub monitoring configuration:" + echo "NRPE commands written into ./nagios-nrpe-server-config/nrpe_local.cfg." + echo "Use this to replace /etc/nagios/nrpe_local.cfg after carefully checking correctness." + echo "Called plugins written into ./nagios-nrpe-server-config/plugins." + echo "Move to /usr/local/lib/nagios once they have been checked for correctness." + echo "Reload nrpe configuration using 'sudo service nagios-nrpe-server reload'" } +/bin/rm -rf nagios-config && /bin/mkdir -p nagios-config +/bin/rm -rf nagios-nrpe-server-config && /bin/mkdir -p nagios-nrpe-server-config/plugins + service_description() { if [ "diskspace" = $1 ]; then echo " service_description Disk Space" @@ -29,7 +39,7 @@ service_description() { } generate_host_definition() { - ep_name=`/usr/bin/expr 1000 + $1 | cut -d1 -f2-` + ep_name=$1 echo echo "# commands to check endpoint pdc-$ep_name" echo "define host {" @@ -40,7 +50,7 @@ generate_host_definition() { } generate_host_service_definition() { - ep_name=`/usr/bin/expr 1000 + $1 | cut -d1 -f2-` + ep_name=$1 echo "define service {" echo " use generic-service" echo " host_name pdc$ep_name" @@ -50,7 +60,7 @@ generate_host_service_definition() { } generate_nagios_command_definition() { - ep_name=`/usr/bin/expr 1000 + $1 | cut -d1 -f2-` + ep_name=$1 if [ "alive" = "$2" ]; then echo echo "# commands to check endpoint pdc-$ep_name" @@ -67,60 +77,55 @@ generate_nagios_command_definition() { } generate_service_host_plugin() { - if [ ! -d ./nagios-nrpe-server-config ]; then - /bin/mkdir nagios-nrpe-server-config - fi - ep_name=`/usr/bin/expr 1000 + $1 | cut -d1 -f2-` + ep_name=$1 ep_port=`/usr/bin/expr 10300 + $1` - /bin/sed "s/ep_port/$ep_port/;s/ep_check/$2/" ./check_service_pdc.template > ./nagios-nrpe-server-config/check_"$2"_"pdc$ep_name".sh - chmod +x ./nagios-nrpe-server-config/check_"$2"_"pdc$ep_name".sh + /bin/sed "s/ep_port/$ep_port/;s/ep_check/$2/" ./check_service_pdc.template > ./nagios-nrpe-server-config/plugins/check_"$2"_"pdc$ep_name".sh + chmod +x ./nagios-nrpe-server-config/plugins/check_"$2"_"pdc$ep_name".sh } generate_nrpe_command() { - ep_name=`/usr/bin/expr 1000 + $1 | cut -d1 -f2-` + ep_name=$1 echo command[check_"$2"_"pdc$ep_name"]=/usr/local/lib/nagios/check_"$2"_"pdc$ep_name".sh } generate_alive_command() { - ep_name=`/usr/bin/expr 1000 + $1 | cut -d1 -f2-` + ep_name=$1 ep_port=`/usr/bin/expr 10300 + $1` echo "# pdc$ep_name checks" echo command[check_alive_"pdc$ep_name"]=/usr/lib/nagios/plugins/check_http -I 127.0.0.1 -p $ep_port echo command[check_tunnel_"pdc$ep_name"]=/usr/lib/nagios/plugins/check_http -H localhost -p $ep_port } -ep_ids_oscar="0 1 2 3 4 5 6 7 8 9 11" -ep_checks_oscar="diskspace import load processes swap tomcat users" -ep_ids_osler="" -ep_checks_osler="diskspace load processes swap users" -cp ./nrpe_local_cfg.prefix ./nrpe_local.cfg -cp ./commands_cfg.prefix ./commands.cfg +cp ./nrpe_local_cfg.prefix ./nagios-nrpe-server-config/nrpe_local.cfg +cp ./commands_cfg.prefix ./nagios-config/commands.cfg # generate oscar configuration and plugins for id in $ep_ids_oscar do - #generate_host_definition $id >> ./commands.cfg - generate_nagios_command_definition $id "alive" >> ./commands.cfg - generate_alive_command $id >> ./nrpe_local.cfg + #generate_host_definition $id >> .//nagios-config/commands.cfg + ep_name=`/usr/bin/expr 1000 + $id | cut -d1 -f2-` + generate_nagios_command_definition $ep_name "alive" >> ./nagios-config/commands.cfg + generate_alive_command $ep_name >> ./nagios-nrpe-server-config/nrpe_local.cfg for check in $ep_checks_oscar do - generate_nagios_command_definition $id $check >> ./commands.cfg - generate_service_host_plugin $id $check # writes file directly - generate_nrpe_command $id $check >> ./nrpe_local.cfg + generate_nagios_command_definition $ep_name $check >> ./nagios-config/commands.cfg + generate_service_host_plugin $ep_name $check # writes file directly + generate_nrpe_command $ep_name $check >> ./nagios-nrpe-server-config/nrpe_local.cfg done done # generate osler configuration and plugins for id in $ep_ids_osler do - #generate_host_definition $id >> ./commands.cfg - generate_nagios_command_definition $id "alive" >> ./commands.cfg - generate_alive_command $id >> ./nrpe_local.cfg + #generate_host_definition $id >> .//nagios-config/commands.cfg + ep_name=`/usr/bin/expr 1000 + $id | cut -d1 -f2-` + generate_nagios_command_definition $ep_name "alive" >> ./nagios-config/commands.cfg + generate_alive_command $ep_name >> ./nagios-nrpe-server-config/nrpe_local.cfg for check in $ep_checks_osler do - generate_nagios_command_definition $id $check >> ./commands.cfg - generate_service_host_plugin $id $check # writes file directly - generate_nrpe_command $id $check >> ./nrpe_local.cfg + generate_nagios_command_definition $ep_name $check >> ./nagios-config/commands.cfg + generate_service_host_plugin $ep_name $check # writes file directly + generate_nrpe_command $ep_name $check >> ./nagios-nrpe-server-config/nrpe_local.cfg done done From 93637a3e4f0e9a15d1fff3f4ea0dcd70d1dd55ed Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Fri, 18 Sep 2015 14:53:29 -0700 Subject: [PATCH 110/117] Generates Nagios configuration and hub NRPE server configuration --- monitoring/generate_nagios3_config.sh | 161 ++++++++++++++++++-------- monitoring/generate_plugins.sh | 62 ---------- 2 files changed, 115 insertions(+), 108 deletions(-) delete mode 100755 monitoring/generate_plugins.sh diff --git a/monitoring/generate_nagios3_config.sh b/monitoring/generate_nagios3_config.sh index f83a2ac..4f63392 100755 --- a/monitoring/generate_nagios3_config.sh +++ b/monitoring/generate_nagios3_config.sh @@ -1,23 +1,51 @@ #!/bin/sh # -# Endpoint ids (Oscar and Osler specified separately) +# Endpoint ids and corresponding checks (Oscar) ep_ids_oscar="0 1 2 3 4 5 6 7 8 9 11" ep_checks_oscar="diskspace import load processes swap tomcat users" -ep_ids_osler="" +# Endpoint ids and corresponding checks (Osler) +ep_ids_osler="50" ep_checks_osler="diskspace load processes swap users" print_info() { - echo "Hub monitoring configuration:" - echo "NRPE commands written into ./nagios-nrpe-server-config/nrpe_local.cfg." - echo "Use this to replace /etc/nagios/nrpe_local.cfg after carefully checking correctness." - echo "Called plugins written into ./nagios-nrpe-server-config/plugins." - echo "Move to /usr/local/lib/nagios once they have been checked for correctness." - echo "Reload nrpe configuration using 'sudo service nagios-nrpe-server reload'" + echo + echo "Hub NRPE server monitoring configuration:" + echo "----------------------------" + echo "WARNING: Don't change any NRPE command or plugin that the Nagios host" + echo "expects to find present on the NRPE server while Nagios is running." + echo "Otherwise, there is likely to be a flood of alerts." + echo "NRPE commands are written into ./nagios-nrpe-server-config/nrpe_local.cfg." + echo "Use this to replace /etc/nagios/nrpe_local.cfg after checking correctness." + echo "The plugins are written into ./nagios-nrpe-server-config/plugins. Move the" + echo "plugins to /usr/local/lib/nagios once they have been checked for correctness." + echo "Reload nrpe configuration on the hub using" + echo " 'sudo service nagios-nrpe-server reload'" + echo + echo "Nagios host configuration:" + echo "-------------------------" + echo "Nagios commands are written into ./nagios-config/commands.cfg." + echo "They should be verified carefully and then copied to" + echo "/etc/nagios3/commands.cfg on the Nagios host." + echo "Endpoint specific Nagios configuration files are in" + echo "./nagios-config/conf.d/pdc-XXX.cfg. They should be" + echo "verifed carefully and then copied to /etc/nagios3/conf.d/." + echo "The generated Nagios configuration should then be checked using" + echo " '/usr/sbin/nagios3 -v /etc/nagios3/nagios.cfg'" + echo "If there are no errors or warnings, it should be safe to execute" + echo " 'sudo service nagios3 restart'" + echo } -/bin/rm -rf nagios-config && /bin/mkdir -p nagios-config +# remove and rebuild Nagios configuration and hub NRPE server configuration +/bin/rm -rf nagios-config && /bin/mkdir -p nagios-config/conf.d /bin/rm -rf nagios-nrpe-server-config && /bin/mkdir -p nagios-nrpe-server-config/plugins +# The function service_description provides a description of +# the service defined in configuration files named +# /etc/nagios3/conf.d/pdc-XXX.cfg on the Nagios host. +# The description is used to provide a informative label +# for the service check on the Nagios services web page. +# Requires one input parameter specifying the service check. service_description() { if [ "diskspace" = $1 ]; then echo " service_description Disk Space" @@ -38,62 +66,99 @@ service_description() { fi } +generate_endpoint_header() { + echo "# Custom services specific to this host are added here, but services" + echo "# defined in nagios2-common_services.cfg may also apply." + echo +} + +# The function generate_host_definition provides the host definition +# in the configuration files /etc/nagios3/conf.d/pdc-XXX.cfg on the +# Nagios host. +# Requires one input parameter specifying the host id generate_host_definition() { - ep_name=$1 + ep_id=$1 echo - echo "# commands to check endpoint pdc-$ep_name" + echo "# commands to check endpoint pdc-$ep_id" echo "define host {" echo " use noping-host" - echo " host_name pdc$ep_name" - echo " check_command check_alive_pdc$ep_name" + echo " host_name pdc-$ep_id" + echo " check_command check_alive_pdc$ep_id" echo "}" } +# The function generate_host_service_definition provides the service +# definition in the configuration files /etc/nagios3/conf.d/pdc-XXX.cfg on +# the Nagios host. +# Requires two input parameters specifying the host id and service checked. generate_host_service_definition() { - ep_name=$1 + ep_id=$1 echo "define service {" - echo " use generic-service" - echo " host_name pdc$ep_name" + if [ "tomcat" = $2 ]; then + echo " use importhours-service,generic-service" + else + echo " use generic-service" + fi + echo " host_name pdc-$ep_id" service_description $2 - echo " check_command $2_pdc$ep_name" + echo " check_command $2_pdc$ep_id" echo "}" } +# The function generate_nagios_command_definition specifies +# the host commands in /etc/nagios3/commands.cfg on the Nagios host. +# Requires two input parameters specifying the host id and the +# service that nagios is checking. The check_alive service +# is special because it determines whether the query-gateway +# is responding to http requests at the endpoint. When it +# doesn't respond the host endpoint is considered DOWN. generate_nagios_command_definition() { - ep_name=$1 + ep_id=$1 if [ "alive" = "$2" ]; then echo - echo "# commands to check endpoint pdc-$ep_name" + echo "# commands to check endpoint pdc-$ep_id" echo "define command{" - echo " command_name check_$2_pdc$ep_name" - echo " command_line \$USER1\$/check_nrpe -H 142.104.90.75 -c check_$2_pdc$ep_name" + echo " command_name check_alive_pdc$ep_id" + echo " command_line \$USER1\$/check_nrpe -H 142.104.90.75 -c check_alive_pdc$ep_id" echo "}" else echo "define command{" - echo " command_name $2_pdc$ep_name" - echo " command_line \$USER1\$/check_nrpe -H 142.104.90.75 -c check_$2_pdc$ep_name" + echo " command_name $2_pdc$ep_id" + echo " command_line \$USER1\$/check_nrpe -H 142.104.90.75 -c check_$2_pdc$ep_id" echo "}" fi } +# The function generate_service_host_plugin generates the +# endpoint service plugin called by the NRPE server on the hub. +# The plugins are kept in /usr/local/lib/nagios on the hub. +# Requires two input parameters, the endpoint id and the +# endpoint service being checked. generate_service_host_plugin() { - ep_name=$1 + ep_id=$1 ep_port=`/usr/bin/expr 10300 + $1` - /bin/sed "s/ep_port/$ep_port/;s/ep_check/$2/" ./check_service_pdc.template > ./nagios-nrpe-server-config/plugins/check_"$2"_"pdc$ep_name".sh - chmod +x ./nagios-nrpe-server-config/plugins/check_"$2"_"pdc$ep_name".sh + /bin/sed "s/ep_port/$ep_port/;s/ep_check/$2/" ./check_service_pdc.template > ./nagios-nrpe-server-config/plugins/check_"$2"_"pdc$ep_id".sh + chmod +x ./nagios-nrpe-server-config/plugins/check_"$2"_"pdc$ep_id".sh } +# The function generate_nrpe_command specifies commands that the +# NRPE server can execute on the hub with the add of plugins. +# Requires two input parameters, the endpoint id and the +# endpoint service being checked. generate_nrpe_command() { - ep_name=$1 - echo command[check_"$2"_"pdc$ep_name"]=/usr/local/lib/nagios/check_"$2"_"pdc$ep_name".sh + ep_id=$1 + echo command[check_"$2"_"pdc$ep_id"]=/usr/local/lib/nagios/check_"$2"_"pdc$ep_id".sh } +# The function generate_alive_command specifies the commands that the NRPE server can +# execute on the hub using check_http to determine whether the query-gateway is running +# at an endpoint. +# Requires one input parameter specifying the endpoint id. generate_alive_command() { - ep_name=$1 + ep_id=$1 ep_port=`/usr/bin/expr 10300 + $1` - echo "# pdc$ep_name checks" - echo command[check_alive_"pdc$ep_name"]=/usr/lib/nagios/plugins/check_http -I 127.0.0.1 -p $ep_port - echo command[check_tunnel_"pdc$ep_name"]=/usr/lib/nagios/plugins/check_http -H localhost -p $ep_port + echo "# pdc$ep_id checks" + echo command[check_alive_"pdc$ep_id"]=/usr/lib/nagios/plugins/check_http -I 127.0.0.1 -p $ep_port } @@ -103,29 +168,33 @@ cp ./commands_cfg.prefix ./nagios-config/commands.cfg # generate oscar configuration and plugins for id in $ep_ids_oscar do - #generate_host_definition $id >> .//nagios-config/commands.cfg - ep_name=`/usr/bin/expr 1000 + $id | cut -d1 -f2-` - generate_nagios_command_definition $ep_name "alive" >> ./nagios-config/commands.cfg - generate_alive_command $ep_name >> ./nagios-nrpe-server-config/nrpe_local.cfg + ep_id=`/usr/bin/expr 1000 + $id | cut -d1 -f2-` + generate_endpoint_header > ./nagios-config/conf.d/pdc-$ep_id.cfg + generate_host_definition $ep_id >> ./nagios-config/conf.d/pdc-$ep_id.cfg + generate_nagios_command_definition $ep_id "alive" >> ./nagios-config/commands.cfg + generate_alive_command $ep_id >> ./nagios-nrpe-server-config/nrpe_local.cfg for check in $ep_checks_oscar do - generate_nagios_command_definition $ep_name $check >> ./nagios-config/commands.cfg - generate_service_host_plugin $ep_name $check # writes file directly - generate_nrpe_command $ep_name $check >> ./nagios-nrpe-server-config/nrpe_local.cfg + generate_host_service_definition $ep_id $check >> ./nagios-config/conf.d/pdc-$ep_id.cfg + generate_nagios_command_definition $ep_id $check >> ./nagios-config/commands.cfg + generate_service_host_plugin $ep_id $check # writes file directly + generate_nrpe_command $ep_id $check >> ./nagios-nrpe-server-config/nrpe_local.cfg done done # generate osler configuration and plugins for id in $ep_ids_osler do - #generate_host_definition $id >> .//nagios-config/commands.cfg - ep_name=`/usr/bin/expr 1000 + $id | cut -d1 -f2-` - generate_nagios_command_definition $ep_name "alive" >> ./nagios-config/commands.cfg - generate_alive_command $ep_name >> ./nagios-nrpe-server-config/nrpe_local.cfg + ep_id=`/usr/bin/expr 1000 + $id | cut -d1 -f2-` + generate_endpoint_header > ./nagios-config/conf.d/pdc-$ep_id.cfg + generate_host_definition $ep_id >> ./nagios-config/conf.d/pdc-$ep_id.cfg + generate_nagios_command_definition $ep_id "alive" >> ./nagios-config/commands.cfg + generate_alive_command $ep_id >> ./nagios-nrpe-server-config/nrpe_local.cfg for check in $ep_checks_osler do - generate_nagios_command_definition $ep_name $check >> ./nagios-config/commands.cfg - generate_service_host_plugin $ep_name $check # writes file directly - generate_nrpe_command $ep_name $check >> ./nagios-nrpe-server-config/nrpe_local.cfg + generate_host_service_definition $ep_id $check >> ./nagios-config/conf.d/pdc-$ep_id.cfg + generate_nagios_command_definition $ep_id $check >> ./nagios-config/commands.cfg + generate_service_host_plugin $ep_id $check # writes file directly + generate_nrpe_command $ep_id $check >> ./nagios-nrpe-server-config/nrpe_local.cfg done done diff --git a/monitoring/generate_plugins.sh b/monitoring/generate_plugins.sh deleted file mode 100755 index a9078bd..0000000 --- a/monitoring/generate_plugins.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/sh -# -print_info() { - echo "Plugins written into ./tmp. Move to /usr/local/lib/nagios once they" - echo "have been checked for correctness." - echo "NRPE commands written into ./nrpe_local.cfg. Use this to replace" - echo "/etc/nagios/nrpe_local.cfg after carefully checking correctness." - echo "Reload nrpe plugins using 'sudo service nagios-nrpe-server reload'" -} - -generate_service_host_plugin() { - if [ ! -d ./tmp ]; then - /bin/mkdir tmp - fi - ep_name=`/usr/bin/expr 1000 + $1 | cut -d1 -f2-` - ep_port=`/usr/bin/expr 10300 + $1` - /bin/sed "s/ep_port/$ep_port/;s/ep_check/$2/" ./check_service_pdc.template > ./tmp/check_"$2"_"pdc$ep_name".sh - chmod +x ./tmp/check_"$2"_"pdc$ep_name".sh -} - -generate_nrpe_command() { - ep_name=`/usr/bin/expr 1000 + $1 | cut -d1 -f2-` - echo command[check_"$2"_"pdc$ep_name"]=/usr/local/lib/nagios/check_"$2"_"pdc$ep_name".sh -} - -generate_alive_command() { - ep_name=`/usr/bin/expr 1000 + $1 | cut -d1 -f2-` - ep_port=`/usr/bin/expr 10300 + $1` - echo "# pdc$ep_name checks" - echo command[check_alive_"pdc$ep_name"]=/usr/lib/nagios/plugins/check_http -I 127.0.0.1 -p $ep_port - echo command[check_tunnel_"pdc$ep_name"]=/usr/lib/nagios/plugins/check_http -H localhost -p $ep_port -} - -ep_ids_oscar="0 1 2 3 4 5 6 7 8 9 11" -ep_checks_oscar="diskspace import load processes swap tomcat users" -ep_ids_osler="50" -ep_checks_osler="diskspace load processes swap users" - -cp ./nrpe_local_cfg.prefix ./nrpe_local.cfg - -# generate oscar configuration and plugins -for id in $ep_ids_oscar -do - generate_alive_command $id >> ./nrpe_local.cfg - for check in $ep_checks_oscar - do - generate_service_host_plugin $id $check - generate_nrpe_command $id $check >> ./nrpe_local.cfg - done -done -# generate osler configuration and plugins -for id in $ep_ids_osler -do - generate_alive_command $id >> ./nrpe_local.cfg - for check in $ep_checks_osler - do - generate_service_host_plugin $id $check - generate_nrpe_command $id $check >> ./nrpe_local.cfg - done -done - -print_info From 0b8b38f7317eed47c47f22aa518067f32816bf00 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Fri, 18 Sep 2015 15:23:11 -0700 Subject: [PATCH 111/117] Support for checking correctness of generated files --- monitoring/generate_nagios3_config.sh | 2 ++ monitoring/verify_nagios.sh | 19 +++++++++++++++++++ monitoring/verify_nrpe.sh | 15 +++++++++++++++ 3 files changed, 36 insertions(+) create mode 100755 monitoring/verify_nagios.sh create mode 100755 monitoring/verify_nrpe.sh diff --git a/monitoring/generate_nagios3_config.sh b/monitoring/generate_nagios3_config.sh index 4f63392..8bf5d69 100755 --- a/monitoring/generate_nagios3_config.sh +++ b/monitoring/generate_nagios3_config.sh @@ -18,6 +18,7 @@ print_info() { echo "Use this to replace /etc/nagios/nrpe_local.cfg after checking correctness." echo "The plugins are written into ./nagios-nrpe-server-config/plugins. Move the" echo "plugins to /usr/local/lib/nagios once they have been checked for correctness." + echo "The script verify_nrpe.sh will assist in checking the generated files." echo "Reload nrpe configuration on the hub using" echo " 'sudo service nagios-nrpe-server reload'" echo @@ -29,6 +30,7 @@ print_info() { echo "Endpoint specific Nagios configuration files are in" echo "./nagios-config/conf.d/pdc-XXX.cfg. They should be" echo "verifed carefully and then copied to /etc/nagios3/conf.d/." + echo "The script verify_nagios.sh will assist in checking the generated files." echo "The generated Nagios configuration should then be checked using" echo " '/usr/sbin/nagios3 -v /etc/nagios3/nagios.cfg'" echo "If there are no errors or warnings, it should be safe to execute" diff --git a/monitoring/verify_nagios.sh b/monitoring/verify_nagios.sh new file mode 100755 index 0000000..5c81dc2 --- /dev/null +++ b/monitoring/verify_nagios.sh @@ -0,0 +1,19 @@ +#!/bin/sh +set -e +cd nagios-config +echo "Differencing generated commands.cfg and /etc/nagios3/commands.cfg" +echo "Begin diff..." +diff -bB commands.cfg /etc/nagios3/commands.cfg +echo "End diff" +cd conf.d +echo "Differencing generated endpoint specific configuration and those in" +echo "/etc/nagios3/conf.d/pdc-XXX.cfg" +echo "Begin diffs..." +for i in * ; do diff -bB $i /etc/nagios3/conf.d/$i ; done +echo "End diffs" +echo "If all the differences shown are expected it should be safe to copy" +echo "the generated files into their proper location and then to execute" +echo " /usr/sbin/nagios3 -v /etc/nagios3/nagios.cfg" +echo "If there are no errors or warnings restart Nagios with the new" +echo "configuration by executing" +echo " sudo service nagios restart" diff --git a/monitoring/verify_nrpe.sh b/monitoring/verify_nrpe.sh new file mode 100755 index 0000000..3c67750 --- /dev/null +++ b/monitoring/verify_nrpe.sh @@ -0,0 +1,15 @@ +#!/bin/sh +set -e +cd nagios-nrpe-server-config +echo "Differencing generated nrpe_local.cfg and /etc/nagios/nrpe_local.cfg" +echo "Begin diff..." +diff -bB nrpe_local.cfg /etc/nagios/nrpe_local.cfg +echo "End diff" +cd plugins +echo "Differencing generated plugins and those in /usr/local/lib/nagios/" +echo "Begin diffs..." +for i in * ; do diff -bB $i /usr/local/lib/nagios/$i ; done +echo "End diffs" +echo "If all the differences shown are expected it should be safe to copy" +echo "the generated files into their proper location and then to execute" +echo " sudo service nagios-nrpe-server reload" From a0fae5543e00424ce6c4fc1ae2752008685b55be Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Fri, 18 Sep 2015 15:25:34 -0700 Subject: [PATCH 112/117] Don't exit on verification errors --- monitoring/verify_nagios.sh | 1 - monitoring/verify_nrpe.sh | 1 - 2 files changed, 2 deletions(-) diff --git a/monitoring/verify_nagios.sh b/monitoring/verify_nagios.sh index 5c81dc2..b42baec 100755 --- a/monitoring/verify_nagios.sh +++ b/monitoring/verify_nagios.sh @@ -1,5 +1,4 @@ #!/bin/sh -set -e cd nagios-config echo "Differencing generated commands.cfg and /etc/nagios3/commands.cfg" echo "Begin diff..." diff --git a/monitoring/verify_nrpe.sh b/monitoring/verify_nrpe.sh index 3c67750..113f237 100755 --- a/monitoring/verify_nrpe.sh +++ b/monitoring/verify_nrpe.sh @@ -1,5 +1,4 @@ #!/bin/sh -set -e cd nagios-nrpe-server-config echo "Differencing generated nrpe_local.cfg and /etc/nagios/nrpe_local.cfg" echo "Begin diff..." From a7ce0f84e2f7738ca9a09332f19ce42c2db8aa50 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Fri, 18 Sep 2015 15:29:41 -0700 Subject: [PATCH 113/117] Remove non-existing endpoint from Nagios configuration --- monitoring/generate_nagios3_config.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monitoring/generate_nagios3_config.sh b/monitoring/generate_nagios3_config.sh index 8bf5d69..a97e8e5 100755 --- a/monitoring/generate_nagios3_config.sh +++ b/monitoring/generate_nagios3_config.sh @@ -4,7 +4,7 @@ ep_ids_oscar="0 1 2 3 4 5 6 7 8 9 11" ep_checks_oscar="diskspace import load processes swap tomcat users" # Endpoint ids and corresponding checks (Osler) -ep_ids_osler="50" +ep_ids_osler="" ep_checks_osler="diskspace load processes swap users" print_info() { From 3f41c7efa36f06c64a409ff45ec3b47071d86ff3 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Fri, 18 Sep 2015 15:34:54 -0700 Subject: [PATCH 114/117] Fix name of service --- monitoring/verify_nagios.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monitoring/verify_nagios.sh b/monitoring/verify_nagios.sh index b42baec..331608a 100755 --- a/monitoring/verify_nagios.sh +++ b/monitoring/verify_nagios.sh @@ -15,4 +15,4 @@ echo "the generated files into their proper location and then to execute" echo " /usr/sbin/nagios3 -v /etc/nagios3/nagios.cfg" echo "If there are no errors or warnings restart Nagios with the new" echo "configuration by executing" -echo " sudo service nagios restart" +echo " sudo service nagios3 restart" From 6cba6c209f77b41a8cbf2c8e8cfaccee4b9892c2 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Fri, 18 Sep 2015 15:38:44 -0700 Subject: [PATCH 115/117] Documentation for PDC monitoring using Nagios --- monitoring/README-nagios.md | 134 ++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 monitoring/README-nagios.md diff --git a/monitoring/README-nagios.md b/monitoring/README-nagios.md new file mode 100644 index 0000000..89ea770 --- /dev/null +++ b/monitoring/README-nagios.md @@ -0,0 +1,134 @@ +This README documents local Nagios configuration modifications used to monitor the PDC network. When a new endpoint is added, items 3 and 7 need to be reviewed. + +1. Updates required in /etc/nagios3/conf.d/contacts_nagios2.cfg + +a) Add the following contact information +define contact{ + contact_name derek + alias derek + service_notification_period 24x7 + host_notification_period 24x7 + service_notification_options w,u,c,r + host_notification_options d,r + service_notification_commands notify-service-by-email + host_notification_commands notify-host-by-email + email derek.roberts@gmail.com + } + +define contact{ + contact_name fieran + alias fieran + service_notification_period 24x7 + host_notification_period 24x7 + service_notification_options w,u,c,r + host_notification_options d,r + service_notification_commands notify-service-by-email + host_notification_commands notify-host-by-email + email fieranmason@gmail.com + } + +define contact{ + contact_name simon + alias simon + service_notification_period 24x7 + host_notification_period 24x7 + service_notification_options w,u,c,r + host_notification_options d,r + service_notification_commands notify-service-by-email + host_notification_commands notify-host-by-email + email simon.diemert@gmail.com + } + +b) Modify the members entry of the admins contactgroup in /etc/nagios3/conf.d/contacts_nagios2.cfg to: + members fieran,simon,derek + + +2. Add file /etc/nagios3/conf.d/noping-host.cfg. This file is exactly the same as /etc/nagios3/conf.d/generic-host_nagios2.cfg except that the line with check_command is commented out: + +Change line: + check_command check-host-alive +to: + ;check_command check-host-alive + +The normal check-host-alive command uses ping but the endpoint servers are behind a firewall so they do not respond to ping. Instead, each endpoint has an entry similar to the following: + +define host{ + use noping-host + host_name pdc-nnn + check_command check_alive_pdcnnn + } + +The check_alive_pdcnnn uses the Nagios plugin check_http to determine whether the endpoint's query-gateway is responding to http requests. If it is, then the endpoint is considered UP. + +3. Each endpoint will have a configuration file similar to /etc/nagios3/conf.d/pdc-nnn.cfg with one "define host" entry like that described above and multiple "define service" commands. These configuration files are auto-generated. + +4. Create a configuration file for the hub by copying /etc/nagios3/conf.d/localhost_nagios2.cfg to pdchub.cfg. Replace all references to localhost with the DNS name of the hub, for instance pdchub.uvic.ca, and replace the localhost IP address of 127.0.0.1 with the correct IP address for the PDC hub. This step is not necessary if Nagios runs on the same host as the hub software. + +5. Add to /etc/nagios3/conf.d/timeperiods_nagios2.cfg the following timeperiod definition. This entry is needed because Tomcat will not run on the Oscar endpoints during times when the Oscar database is being reloaded with the most recent MySQL dump available. +-------------(start)------------- +# Period when Tomcat server on Oscar EMR endpoints should be running +define timeperiod{ + timeperiod_name importhours + alias E2E Import Hours + sunday 09:30-22:00 + monday 09:30-22:00 + tuesday 09:30-22:00 + wednesday 09:30-22:00 + thursday 09:30-22:00 + friday 09:30-22:00 + saturday 09:30-22:00 + } +-------------( end )------------- + +6. Add to /etc/nagios3/conf.d/services_nagios2.cfg the following: +-------------(start)------------- +# generic service for Tomcat checks ("use importhours-service,generic-service") +define service { + name importhours-service + check_period importhours + register 0 +} +-------------( end )------------- + +7. Append to /etc/nagios3/commands.cfg the commands used for host and service checks. They are autogenerated and will have the general form: + +# commands to check endpoint pdc-NNN +define command{ + command_name check_alive_pdcNNN + command_line $USER1$/check_nrpe -H 142.104.90.75 -c check_alive_pdcNNN +} + +define command{ + command_name diskspace_pdcNNN + command_line $USER1$/check_nrpe -H 142.104.90.75 -c check_diskspace_pdcNNN +} + +define command{ + command_name import_pdcNNN + command_line $USER1$/check_nrpe -H 142.104.90.75 -c check_import_pdcNNN +} + +define command{ + command_name load_pdcNNN + command_line $USER1$/check_nrpe -H 142.104.90.75 -c check_load_pdcNNN +} + +define command{ + command_name processes_pdcNNN + command_line $USER1$/check_nrpe -H 142.104.90.75 -c check_processes_pdcNNN +} + +define command{ + command_name swap_pdcNNN + command_line $USER1$/check_nrpe -H 142.104.90.75 -c check_swap_pdcNNN +} + +define command{ + command_name tomcat_pdcNNN + command_line $USER1$/check_nrpe -H 142.104.90.75 -c check_tomcat_pdcNNN +} + +define command{ + command_name users_pdcNNN + command_line $USER1$/check_nrpe -H 142.104.90.75 -c check_users_pdcNNN +} From 77762eba0bb00fc105ee6019353b7171e9d44f75 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Fri, 18 Sep 2015 15:39:52 -0700 Subject: [PATCH 116/117] Disable markdown --- monitoring/{README-nagios.md => README-nagios.txt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename monitoring/{README-nagios.md => README-nagios.txt} (100%) diff --git a/monitoring/README-nagios.md b/monitoring/README-nagios.txt similarity index 100% rename from monitoring/README-nagios.md rename to monitoring/README-nagios.txt From d0b7f4af3d4f409c6ab8b8cb19c065a2727ef0e3 Mon Sep 17 00:00:00 2001 From: Raymond Rusk Date: Fri, 18 Sep 2015 15:41:35 -0700 Subject: [PATCH 117/117] Shorten lines in README --- monitoring/README-nagios.txt | 43 ++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/monitoring/README-nagios.txt b/monitoring/README-nagios.txt index 89ea770..97d0fd6 100644 --- a/monitoring/README-nagios.txt +++ b/monitoring/README-nagios.txt @@ -1,4 +1,6 @@ -This README documents local Nagios configuration modifications used to monitor the PDC network. When a new endpoint is added, items 3 and 7 need to be reviewed. +This README documents local Nagios configuration modifications used to +monitor the PDC network. When a new endpoint is added, items 3 and 7 +need to be reviewed. 1. Updates required in /etc/nagios3/conf.d/contacts_nagios2.cfg @@ -39,18 +41,24 @@ define contact{ email simon.diemert@gmail.com } -b) Modify the members entry of the admins contactgroup in /etc/nagios3/conf.d/contacts_nagios2.cfg to: +b) Modify the members entry of the admins contactgroup in +/etc/nagios3/conf.d/contacts_nagios2.cfg to: + members fieran,simon,derek -2. Add file /etc/nagios3/conf.d/noping-host.cfg. This file is exactly the same as /etc/nagios3/conf.d/generic-host_nagios2.cfg except that the line with check_command is commented out: +2. Add file /etc/nagios3/conf.d/noping-host.cfg. This file is exactly +the same as /etc/nagios3/conf.d/generic-host_nagios2.cfg except that +the line with check_command is commented out: Change line: check_command check-host-alive to: ;check_command check-host-alive -The normal check-host-alive command uses ping but the endpoint servers are behind a firewall so they do not respond to ping. Instead, each endpoint has an entry similar to the following: +The normal check-host-alive command uses ping but the endpoint servers +are behind a firewall so they do not respond to ping. Instead, each +endpoint has an entry similar to the following: define host{ use noping-host @@ -58,13 +66,27 @@ define host{ check_command check_alive_pdcnnn } -The check_alive_pdcnnn uses the Nagios plugin check_http to determine whether the endpoint's query-gateway is responding to http requests. If it is, then the endpoint is considered UP. +The check_alive_pdcnnn uses the Nagios plugin check_http to determine +whether the endpoint's query-gateway is responding to http requests. +If it is, then the endpoint is considered UP. + +3. Each endpoint will have a configuration file similar to +/etc/nagios3/conf.d/pdc-nnn.cfg with one "define host" entry like that +described above and multiple "define service" commands. These +configuration files are auto-generated. -3. Each endpoint will have a configuration file similar to /etc/nagios3/conf.d/pdc-nnn.cfg with one "define host" entry like that described above and multiple "define service" commands. These configuration files are auto-generated. +4. Create a configuration file for the hub by copying +/etc/nagios3/conf.d/localhost_nagios2.cfg to pdchub.cfg. Replace all +references to localhost with the DNS name of the hub, for instance +pdchub.uvic.ca, and replace the localhost IP address of 127.0.0.1 with +the correct IP address for the PDC hub. This step is not necessary if +Nagios runs on the same host as the hub software. -4. Create a configuration file for the hub by copying /etc/nagios3/conf.d/localhost_nagios2.cfg to pdchub.cfg. Replace all references to localhost with the DNS name of the hub, for instance pdchub.uvic.ca, and replace the localhost IP address of 127.0.0.1 with the correct IP address for the PDC hub. This step is not necessary if Nagios runs on the same host as the hub software. +5. Add to /etc/nagios3/conf.d/timeperiods_nagios2.cfg the following +timeperiod definition. This entry is needed because Tomcat will not +run on the Oscar endpoints during times when the Oscar database is +being reloaded with the most recent MySQL dump available. -5. Add to /etc/nagios3/conf.d/timeperiods_nagios2.cfg the following timeperiod definition. This entry is needed because Tomcat will not run on the Oscar endpoints during times when the Oscar database is being reloaded with the most recent MySQL dump available. -------------(start)------------- # Period when Tomcat server on Oscar EMR endpoints should be running define timeperiod{ @@ -81,6 +103,7 @@ define timeperiod{ -------------( end )------------- 6. Add to /etc/nagios3/conf.d/services_nagios2.cfg the following: + -------------(start)------------- # generic service for Tomcat checks ("use importhours-service,generic-service") define service { @@ -90,7 +113,9 @@ define service { } -------------( end )------------- -7. Append to /etc/nagios3/commands.cfg the commands used for host and service checks. They are autogenerated and will have the general form: +7. Append to /etc/nagios3/commands.cfg the commands used for host and +service checks. They are autogenerated and will have the general +form: # commands to check endpoint pdc-NNN define command{