{
  "instance_id": "250eb624-f68339e3",
  "hostname": "skyspark.kw-engineering.com",
  "dis": "kW Prod Server",
  "override_count": 5,
  "overrides": [
    {
      "name": "pointQueryLookup",
      "pod": "kwLinkCoreExt",
      "pod_src": "(target: null, opts: {}) => do\n  cipherText :\n    \"AxD:J7ik5GzASro65uWVIxMkAg::7cPS7lsTZSH5N2vG2V_-JnF7WnnW0YzEzAkoWuWN0t33cekbuST1\" +\n    \"jdwUtsnrnsWKnY2ZJ11FgjHRBw-4DchwEYWtNDzsPhtoG9qIeWzimhGiuRu1zA5WRrk0313ancLuQXcH\" +\n    \"zUsoSr9-_gDRNSvmhd8jJ8XaV0eozzR7scJJx801Sxs1lYKqn9-efJgMoGE5yUdio-ucRJMKwXCuww-J\" +\n    \"b8TqM0LRciBpX_qgy9sWW83-toyx1g1E6NXoPfuyE4EB_DXdpr3CmMSWscawuIAE3KH2FmPCMCU8ihr3\" +\n    \"tr_mcJm1MYsEo96AokjwJZusgH38mbnKrRoCf8NHPHr0pfCbgMSC-bF-D68vIgcs7pkROhkb8dHHy0Yb\" +\n    \"BGZHrQwecGLFxh3jego2SM4MSQxMksgcXyMChH17bY10l6VEqvIczPolCB66sNO2bVrCc5FWAFPGXxtr\" +\n    \"m_T7E__lMU78LEPWLfO1UMWE_FLJtlEAQbuv_xhB4jUy4kyqpWCjuwNLkCrYY7sWHzyE90-Ys6SJzJLF\" +\n    \"INz9kBTIPWsbbjDHx0satQxguftZqyzoAjtoNJvymRdqyVTMTH2kLe1zoF_fI7afvDstxdp_YJ1Snx8y\" +\n    \"b3DLsnyLYJmKX7M8z4og1VWfRq6MdK-OCyjnRkLCO8Yv2ieCKWXBBbt7b5H7sVq8aZe-QHMINJW9XJQa\" +\n    \"AnOn9ePqiMWZoCfUbSB_dpwe89a9xMwOB_Ndj9gW8AoXEiK2uUgBEN_p4zcjOmNOJemXpluU-yQDFqJ3\" +\n    \"bZKgktkwNLUwrhYAYsp8Rg12CkGeXqx5hEEhEeXaUZisO7OKUHC9iFpi0CXbKbIB7bQc5kmWXCQNOKpk\" +\n    \"WJX_EPBrGrlmKXXseMsPuT78bkNoPxGbYxGwE4cSIfDqE0wkZOpILvuYXWkc5_jIdwuNsHSNLMXtEG2W\" +\n    \"NZ2dCBXpdFS7pFE5KrdkkydqepBBHgcCia5uNWcm1Sm9MuqqhjSK3R2r8D8VxPAJNIP-B05znD5pcUt8\" +\n    \"H-XKlS1RIkPpOpT3_0o_ieo7Dk2A51Ta4aSMsV1dkCGA78aq6mSF6oBYWefmW2FGYsmJjl0_KhJ30cuM\" +\n    \"-VLV1Tm58wPWB4gk-VTLLCCYqcu2eiH2XOMA5h2A0Jqm8nAp0-VH8rIvsgcdXV7OyBp7RThiFhmXrczT\" +\n    \"9UjSq1fDGg5ss22R-nyAlL6Cy9lFNgAwJXhhZGyoeEmKAnTju_Eszm8fkclrd66V2OG8Oumqyo_uLyAT\" +\n    \"WaOvw-a_AV8IniBRcJsnpdMFFuoGLKQ_IeAojF82KpVG0sB7Q9SR5iOJOCgu1zOfjmbJJuRiKt_5lvlX\" +\n    \"vjjxxHEwjXF_f-PFNDclHEwLpjwPm0u3Vln7BaLW0nbWkRsC8_GugIUsI0JIOZXfv7gCowIcqWPqFl2k\" +\n    \"AQTXjulVkhATkjviOkhCRzRpJgBt_4vjZzIPZKnJZqEq1aIDDCk8TxIBlABWT2Secx_B7z6vXxM6sKJO\" +\n    \"nThHzuHjlsJYDXrMEq1NVYtIz6HOv86FEksDz8zR7cCtSfQE2z-PMEeIBL0g5g4k5lDduU0ltFQDamy8\" +\n    \"jGokPxsAKgmYeqtWlvQDFircTDaUEURdVC0t0aRmXAOHIlhqYslE5vMmXfaZyB8tY8XC-QO4RwKRNOsA\" +\n    \"Ii_lUujsAX-uRZib_Qj79SArzhQVKHalYEglFumjDyOfjftf0dAqW7Lm3RzLBPnSAP5drZMTfCqr_keo\" +\n    \"qCRPNnnsdgVhHpauC4oI3UwJJ3cnm6wK1qCQzw3LQTapoht77RJRHPZ0uepNmuxAENkXf0tm_ViUbsSj\" +\n    \"6EFCV5CDWQqH3aXWIdkiCAU4A0RkucCfFULcqINf2dfBkY3R9167QcyyhIIR335dIg-Jn2S3Ms2TuOiJ\" +\n    \"mVIx3ht7V091uCY6UWCmpIKebvMwnDubPnelivQ9tAwKnC2jR4eo_SppqT981sI61cG0tmud_TU6lwIW\" +\n    \"KoCXkm74hOIIw-JtB0zwfMXU1joh9m0_aPdw2FHyn4IhZVKpLeLYGlq8LtA_f723YpAqGzUM3VdjBqBq\" +\n    \"evHqr-YL5X8Rq5CdMndKEk5xKgy7a9tabPjmQINlDJvPOh69qnCXU0EjY9YJkJAfVBM0-QUw2ENrkk8X\" +\n    \"0Jnerfrdo-jFmA4UGKQlRooB3WU2zRbzNHpUOlUhdr1PGvwaKFeZBVgD8mKPorQ9M9fpbfvLv94j4u0a\" +\n    \"vGuJnHS8fIEIIttwkptkl6dZY5VJPirMexsQ8x9h7WlmoJc5KmkWxBQhDvM3Ct_MUx1rZJNrOLNi4Ie5\" +\n    \"Js_rUphBPRUBvsZoHHP6a7BkoGVK1Jkkz94oVE3S43QHcwxLRg7LerPwKMIfnnNynQDm7IE0n7FJ6I1J\" +\n    \"SrIJnQ0Lw2TrKHGF3LxRqJPpnzxYXyk__AlFTONjPxdh5D5GWbOXxupbq2XetLrtcbPlXiVhewejzhdo\" +\n    \"9AAHINpe-THmsGMM0YgSq6TGY-nbox6NZfQIV7lFpKfbhb4-vRv6CTcrSo2nPxcPPJklUYDX8AK7h4L2\" +\n    \"Hmc6n3T-BFv3rttrQnM2kmSPKZ2CzO3cMuLCOIdgoO12BVTnhT6Q46g5gwL6YSdsuOcRR1lpko7AMUmv\" +\n    \"KYDmI_qQ3gpToK2m2VtjzmpdQwQPsHEoGZ3KCv3FE37x64gVBjFjkcJuOj8PL87x2xJVivML5GYLopia\" +\n    \"u6glIJnSB-lRUd_NZZanFi05MKqaD37mr4thZHmNgUbyKKJceApVRwPQnH5JXZ-hIdOkErcKotzzFSXH\" +\n    \"QElnlHMJwPqlMH-_7FC2pKOgpjeIZTaAZtI5yubMlvRu6xEYYZMVWjko6C0w6JGAztBsbGGih-cp9UgZ\" +\n    \"vqVdxZpueTfDpepAdIPFNYl5GthaQfyzfldAD2a16HgTl7_RGNKkecRQEq_KUr6iX9Q1PyvswN4LSN6v\" +\n    \"AMgI8Uimcz0ZFZ2GT9AV8rWnSSLxTq-QIMjbJORY3LwDzKOG9IOs4T-5ZAuGoaDwmNklXTxUyPrCAGgT\" +\n    \"koFLAbO8hgV3OIuAMAjOFf77vsgFVzsQhSCAx9uDKsowXuxTnwwfkWn60jPoeZFW_D_IMw_SUil3b73h\" +\n    \"XvVU9TzYdYzAldUUSs8c9T32w_EqTx3dAFeq_UZenGz-Hpb0UvrdWaG4Nak31iEDMWgEaa6A5m7DVrCp\" +\n    \"Ep95i5hgSxW_A9piXVMf0yuX0nS2pUk9I156QvkqM_nqLi0KeHTdObLNxq40FWgvzE8yh-1xYXkUOS9C\" +\n    \"x2pkdEnzNWPzvKEIUPKyaNS6rDKHi4OW2Z20UHi9G08mrHfFWV-tv59bisy7pJA5Gaa2sB7GFqUqyh5X\" +\n    \"mLu9Vy98861yGdSVdKybEmwLrOgz20N63ie0ACuRk6UVaQaFgQX5ZZFBKSO19gsqiNxAGTPucd-9-K8y\" +\n    \"cBtQJ3bJgjboXjjQ7J-ehZxYvVJI-88Rsst_hnmgLUlmqwcZEtOVPuZEl7PjecfjB_2TzH0YQcW1BfWZ\" +\n    \"kr7fT7nwjf-Ow_za4spUGPe2BVMsG8wxDTvVwzzP8Qs-CrExhKiqxD7vImKOyel2BXU79lSJ80EFZJpV\" +\n    \"AmWma5DPsQHQGWxHVYCSe4MBvKBFvu0nE2P3YohFlxU4eR4FDC9ELCSuzy3O-FPmIDZNlb5H-CxKSDf-\" +\n    \"x7RL9sAPVduoRyKm30xnjUh61B2MOlORwB4buvAMVFIqURU86jNv6UqSUjHK_JigaLN9FDz-QJfUT72e\" +\n    \"XX10CJiRvdf9MNPOQ6UZ3scFY0OgFNW6g6BCs3u_wrRvljuvkFI5LYLENV1XGLKLjjmBufV3vfjSql3f\" +\n    \"ihfVGCGjXRLXgutD5lSZpGbSF05Clf1JxfSUJCq1rP4V_3GzXMwZD9AB7_Z3loOAkeRAmsjGndYKW833\" +\n    \"DbR_zGnFc6EoVlDvHScL_l1UYF-piWIb9IOUZ5WdGc0LDiOfSIj3oltosUnyC73nBmLcnRiBKbbKgIlm\" +\n    \"TnyGvqONb_vKNBsOM5f36dcW9AeFBrxLl0-huFK3XA81fp9shkvpybeJz06GmRhVIu9kzAWhqH-rRoE2\" +\n    \"7YuB8U4a6I-5VpHQGdMxAN7tIqpziaSDjsVjlqmvOPk0VQzES2d4Asf6IYRyiA7W-OfGi5pBiw3f2JNR\" +\n    \"leiFvUGd_nBA0Rc-6C9HGTzMLmMzIr_SXfvUxJvBvJRfoEQkWwfdb-FE5dkCupIiFrTR0Lu699B7ACEJ\" +\n    \"k1itx5Q-p3jUqdSEG7AeqdLT6JJ5CwBoEiC1wa15itVs4q2TlsYKVgVWfXDQ06ax7qGwWgYQyk_xwTfE\" +\n    \"p7erfra5P0wL3XDCtKE_oMX0HSpgVgqvKAzDF7GulOpzs8pFiGlNa2a0-6MeZ3cY3Id9vjlDSfdwtg_r\" +\n    \"5yPKDd7I10BFV9PSq6PtI6LVpZDGgTsThjMRpjnloYsrcik5Y_JN8HdTDe2UUZzLlQ\"\n  keyFunc : () => \"ddJNIRm2qio2Z7CXpKADiw\"\n  return afAxonEncryptorRt_callFunc(\"pointQueryLookup\", cipherText, [target, opts], keyFunc)\nend",
      "local_src": "/*\n*   Description : Point queries\n*\n*   Work :\n*     Who                    When             Change\n*     Dylan Bardin           xx/xx/xxxx      - Initial Creation\n*     Apoorv Khanuja         12/16/2024      - Added \"and not syntheticPoint\" to elec_intervalPwr and natGas_intervalCons\n*     Apoorv Khanuja         01/07/2025      - Added a new group \"Synthetic points\" and a new point meter_anomaly. TODO: add more synthetic points like equip_anomaly, modelPoint (mlPoint? syntheticPoint?), etc.\n*/\n\n(target:null, opts:{}) => do\n\n  //opts\n\n\n  colMeta: if(opts.has(\"colMeta\")) true else false\n  show: if(opts.has(\"show\")) true else false\n\n\n  queries: [\n    /////////////////////// AHUS /////////////////////////////////\n    //temps\n              {target:\"oat_sensor\",                  query:\"temp and air and point and outside and sensor\",                            colMeta:{color:\"#00b843\"} },\n              {target:\"dat_sensor\",                  query:\"temp and air and point and discharge and sensor\",                          colMeta:{color:\"#0547fc\"} },\n              {target:\"datClg_sp\",                   query:\"temp and air and point and discharge and cooling sp\",                      colMeta:{color:null} },\n              {target:\"datHtg_sp\",                   query:\"temp and air and point and discharge and heating sp\",                      colMeta:{color:null} },\n              {target:\"dat_sp\",                      query:\"temp and air and point and discharge and sp\",                              colMeta:{color:\"#5cb3ff\"} },\n              {target:\"mat_sensor\",                  query:\"temp and air and point and mixed and sensor\",                              colMeta:{color:\"#FFD580\"} },\n              {target:\"mat_sp\",                      query:\"temp and air and point and mixed and sp\",                                  colMeta:{color:\"#FFA500\"} },\n              {target:\"rat_sensor\",                  query:\"temp and air and point and return and sensor\",                             colMeta:{color:\"#FF0000\"} },\n              {target:\"zntClg_sp\",                   query:\"temp and air and point and effective and zone and cooling and sp\",         colMeta:{color:\"#0547fc\"} },\n              {target:\"zntHtg_sp\",                   query:\"temp and air and point and effective and zone and heating and sp\",         colMeta:{color:\"#FF0000\"} },\n              {target:\"znt_sensor\",                  query:\"temp and air and point and zone and sensor\",                               colMeta:{color:\"#00b843\"} },\n              {target:\"znt_sp\",                      query:\"temp and air and point and zone and sp and not heating and not cooling\",   colMeta:{color:\"#71bd8d\"} },\n\n    //pressures\n              {target:\"dsp_sensor\",                  query:\"pressure and air and point and discharge and sensor and not filter\"       ,colMeta:{color:null} },\n              {target:\"dsp_sp\",                      query:\"pressure and air and point and discharge and sp and not filter\"           ,colMeta:{color:null} },\n              {target:\"bldg_press_sensor\",           query:\"air and building and point and pressure and sensor\"                       ,colMeta:{color:null} },\n              {target:\"bldg_press_sp\",               query:\"air and building and point and pressure and sp\"                           ,colMeta:{color:null} },\n    //Flow\n              {target:\"daFlow_sensor\",               query:\"flow and air and point and discharge and sensor\"                          ,colMeta:{color:null} },\n              {target:\"daFlow_sp\",                   query:\"flow and air and point and discharge and sp\"                              ,colMeta:{color:null} },\n              {target:\"znflow_sp\",                   query:\"flow and air and point and discharge and sp\"                              ,colMeta:{color:null} },\n              {target:\"znflow_sensor\",               query:\"flow and air and point and discharge and sensor\"                          ,colMeta:{color:null} },\n    //valves\n              {target:\"htgValve_cmd\",                query:\"point and cmd and valve and water and (reheat or hot)\"                    ,colMeta:{color:null} },\n              {target:\"clgValve_cmd\",                query:\"point and water and (cool or chilled) and cmd and valve\"                  ,colMeta:{color:null} },\n              {target:\"phtValve_cmd\",                query:\"point and preheat and cmd and valve\"                                      ,colMeta:{color:null} },\n    //dampers\n              {target:\"oaDmpr_cmd\",                  query:\"damper and air and point and outside and cmd\"                             ,colMeta:{color:null} },\n              {target:\"maDmpr_cmd\",                  query:\"damper and air and point and mixed and cmd\"                               ,colMeta:{color:null} },\n              {target:\"raDmpr_cmd\",                  query:\"damper and air and point and return and cmd\"                              ,colMeta:{color:null} },\n              {target:\"rlfDmpr_cmd\",                 query:\"damper and air and point and relief and cmd\"                              ,colMeta:{color:null} },\n              {target:\"dmpr_cmd\",                    query:\"damper and air and point and cmd\"                                         ,colMeta:{color:null} },\n    //fans\n              {target:\"rtnFan_speed\",                query:\"return and point and fan and speed and cmd\"                               ,colMeta:{color:null} },\n              {target:\"rtnFan_cmd\",                  query:\"return and point and fan and run and cmd\"                                 ,colMeta:{color:null} },\n              {target:\"rlfFan_speed\",                query:\"relief and point and fan and speed and cmd\"                               ,colMeta:{color:null} },\n              {target:\"rlfFan_cmd\",                  query:\"relief and point and fan and run and cmd\"                                 ,colMeta:{color:null} },\n              {target:\"exhFan_speed\",                query:\"exhaust and point and fan and speed and cmd\"                              ,colMeta:{color:null} },\n              {target:\"daFan_speed\",                 query:\"discharge and point and fan and speed and cmd\"                            ,colMeta:{color:null} },\n              {target:\"daFan_run\",                   query:\"discharge and point and fan and run and cmd\"                              ,colMeta:{color:null} },\n\n    //humidity\n              {target:\"daHumid_sensor\",              query:\"point and sensor and discharge and air and humidity\"                      ,colMeta:{color:null} },\n              {target:\"humidifier_cmd\",              query:\"point and air and cmd and humidifier and not output\"                      ,colMeta:{color:null} },\n\n    //energy recovery\n              {target:\"ercETemp_sensor\",             query:\"energy and recovery and air and entering and sensor and temp\"             ,colMeta:{color:null} },\n              {target:\"ercLTemp_sensor\",             query:\"energy and recovery and air and leaving and sensor and temp\"              ,colMeta:{color:null} },\n              {target:\"ercLTemp_sp\",                 query:\"energy and recovery and air and leaving and sp and temp\"                  ,colMeta:{color:null} },\n              {target:\"erc_valve\",                   query:\"energy and recovery and valve and sensor and temp\"                        ,colMeta:{color:null} },\n    //other\n              {target:\"occ_cmd\",                     query:\"occupied and point and cmd\"},\n              {target:\"siteOcc_cmd\",                 query:\"occupied and sitePoint\"},\n              {target:\"ahu_state\",                   query:\"point and (ahu or ahuState)\"},\n    //dual duct\n              {target:\"hotDeck_daFlow_sensor\",       query:\"hotDeck and flow and air and point and discharge and sensor\"                          ,colMeta:{color:null} },\n              {target:\"hotDeck_daFlow_sp\",           query:\"hotDeck and flow and air and point and discharge and sp\"                              ,colMeta:{color:null} },\n              {target:\"hotDeck_dmpr_cmd\",            query:\"hotDeck and damper and air and point and cmd\"                                         ,colMeta:{color:null} },\n              {target:\"hotDeck_dmpr_reset\",          query:\"hotDeck and damper and air and point and cmd and reset\"                               ,colMeta:{color:null} },\n\n              {target:\"coldDeck_daFlow_sensor\",      query:\"coldDeck and flow and air and point and discharge and sensor\"                          ,colMeta:{color:null} },\n              {target:\"coldDeck_daFlow_sp\",          query:\"coldDeck and flow and air and point and discharge and sp\"                              ,colMeta:{color:null} },\n              {target:\"coldDeck_dmpr_cmd\",           query:\"coldDeck and damper and air and point and cmd\"                                         ,colMeta:{color:null} },\n              {target:\"coldDeck_dmpr_reset\",         query:\"coldDeck and damper and air and point and cmd and reset\"                               ,colMeta:{color:null} },\n\n    //buildingHealth\n              {target:\"site_eui\",                     query:\"point and eui and equipRef->buildingHealth\"},\n              {target:\"chw_eui\",                      query:\"point and chilledWater and euiContributor and equipRef->buildingHealth\"},\n              {target:\"elec_eui\",                     query:\"point and elec and euiContributor and equipRef->buildingHealth\"},\n              {target:\"hw_eui\",                       query:\"point and hotWater and euiContributor and equipRef->buildingHealth\"},\n              {target:\"natGas_eui\",                   query:\"point and naturalGas and euiContributor and equipRef->buildingHealth\"},\n              {target:\"other_eui\",                    query:\"point and euiContributor and other and equipRef->buildingHealth\"},\n              {target:\"site_eci\",                     query:\"point and eci and equipRef->buildingHealth\"},\n              {target:\"site_uncomfortableVAVs\",       query:\"point and vavScorePt and uncomfortable and equipRef->buildingHealth\"},\n              {target:\"site_comfortableVAVs\",         query:\"point and vavScorePt and comfortable and equipRef->buildingHealth\"},\n              {target:\"site_equipLife\",               query:\"point and equipmentLife and equipRef->buildingHealth\"},\n              {target:\"site_buildingComfort\",         query:\"point and buildingScore and comfort and equipRef->buildingHealth\"},\n              {target:\"site_buildingArea\",            query:\"point and buildingArea and equipRef->buildingHealth\"},\n\n    //elec meter\n              {target:\"elec_intervalPwr\",            query:\"elec and power and interval and not cost and not modelPoint and not syntheticPoint and not savings and not virtualPoint\"},\n              {target:\"elec_modelPwr\",               query:\"elec and power and calculated and modelHisFunction and modelPoint and interval and equipRef->siteMeter\"},\n              {target:\"elec_monthlyEnergy\",          query:\"elec and energy and monthly and not cost and not rateCost and equipRef->siteMeter and not modelPoint and not savings\"},\n              {target:\"elec_modelEnergy\",            query:\"elec and energy and monthly and equipRef->siteMeter and modelPoint\"},\n              {target:\"elec_monthlyCost\",            query:\"elec and energy and monthly and equipRef->siteMeter and cost\"},\n              {target:\"elec_intervalCost\",           query:\"elec and power and interval and equipRef->siteMeter and cost\"},\n              {target:\"elec_monthlyRateCost\",        query:\"elec and energy and monthly and equipRef->siteMeter and rateCost\"},\n              {target:\"elec_intervalSavingsCost\",    query:\"elec and power and interval and equipRef->siteMeter and savings and cost\"},\n              {target:\"elec_savingsPwr\",             query:\"elec and power and interval and equipRef->siteMeter and savings and not cost\"},\n              {target:\"elec_monthlySavingsCost\",     query:\"elec and energy and monthly and equipRef->siteMeter and savings and cost\"},\n              {target:\"elec_savingsEnergy\",          query:\"elec and energy and monthly and equipRef->siteMeter and savings and not cost\"},\n\n    //natGas meter\n              {target:\"natGas_intervalCons\",         query:\"naturalGas and consumption and interval and equipRef->siteMeter and not cost and not modelPoint and not syntheticPoint and not savings\"},\n              {target:\"natGas_intervalModelCons\",    query:\"naturalGas and consumption and calculated and modelHisFunction and modelPoint and interval and equipRef->siteMeter\"},\n              {target:\"natGas_monthlyCons\",          query:\"naturalGas and consumption and monthly and not cost and not rateCost and equipRef->siteMeter and not modelPoint and not savings\"},\n              {target:\"natGas_monthlyModelCons\",     query:\"naturalGas and consumption and monthly and equipRef->siteMeter and modelPoint\"},\n              {target:\"natGas_monthlyCost\",          query:\"naturalGas and consumption and monthly and equipRef->siteMeter and cost\"},\n              {target:\"natGas_intervalCost\",         query:\"naturalGas and consumption and interval and equipRef->siteMeter and cost\"},\n              {target:\"natGas_monthlyRateCost\",      query:\"naturalGas and consumption and monthly and equipRef->siteMeter and rateCost\"},\n              {target:\"natGas_intervalSavingsCost\",  query:\"naturalGas and consumption and interval and equipRef->siteMeter and savings and cost\"},\n              {target:\"natGas_intervalSavingsCons\",  query:\"naturalGas and consumption and interval and equipRef->siteMeter and savings and not cost\"},\n              {target:\"natGas_monthlySavingsCost\",   query:\"naturalGas and consumption and monthly and equipRef->siteMeter and savings and cost\"},\n              {target:\"natGas_monthlySavingsCons\",   query:\"naturalGas and consumption and monthly and equipRef->siteMeter and savings and not cost\"},\n\n    //water meter\n              {target:\"water_intervalCons\",         query:\"water and consumption and interval and equipRef->siteMeter and not cost and not modelPoint and not savings\"},\n              {target:\"water_intervalModelCons\",    query:\"water and consumption and calculated and modelHisFunction and modelPoint and interval and equipRef->siteMeter\"},\n              {target:\"water_monthlyCons\",          query:\"water and consumption and monthly and not cost and not rateCost and equipRef->siteMeter and not modelPoint and not savings\"},\n              {target:\"water_monthlyModelCons\",     query:\"water and consumption and monthly and equipRef->siteMeter and modelPoint\"},\n              {target:\"water_monthlyCost\",          query:\"water and consumption and monthly and equipRef->siteMeter and cost\"},\n              {target:\"water_intervalCost\",         query:\"water and consumption and interval and equipRef->siteMeter and cost\"},\n              {target:\"water_monthlyRateCost\",      query:\"water and consumption and monthly and equipRef->siteMeter and rateCost\"},\n              {target:\"water_intervalSavingsCost\",  query:\"water and consumption and interval and equipRef->siteMeter and savings and cost\"},\n              {target:\"water_intervalSavingsCons\",  query:\"water and consumption and interval and equipRef->siteMeter and savings and not cost\"},\n              {target:\"water_monthlySavingsCost\",   query:\"water and consumption and monthly and equipRef->siteMeter and savings and cost\"},\n              {target:\"water_monthlySavingsCons\",   query:\"water and consumption and monthly and equipRef->siteMeter and savings and not cost\"},\n\n    //steam meter\n              {target:\"steam_intervalCons\",         query:\"steam and interval and equipRef->siteMeter and not cost and not modelPoint and not savings\"},\n              {target:\"steam_intervalModelCons\",    query:\"steam and calculated and modelHisFunction and modelPoint and interval and equipRef->siteMeter\"},\n              {target:\"steam_monthlyCons\",          query:\"steam and monthly and not cost and not rateCost and equipRef->siteMeter and not modelPoint and not savings\"},\n              {target:\"steam_monthlyModelCons\",     query:\"steam and monthly and equipRef->siteMeter and modelPoint\"},\n              {target:\"steam_monthlyCost\",          query:\"steam and monthly and equipRef->siteMeter and cost\"},\n              {target:\"steam_intervalCost\",         query:\"steam and interval and equipRef->siteMeter and cost and not savings\"},\n              {target:\"steam_monthlyRateCost\",      query:\"steam and monthly and equipRef->siteMeter and rateCost\"},\n              {target:\"steam_intervalSavingsCost\",  query:\"steam and interval and equipRef->siteMeter and savings and cost\"},\n              {target:\"steam_intervalSavingsCons\",  query:\"steam and interval and equipRef->siteMeter and savings and not cost\"},\n              {target:\"steam_monthlySavingsCost\",   query:\"steam and monthly and equipRef->siteMeter and savings and cost\"},\n              {target:\"steam_monthlySavingsCons\",   query:\"steam and monthly and equipRef->siteMeter and savings and not cost\"},\n\n    //site meter\n              {target:\"siteMeter_intervalCost\",     query:\"interval and (energy or consumption) and cost and (not savings)\"},\n              {target:\"siteMeter_intervalUse\",      query:\"interval and (usage or consumption) and (not modelPoint) and (not cost)\"},\n              {target:\"siteMeter_monthlyCost\",      query:\"monthly and (energy or consumption) and cost and (not savings)\"},\n              {target:\"siteMeter_monthlyUse\",       query:\"monthly and (usage or consumption) and (not modelPoint) and (not savings) and (not rateCost) and (not cost)\"},\n              {target:\"siteMeter_blendedRate\",      query:\"rateCost and (energy or consumption)\"},\n    //hot water\n              {target:\"hw_delta_press\",             query:\"hot and water and pressure and delta and sensor\"},\n              {target:\"hw_flow\",                    query:\"hot and water and flow and sensor\"},\n              {target:\"hw_pri_pump_speed\",          query:\"hot and water and pump and speed and cmd and primary\"},\n              {target:\"hw_pri_pump_status\",         query:\"hot and water and pump and run and cmd and primary\"},\n              {target:\"hw_sec_pump_speed\",          query:\"hot and water and pump and speed and cmd and secondary\"},\n              {target:\"hw_sec_pump_status\",         query:\"hot and water and pump and run and cmd and secondary\"},\n              {target:\"hw_pri_pump_power\",          query:\"hot and water and pump and power and sensor and primary\"},\n              {target:\"hw_sec_pump_power\",          query:\"hot and water and pump and power and sensor and secondary\"},\n              {target:\"hw_supply_temp\",             query:\"hot and water and supply and temp and sensor\"},\n              {target:\"hw_return_temp\",             query:\"hot and water and return and temp and sensor and not domestic\"},\n              {target:\"hw_supply_temp_sp\",          query:\"hot and water and supply and temp and sp\"},\n              {target:\"hw_delta_press_sp\",          query:\"hot and water and pressure and delta and sp\"},\n              {target:\"hw_delta_temp\",              query:\"hot and water and temp and delta and sensor\"},\n              {target:\"hw_sys_load\",                query:\"hot and water and load and energy\"},\n              {target:\"hw_bypass_valve\",            query:\"hot and water and bypass and valve and cmd\"},\n\n    //chilled water\n              {target:\"chw_delta_press\",             query:\"chilled and water and pressure and delta and sensor\"},\n              {target:\"chw_flow\",                    query:\"chilled and water and flow and sensor and not bypass\"},\n              {target:\"chw_pri_pump_speed\",          query:\"chilled and water and pump and speed and cmd and primary\"},\n              {target:\"chw_sec_pump_speed\",          query:\"chilled and water and pump and speed and cmd and secondary\"},\n              {target:\"chw_pri_pump_status\",         query:\"chilled and water and pump and run and cmd and primary\"},\n              {target:\"chw_sec_pump_status\",         query:\"chilled and water and pump and run and cmd and secondary\"},\n              {target:\"chw_pri_pump_power\",          query:\"chilled and water and pump and power and sensor and primary\"},\n              {target:\"chw_sec_pump_power\",          query:\"chilled and water and pump and power and sensor and secondary\"},\n            //{target:\"chw_pri_pump_status\",         query:\"chilled and water and pump and run and cmd and primary\"},\n            //{target:\"chw_sec_pump_status\",         query:\"chilled and water and pump and run and cmd and secondary\"},\n              {target:\"chw_supply_temp\",             query:\"chilled and water and supply and temp and sensor\"},\n              {target:\"chw_return_temp\",             query:\"chilled and water and return and temp and sensor\"},\n              {target:\"chw_supply_temp_sp\",          query:\"chilled and water and supply and temp and sp\"},\n              {target:\"chw_delta_press_sp\",          query:\"chilled and water and pressure and delta and sp\"},\n              {target:\"chw_delta_temp\",              query:\"chilled and water and temp and delta and sensor\"},\n              {target:\"chw_sys_load\",                query:\"chilled and water and load and energy\"},\n\n     //General Pump Points\n              {target:\"pri_pump_speed\",          query:\"water and pump and speed and cmd and primary\"},\n              {target:\"sec_pump_speed\",          query:\"water and pump and speed and cmd and secondary\"},\n              {target:\"pri_pump_status\",         query:\"water and pump and run and cmd and primary\"},\n              {target:\"sec_pump_status\",         query:\"water and pump and run and cmd and secondary\"},\n              {target:\"pri_pump_power\",          query:\"water and pump and power and sensor and primary\"},\n              {target:\"sec_pump_power\",          query:\"water and pump and power and sensor and secondary\"},\n\n     //chillers\n              {target:\"chlr_status\",                   query:\"chiller and cmd and run\"},\n              {target:\"chlr_power\",                    query:\"chiller and power and sensor\"},\n              {target:\"chlr_entering_temp\",            query:\"chiller and chilled and entering and temp and water and sensor and not condenser\"},\n              {target:\"chlr_leaving_temp\",             query:\"chiller and chilled and leaving and temp and water and sensor and not condenser\"},\n              {target:\"chlr_flow\",                     query:\"chiller and chilled and flow and water and sensor\"},\n              {target:\"chlr_fla\",                      query:\"chiller and fla and sensor\"},\n              {target:\"chlr_cw_entering_temp\",         query:\"chiller and condenser and entering and temp and water and sensor\"},\n              {target:\"chlr_cw_leaving_temp\",          query:\"chiller and condenser and leaving and temp and water and sensor\"},\n              {target:\"chlr_water_load\",               query:\"chiller and sensor and tonref\"},\n\n     //boilers\n              {target:\"blr_firing_rate\",              query:\"boiler and firingRate and sensor\"},\n              {target:\"blr_entering_temp\",            query:\"boiler and hot and (entering or return) and temp and water and sensor\"},\n              {target:\"blr_leaving_temp\",             query:\"boiler and hot and leaving and temp and water and sensor\"},\n              {target:\"blr_leaving_temp_sp\",          query:\"boiler and hot and leaving and temp and water and sp\"},\n              {target:\"blr_run_status\",               query:\"boiler and run and cmd\"},\n              {target:\"blr_enable\",                   query:\"boiler and cmd and enable\"},\n              {target:\"blr_gas_flow_rate\",            query:\"boiler and flow and rate and sensor and naturalGas\"},\n              {target:\"blr_flow\",                     query:\"boiler and notImplemented\"},\n              {target:\"blr_power\",                    query:\"boiler and power and sensor\"},\n              {target:\"blr_iso_valve\",                query:\"boiler and isolation and valve\"},\n\n     //cooling tower\n              {target:\"clgtwr_leaving_temp\",         query:\"coolingTower and temp and (leaving or supply) and water and sensor\"},\n              {target:\"clgtwr_entering_temp\",        query:\"coolingTower and temp and (entering or return) and water and sensor\"},\n              {target:\"clgtwr_fan_speed\",            query:\"coolingTower and fan and speed and air and cmd\"},\n              {target:\"clgtwr_power\",                query:\"coolingTower and power and sensor\"},\n              {target:\"clgtwr_fan_status\",           query:\"coolingTower and cmd and run\"},\n\n\n     //condenser water\n              {target:\"cws_supply_temp\",             query:\"condenser and water and supply and temp and sensor\"},\n              {target:\"cws_supply_temp_sp\",          query:\"condenser and water and supply and temp and sp\"},\n              {target:\"cws_return_temp\",             query:\"condenser and water and return and temp and sensor\"},\n\n     //miscellaneous\n              {target:\"wet_bulb\",                    query:\"temp and wetBulb\"},\n              {target:\"oah_sensor\",                  query:\"humidity and air and point and outside and sensor\"},\n\n     // Synthetic points\n              {target:\"meter_anomaly\",               query:\"anomaly and equipRef->equipRef->siteMeter\"}, // separate out elecMeter_anomaly and gasMeter_anomaly? Resolve -> vs -> ->\n\n     //Coil Temps\n             //hot\n             {target:\"chw_entg_temp\",                    query:\"chilled and water and valve\"},\n             {target:\"chw_lvg_temp\",                     query:\"humidity and air and point and outside and sensor\"},\n\n             //chilled\n             {target:\"hw_entg_temp\",                    query:\"temp and wetBulb\"},\n             {target:\"hw_lvg_temp\",                     query:\"humidity and air and point and outside and sensor\"},\n\n             //Baseline Search\n             {target:\"baseline_calc\",                query:\"point and calculated and modelPoint and not cost and not savings\"},\n           ].toGrid\n\n\n  if(show) return queries\n\n  match: queries.find(r => r.get(\"target\")==target)\n  if (match.isNull) throw \"Cannot find query: \"+target\n\n  out: if (colMeta) match.get(\"colMeta\")\n       else         match.get(\"query\")\n\n  return out\nend",
      "diff": "@@ -1,61 +1,270 @@-(target: null, opts: {}) => do\n-  cipherText :\n-    \"AxD:J7ik5GzASro65uWVIxMkAg::7cPS7lsTZSH5N2vG2V_-JnF7WnnW0YzEzAkoWuWN0t33cekbuST1\" +\n-    \"jdwUtsnrnsWKnY2ZJ11FgjHRBw-4DchwEYWtNDzsPhtoG9qIeWzimhGiuRu1zA5WRrk0313ancLuQXcH\" +\n-    \"zUsoSr9-_gDRNSvmhd8jJ8XaV0eozzR7scJJx801Sxs1lYKqn9-efJgMoGE5yUdio-ucRJMKwXCuww-J\" +\n-    \"b8TqM0LRciBpX_qgy9sWW83-toyx1g1E6NXoPfuyE4EB_DXdpr3CmMSWscawuIAE3KH2FmPCMCU8ihr3\" +\n-    \"tr_mcJm1MYsEo96AokjwJZusgH38mbnKrRoCf8NHPHr0pfCbgMSC-bF-D68vIgcs7pkROhkb8dHHy0Yb\" +\n-    \"BGZHrQwecGLFxh3jego2SM4MSQxMksgcXyMChH17bY10l6VEqvIczPolCB66sNO2bVrCc5FWAFPGXxtr\" +\n-    \"m_T7E__lMU78LEPWLfO1UMWE_FLJtlEAQbuv_xhB4jUy4kyqpWCjuwNLkCrYY7sWHzyE90-Ys6SJzJLF\" +\n-    \"INz9kBTIPWsbbjDHx0satQxguftZqyzoAjtoNJvymRdqyVTMTH2kLe1zoF_fI7afvDstxdp_YJ1Snx8y\" +\n-    \"b3DLsnyLYJmKX7M8z4og1VWfRq6MdK-OCyjnRkLCO8Yv2ieCKWXBBbt7b5H7sVq8aZe-QHMINJW9XJQa\" +\n-    \"AnOn9ePqiMWZoCfUbSB_dpwe89a9xMwOB_Ndj9gW8AoXEiK2uUgBEN_p4zcjOmNOJemXpluU-yQDFqJ3\" +\n-    \"bZKgktkwNLUwrhYAYsp8Rg12CkGeXqx5hEEhEeXaUZisO7OKUHC9iFpi0CXbKbIB7bQc5kmWXCQNOKpk\" +\n-    \"WJX_EPBrGrlmKXXseMsPuT78bkNoPxGbYxGwE4cSIfDqE0wkZOpILvuYXWkc5_jIdwuNsHSNLMXtEG2W\" +\n-    \"NZ2dCBXpdFS7pFE5KrdkkydqepBBHgcCia5uNWcm1Sm9MuqqhjSK3R2r8D8VxPAJNIP-B05znD5pcUt8\" +\n-    \"H-XKlS1RIkPpOpT3_0o_ieo7Dk2A51Ta4aSMsV1dkCGA78aq6mSF6oBYWefmW2FGYsmJjl0_KhJ30cuM\" +\n-    \"-VLV1Tm58wPWB4gk-VTLLCCYqcu2eiH2XOMA5h2A0Jqm8nAp0-VH8rIvsgcdXV7OyBp7RThiFhmXrczT\" +\n-    \"9UjSq1fDGg5ss22R-nyAlL6Cy9lFNgAwJXhhZGyoeEmKAnTju_Eszm8fkclrd66V2OG8Oumqyo_uLyAT\" +\n-    \"WaOvw-a_AV8IniBRcJsnpdMFFuoGLKQ_IeAojF82KpVG0sB7Q9SR5iOJOCgu1zOfjmbJJuRiKt_5lvlX\" +\n-    \"vjjxxHEwjXF_f-PFNDclHEwLpjwPm0u3Vln7BaLW0nbWkRsC8_GugIUsI0JIOZXfv7gCowIcqWPqFl2k\" +\n-    \"AQTXjulVkhATkjviOkhCRzRpJgBt_4vjZzIPZKnJZqEq1aIDDCk8TxIBlABWT2Secx_B7z6vXxM6sKJO\" +\n-    \"nThHzuHjlsJYDXrMEq1NVYtIz6HOv86FEksDz8zR7cCtSfQE2z-PMEeIBL0g5g4k5lDduU0ltFQDamy8\" +\n-    \"jGokPxsAKgmYeqtWlvQDFircTDaUEURdVC0t0aRmXAOHIlhqYslE5vMmXfaZyB8tY8XC-QO4RwKRNOsA\" +\n-    \"Ii_lUujsAX-uRZib_Qj79SArzhQVKHalYEglFumjDyOfjftf0dAqW7Lm3RzLBPnSAP5drZMTfCqr_keo\" +\n-    \"qCRPNnnsdgVhHpauC4oI3UwJJ3cnm6wK1qCQzw3LQTapoht77RJRHPZ0uepNmuxAENkXf0tm_ViUbsSj\" +\n-    \"6EFCV5CDWQqH3aXWIdkiCAU4A0RkucCfFULcqINf2dfBkY3R9167QcyyhIIR335dIg-Jn2S3Ms2TuOiJ\" +\n-    \"mVIx3ht7V091uCY6UWCmpIKebvMwnDubPnelivQ9tAwKnC2jR4eo_SppqT981sI61cG0tmud_TU6lwIW\" +\n-    \"KoCXkm74hOIIw-JtB0zwfMXU1joh9m0_aPdw2FHyn4IhZVKpLeLYGlq8LtA_f723YpAqGzUM3VdjBqBq\" +\n-    \"evHqr-YL5X8Rq5CdMndKEk5xKgy7a9tabPjmQINlDJvPOh69qnCXU0EjY9YJkJAfVBM0-QUw2ENrkk8X\" +\n-    \"0Jnerfrdo-jFmA4UGKQlRooB3WU2zRbzNHpUOlUhdr1PGvwaKFeZBVgD8mKPorQ9M9fpbfvLv94j4u0a\" +\n-    \"vGuJnHS8fIEIIttwkptkl6dZY5VJPirMexsQ8x9h7WlmoJc5KmkWxBQhDvM3Ct_MUx1rZJNrOLNi4Ie5\" +\n-    \"Js_rUphBPRUBvsZoHHP6a7BkoGVK1Jkkz94oVE3S43QHcwxLRg7LerPwKMIfnnNynQDm7IE0n7FJ6I1J\" +\n-    \"SrIJnQ0Lw2TrKHGF3LxRqJPpnzxYXyk__AlFTONjPxdh5D5GWbOXxupbq2XetLrtcbPlXiVhewejzhdo\" +\n-    \"9AAHINpe-THmsGMM0YgSq6TGY-nbox6NZfQIV7lFpKfbhb4-vRv6CTcrSo2nPxcPPJklUYDX8AK7h4L2\" +\n-    \"Hmc6n3T-BFv3rttrQnM2kmSPKZ2CzO3cMuLCOIdgoO12BVTnhT6Q46g5gwL6YSdsuOcRR1lpko7AMUmv\" +\n-    \"KYDmI_qQ3gpToK2m2VtjzmpdQwQPsHEoGZ3KCv3FE37x64gVBjFjkcJuOj8PL87x2xJVivML5GYLopia\" +\n-    \"u6glIJnSB-lRUd_NZZanFi05MKqaD37mr4thZHmNgUbyKKJceApVRwPQnH5JXZ-hIdOkErcKotzzFSXH\" +\n-    \"QElnlHMJwPqlMH-_7FC2pKOgpjeIZTaAZtI5yubMlvRu6xEYYZMVWjko6C0w6JGAztBsbGGih-cp9UgZ\" +\n-    \"vqVdxZpueTfDpepAdIPFNYl5GthaQfyzfldAD2a16HgTl7_RGNKkecRQEq_KUr6iX9Q1PyvswN4LSN6v\" +\n-    \"AMgI8Uimcz0ZFZ2GT9AV8rWnSSLxTq-QIMjbJORY3LwDzKOG9IOs4T-5ZAuGoaDwmNklXTxUyPrCAGgT\" +\n-    \"koFLAbO8hgV3OIuAMAjOFf77vsgFVzsQhSCAx9uDKsowXuxTnwwfkWn60jPoeZFW_D_IMw_SUil3b73h\" +\n-    \"XvVU9TzYdYzAldUUSs8c9T32w_EqTx3dAFeq_UZenGz-Hpb0UvrdWaG4Nak31iEDMWgEaa6A5m7DVrCp\" +\n-    \"Ep95i5hgSxW_A9piXVMf0yuX0nS2pUk9I156QvkqM_nqLi0KeHTdObLNxq40FWgvzE8yh-1xYXkUOS9C\" +\n-    \"x2pkdEnzNWPzvKEIUPKyaNS6rDKHi4OW2Z20UHi9G08mrHfFWV-tv59bisy7pJA5Gaa2sB7GFqUqyh5X\" +\n-    \"mLu9Vy98861yGdSVdKybEmwLrOgz20N63ie0ACuRk6UVaQaFgQX5ZZFBKSO19gsqiNxAGTPucd-9-K8y\" +\n-    \"cBtQJ3bJgjboXjjQ7J-ehZxYvVJI-88Rsst_hnmgLUlmqwcZEtOVPuZEl7PjecfjB_2TzH0YQcW1BfWZ\" +\n-    \"kr7fT7nwjf-Ow_za4spUGPe2BVMsG8wxDTvVwzzP8Qs-CrExhKiqxD7vImKOyel2BXU79lSJ80EFZJpV\" +\n-    \"AmWma5DPsQHQGWxHVYCSe4MBvKBFvu0nE2P3YohFlxU4eR4FDC9ELCSuzy3O-FPmIDZNlb5H-CxKSDf-\" +\n-    \"x7RL9sAPVduoRyKm30xnjUh61B2MOlORwB4buvAMVFIqURU86jNv6UqSUjHK_JigaLN9FDz-QJfUT72e\" +\n-    \"XX10CJiRvdf9MNPOQ6UZ3scFY0OgFNW6g6BCs3u_wrRvljuvkFI5LYLENV1XGLKLjjmBufV3vfjSql3f\" +\n-    \"ihfVGCGjXRLXgutD5lSZpGbSF05Clf1JxfSUJCq1rP4V_3GzXMwZD9AB7_Z3loOAkeRAmsjGndYKW833\" +\n-    \"DbR_zGnFc6EoVlDvHScL_l1UYF-piWIb9IOUZ5WdGc0LDiOfSIj3oltosUnyC73nBmLcnRiBKbbKgIlm\" +\n-    \"TnyGvqONb_vKNBsOM5f36dcW9AeFBrxLl0-huFK3XA81fp9shkvpybeJz06GmRhVIu9kzAWhqH-rRoE2\" +\n-    \"7YuB8U4a6I-5VpHQGdMxAN7tIqpziaSDjsVjlqmvOPk0VQzES2d4Asf6IYRyiA7W-OfGi5pBiw3f2JNR\" +\n-    \"leiFvUGd_nBA0Rc-6C9HGTzMLmMzIr_SXfvUxJvBvJRfoEQkWwfdb-FE5dkCupIiFrTR0Lu699B7ACEJ\" +\n-    \"k1itx5Q-p3jUqdSEG7AeqdLT6JJ5CwBoEiC1wa15itVs4q2TlsYKVgVWfXDQ06ax7qGwWgYQyk_xwTfE\" +\n-    \"p7erfra5P0wL3XDCtKE_oMX0HSpgVgqvKAzDF7GulOpzs8pFiGlNa2a0-6MeZ3cY3Id9vjlDSfdwtg_r\" +\n-    \"5yPKDd7I10BFV9PSq6PtI6LVpZDGgTsThjMRpjnloYsrcik5Y_JN8HdTDe2UUZzLlQ\"\n-  keyFunc : () => \"ddJNIRm2qio2Z7CXpKADiw\"\n-  return afAxonEncryptorRt_callFunc(\"pointQueryLookup\", cipherText, [target, opts], keyFunc)\n+/*\n+*   Description : Point queries\n+*\n+*   Work :\n+*     Who                    When             Change\n+*     Dylan Bardin           xx/xx/xxxx      - Initial Creation\n+*     Apoorv Khanuja         12/16/2024      - Added \"and not syntheticPoint\" to elec_intervalPwr and natGas_intervalCons\n+*     Apoorv Khanuja         01/07/2025      - Added a new group \"Synthetic points\" and a new point meter_anomaly. TODO: add more synthetic points like equip_anomaly, modelPoint (mlPoint? syntheticPoint?), etc.\n+*/\n+\n+(target:null, opts:{}) => do\n+\n+  //opts\n+\n+\n+  colMeta: if(opts.has(\"colMeta\")) true else false\n+  show: if(opts.has(\"show\")) true else false\n+\n+\n+  queries: [\n+    /////////////////////// AHUS /////////////////////////////////\n+    //temps\n+              {target:\"oat_sensor\",                  query:\"temp and air and point and outside and sensor\",                            colMeta:{color:\"#00b843\"} },\n+              {target:\"dat_sensor\",                  query:\"temp and air and point and discharge and sensor\",                          colMeta:{color:\"#0547fc\"} },\n+              {target:\"datClg_sp\",                   query:\"temp and air and point and discharge and cooling sp\",                      colMeta:{color:null} },\n+              {target:\"datHtg_sp\",                   query:\"temp and air and point and discharge and heating sp\",                      colMeta:{color:null} },\n+              {target:\"dat_sp\",                      query:\"temp and air and point and discharge and sp\",                              colMeta:{color:\"#5cb3ff\"} },\n+              {target:\"mat_sensor\",                  query:\"temp and air and point and mixed and sensor\",                              colMeta:{color:\"#FFD580\"} },\n+              {target:\"mat_sp\",                      query:\"temp and air and point and mixed and sp\",                                  colMeta:{color:\"#FFA500\"} },\n+              {target:\"rat_sensor\",                  query:\"temp and air and point and return and sensor\",                             colMeta:{color:\"#FF0000\"} },\n+              {target:\"zntClg_sp\",                   query:\"temp and air and point and effective and zone and cooling and sp\",         colMeta:{color:\"#0547fc\"} },\n+              {target:\"zntHtg_sp\",                   query:\"temp and air and point and effective and zone and heating and sp\",         colMeta:{color:\"#FF0000\"} },\n+              {target:\"znt_sensor\",                  query:\"temp and air and point and zone and sensor\",                               colMeta:{color:\"#00b843\"} },\n+              {target:\"znt_sp\",                      query:\"temp and air and point and zone and sp and not heating and not cooling\",   colMeta:{color:\"#71bd8d\"} },\n+\n+    //pressures\n+              {target:\"dsp_sensor\",                  query:\"pressure and air and point and discharge and sensor and not filter\"       ,colMeta:{color:null} },\n+              {target:\"dsp_sp\",                      query:\"pressure and air and point and discharge and sp and not filter\"           ,colMeta:{color:null} },\n+              {target:\"bldg_press_sensor\",           query:\"air and building and point and pressure and sensor\"                       ,colMeta:{color:null} },\n+              {target:\"bldg_press_sp\",               query:\"air and building and point and pressure and sp\"                           ,colMeta:{color:null} },\n+    //Flow\n+              {target:\"daFlow_sensor\",               query:\"flow and air and point and discharge and sensor\"                          ,colMeta:{color:null} },\n+              {target:\"daFlow_sp\",                   query:\"flow and air and point and discharge and sp\"                              ,colMeta:{color:null} },\n+              {target:\"znflow_sp\",                   query:\"flow and air and point and discharge and sp\"                              ,colMeta:{color:null} },\n+              {target:\"znflow_sensor\",               query:\"flow and air and point and discharge and sensor\"                          ,colMeta:{color:null} },\n+    //valves\n+              {target:\"htgValve_cmd\",                query:\"point and cmd and valve and water and (reheat or hot)\"                    ,colMeta:{color:null} },\n+              {target:\"clgValve_cmd\",                query:\"point and water and (cool or chilled) and cmd and valve\"                  ,colMeta:{color:null} },\n+              {target:\"phtValve_cmd\",                query:\"point and preheat and cmd and valve\"                                      ,colMeta:{color:null} },\n+    //dampers\n+              {target:\"oaDmpr_cmd\",                  query:\"damper and air and point and outside and cmd\"                             ,colMeta:{color:null} },\n+              {target:\"maDmpr_cmd\",                  query:\"damper and air and point and mixed and cmd\"                               ,colMeta:{color:null} },\n+              {target:\"raDmpr_cmd\",                  query:\"damper and air and point and return and cmd\"                              ,colMeta:{color:null} },\n+              {target:\"rlfDmpr_cmd\",                 query:\"damper and air and point and relief and cmd\"                              ,colMeta:{color:null} },\n+              {target:\"dmpr_cmd\",                    query:\"damper and air and point and cmd\"                                         ,colMeta:{color:null} },\n+    //fans\n+              {target:\"rtnFan_speed\",                query:\"return and point and fan and speed and cmd\"                               ,colMeta:{color:null} },\n+              {target:\"rtnFan_cmd\",                  query:\"return and point and fan and run and cmd\"                                 ,colMeta:{color:null} },\n+              {target:\"rlfFan_speed\",                query:\"relief and point and fan and speed and cmd\"                               ,colMeta:{color:null} },\n+              {target:\"rlfFan_cmd\",                  query:\"relief and point and fan and run and cmd\"                                 ,colMeta:{color:null} },\n+              {target:\"exhFan_speed\",                query:\"exhaust and point and fan and speed and cmd\"                              ,colMeta:{color:null} },\n+              {target:\"daFan_speed\",                 query:\"discharge and point and fan and speed and cmd\"                            ,colMeta:{color:null} },\n+              {target:\"daFan_run\",                   query:\"discharge and point and fan and run and cmd\"                              ,colMeta:{color:null} },\n+\n+    //humidity\n+              {target:\"daHumid_sensor\",              query:\"point and sensor and discharge and air and humidity\"                      ,colMeta:{color:null} },\n+              {target:\"humidifier_cmd\",              query:\"point and air and cmd and humidifier and not output\"                      ,colMeta:{color:null} },\n+\n+    //energy recovery\n+              {target:\"ercETemp_sensor\",             query:\"energy and recovery and air and entering and sensor and temp\"             ,colMeta:{color:null} },\n+              {target:\"ercLTemp_sensor\",             query:\"energy and recovery and air and leaving and sensor and temp\"              ,colMeta:{color:null} },\n+              {target:\"ercLTemp_sp\",                 query:\"energy and recovery and air and leaving and sp and temp\"                  ,colMeta:{color:null} },\n+              {target:\"erc_valve\",                   query:\"energy and recovery and valve and sensor and temp\"                        ,colMeta:{color:null} },\n+    //other\n+              {target:\"occ_cmd\",                     query:\"occupied and point and cmd\"},\n+              {target:\"siteOcc_cmd\",                 query:\"occupied and sitePoint\"},\n+              {target:\"ahu_state\",                   query:\"point and (ahu or ahuState)\"},\n+    //dual duct\n+              {target:\"hotDeck_daFlow_sensor\",       query:\"hotDeck and flow and air and point and discharge and sensor\"                          ,colMeta:{color:null} },\n+              {target:\"hotDeck_daFlow_sp\",           query:\"hotDeck and flow and air and point and discharge and sp\"                              ,colMeta:{color:null} },\n+              {target:\"hotDeck_dmpr_cmd\",            query:\"hotDeck and damper and air and point and cmd\"                                         ,colMeta:{color:null} },\n+              {target:\"hotDeck_dmpr_reset\",          query:\"hotDeck and damper and air and point and cmd and reset\"                               ,colMeta:{color:null} },\n+\n+              {target:\"coldDeck_daFlow_sensor\",      query:\"coldDeck and flow and air and point and discharge and sensor\"                          ,colMeta:{color:null} },\n+              {target:\"coldDeck_daFlow_sp\",          query:\"coldDeck and flow and air and point and discharge and sp\"                              ,colMeta:{color:null} },\n+              {target:\"coldDeck_dmpr_cmd\",           query:\"coldDeck and damper and air and point and cmd\"                                         ,colMeta:{color:null} },\n+              {target:\"coldDeck_dmpr_reset\",         query:\"coldDeck and damper and air and point and cmd and reset\"                               ,colMeta:{color:null} },\n+\n+    //buildingHealth\n+              {target:\"site_eui\",                     query:\"point and eui and equipRef->buildingHealth\"},\n+              {target:\"chw_eui\",                      query:\"point and chilledWater and euiContributor and equipRef->buildingHealth\"},\n+              {target:\"elec_eui\",                     query:\"point and elec and euiContributor and equipRef->buildingHealth\"},\n+              {target:\"hw_eui\",                       query:\"point and hotWater and euiContributor and equipRef->buildingHealth\"},\n+              {target:\"natGas_eui\",                   query:\"point and naturalGas and euiContributor and equipRef->buildingHealth\"},\n+              {target:\"other_eui\",                    query:\"point and euiContributor and other and equipRef->buildingHealth\"},\n+              {target:\"site_eci\",                     query:\"point and eci and equipRef->buildingHealth\"},\n+              {target:\"site_uncomfortableVAVs\",       query:\"point and vavScorePt and uncomfortable and equipRef->buildingHealth\"},\n+              {target:\"site_comfortableVAVs\",         query:\"point and vavScorePt and comfortable and equipRef->buildingHealth\"},\n+              {target:\"site_equipLife\",               query:\"point and equipmentLife and equipRef->buildingHealth\"},\n+              {target:\"site_buildingComfort\",         query:\"point and buildingScore and comfort and equipRef->buildingHealth\"},\n+              {target:\"site_buildingArea\",            query:\"point and buildingArea and equipRef->buildingHealth\"},\n+\n+    //elec meter\n+              {target:\"elec_intervalPwr\",            query:\"elec and power and interval and not cost and not modelPoint and not syntheticPoint and not savings and not virtualPoint\"},\n+              {target:\"elec_modelPwr\",               query:\"elec and power and calculated and modelHisFunction and modelPoint and interval and equipRef->siteMeter\"},\n+              {target:\"elec_monthlyEnergy\",          query:\"elec and energy and monthly and not cost and not rateCost and equipRef->siteMeter and not modelPoint and not savings\"},\n+              {target:\"elec_modelEnergy\",            query:\"elec and energy and monthly and equipRef->siteMeter and modelPoint\"},\n+              {target:\"elec_monthlyCost\",            query:\"elec and energy and monthly and equipRef->siteMeter and cost\"},\n+              {target:\"elec_intervalCost\",           query:\"elec and power and interval and equipRef->siteMeter and cost\"},\n+              {target:\"elec_monthlyRateCost\",        query:\"elec and energy and monthly and equipRef->siteMeter and rateCost\"},\n+              {target:\"elec_intervalSavingsCost\",    query:\"elec and power and interval and equipRef->siteMeter and savings and cost\"},\n+              {target:\"elec_savingsPwr\",             query:\"elec and power and interval and equipRef->siteMeter and savings and not cost\"},\n+              {target:\"elec_monthlySavingsCost\",     query:\"elec and energy and monthly and equipRef->siteMeter and savings and cost\"},\n+              {target:\"elec_savingsEnergy\",          query:\"elec and energy and monthly and equipRef->siteMeter and savings and not cost\"},\n+\n+    //natGas meter\n+              {target:\"natGas_intervalCons\",         query:\"naturalGas and consumption and interval and equipRef->siteMeter and not cost and not modelPoint and not syntheticPoint and not savings\"},\n+              {target:\"natGas_intervalModelCons\",    query:\"naturalGas and consumption and calculated and modelHisFunction and modelPoint and interval and equipRef->siteMeter\"},\n+              {target:\"natGas_monthlyCons\",          query:\"naturalGas and consumption and monthly and not cost and not rateCost and equipRef->siteMeter and not modelPoint and not savings\"},\n+              {target:\"natGas_monthlyModelCons\",     query:\"naturalGas and consumption and monthly and equipRef->siteMeter and modelPoint\"},\n+              {target:\"natGas_monthlyCost\",          query:\"naturalGas and consumption and monthly and equipRef->siteMeter and cost\"},\n+              {target:\"natGas_intervalCost\",         query:\"naturalGas and consumption and interval and equipRef->siteMeter and cost\"},\n+              {target:\"natGas_monthlyRateCost\",      query:\"naturalGas and consumption and monthly and equipRef->siteMeter and rateCost\"},\n+              {target:\"natGas_intervalSavingsCost\",  query:\"naturalGas and consumption and interval and equipRef->siteMeter and savings and cost\"},\n+              {target:\"natGas_intervalSavingsCons\",  query:\"naturalGas and consumption and interval and equipRef->siteMeter and savings and not cost\"},\n+              {target:\"natGas_monthlySavingsCost\",   query:\"naturalGas and consumption and monthly and equipRef->siteMeter and savings and cost\"},\n+              {target:\"natGas_monthlySavingsCons\",   query:\"naturalGas and consumption and monthly and equipRef->siteMeter and savings and not cost\"},\n+\n+    //water meter\n+              {target:\"water_intervalCons\",         query:\"water and consumption and interval and equipRef->siteMeter and not cost and not modelPoint and not savings\"},\n+              {target:\"water_intervalModelCons\",    query:\"water and consumption and calculated and modelHisFunction and modelPoint and interval and equipRef->siteMeter\"},\n+              {target:\"water_monthlyCons\",          query:\"water and consumption and monthly and not cost and not rateCost and equipRef->siteMeter and not modelPoint and not savings\"},\n+              {target:\"water_monthlyModelCons\",     query:\"water and consumption and monthly and equipRef->siteMeter and modelPoint\"},\n+              {target:\"water_monthlyCost\",          query:\"water and consumption and monthly and equipRef->siteMeter and cost\"},\n+              {target:\"water_intervalCost\",         query:\"water and consumption and interval and equipRef->siteMeter and cost\"},\n+              {target:\"water_monthlyRateCost\",      query:\"water and consumption and monthly and equipRef->siteMeter and rateCost\"},\n+              {target:\"water_intervalSavingsCost\",  query:\"water and consumption and interval and equipRef->siteMeter and savings and cost\"},\n+              {target:\"water_intervalSavingsCons\",  query:\"water and consumption and interval and equipRef->siteMeter and savings and not cost\"},\n+              {target:\"water_monthlySavingsCost\",   query:\"water and consumption and monthly and equipRef->siteMeter and savings and cost\"},\n+              {target:\"water_monthlySavingsCons\",   query:\"water and consumption and monthly and equipRef->siteMeter and savings and not cost\"},\n+\n+    //steam meter\n+              {target:\"steam_intervalCons\",         query:\"steam and interval and equipRef->siteMeter and not cost and not modelPoint and not savings\"},\n+              {target:\"steam_intervalModelCons\",    query:\"steam and calculated and modelHisFunction and modelPoint and interval and equipRef->siteMeter\"},\n+              {target:\"steam_monthlyCons\",          query:\"steam and monthly and not cost and not rateCost and equipRef->siteMeter and not modelPoint and not savings\"},\n+              {target:\"steam_monthlyModelCons\",     query:\"steam and monthly and equipRef->siteMeter and modelPoint\"},\n+              {target:\"steam_monthlyCost\",          query:\"steam and monthly and equipRef->siteMeter and cost\"},\n+              {target:\"steam_intervalCost\",         query:\"steam and interval and equipRef->siteMeter and cost and not savings\"},\n+              {target:\"steam_monthlyRateCost\",      query:\"steam and monthly and equipRef->siteMeter and rateCost\"},\n+              {target:\"steam_intervalSavingsCost\",  query:\"steam and interval and equipRef->siteMeter and savings and cost\"},\n+              {target:\"steam_intervalSavingsCons\",  query:\"steam and interval and equipRef->siteMeter and savings and not cost\"},\n+              {target:\"steam_monthlySavingsCost\",   query:\"steam and monthly and equipRef->siteMeter and savings and cost\"},\n+              {target:\"steam_monthlySavingsCons\",   query:\"steam and monthly and equipRef->siteMeter and savings and not cost\"},\n+\n+    //site meter\n+              {target:\"siteMeter_intervalCost\",     query:\"interval and (energy or consumption) and cost and (not savings)\"},\n+              {target:\"siteMeter_intervalUse\",      query:\"interval and (usage or consumption) and (not modelPoint) and (not cost)\"},\n+              {target:\"siteMeter_monthlyCost\",      query:\"monthly and (energy or consumption) and cost and (not savings)\"},\n+              {target:\"siteMeter_monthlyUse\",       query:\"monthly and (usage or consumption) and (not modelPoint) and (not savings) and (not rateCost) and (not cost)\"},\n+              {target:\"siteMeter_blendedRate\",      query:\"rateCost and (energy or consumption)\"},\n+    //hot water\n+              {target:\"hw_delta_press\",             query:\"hot and water and pressure and delta and sensor\"},\n+              {target:\"hw_flow\",                    query:\"hot and water and flow and sensor\"},\n+              {target:\"hw_pri_pump_speed\",          query:\"hot and water and pump and speed and cmd and primary\"},\n+              {target:\"hw_pri_pump_status\",         query:\"hot and water and pump and run and cmd and primary\"},\n+              {target:\"hw_sec_pump_speed\",          query:\"hot and water and pump and speed and cmd and secondary\"},\n+              {target:\"hw_sec_pump_status\",         query:\"hot and water and pump and run and cmd and secondary\"},\n+              {target:\"hw_pri_pump_power\",          query:\"hot and water and pump and power and sensor and primary\"},\n+              {target:\"hw_sec_pump_power\",          query:\"hot and water and pump and power and sensor and secondary\"},\n+              {target:\"hw_supply_temp\",             query:\"hot and water and supply and temp and sensor\"},\n+              {target:\"hw_return_temp\",             query:\"hot and water and return and temp and sensor and not domestic\"},\n+              {target:\"hw_supply_temp_sp\",          query:\"hot and water and supply and temp and sp\"},\n+              {target:\"hw_delta_press_sp\",          query:\"hot and water and pressure and delta and sp\"},\n+              {target:\"hw_delta_temp\",              query:\"hot and water and temp and delta and sensor\"},\n+              {target:\"hw_sys_load\",                query:\"hot and water and load and energy\"},\n+              {target:\"hw_bypass_valve\",            query:\"hot and water and bypass and valve and cmd\"},\n+\n+    //chilled water\n+              {target:\"chw_delta_press\",             query:\"chilled and water and pressure and delta and sensor\"},\n+              {target:\"chw_flow\",                    query:\"chilled and water and flow and sensor and not bypass\"},\n+              {target:\"chw_pri_pump_speed\",          query:\"chilled and water and pump and speed and cmd and primary\"},\n+              {target:\"chw_sec_pump_speed\",          query:\"chilled and water and pump and speed and cmd and secondary\"},\n+              {target:\"chw_pri_pump_status\",         query:\"chilled and water and pump and run and cmd and primary\"},\n+              {target:\"chw_sec_pump_status\",         query:\"chilled and water and pump and run and cmd and secondary\"},\n+              {target:\"chw_pri_pump_power\",          query:\"chilled and water and pump and power and sensor and primary\"},\n+              {target:\"chw_sec_pump_power\",          query:\"chilled and water and pump and power and sensor and secondary\"},\n+            //{target:\"chw_pri_pump_status\",         query:\"chilled and water and pump and run and cmd and primary\"},\n+            //{target:\"chw_sec_pump_status\",         query:\"chilled and water and pump and run and cmd and secondary\"},\n+              {target:\"chw_supply_temp\",             query:\"chilled and water and supply and temp and sensor\"},\n+              {target:\"chw_return_temp\",             query:\"chilled and water and return and temp and sensor\"},\n+              {target:\"chw_supply_temp_sp\",          query:\"chilled and water and supply and temp and sp\"},\n+              {target:\"chw_delta_press_sp\",          query:\"chilled and water and pressure and delta and sp\"},\n+              {target:\"chw_delta_temp\",              query:\"chilled and water and temp and delta and sensor\"},\n+              {target:\"chw_sys_load\",                query:\"chilled and water and load and energy\"},\n+\n+     //General Pump Points\n+              {target:\"pri_pump_speed\",          query:\"water and pump and speed and cmd and primary\"},\n+              {target:\"sec_pump_speed\",          query:\"water and pump and speed and cmd and secondary\"},\n+              {target:\"pri_pump_status\",         query:\"water and pump and run and cmd and primary\"},\n+              {target:\"sec_pump_status\",         query:\"water and pump and run and cmd and secondary\"},\n+              {target:\"pri_pump_power\",          query:\"water and pump and power and sensor and primary\"},\n+              {target:\"sec_pump_power\",          query:\"water and pump and power and sensor and secondary\"},\n+\n+     //chillers\n+              {target:\"chlr_status\",                   query:\"chiller and cmd and run\"},\n+              {target:\"chlr_power\",                    query:\"chiller and power and sensor\"},\n+              {target:\"chlr_entering_temp\",            query:\"chiller and chilled and entering and temp and water and sensor and not condenser\"},\n+              {target:\"chlr_leaving_temp\",             query:\"chiller and chilled and leaving and temp and water and sensor and not condenser\"},\n+              {target:\"chlr_flow\",                     query:\"chiller and chilled and flow and water and sensor\"},\n+              {target:\"chlr_fla\",                      query:\"chiller and fla and sensor\"},\n+              {target:\"chlr_cw_entering_temp\",         query:\"chiller and condenser and entering and temp and water and sensor\"},\n+              {target:\"chlr_cw_leaving_temp\",          query:\"chiller and condenser and leaving and temp and water and sensor\"},\n+              {target:\"chlr_water_load\",               query:\"chiller and sensor and tonref\"},\n+\n+     //boilers\n+              {target:\"blr_firing_rate\",              query:\"boiler and firingRate and sensor\"},\n+              {target:\"blr_entering_temp\",            query:\"boiler and hot and (entering or return) and temp and water and sensor\"},\n+              {target:\"blr_leaving_temp\",             query:\"boiler and hot and leaving and temp and water and sensor\"},\n+              {target:\"blr_leaving_temp_sp\",          query:\"boiler and hot and leaving and temp and water and sp\"},\n+              {target:\"blr_run_status\",               query:\"boiler and run and cmd\"},\n+              {target:\"blr_enable\",                   query:\"boiler and cmd and enable\"},\n+              {target:\"blr_gas_flow_rate\",            query:\"boiler and flow and rate and sensor and naturalGas\"},\n+              {target:\"blr_flow\",                     query:\"boiler and notImplemented\"},\n+              {target:\"blr_power\",                    query:\"boiler and power and sensor\"},\n+              {target:\"blr_iso_valve\",                query:\"boiler and isolation and valve\"},\n+\n+     //cooling tower\n+              {target:\"clgtwr_leaving_temp\",         query:\"coolingTower and temp and (leaving or supply) and water and sensor\"},\n+              {target:\"clgtwr_entering_temp\",        query:\"coolingTower and temp and (entering or return) and water and sensor\"},\n+              {target:\"clgtwr_fan_speed\",            query:\"coolingTower and fan and speed and air and cmd\"},\n+              {target:\"clgtwr_power\",                query:\"coolingTower and power and sensor\"},\n+              {target:\"clgtwr_fan_status\",           query:\"coolingTower and cmd and run\"},\n+\n+\n+     //condenser water\n+              {target:\"cws_supply_temp\",             query:\"condenser and water and supply and temp and sensor\"},\n+              {target:\"cws_supply_temp_sp\",          query:\"condenser and water and supply and temp and sp\"},\n+              {target:\"cws_return_temp\",             query:\"condenser and water and return and temp and sensor\"},\n+\n+     //miscellaneous\n+              {target:\"wet_bulb\",                    query:\"temp and wetBulb\"},\n+              {target:\"oah_sensor\",                  query:\"humidity and air and point and outside and sensor\"},\n+\n+     // Synthetic points\n+              {target:\"meter_anomaly\",               query:\"anomaly and equipRef->equipRef->siteMeter\"}, // separate out elecMeter_anomaly and gasMeter_anomaly? Resolve -> vs -> ->\n+\n+     //Coil Temps\n+             //hot\n+             {target:\"chw_entg_temp\",                    query:\"chilled and water and valve\"},\n+             {target:\"chw_lvg_temp\",                     query:\"humidity and air and point and outside and sensor\"},\n+\n+             //chilled\n+             {target:\"hw_entg_temp\",                    query:\"temp and wetBulb\"},\n+             {target:\"hw_lvg_temp\",                     query:\"humidity and air and point and outside and sensor\"},\n+\n+             //Baseline Search\n+             {target:\"baseline_calc\",                query:\"point and calculated and modelPoint and not cost and not savings\"},\n+           ].toGrid\n+\n+\n+  if(show) return queries\n+\n+  match: queries.find(r => r.get(\"target\")==target)\n+  if (match.isNull) throw \"Cannot find query: \"+target\n+\n+  out: if (colMeta) match.get(\"colMeta\")\n+       else         match.get(\"query\")\n+\n+  return out\n end"
    },
    {
      "name": "virtualSyncHis",
      "pod": "kwLinkVirtualExt",
      "pod_src": "(recs, span:null, logging:false, taskId:null, heapLimit:95%) => do\n\n  //ogSpan check to use later\n  ogSpan:span\n  ogRecs: recs.toRecList.toGrid.colToList(\"id\")\n\n  //only sync persistent points\n  recs = recs.toRecList\n             .toGrid\n             .filter(virtualPointMode==\"Persistent\")\n\n  //get full list of all dependencies\n  full: virtualSyncOrder(recs).toGrid.filter(virtualPoint and virtualPointMode==\"Persistent\")\n                              .map(r => if (r.isRef) r.toRec else r)\n\n  //list for keeping track of already synced ids\n  syncedIds: []\n\n  //loop through each point\n  results: full.map() r => do\n\n    //check to see if that point was already synced.  If so continue to next point\n    if(syncedIds.contains(r.get(\"id\"))) do\n      if(logging) log(\"info\", {name:\"virtualSyncHis\", point:r->id}, \"Point has already been synced.  Proceeding to next point\")\n      return r=r\n    end\n\n    //Check Heap usage and cancel task if above 95%\n    if(taskId.isNull) log(\"warn\", {name:\"virtualSyncHis\", point:r->id}, \"No task Id provided.  Skipping Heap Check\")\n    if(taskId.isNonNull) do\n      try heapUsed: diags()[5].get(\"attrs\").last.get(\"val\") catch throw \"Please create a task user with userAllow = diags\"\n      if(heapUsed > heapLimit) taskCancel(taskId)\n    end\n\n\n    //initiate loop, log stuff, sleep\n    if (logging) log(\"info\", {name:\"virtualSyncHis\", point:r->id}, \"Sync Triggered\")\n    projSync()\n    hisSync()\n    if (logging) log(\"info\", {name:\"virtualSyncHis\", point:r->id}, \"Proj Sync\")\n\n  try do\n\n    //lookup necessary values\n    virtualFunc: r.get(\"virtualFunc\")\n\n    dependencies: r.virtualDependenciesDown\n    virtualPointOpts: r.get(\"virtualPointOpts\")\n\n    //get span to sync for (if not defined)\n    //hisStart: try dependencies.filter(hisStart).sort(\"hisStart\").first.get(\"hisStart\")\n    //          catch now()-10yr\n    //hisEnd:   try dependencies.filter(hisEnd).sortr(\"hisEnd\").first.get(\"hisEnd\")\n    //          catch now()\n    //\n    //if (span==null) span = (hisStart..hisEnd).toSpan\n    if (span==null) span = (r.get(\"hisEnd\"))..now() //TODO: need error catching here for missing hisEnd. Just use past month.\n    span = span.toSpan\n    if (logging) log(\"info\", {name:\"virtualSyncHis\", point:r->id, span:span}, \"Span set\")\n\n    //initialize return values for grid\n    dependencyCount: dependencies.size\n    virtualDependencyCount: dependencies.filter(virtualPoint).size\n    virtualDependenciesSynced: dependencies.filter(virtualPoint and virtualPointMode==\"Persistent\").size\n    virtualSyncSuccess: \"failed\"\n    syncSpan: span\n    numItemsWritten: 0\n\n    //err values initialize\n    virtualErrDetails: {spanStart:span.start,\n                        spandEnd: span.end,\n                        dependencies:   try dependencies.colToList(\"id\") catch dependencies.size,\n                        virtualPointOpts: if (virtualPointOpts.isNull) \"none\" else virtualPointOpts,\n                        }\n    dependencies.each() (dep,i) => virtualErrDetails=virtualErrDetails.set(\"depDetails\"+i, [dep.get(\"hisEnd\"), dep.get(\"hisEnd\"), dep.get(\"id\")])\n\n    //recursive dependencies\n   // dependencies.each(p => do\n   //   if (p.get(\"virtualPointMode\")==\"Persistent\") do\n   //     p.virtualSyncHis(span) //todo check if this works\n   //   end\n   // end)\n\n    //now, check if all dependencies have his within span\n    dependencies.each(p => do\n      if (p.toRec.missing(\"hisEnd\"))          throw \"Dependency missing hisEnd: \"+p.dis\n      if ((p.toRec.get(\"hisEnd\") < span.start) or (p.toRec.get(\"hisStart\") > span.end)) throw \"Dependency (\"+p.dis+\") missing data within span: \"+span\n    end)\n\n    //try to do it\n    try do\n\n      //get data by running virtualFunc\n      if (logging) log(\"info\", {name:\"virtualSyncHis\", point:r->id, span:span}, \"Calling \"+virtualFunc+ \" with args \")\n      data: virtualFunc.call([r, span])\n\n      //if data is dict, means it errored, throw err\n      if (data.isDict) throw if (data.has(\"virtualErr\")) data.get(\"virtualErr\") else {dis:\"logic returned dict\"}\n      if (data.isEmpty) throw \"logic returned empty\"\n      if (data.isNull) throw \"logic returned null\"\n\n      if (logging) log(\"info\", {name:\"virtualSyncHis\", point:r->id}, \"Data returned with size: \"+data.size)\n\n      //find all the non-null data\n      // Added != nan() check 6/24/2025\n      data = data.findAll(r => r.get(data.colNames[1]).isNonNull and r.get(data.colNames[1]) != nan() and r.get(data.colNames[1]) != na())\n\n      //check if units match\n      dataUnit: data.find(r=>r.get(data.colNames[1]).isNumber).get(data.colNames[1]).unit\n      recUnit: readById(r->id).get(\"unit\")\n      if (logging) log(\"info\", {name:\"virtualSyncHis\", point:r->id}, \"Comparing data/rec units: \"+dataUnit+\"/\"+recUnit)\n      if (readById(r->id).missing(\"hisOnWrite\")) do\n        if (dataUnit!=recUnit and dataUnit!=null and recUnit!=null) r = diff(readById(r->id), {unit:dataUnit}).commit\n        if (dataUnit!=recUnit and dataUnit!=null and recUnit!=null) r = diff(readById(r->id), {virtualMessage:\"WARNING - auto updated mismatched unit from \"+recUnit+\" => \"+dataUnit}, {transient}).commit\n      end\n\n      //check for nan values\n      //hasNanValues: data.find(r => r.vals.any(v=> v.isNaN))!=null\n      //if (hasNanValues) throw \"Data has NaN values\"\n\n      //clear all his for span\n      if (ogSpan==null) hisClear(r, null)\n      else              hisClear(r, span)\n    //if (logging) log(\"info\", {name:\"virtualSyncHis\", point:r->id}, \"Cleared data via hisClear\")\n\n      //check tz\n      if (r.get(\"tz\")!=data.first.get(\"ts\").tz) data = data.map(row=>row.set(\"ts\",row.get(\"ts\").toTimeZone(r.get(\"tz\"))))\n\n      //write data\n      futureWaitFor(hisWrite(data, r))\n      syncedIds = syncedIds.add(r.get(\"id\"))\n      if (logging) log(\"info\", {name:\"virtualSyncHis\", point:r->id}, \"Wrote data via hisWrite\")\n\n      //clear errors and return success\n      point: diff(readById(r->id), {-virtualErr, -virtualErrDetails, virtualStatus:\"ok\"}, {transient}).commit\n\n      //out values\n      virtualSyncSuccess=\"success\"\n      numItemsWritten= data.size\n      scope: if (ogRecs.contains(r.get(\"id\"))) \"Direct\"\n             else \"Dependency\"\n\n      pointResult: {virtualSyncSuccess:virtualSyncSuccess, numItemsWritten:numItemsWritten, dependencyCount:dependencyCount, virtualDependencyCount:virtualDependencyCount, virtualDependenciesSynced:virtualDependenciesSynced, span:span, scope:scope}\n      end\n    catch (err) do\n\n      if (logging) log(\"err\", {name:\"virtualSyncHis\", point:r->id}, \"Data Error\", err)\n\n      dependencyGrid: try dependencies.toGrid.keepCols([\"id\",\"hisEnd\",\"hisSize\",\"hisStart\",\"hisErr\",\"virtualErr\"])\n                      catch null\n\n      point: diff(readById(r->id), {virtualErr:err.dis, virtualErrDetails:virtualErrDetails, virtualStatus:\"failed\"},{transient}).commit\n\n      pointResult: {virtualSyncSuccess:virtualSyncSuccess, virtualErrDetails:virtualErrDetails, span:span}\n      end\n\n    return point.merge(pointResult)\n    end catch (err) do\n\n      if (logging) log(\"err\", {name:\"virtualSyncHis\", point:r->id}, \"General Error\", err)\n\n      //if any errors caught, update point\n      point: diff(readById(r->id), {virtualErr:err.dis, virtualErrDetails:err, virtualStatus:\"failed\"},{transient}).commit\n    end\n  end\n\n  return results.addMeta({view:\"table\"})\n                .reorderKeepCols([\"scope\",\"id\",\"virtualSyncSuccess\",\"virtualStatus\",\"virtualErr\",\"virtualErrDetails\",\"span\",\"numItemsWritten\",\"dependencyCount\",\"virtualDependencyCount\",\"virtualDependenciesSynced\",\"hisEnd\",\"hisStart\"], true)\nend\n\n//changed the error details on line 107 because virtualErrDetails is not defined outside of the scope of the initial try",
      "local_src": "(recs, span:null, logging:false) => do\n\n  //ogSpan check to use later\n  ogSpan:span\n  ogRecs: recs.toRecList.toGrid.colToList(\"id\")\n\n  //only sync persistent points\n  recs = recs.toRecList\n             .toGrid\n             .filter(virtualPointMode==\"Persistent\")\n\n  //get full list of all dependencies\n  full: virtualSyncOrder(recs).toGrid.filter(virtualPoint and virtualPointMode==\"Persistent\")\n                              .map(r => if (r.isRef) r.toRec else r)\n\n  //loop through each point\n  results: full.map() r => do\n\n    //initiate loop, log stuff, sleep\n    if (logging) log(\"info\", {name:\"virtualSyncHis\", point:r->id}, \"Sync Triggered\")\n    projSync()\n    hisSync()\n    if (logging) log(\"info\", {name:\"virtualSyncHis\", point:r->id}, \"Proj Sync\")\n\n  try do\n\n    //lookup necessary values\n    virtualFunc: r.get(\"virtualFunc\")\n\n    dependencies: r.virtualDependenciesDown\n    virtualPointOpts: r.get(\"virtualPointOpts\")\n\n    //get span to sync for (if not defined)\n    //hisStart: try dependencies.filter(hisStart).sort(\"hisStart\").first.get(\"hisStart\")\n    //          catch now()-10yr\n    //hisEnd:   try dependencies.filter(hisEnd).sortr(\"hisEnd\").first.get(\"hisEnd\")\n    //          catch now()\n    //\n    //if (span==null) span = (hisStart..hisEnd).toSpan\n    if (span==null) span = (r.get(\"hisEnd\"))..now()\n    span = span.toSpan\n    if (logging) log(\"info\", {name:\"virtualSyncHis\", point:r->id, span:span}, \"Span set\")\n\n    //initialize return values for grid\n    dependencyCount: dependencies.size\n    virtualDependencyCount: dependencies.filter(virtualPoint).size\n    virtualDependenciesSynced: dependencies.filter(virtualPoint and virtualPointMode==\"Persistent\").size\n    virtualSyncSuccess: \"failed\"\n    syncSpan: span\n    numItemsWritten: 0\n\n    //err values initialize\n    virtualErrDetails: {spanStart:span.start,\n                        spandEnd: span.end,\n                        dependencies:   try dependencies.colToList(\"id\") catch dependencies.size,\n                        virtualPointOpts: if (virtualPointOpts.isNull) \"none\" else virtualPointOpts,\n                        }\n    dependencies.each() (dep,i) => virtualErrDetails=virtualErrDetails.set(\"depDetails\"+i, [dep.get(\"hisEnd\"), dep.get(\"hisEnd\"), dep.get(\"id\")])\n\n    //recursive dependencies\n   // dependencies.each(p => do\n   //   if (p.get(\"virtualPointMode\")==\"Persistent\") do\n   //     p.virtualSyncHis(span) //todo check if this works\n   //   end\n   // end)\n\n    //now, check if all dependencies have his within span\n    dependencies.each(p => do\n      if (p.toRec.missing(\"hisEnd\"))          throw \"Dependency missing hisEnd: \"+p.dis\n      if ((p.toRec.get(\"hisEnd\") < span.start) or (p.toRec.get(\"hisStart\") > span.end)) throw \"Dependency (\"+p.dis+\") missing data within span: \"+span\n    end)\n\n    //try to do it\n    try do\n\n      //get data by running virtualFunc\n      if (logging) log(\"info\", {name:\"virtualSyncHis\", point:r->id, span:span}, \"Calling \"+virtualFunc+ \" with args \")\n      data: virtualFunc.call([r, span])\n\n      //if data is dict, means it errored, throw err\n      if (data.isDict) throw if (data.has(\"virtualErr\")) data.get(\"virtualErr\") else {dis:\"logic returned dict\"}\n      if (data.isEmpty) throw \"logic returned empty\"\n      if (data.isNull) throw \"logic returned null\"\n\n      if (logging) log(\"info\", {name:\"virtualSyncHis\", point:r->id}, \"Data returned with size: \"+data.size)\n\n      //find all the non-null data\n      data = data.findAll(r => r.get(data.colNames[1]).isNonNull)\n\n      //check if units match\n      dataUnit: data.find(r=>r.get(data.colNames[1]).isNumber).get(data.colNames[1]).unit\n      recUnit: readById(r->id).get(\"unit\")\n      if (logging) log(\"info\", {name:\"virtualSyncHis\", point:r->id}, \"Comparing data/rec units: \"+dataUnit+\"/\"+recUnit)\n      if (readById(r->id).missing(\"hisOnWrite\")) do\n        if (dataUnit!=recUnit and dataUnit!=null and recUnit!=null) r = diff(readById(r->id), {unit:dataUnit}).commit\n        if (dataUnit!=recUnit and dataUnit!=null and recUnit!=null) r = diff(readById(r->id), {virtualMessage:\"WARNING - auto updated mismatched unit from \"+recUnit+\" => \"+dataUnit}, {transient}).commit\n      end\n\n      //check for nan values\n      hasNanValues: data.find(r => r.vals.any(v=> v.isNaN))!=null\n      if (hasNanValues) throw \"Data has NaN values\"\n\n      //clear all his for span\n      if (ogSpan==null) hisClear(r, null)\n      else              hisClear(r, span)\n    //if (logging) log(\"info\", {name:\"virtualSyncHis\", point:r->id}, \"Cleared data via hisClear\")\n\n      //write data\n//CHANGE      \n      if(r.has(\"euiContributor\")) do\n      \n        data = data.map(s=> s.merge({ts: s.get(\"ts\").toTimeZone(\"Denver\")}))\n        data = data.reorderKeepCols([\"ts\"])\n        diff(r, {stopError: data}, {update}).commit\n      end\n      hisWrite(data, r, null)\n      if (logging) log(\"info\", {name:\"virtualSyncHis\", point:r->id}, \"Wrote data via hisWrite\")\n\n      //clear errors and return success\n      point: diff(readById(r->id), {-virtualErr, -virtualErrDetails, virtualStatus:\"ok\"}, {transient}).commit\n\n      //out values\n      virtualSyncSuccess=\"success\"\n      numItemsWritten= data.size\n      scope: if (ogRecs.contains(r.get(\"id\"))) \"Direct\"\n             else \"Dependency\"\n\n      pointResult: {virtualSyncSuccess:virtualSyncSuccess, numItemsWritten:numItemsWritten, dependencyCount:dependencyCount, virtualDependencyCount:virtualDependencyCount, virtualDependenciesSynced:virtualDependenciesSynced, span:span, scope:scope}\n      end\n    catch (err) do\n\n      if (logging) log(\"err\", {name:\"virtualSyncHis\", point:r->id}, \"Data Error\", err)\n\n      dependencyGrid: try dependencies.toGrid.keepCols([\"id\",\"hisEnd\",\"hisSize\",\"hisStart\",\"hisErr\",\"virtualErr\"])\n                      catch null\n\n      point: diff(readById(r->id), {virtualErr:err.dis, virtualErrDetails:virtualErrDetails, virtualStatus:\"failed\"},{transient}).commit\n\n      pointResult: {virtualSyncSuccess:virtualSyncSuccess, virtualErrDetails:virtualErrDetails, span:span}\n      end\n\n    return point.merge(pointResult)\n    end catch (err) do\n\n      if (logging) log(\"err\", {name:\"virtualSyncHis\", point:r->id}, \"General Error\", err)\n\n      //if any errors caught, update point\n      point: diff(readById(r->id), {virtualErr:err.dis, virtualErrDetails:err, virtualStatus:\"failed\"},{transient}).commit\n    end\n  end\n\n  return results.addMeta({view:\"table\"})\n                .reorderKeepCols([\"scope\",\"id\",\"virtualSyncSuccess\",\"virtualStatus\",\"virtualErr\",\"virtualErrDetails\",\"span\",\"numItemsWritten\",\"dependencyCount\",\"virtualDependencyCount\",\"virtualDependenciesSynced\",\"hisEnd\",\"hisStart\"], true)\nend\n\n//changed the error details on line 107 because virtualErrDetails is not defined outside of the scope of the initial try",
      "diff": "@@ -1,4 +1,4 @@-(recs, span:null, logging:false, taskId:null, heapLimit:95%) => do\n+(recs, span:null, logging:false) => do\n \n   //ogSpan check to use later\n   ogSpan:span\n@@ -13,25 +13,8 @@   full: virtualSyncOrder(recs).toGrid.filter(virtualPoint and virtualPointMode==\"Persistent\")\n                               .map(r => if (r.isRef) r.toRec else r)\n \n-  //list for keeping track of already synced ids\n-  syncedIds: []\n-\n   //loop through each point\n   results: full.map() r => do\n-\n-    //check to see if that point was already synced.  If so continue to next point\n-    if(syncedIds.contains(r.get(\"id\"))) do\n-      if(logging) log(\"info\", {name:\"virtualSyncHis\", point:r->id}, \"Point has already been synced.  Proceeding to next point\")\n-      return r=r\n-    end\n-\n-    //Check Heap usage and cancel task if above 95%\n-    if(taskId.isNull) log(\"warn\", {name:\"virtualSyncHis\", point:r->id}, \"No task Id provided.  Skipping Heap Check\")\n-    if(taskId.isNonNull) do\n-      try heapUsed: diags()[5].get(\"attrs\").last.get(\"val\") catch throw \"Please create a task user with userAllow = diags\"\n-      if(heapUsed > heapLimit) taskCancel(taskId)\n-    end\n-\n \n     //initiate loop, log stuff, sleep\n     if (logging) log(\"info\", {name:\"virtualSyncHis\", point:r->id}, \"Sync Triggered\")\n@@ -54,7 +37,7 @@     //          catch now()\n     //\n     //if (span==null) span = (hisStart..hisEnd).toSpan\n-    if (span==null) span = (r.get(\"hisEnd\"))..now() //TODO: need error catching here for missing hisEnd. Just use past month.\n+    if (span==null) span = (r.get(\"hisEnd\"))..now()\n     span = span.toSpan\n     if (logging) log(\"info\", {name:\"virtualSyncHis\", point:r->id, span:span}, \"Span set\")\n \n@@ -102,8 +85,7 @@       if (logging) log(\"info\", {name:\"virtualSyncHis\", point:r->id}, \"Data returned with size: \"+data.size)\n \n       //find all the non-null data\n-      // Added != nan() check 6/24/2025\n-      data = data.findAll(r => r.get(data.colNames[1]).isNonNull and r.get(data.colNames[1]) != nan() and r.get(data.colNames[1]) != na())\n+      data = data.findAll(r => r.get(data.colNames[1]).isNonNull)\n \n       //check if units match\n       dataUnit: data.find(r=>r.get(data.colNames[1]).isNumber).get(data.colNames[1]).unit\n@@ -115,20 +97,23 @@       end\n \n       //check for nan values\n-      //hasNanValues: data.find(r => r.vals.any(v=> v.isNaN))!=null\n-      //if (hasNanValues) throw \"Data has NaN values\"\n+      hasNanValues: data.find(r => r.vals.any(v=> v.isNaN))!=null\n+      if (hasNanValues) throw \"Data has NaN values\"\n \n       //clear all his for span\n       if (ogSpan==null) hisClear(r, null)\n       else              hisClear(r, span)\n     //if (logging) log(\"info\", {name:\"virtualSyncHis\", point:r->id}, \"Cleared data via hisClear\")\n \n-      //check tz\n-      if (r.get(\"tz\")!=data.first.get(\"ts\").tz) data = data.map(row=>row.set(\"ts\",row.get(\"ts\").toTimeZone(r.get(\"tz\"))))\n+      //write data\n+//CHANGE\n+      if(r.has(\"euiContributor\")) do\n \n-      //write data\n-      futureWaitFor(hisWrite(data, r))\n-      syncedIds = syncedIds.add(r.get(\"id\"))\n+        data = data.map(s=> s.merge({ts: s.get(\"ts\").toTimeZone(\"Denver\")}))\n+        data = data.reorderKeepCols([\"ts\"])\n+        diff(r, {stopError: data}, {update}).commit\n+      end\n+      hisWrite(data, r, null)\n       if (logging) log(\"info\", {name:\"virtualSyncHis\", point:r->id}, \"Wrote data via hisWrite\")\n \n       //clear errors and return success\n"
    },
    {
      "name": "action_editNormSavingsRec",
      "pod": "kwLinkModelExt",
      "pod_src": "//\n// Copyright (c) 2024, kW Engineering\n// All Rights Reserved\n//\n// History\n//   Date:       Name:                 Description:\n//   DD MMM 22   Dylan Bardin          - Creation.\n//   05 Jul 24   Thomas Kuhrke Limia   - Refactorization and code documentation.\n//\n// Description\n//   This action edits an existing normalized saving record.\n//\n// Parameters\n//   Name                 Type(s)                                                               DefVal\n//   1. sel               Dict\n//\n// Returns\n//   Type           Description\n//   1. None        - N/A\n//\n(dict) => do\n  // Normalize Input\n  changes: actionNormInput(dict, \"dict\")\n\n  // Initialize variables\n  flag: false\n  type: \"\"\n  spans: \"\"\n\n  // If the normRefPtCsv has a file in the io folder already, delete it.\n  if(changes.get(\"normRefPtCsv\") == `io/`) changes = changes.set(\"normRefPtCsv\", null)\n\n  // Remove unnecessary elements from dict, and check the size.\n  keys: changes.remove(\"pointRef\").remove(\"normSrc\").remove(\"normRefPtSpan\").names()\n  if(keys.size > 1) throw \"Only one normalized source may be selected at once\"\n\n  // Get the normalized source\n  normSrc: changes.get(keys[0])\n  keys = changes.remove(\"pointRef\").remove(\"normSrc\").names()\n\n  // Validate differently if the reference is a csv or a rec.\n  if(keys.contains(\"normRefPtCsv\")) do\n    flag = func_validateNormSource(normSrc, \"csv\", \"validate\")\n    type = \"csv\"\n  else if(keys.contains(\"normRefRec\")) do\n    flag = func_validateNormSource(normSrc, \"rec\", \"validate\")\n    type = \"rec\"\n  end\n\n  // If keys contains the normRefPt, get its span, check that it is 8760hrs, and if so, attempt to validate.\n  // Throw otherwise.\n  if(keys.contains(\"normRefPt\")) do\n    span: changes.get(\"normRefPtSpan\")\n    spanElapsed: (span.end - span.start).to(\"h\")\n    if(spanElapsed != 8760) throw \"Span must contain 8760 hours of data exactly. Supplied:\" + spanElapsed.toStr\n    flag = func_validateNormSource(normSrc, \"pt\", \"validate\", span)\n    type = \"pt\"\n    spans = span\n  end\n\n  // If flag was not changed to true, that means the validation func couldn't validate the source, so we throw.\n  if(flag == false) throw \"Norm Validation Failed\"\n\n  // Retrieve viewConfig point\n  viewConfig: try read(normConfigRecord and kWModelingApp and pointRef == changes.get(\"pointRef\")) catch throw \"Must select two compatible models to use this action\"\n\n  if   (type != \"pt\" ) diff(viewConfig, {\"normSrc\":normSrc, \"normType\": type}, null).commit\n  else                 diff(viewConfig, {\"normSrc\":normSrc, \"normType\": type, \"ptSpan\": spans}, null).commit\nend",
      "local_src": "//\n// Copyright (c) 2024, kW Engineering\n// All Rights Reserved\n//\n// History\n//   Date:       Name:                 Description:\n//   DD MMM 22   Dylan Bardin          - Creation.\n//   05 Jul 24   Thomas Kuhrke Limia   - Refactorization and code documentation.\n//\n// Description\n//   This action edits an existing normalized saving record.\n//\n// Parameters\n//   Name                 Type(s)                                                               DefVal\n//   1. sel               Dict\n//\n// Returns\n//   Type           Description\n//   1. None        - N/A\n//\n(dict) => do\n  // Normalize Input\n  changes: actionNormInput(dict, \"dict\")\n\n  // Initialize variables\n  flag: false\n  type: \"\"\n  spans: \"\"\n\n  // If the normRefPtCsv has a file in the io folder already, delete it.\n  if(changes.get(\"normRefPtCsv\") == `io/`) changes = changes.remove(\"normRefPtCsv\") //.set(\"normRefPtCsv\", null)\n\n  // Remove unnecessary elements from dict, and check the size.\n  keys: changes.remove(\"pointRef\").remove(\"normSrc\").remove(\"normRefPtSpan\").names()\n  //throw keys\n  if(keys.size > 1) throw \"Only one normalized source may be selected at once\"\n\n  // Get the normalized source\n  normSrc: changes.get(keys[0])\n  keys = changes.remove(\"pointRef\").remove(\"normSrc\").names()\n\n  // Validate differently if the reference is a csv or a rec.\n  if(keys.contains(\"normRefPtCsv\")) do\n    flag = func_validateNormSource(normSrc, \"csv\", \"validate\")\n    type = \"csv\"\n  else if(keys.contains(\"normRefRec\")) do\n    flag = func_validateNormSource(normSrc, \"rec\", \"validate\")\n    type = \"rec\"\n  end\n\n  // If keys contains the normRefPt, get its span, check that it is 8760hrs, and if so, attempt to validate.\n  // Throw otherwise.\n  if(keys.contains(\"normRefPt\")) do\n    span: changes.get(\"normRefPtSpan\")\n    spanElapsed: (span.end - span.start).to(\"h\")\n    if(spanElapsed != 8760) throw \"Span must contain 8760 hours of data exactly. Supplied:\" + spanElapsed.toStr\n    flag = func_validateNormSource(normSrc, \"pt\", \"validate\", span)\n    type = \"pt\"\n    spans = span\n  end\n\n  // If flag was not changed to true, that means the validation func couldn't validate the source, so we throw.\n  if(flag == false) throw \"Norm Validation Failed\"\n\n  // Retrieve viewConfig point\n  viewConfig: try read(normConfigRecord and kWModelingApp and pointRef == changes.get(\"pointRef\")) catch throw \"Must select two compatible models to use this action\"\n\n  if   (type != \"pt\" ) diff(viewConfig, {\"normSrc\":normSrc, \"normType\": type}, null).commit\n  else                 diff(viewConfig, {\"normSrc\":normSrc, \"normType\": type, \"ptSpan\": spans}, null).commit\nend",
      "diff": "@@ -28,10 +28,11 @@   spans: \"\"\n \n   // If the normRefPtCsv has a file in the io folder already, delete it.\n-  if(changes.get(\"normRefPtCsv\") == `io/`) changes = changes.set(\"normRefPtCsv\", null)\n+  if(changes.get(\"normRefPtCsv\") == `io/`) changes = changes.remove(\"normRefPtCsv\") //.set(\"normRefPtCsv\", null)\n \n   // Remove unnecessary elements from dict, and check the size.\n   keys: changes.remove(\"pointRef\").remove(\"normSrc\").remove(\"normRefPtSpan\").names()\n+  //throw keys\n   if(keys.size > 1) throw \"Only one normalized source may be selected at once\"\n \n   // Get the normalized source\n"
    },
    {
      "name": "calcTMRASavings",
      "pod": "kwLinkVirtualExt",
      "pod_src": "(siteId, savingsHis, modelPt,  meterPt, performancePeriodStartDate, performancePeriodEndDate, mildTempRangeLower: \"40\", mildTempRangeUpper: \"65\") => do\n  mildTempRange: (mildTempRangeLower.parseNumber.as(\"\u00b0F\")..mildTempRangeUpper.parseNumber.as(\"\u00b0F\"))\n  performancePeriod : (performancePeriodStartDate..performancePeriodEndDate).toDateSpan\n  siteRec: siteId.toRec\n  schedule: siteRec.get(\"scheduleRef\")\n  scheduleRec: schedule.toRec\n  tempPt: read(temp and weatherStationRef == siteRec.get(\"weatherStationRef\"))\n  baselinePeriod: modelPt.get(\"modeledDataSpan\")\n  modelBaselineHis: modelPt.hisRead(baselinePeriod, {-limit}).hisRollup(avg, 1hr)\n  meterBaselineHis: meterPt.hisRead(baselinePeriod, {-limit}).hisRollup(avg, 1hr)\n  tempBaselineHis: tempPt.hisRead(baselinePeriod, {-limit}).hisRollup(avg, 1hr)\n\n  modelPerformanceHis: modelPt.hisRead(performancePeriod, {-limit}).hisRollup(avg, 1hr)\n  meterPerformanceHis: meterPt.hisRead(performancePeriod, {-limit}).hisRollup(avg, 1hr)\n  tempPerformanceHis: tempPt.hisRead(performancePeriod, {-limit}).hisRollup(avg, 1hr)\n  baselineHis: hisJoin([modelBaselineHis, meterBaselineHis, tempBaselineHis])\n  baselineHis = baselineHis.map(r => if(mildTempRange.contains(r.get(\"v2\"))) return r else return r = null).removeCols([\"v2\"])\n  performanceHis: hisJoin([modelPerformanceHis, meterPerformanceHis, tempPerformanceHis])\n  performanceHis = performanceHis.map(r => if(mildTempRange.contains(r.get(\"v2\"))) return r else return r = null).removeCols([\"v2\"])\n\n  baselineResiduals: addColTwoPointDelta(baselineHis, \"delta\",  \"v1\", \"v0\").keepCols([\"ts\", \"delta\"]).renameCol(\"delta\", \"baselineResiduals\")\n  performanceResiduals: addColTwoPointDelta(performanceHis, \"delta\",  \"v1\", \"v0\").keepCols([\"ts\", \"delta\"]).renameCol(\"delta\", \"performanceResiduals\")\n  baselineResidualTrend: baselineResiduals.checkResidualTrend(tempBaselineHis)\n\n  performanceResidualTrend: performanceResiduals.checkResidualTrend(tempPerformanceHis)\n  if(baselineResidualTrend.get(\"r2\") > 0.2 or performanceResidualTrend.get(\"r2\") > 0.2) return {\"msg\": \"TMRA not applicable\",\n                                                                                                \"reason\": \"Residuals in mildBand have trend\",\n                                                                                                \"baselineR_two\":baselineResidualTrend.get(\"r2\"),\n                                                                                                \"performanceR_two\":performanceResidualTrend.get(\"r2\")}\n  onPeakBaselineResiduals: baselineResiduals.map(r => if(schedule.scheduleValAt(r.get(\"ts\"))==true) return r else return null)\n  offPeakBaselineResiduals: baselineResiduals.map(r => if(schedule.scheduleValAt(r.get(\"ts\")).isNull) return r else return null)\n  presentBaselineResiduals: hisJoin([onPeakBaselineResiduals.addColMeta(\"baselineResiduals\", {dis: \"On Peak Residuals\" + \", n= \" + onPeakBaselineResiduals.size}).renameCol(\"baselineResiduals\", \"onPeakResiduals\"),\n                                     offPeakBaselineResiduals.addColMeta(\"baselineResiduals\", {dis: \"Off Peak Residuals\" + \", n= \" + offPeakBaselineResiduals.size}).renameCol(\"baselineResiduals\", \"offPeakResiduals\")])\n  offPeak: 0\n  onPeak: 0\n  cusumBaselineResiduals: presentBaselineResiduals.map r => do\n    ts: r.get(\"ts\")\n    offPeak = if(r.get(\"offPeakResiduals\").isNull) offPeak else offPeak + r.get(\"offPeakResiduals\")\n    onPeak = if(r.get(\"onPeakResiduals\").isNull) onPeak else onPeak + r.get(\"onPeakResiduals\")\n    return {\"ts\": ts, \"offPeakCuSum\": offPeak.as(\"kWh\"), \"onPeakCuSum\": onPeak.as(\"kWh\")}\n  end\n  cusumBaselineResiduals = cusumBaselineResiduals.addColMeta(\"offPeakCuSum\", {\"chartGroup\": \"one\", \"unit\": \"kWh\"}).addColMeta(\"onPeakCuSum\", {\"chartGroup\": \"one\", \"unit\": \"kWh\"})\n\n\n  onPeakPerformanceResiduals: performanceResiduals.map(r => if(schedule.scheduleValAt(r.get(\"ts\"))==true) return r else return null)\n  offPeakPerformanceResiduals: performanceResiduals.map(r => if(schedule.scheduleValAt(r.get(\"ts\")).isNull) return r else return null)\n  presentPerformanceResiduals: hisJoin([onPeakPerformanceResiduals.addColMeta(\"performanceResiduals\", {dis: \"On Peak Residuals\" + \", n= \" + onPeakPerformanceResiduals.size}).renameCol(\"performanceResiduals\", \"onPeakResiduals\"),\n                                        offPeakPerformanceResiduals.addColMeta(\"performanceResiduals\", {dis: \"Off Peak Residuals\" + \", n= \" + offPeakPerformanceResiduals.size}).renameCol(\"performanceResiduals\", \"offPeakResiduals\")])\n  offPeak= 0\n  onPeak= 0\n  cusumPerformanceResiduals: presentPerformanceResiduals.map r => do\n    ts: r.get(\"ts\")\n    offPeak = if(r.get(\"offPeakResiduals\").isNull) offPeak else offPeak + r.get(\"offPeakResiduals\")\n    onPeak = if(r.get(\"onPeakResiduals\").isNull) onPeak else onPeak + r.get(\"onPeakResiduals\")\n    return {\"ts\": ts, \"offPeakCuSum\": offPeak.as(\"kWh\"), \"onPeakCuSum\": onPeak.as(\"kWh\")}\n  end\n  cusumPerformanceResiduals = cusumPerformanceResiduals.addColMeta(\"offPeakCuSum\", {\"chartGroup\": \"two\", \"unit\": \"kWh\"}).addColMeta(\"onPeakCuSum\", {\"chartGroup\": \"two\", \"unit\": \"kWh\"})\n  onPeakBaselineMedian: onPeakBaselineResiduals.hisRollup(median, \"*\").first.get(\"baselineResiduals\")\n  offPeakBaselineMedian: offPeakBaselineResiduals.hisRollup(median, \"*\").first.get(\"baselineResiduals\")\n  onPeakPerformanceMedian: onPeakPerformanceResiduals.hisRollup(median, \"*\").first.get(\"performanceResiduals\")\n  offPeakPerformanceMedian: offPeakPerformanceResiduals.hisRollup(median, \"*\").first.get(\"performanceResiduals\")\n  adderDict: {\"onPeakAdder\": (onPeakPerformanceMedian - onPeakBaselineMedian),\n              \"offPeakAdder\": (offPeakPerformanceMedian - offPeakBaselineMedian)}\n  savingsAfterTMRA: savingsHis.map r => do\n    if(performancePeriod.contains(r.get(\"ts\").date)) do\n      ts: r.get(\"ts\")\n      offPeakAdder: if(adderDict.get(\"offPeakAdder\")<3) 0 else adderDict.get(\"offPeakAdder\")\n      onPeakAdder: if(adderDict.get(\"onPeakAdder\")<3) 0 else adderDict.get(\"onPeakAdder\")\n      adder: if(scheduleRec.scheduleValAt(ts).isNull) offPeakAdder else onPeakAdder\n      return r = r.set(\"delta\", r.get(\"delta\") + adder)\n    end else return r\n  end\n  return savingsAfterTMRA\nend",
      "local_src": "(siteId, savingsHis, modelPt,  meterPt, performancePeriodStartDate, performancePeriodEndDate, mildTempRangeLower: \"35\", mildTempRangeUpper: \"50\") => do\n  mildTempRange: (mildTempRangeLower.parseNumber.as(\"\u00b0F\")..mildTempRangeUpper.parseNumber.as(\"\u00b0F\"))\n  performancePeriod : (performancePeriodStartDate..performancePeriodEndDate).toDateSpan\n  siteRec: siteId.toRec\n  schedule: siteRec.get(\"scheduleRef\")\n  scheduleRec: schedule.toRec\n  tempPt: read(temp and weatherStationRef == siteRec.get(\"weatherStationRef\"))\n  baselinePeriod: modelPt.get(\"modeledDataSpan\")\n  modelBaselineHis: modelPt.hisRead(baselinePeriod, {-limit}).hisRollup(avg, 1hr)\n  meterBaselineHis: meterPt.hisRead(baselinePeriod, {-limit}).hisRollup(avg, 1hr)\n  tempBaselineHis: tempPt.hisRead(baselinePeriod, {-limit}).hisRollup(avg, 1hr)\n \n  modelPerformanceHis: modelPt.hisRead(performancePeriod, {-limit}).hisRollup(avg, 1hr)\n  meterPerformanceHis: meterPt.hisRead(performancePeriod, {-limit}).hisRollup(avg, 1hr)\n  tempPerformanceHis: tempPt.hisRead(performancePeriod, {-limit}).hisRollup(avg, 1hr)\n  baselineHis: hisJoin([modelBaselineHis, meterBaselineHis, tempBaselineHis])\n  baselineHis = baselineHis.map(r => if(mildTempRange.contains(r.get(\"v2\"))) return r else return r = null).removeCols([\"v2\"])\n  performanceHis: hisJoin([modelPerformanceHis, meterPerformanceHis, tempPerformanceHis])\n  performanceHis = performanceHis.map(r => if(mildTempRange.contains(r.get(\"v2\"))) return r else return r = null).removeCols([\"v2\"])\n\n  baselineResiduals: addColTwoPointDelta(baselineHis, \"delta\",  \"v1\", \"v0\").keepCols([\"ts\", \"delta\"]).renameCol(\"delta\", \"baselineResiduals\")\n  performanceResiduals: addColTwoPointDelta(performanceHis, \"delta\",  \"v1\", \"v0\").keepCols([\"ts\", \"delta\"]).renameCol(\"delta\", \"performanceResiduals\")\n  baselineResidualTrend: baselineResiduals.checkResidualTrend(tempBaselineHis)\n \n  performanceResidualTrend: performanceResiduals.checkResidualTrend(tempPerformanceHis)\n  if(baselineResidualTrend.get(\"r2\") > 0.2 or performanceResidualTrend.get(\"r2\") > 0.2) return {\"msg\": \"TMRA not applicable\",\n                                                                                                \"reason\": \"Residuals in mildBand have trend\",\n                                                                                                \"baselineR_two\":baselineResidualTrend.get(\"r2\"),\n                                                                                                \"performanceR_two\":performanceResidualTrend.get(\"r2\")}\n  onPeakBaselineResiduals: baselineResiduals.map(r => if(schedule.scheduleValAt(r.get(\"ts\"))==true) return r else return null)\n  offPeakBaselineResiduals: baselineResiduals.map(r => if(schedule.scheduleValAt(r.get(\"ts\")).isNull) return r else return null)\n  presentBaselineResiduals: hisJoin([onPeakBaselineResiduals.addColMeta(\"baselineResiduals\", {dis: \"On Peak Residuals\" + \", n= \" + onPeakBaselineResiduals.size}).renameCol(\"baselineResiduals\", \"onPeakResiduals\"), \n                                     offPeakBaselineResiduals.addColMeta(\"baselineResiduals\", {dis: \"Off Peak Residuals\" + \", n= \" + offPeakBaselineResiduals.size}).renameCol(\"baselineResiduals\", \"offPeakResiduals\")])\n  offPeak: 0\n  onPeak: 0\n  cusumBaselineResiduals: presentBaselineResiduals.map r => do\n    ts: r.get(\"ts\")\n    offPeak = if(r.get(\"offPeakResiduals\").isNull) offPeak else offPeak + r.get(\"offPeakResiduals\")\n    onPeak = if(r.get(\"onPeakResiduals\").isNull) onPeak else onPeak + r.get(\"onPeakResiduals\")\n    return {\"ts\": ts, \"offPeakCuSum\": offPeak.as(\"kWh\"), \"onPeakCuSum\": onPeak.as(\"kWh\")}\n  end\n  cusumBaselineResiduals = cusumBaselineResiduals.addColMeta(\"offPeakCuSum\", {\"chartGroup\": \"one\", \"unit\": \"kWh\"}).addColMeta(\"onPeakCuSum\", {\"chartGroup\": \"one\", \"unit\": \"kWh\"})\n \n                                                                              \n  onPeakPerformanceResiduals: performanceResiduals.map(r => if(schedule.scheduleValAt(r.get(\"ts\"))==true) return r else return null)\n  offPeakPerformanceResiduals: performanceResiduals.map(r => if(schedule.scheduleValAt(r.get(\"ts\")).isNull) return r else return null)\n  presentPerformanceResiduals: hisJoin([onPeakPerformanceResiduals.addColMeta(\"performanceResiduals\", {dis: \"On Peak Residuals\" + \", n= \" + onPeakPerformanceResiduals.size}).renameCol(\"performanceResiduals\", \"onPeakResiduals\"), \n                                        offPeakPerformanceResiduals.addColMeta(\"performanceResiduals\", {dis: \"Off Peak Residuals\" + \", n= \" + offPeakPerformanceResiduals.size}).renameCol(\"performanceResiduals\", \"offPeakResiduals\")])\n  offPeak= 0\n  onPeak= 0\n  cusumPerformanceResiduals: presentPerformanceResiduals.map r => do\n    ts: r.get(\"ts\")\n    offPeak = if(r.get(\"offPeakResiduals\").isNull) offPeak else offPeak + r.get(\"offPeakResiduals\")\n    onPeak = if(r.get(\"onPeakResiduals\").isNull) onPeak else onPeak + r.get(\"onPeakResiduals\")\n    return {\"ts\": ts, \"offPeakCuSum\": offPeak.as(\"kWh\"), \"onPeakCuSum\": onPeak.as(\"kWh\")}\n  end\n  cusumPerformanceResiduals = cusumPerformanceResiduals.addColMeta(\"offPeakCuSum\", {\"chartGroup\": \"two\", \"unit\": \"kWh\"}).addColMeta(\"onPeakCuSum\", {\"chartGroup\": \"two\", \"unit\": \"kWh\"})\n  onPeakBaselineMedian: onPeakBaselineResiduals.hisRollup(median, \"*\").first.get(\"baselineResiduals\")\n  offPeakBaselineMedian: offPeakBaselineResiduals.hisRollup(median, \"*\").first.get(\"baselineResiduals\")\n  onPeakPerformanceMedian: onPeakPerformanceResiduals.hisRollup(median, \"*\").first.get(\"performanceResiduals\")\n  offPeakPerformanceMedian: offPeakPerformanceResiduals.hisRollup(median, \"*\").first.get(\"performanceResiduals\")\n  adderDict: {\"onPeakAdder\": (onPeakPerformanceMedian - onPeakBaselineMedian),\n              \"offPeakAdder\": (offPeakPerformanceMedian - offPeakBaselineMedian)}\n  savingsAfterTMRA: savingsHis.map r => do\n    if(performancePeriod.contains(r.get(\"ts\").date)) do \n      ts: r.get(\"ts\")\n      offPeakAdder: if(adderDict.get(\"offPeakAdder\")<3) 0 else adderDict.get(\"offPeakAdder\")\n      onPeakAdder: if(adderDict.get(\"onPeakAdder\")<3) 0 else adderDict.get(\"onPeakAdder\")\n      adder: if(scheduleRec.scheduleValAt(ts).isNull) offPeakAdder else onPeakAdder\n      return r = r.set(\"delta\", r.get(\"delta\") + adder)\n    end else return r\n  end\n  return savingsAfterTMRA\nend",
      "diff": "@@ -1,4 +1,4 @@-(siteId, savingsHis, modelPt,  meterPt, performancePeriodStartDate, performancePeriodEndDate, mildTempRangeLower: \"40\", mildTempRangeUpper: \"65\") => do\n+(siteId, savingsHis, modelPt,  meterPt, performancePeriodStartDate, performancePeriodEndDate, mildTempRangeLower: \"35\", mildTempRangeUpper: \"50\") => do\n   mildTempRange: (mildTempRangeLower.parseNumber.as(\"\u00b0F\")..mildTempRangeUpper.parseNumber.as(\"\u00b0F\"))\n   performancePeriod : (performancePeriodStartDate..performancePeriodEndDate).toDateSpan\n   siteRec: siteId.toRec\n"
    },
    {
      "name": "wdg_normalizedSavingsConfig",
      "pod": "kwLinkModelExt",
      "pod_src": "//\n// Copyright (c) 2024, kW Engineering\n// All Rights Reserved\n//\n// History\n//   Date:       Name:                 Description:\n//   DD MMM 22   Dylan Bardin          - Creation.\n//   09 Aug 24   Thomas Kuhrke Limia   - Refactorization and code documentation.\n//\n// Description\n//   This function represents the widget for normalized savings configuration.\n//\n// Parameters\n//   Name                 Type(s)\n//   siteID               Ref\n//   baselineModel        Ref\n//   performanceModel     Ref\n//   query                Str\n//\n// Returns\n//   Type           Description\n//   1. TODO        - TODO\n//\n// NOTES\n// - Re-organize and refactor widget.\n//\n(siteID, baselineModel, performanceModel, query: \"write\") => do\n\n  weatherStr: try \"Normalized Weather Records for \" + readById(siteID)->dis.toStr catch \"Normalized Records for Selected Site\"\n  ivStr:  try \"Normalized Records for \" + readById(siteID)->dis.toStr catch \"Normalized Records for Selected Site\"\n  baselineModelRec: readById(baselineModel)\n  performanceModelRec: readById(performanceModel)\n\n  if(baselineModelRec.get(\"modelType\") != performanceModelRec.get(\"modelType\")) do\n    if(query == \"write\") func_normConfigRecord(null, true)\n    return {\"error\": \"Mismatched Model Types\"}.toGrid.setMeta({\"title\": \"Independent Variable\", \"subtitle\": ivStr})\n  else do\n    baselineModelIVars : try [baselineModelRec.get(\"modelConfig\").get(\"viewInputs\").get(\"temp\")] catch [read(temp and weatherStationRef == baselineModelRec.get(\"modelConfig\").get(\"weather\")).get(\"id\")]\n    baselineModelIVars = try baselineModelIVars.addAll([baselineModelRec.get(\"modelConfig\").get(\"settings\")->additionalPoint]).flatten catch baselineModelIVars\n    baselineModelIVars = try baselineModelIVars.sort catch baselineModelIVars\n\n    performanceModelIVars: try [performanceModelRec.get(\"modelConfig\").get(\"viewInputs\").get(\"temp\")] catch [read(temp and weatherStationRef == performanceModelRec.get(\"modelConfig\").get(\"weather\")).get(\"id\")]\n    performanceModelIVars = try performanceModelIVars.addAll([performanceModelRec.get(\"modelConfig\").get(\"settings\")->additionalPoint]).flatten catch performanceModelIVars\n    performanceModelIVars = try performanceModelIVars.sort catch performanceModelIVars\n\n    if(baselineModelIVars != performanceModelIVars) do\n      if(query == \"write\") func_normConfigRecord(null, true)\n      return {\"error\": \"Models have mismatched independent variables\"}.toGrid.setMeta({\"title\": \"Independent Variable\", \"subtitle\": ivStr})\n    end\n\n\n    iVars: baselineModelIVars\n    if(iVars.size < readAll(normConfigRecord).size) func_normConfigRecord(null, true)\n\n    projSync()\n\n    if(query == \"chart\") do\n      configDefined: readAll(normConfigRecord).findAll(r => r.get(\"normSrc\") != \"undefined\")\n      if(iVars.size == configDefined.size) do\n        normData: func_conditionNormData(baselineModelRec, performanceModelRec, configDefined)\n        return wdg_weatherCoverageChart(normData)\n      else\n        return \"Define All Norm sources before continuing.\"\n    end\n\n    iVars.each r => do\n      func_normConfigRecord(r)\n    end\n\n    configs: readAll(normConfigRecord).setColMeta(\"pointRef\", {\"dis\": \"Independent Variable Reference Point\"})\n                                      .reorderCols([\"pointRef\", \"normSrc\"])\n                                      .setMeta({\"title\": \"Independent Variable\", \"subtitle\": ivStr})\n\n    if(configs.colNames.contains(\"normSrc\")) configs = configs.setColMeta(\"normSrc\", {\"dis\" : \"Normalized Source\"})\n\n    return configs\n  end\nend",
      "local_src": "//\n// Copyright (c) 2024, kW Engineering\n// All Rights Reserved\n//\n// History\n//   Date:       Name:                 Description:\n//   DD MMM 22   Dylan Bardin          - Creation.\n//   09 Aug 24   Thomas Kuhrke Limia   - Refactorization and code documentation.\n//\n// Description\n//   This function represents the widget for normalized savings configuration.\n//\n// Parameters\n//   Name                 Type(s)\n//   siteID               Ref\n//   baselineModel        Ref\n//   performanceModel     Ref\n//   query                Str\n//\n// Returns\n//   Type           Description\n//   1. TODO        - TODO\n//\n// NOTES\n// - Re-organize and refactor widget.\n//\n(siteID, baselineModel, performanceModel, query: \"write\") => do\n\n  weatherStr: try \"Normalized Weather Records for \" + readById(siteID)->dis.toStr catch \"Normalized Records for Selected Site\"\n  ivStr:  try \"Normalized Records for \" + readById(siteID)->dis.toStr catch \"Normalized Records for Selected Site\"\n  baselineModelRec: readById(baselineModel)\n  performanceModelRec: readById(performanceModel)\n\n  if(baselineModelRec.get(\"modelType\") != performanceModelRec.get(\"modelType\")) do\n    if(query == \"write\") func_normConfigRecord(null, true)\n    return {\"error\": \"Mismatched Model Types\"}.toGrid.setMeta({\"title\": \"Independent Variable\", \"subtitle\": ivStr})\n  else do\n    baselineModelIVars : try [read(temp and weatherStationRef == baselineModelRec.get(\"modelConfig\").get(\"weather\")).get(\"id\")] catch [baselineModelRec.get(\"modelConfig\").get(\"viewInputs\").get(\"temp\")]\n    baselineModelIVars = try baselineModelIVars.addAll([baselineModelRec.get(\"modelConfig\").get(\"settings\")->additionalPoint]).flatten catch baselineModelIVars\n    baselineModelIVars = try baselineModelIVars.sort catch baselineModelIVars\n\n    performanceModelIVars: try [read(temp and weatherStationRef == performanceModelRec.get(\"modelConfig\").get(\"weather\")).get(\"id\")] catch [performanceModelRec.get(\"modelConfig\").get(\"viewInputs\").get(\"temp\")] \n    performanceModelIVars = try performanceModelIVars.addAll([performanceModelRec.get(\"modelConfig\").get(\"settings\")->additionalPoint]).flatten catch performanceModelIVars\n    performanceModelIVars = try performanceModelIVars.sort catch performanceModelIVars\n\n    if(baselineModelIVars != performanceModelIVars) do\n      if(query == \"write\") func_normConfigRecord(null, true)\n      return {\"error\": \"Models have mismatched independent variables\"}.toGrid.setMeta({\"title\": \"Independent Variable\", \"subtitle\": ivStr})\n    end\n\n\n    iVars: baselineModelIVars\n    if(iVars.size < readAll(normConfigRecord).size) func_normConfigRecord(null, true)\n\n    projSync()\n\n    if(query == \"chart\") do\n      configDefined: readAll(normConfigRecord).findAll(r => r.get(\"normSrc\") != \"undefined\")\n      if(iVars.size == configDefined.size) do\n        normData: func_conditionNormData(baselineModelRec, performanceModelRec, configDefined)\n        return wdg_weatherCoverageChart(normData)\n      else\n        return \"Define All Norm sources before continuing.\"\n    end\n\n    iVars.each r => do\n      func_normConfigRecord(r)\n    end\n\n    configs: readAll(normConfigRecord).setColMeta(\"pointRef\", {\"dis\": \"Independent Variable Reference Point\"})\n                                      .reorderCols([\"pointRef\", \"normSrc\"])\n                                      .setMeta({\"title\": \"Independent Variable\", \"subtitle\": ivStr})\n\n    if(configs.colNames.contains(\"normSrc\")) configs = configs.setColMeta(\"normSrc\", {\"dis\" : \"Normalized Source\"})\n\n    return configs\n  end\nend",
      "diff": "@@ -35,11 +35,11 @@     if(query == \"write\") func_normConfigRecord(null, true)\n     return {\"error\": \"Mismatched Model Types\"}.toGrid.setMeta({\"title\": \"Independent Variable\", \"subtitle\": ivStr})\n   else do\n-    baselineModelIVars : try [baselineModelRec.get(\"modelConfig\").get(\"viewInputs\").get(\"temp\")] catch [read(temp and weatherStationRef == baselineModelRec.get(\"modelConfig\").get(\"weather\")).get(\"id\")]\n+    baselineModelIVars : try [read(temp and weatherStationRef == baselineModelRec.get(\"modelConfig\").get(\"weather\")).get(\"id\")] catch [baselineModelRec.get(\"modelConfig\").get(\"viewInputs\").get(\"temp\")]\n     baselineModelIVars = try baselineModelIVars.addAll([baselineModelRec.get(\"modelConfig\").get(\"settings\")->additionalPoint]).flatten catch baselineModelIVars\n     baselineModelIVars = try baselineModelIVars.sort catch baselineModelIVars\n \n-    performanceModelIVars: try [performanceModelRec.get(\"modelConfig\").get(\"viewInputs\").get(\"temp\")] catch [read(temp and weatherStationRef == performanceModelRec.get(\"modelConfig\").get(\"weather\")).get(\"id\")]\n+    performanceModelIVars: try [read(temp and weatherStationRef == performanceModelRec.get(\"modelConfig\").get(\"weather\")).get(\"id\")] catch [performanceModelRec.get(\"modelConfig\").get(\"viewInputs\").get(\"temp\")]\n     performanceModelIVars = try performanceModelIVars.addAll([performanceModelRec.get(\"modelConfig\").get(\"settings\")->additionalPoint]).flatten catch performanceModelIVars\n     performanceModelIVars = try performanceModelIVars.sort catch performanceModelIVars\n \n"
    }
  ]
}