{"version":3,"file":"assets/NWS/js/main.min.js","mappings":"yBACO,MAAMA,EAAW,CAACC,EAAIC,KACpBD,EAAGE,UAAUC,SAASF,KACvBD,EAAGE,UAAUE,IAAIH,IACV,GAKFI,EAAc,CAACL,EAAIC,MACxBD,EAAGE,UAAUC,SAASF,KACxBD,EAAGE,UAAUI,OAAOL,IACb,GAqCAM,EAAc,CAACC,EAAOC,KAC1BC,QAAQC,UAAUC,UACnBF,QAAQC,UAAUC,QAChBF,QAAQC,UAAUE,mBAAqBH,QAAQC,UAAUG,uBAE1DJ,QAAQC,UAAUI,UACnBL,QAAQC,UAAUI,QAAU,SAASC,GACjC,IAAIhB,EAAKiB,KAET,EAAG,CACH,GAAIP,QAAQC,UAAUC,QAAQM,KAAKlB,EAAIgB,GAEnC,OAAOhB,EAGXA,EAAKA,EAAGmB,eAAiBnB,EAAGoB,UAC5B,OACc,OAAPpB,GAA+B,IAAhBA,EAAGqB,UAEzB,OAAO,IACX,KAGAb,GACOA,EAAMO,QAAQN,IC5B7B,IC6JA,EAFgB,IAtMhB,MACE,WAAAa,GACEL,KAAKM,QAAUC,SAASC,cAAc,wBACtCR,KAAKS,OAASF,SAASC,cAAc,qCACrCR,KAAKU,SAAWH,SAASC,cAAc,oBACzC,CAEA,UAAAG,CAAWC,GACLZ,KAAKM,SAAWN,KAAKS,SACvBT,KAAKa,aAAeb,KAAKM,QAAQQ,aACjCd,KAAKe,WAAaf,KAAKa,aAAe,EACtCb,KAAKgB,oBAAsBJ,EAE3BZ,KAAKiB,YAAYhB,KAAKD,MACtBkB,OAAOC,iBAAiB,SAAUnB,KAAKiB,YAAYG,KAAKpB,OACxDkB,OAAOC,iBAAiB,SAAUnB,KAAKiB,YAAYG,KAAKpB,OACxDkB,OAAOC,iBAAiB,SAAUnB,KAAKqB,eAAeD,KAAKpB,QAGzDA,KAAKU,UACPV,KAAKU,SAASS,iBAAiB,SAAS,KFLnB,IAACpC,IEMRiB,KAAKU,SFLrB5B,EAASC,EEKsB,SFLLK,EAAYL,EEKP,QFWJ,EAACA,EAAIuC,KAChC,IAAIC,EAAexC,EAAGyC,aAAaF,GAEf,QAAhBC,EACAxC,EAAG0C,aAAaH,EAAM,SAEC,SAAhBC,GACPxC,EAAG0C,aAAaH,EAAM,OAId,EErBRI,CAAgB1B,KAAKU,SAAU,gBAAgB,GAGrD,CAOA,WAAAO,GAIE,GAAIC,OAAOS,YAHW,IAGkB,CACtC,MAAMC,EAAiB5B,KAAKgB,oBAAoBa,KAAI,EAAGC,aAAcA,IAErE,IAAIC,EAAkBxB,SAASyB,iBAAiBJ,EAAeK,KAAK,OAChEC,GAAiB,EAErB,IAAK,IAAIC,EAAI,EAAGA,EAAIJ,EAAgBK,OAAQD,IAC5C,CACE,IAAIE,EAAYN,EAAgBI,GAC5BG,EAAMD,EAAUE,wBAAwBD,IACxCE,EAASH,EAAUE,wBAAwBC,OAC3CC,EAAkBJ,EAAUvB,aAG5B4B,EAAe1C,KAAK2C,oBAAoBN,GAG5C,GAAKC,EAAMtC,KAAKa,cAAgB2B,EAAUC,EAAkBzC,KAAKa,cAC5D2B,EAAS,EAEZ,SAGFN,GAAiB,EAGjB,IAUIU,EAAaC,EAVbC,EAA0BR,GAAO,GAAKA,GAAOtC,KAAKa,cAAgByB,EAAMtC,KAAKe,WAC7EgC,EAA6BP,GAAU,GAAKA,GAAUxC,KAAKe,WAG3DiC,EAAoB1D,EAAY+C,EAAW,eAC/CA,EAAiC,MAArBW,EACRA,EACAX,EAKAA,EAAUY,qBACZL,EAAcP,EAAUY,mBAAmBhE,UAAUC,SAAS,cAC1DmD,EAAUY,mBAAmBC,kBAC7Bb,EAAUY,oBAGZZ,EAAUc,yBACZN,EAAcR,EAAUc,uBAAuBlE,UAAUC,SAAS,cAC9DmD,EAAUc,uBAAuBD,kBACjCb,EAAUc,wBAGhB,IAAIC,EAAsBR,GAAeb,EAAgBI,EAAI,GACzDkB,EAAsBR,GAAed,EAAgBI,EAAI,GAG7DO,EAAeA,EAAaY,MAAM,KAGlC,IAAIC,GAAyB,EAAMC,GAAyB,EACxDC,EAAc,GAAIC,EAAc,GAEpC,IAAK,IAAIvB,EAAI,EAAGA,EAAIO,EAAaN,OAAQD,IAAK,CAC5C,GAAIS,IAAgB5C,KAAK2C,oBAAoBC,GAAae,SAASjB,EAAaP,IAChF,CACEoB,GAAyB,EACzBE,EAAczD,KAAK2C,oBAAoBC,GAAaU,MAAM,KAC1D,KACF,CAEA,GAAIT,IAAgB7C,KAAK2C,oBAAoBE,GAAac,SAASjB,EAAaP,IAChF,CACEqB,GAAyB,EACzBE,EAAc1D,KAAK2C,oBAAoBE,GAAaS,MAAM,KAC1D,KACF,CACF,CAEKP,IAA+BK,GAC/BN,IAA4BO,EAE/BX,EAAakB,SAAQC,GAAKzE,EAAYY,KAAKM,QAASuD,KAG5Cd,GAA8BK,IAAwBG,GAC9Db,EAAakB,SAAQC,GAAKzE,EAAYY,KAAKM,QAASuD,KAEpDJ,EAAYG,SAAQC,GAAK/E,EAASkB,KAAKM,QAASuD,MAExCf,GAA2BO,IAAwBG,GAC3Dd,EAAakB,SAAQC,GAAKzE,EAAYY,KAAKM,QAASuD,KACpDH,EAAYE,SAAQC,GAAK/E,EAASkB,KAAKM,QAASuD,OAI5CJ,GAAaA,EAAYG,SAAQC,GAAKzE,EAAYY,KAAKM,QAASuD,KAChEH,GAAaA,EAAYE,SAAQC,GAAKzE,EAAYY,KAAKM,QAASuD,KAEpEnB,EAAakB,SAAQC,GAAK/E,EAASkB,KAAKM,QAASuD,MAInD,KACF,CAGK3B,IACH9C,EAAYY,KAAKM,QAAS,uBAC1BlB,EAAYY,KAAKM,QAAS,yBAC1BlB,EAAYY,KAAKM,QAAS,eAE9B,MAGElB,EAAYY,KAAKM,QAAS,uBAC1BlB,EAAYY,KAAKM,QAAS,yBAC1BlB,EAAYY,KAAKM,QAAS,cAE9B,CAIA,mBAAAqC,CAAoBN,GAClB,GAAIA,EAAW,CACb,IAAI,IAAIF,EAAI,EAAGA,EAAInC,KAAKgB,oBAAoBoB,OAAQD,IAAK,CACvD,IAAI2B,EAAW9D,KAAKgB,oBAAoBmB,GAAGL,QAAQiC,QAAQ,IAAK,IAEhE,GAAI1B,EAAUpD,UAAUC,SAAS4E,GAE/B,OAAO9D,KAAKgB,oBAAoBmB,GAAG6B,OAEvC,CAEA,MAAO,EACT,CACF,CAOA,cAAA3C,GACsBd,SAASC,cAAc,SAIxBU,OAAOS,YAHP,MAKbpB,SAAS0D,KAAKC,UAAYlE,KAAKe,YAAcR,SAAS4D,gBAAgBD,UAAYlE,KAAKe,YAEzFjC,EAASkB,KAAKM,QAAS,eACvBxB,EAASkB,KAAKM,QAAS,aAKvBlB,EAAYY,KAAKM,QAAS,eAC1BlB,EAAYY,KAAKM,QAAS,YAGhC,GCrKFY,OAAO8C,QADa,CAAC,EAIrB,IAAII,EAAc,CAChBC,QCpCF,MACE,WAAAhE,GAAe,CAEf,kBAAAiE,GACE,MAAO,CAAExC,QAAS,mBAAoBkC,QAAS,wBACjD,GDgCAO,kBErCF,MACE,WAAAlE,GAAe,CAEf,kBAAAiE,GACE,MAAO,CAAExC,QAAS,8BAA+BkC,QAAS,wBAC5D,GFiCAQ,mBGtCF,MACE,WAAAnE,GACEL,KAAKyE,eAAiBlE,SAASC,cAAc,gCAC7CR,KAAK0E,qBAAuBnE,SAASC,cAAc,wBACnDR,KAAK2E,oBAAsBpE,SAASC,cAAc,4BAK9CU,OAAOS,YAFQ,OAIb3B,KAAKyE,gBACPzE,KAAK4E,6BAGH5E,KAAK0E,sBACP1E,KAAK6E,sBAGH7E,KAAK2E,qBACP3E,KAAK8E,sBAGX,CAGA,0BAAAF,GACE,IAAIG,EAAQ/E,KAAKyE,eAAejE,cAAc,MAC1CwE,EAAWhF,KAAKyE,eAAejE,cAAc,cAC7CyE,EAAsBjF,KAAKyE,eAAejE,cAAc,eAE5D0E,KAAKC,GAAGJ,EAAO,CACbK,cAAe,CACbC,QAASrF,KAAKyE,eAAevE,cAC7BoF,MAAO,UACPC,IAAK,UACLC,KAAK,EACLC,OAAO,EACPC,cAAe,yBACfC,SAAS,GAEXC,QAAS,EACTC,UAAW,MAIJX,KAAKY,SAAS,CACrBV,cAAe,CACbC,QAASrF,KAAKyE,eAAevE,cAC7BoF,MAAO,qBACPI,cAAe,yBACfC,SAAS,KAIVR,GAAGH,EAAU,CAAEa,SAAU,IAAKD,QAAS,EAAGG,KAAM,eAChDZ,GAAGF,EAAqB,CAAEe,MAAO,EAAGJ,QAAS,EAAGG,KAAM,aAAe,SACrEZ,GAAGH,EAAU,CAAEiB,UAAW,EAAGC,SAAU,IAAO,IACnD,CAGA,mBAAArB,GACE,IAAIsB,EAAanG,KAAK0E,qBAAqBlE,cAAc,cACrD4F,EAAoBD,EAAW3F,cAAc,iBAG7CoC,EAAc5C,KAAK0E,qBAAqBxE,cAAc+C,mBAC1D,IAAKL,EAAa,OAAO,EAEzB,IAAIqC,EAAsBrC,EAAYpC,cAAc,eAChD6F,EAAezD,EAAYpC,cAAc,cAC7C,IAAKyE,IAAwBoB,EAAc,OAAO,EAuBlDnB,KAAKoB,IAAIH,EAAY,CACnBI,EAAG,EACHC,EAAG,EACHC,OAAQ,CAACtE,EAAGuE,IAASA,EAAKnE,wBAAwBkE,SAIpDvB,KAAKyB,MAAMC,QAAQ,QAAQhD,SAAQ,CAACiD,EAAK1E,KACvC+C,KAAKoB,IAAIO,EAAK,CACZL,GAAuD,EAApDJ,EAAkB7D,wBAAwBkE,OAC7CrB,cAAe,CAAE0B,qBAAqB,IACvC,IAGM5B,KAAKY,SAAS,CACrBV,cAAe,CACbC,QAASc,EACTb,MAAO,kBACPC,IAAK,gBACLG,cAAe,yBACfD,MAAO,IACPqB,qBAAqB,EACrBnB,SAAS,KAIVoB,OAAOX,EACR,CAAER,QAAS,GACX,CAAEM,SAAU,GAAKN,QAAS,GAAI,KAC/BT,GAAG,OAAQ,CACVe,SAAU,GACVc,SAAU,IACVC,gBAAiB,SACjBC,OArDiB,IAAMjC,EAAoB1C,wBAAwBkE,OAASL,EAAkB7D,wBAAwBkE,OAsDtHD,EAAIW,GA5CwB,CAACA,GAMtB,GALUf,EAAkB7D,wBAAwBkE,OACzCxB,EAAoB1C,wBAAwBkE,QAE7C,IAEmBU,EAAQ,GAsC9BC,CAAwBD,GACtCpB,KAAM,YACNsB,QAAS,CAAEC,OAAQ,KAClB,KACFnC,GAAGgB,EAAY,CAAEP,QAAS,GAAK,IAClC,CAGA,mBAAAd,GACE,IAAIyC,EAAYvH,KAAK2E,oBAAoBnE,cAAc,eACnDwE,EAAWhF,KAAK2E,oBAAoBnE,cAAc,cAClDgH,EAAiBxC,EAASxE,cAAc,mCAEnC0E,KAAKY,SAAS,CACrBV,cAAe,CACbC,QAASrF,KAAK2E,oBACdW,MAAO,kBACPC,IAAK,aACLG,cAAe,yBACfC,SAAS,KAIVoB,OAAOQ,EACR,CAAE3B,QAAS,GACX,CAAEA,QAAS,IACZmB,OAAO/B,EAAU,CAChBY,QAAS,EACTC,SAAU,IACT,CACDD,QAAS,EACTC,SAAU,EACVW,EAAG,IAAMgB,EAAe1G,cACvB,SAGHoE,KAAKC,GAAGoC,EAAW,CACjBnC,cAAe,CACbC,QAASkC,EACTjC,MAAO,gBACPmC,WAAYzH,KAAK2E,oBACjBY,IAAK,gBACLC,KAAK,EACLC,OAAO,EACPE,SAAS,KAKbT,KAAK6B,OAAO/B,EAAU,CACpBwB,EAAG,IAAMgB,EAAe1G,cACvB,CACDsE,cAAe,CACbC,QAASrF,KAAK2E,oBACdW,MAAO,aACPC,IAAK,gBACLE,OAAO,EACPC,cAAe,yBACfC,SAAS,GAEXa,EAAG,IAILtB,KAAKC,GAAGqC,EAAgB,CACtBpC,cAAe,CACbC,QAASrF,KAAK2E,oBACdW,MAAO,kBACPC,IAAK,gBACLE,OAAO,EACPC,cAAe,yBACfC,SAAS,GAEXC,QAAS,GAEb,CAGA,kBAAAtB,GAOE,MANoB,CAClB,CAAExC,QAAS,uCAAwCkC,QAAS,mCAC5D,CAAElC,QAAS,+BAAgCkC,QAAS,mCACpD,CAAElC,QAAS,mCAAoCkC,QAAS,yBAI5D,GH/KA0D,KIvCF,MACE,WAAArH,GAAe,CAEf,kBAAAiE,GACE,MAAO,CAAExC,QAAS,gBAAiBkC,QAAS,kCAC9C,GJmCA2D,IKxCF,MACE,WAAAtH,GAAe,GLwCfuH,WMzCF,MACE,WAAAvH,GACEL,KAAK6H,aAAetH,SAASC,cAAc,eAC3CR,KAAK8H,kBAAoB,yCACzB9H,KAAK6B,IAED7B,KAAK6H,eACP7H,KAAK+H,UACL/H,KAAKgI,kBAET,CAEA,aAAMD,GACJ,MAAM,IAAEE,SAAcC,OAAOC,KAAKC,cAAc,QAEhDpI,KAAK6B,IAAM,IAAIoG,EAAIjI,KAAK6H,aAAc,CACpCQ,MAAO,mBACPC,OAAQ,CAAEC,IAAK,GAAIC,KAAM,KACzBC,cAAc,EACdC,gBAAgB,EAChBC,mBAAmB,EACnBC,KAAM,EACNC,QAAS,EACTC,QAAS,EACTC,YAAa,CACXC,aAAc,CACZC,MAAO,GACPC,MAAO,GACPC,MAAO,GACPC,MAAO,OAIf,CAEA,eAAApB,GACEqB,MAAMrJ,KAAK8H,mBACRwB,MAAMC,IACL,GAAIA,EAASC,GACX,OAAOD,EAASE,OAEhB,MAAM,IAAIC,MAAMH,EAASI,WAC3B,IAEDL,MAAMM,GAAc5J,KAAK6J,oBAAoBD,KAC7CE,OAAOC,IACNC,QAAQC,IAAIF,EAAI,GAEtB,CAEA,yBAAMF,CAAoBD,GACxB,MAAM,sBAAEM,SAAgChC,OAAOC,KAAKC,cAAc,UAElEwB,EAAUhG,SAAQ,EAAEuG,EAAUpF,EAAOqF,EAAOC,GAAclI,KACxD,MAAMmI,EAAgB/J,SAASgK,cAAc,OAC7CD,EAAcrL,UAAUE,IAAI,kBAC5BmL,EAAcE,UAGZ,qgBAAwCH,gBAC3BD,UACNrF,aAGT,MAAM0F,EAAS,IAAIP,EAAsB,CACvCrI,IAAK7B,KAAK6B,IACVsI,WACAO,QAASJ,EACTvF,QACA4F,cAAc,IAMhBF,EAAOG,YAAY,SAAS,KACtBH,EAAOC,QAAQzL,UAAUC,SAAS,YACpCuL,EAAOC,QAAQzL,UAAUI,OAAO,WAChCoL,EAAOI,OAAS,OAEhBJ,EAAOC,QAAQzL,UAAUE,IAAI,WAC7BsL,EAAOI,OAAS,EAClB,GACA,GAEN,CAEA,kBAAAvG,GACE,MAAO,CACLxC,QAAS,uBACTkC,QAAS,oCAEb,GNlDA8G,iBOxCF,MACI,WAAAzK,GAII,GAFAL,KAAK+K,WAAaxK,SAASyB,iBAAiB,SAExChC,KAAK+K,WACL,IAAK,IAAI5I,EAAI,EAAGA,EAAInC,KAAK+K,WAAW3I,OAAQD,IAEpCnC,KAAK+K,WAAW5I,GAAGjC,cAAcjB,UAAUC,SAAS,mBViB5CH,EUbAiB,KAAK+K,WAAW5I,GVaZ6I,EUbgBzK,SAASgK,cAAc,OVcnExL,EAAGoB,WAAW8K,aAAaD,EAASjM,GACpCiM,EAAQE,YAAYnM,GACpBD,EAASkM,EUhBkE,iBAC/DhL,KAAKmL,eAAenL,KAAK+K,WAAW5I,KVYzB,IAACpD,EAAIiM,CUT5B,CAIA,cAAAG,CAAepM,GACX,IAAIiH,EAAQ,EAERoF,EAAOrM,EAAGiD,iBAAiB,MAE/B,IAAK,IAAIG,EAAI,EAAGA,EAAIiJ,EAAKhJ,OAAQD,IAAK,CAClC,IAAIkJ,EAAUD,EAAKjJ,GAAG3B,cAAc,MAEpC,GAAI6K,EAAS,CAET,GAA6B,IAAzBD,EAAKjJ,GAAGmJ,MAAMlJ,QAAoD,OAApCiJ,EAAQ7J,aAAa,WAAqB,CACxE,IAAK,IAAI+J,EAAI,EAAGA,EAAIH,EAAKhJ,OAAQmJ,IAC7BH,EAAKG,GAAG/K,cAAc,MAAMgL,MAAMrB,SAAW,WAC7CiB,EAAKG,GAAG/K,cAAc,MAAMgL,MAAMC,gBAAkB,cAGxD,MACJ,CAEA,GAAuC,MAAnCJ,EAAQ7J,aAAa,WAQrB,OAPAwE,EAAQqF,EAAQK,aAlBJ,IAkBuCL,EAAQK,YAAc,KAAOC,QAEhFN,EAAQG,MAAMI,SAAW5F,OAEX1G,EAAY+L,EAAS,kBAC3BG,MAAMK,mBAAsB7F,EAAQ,0BAA4BA,EAAQ,wBAIxF,CACJ,CACJ,GPVF8F,mBFzCF,MACE,WAAAzL,GACEL,KAAK+L,aAAexL,SAASC,cAAc,gCAC3CR,KAAKgM,UAAYzL,SAASC,cAAc,qBACxCR,KAAKiM,cAAgB1L,SAASC,cAAc,wBAExCR,KAAKgM,YACPzL,SAASY,iBAAiB,mBAAoBnB,KAAKkM,WAAW9K,KAAKpB,OACnEkB,OAAOC,iBAAiB,SAAUnB,KAAKmM,KAAK/K,KAAKpB,OAErD,CAGA,IAAAmM,GAEE,IAAIC,EADc,EAGdC,EAAoB,IAAMnL,OAAOoL,SAAY/L,SAAS0D,KAAKsI,aAAerL,OAAOsL,aAEjFH,EALc,IAMhBD,EAAYC,GAGdrM,KAAKgM,UAAUR,MAAM/E,OAAS2F,EAAY,IAG1CpM,KAAKkM,YACP,CAEA,UAAAA,GACE,GAAIlM,KAAKiM,cAAe,CACtB,IAAIQ,EAAe,sBAEhBzM,KAAKiM,cAAchN,UAAUC,SAASuN,GACvC3N,EAASkB,KAAK+L,aAAcU,GAG5BrN,EAAYY,KAAK+L,aAAcU,EAEnC,CACF,GEEAC,uBQ5CF,MACE,WAAArM,GACEL,KAAK2M,wBAA0BpM,SAASC,cAAc,qCAElDR,KAAK2M,yBACP3M,KAAK4M,oBAET,CAEA,kBAAAA,GAIE,GAAI1L,OAAOS,YAFW,IAGtB,CACE,IAAI+I,EAAU1K,KAAK2M,wBAAwBnM,cAAc,wBACzD0E,KAAKyB,MAAMC,QAAQ,gDAAgDhD,SAAQ,CAACiJ,EAAU1K,KACpF+C,KAAK6B,OAAO8F,EAAU,CACpBhH,UAAW,IAAO1D,EAAI,EAAI,IACzB,CACDiD,cAAe,CACbC,QAASrF,KAAK2M,wBACdrH,MAAO,kBACPI,cAAe,yBACfC,SAAS,GAEXE,SAAU,GACV,IAGJX,KAAK6B,OAAO2D,EACZ,CAAE9E,QAAS,GACX,CACER,cAAe,CACbC,QAASrF,KAAK2M,wBACdrH,MAAO,kBACPI,cAAe,0BAEjBE,QAAS,GAEb,CACF,CAEA,kBAAAtB,GACE,MAAO,CAAExC,QAAS,oCAAqCkC,QAAS,wBAClE,IRGE8I,EAAuB,CAAC,GAE5B,WACI,IAAK,MAAOC,EAAKC,KAAUC,OAAOC,QAAQ9I,GACtC0I,EAAqBC,GAAO,IAAIC,CAExC,CAqBAG,GACA,EAAOxM,WAnBP,WACI,IAAIyM,EAAwB,GAE5B,IAAK,MAAOL,EAAKC,KAAUC,OAAOC,QAAQJ,GACxC,GAAwC,mBAA7BE,EAAM1I,mBAAmC,CAClD,IAAI+I,EAASL,EAAM1I,qBAEfgJ,MAAMC,QAAQF,GAChBD,EAAwBA,EAAsBI,OAAOH,GAErDD,EAAsBK,KAAKJ,EAE/B,CAGF,OAAOD,CACT,CAGgB9I,G","sources":["webpack://nws-website-frontend/./src/assets/js/utility.js","webpack://nws-website-frontend/./src/simple/scroll-indicator-bar/scroll-indicator-bar.js","webpack://nws-website-frontend/./src/section/header/header.js","webpack://nws-website-frontend/./src/assets/js/main.js","webpack://nws-website-frontend/./src/section/contact/contact.js","webpack://nws-website-frontend/./src/section/featured-highlight/featured-highlight.js","webpack://nws-website-frontend/./src/section/fullscreen-animated/fullscreen-animated.js","webpack://nws-website-frontend/./src/section/hero/hero.js","webpack://nws-website-frontend/./src/dynamic/nav/nav.js","webpack://nws-website-frontend/./src/section/project-map/project-map.js","webpack://nws-website-frontend/./src/base/02-content/responsiveTable.js","webpack://nws-website-frontend/./src/section/waterfall-feature-images/waterfall-feature-images.js"],"sourcesContent":["// Class List Manipulations\r\nexport const addClass = (el, cssClass) => {\r\n if (!el.classList.contains(cssClass)) {\r\n el.classList.add(cssClass);\r\n return true;\r\n }\r\n return false;\r\n};\r\n\r\nexport const removeClass = (el, cssClass) => {\r\n if (el.classList.contains(cssClass)) {\r\n el.classList.remove(cssClass);\r\n return true;\r\n }\r\n return false;\r\n};\r\n\r\nexport const toggleClass = (el, cssClass) => {\r\n addClass(el, cssClass) || removeClass(el, cssClass);\r\n};\r\n\r\nexport const toggleClasses = (el, classList) => {\r\n for (let c = 0; c < classList.length; c++) {\r\n addClass(el, classList[c]) || removeClass(el, classList[c]);\r\n }\r\n};\r\n\r\nexport const wrapElement = (el, wrapper, wrapperClass) => {\r\n el.parentNode.insertBefore(wrapper, el);\r\n wrapper.appendChild(el);\r\n addClass(wrapper, wrapperClass);\r\n};\r\n\r\n// Toggle binary\r\nexport const toggleAttribute = (el, attr) => {\r\n let currentValue = el.getAttribute(attr);\r\n\r\n if (currentValue == 'true') {\r\n el.setAttribute(attr, \"false\");\r\n return true;\r\n } else if (currentValue == 'false') {\r\n el.setAttribute(attr, \"true\");\r\n return true;\r\n }\r\n \r\n return false;\r\n};\r\n\r\n// Find Closest & return that element\r\nexport const findClosest = (child, find) => {\r\n if (!Element.prototype.matches) {\r\n Element.prototype.matches =\r\n Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;\r\n }\r\n if (!Element.prototype.closest) {\r\n Element.prototype.closest = function(s) {\r\n var el = this;\r\n \r\n do {\r\n if (Element.prototype.matches.call(el, s))\r\n {\r\n return el;\r\n }\r\n \r\n el = el.parentElement || el.parentNode;\r\n }\r\n while (el !== null && el.nodeType === 1);\r\n \r\n return null;\r\n };\r\n }\r\n\r\n if (child) {\r\n return child.closest(find);\r\n }\r\n\r\n return false;\r\n};\r\n","import {addClass, removeClass} from \"../../assets/js/utility\";\r\n\r\nclass ScrollIndicatorBar {\r\n constructor() {\r\n this.indicatorBar = document.querySelector(\".simple-scroll-indicator-bar\");\r\n this.indicator = document.querySelector(\"#scroll-indicator\");\r\n this.headerElement = document.querySelector(\".section-site-header\");\r\n\r\n if (this.indicator) {\r\n document.addEventListener(\"DOMContentLoaded\", this.checkTheme.bind(this));\r\n window.addEventListener(\"scroll\", this.grow.bind(this));\r\n }\r\n }\r\n\r\n \r\n grow() {\r\n const minHeight = 5; // default height set in scss\r\n let newHeight = minHeight;\r\n\r\n let scrollPercentage = (100 * window.scrollY) / (document.body.scrollHeight - window.innerHeight);\r\n\r\n if (scrollPercentage > minHeight) {\r\n newHeight = scrollPercentage;\r\n }\r\n\r\n this.indicator.style.height = newHeight + \"%\";\r\n \r\n // check header if theme change needed\r\n this.checkTheme();\r\n }\r\n\r\n checkTheme() {\r\n if (this.headerElement) {\r\n let frostedTheme = \"theme-frosted-white\";\r\n\r\n if(this.headerElement.classList.contains(frostedTheme)) {\r\n addClass(this.indicatorBar, frostedTheme);\r\n }\r\n else {\r\n removeClass(this.indicatorBar, frostedTheme);\r\n }\r\n }\r\n }\r\n}\r\n\r\nexport default ScrollIndicatorBar;","import {addClass, findClosest, removeClass, toggleAttribute, toggleClass} from '../../assets/js/utility';\r\n\r\nclass Header {\r\n constructor() {\r\n this.element = document.querySelector(\".section-site-header\");\r\n this.navbar = document.querySelector(\".section-site-header .dynamic-nav\");\r\n this.menuIcon = document.querySelector(\"#mobile-menu-icon\");\r\n }\r\n\r\n initNavbar(sections) {\r\n if (this.element && this.navbar) {\r\n this.headerHeight = this.element.offsetHeight;\r\n this.halfHeight = this.headerHeight / 2;\r\n this.themeChangeSections = sections; // sections requiring frosted treatment\r\n\r\n this.changeTheme.call(this);\r\n window.addEventListener(\"resize\", this.changeTheme.bind(this));\r\n window.addEventListener(\"scroll\", this.changeTheme.bind(this));\r\n window.addEventListener(\"scroll\", this.shrinkOnScroll.bind(this));\r\n }\r\n\r\n if (this.menuIcon) {\r\n this.menuIcon.addEventListener(\"click\", () => {\r\n toggleClass(this.menuIcon, \"open\");\r\n toggleAttribute(this.menuIcon, \"aria-expanded\");\r\n })\r\n }\r\n }\r\n\r\n /**\r\n * Changes the header theme when over certain components (eg: hero js)\r\n * Component class names from registerThemeColor() list\r\n * Section requres full selector, Classes is as would appear in the html\r\n */\r\n changeTheme() {\r\n const BREAKPOINT_MD = 886;\r\n\r\n // if using mobile nav, don't change themes\r\n if (window.innerWidth >= BREAKPOINT_MD) {\r\n const sectionClasses = this.themeChangeSections.map(( {section} ) => section);\r\n\r\n let sectionElements = document.querySelectorAll(sectionClasses.join(', '));\r\n let navIsOverTheme = false;\r\n\r\n for (let i = 0; i < sectionElements.length; i++) \r\n {\r\n let component = sectionElements[i];\r\n let top = component.getBoundingClientRect().top;\r\n let bottom = component.getBoundingClientRect().bottom;\r\n let componentHeight = component.offsetHeight;\r\n \r\n // find matching theme values in object array\r\n let themeClasses = this.checkComponentTheme(component);\r\n\r\n // skip if darkbackground isn't underneath the top component\r\n if ( top > this.headerHeight && bottom > (componentHeight + this.headerHeight)\r\n || bottom < 0\r\n ) {\r\n continue;\r\n }\r\n \r\n navIsOverTheme = true;\r\n\r\n //check whether scroll still inside component boundaries\r\n let beyondCurrentSectionTop = top >= 0 && top <= this.headerHeight && top > this.halfHeight;\r\n let beyondCurrentSectionBottom = bottom >= 0 && bottom <= this.halfHeight;\r\n\r\n // is the component in an animation wrapper? If so, use for next/prev comparisons\r\n let parentOfComponent = findClosest(component, \".pin-spacer\");\r\n component = parentOfComponent != null\r\n ? parentOfComponent\r\n : component;\r\n\r\n //check section siblings, minding animation wrappers\r\n let nextSection, prevSection;\r\n\r\n if (component.nextElementSibling) {\r\n nextSection = component.nextElementSibling.classList.contains('pin-spacer')\r\n ? component.nextElementSibling.firstElementChild\r\n : component.nextElementSibling;\r\n }\r\n \r\n if (component.previousElementSibling) {\r\n prevSection = component.previousElementSibling.classList.contains('pin-spacer')\r\n ? component.previousElementSibling.firstElementChild\r\n : component.previousElementSibling;\r\n }\r\n\r\n let isNextSiblingThemed = nextSection == sectionElements[i + 1];\r\n let isPrevSiblingThemed = prevSection == sectionElements[i - 1];\r\n\r\n // split class list into array for assignment\r\n themeClasses = themeClasses.split(\" \");\r\n\r\n // see if sibling is a different theme\r\n let isNextSiblingSameTheme = true, isPrevSiblingSameTheme = true;\r\n let nextClasses = \"\", prevClasses = \"\";\r\n\r\n for (let i = 0; i < themeClasses.length; i++) {\r\n if (nextSection && !this.checkComponentTheme(nextSection).includes(themeClasses[i]))\r\n {\r\n isNextSiblingSameTheme = false;\r\n nextClasses = this.checkComponentTheme(nextSection).split(\" \");\r\n break;\r\n }\r\n\r\n if (prevSection && !this.checkComponentTheme(prevSection).includes(themeClasses[i]))\r\n {\r\n isPrevSiblingSameTheme = false;\r\n prevClasses = this.checkComponentTheme(prevSection).split(\" \");\r\n break;\r\n }\r\n }\r\n\r\n if ( beyondCurrentSectionBottom && !isNextSiblingThemed\r\n || beyondCurrentSectionTop && !isPrevSiblingThemed\r\n ) {\r\n themeClasses.forEach(e => removeClass(this.element, e));\r\n } \r\n // pre-emptively add next/prev classes to avoid stutter\r\n else if ( beyondCurrentSectionBottom && isNextSiblingThemed && !isNextSiblingSameTheme ) {\r\n themeClasses.forEach(e => removeClass(this.element, e));\r\n\r\n nextClasses.forEach(e => addClass(this.element, e));\r\n } \r\n else if ( beyondCurrentSectionTop && isPrevSiblingThemed && !isPrevSiblingSameTheme ) {\r\n themeClasses.forEach(e => removeClass(this.element, e));\r\n prevClasses.forEach(e => addClass(this.element, e));\r\n }\r\n else \r\n {\r\n if (nextClasses) nextClasses.forEach(e => removeClass(this.element, e));\r\n if (prevClasses) prevClasses.forEach(e => removeClass(this.element, e));\r\n\r\n themeClasses.forEach(e => addClass(this.element, e));\r\n }\r\n\r\n //break once found current component\r\n break;\r\n }\r\n\r\n // fallback, remove all themes\r\n if (!navIsOverTheme) {\r\n removeClass(this.element, \"theme-frosted-white\");\r\n removeClass(this.element, \"theme-frosted-primary\");\r\n removeClass(this.element, \"transparent\");\r\n }\r\n }\r\n else {\r\n // remove all possible theme classes in case resize\r\n removeClass(this.element, \"theme-frosted-white\");\r\n removeClass(this.element, \"theme-frosted-primary\");\r\n removeClass(this.element, \"transparent\");\r\n }\r\n }\r\n\r\n // checks if themes are in component list\r\n // returns an array of class names\r\n checkComponentTheme(component) {\r\n if (component) {\r\n for(let i = 0; i < this.themeChangeSections.length; i++) {\r\n let eSection = this.themeChangeSections[i].section.replace(\".\", \"\");\r\n \r\n if (component.classList.contains(eSection))\r\n {\r\n return this.themeChangeSections[i].classes;\r\n }\r\n };\r\n \r\n return \"\";\r\n }\r\n }\r\n\r\n /**\r\n * Shrinks header height if user scrolls on the page.\r\n * Uses scss utility classes to adjust header & the
element, since it has\r\n * negative margin on it to allow hero components to be flush with the top\r\n */\r\n shrinkOnScroll() {\r\n const mainElement = document.querySelector(\"main\");\r\n const breakpoint = 886; // as per scss variables\r\n\r\n // do nothing if device small enough for mobile styles to trigger\r\n if (mainElement && window.innerWidth >= breakpoint) \r\n {\r\n if (document.body.scrollTop > this.halfHeight || document.documentElement.scrollTop > this.halfHeight) \r\n {\r\n addClass(this.element, 'half-height');\r\n addClass(this.element, 'mb-n-xl');\r\n } \r\n else \r\n {\r\n // reset\r\n removeClass(this.element, 'half-height');\r\n removeClass(this.element, 'mb-n-xl');\r\n }\r\n }\r\n }\r\n}\r\n\r\nlet headerObj = new Header();\r\n\r\nexport default headerObj;","import WaterfallFeatureImages from '../../section/waterfall-feature-images/waterfall-feature-images';\r\nimport ServiceRow from '../../section/service-row/service-row';\r\nimport ProjectDetail from '../../section/project-detail/project-detail';\r\nimport LogoShowcase from '../../dynamic/logo-showcase/logo-showcase';\r\nimport ProjectMap from '../../section/project-map/project-map';\r\nimport TextTeaser from '../../simple/text-teaser/text-teaser';\r\nimport IconList from '../../dynamic/icon-list/icon-list';\r\nimport FullscreenAnimated from '../../section/fullscreen-animated/fullscreen-animated';\r\nimport Contact from '../../section/contact/contact';\r\nimport ScrollIndicatorBar from '../../simple/scroll-indicator-bar/scroll-indicator-bar';\r\nimport ImageDetail from '../../simple/image-detail/image-detail';\r\nimport ContentRow from '../../section/content-row/content-row';\r\nimport SwallowtailBanner from '../../section/swallowtail-banner/swallowtail-banner';\r\nimport HighlightGroup from '../../dynamic/highlight-group/highlight-group';\r\nimport FeaturedHighlight from '../../section/featured-highlight/featured-highlight';\r\nimport FeaturedRow from '../../section/featured-row/featured-row';\r\nimport HighlightTile from '../../simple/highlight-tile/highlight-tile';\r\nimport Hero from '../../section/hero/hero';\r\nimport ProjectsGallery from '../../section/projects-gallery/projects-gallery';\r\nimport RichText from '../../simple/rich-text/rich-text';\r\nimport ProjectTile from '../../simple/project-tile/project-tile';\r\nimport Pagination from '../../dynamic/pagination/pagination';\r\nimport GridLayout from '../../dynamic/grid-layout/grid-layout';\r\nimport Spacer from '../../simple/spacer/spacer';\r\nimport Nav from '../../dynamic/nav/nav';\r\nimport Footer from '../../section/footer/footer';\r\nimport Header from '../../section/header/header';\r\nimport ResponsiveTables from '../../base/02-content/responsiveTable';\r\n\r\n//global scope\r\n//used for multiple instances of the same component\r\nvar globalClasses = {};\r\nwindow.classes = globalClasses;\r\n \r\n//used for class to class interactions\r\nvar mainClasses = {\r\n Contact,\r\n FeaturedHighlight,\r\n FullscreenAnimated,\r\n Hero,\r\n Nav,\r\n ProjectMap,\r\n ResponsiveTables,\r\n ScrollIndicatorBar,\r\n WaterfallFeatureImages\r\n};\r\n\r\n//used for class to class interactions\r\nvar mainClassesInstances = {};\r\n\r\nfunction init() {\r\n for (const [key, value] of Object.entries(mainClasses)) {\r\n mainClassesInstances[key] = new value();\r\n }\r\n}\r\n\r\n//register sections that want the navbar to be frosted when overtop\r\nfunction registerThemeColor() {\r\n var themeSectionSelectors = [];\r\n\r\n for (const [key, value] of Object.entries(mainClassesInstances)) {\r\n if (typeof value.registerThemeColor === 'function') {\r\n var values = value.registerThemeColor();\r\n\r\n if (Array.isArray(values)) {\r\n themeSectionSelectors = themeSectionSelectors.concat(values);\r\n } else {\r\n themeSectionSelectors.push(values);\r\n }\r\n }\r\n }\r\n\r\n return themeSectionSelectors;\r\n }\r\n\r\ninit();\r\nHeader.initNavbar(registerThemeColor());\r\n\r\nexport default mainClasses; ","class Contact {\r\n constructor() {}\r\n\r\n registerThemeColor() {\r\n return { section: \".section-contact\", classes: \"theme-frosted-primary\"};\r\n }\r\n}\r\nexport default Contact;","class FeaturedHighlight {\r\n constructor() {}\r\n\r\n registerThemeColor() {\r\n return { section: \".section-featured-highlight\", classes: \"theme-frosted-primary\"};\r\n }\r\n}\r\n\r\nexport default FeaturedHighlight;","class FullscreenAnimated {\r\n constructor() {\r\n this.introContainer = document.querySelector(\".animate-intro-separate-ways\");\r\n this.stackedBarsContainer = document.querySelector(\".animate-shift-stack\");\r\n this.pinSectorsContainer = document.querySelector(\".animate-pin-sector-list\");\r\n\r\n // don't animate on smaller devices\r\n const BREAKPOINT = 1077; // as per scss variables\r\n\r\n if (window.innerWidth >= BREAKPOINT)\r\n {\r\n if (this.introContainer) {\r\n this.introSeparateWaysAnimation();\r\n }\r\n\r\n if (this.stackedBarsContainer) {\r\n this.shiftStackAnimation();\r\n }\r\n\r\n if (this.pinSectorsContainer) {\r\n this.pinSectorsAnimation();\r\n }\r\n }\r\n }\r\n\r\n // Initial home page section animation\r\n introSeparateWaysAnimation() {\r\n let title = this.introContainer.querySelector(\"h1\");\r\n let leftHalf = this.introContainer.querySelector(\".half-left\");\r\n let transitionRightHalf = this.introContainer.querySelector(\".half-right\");\r\n\r\n gsap.to(title, {\r\n scrollTrigger: {\r\n trigger: this.introContainer.parentElement,\r\n start: \"20% 20%\",\r\n end: \"40% 20%\",\r\n pin: true,\r\n scrub: true,\r\n toggleActions: \"play none none reverse\",\r\n markers: false,\r\n },\r\n opacity: 0,\r\n yPercent: -105\r\n });\r\n\r\n // Timeline for halves split & slide up next section\r\n let tl = gsap.timeline({\r\n scrollTrigger: {\r\n trigger: this.introContainer.parentElement,\r\n start: \"center center-=20%\",\r\n toggleActions: \"play none none reverse\",\r\n markers: false,\r\n }\r\n });\r\n\r\n tl.to(leftHalf, { yPercent: 200, opacity: 0, ease: \"back.in(1)\" })\r\n .to(transitionRightHalf, { width: 0, opacity: 0, ease: \"power3.in\" }, \"<+0.3\")\r\n .to(leftHalf, { maxHeight: 0, duration: 0.1 }, \">\") // hide element on page scroll\r\n }\r\n\r\n // Transition from About Us to Sectors\r\n shiftStackAnimation() {\r\n let stickyLeft = this.stackedBarsContainer.querySelector(\".half-left\");\r\n let stickyLeftContent = stickyLeft.querySelector(\".half-wrapper\");\r\n\r\n // for animating up next content section\r\n let nextSection = this.stackedBarsContainer.parentElement.nextElementSibling;\r\n if (!nextSection) return false;\r\n\r\n let transitionRightHalf = nextSection.querySelector(\".half-right\");\r\n let nextLeftHalf = nextSection.querySelector(\".half-left\");\r\n if (!transitionRightHalf || !nextLeftHalf) return false;\r\n\r\n // positional functions for bar stack\r\n let scaleBarSize = () => transitionRightHalf.getBoundingClientRect().height / stickyLeftContent.getBoundingClientRect().height;\r\n\r\n /**\r\n * Calculates the change in position for the bars to avoid gaps/overlap based \r\n * on the difference of size between the two transitioning elements and what \r\n * numbered bar it is.\r\n * eg: 1st bar moves 10%, 2nd bar has to move 20% to close the gap, 3rd is 30%, etc.\r\n * @param {int} index \r\n * @returns {double} y position for the bar\r\n */\r\n let shiftBarsAfterAnimation = (index) => {\r\n let leftHeight = stickyLeftContent.getBoundingClientRect().height;\r\n let rightHeight = transitionRightHalf.getBoundingClientRect().height;\r\n let difference = leftHeight - rightHeight;\r\n const NUM_BARS = 10; // should match the number of animated bars\r\n\r\n return 0 - difference / NUM_BARS * (index + 1);\r\n };\r\n\r\n // necessary or bars will be in a separate stack context (no height)\r\n gsap.set(stickyLeft, {\r\n x: 0, \r\n y: 0,\r\n height: (i, self) => self.getBoundingClientRect().height,\r\n });\r\n\r\n // align bg bar stack with content element\r\n gsap.utils.toArray(\".bar\").forEach((bar, i) => {\r\n gsap.set(bar, { \r\n y: stickyLeftContent.getBoundingClientRect().height * -1, \r\n scrollTrigger: { invalidateOnRefresh: true }\r\n })\r\n });\r\n\r\n let tl = gsap.timeline({\r\n scrollTrigger: {\r\n trigger: stickyLeft,\r\n start: \"top+=10% center\",\r\n end: `bottom center`,\r\n toggleActions: \"play none none reverse\",\r\n scrub: 1.5,\r\n invalidateOnRefresh: true,\r\n markers: false\r\n }\r\n });\r\n\r\n tl.fromTo(stickyLeftContent, \r\n { opacity: 1 }, \r\n { duration: 0.3, opacity: 0}, \"<\")\r\n .to(\".bar\", {\r\n duration: 0.5,\r\n xPercent: 100,\r\n transformOrigin: \"0 100%\",\r\n scaleY: scaleBarSize,\r\n y: (index) => shiftBarsAfterAnimation(index),\r\n ease: \"power1.in\",\r\n stagger: { amount: 0.5 }\r\n }, \"<\")\r\n .to(stickyLeft, { opacity: 0 }, \">\");\r\n }\r\n\r\n // Sectors List \r\n pinSectorsAnimation() {\r\n let rightHalf = this.pinSectorsContainer.querySelector(\".half-right\");\r\n let leftHalf = this.pinSectorsContainer.querySelector(\".half-left\");\r\n let leftTopContent = leftHalf.querySelector(\".half-wrapper > div:first-child\");\r\n\r\n let tl = gsap.timeline({\r\n scrollTrigger: {\r\n trigger: this.pinSectorsContainer,\r\n start: `top-=13% center`,\r\n end: \"top center\",\r\n toggleActions: \"play none none reverse\",\r\n markers: false\r\n }\r\n });\r\n\r\n tl.fromTo(rightHalf, \r\n { opacity: 0 },\r\n { opacity: 1 })\r\n .fromTo(leftHalf, {\r\n opacity: 0,\r\n yPercent: 50\r\n }, { \r\n opacity: 1,\r\n yPercent: 0,\r\n y: () => leftTopContent.offsetHeight\r\n }, \">-0.4\");\r\n\r\n // pin right half on scroll within section\r\n gsap.to(rightHalf, {\r\n scrollTrigger: {\r\n trigger: rightHalf,\r\n start: \"bottom bottom\",\r\n endTrigger: this.pinSectorsContainer,\r\n end: \"bottom bottom\",\r\n pin: true,\r\n scrub: true,\r\n markers: false\r\n }\r\n });\r\n\r\n // undo initial offset to avoid content clipping at bottom\r\n gsap.fromTo(leftHalf, {\r\n y: () => leftTopContent.offsetHeight\r\n }, {\r\n scrollTrigger: {\r\n trigger: this.pinSectorsContainer,\r\n start: \"top center\",\r\n end: \"bottom bottom\",\r\n scrub: true,\r\n toggleActions: \"play none none reverse\",\r\n markers: false,\r\n },\r\n y: 0\r\n });\r\n \r\n // fade on scroll up\r\n gsap.to(leftTopContent, {\r\n scrollTrigger: {\r\n trigger: this.pinSectorsContainer,\r\n start: \"top+=20% center\",\r\n end: \"center center\",\r\n scrub: true,\r\n toggleActions: \"play none none reverse\",\r\n markers: false,\r\n },\r\n opacity: 0\r\n });\r\n }\r\n\r\n // must use section classes for header theming to work\r\n registerThemeColor() {\r\n let sectionThemes = [\r\n { section: \".theming-animate-intro-separate-ways\", classes: \"theme-frosted-white transparent\"}, \r\n { section: \".theming-animate-shift-stack\", classes: \"theme-frosted-white transparent\"},\r\n { section: \".theming-animate-pin-sector-list\", classes: \"theme-frosted-primary\"}\r\n ];\r\n\r\n return sectionThemes;\r\n }\r\n}\r\n\r\nexport default FullscreenAnimated;","class Hero {\r\n constructor() {}\r\n\r\n registerThemeColor() {\r\n return { section: \".section-hero\", classes: \"theme-frosted-white transparent\"};\r\n }\r\n}\r\n\r\nexport default Hero;","class Nav {\r\n constructor() {}\r\n}\r\n\r\nexport default Nav;","class ProjectMap {\r\n constructor() {\r\n this.mapContainer = document.querySelector('#projectMap');\r\n this.locationsFilePath = '/assets/datasources/map-locations.json';\r\n this.map;\r\n\r\n if (this.mapContainer) {\r\n this.initMap();\r\n this.getMapLocations();\r\n }\r\n }\r\n\r\n async initMap() {\r\n const { Map } = await google.maps.importLibrary('maps');\r\n\r\n this.map = new Map(this.mapContainer, {\r\n mapId: 'b099d3f6ebf0fca3',\r\n center: { lat: 56, lng: -116 },\r\n scaleControl: false,\r\n mapTypeControl: false,\r\n streetViewControl: false,\r\n zoom: 5,\r\n minZoom: 5,\r\n maxZoom: 7,\r\n restriction: {\r\n latLngBounds: {\r\n north: 68,\r\n south: 43,\r\n east: -70,\r\n west: -140,\r\n },\r\n },\r\n });\r\n }\r\n\r\n getMapLocations() {\r\n fetch(this.locationsFilePath)\r\n .then((response) => {\r\n if (response.ok) {\r\n return response.json();\r\n } else {\r\n throw new Error(response.statusText);\r\n }\r\n })\r\n .then((locations) => this.createCustomMarkers(locations))\r\n .catch((err) => {\r\n console.log(err);\r\n });\r\n }\r\n\r\n async createCustomMarkers(locations) {\r\n const { AdvancedMarkerElement } = await google.maps.importLibrary('marker');\r\n\r\n locations.forEach(([position, title, image, projectLink], i) => {\r\n const markerContent = document.createElement('div');\r\n markerContent.classList.add('marker-project');\r\n markerContent.innerHTML =\r\n '' +\r\n '
' +\r\n `` +\r\n `` +\r\n `
${title}
` +\r\n '
';\r\n\r\n const marker = new AdvancedMarkerElement({\r\n map: this.map,\r\n position,\r\n content: markerContent,\r\n title,\r\n gmpClickable: true,\r\n });\r\n\r\n // Add a click listener for each marker, and set up the info window.\r\n // not using info windows cause adding custom properties to markers\r\n // appears to be legacy only -- so cannot achieve same effect as previous\r\n marker.addListener('click', () => {\r\n if (marker.content.classList.contains('is-open')) {\r\n marker.content.classList.remove('is-open');\r\n marker.zIndex = null;\r\n } else {\r\n marker.content.classList.add('is-open');\r\n marker.zIndex = 1;\r\n }\r\n });\r\n });\r\n }\r\n\r\n registerThemeColor() {\r\n return {\r\n section: '.section-project-map',\r\n classes: 'theme-frosted-primary transparent',\r\n };\r\n }\r\n}\r\n\r\nexport default ProjectMap;\r\n","import {findClosest, wrapElement} from '../../assets/js/utility';\r\n\r\nclass ResponsiveTables {\r\n constructor() {\r\n // May want to tweak if any tables are used for non-data purposes in project\r\n this.tablesList = document.querySelectorAll('table');\r\n\r\n if (this.tablesList) {\r\n for (let i = 0; i < this.tablesList.length; i++) {\r\n // avoid double wrapping\r\n if (this.tablesList[i].parentElement.classList.contains('table-wrapper')) {\r\n continue;\r\n }\r\n\r\n wrapElement(this.tablesList[i], document.createElement('div'), \"table-wrapper\");\r\n this.setLabelColumn(this.tablesList[i]);\r\n }\r\n }\r\n }\r\n \r\n // assigns a set width for first column for wrapper shadow\r\n // based on auto-fit size determined on load or hardset width if too big\r\n setLabelColumn(el) {\r\n let width = 0;\r\n let largestLabelWidth = 190; // in px\r\n let rows = el.querySelectorAll('tr');\r\n \r\n for (let i = 0; i < rows.length; i++) {\r\n let tdFirst = rows[i].querySelector('td');\r\n\r\n if (tdFirst) {\r\n // special case: check if only 2 columns\r\n if (rows[i].cells.length === 2 && tdFirst.getAttribute('colspan') === null) {\r\n for (let c = 0; c < rows.length; c++) {\r\n rows[c].querySelector('td').style.position = \"relative\";\r\n rows[c].querySelector('td').style.backgroundColor = \"transparent\";\r\n }\r\n\r\n return;\r\n }\r\n\r\n if (tdFirst.getAttribute('colspan') == null) {\r\n width = tdFirst.clientWidth <= largestLabelWidth ? tdFirst.clientWidth + \"px\" : largestLabelWidth + \"px\";\r\n\r\n tdFirst.style.minWidth = width;\r\n\r\n let wrapper = findClosest(tdFirst, '.table-wrapper');\r\n wrapper.style.backgroundPosition = width + \" center, right center, \" + width + \" center, right center\";\r\n\r\n return;\r\n }\r\n }\r\n }\r\n };\r\n}\r\n\r\nexport default ResponsiveTables;","class WaterfallFeatureImages {\r\n constructor() {\r\n this.waterfallFeatureSection = document.querySelector(\".section-waterfall-feature-images\");\r\n\r\n if (this.waterfallFeatureSection) {\r\n this.waterfallAnimation();\r\n }\r\n }\r\n\r\n waterfallAnimation() {\r\n // don't animate on smaller devices\r\n const BREAKPOINT_MD = 886; // as per scss variables\r\n\r\n if (window.innerWidth >= BREAKPOINT_MD)\r\n {\r\n let content = this.waterfallFeatureSection.querySelector(\".dynamic-grid-layout\");\r\n gsap.utils.toArray(\".section-waterfall-feature-images .grid-item\").forEach((gridItem, i) => {\r\n gsap.fromTo(gridItem, { \r\n yPercent: -100 - (i % 2 * 40)\r\n }, {\r\n scrollTrigger: {\r\n trigger: this.waterfallFeatureSection,\r\n start: \"top center-=10%\",\r\n toggleActions: \"play none none reverse\",\r\n markers: false\r\n },\r\n yPercent: 0\r\n });\r\n });\r\n\r\n gsap.fromTo(content, \r\n { opacity: 0 }, \r\n { \r\n scrollTrigger: {\r\n trigger: this.waterfallFeatureSection,\r\n start: \"top center-=10%\",\r\n toggleActions: \"play none none reverse\",\r\n },\r\n opacity: 1\r\n });\r\n }\r\n }\r\n\r\n registerThemeColor() {\r\n return { section: \".section-waterfall-feature-images\", classes: \"theme-frosted-primary\"};\r\n }\r\n}\r\n\r\nexport default WaterfallFeatureImages;"],"names":["addClass","el","cssClass","classList","contains","add","removeClass","remove","findClosest","child","find","Element","prototype","matches","msMatchesSelector","webkitMatchesSelector","closest","s","this","call","parentElement","parentNode","nodeType","constructor","element","document","querySelector","navbar","menuIcon","initNavbar","sections","headerHeight","offsetHeight","halfHeight","themeChangeSections","changeTheme","window","addEventListener","bind","shrinkOnScroll","attr","currentValue","getAttribute","setAttribute","toggleAttribute","innerWidth","sectionClasses","map","section","sectionElements","querySelectorAll","join","navIsOverTheme","i","length","component","top","getBoundingClientRect","bottom","componentHeight","themeClasses","checkComponentTheme","nextSection","prevSection","beyondCurrentSectionTop","beyondCurrentSectionBottom","parentOfComponent","nextElementSibling","firstElementChild","previousElementSibling","isNextSiblingThemed","isPrevSiblingThemed","split","isNextSiblingSameTheme","isPrevSiblingSameTheme","nextClasses","prevClasses","includes","forEach","e","eSection","replace","classes","body","scrollTop","documentElement","mainClasses","Contact","registerThemeColor","FeaturedHighlight","FullscreenAnimated","introContainer","stackedBarsContainer","pinSectorsContainer","introSeparateWaysAnimation","shiftStackAnimation","pinSectorsAnimation","title","leftHalf","transitionRightHalf","gsap","to","scrollTrigger","trigger","start","end","pin","scrub","toggleActions","markers","opacity","yPercent","timeline","ease","width","maxHeight","duration","stickyLeft","stickyLeftContent","nextLeftHalf","set","x","y","height","self","utils","toArray","bar","invalidateOnRefresh","fromTo","xPercent","transformOrigin","scaleY","index","shiftBarsAfterAnimation","stagger","amount","rightHalf","leftTopContent","endTrigger","Hero","Nav","ProjectMap","mapContainer","locationsFilePath","initMap","getMapLocations","Map","google","maps","importLibrary","mapId","center","lat","lng","scaleControl","mapTypeControl","streetViewControl","zoom","minZoom","maxZoom","restriction","latLngBounds","north","south","east","west","fetch","then","response","ok","json","Error","statusText","locations","createCustomMarkers","catch","err","console","log","AdvancedMarkerElement","position","image","projectLink","markerContent","createElement","innerHTML","marker","content","gmpClickable","addListener","zIndex","ResponsiveTables","tablesList","wrapper","insertBefore","appendChild","setLabelColumn","rows","tdFirst","cells","c","style","backgroundColor","clientWidth","largestLabelWidth","minWidth","backgroundPosition","ScrollIndicatorBar","indicatorBar","indicator","headerElement","checkTheme","grow","newHeight","scrollPercentage","scrollY","scrollHeight","innerHeight","frostedTheme","WaterfallFeatureImages","waterfallFeatureSection","waterfallAnimation","gridItem","mainClassesInstances","key","value","Object","entries","init","themeSectionSelectors","values","Array","isArray","concat","push"],"sourceRoot":""}