67314.f06616b99fcd8263.js.map 73 KB

1
  1. {"version":3,"file":"static/chunks/67314.f06616b99fcd8263.js","mappings":"wGAAIA,E,WACJ,SAASC,IAAa,OAAOA,EAAWC,OAAOC,OAASD,OAAOC,OAAOC,OAAS,SAAUC,GAAK,IAAK,IAAIC,EAAI,EAAGA,EAAIC,UAAUC,OAAQF,IAAK,CAAE,IAAIG,EAAIF,UAAUD,GAAI,IAAK,IAAII,KAAKD,GAAG,IAAKE,eAAeC,KAAKH,EAAGC,KAAOL,EAAEK,GAAKD,EAAEC,IAAO,OAAOL,GAAMJ,EAASY,MAAM,KAAMN,WAcvQ,IAZc,SAAiBO,GAC7B,OAAoB,gBAAoB,MAAOb,EAAS,CACtDc,MAAO,GACPC,OAAQ,GACRC,QAAS,YACTC,KAAM,OACNC,MAAO,8BACNL,GAAQd,IAAUA,EAAqB,gBAAoB,OAAQ,CACpEoB,EAAG,+DACHF,KAAM,qB,uCCZNlB,E,WACJ,SAASC,IAAa,OAAOA,EAAWC,OAAOC,OAASD,OAAOC,OAAOC,OAAS,SAAUC,GAAK,IAAK,IAAIC,EAAI,EAAGA,EAAIC,UAAUC,OAAQF,IAAK,CAAE,IAAIG,EAAIF,UAAUD,GAAI,IAAK,IAAII,KAAKD,GAAG,IAAKE,eAAeC,KAAKH,EAAGC,KAAOL,EAAEK,GAAKD,EAAEC,IAAO,OAAOL,GAAMJ,EAASY,MAAM,KAAMN,WAcvQ,IAZc,SAAiBO,GAC7B,OAAoB,gBAAoB,MAAOb,EAAS,CACtDc,MAAO,GACPC,OAAQ,GACRC,QAAS,YACTC,KAAM,OACNC,MAAO,8BACNL,GAAQd,IAAUA,EAAqB,gBAAoB,OAAQ,CACpEoB,EAAG,mLACHF,KAAM,qB,qFCZNlB,EAAOqB,E,oLCqCX,EAxBwC,Y,IACtCC,EAAW,EAAXA,YACAC,EAAsB,EAAtBA,uBACAC,EAAU,EAAVA,WACU,EAAVC,WAEA,OAAIH,GAEA,SAACI,EAAAA,GAAM,CACLC,QAASC,EAAAA,GAAAA,MACTC,KAAMC,EAAAA,GAAAA,MACNC,QAAS,SAACzB,G,OAAMiB,EAAuBjB,EAAGkB,I,UAE1C,SAACQ,EAAAA,EAAS,MAMP,M,8DCAX,EAlBuC,Y,IAAGC,EAAI,EAAJA,KAAMC,EAAI,EAAJA,KACxC,GAAQC,EAAAA,EAAAA,GAAe,UAArB1B,EACR,OACE,UAAC2B,MAAG,CAACC,UAAWC,IAAAA,U,WACd,SAACC,OAAI,CAACF,UAAWC,IAAAA,c,UACf,SAACE,EAAAA,EAAY,OAEf,SAACC,IAAC,CAACJ,UAAWC,IAAAA,K,SACXJ,IAASQ,EAAAA,EAAAA,YACNjC,EAAE,aAAc,CACdkC,YAAaV,IAEfA,Q,4CC4JZ,EAlJsC,Y,QAAGW,cAAiBC,EAAM,EAANA,OAAQC,EAAgB,EAAhBA,iBAC1D,GAAQX,EAAAA,EAAAA,GAAe,UAArB1B,EAENsC,GAAkC,QAAlCA,EAAAA,EAAAA,IAAUC,EAAAA,IAAwB,GAD7BC,EACLF,EAAkC,GADJG,EAC9BH,EAAkC,GACoBI,GAAAA,EAAAA,EAAAA,UAASL,EAAmB,EAAI,MAAjFM,EAAiDD,EAAqC,GAAhEE,EAA2BF,EAAqC,GAE/CA,GAAAA,EAAAA,EAAAA,UAAiB,MAAxDG,EAAuCH,EAAsB,GAA5CI,EAAsBJ,EAAsB,IACpEK,EAAAA,EAAAA,YAAU,WACJN,EAAgBO,SAClBF,EAAmBL,EAAgBO,QAAQC,aAE5C,CAACN,EAAsBF,KAG1BM,EAAAA,EAAAA,YAAU,WACRH,EAAwBP,EAAmB,EAAI,QAC9C,CAACA,IAEJ,IAAMa,GAASC,EAAAA,EAAAA,aACTC,GAAWC,EAAAA,EAAAA,MACXC,GAAiBC,EAAAA,EAAAA,cACrB,SAACC,GAECA,EAAMC,iBACNb,GAAwB,SAACc,G,OAA6BA,EAA2B,KACjFlB,MAEF,CAACA,IAEGmB,GAAmBJ,EAAAA,EAAAA,cACvB,SAACC,GAECA,EAAMC,iBACNb,GAAwB,SAACc,G,OAA6BA,EAA2B,KACjFlB,MAEF,CAACA,IAEGoB,GAAiBL,EAAAA,EAAAA,cACrB,SAACM,GACC,IAAQrC,EAA0BqC,EAA1BrC,KAAMsC,EAAoBD,EAApBC,WAAYC,EAAQF,EAARE,IAC1Bb,EAAOc,MAAKC,EAAAA,EAAAA,IAAiCH,EAAYC,IAAMG,MAAK,WAClEd,EAAS,CAAE3B,KAAM0C,EAAAA,GAAAA,KAA0BC,QAAS,CAAE5C,KAAAA,EAAMsC,WAAAA,EAAYC,IAAAA,KACxEX,EAAS,CAAE3B,KAAM4C,EAAAA,GAAAA,KAAgBD,SAAS,SAG9C,CAAChB,EAAUF,KAEboB,EAAAA,EAAAA,IACE,KACAhB,EACA,CACEiB,QAASlC,GAA6C,IAAzBM,EAC7B6B,aAAc,CAAC,UAEjB,CAAChC,KAEH8B,EAAAA,EAAAA,IACE,OACAX,EACA,CACEY,QAASlC,GAAoBM,IAAyBN,EAAmB,EACzEmC,aAAc,CAAC,UAEjB,CAAChC,KAEH8B,EAAAA,EAAAA,IACE,SACA,WACE,IAAIG,EAAa,KACjBhF,OAAOiF,KAAKtC,GAAQuC,SAAQ,SAACC,GAC3B,IAAMC,EAAkBzC,EAAOwC,GAAcE,MAC3C,SAACjB,G,OAAYA,EAAQkB,QAAUpC,KAE7BkC,IACFJ,EAAaI,MAGjBjB,EAAea,KAEjB,CAAEF,QAAkC,OAAzB5B,EAA+B6B,aAAc,CAAC,UACzD,CAAC7B,EAAsBP,EAAQwB,IAEjC,IAAM9C,EAAyB,SAC7B0C,EACAwB,IAEAC,EAAAA,EAAAA,IAAe,iCAEfzB,EAAM0B,kBACN9B,EAAS,CAAE3B,KAAM0D,EAAAA,GAAAA,KAA6Bf,QAASY,KAGzD,OAAyB,IAArB3C,GACK,SAACL,IAAC,CAACJ,UAAWC,IAAAA,S,SAAkB7B,EAAE,iCAGzC,UAACoF,KAAE,CAACC,KAAK,U,WACP,SAAC1D,MAAG,CACFC,UAAWC,IAAAA,UACXyD,MAAO,CACLC,UAAW1C,EAAkB,cAA8B,OAAhBA,EAAgB,OAAQ,uBAGvE,SAAC2C,KAAE,CAACH,KAAK,e,SACN5F,OAAOiF,KAAKtC,GAAQqD,KAAI,SAACb,GACxB,OACE,UAACjD,MAAG,C,WACF,SAACA,MAAG,CAACC,UAAWC,IAAAA,YAAoB6D,GAAId,E,SACrCA,KAEH,SAACQ,KAAE,CAACC,KAAK,QAAQM,kBAAiBf,E,SAC/BxC,EAAOwC,GAAca,KAAI,SAAC5B,GACzB,IAAQrC,EAAqBqC,EAArBrC,KAAMsC,EAAeD,EAAfC,WACR9C,EAAa2B,IAAyBkB,EAAQkB,MACpD,OACE,UAACS,KAAE,CACDI,IAAK5E,EAAayB,EAAkB,KACpC4C,KAAK,SACLQ,gBAAe7E,EAEfY,UAAWkE,IAAWjE,IAAAA,SAAkB,UAACA,IAAAA,SAAkBb,IAC3DM,QAAS,W,OAAMsC,EAAeC,IAC9BkC,YAAa,W,OAAMnD,EAAwBiB,EAAQkB,Q,WAEnD,SAACiB,EAAa,CAACxE,KAAMA,EAAMC,KAAMqC,KACjC,SAACnC,MAAG,CAACC,UAAWC,IAAAA,uB,UACd,SAACoE,EAAc,CACbpF,YAAagD,EAAQhD,YACrBG,WAAYA,EACZD,WAAY8C,EAAQE,IACpBjD,uBAAwBA,QAXvB+C,EAAQkB,cAbbH,Y,oFH9ItB,SAASpF,IAAa,OAAOA,EAAWC,OAAOC,OAASD,OAAOC,OAAOC,OAAS,SAAUC,GAAK,IAAK,IAAIC,EAAI,EAAGA,EAAIC,UAAUC,OAAQF,IAAK,CAAE,IAAIG,EAAIF,UAAUD,GAAI,IAAK,IAAII,KAAKD,GAAG,IAAKE,eAAeC,KAAKH,EAAGC,KAAOL,EAAEK,GAAKD,EAAEC,IAAO,OAAOL,GAAMJ,EAASY,MAAM,KAAMN,WAEvQ,IIHA,EJkBA,EAfe,SAAkBO,GAC/B,OAAoB,gBAAoB,MAAOb,EAAS,CACtDc,MAAO,GACPC,OAAQ,GACRC,QAAS,YACTC,KAAM,OACNC,MAAO,8BACNL,GAAQd,IAAUA,EAAqB,gBAAoB,OAAQ,CACpEoB,EAAG,6UACAC,IAAWA,EAAsB,gBAAoB,OAAQ,CAChEsF,OAAQ,kCACRC,YAAa,EACbxF,EAAG,gC,SIfFyF,GAAAA,EACU,cAAbC,gBADGD,EAEU,cAAbE,gBAFGF,EAGS,aAAZG,eAHGH,EAIW,eAAdI,iBAJGJ,EAKU,cAAbK,gBALGL,EAMU,cAAbM,gB,CANGN,IAAAA,EAAU,KASf,ICTA,EDSA,IE6DA,EAnD+B,Y,IAAGO,EAAK,EAALA,MAAOC,EAAsB,EAAtBA,uBAAwBC,EAAY,EAAZA,aACzD,GAAQnF,EAAAA,EAAAA,GAAe,UAArB1B,EAMJ8G,EAAO,KACPC,EAAY,KAChB,GAAIH,EACFG,GAAY,SAAC/E,IAAC,C,SAAEhC,EAAE,0BAClB8G,GAAO,SAACE,EAAAA,EAAc,QACjB,CACL,IAAIC,EAAY,GAChB,OAAQN,GACN,KAAKP,EAAAA,cACHa,EAAYjH,EAAE,uBACd8G,GAAO,SAACI,EAAgB,IACxB,MACF,KAAKd,EAAAA,cACHa,EAAYjH,EAAE,uBACd8G,GAAO,SAACI,EAAgB,IACxB,MACF,QACED,EAAYjH,EAAE,eACd8G,GAAO,SAACK,EAAAA,EAAS,IAGrBJ,GACE,UAACpF,MAAG,C,WACF,SAACG,OAAI,C,SAAEmF,KACP,SAACG,EAAAA,EAAI,CACHC,KAAK,8BACLC,UAAQ,EACRpG,QAASqG,EAAAA,EAAAA,UACTjG,QAhCqB,YAE3BkG,EAAAA,EAAAA,IAAoB,GAAkD,OAA/CX,EAAe,cAAgB,gBAAgB,Y,SAgC/D7G,EAAE,oBAMX,OACE,UAAC2B,MAAG,CAACC,UAAWC,IAAAA,U,UACbiF,EACAC,M,oBC7CMU,EAA2B,SAACC,GACvC,OAAOC,KAAKC,IAAc,IAAV,EAAiB,KAAO,GC2B1C,EAjCuC,Y,IACrCC,EAAiB,EAAjBA,kBACAH,EAAM,EAANA,OACAI,EAAc,EAAdA,eACAC,EAAa,EAAbA,cAEM,GAAQrG,EAAAA,EAAAA,GAAe,UAArB1B,EAER,OACE,UAAC2B,MAAG,CAACC,UAAWkE,IAAWjE,IAAAA,eAAuBiG,GAAkBjG,IAAAA,gB,WAClE,UAACF,MAAG,CAACC,UAAWC,IAAAA,e,WACd,UAACF,MAAG,C,WACF,SAACqG,KAAE,CAACpG,UAAWC,IAAAA,a,SAAsB7B,EAAE,0BACvC,SAACgC,IAAC,CAACJ,UAAWC,IAAAA,gB,SAAyB7B,EAAE,gCAG3C,UAAC2B,MAAG,CAACC,UAAWC,IAAAA,iBAAyBP,QAASyG,E,WAChD,SAACpG,MAAG,CACFC,UAAWC,IAAAA,aAGXyD,MAAO,CAAE,WAAYmC,EAAyBC,OAEhD,SAAC/F,MAAG,CAACC,UAAWC,IAAAA,U,UACd,SAACmF,EAAAA,EAAc,aAIrB,SAAChF,IAAC,CAACJ,UAAWC,IAAAA,W,SAAoBgG,Q,8FCkDxC,GApEuC,Y,IAAGI,EAAY,EAAZA,aAAcpB,EAAY,EAAZA,aAChDqB,GAAuBC,EAAAA,EAAAA,IAAYC,GAAAA,GAA4BC,GAAAA,IACjD3G,GAAAA,EAAAA,EAAAA,GAAe,UAA3B1B,EAAY0B,EAAZ1B,EAAGsI,EAAS5G,EAAT4G,KAELC,GAAS,QAEbC,QAASP,EAAaQ,QACnBC,MAAM,EAAG,IACTjD,KAAI,SAACkD,G,MAAU,GAAqBA,OAAlBA,EAAMC,SAAS,KAAiB,OAAdD,EAAME,YAC1CC,KAAK,KACRC,OAAQ,iBAEHlC,IAAgB,QACnBmC,OAAO,KAEDd,EAAqBnI,QAAU,CACnCkJ,aAAcf,EAAqBY,KAAK,KACxCI,kBAAmB,oCAKnBC,GAAiB5F,EAAAA,EAAAA,cACrB,SAAC6F,GACC,GAAIvC,EAAc,CAChB,IAAMwC,EAAsBD,EAAKE,OAAO7D,KAAI,SAAC8D,GAC3C,MAAO,CACLxF,IAAKwF,EAAMC,SACX1F,WAAY7B,EAAAA,EAAAA,KACZT,KAAM,IAAkDiI,QAA9CC,EAAAA,GAAAA,IAAoBH,EAAMC,SAAUlB,GAAM,MAGlD,QAHsDmB,EAAAA,GAAAA,IACtDF,EAAMI,YACN,KAEFC,MAAO5J,EAAE,+BAIb,OACE,SAAC6J,EAAY,CACX1H,cAAe,CACbC,OAAQ0H,IACNT,EAAoB5D,KAAI,SAACsE,EAAMhF,G,OAAW,kBAAKgF,GAAI,CAAEhF,MAAAA,QACrD,SAACgF,G,OAASA,EAAKH,SAEjBvH,iBAAkB+G,EAAKE,OAAOvJ,UAKtC,OACE,qB,SACGqJ,EAAKE,OAAO7D,KAAI,SAAC8D,G,OAChB,SAACS,EAAAA,EAAgB,CAEfC,OAAQV,EACRW,OAAQC,GAAAA,EAAAA,QACRC,QAASC,GAAAA,EAAAA,SAHJd,EAAMC,iBASrB,CAAC3C,EAAcyB,EAAMtI,IAGvB,OAAO,SAACsK,EAAAA,EAAW,CAACC,UAAUC,EAAAA,GAAAA,IAAoBjC,GAASkC,OAAQtB,K,sECzFxDuB,GAAe,SAACC,GAC3B,OAAOA,G,kCLFJC,GAAAA,EACS,aAAZC,eADGD,EAEO,WAAVE,aAFGF,EAGW,eAAdG,iBAHGH,EAIU,cAAbI,gBAJGJ,EAKe,mBAAlBK,qBALGL,EAME,MAALM,Q,CANGN,IAAAA,EAAK,KASV,S,YMUMO,GAAe,CACnBC,WAAY,KACZC,WAAY,MACZC,SAAU,GAGNC,GAAkB,CACtB/H,MAAOoH,GAAAA,YAEHY,GAAoB,CACxBhI,MAAOoH,GAAAA,aACPxB,KAAM,CACJqC,YAAaN,KAIXO,GAAoB,CACxBN,WAAYD,GAAaC,WACzBO,aAAcR,GAAaG,SAC3BM,WAAY,MAGRC,GAAiC,2BAIjCC,GAAkB,SAACC,GACvB,OAAOA,GAAaA,EAAUC,aAAeD,EAAUE,MA0OzD,GAvO8B,WAC5B,IAA4BvJ,GAAAA,EAAAA,EAAAA,UAAiB,GAAtCgF,EAAqBhF,EAAmB,GAAhCwJ,EAAaxJ,EAAmB,GACzCyJ,GAAcC,EAAAA,EAAAA,QAAoB,MACN1J,GAAAA,EAAAA,EAAAA,WAAkB,GAA7C2J,EAA2B3J,EAAwB,GAAxC4J,EAAgB5J,EAAwB,GAChCA,GAAAA,EAAAA,EAAAA,UAAqB,MAAxCiE,EAAmBjE,EAA0B,GAAtC6J,EAAY7J,EAA0B,GACFA,GAAAA,EAAAA,EAAAA,UAAiB,MAA5DmF,EAA2CnF,EAAsB,GAA9C8J,EAAwB9J,EAAsB,GAChCA,GAAAA,EAAAA,EAAAA,UAAuB,MAAxDuF,EAAiCvF,EAA4B,GAA/C+J,EAAmB/J,EAA4B,GACRA,GAAAA,EAAAA,EAAAA,WAAS,GAA9DkE,EAAqDlE,EAAe,GAA5CgK,EAA6BhK,EAAe,GAErEiK,GAAYP,EAAAA,EAAAA,QAAkB,MAC9BQ,GAAWR,EAAAA,EAAAA,QAAqB,MAChCS,GAAiBT,EAAAA,EAAAA,QAAyB,MAC1CU,GAAeV,EAAAA,EAAAA,QAAqB,MACpCW,GAAgBX,EAAAA,EAAAA,QAAmC,OAEzDY,EAAAA,GAAAA,IAAuB,WACrBC,OAAOC,aAAeD,OAAOC,cAAgBD,OAAOE,wBAErBC,IAA3BC,UAAUC,eAEZD,UAAUC,aAAe,SAKiBF,IAAxCC,UAAUC,aAAaC,eACzBF,UAAUC,aAAaC,aAAe,SAACC,GAErC,IAAMD,EAEJF,UAAUI,oBAAsBJ,UAAUK,iBAAmBL,UAAUE,aAIzE,OAAKA,EAKE,IAAII,SAAQ,SAACC,EAASC,GAC3BN,EAAapN,KAAKkN,UAAWG,EAAaI,EAASC,MAL5CF,QAAQE,OAAO,IAAIC,MAAMjC,SASrC,IAEH,IAAMkC,GAAoBxK,EAAAA,EAAAA,cAAY,WAChC4I,EAAYnJ,SACdmJ,EAAYnJ,QAAQgL,iBAAiBrJ,SAAQ,SAACsJ,GAC5CA,EAAMC,UAGVhC,EAAU,KACT,IAKGnE,GAAgBxE,EAAAA,EAAAA,cACpB,oB,IAAO4K,E,8EACL,OADKA,IAAiB,EAAH,iCACKtG,GAMpBiE,GAAgBa,EAAU3J,WAC5B2J,EAAU3J,QAAQoL,KAAKC,KAAKC,UAAU/C,KAClC4C,GACFxB,EAAU3J,QAAQuL,SAItBR,IACInB,GACFA,EAAS5J,QAAQwL,aAEf3B,GACFA,EAAe7J,QAAQwL,aAErBzB,GACFA,EAAc/J,QAAQwL,aAEW,YAA/B1B,EAAa9J,QAAQyL,MAArB3B,C,KACF,C,EAAMA,EAAa9J,QAAQuL,UAtB3B,C,UAsBA,S,kCAGJ,CAACR,EAAmBlG,IAGhB6G,GAAqBnL,EAAAA,EAAAA,cACzB,SAACoL,GACC,IAAM1E,EAASoE,KAAKO,MAAMD,EAAQvF,MAC1B5F,EAAgByG,EAAhBzG,MAAO4F,EAASa,EAATb,KACf,OAAQ5F,GACN,KAAKoH,GAAAA,eACH0B,GAAa,GACb,MACF,KAAK1B,GAAAA,c,IAGE,EAFL0B,GAAa,GACbG,EAAgBrD,IACmB,QAA9B,IAAuBX,eAAO,IAA9B,WAAgC1I,UACnC8O,EAAAA,EAAAA,IAAsB,CACpBC,MAAO1F,EAAK2F,UACZ7E,OAAQC,GAAAA,EAAAA,QACR1I,KAAMuN,GAAAA,EAAAA,MACN5E,QAASC,GAAAA,EAAAA,UAGbtC,IACA,MACF,KAAK6C,GAAAA,mBACH0B,GAAa,GACbE,EAAqBpD,EAAK2F,WAC1B,MACF,KAAKnE,GAAAA,MACH0B,GAAa,IACb2C,EAAAA,EAAAA,IAAS,gBAAiB,CAAEtI,MAAOnD,IACnC+I,EAASnG,EAAAA,mBAMf,CAAC2B,IAGGmH,GAAqC3L,EAAAA,EAAAA,cAAY,oB,kEAEnD,O,sBAAA,C,EAAMuJ,EAAa9J,QAAQmM,aAAaC,UACtC,IAAI1E,GAAa,SAAI2E,IAAI,wB,cAD3B,UAGAJ,EAAAA,EAAAA,IAAS,gCACT3C,GAAa,GAGbK,EAAU3J,QAAU,IAAIsM,UACtB,mDAA8F,OAA3CC,GAAQC,IAAIC,iCAGjE9C,EAAU3J,QAAQ0M,OAAS,YACzBT,EAAAA,EAAAA,IAAS,0BACT3C,GAAa,GACbM,EAAS5J,QAAU8J,EAAa9J,QAAQ2M,iBACxC/C,EAAS5J,QAAQ4M,sBAvJW,GAwJ5BhD,EAAS5J,QAAQ6M,QAvJW,KAwJ5B,IAAMC,EAAU,IAAIC,WAAWnD,EAAS5J,QAAQgN,mBAChDnD,EAAe7J,QAAU,IAAIiN,iBAAiBnD,EAAa9J,QAAS,qBACpE2J,EAAU3J,QAAQoL,KAAKC,KAAKC,UAAU9C,KACtCuB,EAAc/J,QAAQkN,QAAQtD,EAAS5J,SACvC4J,EAAS5J,QAAQkN,QAAQrD,EAAe7J,SACxC6J,EAAe7J,QAAQkN,QAAQpD,EAAa9J,QAAQmN,aAEpDtD,EAAe7J,QAAQoN,KAAKC,UAAY,SAAC7M,GACvC0I,EJ1MsB,SAACU,EAAwBkD,GACvDlD,EAAS0D,qBAAqBR,GAI9B,IAHA,IAAIS,EAAS,EAEP,EAAaT,EAAX/P,OACCyQ,EAAI,EAAGA,EAAIzQ,EAAQyQ,GAAK,EAC/BD,GAAUT,EAAQU,GAEpB,IAAM9I,EAASC,KAAK8I,MAAMF,EAASxQ,GACnC,OAAO2H,EAAS,IAAM,IAAMA,EIiMVgJ,CAAiB9D,EAAS5J,QAAS8M,IAEzChE,GAAgBa,EAAU3J,UAC5B2J,EAAU3J,QAAQoL,KAAK5K,EAAM4F,QAKnCuD,EAAU3J,QAAQqN,UAAY,SAAC1B,GAC7BD,EAAmBC,IAGrBhC,EAAU3J,QAAQ2N,QAAU,YAC1B1B,EAAAA,EAAAA,IAAS,2BACT3C,GAAa,GACbC,EAASnG,EAAAA,cACT2H,K,oBAEQ,UACVkB,EAAAA,EAAAA,IAAS,8BACT1C,EAASnG,EAAAA,e,8BAEV,CAACsI,EAAoBX,IAElB6C,GAAiBrN,EAAAA,EAAAA,cAAY,oB,IAWzBsN,EAaCtD,EAMCuD,E,kEA5BVvE,EAAS,MACTC,EAAqB,MACrBC,EAAgB,MAChBC,GAA0B,GAE1BI,EAAa9J,QAAU,IAAIiK,OAAOC,aAAa,CAAE9B,WAAYD,GAAaC,a,iBAIzD,O,uBAAA,C,EAAMiC,UAAUC,aAAaC,aAAa,CAAEwD,MAAOrF,M,OAA5DmF,EAAS,SACf1E,EAAYnJ,QAAU6N,EACtB,IACE9D,EAAc/J,QAAU8J,EAAa9J,QAAQgO,wBAAwBH,GACrE,MAAOI,GAIP,MAHAhC,EAAAA,EAAAA,IAAS,0CAETlH,IACM,IAAI+F,MAAMjC,IAIlB,O,EAAMqD,K,cAAN,S,oBACO3B,EAAY,UAEFoB,UAAY9C,KAC3BoD,EAAAA,EAAAA,IAAS,8BACT1C,EAASnG,EAAAA,kBAEH0K,EAA2C,oBAAtBvD,EAAa/L,QAEtCyN,EAAAA,EAAAA,IAAS,kCAEX1C,EAASuE,EAAqB1K,EAAAA,cAA2BA,EAAAA,gB,oBAG3DsG,GAA0B,G,4BAE3B,CAAC3E,EAAemH,IAEnB,MAAO,CACL7C,UAAAA,EACA1F,MAAAA,EACAkB,kBAAAA,EACAI,aAAAA,EACAP,OAAAA,EACAd,uBAAAA,EACAgK,eAAAA,EACA7I,cAAAA,IC9KJ,GArFkD,Y,IAiD3BE,E,IAjD8BpB,aAAAA,OAAY,IAAG,GAAK,EAUnEqK,EAAAA,KARF7E,EAQE6E,EARF7E,UACAxE,EAOEqJ,EAPFrJ,kBACAI,EAMEiJ,EANFjJ,aACAtB,EAKEuK,EALFvK,MACAe,EAIEwJ,EAJFxJ,OACAd,EAGEsK,EAHFtK,uBACAgK,EAEEM,EAFFN,eACA7I,EACEmJ,EADFnJ,eAGFhF,EAAAA,EAAAA,YAAU,WAGR,OAFA6N,IAEO,WACL7I,OAKD,IAEH,IA6B4B,EAgBE,EAxC9B,OAAIsE,GACK,SAAC8E,GAAAA,EAAO,CAAC/P,KAAMgQ,GAAAA,EAAAA,QAGpBzK,GAASC,GAET,SAACjF,MAAG,CACFC,UAAWkE,KACT,UAACjE,KAAAA,WAAoBgF,I,UAGvB,SAACiH,EAAK,CACJjH,aAAcA,EACdF,MAAOA,EACPC,uBAAwBA,MAO5BqB,KAAqC,QAApBA,EAAAA,EAAaQ,eAAO,IAApBR,OAAAA,EAAAA,EAAsBlI,SAEvC,SAAC4B,MAAG,CACFC,UAAWkE,KAAW,EAGrB,IAFC,OADoB,EACnBjE,KAAAA,WAAoBgF,IACrB,OAFoB,EAEnBhF,KAAAA,kBAA2BgF,GAFR,I,UAKtB,SAACwK,GAAAA,EAAS,CAACnP,YAAa2F,OAM5B,qB,SACGI,GACC,SAACqJ,GAAa,CAACrJ,aAAcA,EAAcpB,aAAcA,KAEzD,SAAClF,MAAG,CACFC,UAAWkE,KAAW,EAGrB,IAFC,OADoB,EACnBjE,KAAAA,WAAoBgF,IACrB,OAFoB,EAEnBhF,KAAAA,oBAA6BgF,GAFV,I,UAKtB,SAAC0K,EAAa,CACZzJ,gBAAiBjB,EACjBgB,kBAAmBA,EACnBH,OAAQA,EACRK,cAtDc,WAEtBA,GAAc,W,oCCfZyJ,GAAc,CAClB,CACEhQ,KAAM,QACNuC,IAAK,EACLD,WAAY7B,EAAAA,EAAAA,KAEd,CACET,KAAM,SACNuC,IAAK,EACLD,WAAY7B,EAAAA,EAAAA,MAEd,CACET,KAAM,gBACNuC,IAAK,EACLD,WAAY7B,EAAAA,EAAAA,aAEd,CACET,KAAM,SACNuC,IAAK,EACLD,WAAY7B,EAAAA,EAAAA,MAEd,CACET,KAAM,cACNuC,IAAK,GACLD,WAAY7B,EAAAA,EAAAA,OAEd,CACET,KAAM,QACNuC,IAAK,QACLD,WAAY7B,EAAAA,EAAAA,OA4JhB,GAtJiC,WAC/B,IAAM,GAAQP,EAAAA,EAAAA,GAAe,UAArB1B,EACFyR,GAAoBtJ,EAAAA,EAAAA,IAAYuJ,EAAAA,GAAyBrJ,GAAAA,IACzDsJ,GAA2BxJ,EAAAA,EAAAA,IAAYyJ,GAAAA,GAAoCC,EAAAA,IAC3CnP,GAAAA,EAAAA,EAAAA,UAAiB,MAAhDR,EAA+BQ,EAAsB,GAAxCoP,EAAkBpP,EAAsB,GAEtDqP,GAAuBC,EAAAA,GAAAA,GAAoB9P,EARtB,OAU3Ba,EAAAA,EAAAA,YAAU,WAEJgP,IACFE,EAAAA,EAAAA,IAAmBF,EAAsB5H,GAAAA,EAAAA,cAE1C,CAAC4H,IAQJ,IAAMG,GAAsB3O,EAAAA,EAAAA,cAAY,SAACC,GACvCsO,EAAetO,EAAM2O,cAAcC,OAAS,QAC3C,IAWGC,GAAsB9O,EAAAA,EAAAA,cAC1B,W,OACEkO,EACGhM,KAAI,SAAC6M,G,OAAsB,kBACvBA,GAAgB,CACnB1I,MAAO5J,EAAE,kCACTa,aAAa,OAEd0R,OACCf,GAAY/L,KAAI,SAAC+M,G,OAAoB,kBAChCA,GAAc,CACjB5I,MAAO5J,EAAE,8BACTa,aAAa,UAGrB,CAAC4Q,EAAmBzR,IAehByS,GAAoBlP,EAAAA,EAAAA,cACxB,SAAC6F,GACC,IAAIC,EAAsB,GACtBhH,EAAmB,EAoBvB,OAlBK+G,GAIHC,GAAsB,OACjBD,EAAKa,OAAOyI,WAAWjN,KAAI,SAACkN,G,OAAoB,kBAC9CA,GAAc,CACjB/I,MAAO5J,EAAE,iCAFRoJ,OADiB,CAKpB,CACErF,IAAK7B,EACL4B,WAAY7B,EAAAA,EAAAA,YACZT,KAAMU,EACN0H,MAAO5J,EAAE,mBAGbqC,EAAmB+G,EAAKa,OAAOyI,WAAW3S,OAAS,IAfnDsJ,EAAsBgJ,IACtBhQ,EAAmBoP,EAAkB1R,OAASyR,GAAYzR,SAiB1D,SAAC8J,EAAY,CACX1H,cAAe,CACbC,OAAQ0H,IACNT,EAAoB5D,KAAI,SAACsE,EAAMhF,G,OAAW,kBAAKgF,GAAI,CAAEhF,MAAAA,QACrD,SAACgF,G,OAASA,EAAKH,SAEjBvH,iBAAAA,OAKR,CAACgQ,EAAqBZ,EAAkB1R,OAAQmC,EAAalC,IAG/D,OACE,UAAC2B,MAAG,CAACC,UAAWC,IAAAA,U,WACd,SAACF,MAAG,CACFC,UAAWkE,IAAWjE,IAAAA,gBACpB,UAACA,IAAAA,mBAA4B8P,I,UAG7BA,IACA,UAAChQ,MAAG,CAACC,UAAWC,IAAAA,mB,WACd,SAAC+Q,GAAAA,EAAU,KACX,SAACC,QAAK,CACJC,SAAUZ,EACVa,YAAa/S,EAAE,2BACf4B,UAAWC,IAAAA,MACXJ,KAAK,OACLuR,UAAU,OAEVC,WAAS,UAcjB,SAACtR,MAAG,CAACC,UAAWC,IAAAA,c,SACb8P,GACC,SAACuB,GAAwB,CAACrM,cAAY,KAEtC,SAACyD,EAAAA,EAAW,CACVC,SAAUrI,GAAciR,EAAAA,GAAAA,IAAqB,CAAErE,MAAO5M,IAAiB,KACvEuI,OAAQgI,W,uGC1KpB,IAnBmC,Y,IAAGvQ,EAAW,EAAXA,YAC9B,GAAQR,EAAAA,EAAAA,GAAe,UAArB1B,EACR,OACE,qB,UACE,SAAC2B,MAAG,CAACC,UAAWC,IAAAA,U,UACd,UAACF,MAAG,CAACC,UAAWC,IAAAA,S,WACd,SAACF,MAAG,CAACC,UAAWC,IAAAA,c,UACd,SAAC+Q,EAAAA,EAAU,OAEb,SAAC5Q,IAAC,CAACJ,UAAWC,IAAAA,Y,SAAqB7B,EAAE,wBACrC,SAACgC,IAAC,CAACJ,UAAWC,IAAAA,iB,SACX7B,EAAE,+BAAgC,CAAEkC,YAAAA,e,+LC4DjD,IAzD0C,Y,IA8CjC+H,EA9CoCA,EAAM,EAANA,OAAQC,EAAM,EAANA,OAAQ,EAAF,EAAEE,QAAAA,OAAO,IAAG,EAAAC,EAAAA,EAAAA,IAAiB,EAChF,GAAW3I,EAAAA,EAAAA,GAAe,gBAAxB4G,KACF8K,GAAoBC,EAAAA,EAAAA,UACxB,W,OAAM3J,EAAAA,EAAAA,IAAoBO,EAAOT,SAAUlB,KAC3C,CAACA,EAAM2B,EAAOT,WAGV8J,GAAeC,EAAAA,EAAAA,GAAmBjL,GAExC,IAAKgL,EAAc,OAAO,KAE1B,IAAME,GAAgBC,EAAAA,EAAAA,IAAwBxJ,EAAOT,UAC/CkK,GAAcC,EAAAA,EAAAA,IAAeL,EAAcE,EAAcI,YAS/D,OACE,SAACjS,MAAG,CAACC,UAAWC,IAAAA,U,UACd,UAACF,MAAG,CAACC,UAAWC,IAAAA,c,WACd,UAACuF,EAAAA,EAAI,CACHxF,UAAWC,IAAAA,SACXwF,MAAMwM,EAAAA,EAAAA,IAA+B5J,EAAOT,UAC5ClI,QAboB,YAC1B2D,EAAAA,EAAAA,IAAgB,qBAAqB,CACnCmF,QAAAA,EACAF,OAAAA,K,UAYKwJ,EAAYI,mBAAmB,IAAEV,MAEpC,SAACzR,MAAG,CAACC,UAAWC,IAAAA,mB,UACd,SAACF,MAAG,CAACC,UAAWC,IAAAA,gBAAwBkS,UAAU,K,SAC/C9J,EAAOjB,MAAMvD,KAAI,SAACuO,EAAMjP,GACvB,OACE,SAACkP,EAAAA,EAAS,CACRC,gBAAiBF,EAAKG,UAEtBH,KAAMA,EACNI,qBAAqB,EACrBC,4BAA4B,GAHvB,GAAsBtP,OAAnBkF,EAAOT,SAAS,KAAa,OAAVzE,EAAQ,WASzB,QAAnBkF,EAAAA,EAAOhB,oBAAY,IAAnBgB,OAAAA,EAAAA,EAAqBxE,KAAI,SAAC6O,G,OACzB,UAAC3S,MAAG,CAA8BC,UAAWC,IAAAA,qB,WAC3C,SAACF,MAAG,CAAC4S,wBAAyB,CAAEC,OAAQF,EAAYG,SAEpD,UAACzS,IAAC,CAACJ,UAAWC,IAAAA,gB,UAAwB,MAAIyS,EAAYI,kBAH9CJ,EAAYK,sB,2JC/DnBC,EAAqB,SAChCC,GAEA,IAAMC,GAAa1I,EAAAA,EAAAA,QAAU,MAS7B,MAAO,CAPe,WAEhB0I,EAAW9R,SACb8R,EAAW9R,QAAQ+R,eAAeF,IAIfC,IAGZvS,EAA0B,CACrCyS,MAAO,SACPC,SAAU,UAGCC,EAAuB,CAClCF,MAAO,QACPC,SAAU,UAGCE,EAA4B,CACvCH,MAAO,WAGT,Q,oHC9BO,IAAMvL,EAAiB,SAAC2L,EAAmBrV,GAGhD,I,IAHgEsV,EAAS,UAAH,6CAAG,MACnEC,EAAaF,EAAUG,MAAM,GAAIxV,GACnCyV,EAAgB,GACXzQ,EAAQ,EAAGA,EAAQuQ,EAAWvV,OAAQgF,GAAS,EAAG,CACzD,IAAM0Q,EAAYH,EAAWvQ,GAC7B,GAAIyQ,EAAczV,SAAWA,EAAS,EAAG,CACvCyV,EAAgB,GAAmBC,OAAhBD,GAA4BH,OAAZI,GAAmB,OAAPJ,GAC/C,MAEFG,EAAgB,GAAmBC,OAAhBD,GAA0B,OAAVC,GAErC,OAAOD,GASIE,EAAgB,SAACN,G,OAA8BA,EAAUO,QAAQ,gBAAiB,KASlFC,EAAsC,SAACC,GAClD,IAAKA,EACH,MAAO,GAET,IAAMC,EAASD,EAAsBN,MAAM,KAE3C,OAAsB,IAAlBO,EAAO/V,OACF+V,EAAO,GAETA,EAAOA,EAAO/V,OAAS,K,kBC9ChCgW,EAAOC,QAAU,CAAC,UAAY,kCAAkC,mBAAqB,2CAA2C,MAAQ,8BAA8B,eAAiB,uCAAuC,mBAAqB,2CAA2C,cAAgB,sCAAsC,YAAc,sC,kBCAlWD,EAAOC,QAAU,CAAC,SAAW,8BAA8B,YAAc,iCAAiC,QAAU,6BAA6B,SAAW,8BAA8B,UAAY,+BAA+B,uBAAyB,8C,kBCA9PD,EAAOC,QAAU,CAAC,cAAgB,qCAAqC,UAAY,iCAAiC,KAAO,8B,kBCA3HD,EAAOC,QAAU,CAAC,UAAY,6BAA6B,SAAW,4BAA4B,cAAgB,iCAAiC,YAAc,+BAA+B,iBAAmB,sC,kBCAnND,EAAOC,QAAU,CAAC,gBAAkB,0CAA0C,qBAAuB,+CAA+C,UAAY,oCAAoC,cAAgB,wCAAwC,gBAAkB,0CAA0C,SAAW,qC,kBCAnUD,EAAOC,QAAU,CAAC,UAAY,2B,kBCA9BD,EAAOC,QAAU,CAAC,eAAiB,sCAAsC,eAAiB,sCAAsC,WAAa,kCAAkC,aAAe,oCAAoC,gBAAkB,uCAAuC,UAAY,iCAAiC,iBAAmB,wCAAwC,aAAe,oCAAoC,eAAiB,wC,kBCAvcD,EAAOC,QAAU,CAAC,UAAY,4CAA4C,kBAAoB,oDAAoD,oBAAsB","sources":["webpack://_N_E/./public/icons/east.svg","webpack://_N_E/./public/icons/info.svg","webpack://_N_E/./public/icons/no-mic.svg","webpack://_N_E/./src/components/CommandBar/CommandsList/CommandControl.tsx","webpack://_N_E/./src/components/CommandBar/CommandsList/CommandPrefix/index.tsx","webpack://_N_E/./src/components/CommandBar/CommandsList/index.tsx","webpack://_N_E/./types/Tarteel/VoiceError.ts","webpack://_N_E/./types/Tarteel/Event.ts","webpack://_N_E/./src/components/TarteelVoiceSearch/BodyContainer/Error/index.tsx","webpack://_N_E/./src/audioInput/voice.ts","webpack://_N_E/./src/components/TarteelVoiceSearch/BodyContainer/PartialResult/index.tsx","webpack://_N_E/./src/components/TarteelVoiceSearch/BodyContainer/SearchResults.tsx","webpack://_N_E/./src/audioInput/audio-worklet.ts","webpack://_N_E/./src/hooks/useTarteelVoiceSearch.ts","webpack://_N_E/./src/components/TarteelVoiceSearch/BodyContainer/index.tsx","webpack://_N_E/./src/components/CommandBar/CommandBarBody/index.tsx","webpack://_N_E/./src/components/Search/NoResults/index.tsx","webpack://_N_E/./src/components/Search/SearchResults/SearchResultItem.tsx","webpack://_N_E/./src/hooks/useScrollToElement.ts","webpack://_N_E/./src/utils/string.ts","webpack://_N_E/./src/components/CommandBar/CommandBarBody/CommandBarBody.module.scss","webpack://_N_E/./src/components/CommandBar/CommandsList/CommandList.module.scss","webpack://_N_E/./src/components/CommandBar/CommandsList/CommandPrefix/CommandPrefix.module.scss","webpack://_N_E/./src/components/Search/NoResults/NoResults.module.scss","webpack://_N_E/./src/components/Search/SearchResults/SearchResultItem.module.scss","webpack://_N_E/./src/components/TarteelVoiceSearch/BodyContainer/Error/Error.module.scss","webpack://_N_E/./src/components/TarteelVoiceSearch/BodyContainer/PartialResult/PartialResult.module.scss","webpack://_N_E/./src/components/TarteelVoiceSearch/BodyContainer/VoiceSearchBodyContainer.module.scss"],"sourcesContent":["var _path;\nfunction _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }\nimport * as React from \"react\";\nvar SvgEast = function SvgEast(props) {\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 24,\n height: 24,\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n xmlns: \"http://www.w3.org/2000/svg\"\n }, props), _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n d: \"m15 5-1.41 1.41L18.17 11H2v2h16.17l-4.59 4.59L15 19l7-7-7-7Z\",\n fill: \"currentColor\"\n })));\n};\nexport default SvgEast;","var _path;\nfunction _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }\nimport * as React from \"react\";\nvar SvgInfo = function SvgInfo(props) {\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 24,\n height: 24,\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n xmlns: \"http://www.w3.org/2000/svg\"\n }, props), _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M11.625 0C5.208 0 0 5.208 0 11.625S5.208 23.25 11.625 23.25 23.25 18.042 23.25 11.625 18.042 0 11.625 0Zm1.162 17.438h-2.325v-6.975h2.325v6.975Zm0-9.3h-2.325V5.812h2.325v2.324Z\",\n fill: \"currentColor\"\n })));\n};\nexport default SvgInfo;","var _path, _path2;\nfunction _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }\nimport * as React from \"react\";\nvar SvgNoMic = function SvgNoMic(props) {\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 80,\n height: 61,\n viewBox: \"0 0 80 61\",\n fill: \"none\",\n xmlns: \"http://www.w3.org/2000/svg\"\n }, props), _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M41.784 38.612c5.056 0 9.193-4.146 9.193-9.213V9.212C50.977 4.146 46.84 0 41.784 0S32.59 4.146 32.59 9.212V29.4c0 5.067 4.137 9.213 9.193 9.213Zm16.24-10.116c0 9.212-7.813 15.661-16.24 15.661s-16.241-6.449-16.241-15.661h-5.21c0 10.44 8.275 19.192 18.387 20.575v10.992h6.128V49.07c10.112-1.536 18.387-10.135 18.387-20.575h-5.21Z\"\n })), _path2 || (_path2 = /*#__PURE__*/React.createElement(\"path\", {\n stroke: \"var(--color-background-inverse)\",\n strokeWidth: 5,\n d: \"m1.583 56.941 76.999-53\"\n })));\n};\nexport default SvgNoMic;","import React, { MouseEvent } from 'react';\n\nimport Button, { ButtonSize, ButtonVariant } from '@/dls/Button/Button';\nimport CloseIcon from '@/icons/close.svg';\n// import KeyboardInput from '@/dls/KeyboardInput';\n\ninterface Props {\n isClearable: boolean;\n isSelected: boolean;\n commandKey: number | string;\n onRemoveCommandClicked: (event: MouseEvent<Element>, key: number | string) => void;\n}\n\nconst CommandControl: React.FC<Props> = ({\n isClearable,\n onRemoveCommandClicked,\n commandKey,\n isSelected,\n}) => {\n if (isClearable) {\n return (\n <Button\n variant={ButtonVariant.Ghost}\n size={ButtonSize.Small}\n onClick={(e) => onRemoveCommandClicked(e, commandKey)}\n >\n <CloseIcon />\n </Button>\n );\n }\n if (isSelected) {\n // return <KeyboardInput keyboardKey=\"Enter\" />;\n return null;\n }\n return null;\n};\n\nexport default CommandControl;\n","import React from 'react';\n\nimport useTranslation from 'next-translate/useTranslation';\n\nimport styles from './CommandPrefix.module.scss';\n\nimport NavigateIcon from '@/icons/east.svg';\nimport { SearchNavigationType } from 'types/SearchNavigationResult';\n\ninterface Props {\n name: string;\n type: SearchNavigationType;\n}\n\nconst CommandPrefix: React.FC<Props> = ({ name, type }) => {\n const { t } = useTranslation('common');\n return (\n <div className={styles.container}>\n <span className={styles.commandPrefix}>\n <NavigateIcon />\n </span>\n <p className={styles.name}>\n {type === SearchNavigationType.SEARCH_PAGE\n ? t('search-for', {\n searchQuery: name,\n })\n : name}\n </p>\n </div>\n );\n};\n\nexport default CommandPrefix;\n","/* eslint-disable jsx-a11y/control-has-associated-label */\n/* eslint-disable max-lines */\n/* eslint-disable jsx-a11y/click-events-have-key-events */\n/* eslint-disable jsx-a11y/mouse-events-have-key-events */\nimport React, { MouseEvent, useState, useCallback, RefObject, useEffect } from 'react';\n\nimport classNames from 'classnames';\nimport { useRouter } from 'next/router';\nimport useTranslation from 'next-translate/useTranslation';\nimport { useHotkeys } from 'react-hotkeys-hook';\nimport { useDispatch } from 'react-redux';\n\nimport CommandControl from './CommandControl';\nimport styles from './CommandList.module.scss';\nimport CommandPrefix from './CommandPrefix';\n\nimport useScroll, { SMOOTH_SCROLL_TO_CENTER } from '@/hooks/useScrollToElement';\nimport {\n addRecentNavigation,\n removeRecentNavigation,\n setIsOpen,\n} from '@/redux/slices/CommandBar/state';\nimport { logButtonClick } from '@/utils/eventLogger';\nimport { resolveUrlBySearchNavigationType } from '@/utils/navigation';\nimport { SearchNavigationResult } from 'types/SearchNavigationResult';\n\nexport interface Command extends SearchNavigationResult {\n group: string;\n index?: number;\n isClearable?: boolean;\n}\n\ninterface Props {\n commandGroups: { groups: Record<string, Command[]>; numberOfCommands: number };\n}\n\nconst CommandsList: React.FC<Props> = ({ commandGroups: { groups, numberOfCommands } }) => {\n const { t } = useTranslation('common');\n const [scrollToSelectedCommand, selectedItemRef]: [() => void, RefObject<HTMLLIElement>] =\n useScroll(SMOOTH_SCROLL_TO_CENTER);\n const [selectedCommandIndex, setSelectedCommandIndex] = useState(numberOfCommands ? 0 : null);\n\n const [highlightOffset, setHighlightOffset] = useState<number>(null);\n useEffect(() => {\n if (selectedItemRef.current) {\n setHighlightOffset(selectedItemRef.current.offsetTop);\n }\n }, [selectedCommandIndex, selectedItemRef]);\n\n // when the value of numberOfCommands changes, it would be due to change of the query string so we need to reset the selected command\n useEffect(() => {\n setSelectedCommandIndex(numberOfCommands ? 0 : null);\n }, [numberOfCommands]);\n\n const router = useRouter();\n const dispatch = useDispatch();\n const onUpKeyClicked = useCallback(\n (event: KeyboardEvent) => {\n // prevent the input's cursor to jump to the end of the input value.\n event.preventDefault();\n setSelectedCommandIndex((prevSelectedCommandIndex) => prevSelectedCommandIndex - 1);\n scrollToSelectedCommand();\n },\n [scrollToSelectedCommand],\n );\n const onDownKeyClicked = useCallback(\n (event: KeyboardEvent) => {\n // prevent the input's cursor to jump to the beginning of the input value.\n event.preventDefault();\n setSelectedCommandIndex((prevSelectedCommandIndex) => prevSelectedCommandIndex + 1);\n scrollToSelectedCommand();\n },\n [scrollToSelectedCommand],\n );\n const navigateToLink = useCallback(\n (command: Command) => {\n const { name, resultType, key } = command;\n router.push(resolveUrlBySearchNavigationType(resultType, key)).then(() => {\n dispatch({ type: addRecentNavigation.type, payload: { name, resultType, key } });\n dispatch({ type: setIsOpen.type, payload: false });\n });\n },\n [dispatch, router],\n );\n useHotkeys(\n 'up',\n onUpKeyClicked,\n {\n enabled: numberOfCommands && selectedCommandIndex !== 0,\n enableOnTags: ['INPUT'],\n },\n [scrollToSelectedCommand],\n );\n useHotkeys(\n 'down',\n onDownKeyClicked,\n {\n enabled: numberOfCommands && selectedCommandIndex !== numberOfCommands - 1,\n enableOnTags: ['INPUT'],\n },\n [scrollToSelectedCommand],\n );\n useHotkeys(\n 'enter',\n () => {\n let navigateTo = null;\n Object.keys(groups).forEach((commandGroup) => {\n const selectedCommand = groups[commandGroup].find(\n (command) => command.index === selectedCommandIndex,\n );\n if (selectedCommand) {\n navigateTo = selectedCommand;\n }\n });\n navigateToLink(navigateTo);\n },\n { enabled: selectedCommandIndex !== null, enableOnTags: ['INPUT'] },\n [selectedCommandIndex, groups, navigateToLink],\n );\n const onRemoveCommandClicked = (\n event: MouseEvent<Element>,\n navigationItemKey: number | string,\n ) => {\n logButtonClick('remove_command_bar_navigation');\n // to not allow the event to bubble up to the parent container\n event.stopPropagation();\n dispatch({ type: removeRecentNavigation.type, payload: navigationItemKey });\n };\n\n if (numberOfCommands === 0) {\n return <p className={styles.noResult}>{t('command-bar.no-nav-results')}</p>;\n }\n return (\n <ul role=\"listbox\">\n <div\n className={styles.highlight}\n style={{\n transform: highlightOffset ? `translateY(${highlightOffset}px)` : `translateY(100%)`,\n }}\n />\n <li role=\"presentation\">\n {Object.keys(groups).map((commandGroup) => {\n return (\n <div key={commandGroup}>\n <div className={styles.groupHeader} id={commandGroup}>\n {commandGroup}\n </div>\n <ul role=\"group\" aria-labelledby={commandGroup}>\n {groups[commandGroup].map((command) => {\n const { name, resultType } = command;\n const isSelected = selectedCommandIndex === command.index;\n return (\n <li\n ref={isSelected ? selectedItemRef : null}\n role=\"option\"\n aria-selected={isSelected}\n key={command.index}\n className={classNames(styles.command, { [styles.selected]: isSelected })}\n onClick={() => navigateToLink(command)}\n onMouseOver={() => setSelectedCommandIndex(command.index)}\n >\n <CommandPrefix name={name} type={resultType} />\n <div className={styles.keyboardInputContainer}>\n <CommandControl\n isClearable={command.isClearable}\n isSelected={isSelected}\n commandKey={command.key}\n onRemoveCommandClicked={onRemoveCommandClicked}\n />\n </div>\n </li>\n );\n })}\n </ul>\n </div>\n );\n })}\n </li>\n </ul>\n );\n};\n\nexport default CommandsList;\n","enum VoiceError {\n NO_PERMISSION = 'NO_PERMISSION',\n NOT_SUPPORTED = 'NOT_SUPPORTED',\n SOCKET_ERROR = 'SOCKET_ERROR',\n RESPONSE_ERROR = 'RESPONSE_ERROR',\n WORKLET_ERROR = 'WORKLET_ERROR',\n GENERAL_ERROR = 'GENERAL_ERROR',\n}\n\nexport default VoiceError;\n","enum Event {\n START_STREAM = 'START_STREAM',\n END_STREAM = 'END_STREAM',\n SEARCH_LOADING = 'SEARCH_LOADING',\n SEARCH_RESULT = 'SEARCH_RESULT',\n PARTIAL_TRANSCRIPT = 'PARTIAL_TRANSCRIPT',\n ERROR = 'ERROR',\n}\n\nexport default Event;\n","import React from 'react';\n\nimport useTranslation from 'next-translate/useTranslation';\n\nimport styles from './Error.module.scss';\n\nimport Link, { LinkVariant } from '@/dls/Link/Link';\nimport ErrorIcon from '@/icons/info.svg';\nimport MicrophoneIcon from '@/icons/microphone.svg';\nimport NoMicrophoneIcon from '@/icons/no-mic.svg';\nimport { logTarteelLinkClick } from '@/utils/eventLogger';\nimport VoiceError from 'types/Tarteel/VoiceError';\n\ninterface Props {\n error: VoiceError;\n isWaitingForPermission: boolean;\n isCommandBar: boolean;\n}\n\nconst Error: React.FC<Props> = ({ error, isWaitingForPermission, isCommandBar }) => {\n const { t } = useTranslation('common');\n\n const onTarteelLinkClicked = () => {\n // eslint-disable-next-line i18next/no-literal-string\n logTarteelLinkClick(`${isCommandBar ? 'command_bar' : 'search_drawer'}_error`);\n };\n let icon = null;\n let errorBody = null;\n if (isWaitingForPermission) {\n errorBody = <p>{t('voice.ask-permission')}</p>;\n icon = <MicrophoneIcon />;\n } else {\n let errorText = '';\n switch (error) {\n case VoiceError.NO_PERMISSION:\n errorText = t('voice.no-permission');\n icon = <NoMicrophoneIcon />;\n break;\n case VoiceError.NOT_SUPPORTED:\n errorText = t('voice.not-supported');\n icon = <NoMicrophoneIcon />;\n break;\n default:\n errorText = t('voice.error');\n icon = <ErrorIcon />;\n break;\n }\n errorBody = (\n <div>\n <span>{errorText}</span>\n <Link\n href=\"https://download.tarteel.ai\"\n isNewTab\n variant={LinkVariant.Highlight}\n onClick={onTarteelLinkClicked}\n >\n {t('tarteel.app')}\n </Link>\n </div>\n );\n }\n\n return (\n <div className={styles.container}>\n {icon}\n {errorBody}\n </div>\n );\n};\n\nexport default Error;\n","/* eslint-disable import/prefer-default-export */\nexport const getAverageVolume = (analyser: AnalyserNode, volumes: Uint8Array) => {\n analyser.getByteFrequencyData(volumes);\n let values = 0;\n\n const { length } = volumes;\n for (let i = 0; i < length; i += 1) {\n values += volumes[i];\n }\n const volume = Math.round(values / length);\n return volume > 100 ? 100 : volume;\n};\n\n/**\n * Get the value that will be used inside css as a multiplier of the base width\n * and height of the audio visualizer circle.\n *\n * @param {number} volume\n * @returns {number}\n */\nexport const getVolumeLevelMultiplier = (volume: number): number => {\n return Math.max((volume * 1.5) / 100) + 1;\n};\n","import classNames from 'classnames';\nimport useTranslation from 'next-translate/useTranslation';\n\nimport styles from './PartialResult.module.scss';\n\nimport MicrophoneIcon from '@/icons/microphone.svg';\nimport { getVolumeLevelMultiplier } from 'src/audioInput/voice';\n\ninterface Props {\n partialTranscript: string;\n volume: number;\n stopRecording: () => void;\n verticalLayout?: boolean;\n}\n\nconst PartialResult: React.FC<Props> = ({\n partialTranscript,\n volume,\n verticalLayout,\n stopRecording,\n}) => {\n const { t } = useTranslation('common');\n\n return (\n <div className={classNames(styles.outerContainer, verticalLayout && styles.verticalLyaout)}>\n <div className={styles.innerContainer}>\n <div>\n <h3 className={styles.suggestTitle}>{t('voice.suggest-title')}</h3>\n <p className={styles.suggestSubtitle}>{t('voice.suggest-subtitle')}</p>\n </div>\n {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */}\n <div className={styles.circlesContainer} onClick={stopRecording}>\n <div\n className={styles.volumeCircle}\n // @ts-ignore\n // eslint-disable-next-line @typescript-eslint/naming-convention\n style={{ '--volume': getVolumeLevelMultiplier(volume) }}\n />\n <div className={styles.micCircle}>\n <MicrophoneIcon />\n </div>\n </div>\n </div>\n <p className={styles.transcript}>{partialTranscript}</p>\n </div>\n );\n};\n\nexport default PartialResult;\n","import React, { useCallback } from 'react';\n\nimport groupBy from 'lodash/groupBy';\nimport useTranslation from 'next-translate/useTranslation';\nimport { useSelector } from 'react-redux';\n\nimport CommandsList from '@/components/CommandBar/CommandsList';\nimport DataFetcher from '@/components/DataFetcher';\nimport SearchResultItem from '@/components/Search/SearchResults/SearchResultItem';\nimport { selectSelectedTranslations } from '@/redux/slices/QuranReader/translations';\nimport SearchService from '@/types/Search/SearchService';\nimport SearchQuerySource from '@/types/SearchQuerySource';\nimport { makeVersesFilterUrl } from '@/utils/apiPaths';\nimport { areArraysEqual } from '@/utils/array';\nimport { toLocalizedVerseKey } from '@/utils/locale';\nimport { truncateString } from '@/utils/string';\nimport { VersesResponse } from 'types/ApiResponses';\nimport { SearchNavigationType } from 'types/SearchNavigationResult';\nimport SearchResult from 'types/Tarteel/SearchResult';\n\ninterface Props {\n searchResult: SearchResult;\n isCommandBar: boolean;\n}\n\nconst SearchResults: React.FC<Props> = ({ searchResult, isCommandBar }) => {\n const selectedTranslations = useSelector(selectSelectedTranslations, areArraysEqual);\n const { t, lang } = useTranslation('common');\n\n const params = {\n // only get the first 10 results\n filters: searchResult.matches\n .slice(0, 10)\n .map((match) => `${match.surahNum}:${match.ayahNum}`)\n .join(','),\n fields: 'text_uthmani',\n // when it's the search drawer\n ...(!isCommandBar && {\n words: true,\n // when there is a translation in Redux\n ...(!!selectedTranslations.length && {\n translations: selectedTranslations.join(','),\n translationFields: 'text,resource_id,resource_name',\n }),\n }),\n };\n\n const responseRender = useCallback(\n (data: VersesResponse) => {\n if (isCommandBar) {\n const toBeGroupedCommands = data.verses.map((verse) => {\n return {\n key: verse.verseKey,\n resultType: SearchNavigationType.AYAH,\n name: `[${toLocalizedVerseKey(verse.verseKey, lang)}] ${truncateString(\n verse.textUthmani,\n 80,\n )}`,\n group: t('command-bar.navigations'),\n };\n });\n\n return (\n <CommandsList\n commandGroups={{\n groups: groupBy(\n toBeGroupedCommands.map((item, index) => ({ ...item, index })), // append the index so that it can be used for keyboard navigation.\n (item) => item.group, // we group by the group name that has been attached to each command.\n ),\n numberOfCommands: data.verses.length, // this is needed so that we can know when we have reached the last command when using keyboard navigation across multiple groups\n }}\n />\n );\n }\n return (\n <>\n {data.verses.map((verse) => (\n <SearchResultItem\n key={verse.verseKey}\n result={verse}\n source={SearchQuerySource.Tarteel}\n service={SearchService.Tarteel}\n />\n ))}\n </>\n );\n },\n [isCommandBar, lang, t],\n );\n\n return <DataFetcher queryKey={makeVersesFilterUrl(params)} render={responseRender} />;\n};\n\nexport default SearchResults;\n","// eslint-disable-next-line import/prefer-default-export\nexport const AudioWorklet = (url: URL) => {\n return url as unknown as string;\n};\n","/* eslint-disable max-lines */\n/* eslint-disable import/no-unresolved */\n/* eslint-disable react-func/max-lines-per-function */\nimport { useState, useCallback, useRef } from 'react';\n\n// @ts-ignore\nimport { AudioWorklet } from 'audio-worklet';\n\nimport useBrowserLayoutEffect from '@/hooks/useBrowserLayoutEffect';\nimport SearchService from '@/types/Search/SearchService';\nimport SearchQuerySource from '@/types/SearchQuerySource';\nimport SearchType from '@/types/SearchType';\nimport { logEmptySearchResults, logEvent } from '@/utils/eventLogger';\nimport { getAverageVolume } from 'src/audioInput/voice';\nimport Event from 'types/Tarteel/Event';\nimport Result from 'types/Tarteel/Result';\nimport SearchResult from 'types/Tarteel/SearchResult';\nimport VoiceError from 'types/Tarteel/VoiceError';\n\nconst AUDIO_CONFIG = {\n sampleRate: 16000,\n fileFormat: 'WAV',\n channels: 1,\n};\n\nconst END_STREAM_DATA = {\n event: Event.END_STREAM,\n};\nconst START_STREAM_DATA = {\n event: Event.START_STREAM,\n data: {\n audioConfig: AUDIO_CONFIG,\n },\n};\n\nconst AUDIO_CONSTRAINTS = {\n sampleRate: AUDIO_CONFIG.sampleRate,\n channelCount: AUDIO_CONFIG.channels,\n sampleSize: 4096,\n} as MediaTrackConstraints;\n\nconst USER_MEDIA_NOT_SUPPORTED_ERROR = 'USER_MEDIA_NOT_SUPPORTED';\nconst ANALYSER_SMOOTHING_CONSTANT = 0.8;\nconst FAST_FOURIER_TRANSFORM_SIZE = 1024;\n\nconst isWebSocketOpen = (webSocket: WebSocket) => {\n return webSocket && webSocket.readyState === webSocket.OPEN;\n};\n\nconst useTarteelVoiceSearch = () => {\n const [volume, setVolume] = useState<number>(0);\n const mediaStream = useRef<MediaStream>(null);\n const [isLoading, setIsLoading] = useState<boolean>(false);\n const [error, setError] = useState<VoiceError>(null);\n const [partialTranscript, setPartialTranscript] = useState<string>(null);\n const [searchResult, setSearchResult] = useState<SearchResult>(null);\n const [isWaitingForPermission, setIsWaitingForPermission] = useState(false);\n\n const websocket = useRef<WebSocket>(null);\n const analyser = useRef<AnalyserNode>(null);\n const micWorkletNode = useRef<AudioWorkletNode>(null);\n const audioContext = useRef<AudioContext>(null);\n const micSourceNode = useRef<MediaStreamAudioSourceNode>(null);\n\n useBrowserLayoutEffect(() => {\n window.AudioContext = window.AudioContext || window.webkitAudioContext;\n // Older browsers might not implement mediaDevices at all, so we set an empty object first\n if (navigator.mediaDevices === undefined) {\n // @ts-ignore\n navigator.mediaDevices = {};\n }\n // Some browsers partially implement mediaDevices. We can't just assign an object\n // with getUserMedia as it would overwrite existing properties.\n // Here, we will just add the getUserMedia property if it's missing.\n if (navigator.mediaDevices.getUserMedia === undefined) {\n navigator.mediaDevices.getUserMedia = (constraints: MediaStreamConstraints) => {\n // First get ahold of the legacy getUserMedia, if present\n const getUserMedia =\n // @ts-ignore\n navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.getUserMedia;\n\n // Some browsers just don't implement it - return a rejected promise with an error\n // to keep a consistent interface\n if (!getUserMedia) {\n return Promise.reject(new Error(USER_MEDIA_NOT_SUPPORTED_ERROR));\n }\n\n // Otherwise, wrap the call to the old navigator.getUserMedia with a Promise\n return new Promise((resolve, reject) => {\n getUserMedia.call(navigator, constraints, resolve, reject);\n });\n };\n }\n }, []);\n\n const releaseMicrophone = useCallback(() => {\n if (mediaStream.current) {\n mediaStream.current.getAudioTracks().forEach((track) => {\n track.stop();\n });\n }\n setVolume(0);\n }, []);\n\n // the `closeWebsocket` param is used to close the websocket when the user clicks exits the flow.\n // otherwise, the user just clicked on the mic button to stop the recording\n // and the websocket should remain open to receive the final results.\n const stopRecording = useCallback(\n async (closeWebsocket = true) => {\n if (!closeWebsocket && !partialTranscript) {\n // if the user didn't say anything and clicked on the mic button, don't stop the flow\n return;\n }\n\n // if the websocket is still open, close it\n if (isWebSocketOpen(websocket.current)) {\n websocket.current.send(JSON.stringify(END_STREAM_DATA));\n if (closeWebsocket) {\n websocket.current.close();\n }\n }\n\n releaseMicrophone();\n if (analyser) {\n analyser.current.disconnect();\n }\n if (micWorkletNode) {\n micWorkletNode.current.disconnect();\n }\n if (micSourceNode) {\n micSourceNode.current.disconnect();\n }\n if (audioContext.current.state === 'running') {\n await audioContext.current.close();\n }\n },\n [releaseMicrophone, partialTranscript],\n );\n\n const onWebsocketMessage = useCallback(\n (message: MessageEvent) => {\n const result = JSON.parse(message.data) as Result;\n const { event, data } = result;\n switch (event) {\n case Event.SEARCH_LOADING:\n setIsLoading(true);\n break;\n case Event.SEARCH_RESULT:\n setIsLoading(false);\n setSearchResult(data as SearchResult);\n if (!(data as SearchResult).matches?.length) {\n logEmptySearchResults({\n query: data.queryText,\n source: SearchQuerySource.Tarteel,\n type: SearchType.Voice,\n service: SearchService.Tarteel,\n });\n }\n stopRecording();\n break;\n case Event.PARTIAL_TRANSCRIPT:\n setIsLoading(false);\n setPartialTranscript(data.queryText);\n break;\n case Event.ERROR:\n setIsLoading(false);\n logEvent('tarteel_error', { error: event });\n setError(VoiceError.RESPONSE_ERROR);\n break;\n default:\n break;\n }\n },\n [stopRecording],\n );\n\n const addMicInputProcessorToAudioContext = useCallback(async () => {\n try {\n await audioContext.current.audioWorklet.addModule(\n new AudioWorklet(new URL('src/audioInput/MicInputProcessor.ts', import.meta.url)),\n );\n logEvent('tarteel_websocket_initialize');\n setIsLoading(true);\n\n // 3. Start a new websocket\n websocket.current = new WebSocket(\n `wss://voice-v2.tarteel.io/search/?Authorization=${process.env.NEXT_PUBLIC_TARTEEL_VS_API_KEY}`,\n );\n\n websocket.current.onopen = () => {\n logEvent('tarteel_websocket_open');\n setIsLoading(false);\n analyser.current = audioContext.current.createAnalyser();\n analyser.current.smoothingTimeConstant = ANALYSER_SMOOTHING_CONSTANT;\n analyser.current.fftSize = FAST_FOURIER_TRANSFORM_SIZE;\n const volumes = new Uint8Array(analyser.current.frequencyBinCount);\n micWorkletNode.current = new AudioWorkletNode(audioContext.current, 'MicInputProcessor');\n websocket.current.send(JSON.stringify(START_STREAM_DATA));\n micSourceNode.current.connect(analyser.current);\n analyser.current.connect(micWorkletNode.current);\n micWorkletNode.current.connect(audioContext.current.destination);\n // Handling the data being posted from the MicInputProcessor.\n micWorkletNode.current.port.onmessage = (event) => {\n setVolume(getAverageVolume(analyser.current, volumes));\n // sometimes the processor hasn't sent the last bit of data yet but the websocket had already been closed.\n if (isWebSocketOpen(websocket.current)) {\n websocket.current.send(event.data);\n }\n };\n };\n\n websocket.current.onmessage = (message: MessageEvent) => {\n onWebsocketMessage(message);\n };\n\n websocket.current.onerror = () => {\n logEvent('tarteel_websocket_error');\n setIsLoading(false);\n setError(VoiceError.SOCKET_ERROR);\n releaseMicrophone();\n };\n } catch (err) {\n logEvent('voice_search_worklet_error');\n setError(VoiceError.WORKLET_ERROR);\n }\n }, [onWebsocketMessage, releaseMicrophone]);\n\n const startRecording = useCallback(async () => {\n // re-set fields in-case this is not the first time we are running the voice search\n setError(null);\n setPartialTranscript(null);\n setSearchResult(null);\n setIsWaitingForPermission(true);\n\n audioContext.current = new window.AudioContext({ sampleRate: AUDIO_CONFIG.sampleRate });\n\n try {\n // 1. Ask for the user permission to access the mic\n const stream = await navigator.mediaDevices.getUserMedia({ audio: AUDIO_CONSTRAINTS });\n mediaStream.current = stream;\n try {\n micSourceNode.current = audioContext.current.createMediaStreamSource(stream);\n } catch (err) {\n logEvent('voice_search_create_media_stream_error');\n // this will happen for Firefox users due to FF not accepting to change the sampleRate {@see https://bugzilla.mozilla.org/show_bug.cgi?id=1607781}\n stopRecording();\n throw new Error(USER_MEDIA_NOT_SUPPORTED_ERROR);\n }\n\n // 2. Add the MicInputProcessor to the audioContext\n await addMicInputProcessorToAudioContext();\n } catch (getUserMedia) {\n // if it's a custom thrown error when getUserMedia is not implemented in the browser\n if (getUserMedia.message === USER_MEDIA_NOT_SUPPORTED_ERROR) {\n logEvent('voice_search_not_supported');\n setError(VoiceError.NOT_SUPPORTED);\n } else {\n const isPermissionDenied = getUserMedia.name === 'NotAllowedError';\n if (isPermissionDenied) {\n logEvent('voice_search_permission_denied');\n }\n setError(isPermissionDenied ? VoiceError.NO_PERMISSION : VoiceError.GENERAL_ERROR);\n }\n } finally {\n setIsWaitingForPermission(false);\n }\n }, [stopRecording, addMicInputProcessorToAudioContext]);\n\n return {\n isLoading,\n error,\n partialTranscript,\n searchResult,\n volume,\n isWaitingForPermission,\n startRecording,\n stopRecording,\n };\n};\n\nexport default useTarteelVoiceSearch;\n","import { useEffect } from 'react';\n\nimport classNames from 'classnames';\n\nimport Error from './Error';\nimport PartialResult from './PartialResult';\nimport SearchResults from './SearchResults';\nimport styles from './VoiceSearchBodyContainer.module.scss';\n\nimport NoResults from '@/components/Search/NoResults';\nimport Spinner, { SpinnerSize } from '@/dls/Spinner/Spinner';\nimport useTarteelVoiceSearch from '@/hooks/useTarteelVoiceSearch';\n\ninterface Props {\n isCommandBar?: boolean;\n}\n\nconst VoiceSearchBodyContainer: React.FC<Props> = ({ isCommandBar = false }) => {\n const {\n isLoading,\n partialTranscript,\n searchResult,\n error,\n volume,\n isWaitingForPermission,\n startRecording,\n stopRecording,\n } = useTarteelVoiceSearch();\n\n useEffect(() => {\n startRecording();\n\n return () => {\n stopRecording();\n };\n\n // we only want to start the recording once when the component mounts\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const stopVoiceSearch = () => {\n // pass `false` so that we don't stop the recording and get the search results\n stopRecording(false);\n };\n\n if (isLoading) {\n return <Spinner size={SpinnerSize.Large} />;\n }\n // if there is an error or we are waiting for the permission from the user\n if (error || isWaitingForPermission) {\n return (\n <div\n className={classNames({\n [styles.container]: !isCommandBar,\n })}\n >\n <Error\n isCommandBar={isCommandBar}\n error={error}\n isWaitingForPermission={isWaitingForPermission}\n />\n </div>\n );\n }\n\n // if we received the result but no matches\n if (searchResult && !searchResult.matches?.length) {\n return (\n <div\n className={classNames({\n [styles.container]: !isCommandBar,\n [styles.noResultContainer]: isCommandBar,\n })}\n >\n <NoResults searchQuery={partialTranscript} />\n </div>\n );\n }\n\n return (\n <>\n {searchResult ? (\n <SearchResults searchResult={searchResult} isCommandBar={isCommandBar} />\n ) : (\n <div\n className={classNames({\n [styles.container]: !isCommandBar,\n [styles.commandBarContainer]: isCommandBar,\n })}\n >\n <PartialResult\n verticalLayout={!isCommandBar}\n partialTranscript={partialTranscript}\n volume={volume}\n stopRecording={stopVoiceSearch}\n />\n </div>\n )}\n </>\n );\n};\n\nexport default VoiceSearchBodyContainer;\n","/* eslint-disable max-lines */\nimport React, { useState, useCallback, useEffect } from 'react';\n\nimport classNames from 'classnames';\nimport groupBy from 'lodash/groupBy';\nimport useTranslation from 'next-translate/useTranslation';\nimport { shallowEqual, useSelector } from 'react-redux';\n\nimport CommandsList, { Command } from '../CommandsList';\n\nimport styles from './CommandBarBody.module.scss';\n\nimport DataFetcher from '@/components/DataFetcher';\n// import TarteelAttribution from '@/components/TarteelAttribution/TarteelAttribution';\nimport VoiceSearchBodyContainer from '@/components/TarteelVoiceSearch/BodyContainer';\n// import TarteelVoiceSearchTrigger from '@/components/TarteelVoiceSearch/Trigger';\nimport useDebounce from '@/hooks/useDebounce';\nimport IconSearch from '@/icons/search.svg';\nimport { selectRecentNavigations } from '@/redux/slices/CommandBar/state';\nimport { selectIsCommandBarVoiceFlowStarted } from '@/redux/slices/voiceSearch';\nimport SearchQuerySource from '@/types/SearchQuerySource';\nimport { makeSearchResultsUrl } from '@/utils/apiPaths';\nimport { areArraysEqual } from '@/utils/array';\nimport { logTextSearchQuery } from '@/utils/eventLogger'; // logButtonClick,\nimport { SearchResponse } from 'types/ApiResponses';\nimport { SearchNavigationType } from 'types/SearchNavigationResult';\n\nconst NAVIGATE_TO = [\n {\n name: 'Juz 1',\n key: 1,\n resultType: SearchNavigationType.JUZ,\n },\n {\n name: 'Hizb 1',\n key: 1,\n resultType: SearchNavigationType.HIZB,\n },\n {\n name: 'Rub el Hizb 1',\n key: 1,\n resultType: SearchNavigationType.RUB_EL_HIZB,\n },\n {\n name: 'Page 1',\n key: 1,\n resultType: SearchNavigationType.PAGE,\n },\n {\n name: 'Surah Yasin',\n key: 36,\n resultType: SearchNavigationType.SURAH,\n },\n {\n name: '2:255',\n key: '2:255',\n resultType: SearchNavigationType.AYAH,\n },\n];\n\nconst DEBOUNCING_PERIOD_MS = 1500;\n\nconst CommandBarBody: React.FC = () => {\n const { t } = useTranslation('common');\n const recentNavigations = useSelector(selectRecentNavigations, areArraysEqual);\n const isVoiceSearchFlowStarted = useSelector(selectIsCommandBarVoiceFlowStarted, shallowEqual);\n const [searchQuery, setSearchQuery] = useState<string>(null);\n // Debounce search query to avoid having to call the API on every type. The API will be called once the user stops typing.\n const debouncedSearchQuery = useDebounce<string>(searchQuery, DEBOUNCING_PERIOD_MS);\n\n useEffect(() => {\n // only when the search query has a value we call the API.\n if (debouncedSearchQuery) {\n logTextSearchQuery(debouncedSearchQuery, SearchQuerySource.CommandBar);\n }\n }, [debouncedSearchQuery]);\n\n /**\n * Handle when the search query is changed.\n *\n * @param {React.FormEvent<HTMLInputElement>} event\n * @returns {void}\n */\n const onSearchQueryChange = useCallback((event: React.FormEvent<HTMLInputElement>): void => {\n setSearchQuery(event.currentTarget.value || null);\n }, []);\n\n /**\n * Generate an array of commands that will show in the pre-input view.\n * The function takes the original recentNavigations + NAVIGATE_TO and appends\n * to each the group name + which command is clearable and which is not. The group\n * will be used by {@see groupBy} to compose the list of commands for each group.\n *\n * @param {SearchNavigationResult[]} recentNavigations the history of the command bar navigations.\n * @returns {Command[]}\n */\n const getPreInputCommands = useCallback(\n (): Command[] =>\n recentNavigations\n .map((recentNavigation) => ({\n ...recentNavigation,\n group: t('command-bar.recent-navigations'),\n isClearable: true,\n }))\n .concat(\n NAVIGATE_TO.map((navigateToItem) => ({\n ...navigateToItem,\n group: t('command-bar.try-navigating'),\n isClearable: false,\n })),\n ),\n [recentNavigations, t],\n );\n\n /**\n * This function will be used by DataFetcher and will run only when there is no API error\n * or the connections is offline. When we receive the response from DataFetcher,\n * the data can be:\n *\n * 1. empty: which means we are in the initial state where there is no searchQuery and\n * in this case we want to show the recent navigations from Redux (if any) + suggestions\n * on where to navigate to.\n * 2. not empty: and this means we called the API and we got the response. The response will\n * either have results or not (in the case when there are no matches for\n * the search query).\n */\n const dataFetcherRender = useCallback(\n (data: SearchResponse) => {\n let toBeGroupedCommands = [] as Command[];\n let numberOfCommands = 0;\n // if it's pre-input\n if (!data) {\n toBeGroupedCommands = getPreInputCommands();\n numberOfCommands = recentNavigations.length + NAVIGATE_TO.length;\n } else {\n toBeGroupedCommands = [\n ...data.result.navigation.map((navigationItem) => ({\n ...navigationItem,\n group: t('command-bar.navigations'),\n })),\n {\n key: searchQuery,\n resultType: SearchNavigationType.SEARCH_PAGE,\n name: searchQuery,\n group: t('search.title'),\n },\n ];\n numberOfCommands = data.result.navigation.length + 1;\n }\n return (\n <CommandsList\n commandGroups={{\n groups: groupBy(\n toBeGroupedCommands.map((item, index) => ({ ...item, index })), // append the index so that it can be used for keyboard navigation.\n (item) => item.group, // we group by the group name that has been attached to each command.\n ),\n numberOfCommands, // this is needed so that we can know when we have reached the last command when using keyboard navigation across multiple groups\n }}\n />\n );\n },\n [getPreInputCommands, recentNavigations.length, searchQuery, t],\n );\n\n return (\n <div className={styles.container}>\n <div\n className={classNames(styles.inputContainer, {\n [styles.voiceFlowContainer]: isVoiceSearchFlowStarted,\n })}\n >\n {!isVoiceSearchFlowStarted && (\n <div className={styles.textInputContainer}>\n <IconSearch />\n <input\n onChange={onSearchQueryChange}\n placeholder={t('command-bar.placeholder')}\n className={styles.input}\n type=\"text\"\n inputMode=\"text\"\n // eslint-disable-next-line jsx-a11y/no-autofocus\n autoFocus\n />\n </div>\n )}\n {/* <TarteelVoiceSearchTrigger\n isCommandBar\n onClick={(startFlow: boolean) => {\n logButtonClick(\n // eslint-disable-next-line i18next/no-literal-string\n `command_bar_voice_search_${startFlow ? 'start' : 'stop'}_flow`,\n );\n }}\n /> */}\n </div>\n <div className={styles.bodyContainer}>\n {isVoiceSearchFlowStarted ? (\n <VoiceSearchBodyContainer isCommandBar />\n ) : (\n <DataFetcher\n queryKey={searchQuery ? makeSearchResultsUrl({ query: searchQuery }) : null}\n render={dataFetcherRender}\n />\n )}\n </div>\n {/* <div className={styles.attribution}>\n <TarteelAttribution isCommandBar />\n </div> */}\n </div>\n );\n};\n\nexport default CommandBarBody;\n","import React from 'react';\n\nimport useTranslation from 'next-translate/useTranslation';\n\nimport styles from './NoResults.module.scss';\n\nimport IconSearch from '@/icons/search.svg';\n\ninterface Props {\n searchQuery: string;\n}\n\nconst NoResults: React.FC<Props> = ({ searchQuery }) => {\n const { t } = useTranslation('common');\n return (\n <>\n <div className={styles.container}>\n <div className={styles.mainBody}>\n <div className={styles.iconContainer}>\n <IconSearch />\n </div>\n <p className={styles.mainMessage}>{t('search.no-results')}</p>\n <p className={styles.secondaryMessage}>\n {t('search.no-results-suggestion', { searchQuery })}\n </p>\n </div>\n </div>\n </>\n );\n};\n\nexport default NoResults;\n","/* eslint-disable react/no-danger */\n\nimport React, { useMemo } from 'react';\n\nimport useTranslation from 'next-translate/useTranslation';\n\nimport styles from './SearchResultItem.module.scss';\n\nimport Link from '@/dls/Link/Link';\nimport QuranWord from '@/dls/QuranWord/QuranWord';\nimport useGetChaptersData from '@/hooks/useGetChaptersData';\nimport SearchService from '@/types/Search/SearchService';\nimport SearchQuerySource from '@/types/SearchQuerySource';\nimport { getChapterData } from '@/utils/chapter';\nimport { logButtonClick } from '@/utils/eventLogger';\nimport { toLocalizedVerseKey } from '@/utils/locale';\nimport { getChapterWithStartingVerseUrl } from '@/utils/navigation';\nimport { getChapterNumberFromKey } from '@/utils/verse';\nimport Verse from 'types/Verse';\n\ninterface Props {\n result: Verse;\n source: SearchQuerySource;\n service?: SearchService;\n}\n\nconst SearchResultItem: React.FC<Props> = ({ result, source, service = SearchService.QDC }) => {\n const { lang } = useTranslation('quran-reader');\n const localizedVerseKey = useMemo(\n () => toLocalizedVerseKey(result.verseKey, lang),\n [lang, result.verseKey],\n );\n\n const chaptersData = useGetChaptersData(lang);\n\n if (!chaptersData) return null;\n\n const chapterNumber = getChapterNumberFromKey(result.verseKey);\n const chapterData = getChapterData(chaptersData, chapterNumber.toString());\n\n const onResultItemClicked = () => {\n logButtonClick(`search_result_item`, {\n service,\n source,\n });\n };\n\n return (\n <div className={styles.container}>\n <div className={styles.itemContainer}>\n <Link\n className={styles.verseKey}\n href={getChapterWithStartingVerseUrl(result.verseKey)}\n onClick={onResultItemClicked}\n >\n {chapterData.transliteratedName} {localizedVerseKey}\n </Link>\n <div className={styles.quranTextContainer}>\n <div className={styles.quranTextResult} translate=\"no\">\n {result.words.map((word, index) => {\n return (\n <QuranWord\n isHighlighted={!!word.highlight}\n key={`${result.verseKey}:${index + 1}`}\n word={word}\n isWordByWordAllowed={false}\n isAudioHighlightingAllowed={false}\n />\n );\n })}\n </div>\n </div>\n {result.translations?.map((translation) => (\n <div key={translation.resourceId} className={styles.translationContainer}>\n <div dangerouslySetInnerHTML={{ __html: translation.text }} />\n {/* eslint-disable-next-line i18next/no-literal-string */}\n <p className={styles.translationName}> - {translation.resourceName}</p>\n </div>\n ))}\n </div>\n </div>\n );\n};\nexport default SearchResultItem;\n","import { useRef, RefObject } from 'react';\n\n/**\n * A hook that scrolls to a specific element in the DOM.\n * The scrolling will only happen when executeScroll function\n * is invoked.\n *\n * @param {ScrollIntoViewOptions} options\n * @returns {[() => void, RefObject<T>]}\n */\nexport const useScrollToElement = <T extends HTMLElement>(\n options?: ScrollIntoViewOptions,\n): [() => void, RefObject<T>] => {\n const elementRef = useRef<T>(null);\n // a function that will be invoked by the component using this hook to scroll to the element being referenced (if found).\n const executeScroll = (): void => {\n // only scroll when the ref has a value\n if (elementRef.current) {\n elementRef.current.scrollIntoView(options);\n }\n };\n\n return [executeScroll, elementRef];\n};\n\nexport const SMOOTH_SCROLL_TO_CENTER = {\n block: 'center', // 'block' relates to vertical alignment. see: https://stackoverflow.com/a/48635751/1931451 for nearest.\n behavior: 'smooth',\n} as ScrollIntoViewOptions;\n\nexport const SMOOTH_SCROLL_TO_TOP = {\n block: 'start',\n behavior: 'smooth',\n} as ScrollIntoViewOptions;\n\nexport const SCROLL_TO_NEAREST_ELEMENT = {\n block: 'nearest',\n} as ScrollIntoViewOptions;\n\nexport default useScrollToElement;\n","/**\n * Shorten a text by setting the maximum number of characters\n * by the value of the parameter and adding \"...\" at the end.\n *\n * @param {string} rawString\n * @param {number} length\n * @param {string} suffix\n * @returns {string}\n */\nexport const truncateString = (rawString: string, length: number, suffix = '...'): string => {\n const characters = rawString.split('', length);\n let shortenedText = '';\n for (let index = 0; index < characters.length; index += 1) {\n const character = characters[index];\n if (shortenedText.length === length - 1) {\n shortenedText = `${shortenedText}${character}${suffix}`;\n break;\n }\n shortenedText = `${shortenedText}${character}`;\n }\n return shortenedText;\n};\n\n/**\n * Strip HTML tags from a string.\n *\n * @param {string} rawString\n * @returns {string}\n */\nexport const stripHTMLTags = (rawString: string): string => rawString.replace(/(<([^>]+)>)/gi, '');\n\n/**\n * Convert a slugified collection id to collection id only after\n * removing the slug.\n *\n * @param {string} slugifiedCollectionId\n * @returns {string}\n */\nexport const slugifiedCollectionIdToCollectionId = (slugifiedCollectionId: string): string => {\n if (!slugifiedCollectionId) {\n return '';\n }\n const splits = slugifiedCollectionId.split('-');\n // if there is no slug in the url (collections with a name that cannot be slugified e.g. emoticons)\n if (splits.length === 1) {\n return splits[0];\n }\n return splits[splits.length - 1];\n};\n","// extracted by mini-css-extract-plugin\nmodule.exports = {\"container\":\"CommandBarBody_container__s5HGd\",\"textInputContainer\":\"CommandBarBody_textInputContainer__nA99M\",\"input\":\"CommandBarBody_input__EiX78\",\"inputContainer\":\"CommandBarBody_inputContainer__mYwbs\",\"voiceFlowContainer\":\"CommandBarBody_voiceFlowContainer__FlqZy\",\"bodyContainer\":\"CommandBarBody_bodyContainer__R267m\",\"attribution\":\"CommandBarBody_attribution__8GTI0\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"noResult\":\"CommandList_noResult__oTg7n\",\"groupHeader\":\"CommandList_groupHeader___yWaG\",\"command\":\"CommandList_command__BB_Gf\",\"selected\":\"CommandList_selected__rVGLj\",\"highlight\":\"CommandList_highlight__1HwZs\",\"keyboardInputContainer\":\"CommandList_keyboardInputContainer__9XbOW\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"commandPrefix\":\"CommandPrefix_commandPrefix__MOHuk\",\"container\":\"CommandPrefix_container__xqFc2\",\"name\":\"CommandPrefix_name__P_IKZ\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"container\":\"NoResults_container__I2jHF\",\"mainBody\":\"NoResults_mainBody__GC8l_\",\"iconContainer\":\"NoResults_iconContainer__ks7uY\",\"mainMessage\":\"NoResults_mainMessage__o3ksN\",\"secondaryMessage\":\"NoResults_secondaryMessage__CNI0d\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"translationName\":\"SearchResultItem_translationName__5mkDi\",\"translationContainer\":\"SearchResultItem_translationContainer__OaPZE\",\"container\":\"SearchResultItem_container__Cvqx0\",\"itemContainer\":\"SearchResultItem_itemContainer__NRd1r\",\"quranTextResult\":\"SearchResultItem_quranTextResult__texyH\",\"verseKey\":\"SearchResultItem_verseKey__dyumW\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"container\":\"Error_container__yeY3V\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"outerContainer\":\"PartialResult_outerContainer__AcDv0\",\"innerContainer\":\"PartialResult_innerContainer__v1QDG\",\"transcript\":\"PartialResult_transcript__Lcscd\",\"suggestTitle\":\"PartialResult_suggestTitle__e8lBr\",\"suggestSubtitle\":\"PartialResult_suggestSubtitle__utXHd\",\"micCircle\":\"PartialResult_micCircle__ioN7o\",\"circlesContainer\":\"PartialResult_circlesContainer__EWZIJ\",\"volumeCircle\":\"PartialResult_volumeCircle__GvhbK\",\"verticalLyaout\":\"PartialResult_verticalLyaout__XWlc6\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"container\":\"VoiceSearchBodyContainer_container__GpMSO\",\"noResultContainer\":\"VoiceSearchBodyContainer_noResultContainer__lv_Zl\",\"commandBarContainer\":\"VoiceSearchBodyContainer_commandBarContainer__U85vU\"};"],"names":["_path","_extends","Object","assign","bind","n","e","arguments","length","t","r","hasOwnProperty","call","apply","props","width","height","viewBox","fill","xmlns","d","_path2","isClearable","onRemoveCommandClicked","commandKey","isSelected","Button","variant","ButtonVariant","size","ButtonSize","onClick","CloseIcon","name","type","useTranslation","div","className","styles","span","NavigateIcon","p","SearchNavigationType","searchQuery","commandGroups","groups","numberOfCommands","useScroll","SMOOTH_SCROLL_TO_CENTER","scrollToSelectedCommand","selectedItemRef","useState","selectedCommandIndex","setSelectedCommandIndex","highlightOffset","setHighlightOffset","useEffect","current","offsetTop","router","useRouter","dispatch","useDispatch","onUpKeyClicked","useCallback","event","preventDefault","prevSelectedCommandIndex","onDownKeyClicked","navigateToLink","command","resultType","key","push","resolveUrlBySearchNavigationType","then","addRecentNavigation","payload","setIsOpen","useHotkeys","enabled","enableOnTags","navigateTo","keys","forEach","commandGroup","selectedCommand","find","index","navigationItemKey","logButtonClick","stopPropagation","removeRecentNavigation","ul","role","style","transform","li","map","id","aria-labelledby","ref","aria-selected","classNames","onMouseOver","CommandPrefix","CommandControl","stroke","strokeWidth","VoiceError","NO_PERMISSION","NOT_SUPPORTED","SOCKET_ERROR","RESPONSE_ERROR","WORKLET_ERROR","GENERAL_ERROR","error","isWaitingForPermission","isCommandBar","icon","errorBody","MicrophoneIcon","errorText","NoMicrophoneIcon","ErrorIcon","Link","href","isNewTab","LinkVariant","logTarteelLinkClick","getVolumeLevelMultiplier","volume","Math","max","partialTranscript","verticalLayout","stopRecording","h3","searchResult","selectedTranslations","useSelector","selectSelectedTranslations","areArraysEqual","lang","params","filters","matches","slice","match","surahNum","ayahNum","join","fields","words","translations","translationFields","responseRender","data","toBeGroupedCommands","verses","verse","verseKey","truncateString","toLocalizedVerseKey","textUthmani","group","CommandsList","groupBy","item","SearchResultItem","result","source","SearchQuerySource","service","SearchService","DataFetcher","queryKey","makeVersesFilterUrl","render","AudioWorklet","url","Event","START_STREAM","END_STREAM","SEARCH_LOADING","SEARCH_RESULT","PARTIAL_TRANSCRIPT","ERROR","AUDIO_CONFIG","sampleRate","fileFormat","channels","END_STREAM_DATA","START_STREAM_DATA","audioConfig","AUDIO_CONSTRAINTS","channelCount","sampleSize","USER_MEDIA_NOT_SUPPORTED_ERROR","isWebSocketOpen","webSocket","readyState","OPEN","setVolume","mediaStream","useRef","isLoading","setIsLoading","setError","setPartialTranscript","setSearchResult","setIsWaitingForPermission","websocket","analyser","micWorkletNode","audioContext","micSourceNode","useBrowserLayoutEffect","window","AudioContext","webkitAudioContext","undefined","navigator","mediaDevices","getUserMedia","constraints","webkitGetUserMedia","mozGetUserMedia","Promise","resolve","reject","Error","releaseMicrophone","getAudioTracks","track","stop","closeWebsocket","send","JSON","stringify","close","disconnect","state","onWebsocketMessage","message","parse","logEmptySearchResults","query","queryText","SearchType","logEvent","addMicInputProcessorToAudioContext","audioWorklet","addModule","URL","WebSocket","process","env","NEXT_PUBLIC_TARTEEL_VS_API_KEY","onopen","createAnalyser","smoothingTimeConstant","fftSize","volumes","Uint8Array","frequencyBinCount","AudioWorkletNode","connect","destination","port","onmessage","getByteFrequencyData","values","i","round","getAverageVolume","onerror","startRecording","stream","isPermissionDenied","audio","createMediaStreamSource","err","useTarteelVoiceSearch","Spinner","SpinnerSize","NoResults","SearchResults","PartialResult","NAVIGATE_TO","recentNavigations","selectRecentNavigations","isVoiceSearchFlowStarted","selectIsCommandBarVoiceFlowStarted","shallowEqual","setSearchQuery","debouncedSearchQuery","useDebounce","logTextSearchQuery","onSearchQueryChange","currentTarget","value","getPreInputCommands","recentNavigation","concat","navigateToItem","dataFetcherRender","navigation","navigationItem","IconSearch","input","onChange","placeholder","inputMode","autoFocus","VoiceSearchBodyContainer","makeSearchResultsUrl","localizedVerseKey","useMemo","chaptersData","useGetChaptersData","chapterNumber","getChapterNumberFromKey","chapterData","getChapterData","toString","getChapterWithStartingVerseUrl","transliteratedName","translate","word","QuranWord","isHighlighted","highlight","isWordByWordAllowed","isAudioHighlightingAllowed","translation","dangerouslySetInnerHTML","__html","text","resourceName","resourceId","useScrollToElement","options","elementRef","scrollIntoView","block","behavior","SMOOTH_SCROLL_TO_TOP","SCROLL_TO_NEAREST_ELEMENT","rawString","suffix","characters","split","shortenedText","character","stripHTMLTags","replace","slugifiedCollectionIdToCollectionId","slugifiedCollectionId","splits","module","exports"],"sourceRoot":""}