36. EPMO Open Source Coordination Office Redaction File Detail Report

Produced by Araxis Merge on 11/9/2018 12:16:35 PM Eastern Standard Time. See www.araxis.com for information about Merge. This report uses XHTML and CSS2, and is best viewed with a modern standards-compliant browser. For optimum results when printing this report, use landscape orientation and enable printing of background images and colours in your browser.

36.1 Files compared

# Location File Last Modified
1 RAMS-2.3.0.zip\RAMS-2.3.0\SiteAssets\js facilityInfo.js Wed May 30 20:34:16 2018 UTC
2 RAMS-2.3.0.zip\RAMS-2.3.0\SiteAssets\js facilityInfo.js Fri Nov 9 14:54:12 2018 UTC

36.2 Comparison summary

Description Between
Files 1 and 2
Text Blocks Lines
Unchanged 4 2446
Changed 3 6
Inserted 0 0
Removed 0 0

36.3 Comparison options

Whitespace
Character case Differences in character case are significant
Line endings Differences in line endings (CR and LF characters) are ignored
CR/LF characters Not shown in the comparison detail

36.4 Active regular expressions

No regular expressions were active.

36.5 Comparison detail

  1   /**
  2    * @fileOv erview Fac ilityInfo  contains a ll the "cl asses" for  the Facil ityInfoCol lection, i ncluding t he Facilit yInfo and
  3    *                Sec urityGroup s. The Fac ilityInfo  is lazily  initialize d and adde d to the c ollection  on first u se. See
  4    *                the  facilityI nfoTest.ht ml for exa mples of h ow tu use  the Facili tyInfoColl ection obj ects. This  file
  5    *                dep ends ine i nclusion o f the foll owing file s in the h tml or asp x page whe re it is u sed.
  6    * 
  7    * <pre>
  8    * &lt;scr ipt type=& quot;text/ javascript &quot; src =&quot;jsh ashtable-3 .0.js&quot ;&gt;&lt;/ script&gt;
  9    * &lt;scr ipt type=& quot;text/ javascript &quot; src =&quot;jsh ashset-3.0 .js&quot;& gt;&lt;/sc ript&gt;
  10    * &lt;scr ipt type=& quot;text/ javascript &quot; src =&quot;ram s-environm ent.js&quo t;&gt;&lt; /script&gt ;
  11    * &lt;scr ipt type=& quot;text/ javascript &quot; src =&quot;dyn amicGenera tion.js&qu ot;&gt;&lt ;/script&g t;
  12    * </pre>
  13    * 
  14    * In some  cases the  jshint er rors are s uppressed  with jshin t -W### co des.
  15    * 
  16    * @versio n 2.3.0
  17    */
  18   // Constan ts for com mittees us ed through out classe s
  19   var IACUC  = "IACUC";
  20   var IRB =  "IRB";
  21   var RDC =  "RDC";
  22   var SRS =  "SRS";
  23   var SC1 =  "SC1";
  24   var SC2 =  "SC2";
  25   var SC3 =  "SC3";
  26   // Constan ts for sec urityGroup Type used  throughout  classes
  27   var SGTYPE _AO = "Adm inistrativ e Officers ";
  28   var SGTYPE _AFM = "An imal Facil ity Manage rs";
  29   var SGTYPE _LSA = "Lo cal Site A dministrat ors";
  30   var SGTYPE _LSL = "Lo cal Site L iaisons";
  31   var SGTYPE _RCO = "Re search Com pliance Of ficers";
  32   var SGTYPE _USERS = " Users";
  33   var SGTYPE _ADMIN = " Administra tors";
  34   var SGTYPE _COORDINAT ORS = "Com mittee Coo rdinators" ;
  35   var SGTYPE _MEMBERS =  "Committe e Members" ;
  36  
  37   function F acilityInf oCollectio n() {
  38      // cons tructor
  39      // Sing leton Patt ern so tha t only one  instance  is created .
  40      if (typ eof Facili tyInfoColl ection.ins tance ===  "object")  {
  41         retu rn Facilit yInfoColle ction.inst ance;
  42      }
  43  
  44      // JSHI NT This fi le require s Hashset  and Hashta ble to be  loaded. @s ee fileOve rview
  45      // jshi nt -W117
  46      this.fi c = new Ha shtable();
  47      // prox yHolders i s a 2 dime nsional ar ray indexe d by proxy Holder (ak a Delegate d.Id) and  Committees Id. The va lue
  48      // cont ains a com ma separat ed list of  Facilitie s. The lis t of facil ities is a ll the sit es that de legated th eir
  49      // comm ittee func tion to pr oxyHolder.  Said anot her way, I f I am the  proxy Hol der, what  facility a m I perfor ming
  50      // comm ittee acti vities for .
  51      // this .proxyHold ers = new  Hashtable( );
  52      this.pr oxyHolders  = {};
  53      Facilit yInfoColle ction.inst ance = thi s;
  54      var fic Obj = this ;
  55  
  56      // Get  the list o f delegate d committe es for use  later by  the proxy  holder whe n creating  their com mitteeInfo
  57      this.ge tProxyHold ers(functi on() {
  58         // l oad the Ce ntral IRB  by default  because i t may be n eeded.
  59         // J SHINT This  file requ ires requi res RAMS-e nvironment .js to be  loaded. @s ee fileOve rview
  60         // J SHINT 'fi'  is define d but neve r used. Th is is true  in this c ase becaus e there is  no need t o return f i to
  61         // w homever
  62         // i nstantiate d the fic.
  63         // j shint -W09 8
  64         ficO bj.get(RAM S.Environm ent.ShareP oint.Centr alIRBSite,  function( fi) {
  65            r eturn Faci lityInfoCo llection.i nstance;
  66         });
  67      });
  68   }
  69   FacilityIn foCollecti on.prototy pe.getProx yHolderInf o = functi on(proxyHo lderId, co mmitteeTyp e) {
  70      var fic Obj = this ;
  71      var pro xies = [];
  72      var cps  = {};
  73  
  74      if (fic Obj.proxyH olders.has OwnPropert y(proxyHol derId)) {
  75         cps  = ficObj.p roxyHolder s[proxyHol derId];
  76         if ( typeof cps [committee Type] !==  "undefined ") {
  77            / / console. log("getPr oxyHolderI nfo for pr oxyHolderI d: " + pro xyHolderId  + " commi tteeType:  " + commit teeType
  78            / / + " cps[ " + commit teeType +  "]: " + cp s[committe eType]);
  79            p roxies = c ps[committ eeType];
  80         }
  81      }
  82      return  proxies;
  83   };
  84  
  85   FacilityIn foCollecti on.prototy pe.getProx yHolders =  function( callback)  {
  86      var fic Obj = this ;
  87      
  88      var onE rror = fun ction onEr ror(error)  {
  89         //al ert(JSON.s tringify(e rror));
  90         thro w "Error r etrieving  Facility P roxy infor mation. (F acilityInf oCollectio n.onError)  " + JSON. stringify( error);
  91      };
  92  
  93      if (typ eof callba ck === "fu nction") {
  94         // J SHINT This  file requ ires requi res RAMS-e nvironment .js to be  loaded. @s ee fileOve rview
  95         // j shint -W11 7
  96         var  comUrl = d ynamicShar epointURL  + "_api/we b/lists/ge tbytitle(' Committees ')/items"
  97            +  "?$select =Id,Title, Committees Lookup/ID, Committees Lookup/Com mitteesNam e,Faciliti esLookup/I D,"
  98            +  "Faciliti esLookup/T itle,Deleg ated/ID,De legated/Ti tle,Hidden "
  99            +  "&$expand =Facilitie sLookup,Co mmitteesLo okup,Deleg ated" + "& $filter=De legated/ID  gt 0"
  100            +  "&$orderb y=Delegate d/ID,Id";
  101         // c ps = commi ttee proxi es holds t he committ ees that a  facility  proxies fo r
  102         var  cps = {};
  103         var  pfa = [];
  104         $.aj ax({
  105            u rl : comUr l,
  106            m ethod : "G ET",
  107            a sync : fal se,
  108            h eaders : {
  109                "Accept"  : "applic ation/json ; odata=ve rbose"
  110            } ,
  111            s uccess : f unction(da ta) {
  112                var comP roxies = d ata.d.resu lts;
  113                for (var  i = 0; i  < comProxi es.length;  i++) {
  114                   cps =  {};
  115                   pfa =  [];
  116                   if (( ficObj.pro xyHolders. hasOwnProp erty(comPr oxies[i].D elegated.I D))) {
  117                      //  The deleg ated facil ity is in  the proxy  holders ob ject so se e if the c ommittee i s also pre sent.
  118                      //  if so, co ncatenate  the facili ties, othe rwise add  the commit tee and th e facility .
  119                      cp s = ficObj .proxyHold ers[comPro xies[i].De legated.ID ];
  120                      if  ((ficObj. proxyHolde rs[comProx ies[i].Del egated.ID]
  121                          .hasOwnPr operty(com Proxies[i] .Committee sLookup.Co mmitteesNa me))) {
  122                          if ((type of cps[com Proxies[i] .Committee sLookup.Co mmitteesNa me] === "u ndefined")
  123                             || (cp s[comProxi es[i].Comm itteesLook up.Committ eesName] = == "")
  124                             || (cp s[comProxi es[i].Comm itteesLook up.Committ eesName] = == null))  {
  125                             pfa.pu sh(comProx ies[i].Fac ilitiesLoo kup.ID);
  126                             cps[co mProxies[i ].Committe esLookup.C ommitteesN ame] = pfa ;
  127                          } else {
  128                             // ...  otherwise  add the c ommittee a nd the fac ility.
  129                             pfa =  cps[comPro xies[i].Co mmitteesLo okup.Commi tteesName] ;
  130                             pfa.pu sh(comProx ies[i].Fac ilitiesLoo kup.ID);
  131                             cps[co mProxies[i ].Committe esLookup.C ommitteesN ame] = pfa ;
  132                          }
  133                      }  else {
  134                          pfa.push( comProxies [i].Facili tiesLookup .ID);
  135                          cps[comPr oxies[i].C ommitteesL ookup.Comm itteesName ] = pfa;
  136                      }
  137                   } els e {
  138                      //  This is t he first t ime the De legated fa cilityId i s added to  the proxy Holders ob ject so
  139                      //  we know t hat the co mmittee is  also empt y. Initial ize it to  the commit tee being  processed.
  140                      pf a.push(com Proxies[i] .Facilitie sLookup.ID );
  141                      cp s[comProxi es[i].Comm itteesLook up.Committ eesName] =  pfa;
  142                   }
  143                   ficOb j.proxyHol ders[comPr oxies[i].D elegated.I D] = cps;
  144                }
  145                callback ();
  146            } ,
  147            e rror : onE rror 
  148         });
  149      } else  {
  150         thro w "Invalid  callback  function.  (FacilityI nfoCollect ion.getPro xyHolders) ";
  151      }
  152   };
  153   FacilityIn foCollecti on.prototy pe.get = f unction(fa cility, ca llback) {
  154      var fi;
  155      // need  to save " this" to a  variable  because ot her functi ons can't  rely on th is being s et.
  156      var fic Obj = this ;
  157      if (typ eof callba ck === "fu nction") {
  158         // d oes the fa cility exi st in the  fic?
  159         if ( !(ficObj.f ic.contain sKey(facil ity))) {
  160            / / JSHINT t he newFaci lityInfo l ine receiv es the war ning "Do n ot use 'ne w' for sid e effects"
  161            / / however  the constr uctor pass es the cre ated objec t to the c allback fu nction. Us ing the JS HINT annot ation
  162            / / to remov e the warn ing.
  163            / / jshint - W031
  164            n ew Facilit yInfo(faci lity, ficO bj, functi on(returne dFI) {
  165                if (type of returne dFI === "u ndefined")  {
  166                   throw  "Facility  " + facil ity + " is  not found . (Facilit yInfoColle ction.get) ";
  167                } else {
  168                   // ad d the faci lity by na me and ID  so it can  be found e ither way.
  169                   ficOb j.fic.put( returnedFI .getFacili tyId(), re turnedFI);
  170                   ficOb j.fic.put( returnedFI .getFacili tyName(),  returnedFI );
  171                   fi =  returnedFI ;
  172                   // re turn the r equested F acilityIte m
  173                   callb ack(fi);
  174                }
  175            } );
  176         } el se {
  177            f i = ficObj .fic.get(f acility);
  178            / / return t he request ed Facilit yItem
  179            c allback(fi );
  180         }
  181      } else  {
  182         thro w "Invalid  callback  function.  (FacilityI nfoCollect ion.get)";
  183      }
  184   };
  185   FacilityIn foCollecti on.prototy pe.remove  = function (facility)  {
  186      // does  the facil ity exist  in the fic ?
  187      if (thi s.fic.cont ainsKey(fa cility)) {
  188         // r emove the  fic entry
  189         var  fi = this. fic.get(fa cility);
  190         var  fiId = fi. facilityId ;
  191         // v ar fiName  = fi.facil ityName;
  192         this .fic.remov e(fiId);
  193         this .fic.remov e(facility );
  194      }
  195      return;
  196   };
  197   // ------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- -----
  198   function F acilityInf o(facility Key, ficOb j, callbac k) {
  199      var fSt artTime =  new Date() .getTime() ;
  200      var fEn dTime;
  201      this.ex ecutionTim e = 0;
  202      Facilit yInfo.inst ance = thi s;
  203  
  204      this.fi  = this;
  205      this.fa cilityId =  "";
  206      this.fa cilityName  = facilit yKey;
  207      // this .facilityT itle = "";
  208      this.fa cilityLoca tion = "";
  209      this.fa cilitySite Code = "00 0";
  210      this.fa cilitySubs ite = "";
  211      this.fa cilityLiai son = {
  212         id :  "",
  213         name  : "",
  214         faci lityName :  "",
  215         comm itteeType  : "",
  216         secu rityGroupT ype : ""
  217      };
  218      this.fa cilityLoca lSiteAdmin istrator =  {
  219         id :  "",
  220         name  : "",
  221         faci lityName :  "",
  222         comm itteeType  : "",
  223         secu rityGroupT ype : ""
  224      };
  225      this.fa cilityLoca lSiteLiais ons = {
  226         id :  "",
  227         name  : "",
  228         faci lityName :  "",
  229         comm itteeType  : "",
  230         secu rityGroupT ype : ""
  231      };
  232      this.fa cilityAdmi nistrative Officers =  {
  233         id :  "",
  234         name  : "",
  235         faci lityName :  "",
  236         comm itteeType  : "",
  237         secu rityGroupT ype : ""
  238      };
  239      this.fa cilityRese archCompli anceOffice rs = {
  240         id :  "",
  241         name  : "",
  242         faci lityName :  "",
  243         comm itteeType  : "",
  244         secu rityGroupT ype : ""
  245      };
  246      this.fa cilityAnim alFacility Managers =  {
  247         id :  "",
  248         name  : "",
  249         faci lityName :  "",
  250         comm itteeType  : "",
  251         secu rityGroupT ype : ""
  252      };
  253      this.fa cilityUser s = {
  254         id :  "",
  255         name  : "",
  256         faci lityName :  "",
  257         comm itteeType  : "",
  258         secu rityGroupT ype : ""
  259      };
  260  
  261      // asso ciative ar ray of com mittees, i ndexed by  committeeT ype.
  262      this.co mmittees =  [];
  263  
  264      // need  to save " this" to a  variable  because ot her functi ons can't  rely on th is being s et.
  265      var fiO bj = this;
  266      var onE rror = fun ction onEr ror(error)  {
  267         //al ert(JSON.s tringify(e rror));
  268         fEnd Time = new  Date().ge tTime();
  269         fiOb j.executio nTime = fE ndTime - f StartTime;  
  270         thro w "Error r etrieving  Facility o r Committe e. (Facili tyInfo.onE rror) " +  JSON.strin gify(error );
  271      };
  272      var pro cessCommit tee = func tion proce ssCommitte e(comData,  callback)  {
  273         var  returnedCo mJson;
  274         if ( typeof cal lback ===  "function" ) {
  275            i f ((comDat a) && (com Data.d) &&  (comData. d.results[ 0])) {
  276                returned ComJson =  comData.d. results;
  277            }  else {
  278                fEndTime  = new Dat e().getTim e();
  279                fiObj.ex ecutionTim e = fEndTi me - fStar tTime; 
  280                throw "N o result s et found f or Committ ee " + fiO bj.Facilit yName + ".  (Facility Info.proce ssCommitte e)";
  281            }
  282            v ar cObj;
  283            v ar cItem;
  284            / / we shoul d have one  record fo r each com mittee at  the facili ty.
  285            f or (var i  = 0; i < r eturnedCom Json.lengt h; i++) {
  286                cItem =  returnedCo mJson[i];
  287                // var c Obj = new  CommitteeI nfo(cItem. CommitteeT ype, new S ecurityGro up(cItem.A dministrat ors.ID,
  288                // id, c type, name , acronym,  adminGrou p, coordGr oup, membe rGroup, de legateId,  hideGroup
  289   //             try {
  290                   cObj  = {};
  291                   var d elCom = (c Item.hasOw nProperty( "Delegated ") ? 
  292                      (( (cItem.Del egated.has OwnPropert y("ID")) & & (cItem.D elegated.I D !== -1))  ? cItem.D elegated.I D
  293                      :  "") : "");
  294                   var a dminSG;
  295                   var c oordSG;
  296                   var m brSG;
  297                   if (c Item.Hidde n)  {
  298                      ad minSG = {} ;
  299                      co ordSG = {} ;
  300                      mb rSG = {};
  301                   } els e {
  302                      tr y {
  303                          adminSG =  new Secur ityGroup(c Item.Admin istrators. ID, cItem. Administra tors.Name) ;
  304                          coordSG =  new Secur ityGroup(c Item.Commi tteeCoordi nators.ID,  cItem.Com mitteeCoor dinators.N ame);
  305                          mbrSG = n ew Securit yGroup(cIt em.Committ eeMembers. ID, cItem. CommitteeM embers.Nam e);
  306                      }  catch (err ) {
  307                          adminSG =  {};
  308                          coordSG =  {};
  309                          mbrSG = { };
  310                      }
  311                   }
  312                   cObj  = new Comm itteeInfo(
  313                      cI tem.Id,
  314                      cI tem.Commit teesLookup .Committee sName,
  315                      cI tem.Title,
  316                      cI tem.Acrony m,
  317                      ad minSG,
  318                      co ordSG,
  319                      mb rSG,
  320                      de lCom,
  321                      //  (cItem.ha sOwnProper ty("delega ted.Title" ) ? cItem. delegated. Title : ""  ),
  322                      cI tem.Hidden , ficObj,  fiObj);
  323   //             } catc h (err) {
  324   //                con sole.log(e rr);
  325                   // do  nothing
  326   //             }
  327                fiObj.co mmittees[c Item.Commi tteesLooku p.Committe esName] =  cObj;
  328            }
  329            f iObj.getAl lFacilityU sers();
  330            c allback(fi Obj);
  331         } el se {
  332            f EndTime =  new Date() .getTime() ;
  333            f iObj.execu tionTime =  fEndTime  - fStartTi me; 
  334            t hrow "Inva lid callba ck functio n. (Facili tyInfo.pro cessCommit tee)";
  335         }
  336      };
  337      var pro cessFacili ty = funct ion proces sFacility( facData, c allback) {
  338         var  returnedFa cJson;
  339         if ( typeof cal lback ===  "function" ) {
  340            i f ((facDat a) && (fac Data.d) &&  (facData. d.results[ 0])) {
  341                returned FacJson =  facData.d. results[0] ;
  342            }  else {
  343                // JSHIN T possible  strict vi olation be cause of t he use of  "this"
  344                fEndTime  = new Dat e().getTim e();
  345                fiObj.ex ecutionTim e = fEndTi me - fStar tTime; 
  346                throw "N o result s et found f or Facilit y " + this .FacilityN ame;
  347            }
  348            f iObj.facil ityId = re turnedFacJ son.Id;
  349            f iObj.facil ityName =  returnedFa cJson.Titl e;
  350            f iObj.facil ityTitle =  returnedF acJson.Tit le;
  351            f iObj.facil itySiteCod e = return edFacJson. SiteCode;
  352            f iObj.facil ityLocatio n = return edFacJson. FacilityLo cation;
  353            f iObj.facil itySubsite  = returne dFacJson.F acilitySub site.Url;
  354            f iObj.facil ityLiaison Id = retur nedFacJson .FacilityL iaison.ID;
  355            f iObj.facil ityLiaison Name = ret urnedFacJs on.Facilit yLiaison.T itle;
  356            f iObj.facil ityAdminis trativeOff icers = ne w Security Group(retu rnedFacJso n.Administ rativeOffi cers.ID,
  357                returned FacJson.Ad ministrati veOfficers .Name);
  358            t ry {
  359                fiObj.fa cilityAnim alFacility Managers =  new Secur ityGroup(r eturnedFac Json.Anima lFacilityM anagers.ID ,
  360                   retur nedFacJson .AnimalFac ilityManag ers.Name);
  361            }  catch (er r) {
  362                // do no thing
  363            }
  364            f iObj.facil ityLocalSi teAdminist rator = ne w Security Group(retu rnedFacJso n.LocalSit eAdministr ators.ID,
  365                returned FacJson.Lo calSiteAdm inistrator s.Name);
  366            t ry {
  367                fiObj.fa cilityLoca lSiteLiais ons = new  SecurityGr oup(return edFacJson. LocalSiteL iaisons.ID ,
  368                   retur nedFacJson .LocalSite Liaisons.N ame);
  369            }  catch (er r) {
  370                // do no thing
  371            }
  372            f iObj.facil ityResearc hComplianc eOfficers  = new Secu rityGroup( returnedFa cJson.Rese archCompli anceOffice rs.ID,
  373                returned FacJson.Re searchComp lianceOffi cers.Name) ;
  374            f iObj.facil ityUsers =  new Secur ityGroup(r eturnedFac Json.Users .ID, retur nedFacJson .Users.Nam e);
  375  
  376            / / callback (fiObj); / / remove m e when com mittee is  working.
  377            / / lookup C ommitteeLi st info ba sed on fac ilityKey a nd link to  Committee List and p opulate at tributes
  378              // https:/ / DNS . URL /sites/IRB Applicatio ns/_api/We b/Lists/Ge tByTitle(' Committee% 20List')/I tems?$filt er=Title
  379            / / eq 'Miam i' or Id e q 'Miami'
  380            / / or
  381              // https:/ / DNS . URL /sites/IRB Applicatio ns/_api/We b/Lists/Ge tByTitle(' Committee% 20List')/I tems?$filt er=Id
  382            / / eq Commi tteeLookup Id
  383  
  384            / / &$select =Id,Title, FacilityLo okup/ID,
  385            / / Facility Lookup/Fac ilityName, Administra tors/ID,Ad ministrato rs/Name,Co mmitteeCoo rdinators/ ID,Committ eeCoordina tors/Name,
  386            / / Committe eMembers/I D,Committe eMembers/N ame,Delega tedTo/ID,D elegatedTo /Name,Hidd en
  387            / / &$expand =FacilityL ookup,Admi nistrators ,Committee Coordinato rs,Committ eeMembers, DelegatedT o
  388  
  389            / / JSHINT T his file r equires re quires RAM S-environm ent.js to  be loaded.  @see file Overview
  390            / / jshint - W117
  391            v ar comUrl  = dynamicS harepointU RL + "_api /web/lists /getbytitl e('Committ ees')/item s" + "?$fi lter="
  392            / / + "Facil ityLookup/ ID eq '" +  fiObj.fac ilityId +  "' "
  393            / / + "or "
  394            +  "Faciliti esLookup/T itle eq '"  + fiObj.f acilityNam e + "' " +  "&$select =Id,Title, "
  395                + "Commi tteesLooku p/ID,Commi tteesLooku p/Committe esName,Acr onym,"
  396                + "Facil itiesLooku p/ID, Faci litiesLook up/Title,"  + "Admini strators/I D,Administ rators/Nam e,"
  397                + "Commi tteeCoordi nators/ID, CommitteeC oordinator s/Name," +  "Committe eMembers/I D,Committe eMembers/N ame,"
  398                + "Deleg ated/ID,De legated/Ti tle," + "H idden" + " &$expand=F acilitiesL ookup,Comm itteesLook up,"
  399                + "Admin istrators, CommitteeC oordinator s,Committe eMembers,"  + "Delega ted";
  400            $ .ajax({
  401                url : co mUrl,
  402                method :  "GET",
  403                async :  false,
  404                headers  : {
  405                   "Acce pt" : "app lication/j son; odata =verbose"
  406                },
  407                success  : function (data) {
  408                   proce ssCommitte e(data, ca llback);
  409                },
  410                error :  onError
  411            } );
  412         } el se {
  413            f EndTime =  new Date() .getTime() ;
  414            f iObj.execu tionTime =  fEndTime  - fStartTi me; 
  415            t hrow "Inva lid callba ck functio n. (Facili tyInfoColl ection.pro cessFacili ty)";
  416         }
  417      };
  418  
  419      if (typ eof callba ck === "fu nction") {
  420         // c onstructor
  421         // l ookup faci lityList i nfo based  on facilit yKey and p opulate at tributes
  422           // https:/ / DNS . URL /sites/IRB Applicatio ns/_api/we b/lists/ge tbytitle(' Facility') /items?
  423         // $ filter=Fac ilityName% 20eq%20%27 Central%20 IRB%27%20o r%20Id%20e q%20%27Cen tral%20IRB %27&
  424         // $ select=Id, FacilityNa me,Title,F acilityLoc ation,Faci lityLiaiso n/ID,Facil ityLiaison /Name,Faci lityLiaiso n/Title,
  425         // F acilitySub site,Admin istrativeO fficers/ID ,Administr ativeOffic ers/Name,L ocalSiteAd ministrato rs/ID,Loca lSiteAdmin istrators/ Name,
  426         // L ocalSiteLi aisons/ID, LocalSiteL iaisons/Na me,Researc hComplianc eOfficers/ ID,Researc hComplianc eOfficers/ Name,Users /ID,Users/ Name&
  427         // $ expand=Fac ilityLiais on,Adminis trativeOff icers,Loca lSiteAdmin istrators, LocalSiteL iaisons,Re searchComp lianceOffi cers,Users
  428         // J SHINT This  file requ ires requi res RAMS-e nvironment .js to be  loaded. @s ee fileOve rview
  429         // j shint -W11 7
  430         var  facUrl = d ynamicShar epointURL
  431            +  "_api/web /lists/get bytitle('F acilities' )/items"
  432            +  "?$filter =Title eq  '"
  433            +  facilityK ey
  434            +  "' or Id  eq '"
  435            +  facilityK ey
  436            +  "' "
  437            +  "&$select =Id,Title, FacilityLo cation,Fac ilityLiais on/ID,Faci lityLiaiso n/Name,Fac ilityLiais on/Title,"
  438            +  "Facility Subsite,Ad ministrati veOfficers /ID,Admini strativeOf ficers/Nam e,"
  439            +  "AnimalFa cilityMana gers/ID,An imalFacili tyManagers /Name,"
  440            +  "LocalSit eAdministr ators/ID,L ocalSiteAd ministrato rs/Name,"
  441            +  "LocalSit eLiaisons/ ID,LocalSi teLiaisons /Name,Rese archCompli anceOffice rs/ID,Rese archCompli anceOffice rs/Name,Us ers/ID,Use rs/Name"
  442            +  "&$expand =FacilityL iaison,Adm inistrativ eOfficers, " + "Anima lFacilityM anagers,"
  443            +  "LocalSit eAdministr ators,Loca lSiteLiais ons,Resear chComplian ceOfficers ,Users";
  444         $.aj ax({
  445            u rl : facUr l,
  446            m ethod : "G ET",
  447            a sync : fal se,
  448            h eaders : {
  449                "Accept"  : "applic ation/json ; odata=ve rbose"
  450            } ,
  451            s uccess : f unction(da ta) {
  452                // fiObj .facilityI d = 123;
  453                processF acility(da ta, callba ck);
  454                fEndTime  = new Dat e().getTim e();
  455                fiObj.ex ecutionTim e = fEndTi me - fStar tTime; 
  456            } ,
  457            e rror : onE rror
  458         });
  459      } else  {
  460         fEnd Time = new  Date().ge tTime();
  461         fiOb j.executio nTime = fE ndTime - f StartTime;  
  462         thro w "Invalid  callback  function.  (FacilityI nfo.constr uctor)";
  463      }
  464      
  465   }
  466   /**
  467    * Returns  the insta ntiationTi me
  468    * 
  469    * @return s {number}  the insta ntiation t ime in mil liseconds
  470    */
  471   FacilityIn fo.prototy pe.getExec utionTime  = function () {
  472      return  this.execu tionTime;
  473   };
  474   FacilityIn fo.prototy pe.getFaci lityId = f unction()  {
  475      return  this.facil ityId;
  476   };
  477   FacilityIn fo.prototy pe.getFaci lityName =  function( ) {
  478      return  this.facil ityName;
  479   };
  480   FacilityIn fo.prototy pe.getFaci lityTitle  = function () {
  481      return  this.facil ityTitle;
  482   };
  483   FacilityIn fo.prototy pe.getFaci litySiteCo de = funct ion() {
  484      return  this.facil itySiteCod e;
  485   };
  486   FacilityIn fo.prototy pe.getFaci lityLocati on = funct ion() {
  487      return  this.facil ityLocatio n;
  488   };
  489   FacilityIn fo.prototy pe.getFaci litySubsit eUrl = fun ction() {
  490      return  this.facil itySubsite ;
  491   };
  492   // Facilit yInfo.prot otype.getF acilityCom mitteeLook upId = fun ction() {
  493   // return  this.facil ityCommitt eeLookupId ;
  494   // }
  495   FacilityIn fo.prototy pe.getFaci lityGroup  = function (group) {
  496      var lcG roup = gro up.toLower Case();
  497      switch  (lcGroup)  {
  498      case "a dministrat iveofficer s":
  499         retu rn this.fa cilityAdmi nistrative Officers;
  500         // b reak;
  501      case "l iaison":
  502         retu rn this.fa cilityLiai son;
  503         // b reak;
  504      case "l ocalsitead ministrato r":
  505         retu rn this.fa cilityLoca lSiteAdmin istrator;
  506         // b reak;
  507      case "l ocalsiteli aisons":
  508         retu rn this.fa cilityLoca lSiteLiais ons;
  509         // b reak;
  510      case "r esearchcom plianceoff icers":
  511         retu rn this.fa cilityRese archCompli anceOffice rs;
  512         // b reak;
  513      case "u sers":
  514         retu rn this.fa cilityUser s;
  515         // b reak;
  516      }
  517      return  {};
  518   };
  519   FacilityIn fo.prototy pe.getComm itteeGroup  = functio n(committe e) {
  520      var ucC ommittee =  committee .toUpperCa se();
  521      switch  (ucCommitt ee) {
  522      case IA CUC:
  523         retu rn this.co mmittees[I ACUC];
  524         // b reak;
  525      case IR B:
  526         retu rn this.co mmittees[I RB];
  527         // b reak;
  528      case RD C:
  529         retu rn this.co mmittees[R DC];
  530         // b reak;
  531      case SR S:
  532         retu rn this.co mmittees[S RS];
  533         // b reak;
  534      case SC 1:
  535         retu rn this.co mmittees[S C1];
  536         // b reak;
  537      case SC 2:
  538         retu rn this.co mmittees[S C2];
  539         // b reak;
  540      case SC 3:
  541         retu rn this.co mmittees[S C3];
  542         // b reak;
  543      default :
  544         thro w "Unknown  committee  (" + comm ittee + ") ";
  545         // b reak;
  546      }
  547   };
  548   FacilityIn fo.prototy pe.getAllC ommitteeSe curityGrou ps = funct ion() {
  549      var fi  = this;
  550      var csg  = {};
  551      var cfg  = {};
  552      var fac Committees  = fi.comm ittees;
  553      for ( v ar c in fa cCommittee s) {
  554         if ( !(facCommi ttees[c].i sCommittee Delegated( )) && !(fa cCommittee s[c].isCom mitteeHidd en())) {
  555            c fg = facCo mmittees[c ].getSecur ityGroups( );
  556            c sg = cfg;
  557         }
  558      }
  559      return  csg;
  560   };
  561   FacilityIn fo.prototy pe.getAllF acilitySec urityGroup s = functi on() {
  562      var fi  = this;
  563      var sg  = fi.getAl lCommittee SecurityGr oups();
  564  
  565      sg.admi nistrative officers =  fi.facili tyAdminist rativeOffi cers;
  566      sg.liai son = fi.f acilityLia ison;
  567      sg.loca lsiteadmin istrator =  fi.facili tyLocalSit eAdministr ator;
  568      sg.loca lsiteliais ons = fi.f acilityLoc alSiteLiai sons;
  569      sg.rese archcompli anceoffice rs = fi.fa cilityRese archCompli anceOffice rs;
  570      sg.user s = fi.fac ilityUsers ;
  571      return  sg;
  572   };
  573   FacilityIn fo.prototy pe.getAllF acilityUse rs = funct ion() {
  574      var fi  = this;
  575      var fsg u = [];
  576      var uc  = 0;
  577      var use rs;
  578      var fac SecurityGr oups = fi. getAllFaci litySecuri tyGroups() ;
  579      for ( v ar sg in f acSecurity Groups) {
  580         if ( (sg === "a dministrat iveofficer s") || (sg  === "loca lsiteadmin istrator")  || (sg == = "localsi teliaisons ")
  581            | | (sg ===  "researchc omplianceo fficers")  || (sg ===  "users"))  {
  582            i f (typeof  facSecurit yGroups[sg ].getUsers  === "func tion") {
  583                users =  facSecurit yGroups[sg ].getUsers ();
  584            }  else {
  585                users =  [];
  586            }
  587            f or ( var u  in users)  {
  588                if ((typ eof users[ u] !== "un defined")  && (users[ u])) {
  589                   uc =  uc + 1;
  590                   fsgu[ u] = users [u];
  591                }
  592            }
  593         } el se if ((sg  === "liai son")) {
  594            i f ((typeof  fsgu[facS ecurityGro ups[sg].Id ] !== "und efined") & & (fsgu[fa cSecurityG roups[sg]. Id])) {
  595                uc = uc  + 1;
  596                fsgu[fac SecurityGr oups[sg].I d] = facSe curityGrou ps[sg];
  597            }
  598         } el se {
  599            u sers = fac SecurityGr oups[sg].a dministrat ors.getUse rs();
  600            f or ( var a  in users)  {
  601                if ((typ eof users[ a] !== "un defined")  && (users[ a])) {
  602                   uc =  uc + 1;
  603                   fsgu[ a] = users [a];
  604                }
  605            }
  606            u sers = fac SecurityGr oups[sg].c oordinator s.getUsers ();
  607            f or ( var c  in users)  {
  608                if ((typ eof users[ c] !== "un defined")  && (users[ c])) {
  609                   uc =  uc + 1;
  610                   fsgu[ c] = users [c];
  611                }
  612            }
  613            u sers = fac SecurityGr oups[sg].m embers.get Users();
  614            f or ( var m  in users)  {
  615                if ((typ eof users[ m] !== "un defined")  && (users[ m])) {
  616                   uc =  uc + 1;
  617                   fsgu[ m] = users [m];
  618                }
  619            }
  620         }
  621      }
  622      fi.user s = fsgu;
  623      fi.user sCount = u c;
  624   };
  625   /**
  626    * @return s {Array}  associativ e array of  users, in dexed by S PUserId.
  627    */
  628   FacilityIn fo.prototy pe.getUser s = functi on() {
  629      return  this.users ;
  630   };
  631  
  632   // ------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- -----
  633   /**
  634    * The Com mittee Inf o object h olds the a ttributes  of a given  facility' s committe e in the C ommittee L ist. This  method is
  635    * the con structor w here all a ttribute a re require d for inst antiation.
  636    * 
  637    * @param  id {number } the comm ittee id f rom the co mmittee li st.
  638    * @param  ctype {str ing} the t ype of com mittee as  specified  in the com mitteeType  list.
  639    * @param  name {stri ng} the lo ng name of  the commi ttee for d isplay on  pages and  documents.
  640    * @param  adminGroup  {object}  object tha t contains  the admin istrator s ecurity gr oup object , containi ng the sec urity
  641    *            group i d and name .
  642    * @param  coordGroup  {object}  object tha t contains  the coord inator sec urity grou p object,  containing  the secur ity group
  643    *            id and  name.
  644    * @param  memberGrou p {object}  object th at contain s the memb er securit y group ob ject, cont aining the  security  group id
  645    *            and nam e.
  646    * @param  delegateId  {number}  the id of  the facili ty where t he facilit y delegate d its comm ittee func tion to.
  647    * @param  hideGroup  {Boolean}  indicates  if the com mittee fun ction is h idden at t he given f acility.
  648    */
  649   function C ommitteeIn fo(id, cty pe, name,  acronym, a dminGroup,  coordGrou p, memberG roup, dele gateId, hi deGroup, f icObj,
  650      fiObj)  {
  651      var ucT ype = ctyp e.toUpperC ase();
  652      if ((uc Type === I ACUC || uc Type === I RB || ucTy pe === RDC  || ucType  === SRS | | ucType = == SC1 ||  ucType ===  SC2 || uc Type === S C3)) {
  653   //      &&  (adminGro up instanc eof Securi tyGroup)
  654   //      &&  (coordGro up instanc eof Securi tyGroup)
  655   //      &&  (memberGr oup instan ceof Secur ityGroup))  {
  656         if ( typeof id  === "numbe r") {
  657            t his.commit teeId = id ;
  658         } el se {
  659            t hrow "Unab le to crea te committ ee because  id (" + i d + ") is  not a numb er.";
  660         }
  661         this .committee Type = ucT ype;
  662         this .committee Name = nam e;
  663         this .committee Acronym =  acronym;
  664         this .administr ators = ad minGroup;
  665         this .coordinat ors = coor dGroup;
  666         this .members =  memberGro up;
  667         if ( typeof del egateId == = "number" ) {
  668            t his.delaga teId = del egateId;
  669         } el se {
  670            t his.delaga teId = "";
  671         }
  672         if ( (typeof hi deGroup == = "undefin ed") || (h ideGroup ! == true))  {
  673            t his.commit teeHidden  = false;
  674         } el se {
  675            t his.commit teeHidden  = hideGrou p;
  676         }
  677         this .proxyForF acilities  = ficObj.g etProxyHol derInfo(fi Obj.getFac ilityId(),  ucType);
  678         this .getSecuri tyGroupUse rs();
  679      } else  {
  680         thro w "Unable  to create  committee  " + ucType ;
  681      }
  682      return;
  683   }
  684   /**
  685    * Returns  the ID of  the Commi ttee recor d in the c ommittee l ist.
  686    * 
  687    * @return s Id {numb er} the id
  688    */
  689   CommitteeI nfo.protot ype.getCom mitteeId =  function( ) {
  690      return  this.commi tteeId;
  691   };
  692   /**
  693    * Returns  the commi tteeType t ext for th e committe e as defin ed in the  CommitteeT ype list.
  694    * 
  695    * @return s committe eType {str ing} the c ommitteeTy pe
  696    */
  697   CommitteeI nfo.protot ype.getCom mitteeType  = functio n() {
  698      return  this.commi tteeType;
  699   };
  700   /**
  701    * Returns  the commi tteeName t ext for th e committe e. This is  the long  name and w ill contai n (SC1, SC 2, or SC3)  for the
  702    * supplem ental comm ittees.
  703    * 
  704    * @return s committe eName {str ing} the a cronym for  the commi ttee
  705    */
  706   CommitteeI nfo.protot ype.getCom mitteeName  = functio n() {
  707      return  this.commi tteeName;
  708   };
  709   /**
  710    * Returns  the commi tteeAcrony m text for  the commi ttee and w ill contai n (SC1, SC 2, or SC3)  for the s upplementa l
  711    * committ ees.
  712    * 
  713    * @return s committe eAcronym { string} th e acronym  for the co mmittee
  714    */
  715   CommitteeI nfo.protot ype.getCom mitteeAcro nym = func tion() {
  716      return  this.commi tteeAcrony m;
  717   };
  718   /**
  719    * Returns  the commi ttee admin istrators  object tha t contains  id and na me.
  720    * 
  721    * @return s members  {object} t he committ ee adminis trators ob ject
  722    */
  723   CommitteeI nfo.protot ype.getAdm inistrator s = functi on() {
  724      return  this.admin istrators;
  725   };
  726   /**
  727    * Returns  the commi ttee coord inators ob ject that  contains i d and name .
  728    * 
  729    * @return s members  {object} t he committ ee coordin ators obje ct
  730    */
  731   CommitteeI nfo.protot ype.getCoo rdinators  = function () {
  732      return  this.coord inators;
  733   };
  734   /**
  735    * Returns  the commi ttee membe rs object  that conta ins id and  name.
  736    * 
  737    * @return s members  {object} t he committ ee members  object
  738    */
  739   CommitteeI nfo.protot ype.getMem bers = fun ction() {
  740      return  this.membe rs;
  741   };
  742   /**
  743    * Returns  the facil ityID that  is commit te functio n is deleg ated to.
  744    * 
  745    * @return s {number}  the id of  the facil ity delega ted to.
  746    */
  747   CommitteeI nfo.protot ype.getDel egateId =  function()  {
  748      return  this.delag ateId;
  749   };
  750   /**
  751    * Evaluat es if the  Committee  is delegat ed for the  facility.
  752    * 
  753    * @return s {Boolean }
  754    */
  755   CommitteeI nfo.protot ype.isComm itteeDeleg ated = fun ction() {
  756      if (thi s.delagate Id) {
  757         retu rn true;
  758      } else  {
  759         retu rn false;
  760      }
  761   };
  762   /**
  763    * Evaluat es if the  Committee  is hidden  for the fa cility.
  764    * 
  765    * @return s {Boolean }
  766    */
  767   CommitteeI nfo.protot ype.isComm itteeHidde n = functi on() {
  768      if (thi s.committe eHidden) {
  769         retu rn true;
  770      } else  {
  771         retu rn false;
  772      }
  773   };
  774   /**
  775    * returns  the proxy ForFacilit ies array.
  776    * 
  777    * @return s {Array}  proxyForFa cilities
  778    */
  779   CommitteeI nfo.protot ype.getPro xyFor = fu nction() {
  780      return  this.proxy ForFacilit ies;
  781   };
  782   /**
  783    * returns  an object  containin g this com mittee's s ecurity gr oups, unle ss it is d elegated o r hidden.  If delegat ed or
  784    * hidden,  return em pty securi ty groups.
  785    * 
  786    * @return s {Object}  sg contai ns committ eeType, co mmitteeNam e, committ eeStatus ( Active, De legated, o r Hidden),
  787    *           administ rator secu rity group , coordina tors secur ity group,  and membe rs securit y group
  788    */
  789   CommitteeI nfo.protot ype.getSec urityGroup s = functi on() {
  790      var ci  = this;
  791      var sg  = {};
  792      var com mitteeType  = ci.getC ommitteeTy pe();
  793      sg[comm itteeType]  = {};
  794      sg[comm itteeType] .committee Name = ci. getCommitt eeName();
  795      sg[comm itteeType] .administr ators = {} ;
  796      sg[comm itteeType] .coordinat ors = {};
  797      sg[comm itteeType] .members =  {};
  798  
  799      if (ci. isCommitte eDelegated ()) {
  800         ci.c ommitteeSt atus = "De legated";
  801      } else  if (ci.isC ommitteeHi dden()) {
  802         ci.c ommitteeSt atus = "Hi dden";
  803      } else  {
  804         ci.c ommitteeSt atus = "Ac tive";
  805         sg[c ommitteeTy pe].admini strators =  ci.getAdm inistrator s();
  806         sg[c ommitteeTy pe].coordi nators = c i.getCoord inators();
  807         sg[c ommitteeTy pe].member s = ci.get Members();
  808      }
  809      sg[comm itteeType] .committee Status = c i.committe eStatus;
  810      return  sg;
  811   };
  812   /**
  813    * returns  an object  containin g this com mittee's s ecurity gr oup's user s, unless  it is dele gated or h idden. If  delegated
  814    * or hidd en, return  empty sec urity grou ps.
  815    * 
  816    * @return s {Object}  sg contai ns committ eeType, co mmitteeNam e, committ eeStatus ( Active, De legated, o r Hidden),
  817    *           administ rator secu rity group , coordina tors secur ity group,  and membe rs securit y group
  818    */
  819   CommitteeI nfo.protot ype.getSec urityGroup Users = fu nction() {
  820      var ci  = this;
  821      var sgu  = {};
  822      //var a ;
  823      var com mitteeType  = ci.getC ommitteeTy pe();
  824      //sgu[c ommitteeTy pe] = {};
  825      //sgu[c ommitteeTy pe].adminU sers = [];
  826      //sgu[c ommitteeTy pe].coordU sers = [];
  827      //sgu[c ommitteeTy pe].member Users = [] ;
  828      sgu.use rs = [];
  829      ci.user s = [];
  830      sgu.use rsCount =  0;
  831      var auc  = 0;
  832  
  833      //if (t ypeof call back === " function")  {
  834      sgu = c i.getSecur ityGroups( );
  835      if (!(c i.isCommit teeDelegat ed()) && ! (ci.isComm itteeHidde n())) {
  836         var  adminUsers  = [];
  837         if ( ci.adminis trators.ha sOwnProper ty("users" )) {
  838            a dminUsers  = ci.admin istrators. getUsers() ;
  839         }
  840         var  coordUsers  = [];
  841         if ( ci.coordin ators.hasO wnProperty ("users"))  {
  842            c i.coordina tors.getUs ers();
  843         }
  844         var  memberUser s = [];
  845         if ( ci.members .hasOwnPro perty("use rs")) {
  846            c i.members. getUsers() ;
  847         }
  848         for  ( var u in  adminUser s) {
  849            i f ((typeof  ci.users[ u] === "un defined")
  850                || (!(ci .users[u]) )) {
  851                auc = au c + 1;
  852                ci.users [u] = admi nUsers[u];
  853            }
  854         }
  855         for  (u in coor dUsers) {
  856            i f ((typeof  ci.users[ u] === "un defined")
  857                || (!(ci .users[u]) )) {
  858                auc = au c + 1;
  859                ci.users [u] = coor dUsers[u];
  860            }
  861         }
  862         for  (u in memb erUsers) {
  863            i f ((typeof  ci.users[ u] === "un defined")
  864                || (!(ci .users[u]) )) {
  865                auc = au c + 1;
  866                ci.users [u] = memb erUsers[u] ;
  867            }
  868         }
  869         ci.u sersCount  = auc;
  870         sgu[ committeeT ype].users  = ci.user s;
  871         sgu[ committeeT ype].users Count = au c;
  872   //      sg u[committe eType].adm inUsers =  adminUsers ;
  873   //      sg u[committe eType].coo rdUsers =  coordUsers ;
  874   //      sg u[committe eType].mem berUsers =  memberUse rs;
  875         
  876         
  877   //      fo r (a in sg u) {
  878   //          if (sgu.h asOwnPrope rty(a)) {
  879   //             ci[a]  = a;
  880   //          }
  881   //      }
  882   //      // callback(s gu);
  883   //   } els e {
  884   //      fo r (a in sg u) {
  885   //          if (sgu.h asOwnPrope rty(a)) {
  886   //             ci[a]  = a;
  887   //          }
  888   //      }
  889         //ca llback(sgu );
  890      }
  891   //   } els e {
  892   //      th row "Inval id callbac k function . (Committ eeInfo.get SecurityGr oupUsers)" ;
  893   //   }
  894   };
  895   /**
  896    * @return s {Array}  associativ e array of  users, in dexed by S PUserId.
  897    */
  898   CommitteeI nfo.protot ype.getUse rs = funct ion() {
  899      return  this.users ;
  900   };
  901  
  902   // ------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- -----
  903   /**
  904    * The Sec urity Grou p object c ontains th e id and n ame of the  security  group. in  addition i s parses t he Securit y Group
  905    * name to  determine  the Facil ity, commi tteeType a nd Securit y Group. T he Securit y Group Ob ject conta ins:
  906    * <ul>
  907    * <li>id  - this is  the SPUser ID of the  security g roup.</li>
  908    * <li>nam e - this i s the full name of th e security  group, co mposed of  one of two  patterns:
  909    * <ul>
  910    * <li>&lt ;facilityN ame&gt; &l t;committe eType&gt;  &lt;securi tyGroupTyp e&gt; - th ese are co mmittee le vel securi ty groups< /li>
  911    * <li>&lt ;facilityN ame&gt; &l t;security GroupType& gt; - thes e are faci lity level  security  groups</li >
  912    * </ul>
  913    * </li>
  914    * <li>fac ilityName  - The faci lityName i s extracte d from the  first par t of the n ame.</li>
  915    * <li>sec urityGroup Type - The  securityG roupType i s extracte d from the  last part  of the na me.</li>
  916    * <li>com mitteeType  - The com mitteeType  is extrac ted from t he middle  of the com mittee lev el securit y groups</ li>
  917    * <li>use rs - Users  is an ass ociative a rray of th e users in  the secur ity group.  It is pop ulated whe n the secu rity
  918    * group o bject is i nstantiate d.</li>
  919    * </ul>
  920    * 
  921    * @param  id {number } the spUs erId of th e Security  Group
  922    * @param  name {stri ng} the na me of the  security g roup.
  923    */
  924   function S ecurityGro up(id, nam e, skipUse rRetrieval ) {
  925      var fSt artTime =  new Date() .getTime() ;
  926      var fEn dTime;
  927      this.id  = undefin ed;
  928      this.na me = undef ined;
  929      this.fa cilityName  = undefin ed;
  930      this.se curityGrou pType = un defined;
  931      this.co mmitteeTyp e = undefi ned;
  932      this.us ers = [];
  933      this.us ersCount =  0;
  934      this.ex ecutionTim e = 0;
  935      this.sk ipUserRetr ieval = (( (skipUserR etrieval = == "undefi ned") || ! (skipUserR etrieval))  ? false :  true );
  936  
  937      if ((ty peof id == = "undefin ed") && (t ypeof name  === "unde fined")) {
  938         fEnd Time = new  Date().ge tTime();
  939         this .execution Time = fEn dTime - fS tartTime; 
  940         thro w "Unable  to create  security g roup becau se id (" +  id + ") a nd name ("  + name +  ") are und efined.";
  941      } else  if ((typeo f id === " number") & & (id != - 1)){
  942         this .id = id;
  943      } else  {
  944         fEnd Time = new  Date().ge tTime();
  945         this .execution Time = fEn dTime - fS tartTime; 
  946         thro w "Unable  to create  security g roup becau se id (" +  id + ") w ith name "  + name +  " is not v alid.";
  947      }
  948  
  949      // the  id will be  -1 if the  committee  is hidden  for the f acility
  950      if (id  < 0) {
  951         this .name = un defined;
  952      } else  {
  953         this .name = na me;
  954      }
  955      // sgPo s is the p osition of  the begin ning of th e security  group typ e in the n ame field
  956      var sgP os = 0;
  957      // sgNo Type is th e security  group nam e with the  security  group type  stripped  off the en d.
  958      var sgN oType = "" ;
  959  
  960      // this  logic eva luates the  security  group name  to determ ine the co mponents.  Security g roup names  are compo sed of
  961      // eith er <Facili tyName><Co mmitteeTyp e><Securit yGroupType > or <faci lityName>< SecurityGr oupType>,  with a spa ce
  962      // sepa rating the  component s, e.g. Mi ami IRB Ad ministrato rs, Ashevi lle Users,  or Centra l IRB IRB  Members.
  963      if (typ eof this.n ame !== "u ndefined")  {
  964         // T he first g roup for i f statemen ts is look ing for th e facility  level sec urity grou ps (SGTYPE _AO - SGTY PE_USERS).
  965         // T he 3 if st atements f or SGTYPE_ ADMIN, SGT YPE_COORDI NATORS, an d SGTYPE_M EMBERS are  the commi ttee level  security
  966         // g roups.
  967         if ( name.lastI ndexOf(SGT YPE_AO) != = -1) {
  968            t his.securi tyGroupTyp e = SGTYPE _AO;
  969            s gPos = nam e.lastInde xOf(SGTYPE _AO);
  970            s gNoType =  name.repla ce(SGTYPE_ AO, "").tr im();
  971            t his.facili tyName = s gNoType;
  972         } el se if (nam e.lastInde xOf(SGTYPE _AFM) !==  -1) {
  973            t his.securi tyGroupTyp e = SGTYPE _AFM;
  974            s gPos = nam e.lastInde xOf(SGTYPE _AFM);
  975            s gNoType =  name.repla ce(SGTYPE_ AFM, "").t rim();
  976            t his.facili tyName = s gNoType;
  977         } el se if (nam e.lastInde xOf(SGTYPE _LSA) !==  -1) {
  978            t his.securi tyGroupTyp e = SGTYPE _LSA;
  979            s gPos = nam e.lastInde xOf(SGTYPE _LSA);
  980            s gNoType =  name.repla ce(SGTYPE_ LSA, "").t rim();
  981            t his.facili tyName = s gNoType;
  982         } el se if (nam e.lastInde xOf(SGTYPE _LSL) !==  -1) {
  983            t his.securi tyGroupTyp e = SGTYPE _LSL;
  984            s gPos = nam e.lastInde xOf(SGTYPE _LSL);
  985            s gNoType =  name.repla ce(SGTYPE_ LSL, "").t rim();
  986            t his.facili tyName = s gNoType;
  987         } el se if (nam e.lastInde xOf(SGTYPE _RCO) !==  -1) {
  988            t his.securi tyGroupTyp e = SGTYPE _RCO;
  989            s gPos = nam e.lastInde xOf(SGTYPE _RCO);
  990            s gNoType =  name.repla ce(SGTYPE_ RCO, "").t rim();
  991            t his.facili tyName = s gNoType;
  992         } el se if (nam e.lastInde xOf(SGTYPE _USERS) != = -1) {
  993            t his.securi tyGroupTyp e = SGTYPE _USERS;
  994            s gPos = nam e.lastInde xOf(SGTYPE _USERS);
  995            s gNoType =  name.repla ce(SGTYPE_ USERS, "") .trim();
  996            t his.facili tyName = s gNoType;
  997         } el se if (nam e.lastInde xOf(SGTYPE _ADMIN) != = -1) {
  998            t his.securi tyGroupTyp e = SGTYPE _ADMIN;
  999            s gPos = nam e.lastInde xOf(SGTYPE _ADMIN);
  1000            s gNoType =  name.repla ce(SGTYPE_ ADMIN, "") .trim();
  1001         } el se if (nam e.lastInde xOf(SGTYPE _COORDINAT ORS) !== - 1) {
  1002            t his.securi tyGroupTyp e = SGTYPE _COORDINAT ORS;
  1003            s gPos = nam e.lastInde xOf(SGTYPE _COORDINAT ORS);
  1004            s gNoType =  name.repla ce(SGTYPE_ COORDINATO RS, "").tr im();
  1005         } el se if (nam e.lastInde xOf(SGTYPE _MEMBERS)  !== -1) {
  1006            t his.securi tyGroupTyp e = SGTYPE _MEMBERS;
  1007            s gPos = nam e.lastInde xOf(SGTYPE _MEMBERS);
  1008            s gNoType =  name.repla ce(SGTYPE_ MEMBERS, " ").trim();
  1009         } el se if (nam e.length < = sgNoType .length) {
  1010            / / if the l ength of t he sgNoTyp e is not l ess than t he name, i t means we  didn't fi nd the sgT ype and st rip it
  1011            / / off.
  1012            f EndTime =  new Date() .getTime() ;
  1013            t his.execut ionTime =  fEndTime -  fStartTim e; 
  1014            t hrow "Unab le to set  security g roup name  (" + name  + ") becau se the sec urity grou p is not k nown.";
  1015         }
  1016      } else  {
  1017         // T he name is  null or u ndefined s o set the  securityGr oupType to  undefined .
  1018         this .securityG roupType =  undefined ;
  1019      }
  1020  
  1021      // If t he facilit yName is s till undef ined, we f ound a com mittee lev el securit y group an d need to  see which  one and
  1022      // fini sh setting  the facil ityName.
  1023      if ((ty peof this. facilityNa me === "un defined")  && (typeof  this.secu rityGroupT ype !== "u ndefined") ) {
  1024         // s gNoCom is  the securi ty group n ame with t he committ ee strippe d off the  end.
  1025         var  sgNoCom =  "";
  1026         // l ioCommitte eType is t he lastind exof the c ommittee t ype
  1027         var  lioCommitt eeType = 0 ;
  1028         if ( sgNoType.l astIndexOf (IACUC) != = -1) {
  1029            t his.commit teeType =  IACUC;
  1030            l ioCommitte eType = sg NoType.las tIndexOf(I ACUC);
  1031            s gPos = sgN oType.last IndexOf(IA CUC);
  1032            s gNoCom = s gNoType.re place(IACU C, "").tri m();
  1033         } el se if (sgN oType.last IndexOf(RD C) !== -1)  {
  1034            t his.commit teeType =  RDC;
  1035            l ioCommitte eType = sg NoType.las tIndexOf(R DC);
  1036            s gPos = sgN oType.last IndexOf(RD C);
  1037            s gNoCom = s gNoType.re place(RDC,  "").trim( );
  1038         } el se if (sgN oType.last IndexOf(SR S) !== -1)  {
  1039            t his.commit teeType =  SRS;
  1040            l ioCommitte eType = sg NoType.las tIndexOf(S RS);
  1041            s gPos = sgN oType.last IndexOf(SR S);
  1042            s gNoCom = s gNoType.re place(SRS,  "").trim( );
  1043         } el se if (sgN oType.last IndexOf(SC 1) !== -1)  {
  1044            t his.commit teeType =  SC1;
  1045            l ioCommitte eType = sg NoType.las tIndexOf(S C1);
  1046            s gPos = sgN oType.last IndexOf(SC 1);
  1047            s gNoCom = s gNoType.re place(SC1,  "").trim( );
  1048         } el se if (sgN oType.last IndexOf(SC 2) !== -1)  {
  1049            t his.commit teeType =  SC2;
  1050            l ioCommitte eType = sg NoType.las tIndexOf(S C2);
  1051            s gPos = sgN oType.last IndexOf(SC 2);
  1052            s gNoCom = s gNoType.re place(SC2,  "").trim( );
  1053         } el se if (sgN oType.last IndexOf(SC 3) !== -1)  {
  1054            t his.commit teeType =  SC3;
  1055            l ioCommitte eType = sg NoType.las tIndexOf(S C3);
  1056            s gPos = sgN oType.last IndexOf(SC 3);
  1057            s gNoCom = s gNoType.re place(SC3,  "").trim( );
  1058         } el se if (sgN oType.last IndexOf(IR B) !== -1)  {
  1059            t his.commit teeType =  IRB;
  1060            l ioCommitte eType = sg NoType.las tIndexOf(I RB);
  1061            s gPos = sgN oType.last IndexOf(IR B);
  1062            s gNoCom = s gNoType.sl ice(0, sgP os).trim() ;
  1063         } el se if (sgN oType.leng th <= sgNo Com.length ) {
  1064            / / if the l ength of t he sgNoTyp e is not l ess than t he name, i t means we  didn't fi nd the sgT ype and st rip it
  1065            / / off.
  1066            f EndTime =  new Date() .getTime() ;
  1067            t his.execut ionTime =  fEndTime -  fStartTim e; 
  1068            t hrow "Unab le to set  security g roup commi tteeType ( " + name +  ") becaus e the type  is not kn own.";
  1069         }
  1070         this .facilityN ame = sgNo Com;
  1071      } else  {
  1072         this .committee Type = "";
  1073      }
  1074  
  1075      try {
  1076         if ( skipUserRe trieval) {
  1077            t his.users  = [];
  1078            t his.usersC ount = 0;
  1079         } el se {
  1080            t his.getUse rsFromShar ePoint();
  1081         }
  1082         fEnd Time = new  Date().ge tTime();
  1083         this .execution Time = fEn dTime - fS tartTime; 
  1084      } catch  (err) {
  1085         cons ole.log(er r);
  1086         fEnd Time = new  Date().ge tTime();
  1087         this .execution Time = fEn dTime - fS tartTime; 
  1088      }
  1089   }
  1090   /**
  1091    * Returns  the id as sociated t o the secu rity group . This is  the SPUser ID of the  security G roup
  1092    * 
  1093    * @return s id {numb er} the sp UserId of  the securi tyGroup.
  1094    */
  1095   SecurityGr oup.protot ype.getId  = function () {
  1096      return  this.id;
  1097   };
  1098   /**
  1099    * Returns  the full  name of th e security  Group
  1100    * 
  1101    * @return s name {st ring} the  full name  of the sec urity grou p
  1102    */
  1103   SecurityGr oup.protot ype.getNam e = functi on() {
  1104      return  this.name;
  1105   };
  1106   /**
  1107    * Returns  the insta ntiationTi me
  1108    * 
  1109    * @return s {number}  the insta ntiation t ime in mil liseconds
  1110    */
  1111   SecurityGr oup.protot ype.getExe cutionTime  = functio n() {
  1112      return  this.execu tionTime;
  1113   };
  1114   /**
  1115    * Returns  the Facil ity Name e xtracted f rom the Se curity Gro up Name
  1116    * 
  1117    * @return s facility Name {stri ng} the na me of the  facility
  1118    */
  1119   SecurityGr oup.protot ype.getFac ilityName  = function () {
  1120      return  this.facil ityName;
  1121   };
  1122   /**
  1123    * Returns  the Commi tteeType f rom the Se curity Gro up Name. t his can be  any of th e followin g:
  1124    * <ul>
  1125    * <li>IAC UC
  1126    * <li>IRB
  1127    * <li>RDC
  1128    * <li>SRS
  1129    * <li>SC1
  1130    * <li>SC2
  1131    * <li>SC3
  1132    * </ul>
  1133    * 
  1134    * @return s committe eType {str ing} the t ype of com mittee
  1135    */
  1136   SecurityGr oup.protot ype.getCom mitteeType  = functio n() {
  1137      return  this.commi tteeType;
  1138   };
  1139   /**
  1140    * Return  the object 's securit y Group Ty pe. this c an be any  of the fol lowing:
  1141    * <ul>
  1142    * <li>Adm inistrativ e Officers
  1143    * <li>Ani mal Facili ty Manager s
  1144    * <li>Loc al Site Ad ministrato rs
  1145    * <li>Loc al Site Li aisons
  1146    * <li>Res earch Comp liance Off icers
  1147    * <li>Use rs
  1148    * <li>Adm inistrator s
  1149    * <li>Com mittee Coo rdinators
  1150    * <li>Com mittee Mem bers
  1151    * </ul>
  1152    * 
  1153    * @return s security GroupType  {string} t he type of  security  group
  1154    */
  1155   SecurityGr oup.protot ype.getSec urityGroup Type = fun ction() {
  1156      return  this.secur ityGroupTy pe;
  1157   };
  1158   /**
  1159    * @return s {Array}  associativ e array of  users, in dexed by S PUserId.
  1160    */
  1161   SecurityGr oup.protot ype.getUse rs = funct ion() {
  1162      return  this.users ;
  1163   };
  1164   /**
  1165    * Returns  the numbe r of users  in the us ers associ ative arra y.
  1166    * 
  1167    * @return s {number}  usersCoun t the spUs erId of th e security Group.
  1168    */
  1169   SecurityGr oup.protot ype.getUse rsCount =  function()  {
  1170      return  this.users Count;
  1171   };
  1172   /**
  1173    * Populat es the use rs associa tive array ,indexed b y SPUserID  from the  SharePoint  Security  Group.
  1174    * @throws  Unable to  get users  from secu rity group  name
  1175    * @return s {functio n} Callbac k function  passing a n associat ive array  of users i ndexed by  SPUserId
  1176    */
  1177   SecurityGr oup.protot ype.getUse rsFromShar ePoint = f unction()  {
  1178      var sg  = this;
  1179      var sgu  = [];
  1180      var uc  = 0;
  1181   //   if (t ypeof call back === " function")  {
  1182         // J SHINT This  file requ ires requi res RAMS-e nvironment .js to be  loaded. @s ee fileOve rview
  1183         // j shint -W11 7
  1184         var  sgUrl = dy namicShare pointURL +  "_api/Web /SiteGroup s(" + sg.i d + ")/Use rs";
  1185         $.aj ax({
  1186            u rl : sgUrl ,
  1187            m ethod : "G ET",
  1188            a sync : fal se,
  1189            h eaders : {
  1190                "Accept"  : "applic ation/json ; odata=ve rbose"
  1191            } ,
  1192            s uccess : f unction(da ta) {
  1193                var resu lts = data .d.results ;
  1194                for (var  i = 0; i  < results. length; i+ +) {
  1195                   var u cSGName =  results[i] .Title.toU pperCase() ;
  1196                   if (( ucSGName.i ndexOf("SE RVICEACCOU NT") == -1 ) && (ucSG Name.index Of("SERVIC E ACCOUNT" ) == -1))  {
  1197                      uc  = uc + 1;
  1198                      sg u[results[ i].Id] = r esults[i];
  1199                   }
  1200                }
  1201                sg.users  = sgu;
  1202                sg.users Count = uc ;
  1203                //callba ck(sgu);
  1204            } ,
  1205            e rror : fun ction(erro r) {
  1206                sg.users  = sgu;
  1207                sg.users Count = uc ;
  1208                throw "U nable to g et users f rom securi ty group n ame " + sg .name + "  with id "  + sg.id +  ". " + err or.status
  1209                   + " "  + error.s tatusText  + " " + er ror.respon seText + "  (Security Group.getU sers)";
  1210            }
  1211         });
  1212   //   } els e {
  1213   //      th row "Inval id callbac k function . (Securit yGroup.get Users)";
  1214   //   }
  1215   };
  1216   // ------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- -----
  1217   String.pro totype.tri m = functi on() {
  1218      return  this.repla ce(/^\s+|\ s+$/g, "") ;
  1219   };
  1220   /*
  1221    * //Usage : var fic  = new Faci lityInfoCo llection() ; var fiMi amiByName  = fic.get( "Miami");  var fiMiam iByNumber  =
  1222    * fic.get (5); var f iMiamiIRBI nfo = fiMi amiByName. getCommtit teeGroups( "IRB"); va r fiMiamiI RBAdminist ratorsId =
  1223    * fiMiami IRBInfo.ge tAdministr ators().ge tName(); v ar fiMiami IACUCisCom mitteeDele gated =
  1224    * fiMiami ByName.get Commtittee Groups("IA CUC").isCo mmitteeDel egated();
  1225    */
  1226