{"version":3,"file":"js/9805-ff628eb1d7220bebf7fb.js","mappings":"+UAAO,IAAMA,EACX,oGACWC,EACX,qJACWC,EAAc,IACdC,EAA+B,IAC/BC,EAAoB,uBACpBC,EAAwC,IACxCC,EAAgC,C,+BCRtC,SAASC,EAAwBC,GACtC,IAIMC,EAJWC,SAASC,cACxB,qBAGqBC,QAAQC,WAAU,GACnCC,EAAOL,EAAME,cAAc,2BAKjC,OAJeF,EAAME,cAAc,kCAE5BI,YAAcP,EAEdM,CACT,C,4GCPO,IAAKE,EAAS,SAATA,GAAS,OAATA,EAAS,6BAATA,EAAS,oCAATA,CAAS,K,wJCLRC,EACR,SAACC,GACF,OAAOC,KAAKC,MAAMC,aAAaC,QAAQJ,GACzC,EAHWD,EAKR,SAACC,EAAaK,GACfF,aAAaG,QAAQN,EAAKC,KAAKM,UAAUF,GAC3C,E,+xECU8E,IAAAG,EAAA,SAAAC,I,sRAAAC,CAAAF,EAAAC,GAAA,I,MAAAE,EAAAC,EAAAJ,GAAA,SAAAA,IAAA,IAAAK,G,4FAAAC,CAAA,KAAAN,GAAA,QAAAO,EAAAC,UAAAC,OAAAC,EAAA,IAAAC,MAAAJ,GAAAK,EAAA,EAAAA,EAAAL,EAAAK,IAAAF,EAAAE,GAAAJ,UAAAI,GAM/C,OAN+CP,EAAAF,EAAAU,KAAAC,MAAAX,EAAA,OAAAY,OAAAL,KAGtEM,YAAc,SAAQX,EACtBY,cAAgB,kBAAiBZ,EACjCa,WAAa,IAAIC,IAAKd,EACtBe,WAAa,IAAID,IAAKd,CAAC,CAimB9B,O,EAjmB6BL,G,EAAA,EAAAR,IAAA,cAAAK,MA0D9B,SAAYwB,GACV,OAAOA,EAAWC,KAAI,SAACC,GACrB,MAAO,CACLC,KAAMD,EACNE,KAAMjD,EAAAA,YACNkD,SAAU,QAEd,GACF,GAAC,CAAAlC,IAAA,UAAAK,MAED,WAAW,IAAD8B,EAAAC,EAAA,KACRC,KAAKC,OAAS9C,SAASC,cAAc,cACrC4C,KAAKE,YAAc/C,SAASgD,gBAG5BH,KAAKI,eAAiB1C,EAAuBb,EAAAA,mBAEjB,OAAxBmD,KAAKI,gBACPJ,KAAKK,qBAAsB,EAC3BL,KAAKM,6BAA6BN,KAAKI,gBACvCJ,KAAKO,eAAeC,UAAUC,IAAIT,KAAKb,cAEvCa,KAAKU,aAAaF,UAAUC,IAAIT,KAAKb,aAIvC,IAuBQwB,EAvB8B,IAAIC,EAAAA,EAA8B,CACtEC,OAAQ,CACNC,OAAQd,KAAKe,YAAYD,OACzBE,6BAA8B,EAC9BC,YAAa,CACXtB,KAAMK,KAAKe,YAAYG,gBACvBtB,KAAMjD,EAAAA,YACNkD,SAAU,SAEZsB,MAAOnB,KAAKoB,YAAYpB,KAAKe,YAAYvB,aAE3C6B,oCAAkCvB,EAAA,GAAAwB,EAAAxB,EAC/BE,KAAKe,YAAYQ,gBAAkB,CAClCC,OAAQxB,KAAKe,YAAYU,iBACzBC,eAAgBjF,EAAAA,gBACjB6E,EAAAxB,EACAE,KAAKe,YAAYY,gBAAkB,CAClCH,OAAQxB,KAAKe,YAAYa,iBACzBF,eAAgBhF,EAAAA,gBACjBoD,KAIGa,aAERX,KAAK6B,QAASC,EAAAA,EAAAA,SAAc,CAC1BnB,aAAAA,EACAoB,UAAW/B,KAAKe,YAAYQ,gBAC5BS,eAAcV,EAAA,GACXtB,KAAKe,YAAYQ,gBAAkB,CAClCtE,MAAO,KAGXgF,cAAe,SAAAC,GAA8B,IAA3BC,EAAOD,EAAPC,QAASC,EAAUF,EAAVE,WAGzB,GAFcD,EAAQpC,EAAKgB,YAAYQ,iBAAiBtE,MAKtD,OAFA8C,EAAKsC,6BACLD,EAAWD,GAGbpC,EAAKuC,yBACP,IAGF,IAgMIC,EAhMAC,EAAexC,KAAKyC,QAExBzC,KAAK6B,OAAOa,WAAW,EACrBC,EAAAA,EAAAA,GAAU,CACRC,UAAW,aACXC,YAAa,qBACbC,UAAS,SAAC7F,EAAO8F,GACfC,aAAaR,GACbA,EAAeS,YACb,kBAAMF,EAAO9F,EAAM,GACnBL,EAAAA,6BAEJ,KAEFsG,EAAAA,EAAAA,GAAM,CACJN,UAAW,SACXO,UAAW,CACTC,KAAI,SAACC,EAAIC,GAAa,IAATC,EAAID,EAAJC,KACX,OAAKF,EAAKG,aAEHD,EAAIE,IAAAA,EAAAC,EAAA,uRAFoB,IAQjC,MAGJC,EAAAA,EAAAA,GAAK,CACHf,UAAW,eACXgB,eAAgB,SAACC,EAAKC,GAAmB,IAAfC,EAAOD,EAAPC,QAYxB,OAVAhE,EAAKV,WAAW2E,QAEhBjE,EAAKkE,SAAS,sBAAuB,CACnCC,OAAQ,CACNP,KAAMI,EAAQJ,KAAK/E,UAIvBmB,EAAKoE,mBAAqBJ,EAAQJ,KAAK/E,OAEhCiF,EAAMpE,KAAI,SAAClC,GAEhB,OADAwC,EAAKV,WAAW+E,IAAI7G,EAAK8G,UAAW9G,GAC7BA,CACT,GACF,EACA4F,UAAW,CACTmB,MAAK,WACH,OAAO,IACT,EACA/G,KAAM,SAACgH,EAAGC,GAAA,IAAIjB,EAAIiB,EAAJjB,KAAMkB,EAAUD,EAAVC,WAAU,OAC5BlB,EAAImB,IAAAA,EAAAhB,EAAA,wlCAGQa,EAAII,KAEGJ,EAAIF,UAIIE,EAAIK,WAAWC,MAKhCJ,EAAWK,UAAU,CACrBP,IAAAA,EACAQ,UAAW,sBAMXN,EAAWK,UAAU,CAAEP,IAAAA,EAAKQ,UAAW,UAKnB,GAApBR,EAAIS,aACFzB,EAAI0B,IAAAA,EAAAvB,EAAA,yBAAGa,EAAIS,cACXzB,EAAI2B,IAAAA,EAAAxB,EAAA,0BAAGa,EAAIS,cAIjBT,EAAIY,cAAgBZ,EAAIa,MAAK,IAC3B7B,EAAI8B,IAAAA,EAAA3B,EAAA,uNAGAa,EAAIa,MAAMhC,MAEd,KACFmB,EAAIa,MAAK,IACP7B,EAAI+B,IAAAA,EAAA5B,EAAA,yWAOJ,KAAI,MAKlB6B,EAAAA,EAAAA,GAAM,CAAExD,UAAW/B,KAAKe,YAAYY,kBAAmBe,WAAW,EAChEiB,EAAAA,EAAAA,GAAK,CACHf,UAAW,eACXgB,eAAgB,SAACC,EAAK2B,GAAmB,IAAfzB,EAAOyB,EAAPzB,QAIxB,OAFAhE,EAAKR,WAAWyE,QAEM,KAAlBD,EAAQ9G,MAAqB,IACjC8C,EAAK0F,mBAAqB1B,EAAQJ,KAAK/E,OAEhCiF,EAAMpE,KAAI,SAAClC,GAEhB,OADAwC,EAAKR,WAAW6E,IAAI7G,EAAKmI,OAAOC,GAAIpI,GAC7BA,CACT,IACF,EACA4F,UAAW,CACTmB,MAAK,WACH,OAAO,IACT,EACA/G,KAAM,SAACgH,EAAGqB,GAAA,IAAIrC,EAAIqC,EAAJrC,KAAMkB,EAAUmB,EAAVnB,WAAU,OAC5BlB,EAAIsC,IAAAA,EAAAnC,EAAA,i4DAGQa,EAAImB,OAAOf,KAEJJ,EAAImB,OAAOC,GAOfpB,EAAImB,OAAOd,WAAWkB,OAM3BvB,EAAImB,OAAOK,SAAW,IACO,GAAvBxB,EAAImB,OAAOK,SAAgB,MAAQ,OAOzCtB,EAAWK,UAAU,CACrBP,IAAAA,EACAQ,UAAW,iBAKTN,EAAWK,UAAU,CACrBP,IAAAA,EACAQ,UAAW,sBAIHR,EAAImB,OAAOM,SAAYzB,EAAI0B,aAOvC1B,EAAImB,OAAOK,SAAW,IACO,GAAvBxB,EAAImB,OAAOK,SAAgB,MAAQ,OAAM,SASjE/F,KAAK6B,OAAOqE,QAEZlG,KAAK6B,OAAOsE,GAAG,UAAU,WACvBC,uBAAsB,WACpBrG,EAAKkE,SAAS,sBAChB,GACF,IAGAjE,KAAKqG,aAAerG,KAAKsG,QAAQlJ,cAAc,wBAG/C4C,KAAKqG,aAAaE,iBAAiB,SAAS,SAACC,GAC3C,IAAMC,EAASD,EAAEC,OACjB1G,EAAK2G,YAAc,aAEnB1D,aAAaT,GAEbA,EAAcU,YAAW,WACvB,IAAM0D,EAAa5G,EAAK6G,gBAAgB,CACtC3J,MAAOwJ,EAAOzI,MACd6I,UAAWC,KAAKC,QAIa,GAA3BhH,EAAKoE,oBAAsD,GAA3BpE,EAAK0F,oBAIrB,IAAhBgB,EAAOzI,QAEX+B,EAAKiH,kBAAkBvJ,EAAAA,UAAUwJ,cACjCvJ,EAAuBb,EAAAA,kBAAmB8J,GAC1C5G,EAAKM,qBAAsB,EAC3BN,EAAKmH,0BAA0BT,EAAOzI,OACxC,GAAGlB,EAAAA,sCACL,GACF,GAAC,CAAAa,IAAA,6BAAAK,MAED,SAA2BA,GACzBgC,KAAKU,aAAaF,UAAU2G,OAAOnH,KAAKb,aAAcnB,GAClDA,GACFgC,KAAKO,eAAeC,UAAUC,IAAIT,KAAKb,YAE3C,GAAC,CAAAxB,IAAA,mCAAAK,MAED,WACE,IAAMA,EAAQgC,KAAK6B,OAAOuF,OAAOC,MAAMpK,MACjCqK,EAAUtH,KAAK4G,gBAAgB,CACnC3J,MAAOe,EACP6I,UAAWC,KAAKC,QAElBrJ,EAAuBb,EAAAA,kBAAmByK,GAE1CtH,KAAKkH,0BAA0BlJ,EACjC,GAAC,CAAAL,IAAA,eAAAK,MAED,SAAAuJ,GAA6BA,EAAdrD,OAAUsD,MAErBxH,KAAKE,YAAYM,UAAUC,IAAIT,KAAKZ,eAChBY,KAAKsG,QAAQlJ,cAC/B,wBAEUqK,UAEZzH,KAAKsC,0BACLtC,KAAK0H,mBAAmBD,QAE5B,GAAC,CAAA9J,IAAA,wBAAAK,MAED,WACE,IAAM2J,EAAWxK,SAASC,cAAc,oBAGpCuK,IACFA,EAASC,WAAa,GAGxB5H,KAAK6H,WAAWrH,UAAUsH,OAAO9H,KAAKb,aACtCa,KAAK+H,cAAcvH,UAAUC,IAAIT,KAAKb,aACtCa,KAAKC,OAAO+H,MAAMC,YAAY,oBAAqB,WACnDjI,KAAKC,OAAO+H,MAAMC,YAAY,iBAAkB,QAChDjI,KAAKC,OAAO+H,MAAMC,YAAY,oBAAqB,QACnDjI,KAAKC,OAAO+H,MAAMC,YAAY,yBAA0B,QACxDjI,KAAKC,OAAO+H,MAAMC,YAAY,8BAA+B,QAC7DjI,KAAKC,OAAO+H,MAAMC,YAAY,mBAAoB,QAClDjI,KAAKC,OAAO+H,MAAMC,YAAY,wBAAyB,QACvDjI,KAAKC,OAAO+H,MAAMC,YAAY,4BAA6B,QAC3DjI,KAAKE,YAAYM,UAAUC,IAAIT,KAAKZ,cACtC,GAAC,CAAAzB,IAAA,0BAAAK,MAED,WACEgC,KAAK6H,WAAWrH,UAAUC,IAAIT,KAAKb,aACnCa,KAAK+H,cAAcvH,UAAUsH,OAAO9H,KAAKb,aACzCa,KAAKC,OAAO+H,MAAME,eAAe,qBACjClI,KAAKC,OAAO+H,MAAME,eAAe,kBACjClI,KAAKC,OAAO+H,MAAME,eAAe,qBACjClI,KAAKC,OAAO+H,MAAME,eAAe,0BACjClI,KAAKC,OAAO+H,MAAME,eAAe,+BACjClI,KAAKC,OAAO+H,MAAME,eAAe,oBACjClI,KAAKC,OAAO+H,MAAME,eAAe,yBACjClI,KAAKC,OAAO+H,MAAME,eAAe,6BACjClI,KAAKE,YAAYM,UAAUsH,OAAO9H,KAAKZ,cACzC,GAAC,CAAAzB,IAAA,eAAAK,MAED,SAAawI,GACX,IAAMC,EAASD,EAAEC,OACXzI,EAAQyI,EAAOjJ,YAErBwC,KAAK0G,YAAcD,EAAO0B,QAAQzB,YAElC1G,KAAK6B,OAAOuF,OAAOgB,SAASpK,GAAO6D,SAEnC7B,KAAKkH,0BAA0BlJ,GAC/BgC,KAAKgH,kBAAkBvJ,EAAAA,UAAUwJ,aACnC,GAAC,CAAAtJ,IAAA,4BAAAK,MAED,SAA0BA,GACxBgC,KAAKqI,iBAAiB7H,UAAU2G,OAAOnH,KAAKb,YAAsB,GAATnB,EAC3D,GAAC,CAAAL,IAAA,4BAAAK,MAED,SAA0BA,GACxBgC,KAAKsI,iBAAiB9H,UAAU2G,OAAOnH,KAAKb,YAAsB,GAATnB,EAC3D,GAAC,CAAAL,IAAA,aAAAK,MAED,WACEgC,KAAKE,YAAYM,UAAUsH,OAAO9H,KAAKZ,eACvC4D,aAAahD,KAAKyC,SAClBzC,KAAKsC,yBACP,GAAC,CAAA3E,IAAA,4BAAAK,MAED,SAA0Bf,GACxB,IAAI+C,KAAKuI,oBAAoBtL,KAE7B+C,KAAKwI,yBAAyBvL,IAE1B+C,KAAKyI,4BAAT,CAEA,IAAMC,EAAa,CACjBzL,MAAAA,EACA4J,UAAWC,KAAKC,OAGlBrJ,EAAuBb,EAAAA,kBAAmB,CAAC6L,IAC3C1I,KAAKK,qBAAsB,CARgB,CAS7C,GAAC,CAAA1C,IAAA,+BAAAK,MAED,SAA6B2K,GAAoC,IAADC,EAAA,KAC9DD,EAASE,SAAQ,SAAChH,GAChB+G,EAAKhC,gBAAgB,CACnB3J,MAAO4E,EAAO5E,MACd4J,UAAWhF,EAAOgF,YAEpB,IAAMtJ,GAAOP,EAAAA,EAAAA,yBAAwB6E,EAAO5E,OAC5C2L,EAAKE,iBAAiBC,YAAYxL,EACpC,GACF,GAAC,CAAAI,IAAA,kBAAAK,MAED,SAAAgL,GAG+C,IAF7C/L,EAAK+L,EAAL/L,MACA4J,EAASmC,EAATnC,UAEIoC,EAAoB,GAClBC,EAAiBlJ,KAAKyI,2BAE5B,MAAa,IAATxL,GAAiC,MAAlBiM,EAA+BA,EAE5B,MAAlBA,GACFD,EAAkBE,KAAK,CACrBlM,MAAAA,EACA4J,UAAAA,IAGKoC,KAGTA,EAAoBC,EAAeE,QACjC,SAACvH,GAAwB,OACvBA,EAAO5E,QAAUA,IAAUA,EAAMoM,SAASxH,EAAO5E,MAAM,KAKrC2B,QAAU7B,EAAAA,+BAC9BkM,EAAkBK,MAGpBL,EAAkBM,QAAQ,CACxBtM,MAAAA,EACA4J,UAAAA,IAGKoC,EACT,GAAC,CAAAtL,IAAA,2BAAAK,MAED,WACE,OAAON,EAAuBb,EAAAA,kBAChC,GAAC,CAAAc,IAAA,sBAAAK,MAED,SAAoBf,GAElB,OADkB+C,KAAKwJ,2BACNC,MACf,SAACC,GAAE,OAAKA,EAAGlM,YAAYmM,OAAOC,gBAAkB3M,EAAM2M,aAAa,GAEvE,GAAC,CAAAjM,IAAA,2BAAAK,MAED,WACE,OAAOc,MAAM+K,KAAK7J,KAAK8I,iBAAiBgB,qBAAqB,MAC/D,GAAC,CAAAnM,IAAA,2BAAAK,MAED,SAAyBf,GAAgB,IAAD8M,EAAA,KAChCC,EAAchK,KAAKyI,2BACnBlL,GAAOP,EAAAA,EAAAA,yBAAwBC,GAErC+C,KAAK8I,iBAAiBmB,UAAY,GAE7BD,EAKLA,EAAYnB,SAAQ,SAACqB,GACnB,IAAM3M,GAAOP,EAAAA,EAAAA,yBAAwBkN,EAAWjN,OAChD8M,EAAKjB,iBAAiBC,YAAYxL,EACpC,IAPEyC,KAAK8I,iBAAiBC,YAAYxL,EAQtC,GAAC,CAAAI,IAAA,oBAAAK,MAED,SAAkBmM,GAChB,IAAMC,EAAapK,KAAKqK,2BAClBC,EAAYtK,KAAKuK,eAEvBC,OAAOC,UAAUC,MAAMP,EAASQ,EAAAA,EAAA,GAC3BP,GACAE,GAEP,GAAC,CAAA3M,IAAA,mBAAAK,MAED,SAAiB4M,GACf,IAAMrG,EAAMvE,KAAK6K,WAAWD,EAAO,cAC7BR,EAAapK,KAAKqK,2BAExBG,OAAOC,UAAUC,MAAMjN,EAAAA,UAAUqN,gBAAeH,EAAA,CAC9CI,KAAM,SACNC,aAAczG,EAAI0G,MAClBC,cAAe3G,EAAI4G,WAAa,EAChCC,aAAc7G,EAAI8G,QAAQC,UAC1BC,UAAWhH,EAAIF,UACfmH,UAAWjH,EAAImB,OAAOC,GACtB8F,aAAclH,EAAImB,OAAOuF,OACtBb,GAEP,GAAC,CAAAzM,IAAA,mBAAAK,MAED,SAAiB4M,GACf,IAAMrG,EAAMvE,KAAK6K,WAAWD,EAAO,cAC7BR,EAAapK,KAAKqK,2BAExBG,OAAOC,UAAUC,MAAMjN,EAAAA,UAAUqN,gBAAeH,EAAA,CAC9CI,KAAM,SACN9N,MAAO+C,KAAK6B,OAAOuF,OAAOC,MAAMpK,MAChCiO,cAAe3G,EAAI4G,WAAa,EAChCH,aAAczG,EAAI0G,MAClBG,aAAc7G,EAAI8G,QAAQC,UAC1BC,UAAWhH,EAAIF,WACZ+F,GAEP,GAAC,CAAAzM,IAAA,aAAAK,MAED,SAAW4M,EAAcG,GACvB,IAAMtE,EAASmE,EAAMnE,OACfiF,EAAQC,OAAOlF,EAAOmF,QAAQ,KAAKzD,QAAQuD,OACjD,OAAO1L,KAAK+K,GAAMc,IAAIH,EACxB,GAAC,CAAA/N,IAAA,2BAAAK,MAED,WAGE,MAAO,CACLf,MAHY+C,KAAK6B,OAAOuF,OAAOC,MAAMpK,MAIrC6O,SAAU,MACVC,QAASJ,OAAOnB,OAAOC,UAAUuB,OAAOrG,MACxCsG,aAAcjM,KAAK0G,YAEvB,GAAC,CAAA/I,IAAA,eAAAK,MAED,WACE,IAAMkO,EACJlM,KAAK6B,OAAOsK,YAAYnM,KAAKe,YAAYQ,iBAAiBoC,KAAKI,QAC5DqI,OACCC,EACJrM,KAAK6B,OAAOsK,YAAYnM,KAAKe,YAAYY,iBAAiBgC,KAAKI,QAC5DqI,OAEL,MAAO,CACLE,SAAUJ,EAAmBG,EAC7BA,iBAAAA,EACAH,iBAAAA,EAEJ,M,8EAAC/N,CAAA,CAvmB6E,CAEnDoO,EAAAA,IAAUpO,EAM9BqO,QAAU,CACf,OACA,UACA,aACA,aACA,WACA,aACA,SACA,gBACDrO,EAEMsO,OAAS,CACdC,OAAQC,OACRC,cAAe,CACbC,QAAS,EACT9B,KAAMY,QAERmB,cAAe,CACbD,QAAS,EACT9B,KAAMY,QAERzC,eAAgB,CACd2D,SAAS,EACT9B,KAAMgC,S","sources":["webpack://bbc-maestro/./app/webpack/packs/controllers/search/constants.ts","webpack://bbc-maestro/./app/webpack/packs/controllers/search/helpers.ts","webpack://bbc-maestro/./app/webpack/packs/controllers/search/types.ts","webpack://bbc-maestro/./app/webpack/javascripts/utils/localStorage.ts","webpack://bbc-maestro/./app/webpack/packs/controllers/search_controller.ts"],"sourcesContent":["export const COURSE_FIELDS =\n \"id,record_id,path,title,main_image,coming_soon,maestro.full_name,badge.new,badge.text,badge.theme\";\nexport const LESSON_FIELDS =\n \"id,lesson.path,title,record_id,maestro.full_name,coming_soon,lesson.id,lesson.title,lesson.main_image,lesson.duration,lesson.position,lesson_count\";\nexport const PORT_NUMBER = 443;\nexport const RECENT_SEARCH_DEBOUNCE_VALUE = 400;\nexport const RECENT_SEARCH_KEY = \"bbcm-recent-searches\";\nexport const COMMIT_RECENT_SEARCH_RESULT_WAIT_TIME = 4000;\nexport const MAX_NUMBER_OF_RECENT_SEARCHES = 5;\n","export function getRecentSearchTemplate(query: string) {\n const template = document.querySelector(\n \"#bm-recent-search\"\n ) as HTMLTemplateElement;\n\n const clone = template.content.cloneNode(true) as HTMLElement;\n const item = clone.querySelector(\".bm-recent-search__item\");\n const button = clone.querySelector(\".bm-recent-search__item button\");\n\n button.textContent = query;\n\n return item;\n}\n","export type RecentSearchType = {\n query: string;\n timestamp: number;\n};\n\nexport enum EventType {\n SearchResult = \"Search Result\",\n SearchResultTap = \"Search Result Tap\",\n}\n\nexport type SearchInputSource =\n | \"search-bar\"\n | \"trending-search\"\n | \"recent-search\";\n","export const localStorageHelper = {\n get(key: string) {\n return JSON.parse(localStorage.getItem(key));\n },\n\n set(key: string, value: any) {\n localStorage.setItem(key, JSON.stringify(value));\n },\n\n remove(key: string) {\n localStorage.removeItem(key);\n },\n};\n","import { Controller } from \"@hotwired/stimulus\";\nimport TypesenseInstantSearchAdapter from \"typesense-instantsearch-adapter\";\nimport instantsearch from \"instantsearch.js\";\nimport { searchBox, hits, index, stats } from \"instantsearch.js/es/widgets\";\nimport { localStorageHelper } from \"../../javascripts/utils/localStorage\";\nimport {\n COMMIT_RECENT_SEARCH_RESULT_WAIT_TIME,\n COURSE_FIELDS,\n LESSON_FIELDS,\n MAX_NUMBER_OF_RECENT_SEARCHES,\n PORT_NUMBER,\n RECENT_SEARCH_DEBOUNCE_VALUE,\n RECENT_SEARCH_KEY,\n} from \"./search/constants\";\n\nimport { getRecentSearchTemplate } from \"./search/helpers\";\n\nimport { RecentSearchType, EventType, SearchInputSource } from \"./search/types\";\n\nexport default class extends Controller {\n private hiddenClass = \"d-none\";\n private overflowClass = \"overflow-hidden\";\n private courseHits = new Map();\n private lessonHits = new Map();\n\n static targets = [\n \"hits\",\n \"default\",\n \"courseHits\",\n \"lessonHits\",\n \"trending\",\n \"recentList\",\n \"recent\",\n \"searchButton\",\n ];\n\n static values = {\n config: Object,\n courseResults: {\n default: 0,\n type: Number,\n },\n lessonResults: {\n default: 0,\n type: Number,\n },\n recentSearches: {\n default: false,\n type: Boolean,\n },\n };\n\n declare configValue: {\n apiKey: string;\n nearestNodeHost: string;\n nodesHosts: string[];\n courseIndexName: string;\n lessonIndexName: string;\n coursePresetName: string;\n lessonPresetName: string;\n };\n\n declare search: any;\n declare timerId: ReturnType;\n declare hitsTarget: HTMLElement;\n declare defaultTarget: HTMLElement;\n declare header: HTMLHeadElement;\n declare htmlElement: HTMLElement;\n declare courseHitsTarget: HTMLElement;\n declare lessonHitsTarget: HTMLElement;\n declare courseResultsValue: number;\n declare lessonResultsValue: number;\n declare inputElement: HTMLInputElement;\n declare trendingTarget: HTMLUListElement;\n declare recentListTarget: HTMLUListElement;\n declare recentTarget: HTMLElement;\n declare recentSearchesValue: boolean;\n declare storedSearches: Array;\n declare searchButtonTarget: HTMLButtonElement;\n declare inputSource: SearchInputSource;\n\n createNodes(nodesHosts: string[]) {\n return nodesHosts.map((node) => {\n return {\n host: node,\n port: PORT_NUMBER,\n protocol: \"https\",\n };\n });\n }\n\n connect() {\n this.header = document.querySelector(\".bm-header\") as HTMLElement;\n this.htmlElement = document.documentElement;\n\n // Get the recent searches from local storage\n this.storedSearches = localStorageHelper.get(RECENT_SEARCH_KEY);\n // Determine if we show the trending/recent searches list\n if (this.storedSearches !== null) {\n this.recentSearchesValue = true;\n this.displayInitialRecentSearches(this.storedSearches);\n this.trendingTarget.classList.add(this.hiddenClass);\n } else {\n this.recentTarget.classList.add(this.hiddenClass);\n }\n\n // Setup typesense adapter\n const typesenseInstantsearchAdapter = new TypesenseInstantSearchAdapter({\n server: {\n apiKey: this.configValue.apiKey,\n cacheSearchResultsForSeconds: 0,\n nearestNode: {\n host: this.configValue.nearestNodeHost,\n port: PORT_NUMBER,\n protocol: \"https\",\n },\n nodes: this.createNodes(this.configValue.nodesHosts),\n },\n collectionSpecificSearchParameters: {\n [this.configValue.courseIndexName]: {\n preset: this.configValue.coursePresetName,\n include_fields: COURSE_FIELDS,\n },\n [this.configValue.lessonIndexName]: {\n preset: this.configValue.lessonPresetName,\n include_fields: LESSON_FIELDS,\n },\n },\n });\n\n const { searchClient } = typesenseInstantsearchAdapter;\n\n this.search = instantsearch({\n searchClient,\n indexName: this.configValue.courseIndexName,\n initialUiState: {\n [this.configValue.courseIndexName]: {\n query: \"\",\n },\n },\n onStateChange: ({ uiState, setUiState }) => {\n const query = uiState[this.configValue.courseIndexName].query;\n\n if (query) {\n this.initSearchActiveState();\n setUiState(uiState);\n return;\n }\n this.removeSearchActiveState();\n },\n });\n\n let timerInputId = this.timerId;\n\n this.search.addWidgets([\n searchBox({\n container: \".searchbox\",\n placeholder: \"Search BBC Maestro\",\n queryHook(query, refine) {\n clearTimeout(timerInputId);\n timerInputId = setTimeout(\n () => refine(query),\n RECENT_SEARCH_DEBOUNCE_VALUE\n );\n },\n }),\n stats({\n container: \".stats\",\n templates: {\n text(data, { html }) {\n if (!data.hasNoResults) return null;\n\n return html`
\n

No results found

\n

\n Try searching for another course, name or topic\n

\n
`;\n },\n },\n }),\n hits({\n container: \".course-hits\",\n transformItems: (items, { results }) => {\n // Clear our course map to ensure current state is up to date\n this.courseHits.clear();\n\n this.dispatch(\"course-state-change\", {\n detail: {\n hits: results.hits.length,\n },\n });\n\n this.courseResultsValue = results.hits.length;\n\n return items.map((item) => {\n this.courseHits.set(item.record_id, item);\n return item;\n });\n },\n templates: {\n empty() {\n return null;\n },\n item: (hit, { html, components }) =>\n html`\n search#addSelectedQueryToRecentSearches click->search#trackCourseClick\"\n data-hit-id=\"${hit.record_id}\"\n >\n
\n \n \"\"\n \n
\n
\n

\n ${components.Highlight({\n hit,\n attribute: \"maestro.full_name\",\n })}\n

\n \n ${components.Highlight({ hit, attribute: \"title\" })}\n

\n \n ${hit._group_found == 1\n ? html`${hit._group_found} Related Lesson`\n : html`${hit._group_found} Related Lessons`}\n

\n
\n\n ${hit.coming_soon && !hit.badge.new\n ? html`\n ${hit.badge.text}\n

`\n : null}\n ${hit.badge.new\n ? html`
\n \n New\n

\n
`\n : null}\n \n `,\n },\n }),\n index({ indexName: this.configValue.lessonIndexName }).addWidgets([\n hits({\n container: \".lesson-hits\",\n transformItems: (items, { results }) => {\n // Clear our lesson map to ensure current state is up to date\n this.lessonHits.clear();\n\n if (results.query === \"\") return [];\n this.lessonResultsValue = results.hits.length;\n\n return items.map((item) => {\n this.lessonHits.set(item.lesson.id, item);\n return item;\n });\n },\n templates: {\n empty() {\n return null;\n },\n item: (hit, { html, components }) =>\n html`\n search#addSelectedQueryToRecentSearches click->search#trackLessonClick\"\n data-hit-id=\"${hit.lesson.id}\"\n >\n \n \n \n ${hit.lesson.duration}${\" \"}\n ${hit.lesson.duration == 1 ? \"min\" : \"mins\"}\n

\n \n
\n \n ${components.Highlight({\n hit,\n attribute: \"lesson.title\",\n })}\n \n

\n \n ${components.Highlight({\n hit,\n attribute: \"maestro.full_name\",\n })}\n \n Lesson ${hit.lesson.position}/${hit.lesson_count}\n

\n
\n \n ${hit.lesson.duration}${\" \"}\n ${hit.lesson.duration == 1 ? \"min\" : \"mins\"}\n

\n \n `,\n },\n }),\n ]),\n ]);\n\n this.search.start();\n\n this.search.on(\"render\", () => {\n requestAnimationFrame(() => {\n this.dispatch(\"search-state-change\");\n });\n });\n\n // Bind events to input\n this.inputElement = this.element.querySelector(\".ais-SearchBox-input\");\n let typingTimer: ReturnType;\n\n this.inputElement.addEventListener(\"input\", (e: Event) => {\n const target = e.target as HTMLInputElement;\n this.inputSource = \"search-bar\";\n\n clearTimeout(typingTimer);\n\n typingTimer = setTimeout(() => {\n const updateList = this.addRecentSearch({\n query: target.value,\n timestamp: Date.now(),\n });\n\n // If we have no results, don't add the term to the recent searches list\n if (this.courseResultsValue == 0 && this.lessonResultsValue == 0)\n return;\n\n // If the search field is empty, don't track or add to recent searches\n if (target.value == \"\") return;\n\n this.trackSearchResult(EventType.SearchResult);\n localStorageHelper.set(RECENT_SEARCH_KEY, updateList);\n this.recentSearchesValue = true;\n this.updateRecentSearchesState(target.value);\n }, COMMIT_RECENT_SEARCH_RESULT_WAIT_TIME);\n });\n }\n\n recentSearchesValueChanged(value: boolean) {\n this.recentTarget.classList.toggle(this.hiddenClass, !value);\n if (value) {\n this.trendingTarget.classList.add(this.hiddenClass);\n }\n }\n\n addSelectedQueryToRecentSearches() {\n const value = this.search.helper.state.query;\n const newList = this.addRecentSearch({\n query: value,\n timestamp: Date.now(),\n });\n localStorageHelper.set(RECENT_SEARCH_KEY, newList);\n\n this.updateRecentSearchesState(value);\n }\n\n updateHeader({ detail: { open } }) {\n if (open) {\n this.htmlElement.classList.add(this.overflowClass);\n const searchField = this.element.querySelector(\n \"input[type='search']\"\n ) as HTMLInputElement;\n searchField.focus();\n } else {\n this.removeSearchActiveState();\n this.searchButtonTarget.focus();\n }\n }\n\n initSearchActiveState() {\n const carousel = document.querySelector(\"ol.ais-Hits-list\");\n // When a new search is initiliased, explicitly move the carousel\n // all the way to the beginning again\n if (carousel) {\n carousel.scrollLeft = 0;\n }\n\n this.hitsTarget.classList.remove(this.hiddenClass);\n this.defaultTarget.classList.add(this.hiddenClass);\n this.header.style.setProperty(\"--header-bg-color\", \"#1a1a1a\");\n this.header.style.setProperty(\"--search-color\", \"#fff\");\n this.header.style.setProperty(\"--logo-fill-color\", \"#fff\");\n this.header.style.setProperty(\"--hamburger-menu-color\", \"#fff\");\n this.header.style.setProperty(\"--hamburger-menu-color-open\", \"#fff\");\n this.header.style.setProperty(\"--nav-item-color\", \"#fff\");\n this.header.style.setProperty(\"--logo-fill-color-bbc\", \"#fff\");\n this.header.style.setProperty(\"--logo-fill-color-maestro\", \"#fff\");\n this.htmlElement.classList.add(this.overflowClass);\n }\n\n removeSearchActiveState() {\n this.hitsTarget.classList.add(this.hiddenClass);\n this.defaultTarget.classList.remove(this.hiddenClass);\n this.header.style.removeProperty(\"--header-bg-color\");\n this.header.style.removeProperty(\"--search-color\");\n this.header.style.removeProperty(\"--logo-fill-color\");\n this.header.style.removeProperty(\"--hamburger-menu-color\");\n this.header.style.removeProperty(\"--hamburger-menu-color-open\");\n this.header.style.removeProperty(\"--nav-item-color\");\n this.header.style.removeProperty(\"--logo-fill-color-bbc\");\n this.header.style.removeProperty(\"--logo-fill-color-maestro\");\n this.htmlElement.classList.remove(this.overflowClass);\n }\n\n submitSearch(e: Event) {\n const target = e.target as HTMLElement;\n const value = target.textContent;\n // This will either be \"recent-search\" or \"trending-search\"\n this.inputSource = target.dataset.inputSource as SearchInputSource;\n\n this.search.helper.setQuery(value).search();\n\n this.updateRecentSearchesState(value);\n this.trackSearchResult(EventType.SearchResult);\n }\n\n courseResultsValueChanged(value: number) {\n this.courseHitsTarget.classList.toggle(this.hiddenClass, value == 0);\n }\n\n lessonResultsValueChanged(value: number) {\n this.lessonHitsTarget.classList.toggle(this.hiddenClass, value == 0);\n }\n\n disconnect() {\n this.htmlElement.classList.remove(this.overflowClass);\n clearTimeout(this.timerId);\n this.removeSearchActiveState();\n }\n\n updateRecentSearchesState(query: string) {\n if (this.doesSearchTermExist(query)) return;\n\n this.updateRecentSearchesList(query);\n\n if (this.getCurrentRecentSearches()) return;\n\n const searchItem = {\n query,\n timestamp: Date.now(),\n };\n\n localStorageHelper.set(RECENT_SEARCH_KEY, [searchItem]);\n this.recentSearchesValue = true;\n }\n\n displayInitialRecentSearches(searches: Array) {\n searches.forEach((search: RecentSearchType) => {\n this.addRecentSearch({\n query: search.query,\n timestamp: search.timestamp,\n });\n const item = getRecentSearchTemplate(search.query);\n this.recentListTarget.appendChild(item);\n });\n }\n\n addRecentSearch({\n query,\n timestamp,\n }: RecentSearchType): Array {\n let newRecentSearches = [];\n const recentSearches = this.getCurrentRecentSearches();\n\n if (query == \"\" && recentSearches != null) return recentSearches;\n\n if (recentSearches == null) {\n newRecentSearches.push({\n query,\n timestamp,\n });\n\n return newRecentSearches;\n }\n\n newRecentSearches = recentSearches.filter(\n (search: RecentSearchType) =>\n search.query !== query && !query.includes(search.query)\n );\n\n // If we hit the maximum amount of recent searches then remove the\n // last item\n if (newRecentSearches.length == MAX_NUMBER_OF_RECENT_SEARCHES) {\n newRecentSearches.pop();\n }\n\n newRecentSearches.unshift({\n query,\n timestamp,\n });\n\n return newRecentSearches;\n }\n\n getCurrentRecentSearches() {\n return localStorageHelper.get(RECENT_SEARCH_KEY);\n }\n\n doesSearchTermExist(query: string) {\n const listItems = this.getRecentSearchListItems();\n return listItems.some(\n (li) => li.textContent.trim().toLowerCase() === query.toLowerCase()\n );\n }\n\n getRecentSearchListItems() {\n return Array.from(this.recentListTarget.getElementsByTagName(\"li\"));\n }\n\n updateRecentSearchesList(query: string) {\n const recentItems = this.getCurrentRecentSearches();\n const item = getRecentSearchTemplate(query) as HTMLElement;\n\n this.recentListTarget.innerHTML = \"\";\n\n if (!recentItems) {\n this.recentListTarget.appendChild(item);\n return;\n }\n\n recentItems.forEach((recentItem: RecentSearchType) => {\n const item = getRecentSearchTemplate(recentItem.query) as HTMLElement;\n this.recentListTarget.appendChild(item);\n });\n }\n\n trackSearchResult(eventName: EventType) {\n const properties = this.getCommonEventProperties();\n const hitCounts = this.getHitCounts();\n\n window.analytics.track(eventName, {\n ...properties,\n ...hitCounts,\n });\n }\n\n trackLessonClick(event: Event) {\n const hit = this.getHitData(event, \"lessonHits\");\n const properties = this.getCommonEventProperties();\n\n window.analytics.track(EventType.SearchResultTap, {\n type: \"LESSON\",\n course_title: hit.title,\n list_position: hit.__position - 1,\n maestro_name: hit.maestro.full_name,\n course_id: hit.record_id,\n lesson_id: hit.lesson.id,\n lesson_title: hit.lesson.title,\n ...properties,\n });\n }\n\n trackCourseClick(event: Event) {\n const hit = this.getHitData(event, \"courseHits\");\n const properties = this.getCommonEventProperties();\n\n window.analytics.track(EventType.SearchResultTap, {\n type: \"COURSE\",\n query: this.search.helper.state.query,\n list_position: hit.__position - 1,\n course_title: hit.title,\n maestro_name: hit.maestro.full_name,\n course_id: hit.record_id,\n ...properties,\n });\n }\n\n getHitData(event: Event, type: string) {\n const target = event.target as HTMLElement;\n const hitId = Number(target.closest(\"a\").dataset.hitId);\n return this[type].get(hitId);\n }\n\n getCommonEventProperties() {\n const query = this.search.helper.state.query;\n\n return {\n query,\n platform: \"web\",\n user_id: Number(window.analytics.user().id()),\n input_source: this.inputSource,\n };\n }\n\n getHitCounts() {\n const num_hits_courses =\n this.search.renderState[this.configValue.courseIndexName].hits.results\n .nbHits;\n const num_hits_lessons =\n this.search.renderState[this.configValue.lessonIndexName].hits.results\n .nbHits;\n\n return {\n num_hits: num_hits_courses + num_hits_lessons,\n num_hits_lessons,\n num_hits_courses,\n };\n }\n}\n"],"names":["COURSE_FIELDS","LESSON_FIELDS","PORT_NUMBER","RECENT_SEARCH_DEBOUNCE_VALUE","RECENT_SEARCH_KEY","COMMIT_RECENT_SEARCH_RESULT_WAIT_TIME","MAX_NUMBER_OF_RECENT_SEARCHES","getRecentSearchTemplate","query","clone","document","querySelector","content","cloneNode","item","textContent","EventType","localStorageHelper","key","JSON","parse","localStorage","getItem","value","setItem","stringify","_default","_Controller","_inherits","_super","_createSuper","_this","_classCallCheck","_len","arguments","length","args","Array","_key","call","apply","concat","hiddenClass","overflowClass","courseHits","Map","lessonHits","nodesHosts","map","node","host","port","protocol","_collectionSpecificSe","_this2","this","header","htmlElement","documentElement","storedSearches","recentSearchesValue","displayInitialRecentSearches","trendingTarget","classList","add","recentTarget","searchClient","TypesenseInstantSearchAdapter","server","apiKey","configValue","cacheSearchResultsForSeconds","nearestNode","nearestNodeHost","nodes","createNodes","collectionSpecificSearchParameters","_defineProperty","courseIndexName","preset","coursePresetName","include_fields","lessonIndexName","lessonPresetName","search","instantsearch","indexName","initialUiState","onStateChange","_ref","uiState","setUiState","initSearchActiveState","removeSearchActiveState","typingTimer","timerInputId","timerId","addWidgets","searchBox","container","placeholder","queryHook","refine","clearTimeout","setTimeout","stats","templates","text","data","_ref2","html","hasNoResults","_templateObject","_taggedTemplateLiteral","hits","transformItems","items","_ref3","results","clear","dispatch","detail","courseResultsValue","set","record_id","empty","hit","_ref4","components","_templateObject2","path","main_image","large","Highlight","attribute","_group_found","_templateObject3","_templateObject4","coming_soon","badge","_templateObject5","_templateObject6","index","_ref5","lessonResultsValue","lesson","id","_ref6","_templateObject7","medium","duration","position","lesson_count","start","on","requestAnimationFrame","inputElement","element","addEventListener","e","target","inputSource","updateList","addRecentSearch","timestamp","Date","now","trackSearchResult","SearchResult","updateRecentSearchesState","toggle","helper","state","newList","_ref7","open","focus","searchButtonTarget","carousel","scrollLeft","hitsTarget","remove","defaultTarget","style","setProperty","removeProperty","dataset","setQuery","courseHitsTarget","lessonHitsTarget","doesSearchTermExist","updateRecentSearchesList","getCurrentRecentSearches","searchItem","searches","_this3","forEach","recentListTarget","appendChild","_ref8","newRecentSearches","recentSearches","push","filter","includes","pop","unshift","getRecentSearchListItems","some","li","trim","toLowerCase","from","getElementsByTagName","_this4","recentItems","innerHTML","recentItem","eventName","properties","getCommonEventProperties","hitCounts","getHitCounts","window","analytics","track","_objectSpread","event","getHitData","SearchResultTap","type","course_title","title","list_position","__position","maestro_name","maestro","full_name","course_id","lesson_id","lesson_title","hitId","Number","closest","get","platform","user_id","user","input_source","num_hits_courses","renderState","nbHits","num_hits_lessons","num_hits","Controller","targets","values","config","Object","courseResults","default","lessonResults","Boolean"],"sourceRoot":""}