{"version":3,"file":"static/js/e1ea1606c1b33342ccaa.bundle.js","mappings":";oSAIM,MAAOA,EAITC,YAAYC,EAAmCC,GAMxC,KAAAC,sBAAwB,IACpBC,KAAKC,MAAMC,qCACd,2BACA,EACAC,EAAAA,cACA,QACA,CACIC,YAAa,MACbC,aAAc,0BAElB,IAID,KAAAC,kBAAoB,KAAe,EAEnC,KAAAC,YAAc,IAAM,wBAAwBP,KAAKF,OACjD,KAAAU,mBAAqB,IAAM,uBAC3B,KAAAC,cAAgB,IAAiB,UAvBpCT,KAAKF,KAAOA,EAEZE,KAAKC,MAAQ,IAAIS,EAAAA,kBAwBzB,MAKaC,EAAgCC,MAAOC,EAAqCC,IAChFA,EAAIC,eAAejB,KAAKkB,sBAGRC,EAAAA,EAAAA,qBAA8BJ,EAAMd,wBAAyBe,GAF7D,GAMZI,GAA0BC,EAAAA,EAAAA,IAA2B,CAC9DC,GAAI,wCACJC,OAA2BV,EAC3BE,MAhBiBS,IAAiF,IAAAC,EAClG,MAAM,KAAEzB,GAASwB,EAAUP,eAC3B,OAAO,IAAIpB,EAA6B2B,EAAUP,eAAelB,YAAuC,QAA5B0B,EAAEzB,EAAK0B,6BAAqB,IAAAD,EAAAA,EAAI,OAiBhH,2IC1CA,MA4BA,EA5BuCE,IAOlC,IAPmC,UACpCC,EAAS,MACTC,EAAK,QACLC,EAAO,SACPC,EAAQ,KACRC,EAAI,UACJC,GACHN,EACG,MAAOO,EAAiBC,GAAsBC,EAAAA,SAAeC,QAAQP,IAErEM,EAAAA,WAAgB,KACZD,EAAmBE,QAAQP,MAC5B,CAACA,IAOJ,OACIM,EAAAA,cAAA,SAAOR,UAAWU,GAAAA,CAAW,kBAAmB,CAAE,KAAQN,GAAQJ,GAAYW,MAAOV,GACjFO,EAAAA,cAAA,SAAOI,KAAK,WAAWV,QAASI,EAAiBH,SAPhCU,IACrBN,EAAmBM,EAAMC,OAAOZ,SAChCC,MAAAA,GAAAA,EAAWU,EAAMC,OAAOZ,YAMpBM,EAAAA,cAAA,QAAMR,UAAU,gCAA+B,kBAAkBK,IACjEG,EAAAA,cAAA,QAAMR,UAAU,2BAA2BI,GAAQH,kBCiBzD,SAAUc,EAAwBC,EAAsBC,GAAsB,IAAAC,EAChF,MAAMC,GAA6B,QAAhBD,EAAAD,EAAQG,gBAAQ,IAAAF,OAAA,EAAhBA,EAAkBG,kBAAmB,EAClDC,EAASC,KAAKC,MAAuD,KAA/CR,EAAeG,EAAcM,OAAOC,UAAmB,IAEnF,OAAkB,IADgB,IAAfV,GAAqC,IAAbG,GAEhC,CAAEG,OAAAA,EAAQK,UAAU,GAEpB,CAAEA,UAAU,GAQ3B,IAAqBC,EAArB,cAAsDpB,EAAAA,cAqElDtC,YAAY2D,GACRC,MAAMD,GA/DO,KAAAE,SAA8CvB,EAAAA,YAgVvD,KAAAwB,4BAA8B,KAA8B,IAAAC,EAAAC,EAAAC,EAChE,IAAK7D,KAAKuD,MAAMO,iBAAsC,QAAnBH,EAAC3D,KAAKuD,MAAMZ,eAAO,IAAAgB,IAAlBA,EAAoBI,qBACpD,OAGJ,MAAMC,EAAwC,QAA7BJ,EAAG5D,KAAKuD,MAAMO,uBAAe,IAAAF,OAAA,EAA1BA,EAA4BK,QAAOC,IAAC,IAAAC,EAAA,OAAID,EAAEE,2BAA8C,QAAvBD,EAAKnE,KAAKuD,MAAMZ,eAAO,IAAAwB,OAAA,EAAlBA,EAAoBJ,yBACxGM,GAAaC,EAAAA,EAAAA,GAA0BN,GAE7C,IAAKK,EACD,OAGJ,MAAMrB,GAASuB,EAAAA,EAAAA,IAAiBF,GAAYG,eAAexE,KAAKuD,MAAMkB,OAAQ,CAC1EC,uBAAuBC,EAAAA,EAAAA,IAAmBN,EAAWO,uBACrDC,sBAAuB,EACvBC,aAAa,IAEXC,GAAaC,EAAAA,EAAAA,GAAsBhF,KAAKuD,MAAM0B,QAA2B,QAApBpB,EAAE7D,KAAKuD,MAAMZ,eAAO,IAAAkB,OAAA,EAAlBA,EAAoBE,qBAAsB/D,KAAKuD,MAAMZ,SAC5GuC,GAAgBF,EAAAA,EAAAA,GAAsBhF,KAAKuD,MAAM0B,QAASZ,EAAWO,uBAAuBO,oBAElG,OACIjD,EAAAA,cAAA,gBACO6C,EAAU,MAAK,GAAG/B,KAAUkC,MAKnC,KAAAE,yBAA4BC,GACzBA,EAAWrF,KAAKsF,WAGnB,KAAAC,yBAA4BF,IAChC,MAAMG,EAAWH,EAAWrF,KAAKsF,WAEjC,OAAOrC,KAAKC,MAAoC,KAA7BsC,EAAWrC,OAAOC,UAAmB,KAGpD,KAAAqC,kBAAqB7D,IAA0B,IAAA8D,EAAAC,EACnD3F,KAAK4F,SAAS,CAAEvC,SAAUzB,IACC,QAA3B8D,GAAAC,EAAA3F,KAAKuD,OAAMsC,wBAAgB,IAAAH,GAA3BA,EAAAI,KAAAH,EAA8B/D,IAWjB,KAAAmE,OAAUC,GACnBhG,KAAKiG,wBAA0BD,GAAS,GAAKA,EAAQhG,KAAKiG,uBACnDjG,KAAKiG,uBAAyBjG,KAAKsF,WACnCtF,KAAKkG,wBAA0BF,EAAQhG,KAAKkG,uBAC5ClG,KAAKkG,uBAAyBlG,KAAKsF,WAEnCU,EAAQhG,KAAKsF,WAIX,KAAAa,oBAAuBC,KAChB,IAAhBA,IAAqBpG,KAAKuD,MAAM8C,aAG5BC,MAAMF,IAAgBA,GAAepG,KAAKuG,SAAWH,GAAepG,KAAKwG,QA/UjF,MAAM,UAAEH,EAAS,aAAEI,EAAY,QAAE9D,GAAY3C,KAAKuD,MAClD,IAAIF,GAAW,EACXX,EAAgC,GAEvB,IAAAgE,EAAb,GAAI/D,IACAD,EAAe+D,IAAiBJ,EAAY,EAA+B,QAA9BK,EAAG1G,KAAKiG,8BAAsB,IAAAS,EAAAA,EAAI,GAE3E1G,KAAK2G,aACL,GAAIpD,EAAMF,SACNA,GAAW,MACR,CACH,MAAMuD,EAAgBnE,EAAwBC,EAAcC,GAExDiE,EAAc5D,OACdN,EAAekE,EAAc5D,OAE7BK,EAAWuD,EAAcvD,SAMzCrD,KAAK6G,MAAQ,CACTC,aAAcpE,EACdqE,mBAA4C,iBAAjBrE,EAA4BA,EAAeS,OAAO6D,WAAWtE,IAAiB,EACzGW,SAAAA,GAEJrD,KAAK+F,OAAS/F,KAAK+F,OAAOkB,KAAKjH,MAC/BA,KAAKkH,cAAgBlH,KAAKkH,cAAcD,KAAKjH,MAC7CA,KAAKmH,kBAAoBnH,KAAKmH,kBAAkBF,KAAKjH,MACrDA,KAAKyF,kBAAoBzF,KAAKyF,kBAAkBwB,KAAKjH,MA7F/C,kBAAe,IAAAoH,EACrB,QAA2B,QAAnBA,EAACpH,KAAKuD,MAAMZ,eAAO,IAAAyE,GAAU,QAAVA,EAAlBA,EAAoBtE,gBAAQ,IAAAsE,IAA5BA,EAA8BrE,iBAGjC,cACN,OAAQ/C,KAAKiG,wBAA0B9C,QAAQnD,KAAKuD,MAAM8C,YAAcrG,KAAKsF,WAGvE,cAEN,OADYtF,KAAKkG,wBAA0B,WAC9BlG,KAAKsF,WAGZ,iBACN,OAAItF,KAAK6G,MAAMxD,SAEJrD,KAAKqH,2BAA6B,EAGtCrH,KAAKsH,wBAA0B,EAGhC,6BAA0B,IAAAC,EAChC,OAAyB,QAAzBA,EAAOvH,KAAKuD,MAAMZ,eAAO,IAAA4E,GAAU,QAAVA,EAAlBA,EAAoBzE,gBAAQ,IAAAyE,OAAA,EAA5BA,EAA8BxE,gBAG/B,6BAA0B,IAAAyE,EAChC,OAAyB,QAAzBA,EAAOxH,KAAKuD,MAAMZ,eAAO,IAAA6E,GAAU,QAAVA,EAAlBA,EAAoB1E,gBAAQ,IAAA0E,OAAA,EAA5BA,EAA8BC,gBAG/B,6BAA0B,IAAAC,EAChC,OAAyB,QAAzBA,EAAO1H,KAAKuD,MAAMZ,eAAO,IAAA+E,GAAU,QAAVA,EAAlBA,EAAoB5E,gBAAQ,IAAA4E,OAAA,EAA5BA,EAA8BC,gBAG/B,gCAA6B,IAAAC,EACnC,OAAyB,QAAzBA,EAAO5H,KAAKuD,MAAMZ,eAAO,IAAAiF,GAAU,QAAVA,EAAlBA,EAAoB9E,gBAAQ,IAAA8E,OAAA,EAA5BA,EAA8BC,mBAG/B,YACN,OAAO7H,KAAK6G,MAAME,mBAAqB/G,KAAKsF,WAGtC,qBAAkB,IAAAwC,EACxB,OAAO9H,KAAKgG,MAAMxB,eAAexE,KAAKuD,MAAMkB,OAAQ,CAChDC,uBAAuBC,EAAAA,EAAAA,IAAqC,QAAnBmD,EAAC9H,KAAKuD,MAAMZ,eAAO,IAAAmF,OAAA,EAAlBA,EAAoB/D,sBAC9Dc,sBAAuB,EACvBC,aAAa,IAIX,mBAAgB,IAAAiD,EACtB,MAIMC,EAAwB,QAArBD,EAAG/H,KAAKuD,MAAMZ,eAAO,IAAAoF,OAAA,EAAlBA,EAAoBhE,qBAEhC,QAASiE,GANK,CACV,KACA,YAIkBC,SAASD,GAuC5BE,qBACHC,EAAAA,EAAAA,KACI,SAA6BC,IAAvBpI,KAAKuD,MAAMZ,UAAsD,KAA5B3C,KAAK6G,MAAMC,cAAmD,IAA5B9G,KAAK6G,MAAMC,gBACxF,KAAK,IAAAuB,EACD,MAAM,UAAEhC,EAAS,aAAEI,GAAiBzG,KAAKuD,MACnCb,EAAe+D,IAAiBJ,EAAY,EAA+B,QAA9BgC,EAAGrI,KAAKiG,8BAAsB,IAAAoC,EAAAA,EAAI,GAErF,GAAIrI,KAAK2G,YAAa,CAClB,MAAM2B,EAAYtI,KAAKsH,uBACjBtE,EAASN,EAAe4F,EAGZ,IAFA5F,EAAe4F,EAG7BtI,KAAK4F,SAAS,CAAEkB,aAAc9D,IAE9BhD,KAAK4F,SAAS,CAAEvC,UAAU,SAG9BrD,KAAK4F,SAAS,CAAEkB,aAAcpE,QAK1C6F,EAAAA,EAAAA,KACI,IAAMvI,KAAKuD,MAAMF,WAChBA,IACGrD,KAAK4F,SAAS,CAAEvC,SAAUlB,QAAQkB,SAI1CkF,EAAAA,EAAAA,KACI,IAAMvI,KAAKuD,MAAMkD,eACjB,KAAK,IAAA+B,EACD,MAAM1B,EAAkD,iBAA5B9G,KAAK6G,MAAMC,aACjC3D,OAAO6D,WAAWhH,KAAK6G,MAAMC,aAAa2B,QAAQ,IAAK,MAAQ,KAC/DzI,KAAK6G,MAAMC,aACX4B,EAAc1I,KAAKuF,yBAAyBuB,GAC5CV,EAAcpG,KAAKoF,yBAAgD,QAAxBoD,EAACxI,KAAKuD,MAAMkD,oBAAY,IAAA+B,EAAAA,EAAI,GAGzExI,KAAKuD,MAAMkD,eAAiBiC,GAC5B1I,KAAK4F,SAAS,CACVkB,aAAcV,QAM9BmC,EAAAA,EAAAA,KACI,IAAMvI,KAAK6G,MAAMxD,WAChBsF,IACG,GAAIA,EAAU,KAAAC,EACV,MAAMC,GAAmC,QAAxBD,EAAC5I,KAAKuD,MAAMkD,oBAAY,IAAAmC,EAAAA,EAAI,GAAK5I,KAAKsF,WAEvDtF,KAAK4F,SAAS,CACVkB,aAAc+B,EACd9B,mBAAoB8B,QAErB,KAAAC,EACH,MAAMD,GAAmC,QAAxBC,EAAC9I,KAAKuD,MAAMkD,oBAAY,IAAAqC,EAAAA,EAAI,GAAK9I,KAAKsF,WAEvDtF,KAAK4F,SAAS,CACVkB,aAAc+B,EACd9B,mBAAoB8B,SAMpCN,EAAAA,EAAAA,KACI,IAAMvI,KAAK6G,MAAMC,eACjB,KAAK,IAAAiC,EACD/I,KAAK4F,SAAS,CACVkB,aAAc9G,KAAKgJ,aAAehJ,KAAK6G,MAAMC,aAAatC,eAAexE,KAAKuD,MAAMkB,OAAQ,CACxFC,uBAAuBC,EAAAA,EAAAA,IAAqC,QAAnBoE,EAAC/I,KAAKuD,MAAMZ,eAAO,IAAAoG,OAAA,EAAlBA,EAAoBhF,sBAC9Dc,sBAAuB,EACvBC,aAAa,IACd2D,QAAQ,IAAK,KAAOzI,KAAK6G,MAAMC,aAClCC,mBAAoB5D,OAAO6D,WAAWhH,KAAK6G,MAAMC,aAAamC,WAAWR,QAAQ,IAAK,MAAQ,UAMvGS,SAAM,IAAAC,EAAAC,EACT,MAAM,UAAE/C,EAAS,QAAEpB,EAAO,QAAEtC,EAAO,mBAAE0G,GAAuBrJ,KAAKuD,MAC3D+F,EAAWtJ,KAAK6G,MAAME,sBAAwBV,EAAa,EAAIrG,KAAKuG,SACpEgD,EAAcvJ,KAAK6G,MAAME,qBAAuB/G,KAAKwG,QACrDgD,EAAexJ,KAAK6G,MAAMC,aAC1B2C,EAAgB,oBAChBC,GAAgB1J,KAAKuD,MAAMoG,eAEjC,IAAIC,EAAa,GACbN,EAEAM,EAAa,WACN5J,KAAKuD,MAAM+F,WAElBM,EAAa,cAEjB,MAAMC,EAAoBxI,GAAsC,KAC5D,IAAIyI,EAAoB,cAAXzI,EAAyB,GAAK,EAE3C,MAAM0I,EAAaC,IACf,MAAMC,EAAYjK,KAAK6G,MAAME,mBAAqBiD,EAClD,OAAOhK,KAAKsF,WAAa2E,GAG7B,IAAIC,EAAWH,EAAUD,GAEV,cAAXzI,GAA0B6I,EAAW,IACjClK,KAAKiG,wBAA0BiE,EAAWlK,KAAKiG,yBAC/C6D,GAAU9J,KAAKiG,uBAAyBjG,KAAKgG,OAAShG,KAAKsF,YAG/D4E,EAAWH,EAAUD,GAEjB9J,KAAKkG,wBAA0BgE,EAAWlK,KAAKkG,yBAC/C4D,GAAU9J,KAAKkG,uBAAyBlG,KAAKgG,OAAShG,KAAKsF,aAIpD,cAAXjE,GAA2B6I,EAAW,IAClClK,KAAKiG,wBAA0BiE,EAAWlK,KAAKiG,yBAE3C6D,EADAzD,GACUrG,KAAK6G,MAAME,mBAEZ/G,KAAKuG,QAAUvG,KAAK6G,MAAME,oBAGvC/G,KAAKkG,wBAA0BgE,EAAWlK,KAAKkG,yBAC/C4D,EAAS9J,KAAKwG,QAAUxG,KAAK6G,MAAME,qBAI3C/G,KAAKmK,qBAAqBL,IAG9B,OACI5H,EAAAA,cAAA,OAAKR,UAAWU,GAAAA,CAAWqH,EAAe,CAAE,KAAQC,EAAc,gBAAiBL,OAC7E1G,MAAAA,GAAiB,QAAVwG,EAAPxG,EAASG,gBAAQ,IAAAqG,GAAjBA,EAAmBxB,mBAAoB+B,GACrCxH,EAAAA,cAACkI,EAAM,CACH1I,UAAWU,GAAAA,CAAW,kBAAmB,CAAE,QAAWpC,KAAK2G,cAC3DhF,MAAM,UACNC,QAAS5B,KAAK6G,MAAMxD,SACpBxB,SAAU7B,KAAK2G,YAAc3G,KAAKyF,uBAAoB2C,IAE9DlG,EAAAA,cAAA,OAAKR,UAAW,GAAG+H,uBACfvH,EAAAA,cAAA,OAAKR,UAAWU,GAAAA,CAAW,GAAGqH,4BAAyC,CAAEH,SAAUtJ,KAAKuD,MAAM+F,cACxF3G,MAAAA,GAAiB,QAAVyG,EAAPzG,EAASG,gBAAQ,IAAAsG,GAAjBA,EAAmBzB,kBAAmB+B,GAAgB1J,KAAK2G,aACzDzE,EAAAA,cAACkI,EAAM,CACH1I,UAAWU,GAAAA,CAAW,uBAAwB,CAAE,QAAWpC,KAAK2G,cAChEhF,MAAM,UACNG,MAAI,EACJC,UAAU,IACVH,QAAS5B,KAAK6G,MAAMxD,SACpBxB,SAAU7B,KAAK2G,YAAc3G,KAAKyF,uBAAoB2C,IAE7DsB,GAAgB1J,KAAK2G,aAClBzE,EAAAA,cAAA,QAAMR,UAAW,GAAG+H,mBACf,GAAGzJ,KAAKsF,cAAa,MAI9BpD,EAAAA,cAAA,UACIoH,SAAUtJ,KAAKuD,MAAM+F,UAAYA,EACjCjH,MAAOiH,EAAW,GAAKtJ,KAAKuD,MAAM8G,yBAClC3I,UAAW,GAAG+H,mCAA+CG,IAC7DU,QAAST,EAAiB,aAAY,8BAE1B,GAAG7J,KAAKuD,MAAM8G,2BAC1BE,UAAW,EACXC,MAAM,cAEVtI,EAAAA,cAAA,SAEII,KAAK,OACLZ,UAAW,GAAG+H,oBACdgB,QAAQ,SACRC,MAA+B,iBAAjBlB,EAA4BA,EAAeA,EAAahF,eAAexE,KAAKuD,MAAMkB,OAAQ,CAAEK,aAAa,IACvH6F,OAAQ3K,KAAKmH,kBACbtF,SAAU7B,KAAKkH,cACf0D,WAAaC,IACT,MACMC,EAAcD,EAAErI,OAAekI,MAC/BK,EAAqBD,EAAW7C,SAAS,MAAQ6C,EAAW7C,SAAS,KACrE+C,EAA4B,MAAVH,EAAEI,KAAyB,MAAVJ,EAAEI,MAHlB,YAKHC,KAAKL,EAAEI,MAASD,GAAmBD,IACrDF,EAAEM,iBAGN,MAAMC,EAjUtC,SAA6B3G,GAAc,IAAA4G,EACvC,MACMD,EAEoC,QAF3BC,EAAGC,KAAKC,aAAa9G,GAC/B+G,cAF8B,KAG9BC,MAAKC,GAAsB,YAAdA,EAAKpJ,cAAmB,IAAA+I,OAAA,EAFxBA,EAGZX,MACN,OAAOU,MAAAA,EAAAA,EAAa,IA2T0BO,CAAoB3L,KAAKuD,MAAMkB,QAC3CgE,EAAwB,MAAd2C,EAAoB,IAAM,IACzCP,EAAUrI,OAAOkI,MAAQI,EAAWrC,QAAQA,EAAS2C,IACzD,YACS,SAAQ,aACN,GAAGpL,KAAKuD,MAAMqI,yBAC1BC,KAAK,aAAY,gBACF,EAAC,gBACD7L,KAAKwG,QAAO,gBACZrD,OAAO6D,WAAWwC,EAAaP,aAAe,EAC7D6C,IAAK9L,KAAKyD,SACV6F,SAAUtJ,KAAKuD,MAAM+F,SAAQ,uBAGjCpH,EAAAA,cAAA,UACIoH,SAAUtJ,KAAKuD,MAAM+F,UAAYC,EACjClH,MAAOkH,EAAc,GAAKvJ,KAAKuD,MAAMwI,yBACrCrK,UAAW,GAAG+H,mCAA+CF,EAAc,WAAa,KACxFe,QAAST,EAAiB,aAAY,8BAE1B,GAAG7J,KAAKuD,MAAMwI,2BAC1BxB,UAAW,EACXC,MAAM,eAGdtI,EAAAA,cAAA,QAAMR,UAAW,GAAG+H,2BAAqC,KAClDzJ,KAAKgM,eAAc,IACtB9J,EAAAA,cAAC+J,EAAAA,EAAa,CAAChH,QAASA,EAASiH,cAAevJ,OAGtD0G,GACEnH,EAAAA,cAAAA,EAAAA,SAAA,KACIA,EAAAA,cAAA,OAAKR,UAAW,GAAG+H,2BAAqC,OAEnD,GAAGzJ,KAAKsF,cACTpD,EAAAA,cAAC+J,EAAAA,EAAa,CAAChH,QAASA,EAASiH,cAAevJ,KAEpDT,EAAAA,cAAA,OAAKR,UAAW,GAAG+H,8BACdzJ,KAAK0D,iCAkDtByG,qBAAqBL,GACzB,MAAMqC,EAAkBnM,KAAK6G,MAAME,mBAAqB+C,EAET,IAAAsC,EAAAC,EAA3CrM,KAAKmG,oBAAoBgG,KACN,QAAnBC,GAAAC,EAAArM,KAAKuD,OAAM1B,gBAAQ,IAAAuK,GAAnBA,EAAAtG,KAAAuG,EAAsBrM,KAAKuF,yBAAyB4G,KAqBpDjF,cAAc2D,GAClB,IAAIlC,EAA4BkC,EAAErI,OAAOkI,MAEzCG,EAAEyB,UACFtM,KAAK4F,SAAS,CAAEkB,aAAc6B,IAAY,KAKE,IAAA4D,EAAAC,GAJhB,iBAAb7D,IACPA,EAAWxF,OAAO6D,WAAW2B,EAASF,QAAQ,IAAK,OAGnDzI,KAAKmG,oBAAoBwC,MACN,QAAnB4D,GAAAC,EAAAxM,KAAKuD,OAAM1B,gBAAQ,IAAA0K,GAAnBA,EAAAzG,KAAA0G,EAAsBxM,KAAKuF,yBAAyBoD,QAKxDxB,kBAAkB0D,GAAqC,IAAA4B,EAC3D,MAAMjD,EAAerG,OAAO6D,WAAW6D,EAAErI,OAAOkI,MAAMjC,QAAQ,IAAK,MAAQ,KACrEzC,EAAQhG,KAAKsF,WAAakE,EAC1Bb,EAAW1F,KAAKyJ,IAAsB,QAAnBD,EAACzM,KAAK+F,OAAOC,UAAM,IAAAyG,EAAAA,EAAI,EAAGtJ,QAAQnD,KAAKuD,MAAM8C,YAEtEwE,EAAEyB,UACFtM,KAAK4F,SAAS,CAAEkB,aAAc6B,IAAY,KAAK,IAAAgE,EAAAC,EACxB,QAAnBD,GAAAC,EAAA5M,KAAKuD,OAAM1B,gBAAQ,IAAA8K,GAAnBA,EAAA7G,KAAA8G,EAAsB5M,KAAKuF,yBAAyBoD,SA/a9CrF,EAAAuJ,aAAwC,CAClDxG,WAAW,EACXyG,oBAAqB,eACrBC,oBAAqB,gBAKfC,EAAAA,EAAAA,IAAA,CAATC,EAAAA,IAAQ,iCAICD,EAAAA,EAAAA,IAAA,CAATC,EAAAA,IAAQ,6BAICD,EAAAA,EAAAA,IAAA,CAATC,EAAAA,IAAQ,6BAKCD,EAAAA,EAAAA,IAAA,CAATC,EAAAA,IAAQ,gCASCD,EAAAA,EAAAA,IAAA,CAATC,EAAAA,IAAQ,4CAICD,EAAAA,EAAAA,IAAA,CAATC,EAAAA,IAAQ,4CAICD,EAAAA,EAAAA,IAAA,CAATC,EAAAA,IAAQ,4CAICD,EAAAA,EAAAA,IAAA,CAATC,EAAAA,IAAQ,+CAICD,EAAAA,EAAAA,IAAA,CAATC,EAAAA,IAAQ,2BAICD,EAAAA,EAAAA,IAAA,CAATC,EAAAA,IAAQ,oCAQCD,EAAAA,EAAAA,IAAA,CAATC,EAAAA,IAAQ,iCA3DQ3J,GAAwB0J,EAAAA,EAAAA,IAAA,CAD5CE,EAAAA,IACoB5J,gEClCT6J,EAUAC,wvBAVZ,SAAYD,GACRA,EAAA,0BACAA,EAAA,kBACAA,EAAA,kBACAA,EAAA,YAJJ,CAAYA,IAAAA,EAAc,KAU1B,SAAYC,GAIRA,EAAA,kBAKAA,EAAA,kBAKAA,EAAA,kBAdJ,CAAYA,IAAAA,EAAoC,KAoB1C,MAAOC,EAWTzN,YAAmB0N,EAAqBC,EAAcC,EAAyBC,EAAoBC,GAQ5F,KAAAnN,YAAc,IAAM,+BAEpB,KAAAC,mBAAqB,IAAM,+BAE3B,KAAAC,cAAgB,IAAiB,OAXpCT,KAAK2N,YAAcL,EACnBtN,KAAK4N,gBAAkBL,EACvBvN,KAAKwN,eAAiBA,EACtBxN,KAAKyN,UAAYA,EACjBzN,KAAK0N,UAAYA,GA2DzB9M,eAAeiN,EAAgBhN,EAAyBiN,EAA8BhN,GAAmB,IAAAiN,EAAAC,EACrG,MAAMC,GAAYC,EAAAA,EAAAA,IAAapN,EAAIC,gBACnC,IAAIoN,EAA+C,CAC/CC,gBAAiBvN,EAAM8M,aAAe9M,EAAM8M,YAAYU,OAAS,EAAIxN,EAAM8M,YAAc,GACzFW,QAAS,CACLC,WAAYzN,EAAIC,eAAelB,YAAY2O,UAC3CC,UAAWR,IAInB,IAAiC,QAA7BF,EAAAjN,EAAIC,eAAe2N,IAAIC,cAAM,IAAAZ,OAAA,EAA7BA,EAA+Ba,+BAAgCxB,EAAqCyB,QAAS,CAC7G,MAEMC,EAjC2BC,EACrCC,EACAC,KAEA,GAAID,GAAiCA,EAA8BE,6CAC/D,MAAO,CACHC,gBAAiBH,EAA8BE,6CAC/CE,cAAeC,EAAAA,kBAAkBC,UACjCC,qBAAsBN,EAAY,OAAS,QAC3CO,sBAAuBP,EAAY,OAAS,QAC5CQ,SAAU,GACVC,UAAW,EACXC,MAAO,EACPC,oBAAqB,GACrBC,mBAAoBC,EAAAA,qBAAqBC,YAmBfhB,OAFciB,EAAAA,EAAAA,gCAA+B,CAAEC,cAAenP,KACnE,GAGrBgO,IACAX,EAAqB+B,EAAAA,EAAA,GACd/B,GAAqB,IACxBgC,WAAY,CAACrB,MAKzB,MAAMsB,EAA2C,CAC7CC,sBAAuBlC,EACvBmC,UAAWzP,EAAM4M,UACjB8C,UAAW1P,EAAM6M,UACjBP,eAAgBtM,EAAM2M,gBAG1B4C,EAAeC,sBAAuBF,YAAaK,EAAAA,EAAAA,IAA4B1P,EAAyC,QAAtCkN,EAAEoC,EAAeC,6BAAqB,IAAArC,OAAA,EAApCA,EAAsCmC,aAEtHM,EAAAA,EAAAA,IAAoB3P,UACd4P,EAAAA,EAAAA,IAAkB5P,EAAKsP,EAAeC,6BAG1CM,EAAAA,EAAAA,IAAwB7P,EAAKsP,EAAeC,uBAElD,MAAMO,QAA0BC,EAAAA,EAAAA,2BAC5B,CAAEZ,cAAenP,EAAKgQ,oBAAqB,CAAEC,OAAQ,CAAEC,IAAKnQ,EAAM+M,mBAClEwC,GAGAQ,GAAqBA,EAAkBvC,OAAS,GAChDuC,EAAkBK,KAAKC,IAA0B,IAAAC,EAE7CD,EAAKE,SAAWF,EAAKE,UAAWC,EAAAA,EAAAA,kBAAiBH,EAAKE,SAAUtQ,EAAIC,eAAelB,aAAe,GAGnF,QAAfsR,EAAID,EAAKI,cAAM,IAAAH,GAAO,QAAPA,EAAXA,EAAaI,aAAK,IAAAJ,GAAlBA,EAAoBK,eACpBN,EAAKI,OAAOC,MAAMC,kBAAepJ,MAIzC0F,EAAY2D,iBAAmBb,GAE/B9P,EAAI4Q,UAAUC,MACV,4FAA4FvB,EAAejD,kBAKhH,MAMP,GANoDhM,EAAAA,EAAAA,IAA2B,CAC3EC,GAAI,iEACJC,OAxGGT,eAA0CC,EAAyBC,GAEtE,IAAKD,IAAUA,EAAM8M,YACjB,MAAM,IAAIiE,MAAM,oEAGpB,MAAM9D,EAA+B,GAE/B+D,EAAsB,CAAChE,EAAgBhN,EAAOiN,EAAahN,IACjE,OAAOgR,QAAQC,IAAIF,GAAqBG,MAAK,IAClClE,KA+FXjN,MAlHiBS,GACV,IAAI+L,6CCnDf,IAAI4E,EAMG,MAAMC,EAAgC3O,IACzC,MAAM,YACF4O,EAAW,WACX7E,EACA8E,kBACIC,WAAW,0BAAEC,KAEjB/O,EAEEgP,EAAgC,GACtCN,GAAUO,EAAAA,EAAAA,kBAAiB,QAASjP,EAAMkP,iBAAmB,IAE7DN,MAAAA,GAAAA,EAAalB,KAAIC,IACbqB,EAAWG,KAAKC,EAAczB,EAAM3N,OAItBqP,EAAaN,EAA2BhF,GAE1D,MAAO,CAAEjL,MAAO,KAAMwQ,KAAMN,IAG1BK,EAAeA,CAACN,EAAmChF,KACrD,MAAMwF,EAAgCR,GAChCS,EAAAA,EAAAA,QAAOT,EAA2BhF,GAClC,WAAWA,mBAEjB,OAAOpL,EAAAA,cAAA,MAAIR,UAAU,0CAA0CoR,IAG7DH,EAAgBA,CAACzB,EAAwB3N,KAAsC,IAAA4N,EAAA6B,EAAAC,EAAAC,EAAAC,EACjF,MAAM,WAAE7F,EAAU,UAAEG,EAAS,UAAEC,EAAS,mBAAE0F,GAAuB7P,EAE3D8P,EAAaD,EAA+B,QAAbjC,EAAGD,EAAKK,aAAK,IAAAJ,OAAA,EAAVA,EAAY1I,QAAQ,MAAO,MAAQyI,EAAKK,OAASL,EAAKK,MAAM+B,MAAM,KAAKC,MACzGC,EAAYH,EACZA,EAAW5K,QAAQ,IAAIgL,OAAO,IAAIhG,KAAc,MAAO,IAAIhF,QAAQ,IAAIgL,OAAO,IAAI/F,KAAc,MAAO,IACvGwD,EAAKK,OAASL,EAAKK,MAAM9I,QAAQ,IAAIgL,OAAO,IAAIhG,KAAc,MAAO,IAAIhF,QAAQ,IAAIgL,OAAO,IAAI/F,KAAc,MAAO,IACrHgG,EAAW,GAA4B,QAA5BV,EAAGzP,EAAMoQ,2BAAmB,IAAAX,OAAA,EAAzBA,EAA2BY,iBAAiBrQ,EAAMsQ,gCAAgCL,IACtGvB,EAAQ6B,cAAcC,MAAQ7C,EAAKK,MACnC,MAAMyC,GAAYC,EAAAA,EAAAA,wBAAuB1Q,EAAMkP,iBAAmBR,GAE5DiC,EAA8B,KADX,QAAdjB,EAAG/B,EAAKI,cAAM,IAAA2B,GAAO,QAAPA,EAAXA,EAAa1B,aAAK,IAAA0B,OAAA,EAAlBA,EAAoBkB,cAE5B5Q,EAAM6Q,+BACN7Q,EAAM8Q,qCACZ,OACInS,EAAAA,cAAA,MAAIR,UAAU,wCAAwCuJ,IAAKiG,EAAKoD,IAC5DpS,EAAAA,cAAA,IAAAqS,OAAAC,OAAA,cAAed,EAAUe,KAAMC,EAAcxD,EAAM5D,EAAY/J,IAAYyQ,EAAS,CAAE3R,MAAOqR,IACzFxR,EAAAA,cAAA,YACIA,EAAAA,cAAA,QAAMR,UAAU,sDAA+E,QAA3BwR,EAAE3P,EAAMoQ,2BAAmB,IAAAT,OAAA,EAAzBA,EAA2BU,eACjG1R,EAAAA,cAAA,iBAAmBqB,EAAMsQ,6BAA4B,MACpDa,EAAcxD,EAAM5D,EAAY/J,IAAUoR,EAAoBtB,GAA0B,GAAI5F,EAAWC,IAE5GxL,EAAAA,cAAA,gBAAO0S,EAAAA,EAAAA,GAAaV,EAA8B,QAAbf,EAAEjC,EAAKI,cAAM,IAAA6B,GAAO,QAAPA,EAAXA,EAAa5B,aAAK,IAAA4B,OAAA,EAAlBA,EAAoBgB,cAAa,QAMlFO,EAAgBA,CAACG,EAA8BvH,EAAoB/J,IAC9DsR,GAAcA,EAAWP,GAAKQ,EAAiBD,EAAWP,GAAIhH,EAAY/J,GAAS,GAGxFuR,EAAmBA,CAAC1T,EAAYkM,EAAoB/J,KAA8C,IAAAwR,EACpG,MAAM,cAAEC,EAAa,UAAEC,EAAS,eAAEC,GAAmB3R,EAErD,IAAK4R,EAAAA,GAASC,UACV,MAAO,GAGX,MAAMC,EAAW,IAAIC,IAAIN,EAAeO,OAAOC,SAASf,MAEpDQ,GAAa3H,GACb+H,EAASI,aAAaC,IAAIT,EAAW3H,GAGzC,MAAMqI,EAAmBT,MAAAA,OAAc,EAAdA,EAAgBzJ,MAAKmK,GACnCA,EAASC,cAAgB/F,EAAAA,qBAAqBgG,WAEnDC,EAAUJ,MAAAA,GAAwB,QAARZ,EAAhBY,EAAkBK,cAAM,IAAAjB,OAAA,EAAxBA,EAA0BtJ,MAAKyF,GACpCA,EAAK/B,kBAAoBhM,OAAO8S,SAAS7U,EAAI,MAGlD8U,EAAiBH,GAAWI,KAAKC,UAAUC,EAAiB,CAACN,KAKnE,OAJIG,GACAb,EAASI,aAAaC,IAAI,WAAYQ,GAGnCb,EAASZ,MAGdE,EAAsBA,CAACE,EAAoBpH,EAAmBC,KAChE,MAAM4I,EAAgBzB,EACjBpM,QAAQ,IAAIgL,OAAO,IAAIhG,KAAc,MAAO,YAC5ChF,QAAQ,IAAIgL,OAAO,IAAI/F,KAAc,MAAO,aAGjD,OAAOxL,EAAAA,cAAA,QAAMqU,yBAAyBC,EAAAA,EAAAA,IAAgBF,MAKpDG,EAAwB,CAC1B,gBACA,uBACA,gCACA,kBACA,qBACA,wBACA,iCACA,WACA,aAOEJ,EAAoBT,IACtB,MAAMc,EAA4C,GAUlD,OARAd,EAASe,SAAQZ,IACb,MAAMa,EAAyC,GAC/CH,EAAsBE,SAAQE,IAC1BD,EAAkBlE,KAAKqD,EAAQc,OAEnCH,EAAmBhE,KAAKkE,MAGrBF,GCpIEI,EAAiBvT,IAC1B,MAAM,QACF0B,EAAO,UACPgQ,EAAS,kBACT8B,EAAiB,gBACjBC,EAAe,kBACfC,EAAiB,SACjBC,EAAQ,oBACRC,EAAmB,yBACnBC,EAAwB,yBACxBC,EAAwB,MACxBpX,EAAK,gBACLqX,EAAe,gBACfC,EAAe,gBACfC,GACAjU,EAEEkU,EApBqBR,CAAAA,GAAgD1U,IAC3E0U,EAAkB1U,EAAMC,OAAOkI,OAAS,KAmBlBgN,CAAsBT,GAEtCU,EACFzV,EAAAA,cAAA,SACIR,UAAWU,GAAAA,CAAW,2BACtBE,KAAK,OAAM,aACCiV,EACZK,KAAM3C,EACN4C,YAAad,EACbjL,IAAKkL,EACLnV,SAAU4V,EACVK,UAAWZ,EACXxM,MAAOzK,IAIT8X,GAAiBZ,GACnBjV,EAAAA,cAAC8V,EAAAA,OAAM,CAACtW,UAAU,+BAA8B,aAAa8V,GACzDtV,EAAAA,cAAA,OAAK+V,KAAKC,EAAAA,EAAAA,IAAS,mBAAoBjT,EAAQkT,YAuBvD,MAAO,CAAEtX,MAAO8W,EAAWS,UAlBvBlW,EAAAA,cAAC8V,EAAAA,OAAM,CACHtW,UAAYyV,EAAuD,uCAAjC,+BAAuE,aAC7FG,EACZhN,QAAS8M,EACT9U,KAAK,WAcwC+V,UAAWN,EAAeO,WAT3EpW,EAAAA,cAAC8V,EAAAA,OAAM,CACHtW,UAAU,0BACV4I,QAAS+M,EACT/U,KAAK,UAELJ,EAAAA,cAAA,OAAK+V,KAAKC,EAAAA,EAAAA,IAAS,oBAAqBjT,EAAQkT,SAAUI,MAAO,GAAIC,OAAQ,QC/DzF,IAAIvG,EAMG,MAAMwG,EAA+BlV,IACxC,MAAM,oBAAEoQ,EAAmB,YAAExB,EAAW,UAAE1E,EAAS,UAAEC,GAAcnK,EAEnE0O,GAAUO,EAAAA,EAAAA,kBAAiB,QAASjP,EAAMkP,iBAAmB,IAE7D,MAAMF,EAAgC,GAiBtC,OAfIJ,GAAewB,IACfxB,EAAYuG,OAAO,EAAG,EAAG,CACrBpE,GAAI,kBACJ/C,MAAO,GAAG9D,IAAYkG,EAAoBC,gBAAgBlG,MAG9DyE,MAAAA,GAAAA,EAAawG,MAAM,EAAG,GAAG1H,KAAIC,IACzBqB,EAAWG,KAAKC,EAAczB,EAAMzD,EAAWC,EAAWnK,QAQ3D,CAAEsP,KAAMN,IAGbI,EAAgBA,CAACzB,EAAwBzD,EAAmBC,EAAmBnK,KACjF,MAAMiQ,EACFtC,EAAKK,OAASL,EAAKK,MAAM9I,QAAQ,IAAIgL,OAAO,IAAIhG,KAAc,MAAO,IAAIhF,QAAQ,IAAIgL,OAAO,IAAI/F,KAAc,MAAO,IACzHuE,EAAQ6B,cAAcC,MAAQP,EAC9B,MAAMQ,GAAYC,EAAAA,EAAAA,wBAAuB1Q,EAAMkP,iBAAmBR,GAClE,OACI/P,EAAAA,cAAA,MAAIR,UAAU,uCAAuCuJ,IAAKiG,EAAKoD,IAC3DpS,EAAAA,cAAA,IAAAqS,OAAAC,OAAA,cAAehB,EAAWiB,KAAMC,EAAcxD,EAAMzD,EAAWC,EAAWnK,IAAYyQ,GACjFU,EAAcxD,EAAMzD,EAAWC,EAAWnK,IACvCoR,EAAoBzD,EAAKK,MAAQL,EAAKK,MAAQ,GAAI9D,EAAWC,MAM3EgH,EAAgBA,CAACG,EAA8BpH,EAAmBC,EAAmBnK,KACvF,MAAM,cAAEyR,EAAa,UAAEC,GAAc1R,EAE/BqV,EAAiB/D,EAAWtD,MAC7B9I,QAAQ,IAAIgL,OAAO,IAAIhG,KAAc,MAAO,IAC5ChF,QAAQ,IAAIgL,OAAO,IAAI/F,KAAc,MAAO,IAEjD,IAAKyH,EAAAA,GAASC,UACV,MAAO,GAGX,MAAMC,EAAW,IAAIC,IAAIN,EAAeO,OAAOC,SAASf,MAKxD,OAJIQ,GAAa2D,GACbvD,EAASI,aAAaC,IAAIT,EAAW2D,GAGlCvD,EAASZ,MAGdE,EAAsBA,CAACE,EAAoBpH,EAAmBC,KAChE,MAAM4I,EAAgBzB,EACjBpM,QAAQ,IAAIgL,OAAO,IAAIhG,KAAc,MAAO,YAC5ChF,QAAQ,IAAIgL,OAAO,IAAI/F,KAAc,MAAO,aAGjD,OAAOxL,EAAAA,cAAA,QAAMqU,yBAAyBC,EAAAA,EAAAA,IAAgBF,oCC1F1D,MAmCA,EAnCmB/S,IAA0B,IAAAsV,EACzC,MAAM,KAAEC,EAAI,UAAEC,EAAS,kBAAEC,GAAsBzV,GACxC0V,EAAsBC,GAA2BhX,EAAAA,UAAwB,GAG1EiX,EAAeL,MAAAA,GAAoB,QAAhBD,EAAJC,EAAMA,KAAKM,iBAAS,IAAAP,OAAA,EAApBA,EAAsB5U,QAAOC,GAAKA,EAAEmV,YAAcN,IAAWO,QAAO,CAACC,EAAKC,IAAQD,GAAOC,EAAIC,UAAY,IAAI,GAElI,IAAKN,EACD,OAAO,KAGX,MAAMO,EAAc,kCAAkCX,IAChDY,EAAgBX,GAAqB,qBACrCY,GAAc7G,EAAAA,EAAAA,QAAO4G,EAAeR,GAE1C,OACIjX,EAAAA,cAAA,QACId,GAAIsY,EACJhY,UAAW,kDACXmY,YAAaA,IAAMX,GAAwB,GAC3CY,WAAYA,IAAMZ,GAAwB,GAC1Ca,aAAcA,IAAMb,GAAwB,IAE3CC,EACDjX,EAAAA,cAAC8X,EAAAA,QAAO,CACJC,OAAQhB,EACRzW,OAAQ,IAAIkX,IACZhY,UAAU,0BAETkY,KC2EjB,EA1FoBrW,IAChB,MAAM,GACFnC,EAAE,SACF8Y,EAAQ,QACRjV,EAAO,UACPoN,EAAS,gBACT8H,EAAe,cACfjO,EAAa,aACbkO,EAAY,KACZtB,EAAI,UACJuB,EAAS,kBACTrB,GACAzV,GACG8B,EAAUiV,GAAepY,EAAAA,SAAuB,IAChDmB,EAAUkX,GAAerY,EAAAA,UAAwB,IACjDsY,EAAcC,GAAkBvY,EAAAA,SAAe,GAEhDwY,EAAmBxY,EAAAA,aAAmB2I,IACnCA,EAAErI,OAAuBmY,QAAQ,sBAKtC9P,EAAEM,iBACFN,EAAE+P,qBACH,IAEGC,EAAyC,CAC3CC,YAAazI,EAAU0I,iBACvBC,oBAAqB3I,EAAU2I,oBAC/BC,wBAAyB5I,EAAU4I,wBACnCC,sBAAuB7I,EAAU6I,sBACjCC,SAAU9I,EAAU+I,cACpBC,kBAAmBhJ,EAAUiJ,wBAG3BC,EAA8C,CAChDC,SAAUrB,EACVsB,OAAOrB,MAAAA,OAAY,EAAZA,EAAcsB,0BAA2B,GAGpD,OACIxZ,EAAAA,cAAA,OAAKR,UAAU,yBAAyBia,WAAS,EAACC,YAAa/Q,GAAKA,EAAEM,iBAAkBb,QAASoQ,GAC7FxY,EAAAA,cAACoB,EAAAA,EAAwB,CACrB2B,QAASA,EACToB,WAAS,EACT1D,QAASuJ,EACTzH,OAAQQ,EAAQkT,QAAQ1T,OACxBgC,aAAcpB,EACdxD,SAAUyY,EACVhR,UAAW4C,EACX7I,SAAUA,EACVgG,oBAAkB,EAClBxD,iBAAmB6E,IAAkB,IAAAmR,EACjCtB,EAAY7P,GACU,QAAtBmR,EAAAtY,EAAMsC,wBAAgB,IAAAgW,GAAtBA,EAAA/V,KAAAvC,EAAyBA,EAAM4W,gBAAiBzP,MAIvDwB,GACGhK,EAAAA,cAAA,OAAKR,UAAU,iCACXQ,EAAAA,cAAC4Z,EAAS,CAAC7Q,IAAKuP,EAAa1B,KAAMA,EAAMC,UAAWoB,EAAiBnB,kBAAmBA,IACxF9W,EAAAA,cAAC6Z,EAAAA,mBAAkB,CACf3a,GAAIA,EACJ6D,QAASA,EACTiV,SAAUA,EACV7U,SAAUA,EACVhC,SAAUA,EACV2Y,iBAAkB1B,EAClB2B,KAAM,CACFnD,KAAAA,EACAnW,QAASuJ,EACTgQ,MAAO9B,EACP+B,cAAeZ,GACnBlB,UAAWA,EACX+B,cAAY,EACZC,cAAehK,EAAUiK,oBACzBC,mBAAmB,qBACnBC,eAAe,eACfC,YAAapK,EAAUoK,YACvB5B,aAAcA,EACd6B,cAAenZ,EAAMmZ,cACrBC,MAAO/b,UAAc6Z,EAAeD,EAAc,4PC9B1E,IAAIvI,EACAQ,EAMG,MAAMmK,EAA+BrZ,IACxC,MAAM,YACF4O,EAAW,UACXzE,EAAS,UACTD,EACA2E,kBACInN,SAAS,cAAE4X,GACXxK,WAAW,yBAAEyK,IAChB,WACDC,EAAU,SACVC,GACAzZ,EACEgP,EAA4C,GAClDE,EAAmBlP,EAAMkP,iBACzBR,GAAUO,EAAAA,EAAAA,kBAAiB,QAASjP,EAAMkP,iBAAmB,IAE7DN,MAAAA,GAAAA,EAAalB,KAAIC,IACbqB,EAAWG,KAAKC,GAAczB,EAAMzD,EAAWC,EAAWmP,EAAetZ,EAAOwZ,EAAYC,OAKhG,MAAO,CAAE3a,MAFSuQ,EAAakK,GAEJG,MAAO1K,IAGhCK,EAAgBkK,IAClB,MAAMI,EAA+BJ,GAAsD,iBAE3F,OAAO5a,EAAAA,cAAA,MAAIR,UAAU,yCAAyCwb,IAG5DvK,GAAgBA,CAClBzB,EACAzD,EACAC,EACAmP,EACAtZ,EACAwZ,EACAC,KAEA,MAAMG,EACFjM,EAAKK,OAASL,EAAKK,MAAM9I,QAAQ,IAAIgL,OAAO,IAAIhG,KAAc,MAAO,IAAIhF,QAAQ,IAAIgL,OAAO,IAAI/F,KAAc,MAAO,IAEnHwO,EAAQ3Y,EAAM6Z,aAAalM,EAAKoD,IAChCpI,EAAgB3I,EAAM8Z,eAAe5R,MAAK9I,GAAWA,EAAQ6Y,WAAavF,SAAS/E,EAAKoD,GAAK,MAEnG,MAAO,CACHzB,KAAM8B,GAAoBzD,EAAKK,MAAQL,EAAKK,MAAQ,GAAI9D,EAAWC,GACnE4P,UAAWC,GAAiBrM,EAAMiM,GAAoB,GAAI5Z,GAC1D2Y,MAAOsB,GAAatB,EAAOhQ,EAAe8Q,EAAUD,EAAYxZ,GAChEka,WAAYC,GAAkBxM,EAAKoD,GAAK/Q,GACxCoa,UAAWC,KACXC,SAAUC,GAAa5M,EAAMzD,EAAWC,EAAWmP,EAAetZ,GAClEnC,GAAI8P,EAAKoD,KAIXsJ,GAAgBA,KACX,CACHlc,UAAW,uCACXqc,IAAK,OAIPD,GAAeA,CACjB5M,EACAzD,EACAC,EACAmP,EACAtZ,KACA,IAAA4N,EACA,MACIiB,kBAAkB,QAAEnN,IACpB1B,EACEiQ,EACFtC,EAAKK,OAASL,EAAKK,MAAM9I,QAAQ,IAAIgL,OAAO,IAAIhG,KAAc,MAAO,IAAIhF,QAAQ,IAAIgL,OAAO,IAAI/F,KAAc,MAAO,IAEzHuE,EAAQ6B,cAAckK,MAAQ9M,EAAKoD,GACnC,MAAMN,GAAYC,EAAAA,EAAAA,wBAAuBxB,EAAmBR,GAG5D,4WAAA/B,CAAA,CACIxO,UAAW,uCACXqc,IAAK,IACL,aAAc,GAAGvK,MALW,QAAXrC,EAAAD,EAAKI,cAAM,IAAAH,GAAO,QAAPA,EAAXA,EAAaI,aAAK,IAAAJ,GAAlBA,EAAoBK,aAAevM,EAAQgZ,iBAAiBC,eAAehN,EAAKI,OAAOC,MAAMC,mBAAgBpJ,IAK/E,KAC/CqM,KAAMC,GAAcxD,EAAMzD,EAAWC,EAAWmP,IAC7C7I,IAILU,GAAgBA,CAACG,EAA8BpH,EAAmBC,EAAmBmP,KACvF,MAAMjE,EAAiB/D,EAAWtD,MAC7B9I,QAAQ,IAAIgL,OAAO,IAAIhG,KAAc,MAAO,IAC5ChF,QAAQ,IAAIgL,OAAO,IAAI/F,KAAc,MAAO,IACjD,OAAOmH,EAAWtD,OAASsD,EAAWP,IAChC6J,EAAAA,EAAAA,uBAAsBvF,EAAgB/D,EAAWP,GAA0BuI,OAAezU,GAC1F,IAGJuM,GAAsBA,CAACE,EAAoBpH,EAAmBC,KAChE,MAAM4I,EAAgBzB,EACjBpM,QAAQ,IAAIgL,OAAO,IAAIhG,KAAc,MAAO,YAC5ChF,QAAQ,IAAIgL,OAAO,IAAI/F,KAAc,MAAO,aAEjD,OAEIxL,EAAAA,cAAA,QAAMR,UAAU,sDAAsD6U,yBAAyBC,EAAAA,EAAAA,IAAgBF,MAIjHkH,GAAeA,CACjBtB,EACAhQ,EACA8Q,EACAD,EACAxZ,KACoB,IAAA6a,EAAAC,EAAAC,EAAAC,EAAAC,EACpB,MACIpM,kBAAkB,QAAEnN,IACpB1B,EAEJ,IAAK2Y,IAAUhQ,EACX,OACIhK,EAAAA,cAAA,QAAMR,UAAU,wDACZQ,EAAAA,cAAA,QAAMR,UAAU,gCAA8B,QAO1D,IAAI0Y,EAAe8B,EAMnB,OAJK3Y,EAAMkb,iBAAiBvS,EAAcsP,WAAmC,QAA1B4C,EAAIlS,EAAcpJ,gBAAQ,IAAAsb,GAAtBA,EAAwBrb,kBAC3EqX,GAAesE,EAAAA,EAAAA,GAAgBtE,EAAclO,EAAcpJ,SAASC,kBAIpEb,EAAAA,cAAA,OAAKR,UAAU,0CACXQ,EAAAA,cAACyc,EAAAA,eAAc,CACXvd,GAAI4b,EACJ9C,SAAU6C,EACV9X,QAASA,EACTgX,KAAM,CACFC,MAAO,CACHR,wBAAyBtB,EAAasB,0BAG9Cha,UAAU,6CACVkd,cAA8B,QAAjBP,EAAE9a,EAAM8O,iBAAS,IAAAgM,OAAA,EAAfA,EAAiBO,iBAElCrb,EAAMkb,iBAAiBvS,EAAcsP,YAAmC,QAA1B8C,EAAIpS,EAAcpJ,gBAAQ,IAAAwb,OAAA,EAAtBA,EAAwBvb,kBACxEb,EAAAA,cAAA,OAAKR,UAAU,2DACXQ,EAAAA,cAACyc,EAAAA,eAAc,CACXvd,GAAI4b,EACJ9C,SAAU6C,EACV9X,QAASA,EACTgX,KAAM,CACFC,MAAO,CACHR,wBAAyBQ,EAAMR,0BAGvCha,UAAU,iDACVkd,cAA8B,QAAjBL,EAAEhb,EAAM8O,iBAAS,IAAAkM,OAAA,EAAfA,EAAiBK,gBAEpC1c,EAAAA,cAAA,iBAEK6Q,EAAAA,EAAAA,SAAsB,QAAfyL,EAAAjb,EAAM8O,iBAAS,IAAAmM,OAAA,EAAfA,EAAiBK,eAAgB,WAAW7Z,EAAAA,EAAAA,GAAsBzB,EAAMkB,OAAQyH,EAAcnI,qBAAsBmI,QAQ9IwR,GAAoBA,CAACoB,EAAgBvb,KAAyD,IAAAwb,EAChG,MAAMhG,EAAY9C,SAAS6I,EAAQ,IAEnC,GAAIxY,MAAMyS,KAAexV,EAAMuV,KAC3B,OAAO,KAGX,IAAKvV,EAAM6O,iBAAiBnN,QAAQkT,QAAQrY,KAAKkB,gBAC7C,OAAO,KAGX,MAAM,GACFI,EAAE,SACF8Y,EAAQ,QACRjV,GACA1B,EAAM6O,iBACJlG,EAAgB3I,EAAM8Z,eAAe5R,MAAK9I,GAAWA,EAAQ6Y,WAAazC,IAC1EqB,EAAe7W,EAAM6Z,aAAa0B,GAExC,OACI5c,EAAAA,cAAC8c,EAAU,CACP5d,GAAIA,EACJ8Y,SAAUA,EACVjV,QAASA,EACToN,UAAW9O,EAAM8O,UACjB8H,gBAAiBpB,EACjB7M,cAAeA,EACfkO,aAAcA,EACdtB,KAAMvV,EAAMuV,KACZuB,UAAW9W,EAAM8W,UACjBqC,cAAenZ,EAAMmZ,cACrB1D,kBAAkC,QAAjB+F,EAAExb,EAAM8O,iBAAS,IAAA0M,OAAA,EAAfA,EAAiB/F,kBACpCnT,iBAAkBtC,EAAMsC,oBAI9B0X,GAAmBA,CAAC1I,EAA8BsI,EAAiB5Z,KACrE,MACI6O,kBACInN,SACIkT,SAAS,aAAE8G,IAEftQ,QAAQ,cAAEuQ,KAEd3b,EAKJ,GAJI2b,IACAA,EAAcC,iBAAkB,IAG/BtK,IAAeA,EAAWzD,SAE3B,OADA7N,EAAMmO,UAAUC,MAAM,2DACf,KAGX,MAAMyN,EAAuC,CACzCC,UAAW,CACPC,GAAI,CAAEC,EAAG,uBAAwBC,EAAG,GAAIC,EAAG,IAC3CC,GAAI,CAAEH,EAAG,uBAAwBC,EAAG,GAAIC,EAAG,IAC3CE,GAAI,CAAEJ,EAAG,uBAAwBC,EAAG,GAAIC,EAAG,IAC3CG,GAAI,CAAEL,EAAG,uBAAwBC,EAAG,GAAIC,EAAG,IAC3CI,GAAI,CAAEN,EAAG,uBAAwBC,EAAG,GAAIC,EAAG,KAE/CK,UAAU,EACVX,iBAAiB,GAOrB,OAJID,IACAA,EAAcG,UAAYD,EAAqBC,WAI/Cnd,EAAAA,cAAC6d,EAAAA,GAAK,CACFhf,eAAgBwC,EAAM6O,iBAAiBnN,QAAQ4X,cAAc9b,eAC7Doc,QAASA,EACTzb,UAAU,2CACVuW,IAAKpD,EAAWzD,SAChB6N,aAAcA,EACdC,cAAeA,GAAgCE,EAC/CY,oBAAoB,WCtRzB,IAAWC,IAAlB,SAAkBA,GACdA,EAAA,kBACAA,EAAA,kBACAA,EAAA,gCAHJ,CAAkBA,KAAAA,GAAqC,+mBCxDvD,MAAMC,GAAiB,2BACvB,IAAIC,GAEJvf,eAAewf,KAIX,OAHKD,KACDA,SAAqB,oDAElBA,GAoBX,MAAME,GAA6C,CAC/CC,qBAAsB,0BACtBC,oBAAqB,wBACrBC,QAAS,aACTC,aAAc,wBACdC,aAAc,gBACdC,MAAO,SAkLX,GA/KwBpd,IACpB,MAAM,QAAE0B,EAAO,YAAE2b,GAAgBrd,EAC3B8O,EAASnC,GAAAA,GAAA,GAAQmQ,IAAqB9c,EAAM8O,YAC3CwO,EAASC,GAAc5e,EAAAA,cAA2CkG,IAClE2Y,EAASC,GAAc9e,EAAAA,UAAe,IACtCyP,EAAOsP,GAAY/e,EAAAA,cAAmCkG,IACtD8Y,EAAkBC,GAAuBjf,EAAAA,cAAmCkG,GAE7EgZ,EAAUlf,EAAAA,OAAiC,MAEjDA,EAAAA,WAAgB,KACZ,IAAK0e,EAAa,KAAAS,EACmBC,EAAjC,GAAmB,QAAnBD,EAAID,EAAQG,eAAO,IAAAF,GAAfA,EAAiBG,WACF,QAAfF,EAAAF,EAAQG,eAAO,IAAAD,GAAfA,EAAiBG,OAAOzP,MAAK,KAAK,IAAA0P,EACf,QAAfA,EAAAN,EAAQG,eAAO,IAAAG,GAAfA,EAAiBC,WAMzB,OAHAX,GAAW,GACXC,OAAS7Y,QACT+Y,OAAoB/Y,GAIxB,GAAIyY,EAAS,CACTG,GAAW,GAEX,MAAMY,EAAWC,aAAaC,QAAQ,0BAKtC,YAJIF,GAAYf,EAAQkB,MAAKC,GAAKA,EAAE5gB,KAAOwgB,KACvCT,EAAoBS,IAOfhhB,WACT,MAAM,YAAEqhB,SAAsB7B,KAE9B,IACI,MAAMS,QAAgBoB,EAAYC,aAClCpB,EAAWD,EAAQxS,OAAS,EAAIwS,OAAUzY,GAiBnB,IAAnByY,EAAQxS,OACR4S,EAAS5O,EAAUiO,sBACO,IAAnBO,EAAQxS,QACf8S,EAAoBN,EAAQ,GAAGzf,IAGnC,MAAMwgB,EAAWC,aAAaC,QAAQ,0BAClCF,GAAYf,EAAQkB,MAAKC,GAAKA,EAAE5gB,KAAOwgB,KACvCT,EAAoBS,GAE1B,MAAOjQ,GACLwQ,QAAQxQ,MAAM,wBAAyBA,GACvCsP,EAAS5O,EAAUkO,qBACrB,QACES,GAAW,KAGdoB,KACN,CAACxB,IAEJ1e,EAAAA,WAAgB,KACZ,IAAKgf,EAAkB,KAAAmB,EACcC,EAAjC,GAAmB,QAAnBD,EAAIjB,EAAQG,eAAO,IAAAc,GAAfA,EAAiBb,WACF,QAAfc,EAAAlB,EAAQG,eAAO,IAAAe,GAAfA,EAAiBb,OAErB,OAGS7gB,WACT,MAAM,YAAEqhB,SAAsB7B,KAE9BgB,EAAQG,QAAU,IAAIU,EAAY/B,IAC7BkB,EAAQG,QAAQgB,MAAMrB,EAAkB,CACzCsB,IAAK,GAELC,MAAOA,CAACC,EAAiBC,KACrB,MACMC,EAAc3f,KAAK4f,IAAIH,EAAiBC,GACxCG,EAAY7f,KAAK4f,IAAI5f,KAAK8f,MAFN,GAEYH,GAAkC,KACxE,MAAO,CACHrK,MAAOuK,EACPtK,OAAQsK,KAGjBE,OAAe5a,IAEjBga,KACN,CAAClB,IAEJ,MAAM8B,EAAiBC,IAEnB1f,EAAM2f,QAAQD,IAGZxZ,EAAgB,qBAChB0Z,GAAqBpC,IAAYpP,GAASkP,GAAWK,EAQ3D,OACIhf,EAAAA,cAACkhB,EAAAA,MAAK,CAACC,eAAgB,GAAG5Z,aAA0B/H,UAAU,8CAA8CuY,OAAQ2G,EAAa0C,OAAQ/f,EAAMggB,SAC3IrhB,EAAAA,cAACshB,EAAAA,UAAS,CAAC9hB,UAAWyhB,EAAoB,cAAW/a,GACjDlG,EAAAA,cAAA,OAAKuhB,MAAO,CAAEC,QAAS3C,EAAU,QAAU,SAAW1O,EAAUmO,SAEhEte,EAAAA,cAAA,OAAKuhB,MAAO,CAAEC,QAAS/R,EAAQ,QAAU,SAAWA,GAEpDzP,EAAAA,cAAA,OAAKuhB,MAAO,CAAEC,QAAU3C,GAAYpP,IAASkP,GAAYK,EAA6B,OAAV,UACxEhf,EAAAA,cAAA,OAAKR,UAAW,GAAG+H,cAA2B4I,EAAUoO,cACxDve,EAAAA,cAAA,MAAIR,UAAW,GAAG+H,2BACboX,MAAAA,OAAO,EAAPA,EAAS5P,KAAI,CAAC0S,EAAQC,IACnB1hB,EAAAA,cAAA,MAAI+I,IAAK2Y,GACL1hB,EAAAA,cAAC8V,EAAAA,OAAM,CAAC1N,QAASA,KAAMuZ,OAlB3BjC,EAkB0C+B,EAAOviB,GAjBrE+f,EAAoBS,QAEpBC,aAAaiC,QAAQ,yBAA0BlC,GAH3BA,IAAAA,IAmBQ1f,EAAAA,cAAA,YAAOyhB,EAAOhiB,OACdO,EAAAA,cAAA,OAAK+V,KAAKC,EAAAA,EAAAA,IAAS,wBAAyBjT,EAAQkT,SAAUK,OAAQ,GAAID,MAAO,aAOrGrW,EAAAA,cAAA,OAAKuhB,MAAO,CAAEC,QAASP,EAAoB,QAAU,OAAQY,SAAU,WAAYxL,MAAO,SACtFrW,EAAAA,cAAA,OAAKd,GAAI8e,GAAgBuD,MAAO,CAAElL,MAAO,YAajDrW,EAAAA,cAAC8hB,EAAAA,YAAW,KACR9hB,EAAAA,cAAC8V,EAAAA,OAAM,CACHtW,UAAW,GAAG+H,uBACda,QAASA,IAAM6W,OAAoB/Y,GACnCqb,MAAO,CAAEC,QAASxC,KAAqBL,MAAAA,OAAO,EAAPA,EAASxS,SAAU,GAAK,EAAI,QAAU,SAE5EgE,EAAUqO,cAEfxe,EAAAA,cAAC8V,EAAAA,OAAM,CAACtW,UAAW,GAAG+H,gBAA6Ba,QAAUO,IACzDA,EAAE+P,kBACF/P,EAAEoZ,YAAYC,2BACd3gB,EAAMggB,YAELlR,EAAUsO,mlBC1H/B,MAAMwD,WAAejiB,EAAAA,UAgCjBtC,YAAmB2D,GACfC,MAAMD,GAxBO,KAAAkK,UAAoB,IAEpB,KAAAC,UAAoB,IAEpB,KAAA0W,SAAmB,IAiB5B,KAAA/J,UAAY,IAAIgK,GAAAA,EAAO,CAAEC,YAAa,IA2R7B,KAAAC,eAAiB,KAC9B,MAAMC,EAAcxkB,KAAKuD,MAAM8O,UAAUoS,gCACzC,OAAOviB,EAAAA,cAACwiB,EAAAA,EAAO,CAAChjB,UAAU,iCAAiCC,MAAO6iB,EAAaG,KAAMC,EAAAA,EAAYC,OAAQC,cAAc,WAI1G,KAAAC,gBAAmBla,IAChC,MAAM,YAAEsH,GAAgBnS,KAAK6G,MAEzBsL,GAAeA,EAAYV,kBAAuD,OAAnC5G,EAAErI,OAAOmY,QAAQ,eAChE3a,KAAKglB,0BAII,KAAAC,OAAUpa,IACvB,MAAM,YAAEsH,GAAgBnS,KAAK6G,MAEzBsL,GAAeA,EAAYV,kBAAoB5G,EAAEqa,UAAYC,EAAAA,SAASC,QACtEplB,KAAKglB,yBAKAhlB,KAAKqlB,cAAc9D,SAAWvhB,KAAKqlB,cAAc9D,QAAQ+D,SAAUza,EAAErI,SACrExC,KAAKulB,qBAAqBhE,SAAWvhB,KAAKulB,qBAAqBhE,QAAQ+D,SAAUza,EAAErI,SAGpF2P,GAAeA,EAAYV,kBAC3BzR,KAAKglB,0BAKA,KAAAA,uBAAyB,KACtC,MACI/f,SAAS,cAAE4X,GACXZ,MAAM,YAAEuJ,IACRxlB,KAAKuD,MAELvD,KAAKgX,gBAAgBuK,SAAWvhB,KAAKgX,gBAAgBuK,QAAQ7W,MAAM2D,OAAS,IAC5EmX,EAAYlY,WAAa,GACzBkY,EAAYC,sBAAwB,GACpCD,EAAYE,2BAA6B,GACzC7I,GAAgBA,EAAc8I,QAAOC,EAAAA,EAAAA,IAAuBJ,GAAcA,GAC1ExlB,KAAKgX,gBAAgBuK,QAAQ7W,MAAQ,IAGzC1K,KAAK4F,SAAS,CAAE0H,WAAY,GAAI6E,iBAAa/J,EAAW8M,oBAAgB9M,EAAWuL,oBAAqB,MA2G3F,KAAAkS,mBAAsB5lB,MAC9BA,GAASA,EAAMoO,QAAUrO,KAAKkX,WAC/BlX,KAAK4F,SAAS,CAAE0H,WAAYrN,IAG5BD,KAAK8lB,qBACL9lB,KAAK8lB,oBAAoBC,SAG7B,MAAM,QACF9gB,EACAgX,MAAM,YAAEuJ,IACRxlB,KAAKuD,MAET,GAAI0B,EAAS,CACT,GAAIhF,GAASA,EAAMoO,OAAS,EAAG,CAC3B,GAAIpO,EAAMoO,OAASrO,KAAKkX,SACpB,OAGA8O,EAAAA,gBAAgBC,YAAYjmB,KAAKkmB,sBACjClmB,KAAKmmB,iBAAiBlmB,GAG1BulB,EAAYlY,WAAarN,OAEzBD,KAAK4F,SAAS,CAAEuM,iBAAa/J,EAAW8M,oBAAgB9M,IACxDod,EAAYlY,WAAa,GAE7BrI,EAAQ4X,cAAc8I,QAAOC,EAAAA,EAAAA,IAAuBJ,GAAcA,KA2BzD,KAAAY,cACbvb,IAEA,MACI8D,QAAQ,oBAAEwI,GACVlS,SAAS,cACL4X,EACAnO,KACIC,QAAQ,2BAAE+W,MAGlB1lB,KAAKuD,MAEHtD,EAAQD,KAAKgX,gBAAgBuK,SAAWvhB,KAAKgX,gBAAgBuK,QAAQ7W,MAG3E,GAFAG,MAAAA,GAAAA,EAAGM,kBAEElL,GAAUA,GAA0B,IAAjBA,EAAMoO,QAAiB8I,EAC3CnX,KAAKgX,iBAAmBhX,KAAKgX,gBAAgBuK,SAAWvhB,KAAKgX,gBAAgBuK,QAAQ8E,YAClF,CACH,MAAMpR,EAAYyQ,GAA8B,IAC1CY,EAAYtmB,KAAKumB,oBAAmBC,EAAAA,EAAAA,IAAW,SAAU3J,IAAkB,GAAI5c,EAAOgV,GAC5FwR,SAASjR,SAASf,KAAO6R,IAIhB,KAAAI,0BAA4B,KACzC,MAAM,YAAEvU,GAAgBnS,KAAK6G,MAEzBsL,GAAeA,EAAYV,kBAC3BzR,KAAKglB,yBAIThlB,KAAK4F,SAAS,CACV0H,WAAY,GACZqZ,gBAAgB,EAChBhT,oBAAqB,MAIZ,KAAAiT,0BAA4B,KACzC5mB,KAAK4F,SAAS,CAAEihB,kBAAkB,KAGrB,KAAAC,2BAA6B,KAC1C,MAAM,YAAE3U,GAAgBnS,KAAK6G,MACvBsL,GAAeA,EAAYV,kBAC7BzR,KAAKglB,0BAII,KAAAuB,mBAAqB,CAACQ,EAAe9mB,EAAe+mB,KACjE,IAAK7R,EAAAA,GAASC,UACV,MAAO,GAGX,MAAMC,EAAW,IAAIC,IAAIyR,EAAOxR,OAAOC,SAASf,MAKhD,OAJIuS,GAAO/mB,GACPoV,EAASI,aAAaC,IAAIsR,EAAK/mB,GAG5BoV,EAASZ,MAGH,KAAAwS,2BAA8BC,IAC3C,GAAsD,OAAlDlnB,KAAKmnB,iCAAiC5F,QAAkB,CACxD,MAAM6F,EAAiBpnB,KAAKmnB,iCAAiC5F,QACvD8F,EAAsBrnB,KAAKuD,MAAM8O,UAAUiV,wBAC3CC,EAAoBvnB,KAAKuD,MAAM8O,UAAUmV,wBAI/C,OAHAJ,EAAeK,UACXP,GAAUA,EAAOzV,kBAAoByV,EAAOzV,iBAAiBpD,OAAS,EAAIgZ,EAAsBE,EACpGH,EAAeM,aAAa,YAAa,aAClCN,EAAeK,UAE1B,MAAO,IAGM,KAAAE,eAAiB/mB,MAAO+B,EAAiC0C,KAAkD,IAAAuiB,EACxH,MAAM,QAAE3iB,EAAO,KAAEgX,EAAI,UAAE5J,GAAcrS,KAAKuD,MAIpCskB,EAAwC,QAAzBD,EAAG5nB,KAAK6G,MAAMsL,mBAAW,IAAAyV,GAAkB,QAAlBA,EAAtBA,EAAwBnW,wBAAgB,IAAAmW,OAAA,EAAxCA,EAClB3jB,QAAOC,GAAKA,EAAEoQ,IAA2B,YAArBpQ,EAAEiJ,iBAAiCnN,KAAK6G,MAAMihB,qBAAqBrc,MAAKsc,GAAKA,EAAEvM,WAAavF,SAAS/R,EAAEoQ,GAAK,QAEtI,GAAIuT,GAAmBA,EAAgBxZ,OAAS,EAAG,CAE/C,MAAM2Z,QAAsBC,EAAAA,GAAAA,uBACxB,CAAEhY,cAAehL,EAAQ4X,eACzB,CACIvO,QAAS,CACLG,WAAWP,EAAAA,EAAAA,IAAajJ,EAAQ4X,cAAc9b,gBAC9CwN,WAAYtJ,EAAQ4X,cAAc9b,eAAelB,YAAY2O,WAEjE0Z,IAAKL,EAAgB5W,KAAI/M,GAAK+R,SAAS/R,EAAEoQ,GAAK,MAC9C6T,mBAAmB,IAG3BnoB,KAAK4F,SAAS,CAAEkiB,qBAAsB,IAAI9nB,KAAK6G,MAAMihB,wBAAyBE,KAGlF,OAAOI,EAAAA,GAAAA,GACHnjB,EACAgX,EAAKoM,eAAenB,OACpBlnB,KAAK6G,MAAMihB,qBAAqBrc,MAAKvH,GAAKA,EAAEsX,WAAa7Y,EAAQ6Y,WACjEnJ,EAAUiJ,yBAID,KAAAgN,kBAAoB,CAACnO,EAAyB9W,KAC3DrD,KAAK4F,UAAU2iB,IAAS,CACpB9J,iBAAgBvO,GAAAA,GAAA,GAAQqY,EAAU9J,kBAAgB,IAAE,CAACtE,GAAkB9W,SAI9D,KAAAmlB,oBAAsB,IAE/BtmB,EAAAA,cAACumB,GAAc,CACXxjB,QAASjF,KAAKuD,MAAM0B,QACpB2b,YAAa5gB,KAAK6G,MAAMggB,iBACxBtD,QAASA,IAAMvjB,KAAK4F,SAAS,CAAEihB,kBAAkB,IACjD3D,QAAUrQ,IACN7S,KAAK6lB,mBAAmBhT,GACxB7S,KAAKomB,mBAAche,GACnBpI,KAAK4F,SAAS,CAAEihB,kBAAkB,KAEtCxU,UAAW,CACPiO,qBAAsBtgB,KAAKuD,MAAM8O,UAAUqW,yBAC3CnI,oBAAqBvgB,KAAKuD,MAAM8O,UAAUsW,wBAC1CnI,QAASxgB,KAAKuD,MAAM8O,UAAUoS,gCAC9BhE,aAAczgB,KAAKuD,MAAM8O,UAAUuW,iBACnClI,aAAc1gB,KAAKuD,MAAM8O,UAAUwW,iBACnClI,MAAO3gB,KAAKuD,MAAM8O,UAAUyW,wBA7mBxC9oB,KAAKgX,gBAAkB9U,EAAAA,YACvBlC,KAAKmnB,iCAAmCjlB,EAAAA,YACxClC,KAAKulB,qBAAuBrjB,EAAAA,YAC5BlC,KAAKqlB,cAAgBnjB,EAAAA,YACrBlC,KAAK6G,MAAQ,CACTyG,WAAY,GACZyb,0BAA2B,kCAC3BC,0BAA2B,kCAC3BC,2BAA4B,mCAC5B9W,iBAAa/J,EACb8M,oBAAgB9M,EAChB8gB,qBAAsB,GACtBvC,gBAAgB,EAChBwC,sBAAsB,EACtB/L,aAAc,GACdC,eAAgB,GAChByK,qBAAsB,GACtBrJ,iBAAkB,GAClBoI,kBAAkB,GAEtB7mB,KAAKkX,SACAlX,KAAKuD,MAAM0B,SACRjF,KAAKuD,MAAM0B,QAAQyJ,KACnB1O,KAAKuD,MAAM0B,QAAQyJ,IAAIC,QACvB3O,KAAKuD,MAAM0B,QAAQyJ,IAAIC,OAAOya,sBAClC,GAEJppB,KAAKkmB,oBAAsB,GAC3BlmB,KAAK4N,gBAAkB5N,KAAKuD,MAAMoL,QAAU3O,KAAKuD,MAAMoL,OAAOf,gBAAkB5N,KAAKuD,MAAMoL,OAAOf,gBAAkB,EACpH5N,KAAKqpB,gBAAkB,kBACvBrpB,KAAKyS,kBAAmB6W,EAAAA,EAAAA,oBACpBtpB,KAAKuD,MAAM0B,QAAQkT,QAAQoR,kBAC3BvpB,KAAKuD,MAAMimB,aACXxpB,KAAKuD,MAAMmO,WAGf1R,KAAKypB,uBAGF,0BACHhD,SAASiD,MAAQjD,SAASiD,KAAKC,iBAAiB,YAAa3pB,KAAK+kB,iBAClExP,QAAUA,OAAOoU,iBAAiB,QAAS3pB,KAAKilB,QAG7C2E,uBACHnD,SAASiD,MAAQjD,SAASiD,KAAKG,oBAAoB,YAAa7pB,KAAK+kB,iBAAiB,GACtFxP,QAAUA,OAAOsU,oBAAoB,QAAS7pB,KAAKilB,QAAQ,GAGxD6E,qBACE9pB,KAAK+pB,mBACL/pB,KAAKgqB,qBAGPC,sBAAsBC,EAAsDC,GAC/E,OAAInqB,KAAK6G,QAAUsjB,GAAanqB,KAAKuD,QAAU2mB,EAO5ChhB,SAAM,IAAAkhB,EAAAC,EAAAC,EACT,MAAM,QACFrlB,EACAoN,WAAW,mBAAEkY,EAAkB,mBAAEC,EAAkB,mBAAEC,GACrD9b,QAAQ,oBAAEwI,EAAmB,sBAAEuT,EAAqB,2BAAEC,EAA0B,UAAEjpB,EAAY,KAC9F1B,KAAKuD,OAEH,WACF+J,EAAU,0BACVyb,EAAyB,0BACzBC,EAAyB,2BACzBC,EAA0B,YAC1B9W,EAAW,eACX+C,EAAc,qBACdiU,GACAnpB,KAAK6G,MAEHoO,EAAahQ,GAAWA,EAAQyJ,KAAOzJ,EAAQyJ,IAAIC,QAAU1J,EAAQyJ,IAAIC,OAAO+W,4BAA+B,IAC/G1Q,GAAgBwR,EAAAA,EAAAA,IAAW,SAAUvhB,GAAWA,EAAQ4X,gBAAkB,GAC1EyJ,EAAYtmB,KAAKumB,mBAAmBvR,EAAe1H,EAAY2H,GAC/D8B,EAAoB2T,GAAyBA,EAAsBrc,OAAS,EAAIqc,EAAwB,qBAExGE,EAAqBzY,MAAAA,GAA6B,QAAlBiY,EAAXjY,EAAaV,wBAAgB,IAAA2Y,OAAA,EAA7BA,EAA+BnmB,QACtD4Q,GAAcA,EAAW1H,iBAAmBA,EAAe0d,SAAWhW,EAAW1H,iBAAmBA,EAAe2d,OAEjHC,EAAqB5Y,MAAAA,GAA6B,QAAlBkY,EAAXlY,EAAaV,wBAAgB,IAAA4Y,OAAA,EAA7BA,EAA+BpmB,QACtD4Q,GAAcA,EAAW1H,iBAAmBA,EAAe6d,UAEzDrV,EAAmBT,MAAAA,OAAc,EAAdA,EAAgBzJ,MAAKsK,GACnCA,EAAQF,cAAgB/F,EAAAA,qBAAqBgG,WAElDmV,EAAsB9Y,MAAAA,GAA6B,QAAlBmY,EAAXnY,EAAaV,wBAAgB,IAAA6Y,OAAA,EAA7BA,EAA+BrmB,QAAO4Q,IAAa,IAAAE,EAC3E,GAAIF,EAAW1H,iBAAmBA,EAAe2I,SAC7C,OAAO,EAEX,MAAMC,EAAUJ,MAAAA,GAAwB,QAARZ,EAAhBY,EAAkBK,cAAM,IAAAjB,OAAA,EAAxBA,EAA0BtJ,MAAKyF,IAAO,IAAAga,EAClD,MAAO,GAAuB,QAAvBA,EAAGha,EAAK/B,uBAAe,IAAA+b,EAAAA,EAAI,MAAQrW,EAAWP,MAGzD,OAAQ6W,EAAAA,iBAAiBC,kBAAkBrV,MAGzCsV,EAASnb,GAAAA,GAAA,GACPlQ,KAAKuD,OAAmD,IAE5D4gB,OAAQ,CACJmH,YAAatrB,KAAKuD,MAClB7B,UAAW,GAAGU,GAAAA,CAAW,YAAaV,MAAcyV,EAAsB,YAAc,iBAE5FoU,qBAAsB,CAClBxN,IAAK,MACLrc,UAAW,iCACX,YAAa,YACboK,IAAK9L,KAAKmnB,kCAEdqE,yBAA0BxrB,KAAK6G,MAAMqiB,qBACrC5b,WAAYtN,KAAK6G,MAAMyG,WACvBme,YAAa,CACT3f,IAAK9L,KAAKulB,qBACV7jB,UAAWU,GAAAA,CAAW,yBAA0B,CAAEspB,KAAM1rB,KAAK6G,MAAM8M,oBAAqBgY,MAAO3rB,KAAK6G,MAAM8M,uBAE9GiY,eAAgB,CACZlqB,UAAWqnB,GAEf8C,eAAgB,CACZnqB,UAAWsnB,GAEf8C,gBAAiB,CACbpqB,UAAWunB,GAEf8C,WAAY,CACRrqB,UAAW,GAAG1B,KAAKqpB,mBAEvB2C,YAAa,CACTjO,IAAK,OACLjS,IAAK9L,KAAKqlB,cACV3jB,UAAW,wBACX,aAAc,SACdkW,KAAM,aACN/L,KAAM,SACNxK,OAAQilB,EACR2F,aAAc,MACdC,SAAUlsB,KAAKomB,eAEnB+F,UAAW,CACPpO,IAAK,KACLrc,UAAWU,GAAAA,CAAW,wCAAyCV,IAEnE0qB,UAAW,CACPrO,IAAK,KACLrc,UAAWU,GAAAA,CAAW,wCAAyCV,IAEnE2qB,WAAY,CACRtO,IAAK,KACLrc,UAAWU,GAAAA,CAAW,yCAA0CV,IAEpE4qB,KAAMxV,EAAc,CAChB7R,QAASjF,KAAKuD,MAAM0B,QACpBqS,gBAAiBiT,EACjBhT,gBAAiBiT,EACjBhT,gBAAiBiT,EACjBzT,gBAAiBhX,KAAKgX,gBACtBG,oBAAAA,EACAF,kBAAmBjX,KAAK6lB,mBACxBzO,yBAA0BpX,KAAK0mB,0BAC/BrP,yBAA0BrX,KAAK4mB,0BAC/B1P,SAAUlX,KAAKkX,SACfjC,UAAAA,EACA8B,kBAAAA,EACA9W,MAAOqN,IAEXif,mBACIjf,GACAA,EAAWe,OAAS,IACnB8a,GAAyByB,GAAsB5E,EAAAA,gBAAgBC,YAAY2E,IACtEnS,EAA4B,CACxBsQ,0BAAAA,EACA/T,cAAAA,EACAC,UAAAA,EACAxH,UAAWzN,KAAKyN,UAChBC,UAAW1N,KAAK0N,UAChB0E,iBAAkBpS,KAAKuD,MACvB+J,WAAAA,EACAqG,oBAAqB3T,KAAK6G,MAAM8M,oBAChCxB,YAAayY,EACbnY,iBAAkBzS,KAAKyS,wBAE3BrK,EACVokB,mBACIlf,GACAA,EAAWe,OAAS,IACnB8a,GAAyB4B,GAAsB/E,EAAAA,gBAAgBC,YAAY8E,IACtEnO,EAA4B,CACxBoM,0BAAAA,EACAhU,cAAAA,EACAC,UAAAA,EACAxH,UAAWzN,KAAKyN,UAChBC,UAAW1N,KAAK0N,UAChB0E,iBAAkBpS,KAAKuD,MACvB+J,WAAAA,EACA6E,YAAa4Y,EACbrZ,UAAW1R,KAAKuD,MAAMmO,UACtBqL,WAAY/c,KAAKuD,MAAM2W,SACvB8C,SAAUhd,KAAKuD,MAAMnC,GACrBqR,iBAAkBzS,KAAKyS,iBACvBhO,OAAQzE,KAAKuD,MAAM0B,QAAQkT,QAAQ1T,OACnC4N,UAAWrS,KAAKuD,MAAM8O,UACtB+K,aAAcpd,KAAK6G,MAAMuW,aACzBC,eAAgBrd,KAAK6G,MAAMwW,eAC3BvE,KAAM9Y,KAAKuD,MAAM0Y,KAAKnD,KAAKoO,OAC3B7M,UAAWra,KAAKqa,UAChBoE,iBAAkBze,KAAK6G,MAAM4X,iBAC7B/B,cAAe1c,KAAK2nB,eACpB9hB,iBAAkB7F,KAAKsoB,yBAE3BlgB,EACVqkB,oBACInf,GACAA,EAAWe,OAAS,IACnB8a,GAAyB8B,GAAuBjF,EAAAA,gBAAgBC,YAAYgF,IACvE/Y,EAA6B,CACzB+W,2BAAAA,EACAjU,cAAAA,EACAC,UAAAA,EACAxH,UAAWzN,KAAKyN,UAChBC,UAAW1N,KAAK0N,UAChB0E,iBAAkBpS,KAAKuD,MACvB+J,WAAAA,EACA6E,YAAa8Y,EACb/V,eAAAA,EACAzC,iBAAkBzS,KAAKyS,iBACvBW,mBAAoBuX,EACpBhX,oBAAqB3T,KAAK6G,MAAM8M,oBAChCS,+BAAgCpU,KAAKuD,MAAM8O,UAAU+B,+BACrDC,qCAAsCrU,KAAKuD,MAAM8O,UAAUgC,qCAC3DR,6BAA8B7T,KAAKuD,MAAM8O,UAAUwB,oCAEvDzL,EACVskB,UAAW,CACPtV,yBAA0BpX,KAAK0mB,0BAC/BiG,0BAA2B3sB,KAAK8mB,4BAEpCqC,qBAAAA,EACAyD,cAAe5sB,KAAKukB,iBACpB5Q,oBAAqB3T,KAAK6G,MAAM8M,oBAChCkZ,aAAc7sB,KAAKwoB,wBAGvB,OAAOxoB,KAAKuD,MAAMupB,WAAWzB,GAGzB5B,uBACJ,MAAMsD,EAAkB/sB,KAAKuD,MAAMoL,OAAOqe,wBAEpC7a,EAAc6T,EAAAA,gBAAgBiH,OAAOjH,EAAAA,gBAAgBkH,YAAYH,IACvE,IAAK/G,EAAAA,gBAAgBC,YAAY9T,GAM7B,YALAnS,KAAKkmB,oBAAsB,CACvB,CAAE/Y,eAAgB8S,GAAsCkN,SACxD,CAAEhgB,eAAgB8S,GAAsCtd,SACxD,CAAEwK,eAAgB8S,GAAsCmN,kBAKhE,MAAMC,EAAmBlb,EAAYlO,QAAO4Q,GAAcA,EAAW1H,iBACjE6Y,EAAAA,gBAAgBC,YAAYoH,GAC5BrtB,KAAKkmB,oBAAsBmH,EAI/BrtB,KAAKkmB,oBAAsB,GAyDvB,yBAAsB,IAAAoH,EAC1B,MAAM,QAAEroB,GAAYjF,KAAKuD,MACnBgqB,EAAsC,QAAzBD,EAAGttB,KAAK6G,MAAMsL,mBAAW,IAAAmb,GAAkB,QAAlBA,EAAtBA,EAAwB7b,wBAAgB,IAAA6b,OAAA,EAAxCA,EAA0CrpB,QAAOC,GAA0B,YAArBA,EAAEiJ,iBAAiCnN,KAAK6G,MAAMuW,aAAalZ,EAAEoQ,MACnIkZ,EAAkC,CAAEjf,WAAYtJ,EAAQkT,QAAQtY,YAAY2O,UAAWC,UAAWxJ,EAAQkT,QAAQtY,YAAYoO,WAEpI,IAAKsf,GAA0C,IAAzBA,EAAclf,OAChC,OAGJ,MAAMof,QAAeC,EAAAA,GAAAA,sBAAqB,CAAEzd,cAAehL,EAAQ4X,eAC/D2Q,EACAD,EAActc,KAAI/M,IAAMA,EAAEoQ,KAC1B,IAAIqZ,KACJ,UACAvlB,GACA,GAEEwlB,EAAe1d,GAAA,GAAQlQ,KAAK6G,MAAMuW,cACxCqQ,EAAO9W,SAAQzS,IACPA,EAAEmV,WAAanV,EAAEwX,0BACjBkS,EAAgB1pB,EAAEmV,UAAUpQ,YAAc/E,MAIlDlE,KAAK4F,SAAS,CAAEwX,aAAcwQ,IAG1B,2BAAwB,IAAAC,EAC5B,MAAM,QAAE5oB,GAAYjF,KAAKuD,MACnBskB,EAAwC,QAAzBgG,EAAG7tB,KAAK6G,MAAMsL,mBAAW,IAAA0b,GAAkB,QAAlBA,EAAtBA,EAAwBpc,wBAAgB,IAAAoc,OAAA,EAAxCA,EAClB5pB,QAAOC,GAAKA,EAAEoQ,IAA2B,YAArBpQ,EAAEiJ,iBAAiCnN,KAAK6G,MAAMwW,eAAe5R,MAAKsc,GAAKA,EAAEvM,WAAavF,SAAS/R,EAAEoQ,GAAK,QAEhI,IAAKuT,GAA8C,IAA3BA,EAAgBxZ,OACpC,OAGJ,MAAMgP,QAAuByQ,EAAAA,oBAAAA,cACzB,CAAE7d,cAAehL,EAAQ4X,eACzB5X,EAAQkT,QAAQtY,YAAY2O,UAC5BqZ,EAAgB5jB,QAAOC,GAAKA,EAAEoQ,KAAIrD,KAAI/M,GAAK+R,SAAS/R,EAAEoQ,GAAK,OAEzDyZ,EAAoB,IAAK/tB,KAAK6G,MAAMwW,kBAAmBA,GAE7Drd,KAAK4F,SAAS,CAAEyX,eAAgB0Q,IAG5B,4BAA4BC,EAAkC/tB,GAClE,IACI,MAAM2Q,QAA0Bqd,EAC5B,IAAI5gB,EAAiBpN,EAAOD,KAAK4N,gBAAiB5N,KAAKkuB,qBAAsBluB,KAAKyN,UAAWzN,KAAK0N,WAClG1N,KAAKuD,MAAM0B,QAAQ4X,eAEvB,GAAImR,IAA6BhuB,KAAKguB,yBAClC,OAEJ,OAAOpd,EACT,MAAOe,GACL,GAAIqc,IAA6BhuB,KAAKguB,yBAClC,OAKJ,OAHAhuB,KAAK4F,SAAS,CAAEuM,iBAAa/J,EAAW8M,oBAAgB9M,EAAW8gB,qBAAsBlpB,KAAKinB,+BAC9FjnB,KAAKuD,MAAMmO,UAAUyc,UAAUxc,QAC/B3R,KAAKuD,MAAMmO,UAAU0c,MAAM,uCAK3B,4BAA4BJ,EAAkC/tB,EAAekS,GACjF,IACI,MAAMyD,QAAiB5V,KAAKquB,mBAAmBpuB,GAC/C,GAAI+tB,IAA6BhuB,KAAKguB,yBAClC,OAEJhuB,KAAK4F,SAAS,CACVuM,YAAAA,EACA+C,eAAgBU,EAChBsT,qBAAsBlpB,KAAKinB,2BAA2B9U,GACtDgX,sBAAsB,EACtBxV,oBAAqB1T,IAE3B,MAAO0R,GACL,GAAIqc,IAA6BhuB,KAAKguB,yBAClC,OAEJhuB,KAAK4F,SAAS,CAAEuM,YAAAA,EAAa+C,oBAAgB9M,EAAW8gB,qBAAsBlpB,KAAKinB,2BAA2B9U,KAC9GnS,KAAKuD,MAAMmO,UAAUyc,UAAUxc,GAC/B3R,KAAKuD,MAAMmO,UAAU0c,MAAM,mCAI3BjI,iBAAiBlmB,GACrBD,KAAK8lB,oBAAsBwI,GAAAA,EAAS1tB,UAChCZ,KAAK4F,SAAS,CAAEujB,sBAAsB,IACtC,MAAM6E,EAA2BO,EAAAA,OAAOC,KAAKC,eAC7CzuB,KAAKguB,yBAA2BA,EAChC,MAAMpd,QAA0B5Q,KAAK0uB,sBAAsBV,EAA0B/tB,SAC/ED,KAAK2uB,sBAAsBX,EAA0B/tB,EAAO2Q,KACnE5Q,KAAKokB,UAERwK,YAAW,KACP5uB,KAAK8lB,wBACN,GAoCCoI,qBAIJ,OAH0CluB,KAAKkmB,oBAAoBjV,KAC/D4d,GAAsBA,EAAmB1hB,eAAgB2hB,OAAO,GAAGlb,cAAgBib,EAAmB1hB,eAAgBwL,MAAM,KAEjGoW,KAAK,KAGhC,yBAAyBzhB,GAC7B,MAAQuP,cAAe/b,GAAQd,KAAKuD,MAAM0B,QACpCgJ,GAAYC,EAAAA,EAAAA,IAAapN,EAAIC,gBAEnC,OADAiuB,EAAAA,EAAAA,mBAAkB/gB,GACX6f,EAAAA,oBAAAA,8BACH,CAAE7d,cAAenP,GACjB,CACIsN,gBAAiBd,EACjBgB,QAAS,CACLC,WAAYzN,EAAIC,eAAelB,YAAY2O,UAC3CC,UAAWR,MAiJ/B,sFCvuBO,MCoFDghB,EAAcA,CAChB3C,EACAP,EACAC,EACA1e,EACAqG,EACAkZ,IAGI3qB,EAAAA,cAACgtB,EAAAA,KAAI3a,OAAAC,OAAA,GAAKuX,GACN7pB,EAAAA,cAACgtB,EAAAA,KAAI3a,OAAAC,OAAA,GAAKwX,GACLM,EAAKjU,UACLiU,EAAKzrB,MACLyrB,EAAKhU,WACLuU,IAMXsC,EAA4BA,CAC9BvD,EACAO,EACAvB,EACAzB,EACAyD,IAGIhC,GACI1oB,EAAAA,cAACgtB,EAAAA,KAAI3a,OAAAC,OAAA,GAAKoX,GACN1pB,EAAAA,cAACgtB,EAAAA,KAAI3a,OAAAC,OAAA,GAAK2X,IAEJhD,GACEyB,EAAmB/X,KAAK5B,KAAI4B,GACjBA,MAQ7Buc,EAA4BA,CAC9BvD,EACAO,EACArB,EACA5B,EACAyD,IAGI7B,GACI7oB,EAAAA,cAACgtB,EAAAA,KAAI3a,OAAAC,OAAA,GAAKqX,GACN3pB,EAAAA,cAACgtB,EAAAA,KAAI3a,OAAAC,OAAA,GAAK4X,GACLrB,EAAmB1oB,MACnB8mB,GAAwByD,GACvBzD,GACE4B,EAAmB9N,MAAMhM,KAAI,CAACC,EAAM0S,IAE5B1hB,EAAAA,cAACgtB,EAAAA,KAAI3a,OAAAC,OAAA,GAAKtD,EAAKyM,UAAS,CAAE1S,IAAKiG,EAAK9P,IAAMwiB,IACtC1hB,EAAAA,cAACgtB,EAAAA,KAAI3a,OAAAC,OAAA,GAAKtD,EAAK2M,UACV3M,EAAKoM,UACNpb,EAAAA,cAAA,OAAKR,UAAU,6CACVwP,EAAK2B,KACN3Q,EAAAA,cAAA,OAAKR,UAAU,oDACVwP,EAAKgL,MACLhL,EAAKuM,mBAahD4R,EAA6BA,CAC/BvD,EACAO,EACApB,EACA9B,EACAyD,IAGI3B,GACI/oB,EAAAA,cAACgtB,EAAAA,KAAI3a,OAAAC,OAAA,GAAKsX,GACN5pB,EAAAA,cAACgtB,EAAAA,KAAI3a,OAAAC,OAAA,GAAK6X,GACLpB,EAAoB5oB,MACpB8mB,GAAwByD,GACvBzD,GACE8B,EAAoBpY,KAAK5B,KAAI4B,GAClBA,MAQnC,EAlL+CtP,IAC3C,MAAM,QACF0B,EAAO,OACPkf,EAAM,qBACNoH,EAAoB,yBACpBC,EAAwB,WACxBle,EAAU,YACVme,EAAW,eACXG,EAAc,eACdC,EAAc,gBACdC,EAAe,UACfK,EAAS,UACTC,EAAS,WACTC,EAAU,KACVC,EAAI,oBACJG,EAAmB,mBACnBF,EAAkB,mBAClBC,EAAkB,WAClBT,EAAU,YACVC,EAAW,qBACX7C,EAAoB,cACpByD,EAAa,oBACbjZ,EAAmB,aACnBkZ,EACAH,WAAW,0BAAEC,IACbppB,GAEG+rB,EAAcC,GAAertB,EAAAA,UAAwB,GACtDstB,EAAgBttB,EAAAA,OAAoC,MACpDutB,EAAevtB,EAAAA,OAAoC,OAErDwtB,EACAC,EACAC,GDxC0BC,EAC9BC,EACAL,EACAH,EACAS,EACAC,KAEA,MAAOL,EAAeM,GAAoB/tB,EAAAA,SAAoC,KACvEguB,EAAgBN,GAAqB1tB,EAAAA,UAAwB,GAE9DiuB,EAAmBL,EAAYxD,KAA8BzrB,MAAciL,IAE3EskB,EAAsBA,KACnBX,EAAalO,SAIlB0O,EAAiB,CACb1iB,IAAKkiB,EAAalO,QAAQ8O,UAAYZ,EAAalO,QAAQ+O,aAAe,GAC1EC,KAAMd,EAAalO,QAAQiP,WAC3BjY,MAAOkX,EAAalO,QAAQkP,eAIpCvuB,EAAAA,WAAgB,KACZ,IAAKiuB,EAAe5O,QAChB,OAGJ,MAAM8E,EAAQA,KAAQuJ,GAAkB,IAClCc,EAAOA,KAAQd,GAAkB,IAKvC,OAHAO,EAAe5O,QAAQoI,iBAAiB,QAAStD,GACjD8J,EAAe5O,QAAQoI,iBAAiB,OAAQ+G,GAEzC,KACHP,EAAe5O,QAASsI,oBAAoB,QAASxD,GACrD8J,EAAe5O,QAASsI,oBAAoB,OAAQ6G,MAEzD,CAACP,EAAe5O,UAEnBrf,EAAAA,WAAgB,KACZ,IAAKutB,EAAalO,QACd,OAGJ,MAAMoP,EAASA,KACXP,KAKJ,OAFA7a,OAAOoU,iBAAiB,SAAUgH,GAE3B,KACHpb,OAAOsU,oBAAoB,SAAU8G,MAE1C,CAAClB,EAAcA,EAAalO,QAAS0O,IAExC,MAAMP,EAAoBxtB,EAAAA,SAAc,KACnC8tB,IAAmBE,GAAkBH,IACtC,CAACC,EAAgBE,EAAgBH,EAAcT,IA0BnD,OAvBAptB,EAAAA,WAAgB,KACZ,GAAKwtB,EAaL,OARAjJ,SAASiD,KAAKjG,MAAMM,SAAW,QAC/B0C,SAASiD,KAAKjG,MAAMlW,IAAM,MAC1BkZ,SAASiD,KAAKjG,MAAMmN,MAAQ,OAC5BnK,SAASiD,KAAKjG,MAAM8M,KAAO,MAC3B9J,SAASiD,KAAKhC,aAAa,aAAc,QAEzC0I,IAEO,KACH3J,SAASiD,KAAKjG,MAAMM,SAAW,GAC/B0C,SAASiD,KAAKjG,MAAMlW,IAAM,GAC1BkZ,SAASiD,KAAKjG,MAAMmN,MAAQ,GAC5BnK,SAASiD,KAAKjG,MAAM8M,KAAO,GAC3B9J,SAASiD,KAAKmH,gBAAgB,eAjB9BT,MAmBL,CAACV,EAAmBD,EAAalO,UAEhCyO,EACO,EAAE,EAAOL,EAAeC,GAG5B,CAAEF,EAAmBC,EAAeC,IChDvCC,CAAmBtsB,EAAOksB,EAAcH,EAAcntB,QAAQmL,IAAa,GAe/E,OAbApL,EAAAA,WAAgB,KACZ,MAAM4uB,EAAWA,KACb,MAAMC,EAAwF,QAAzEC,EAAAA,EAAAA,UAAS,CAAEC,QAASC,EAAAA,YAAYC,QAASlsB,QAASA,EAAQkT,UAC/EoX,EAAYwB,IAKhB,OAHAD,IAEAvb,OAAOoU,iBAAiB,SAAUmH,GAC3B,KACHvb,OAAOsU,oBAAoB,SAAUiH,MAE1C,CAAC7rB,IAGA/C,EAAAA,cAAAA,EAAAA,SAAA,KACAA,EAAAA,cAACkvB,EAAAA,OAAM7c,OAAAC,OAAA,GAAK2P,EAAM,kBAAgBuL,QAA2BtnB,EAAW0D,IAAK2jB,IACxER,EAAY3C,EAA8BP,EAAYC,EAAa1e,EAAYqG,EAAqBkZ,GACrG3qB,EAAAA,cAACgtB,EAAAA,KAAI3a,OAAAC,OAAA,GAAKiX,EAAW,CAAEhI,MAAOkM,IACzBriB,GAAcA,EAAWe,OAAS,EAAInM,EAAAA,cAACgtB,EAAAA,KAAI3a,OAAAC,OAAA,GAAK+W,GAAuBC,GAAmC,GAE1G7X,GACGzR,EAAAA,cAACgtB,EAAAA,KAAI,CAACxtB,UAAU,sCACXytB,EAA0BvD,EAAgBO,EAAWI,EAAoBpD,EAAsByD,GAC/FyC,EAA2BvD,EAAiBO,EAAYI,EAAqBtD,EAAsByD,GACnGwC,EAA0BvD,EAAgBO,EAAWI,EAAoBrD,EAAsByD,MAK/G8C,GACGxtB,EAAAA,cAAA,OAAK4J,IAAK0jB,EAAe9tB,UAAU,qBAAqB4I,QAAU/H,IAC1DA,EAAMC,SAAWgtB,EAAcjO,UAC/BqO,GAAkB,GAClBjD,MAAAA,GAAAA,ipBCDd,SAAU0E,EAAUC,GAGtB,OAFsC,iBAAlBA,EAA6BA,EAAgBA,EAAcnZ,QAAQ1T,QAGnF,IAAK,QACD,OAAO8sB,EACX,IAAK,QACD,OAAArhB,EAAAA,EAAA,GAAWqhB,GAASC,GACxB,QACI,OAAOD,qDChFZ3wB,eAAewnB,EAClBnjB,EACAwsB,EACA9uB,EACA+uB,GAEA,IAAK/uB,IAAYA,EAAQgvB,gBACrB,MAAO,CAAEC,SAAS,GAGtB,MAAMC,GAAYC,EAAAA,EAAAA,IAAe7sB,EAASwsB,EAAU9uB,EAAQgvB,iBAE5D,MAAO,CACHC,QAASC,EACTE,QAASF,OAAYzpB,EAAYspB,0RCtBnC,SAAUhT,EAAgBxC,EAAqBrZ,GACjD,MAAMmvB,uWAAQ9hB,CAAA,GAAQgM,GA8BtB,OA5BI8V,EAASC,gBACTD,EAASC,eAAiBpvB,GAG1BmvB,EAASE,YACTF,EAASE,WAAarvB,GAGtBmvB,EAASG,sBACTH,EAASG,qBAAuBtvB,GAGhCmvB,EAAStW,0BACTsW,EAAStW,yBAA2B7Y,GAGpCmvB,EAASI,iBACTJ,EAASI,gBAAkBvvB,GAG3BmvB,EAASK,eAAiBL,EAASK,cAAchkB,OAAS,GAC1D2jB,EAASK,cAAc1b,SAAS2b,IACxBA,EAAKC,kBACLD,EAAKC,iBAAmB1vB,MAK7BmvB,EAGL,SAAUQ,EAActW,EAAqBuW,GAC/C,OAAO/T,EAAgBxC,EAAO,EAAIuW,iqBCjChC,SAAUhiB,EAAoBxL,GAAuB,IAAAytB,EAAAC,EACvD,MAAMC,EAA0G,WAApB,QAAjEF,EAAAztB,EAAQlE,eAAe8xB,IAAIC,WAAWrd,aAAasd,IAAI,kBAAU,IAAAL,OAAA,EAAjEA,EAAmEM,eACxFC,EAAyB9vB,OAAwC,QAAlCwvB,EAAC1tB,EAAQlE,eAAe2N,IAAIC,cAAM,IAAAgkB,OAAA,EAAjCA,EAAmCM,wBAEzE,OAAOL,IAAuBtsB,MAAM2sB,IAA2BA,EAAyB,EAGrFryB,eAAesyB,EAAmBjuB,GAAuB,IAAAkuB,EAC5D,MAAMC,EAA0BjwB,OAAwC,QAAlCgwB,EAACluB,EAAQlE,eAAe2N,IAAIC,cAAM,IAAAwkB,OAAA,EAAjCA,EAAmCF,wBAE1E,GAAI3sB,MAAM8sB,IAAwD,IAA5BA,EAClC,MAAO,GAGX,MAAMlM,EAAgC,GAChCmM,EAAsC,CACxCjkB,cAAe,EACfG,qBAAsB,IACtBJ,gBAAiBikB,EACjBvjB,mBAAoB,EACpBL,sBAAuB,IACvBC,SAAU,IAGdyX,EAAOxU,KAAK2gB,GAEZ,IACI,IAAIC,EAAsB,EAE1B,GAAIruB,EAAQlE,eAAejB,KAAKkB,gBAAiB,KAAAuyB,EAG7C,MAAM9B,QAAiBvwB,EAAAA,EAAAA,SAAwB,IAAIvB,EAAAA,6BAA6BsF,EAAQlE,eAAelB,YAAaoF,EAAQlE,eAAejB,KAAK0B,uBAAyByD,GACnKuuB,EAAiBrwB,OAA0B,QAApBowB,EAAC9B,EAASgC,kBAAU,IAAAF,GAAmD,QAAnDA,EAAnBA,EAAqB9nB,MAAKvH,GAAKA,EAAEsX,WAAa4X,WAAwB,IAAAG,GAAgB,QAAhBA,EAAtEA,EAAwEG,sBAAc,IAAAH,OAAA,EAAtFA,EAAwFI,aAElHrtB,MAAMktB,GAENrR,QAAQyR,KAAK,qDAEbN,EAAsBE,OAI1BF,EAAsB,EAQ1BO,MAAMP,GAAqBQ,KAAK,GAAGnd,SAAQ,CAACod,EAAGnQ,KAC3CsD,EAAOxU,KAAIxC,EAAAA,EAAC,GACLmjB,GAAc,IACjB9jB,sBAAuBqU,EAAQ,GAAG3a,WAClCuG,uBAAwBoU,EAAQ,GAAG3a,iBAG7C,MAAO0I,GACLwQ,QAAQyR,KAAK,2HAA4HjiB,GAG7I,OAAOuV,EAGJtmB,eAAe8P,EAAkBzL,EAAyB+uB,GAA0C,IAAAC,EACvG,MAAMb,EAA0BjwB,OAAwC,QAAlC8wB,EAAChvB,EAAQlE,eAAe2N,IAAIC,cAAM,IAAAslB,OAAA,EAAjCA,EAAmChB,wBAE1E,GAAI3sB,MAAM8sB,IAAwD,IAA5BA,EAClC,OAGAY,EAAoB7jB,WAAY4R,MAAK7d,GAAKA,EAAEiL,kBAAoBikB,MAEhEY,EAAoB7jB,WAAa6jB,EAAoB7jB,WAAYlM,QAAOC,GAAKA,EAAEiL,kBAAoBikB,KAGvG,MAAMxd,QAAiBsd,EAAmBjuB,GAI1C,OAFA+uB,EAAoB7jB,WAAa6jB,EAAoB7jB,WAAY+jB,OAAOte,GAEjE9D,QAAQqiB,usBC/EnB,SAASC,EAAiBnvB,GAAuB,IAAAytB,EAC7C,MAAM2B,EAA2E,QAApE3B,EAAGztB,EAAQlE,eAAe8xB,IAAIC,WAAWrd,aAAasd,IAAI,kBAAU,IAAAL,OAAA,EAAjEA,EAAmEM,cAEnF,MAAmB,MAAZqB,GAA+B,SAAZA,EAGxB,SAAU7jB,EAA4BvL,EAAyB2Q,GAAgC,IAAA+c,EACjG,MAAM2B,EAA+D,QAApC3B,EAAG1tB,EAAQlE,eAAe2N,IAAIC,cAAM,IAAAgkB,OAAA,EAAjCA,EAAmC4B,sBAMvE,KAF+BH,EAAiBnvB,IAAYqvB,GAE/B,CACzB,MAAMpN,EAAStR,EAAW,IAAIA,GAAY,GAGpC4e,EAAetN,EAAOzb,MAAKvH,GAA2B,IAAtBA,EAAEiL,kBAOjC,IAAAgkB,EALP,GAAIqB,IAEKA,EAAajlB,sBAAwBpM,OAAOqxB,EAAajlB,sBAAwB,OAClFilB,EAAajlB,qBAAuB,aAIxC2X,EAAOxU,KAAK,CACR,cAAe,qEACf/C,MAAO,EACPP,cAAe,EACfG,qBAAsB,OACtBK,oBAAqB,GACrBT,gBAAiB,EACjBU,mBAAoB,EACpBL,sBAAuB,aACvBE,UAAW,EACXD,SAAwC,QAAhC0jB,EAAEluB,EAAQlE,eAAe0zB,eAAO,IAAAtB,OAAA,EAA9BA,EAAgCuB,WAIlD,OAAOxN,EAGX,OAAOtR,GAAY,GAGhBhV,eAAe+zB,EAAqB1vB,EAAyBwsB,EAAgCmD,EAA2BpL,GAC3H,MAAMtC,EAAgC,GAChCnR,EAA+B,CACjC3G,cAAe,EACfG,qBAAsB,IACtBJ,gBAAiBylB,EACjB/kB,mBAAoB,EACpBL,sBAAuB,IACvBC,SAAU,IAGdyX,EAAOxU,KAAKqD,GAEZ,IACI,IAAI8e,EAAiB,EAErB,GAAIpD,EAAU,KAAA8B,EACV,MAAMvf,EAAY7Q,OAA0B,QAApBowB,EAAC9B,EAASgC,kBAAU,IAAAF,GAA6C,QAA7CA,EAAnBA,EAAqB9nB,MAAKvH,GAAKA,EAAEsX,WAAaoZ,WAAkB,IAAArB,GAAgB,QAAhBA,EAAhEA,EAAkEG,sBAAc,IAAAH,OAAA,EAAhFA,EAAkFI,aAEvGrtB,MAAM0N,GAEFwV,EACArH,QAAQyR,KAAK,GAAGpK,iDAEhBrH,QAAQyR,KAAK,4BAA4BgB,yCAG7CC,EAAiB7gB,OAIrB6gB,EAAiB,EAGE,IAAnBA,GACA3N,EAAOxU,KAAIxC,EAAAA,EAAC,GACL6F,GAAO,IACVxG,qBAAsBslB,EAAe5rB,WACrCuG,sBAAuBqlB,EAAe5rB,cAGhD,MAAO0I,GACD6X,EACArH,QAAQyR,KAAK,iBAAiBpK,iFAA6F7X,GAE3HwQ,QAAQyR,KAAK,gDAAgDgB,+DAAgFjjB,GAIrJ,OAAOuV,EAGX,SAAS4N,EAA4B7vB,EAAyBwsB,GAA8B,IAAAwC,EACxF,MAAMW,EAAoBzxB,OAAwC,QAAlC8wB,EAAChvB,EAAQlE,eAAe2N,IAAIC,cAAM,IAAAslB,OAAA,EAAjCA,EAAmCc,iCAEpE,GAAIzuB,MAAMsuB,IAAsBA,GAAqB,EACjD,OAGJ,MAAMI,EAA0C,CAC5C5lB,cAAeC,EAAAA,kBAAkB4lB,KACjC1lB,qBAAsB,IACtBJ,gBAAiBylB,EACjB/kB,mBAAoBC,EAAAA,qBAAqBC,UACzCP,sBAAuB,IACvBC,SAAU,IAGd,OAAIgiB,EACO,CACHuD,EAAkB9kB,EAAAA,EAAA,GAEX8kB,GAAkB,IACrBzlB,qBAAsBkiB,EAASyD,cAC/B1lB,sBAAuBiiB,EAASyD,iBAKrC,CAACF,GAGLp0B,eAAeu0B,EAAoBlwB,EAAyBwsB,EAAgCuC,EAA4CY,GACvIZ,EAAoB7jB,WAAY4R,MAAK7d,GAAKA,EAAEiL,kBAAoBylB,MAEhEZ,EAAoB7jB,WAAa6jB,EAAoB7jB,WAAYlM,QAAOC,GAAKA,EAAEiL,kBAAoBylB,KAGvG,MAAMhf,QAAiB+e,EAAqB1vB,EAASwsB,EAAUmD,GAE/DZ,EAAoB7jB,WAAa6jB,EAAoB7jB,WAAY+jB,OAAOte,GAGrEhV,eAAe+P,EAAwB1L,EAAyB+uB,GAA0C,IAAAoB,EAG7G,GAFgBhB,EAAiBnvB,GAG7B,OAGJ,MAAMowB,EAA+B,CACA,QADAD,EACjCnwB,EAAQlE,eAAe2N,IAAIC,cAAM,IAAAymB,OAAA,EAAjCA,EAAmCE,yBAEjC,YAAEz1B,EAAaC,MAAM,sBAAE0B,IAA4ByD,EAAQlE,eACjE,IAAI0wB,EAEAxsB,EAAQlE,eAAejB,KAAKkB,kBAC5BywB,QAAiBvwB,EAAAA,EAAAA,SAAwB,IAAIvB,EAAAA,6BAA6BE,EAAa2B,GAAyByD,IAGpH,IAAK,MAAM2vB,KAAqBS,EAAoB,CAChD,MAAMj0B,EAAK+B,OAAOyxB,IAGbtuB,MAAMlF,IAAOA,EAAK,SACb+zB,EAAoBlwB,EAASwsB,EAAUuC,EAAqB5yB,GAK1E,MAAMm0B,EAA2BT,EAA4B7vB,EAASwsB,GAClE8D,IACAvB,EAAoB7jB,WAAa6jB,EAAoB7jB,WAAY+jB,OAAOqB,IAIzE30B,eAAe40B,EAAwBvwB,GAAuB,IAAAwwB,EAGjE,GAFgBrB,EAAiBnvB,GAG7B,MAAO,GAGX,MAAMowB,EAA+B,CACA,QADAI,EACjCxwB,EAAQlE,eAAe2N,IAAIC,cAAM,IAAA8mB,OAAA,EAAjCA,EAAmCH,yBAEjC,YAAEz1B,EAAaC,MAAM,sBAAE0B,IAA4ByD,EAAQlE,eACjE,IAAI0wB,EAEAxsB,EAAQlE,eAAejB,KAAKkB,kBAC5BywB,QAAiBvwB,EAAAA,EAAAA,SAAwB,IAAIvB,EAAAA,6BAA6BE,EAAa2B,GAAyByD,IAGpH,MAAMiiB,EAAgC,GAEtC,IAAK,MAAM0N,KAAqBS,EAAoB,CAChD,MAAMj0B,EAAK+B,OAAOyxB,GAGlB,IAAKtuB,MAAMlF,IAAOA,EAAK,EAAG,CACtB,MAAMwU,QAAiB+e,EAAqB1vB,EAASwsB,EAAUrwB,GAC/D8lB,EAAOxU,QAAQkD,IAKvB,MAAM2f,EAA2BT,EAA4B7vB,EAASwsB,GAKtE,OAJI8D,GACArO,EAAOxU,QAAQ6iB,GAGZrO,EAkBL,SAAUwO,EAAsBzwB,GAClC,MAAM0wB,EAhBJ,SAA6B1wB,GAC/B,MAAMR,GAAS4sB,EAAAA,EAAAA,GAAUpsB,GAEzB,MAAO,CACHR,EAAOmxB,YACPnxB,EAAOoxB,QACPpxB,EAAOqxB,SACPrxB,EAAOsxB,cACPtxB,EAAOuxB,QACPvxB,EAAOwxB,QACPxxB,EAAOyxB,SACPzxB,EAAO0xB,WAKaC,CAAmBnxB,GACrCoxB,EAAW,IAAIC,IAAIX,EAAgB1kB,KAAI,CAACC,EAAM0S,IAAU,CAAC1S,EAAK8hB,cAAepP,MAEnF,MAAO,CAAC2S,EAAGC,KAAK,IAAAC,EAAAC,EAAAC,EAAAC,EAIZ,OAHeP,EAASQ,KAAa,QAATJ,EAAAF,EAAEO,eAAO,IAAAL,OAAA,EAATA,EAAWzD,gBAAiB,IAAMqD,EAAStD,KAAa,QAAT2D,EAAAH,EAAEO,eAAO,IAAAJ,OAAA,EAATA,EAAW1D,gBAAiB,IAAO+D,EAAAA,IAC/FV,EAASQ,KAAa,QAATF,EAAAH,EAAEM,eAAO,IAAAH,OAAA,EAATA,EAAW3D,gBAAiB,IAAMqD,EAAStD,KAAa,QAAT6D,EAAAJ,EAAEM,eAAO,IAAAF,OAAA,EAATA,EAAW5D,gBAAiB,IAAO+D,EAAAA,gFC/MhH,SAAUniB,EAAaoiB,GAAkC,QAAAC,EAAAC,UAAA7oB,OAAb8oB,EAAa,IAAAtD,MAAAoD,EAAA,EAAAA,EAAA,KAAAG,EAAA,EAAAA,EAAAH,EAAAG,IAAbD,EAAaC,EAAA,GAAAF,UAAAE,GAC3D,OAAKJ,EAGEA,EAASvuB,QAAQ,YAAY,CAAC4uB,EAAOzT,KACxC,MAAM0T,EAAarhB,SAAS2N,EAAO,IACnC,YAA8Bxb,IAAvB+uB,EAAOG,GAA4BH,EAAOG,GAAcD,KAJxD,GAQT,SAAUE,EACZC,EACAC,EACAC,EACAC,GAA6C,IAAAC,EAE7C,MAAMC,EAAwBJ,MAAAA,GAAkE,QAA9CG,EAApBH,EAAsBK,yBAAyBloB,2BAAmB,IAAAgoB,GAC5D,QAD4DA,EAAlEA,EACxBnsB,MAAKvH,GAAe,YAAVA,EAAE6zB,aAAkB,IAAAH,GAAO,QAAPA,EADNA,EACQrmB,aAAK,IAAAqmB,OAAA,EADbA,EACeI,oBAMvCC,EAA4BR,MAAAA,OAAoB,EAApBA,EAAsBK,yBAAyBI,kBAEjF,GAAIL,EAAuB,CAKvB,MAAMM,EAvDd,SAAuBC,GAEnB,MAAMC,EAAc,IAAI1K,KAAKA,KAAK2K,IAAIF,EAAKG,cAAeH,EAAKI,WAAYJ,EAAKK,YAI1EC,GAAaL,EAAYM,YAAc,GAAK,EAGlDN,EAAYO,WAAWP,EAAYQ,aAAeH,EAAY,GAG9D,MAAMI,EAAgB,IAAInL,KAAKA,KAAK2K,IAAID,EAAYU,iBAAkB,EAAG,IAGvC,IAA9BD,EAAcH,aACdG,EAAcF,WAAWE,EAAcD,cAAiBC,EAAcH,YAAc,GAAK,GAI7F,MAAMR,EAAal1B,KAAK+1B,OAAOX,EAAYY,UAAYH,EAAcG,WAAa,MAAW,GAAK,GAElG,OAAOd,EAAa,EAAIA,EAAa,EAiCde,CAAc,IAAIvL,KAAKkK,IAE1C,GAAII,EAA2B,CAC3B,MAAMplB,EAAO6kB,GAAyC,mCACtDF,GAAiB,GAAGA,EAAgB,KAAO,MAAKzkB,EAAAA,EAAAA,QAAOF,EAAMolB,EAA2BE,SACrF,CACH,MAAMtlB,EAAO8kB,GAA6B,+BAC1CH,GAAiB,GAAGA,EAAgB,KAAO,MAAKzkB,EAAAA,EAAAA,QAAOF,EAAMslB,KAG7DX,EAAc2B,SAAS,OACvB3B,EAAgBA,EAAc7e,MAAM,GAAI,IAIhD,OAAO6e,4ECzEL,SAAUlzB,EAA0BN,GAEtC,MAAMo1B,EAAkB,CACpB,MACA,QACA,SACA,WACA,KACA,QACA,aAGJ,IAAK,MAAMC,KAAQD,EAAiB,CAChC,MAAM3tB,EAAOzH,MAAAA,OAAW,EAAXA,EAAayH,MAAKpH,GAAcA,EAAWO,wBAA0By0B,IAClF,GAAI5tB,EACA,OAAOA,GAOb,SAAU6tB,EAAsBC,EAA0Cv1B,GAC5E,IAAKu1B,EACD,OAGJ,MAAMH,EAAkB,CACpB,WACA,MAEJ,OAAOp1B,MAAAA,OAAW,EAAXA,EAAayH,MAAKpH,GACrBA,EAAWD,0BAA4Bm1B,GACvCl1B,EAAWO,uBAAyBw0B,EAAgBnxB,SAAS5D,EAAWO,yBAG1E,SAAU40B,EAAiBx1B,GAC7B,MAAMy1B,EAAoB,CACtB,SACA,UAEEL,EAAkB,CACpB,MACA,QACA,SACA,WAGJ,OAAOp1B,MAAAA,OAAW,EAAXA,EAAayH,MAAKpH,GACpBA,EAAWD,yBAA2Bq1B,EAAkBxxB,SAAS5D,EAAWD,0BAC5EC,EAAWO,uBAAyBw0B,EAAgBnxB,SAAS5D,EAAWO,yBAG3E,SAAUL,EAAiBF,GAE7B,OAAIA,EAAWq1B,QAAgD,OAArCr1B,EAAWO,uBAAuE,aAArCP,EAAWO,sBAGvEP,EAAWq1B,QAAU,EAFrBz2B,KAAKC,MAA6C,KAAtCmB,EAAWq1B,OAASv2B,OAAOC,UAAkB,IAMlE,SAAUuB,EAAmBg1B,GAK/B,MAJc,CACV,KACA,YAES1xB,SAAS0xB,GAAiB,IAAM,EAAI,wmBCrErD,MAAMC,EAAU,CAAEC,QAAS,GAAIC,YAAa,IAmBlCC,EAA8BA,CAACC,EAAqBC,KAUlD,GADAL,EAAQE,YAAYE,GAAuBC,GACtCL,EAAQE,YAAYE,GAAqBE,QAC1C,MAAM,IAAItoB,MAAM,oBAAsBooB,EAAsB,mCAEhEJ,EAAQE,YAAYE,GAAqBE,QAAQC,UAAUC,eAAiBJ,EACxEJ,EAAQE,YAAYE,GAAqBE,QAAQC,UAAU/4B,KAC3Dw4B,EAAQE,YAAYF,EAAQE,YAAYE,GAAqBE,QAAQC,UAAU/4B,IAAM44B,IAMhGJ,EAAQC,QAAQ,mBAAqB,CAClCQ,EAAGA,IAAMC,EAAQ,MACjBC,MAAO,gBACPC,GAAI,CAAC,CAAC5iB,KAAK,OAAS6iB,KAAK,+EAAgFC,MAAO,GAAG,CAAC9iB,KAAK,iBAAmB6iB,KAAK,oCAAqCC,MAAO,GAAG,CAAC9iB,KAAK,cAAgB6iB,KAAK,gFAAiFC,MAAO,IAEnTC,KAAK,EACLC,GAAI,YACJC,EAAG,kBACHC,EAAG,YAEHC,IAAK,GAGLrb,GAAI,+BAOAqa,EAF4B,gFACXO,EAAQ,MAQzBP,EAF4B,+EACXO,EAAQ,KAQzBP,EAF4B,oCACXO,EAAQ,KAMjC/kB,OAAOylB,aAAezlB,OAAOylB,cAAgB,GAC7CzlB,OAAOylB,aAAanB,QAAO3pB,EAAAA,EAAA,GACpBqF,OAAOylB,aAAanB,SAAW,IAC/BD,EAAQC,SAGXtkB,OAAOylB,aAAalB,YAAW5pB,EAAAA,EAAA,GAC5BqF,OAAOylB,aAAalB,aAAe,IACnCF,EAAQE,aAEY,MAAMmB,EAAiB,GAC9BA,EAAe,+DAAiE,CACxFZ,EAAGA,IAAMC,EAAQ,MACjBY,GAAI,uCAEpB3lB,OAAOylB,aAAezlB,OAAOylB,cAAgB,GAC7CzlB,OAAOylB,aAAaC,eAAc/qB,EAAAA,EAAA,GACPqF,OAAOylB,aAAaC,gBAAkB,IACtCA,wFCvFpB,MAAME,IACGnuB,EAAAA,EAAAA,IAAA,CAAXouB,EAAAA,IAAU,kCAECpuB,EAAAA,EAAAA,IAAA,CAAXouB,EAAAA,IAAU,6CAECpuB,EAAAA,EAAAA,IAAA,CAAXouB,EAAAA,IAAU,8KCLR,SAASxV,EAAuBsB,GACnC,OAAO,IAAImU,EAAAA,aAA0B,cAAenU,EAAQ,eAGhE,MAIaoU,GAA6Bn6B,EAAAA,EAAAA,IAA2B,CACjEE,OAA8Bk6B,EAAAA,iBAC9B16B,MANoCS,GAC7BskB,EAAuB,CAAEtY,WAAY,OAQhD,WCvBAkuB,EAAOC,QAAUv5B,cCAjBs5B,EAAOC,QAAUC","sources":["webpack://Msdyn365.Commerce.Online/./src/actions/get-organization-customer.ts?79c2","webpack://Msdyn365.Commerce.Online/./src/components/switch/switch.tsx?ec26","webpack://Msdyn365.Commerce.Online/./src/components/common/product-list-order-quantity.tsx?cd94","webpack://Msdyn365.Commerce.Online/./src/modules/vinhuset-search/actions/get-auto-suggest-suggestions.ts?e393","webpack://Msdyn365.Commerce.Online/./src/modules/vinhuset-search/components/vinhuset-search.categorysuggest.tsx?a3b8","webpack://Msdyn365.Commerce.Online/./src/modules/vinhuset-search/components/vinhuset-search.form.tsx?3832","webpack://Msdyn365.Commerce.Online/./src/modules/vinhuset-search/components/vinhuset-search.keywordsuggest.tsx?c522","webpack://Msdyn365.Commerce.Online/./src/modules/vinhuset-search/components/cart-count.tsx?7991","webpack://Msdyn365.Commerce.Online/./src/modules/vinhuset-search/components/buy-section.tsx?e377","webpack://Msdyn365.Commerce.Online/./src/modules/vinhuset-search/components/vinhuset-search.productsuggest.tsx?1804","webpack://Msdyn365.Commerce.Online/./src/modules/vinhuset-search/vinhuset-search.props.autogenerated.ts?0fd3","webpack://Msdyn365.Commerce.Online/./src/components/barcode-scanner/barcode-scanner.tsx?00fd","webpack://Msdyn365.Commerce.Online/./src/modules/vinhuset-search/vinhuset-search.tsx?5879","webpack://Msdyn365.Commerce.Online/./src/modules/vinhuset-search/components/vinhuset-search.hooks.tsx?f0cc","webpack://Msdyn365.Commerce.Online/./src/modules/vinhuset-search/vinhuset-search.view.tsx?211a","webpack://Msdyn365.Commerce.Online/./src/shared-utils/attributes/locale/locale.ts?bf3e","webpack://Msdyn365.Commerce.Online/./src/shared-utils/attributes/on-buy-access-validator.ts?4b31","webpack://Msdyn365.Commerce.Online/./src/shared-utils/price-utils.ts?b25e","webpack://Msdyn365.Commerce.Online/./src/shared-utils/refiner-utils.alcohol.ts?83dc","webpack://Msdyn365.Commerce.Online/./src/shared-utils/refiner-utils.ts?1ea9","webpack://Msdyn365.Commerce.Online/./src/shared-utils/string-utils.ts?de49","webpack://Msdyn365.Commerce.Online/./src/shared-utils/unit-conversion-utils.ts?1560","webpack://Msdyn365.Commerce.Online/./lib/vinhuset-search/module-registration.js?c299","webpack://Msdyn365.Commerce.Online/./src/search-state.ts?dd10","webpack://Msdyn365.Commerce.Online/./src/search-state-data-action.ts?8223","webpack://Msdyn365.Commerce.Online/external var \"React\"?0d3b","webpack://Msdyn365.Commerce.Online/external var \"ReactDOM\"?853b"],"sourcesContent":["import { createObservableDataAction, IActionContext, IAction, ICreateActionContext, IGeneric, IAny, ICommerceApiSettings } from '@msdyn365-commerce/core';\r\nimport { CacheType, callActionOrExecute, Customer, DataServiceQuery, IActionInput, IDataServiceRequest } from \"@msdyn365-commerce/retail-proxy\";\r\nimport * as Entities from '@msdyn365-commerce/retail-proxy/dist/Entities/CommerceModels.g';\r\n\r\nexport class GetOrganizationCustomerInput implements IActionInput {\r\n private readonly user: string | undefined;\r\n private readonly query: DataServiceQuery;\r\n\r\n constructor(apiSettings: ICommerceApiSettings, user: string) {\r\n this.user = user;\r\n\r\n this.query = new DataServiceQuery();\r\n }\r\n\r\n public getDataServiceRequest = (): IDataServiceRequest => {\r\n return this.query.createDataServiceRequestForOperation(\r\n 'GetOrganizationCustomer',\r\n false,\r\n Entities.CustomerClass,\r\n 'false',\r\n {\r\n bypassCache: 'get',\r\n returnEntity: 'Entities.CustomerClass'\r\n },\r\n {}\r\n );\r\n };\r\n\r\n public shouldCacheOutput = (): boolean => false;\r\n\r\n public getCacheKey = () => `OrganizationCustomer-${this.user}`;\r\n public getCacheObjectType = () => 'OrganizationCustomer';\r\n public dataCacheType = (): CacheType => 'request';\r\n}\r\n\r\nconst createInput = (inputData: ICreateActionContext>): GetOrganizationCustomerInput => {\r\n const { user } = inputData.requestContext;\r\n return new GetOrganizationCustomerInput(inputData.requestContext.apiSettings, user.customerAccountNumber ?? \"\");\r\n};\r\n\r\nexport const getOrganizationCustomerAction = async (input: GetOrganizationCustomerInput, ctx: IActionContext): Promise => {\r\n if (!ctx.requestContext.user.isAuthenticated) {\r\n return {};\r\n }\r\n var customer = await callActionOrExecute(input.getDataServiceRequest(), ctx);\r\n return customer;\r\n};\r\n\r\nexport const getOrganizationCustomer = createObservableDataAction({\r\n id: 'src/actions/get-organization-customer',\r\n action: >getOrganizationCustomerAction,\r\n input: createInput\r\n});\r\n\r\nexport default getOrganizationCustomer;\r\n","import * as React from 'react';\r\nimport classnames from 'classnames';\r\n\r\ninterface ISwitchProps {\r\n className?: string;\r\n label?: string;\r\n checked?: boolean;\r\n onChange?: (value: boolean) => void;\r\n mini?: boolean;\r\n miniLabel?: string;\r\n}\r\n\r\nconst Switch: React.FC = ({\r\n className,\r\n label,\r\n checked,\r\n onChange,\r\n mini,\r\n miniLabel\r\n}) => {\r\n const [internalChecked, setInternalChecked] = React.useState(Boolean(checked));\r\n\r\n React.useEffect(() => {\r\n setInternalChecked(Boolean(checked));\r\n }, [checked]);\r\n\r\n const onChangeHandler = (event: React.ChangeEvent) => {\r\n setInternalChecked(event.target.checked);\r\n onChange?.(event.target.checked);\r\n };\r\n\r\n return (\r\n \r\n );\r\n};\r\n\r\nexport default Switch;\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\nimport { ICoreContext } from '@msdyn365-commerce/core';\r\nimport { SimpleProduct, UnitOfMeasureConversion } from '@msdyn365-commerce/retail-proxy';\r\nimport { reaction, computed, when } from 'mobx';\r\nimport { observer } from 'mobx-react';\r\nimport * as React from 'react';\r\nimport classnames from 'classnames';\r\nimport { UnitOfMeasure, humanizeUnitOfMeasure } from '../unit-of-measure';\r\nimport Switch from '../switch/switch';\r\nimport { getMinimumDecimals, getMostRelevantConversion, getRoundedFactor } from '../../shared-utils/unit-conversion-utils';\r\n\r\ninterface IQuantityProps {\r\n context: ICoreContext;\r\n locale: string;\r\n product: SimpleProduct | undefined;\r\n unitConversions?: UnitOfMeasureConversion[];\r\n currentCount?: number;\r\n allowZero?: boolean;\r\n disabled?: boolean;\r\n hideUnitConversion?: boolean;\r\n incrementGlyphClass?: string;\r\n decrementGlyphClass?: string;\r\n decrementButtonAriaLabel?: string;\r\n incrementButtonAriaLabel?: string;\r\n inputQuantityAriaLabel?: string;\r\n id?: string;\r\n min?: number;\r\n breakoff?: boolean;\r\n legacyBreakoff?: boolean;\r\n onChange?(newValue: number): void;\r\n onBreakoffChange?(enabled: boolean): void;\r\n}\r\n\r\ninterface IQuantityState {\r\n currentInput: string | number;\r\n parsedCurrentInput: number;\r\n breakoff: boolean;\r\n}\r\n\r\nfunction getDecimalSeparator(locale: string) {\r\n const numberWithDecimalSeparator = 1.1;\r\n const separator = Intl.NumberFormat(locale)\r\n .formatToParts(numberWithDecimalSeparator)\r\n .find(part => part.type === 'decimal')\r\n ?.value;\r\n return separator ?? ',';\r\n}\r\n\r\nexport function getInitialBreakoffState(initialValue: number, product: SimpleProduct): { factor?: number, breakoff: boolean } {\r\n const multiplier = product.Behavior?.DefaultQuantity || 1;\r\n const factor = Math.round(((initialValue / multiplier) + Number.EPSILON) * 1000) / 1000;\r\n const remainder = (initialValue * 1000) % (multiplier * 1000);\r\n if (remainder === 0) {\r\n return { factor, breakoff: false };\r\n } else {\r\n return { breakoff: true };\r\n }\r\n}\r\n\r\n/**\r\n * Quantity Component - This component is used to add or remove quantity.\r\n */\r\n@observer\r\nexport default class ProductListOrderQuantity extends React.PureComponent {\r\n public static defaultProps: Partial = {\r\n allowZero: true,\r\n decrementGlyphClass: 'fas fa-minus',\r\n incrementGlyphClass: 'fas fa-plus'\r\n };\r\n\r\n private readonly inputRef: React.RefObject = React.createRef();\r\n\r\n @computed get hasBreakoff(): boolean {\r\n return !!this.props.product?.Behavior?.DefaultQuantity;\r\n }\r\n\r\n @computed get minimum(): number {\r\n return (this.productMinimumQuantity || Number(!this.props.allowZero)) / this.multipleOf;\r\n }\r\n\r\n @computed get maximum(): number {\r\n const max = this.productMaximumQuantity || 999_999_999;\r\n return max / this.multipleOf;\r\n }\r\n\r\n @computed get multipleOf(): number {\r\n if (this.state.breakoff) {\r\n // Breakoff is enabled\r\n return this.productMultipleOfQuantity || 1;\r\n }\r\n\r\n return this.productDefaultQuantity || 1;\r\n }\r\n\r\n @computed get productDefaultQuantity(): number | undefined {\r\n return this.props.product?.Behavior?.DefaultQuantity;\r\n }\r\n\r\n @computed get productMaximumQuantity(): number | undefined {\r\n return this.props.product?.Behavior?.MaximumQuantity;\r\n }\r\n\r\n @computed get productMinimumQuantity(): number | undefined {\r\n return this.props.product?.Behavior?.MinimumQuantity;\r\n }\r\n\r\n @computed get productMultipleOfQuantity(): number | undefined {\r\n return this.props.product?.Behavior?.MultipleOfQuantity;\r\n }\r\n\r\n @computed get total(): number {\r\n return this.state.parsedCurrentInput * this.multipleOf;\r\n }\r\n\r\n @computed get totalFormatted(): string {\r\n return this.total.toLocaleString(this.props.locale, {\r\n minimumFractionDigits: getMinimumDecimals(this.props.product?.DefaultUnitOfMeasure),\r\n maximumFractionDigits: 2,\r\n useGrouping: false\r\n });\r\n }\r\n\r\n @computed get showDecimals(): boolean {\r\n const units = [\r\n 'kg',\r\n 'Kilogram'\r\n ];\r\n const uom = this.props.product?.DefaultUnitOfMeasure;\r\n\r\n return !!uom && units.includes(uom);\r\n }\r\n\r\n constructor(props: IQuantityProps) {\r\n super(props);\r\n\r\n const { allowZero, currentCount, product } = this.props;\r\n let breakoff = false;\r\n let initialValue: number | string = '';\r\n\r\n if (product) {\r\n initialValue = currentCount || (allowZero ? 0 : this.productMinimumQuantity ?? 1);\r\n\r\n if (this.hasBreakoff) {\r\n if (props.breakoff) {\r\n breakoff = true;\r\n } else {\r\n const breakoffState = getInitialBreakoffState(initialValue, product);\r\n\r\n if (breakoffState.factor) {\r\n initialValue = breakoffState.factor;\r\n } else {\r\n breakoff = breakoffState.breakoff;\r\n }\r\n }\r\n }\r\n }\r\n\r\n this.state = {\r\n currentInput: initialValue,\r\n parsedCurrentInput: typeof initialValue === 'number' ? initialValue : Number.parseFloat(initialValue) || 0,\r\n breakoff\r\n };\r\n this._clamp = this._clamp.bind(this);\r\n this._handleChange = this._handleChange.bind(this);\r\n this._validateQuantity = this._validateQuantity.bind(this);\r\n this._onToggleBreakoff = this._onToggleBreakoff.bind(this);\r\n }\r\n\r\n public componentDidMount(): void {\r\n when(\r\n () => this.props.product !== undefined && (this.state.currentInput === '' || this.state.currentInput === 0),\r\n () => {\r\n const { allowZero, currentCount } = this.props;\r\n const initialValue = currentCount || (allowZero ? 0 : this.productMinimumQuantity ?? 1);\r\n\r\n if (this.hasBreakoff) {\r\n const multipler = this.productDefaultQuantity!;\r\n const factor = initialValue / multipler;\r\n const remainder = initialValue % multipler;\r\n\r\n if (remainder === 0) {\r\n this.setState({ currentInput: factor });\r\n } else {\r\n this.setState({ breakoff: true });\r\n }\r\n } else {\r\n this.setState({ currentInput: initialValue });\r\n }\r\n }\r\n );\r\n\r\n reaction(\r\n () => this.props.breakoff,\r\n (breakoff) => {\r\n this.setState({ breakoff: Boolean(breakoff) });\r\n }\r\n );\r\n\r\n reaction(\r\n () => this.props.currentCount,\r\n () => {\r\n const currentInput = typeof this.state.currentInput === 'string'\r\n ? Number.parseFloat(this.state.currentInput.replace(',', '.') || '0')\r\n : this.state.currentInput;\r\n const oldQuantity = this._convertOutgoingQuantity(currentInput);\r\n const newQuantity = this._convertIncomingQuantity(this.props.currentCount ?? 0);\r\n\r\n // Only allow the change from props if it's meaningfully different\r\n if (this.props.currentCount !== oldQuantity) {\r\n this.setState({\r\n currentInput: newQuantity\r\n });\r\n }\r\n }\r\n );\r\n\r\n reaction(\r\n () => this.state.breakoff,\r\n (newValue) => {\r\n if (newValue) {\r\n const newInput = (this.props.currentCount ?? 0) / this.multipleOf;\r\n\r\n this.setState({\r\n currentInput: newInput,\r\n parsedCurrentInput: newInput\r\n });\r\n } else {\r\n const newInput = (this.props.currentCount ?? 0) / this.multipleOf;\r\n\r\n this.setState({\r\n currentInput: newInput,\r\n parsedCurrentInput: newInput\r\n });\r\n }\r\n }\r\n );\r\n\r\n reaction(\r\n () => this.state.currentInput,\r\n () => {\r\n this.setState({\r\n currentInput: this.showDecimals ? this.state.currentInput.toLocaleString(this.props.locale, {\r\n minimumFractionDigits: getMinimumDecimals(this.props.product?.DefaultUnitOfMeasure),\r\n maximumFractionDigits: 2,\r\n useGrouping: false\r\n }).replace('.', ',') : this.state.currentInput,\r\n parsedCurrentInput: Number.parseFloat(this.state.currentInput.toString().replace(',', '.') || '0')\r\n });\r\n }\r\n );\r\n }\r\n\r\n public render(): JSX.Element {\r\n const { allowZero, context, product, hideUnitConversion } = this.props;\r\n const disabled = this.state.parsedCurrentInput === (allowZero ? 0 : this.minimum);\r\n const incDisabled = this.state.parsedCurrentInput === this.maximum;\r\n const currentValue = this.state.currentInput;\r\n const baseClassName = 'vinhuset-quantity';\r\n const miniBreakoff = !this.props.legacyBreakoff;\r\n\r\n let extraClass = '';\r\n if (disabled) {\r\n // The quantity has reached its boundaries (max or min)\r\n extraClass = 'disabled';\r\n } else if (this.props.disabled) {\r\n // This.props.disabled shows if the state is not succeded yet\r\n extraClass = 'transition';\r\n }\r\n const getChangeHandler = (action: 'increment' | 'decrement') => () => {\r\n let amount = action === 'increment' ? 1 : -1;\r\n\r\n const calcTotal = (change: number): number => {\r\n const newAmount = this.state.parsedCurrentInput + change;\r\n return this.multipleOf * newAmount;\r\n };\r\n\r\n let newTotal = calcTotal(amount);\r\n\r\n if (action === 'increment' && newTotal > 0) {\r\n if (this.productMinimumQuantity && newTotal < this.productMinimumQuantity) {\r\n amount = (this.productMinimumQuantity - this.total) / this.multipleOf;\r\n }\r\n\r\n newTotal = calcTotal(amount);\r\n\r\n if (this.productMaximumQuantity && newTotal > this.productMaximumQuantity) {\r\n amount = (this.productMaximumQuantity - this.total) / this.multipleOf;\r\n }\r\n }\r\n\r\n if (action === 'decrement' && newTotal > 0) {\r\n if (this.productMinimumQuantity && newTotal < this.productMinimumQuantity) {\r\n if (allowZero) {\r\n amount = -this.state.parsedCurrentInput;\r\n } else {\r\n amount = this.minimum - this.state.parsedCurrentInput;\r\n }\r\n }\r\n if (this.productMaximumQuantity && newTotal > this.productMaximumQuantity) {\r\n amount = this.maximum - this.state.parsedCurrentInput;\r\n }\r\n }\r\n\r\n this._onIncrementalChange(amount);\r\n };\r\n\r\n return (\r\n
\r\n {!product?.Behavior?.MinimumQuantity && !miniBreakoff && (\r\n \r\n )}\r\n
\r\n
\r\n {!product?.Behavior?.MinimumQuantity && miniBreakoff && this.hasBreakoff && (\r\n \r\n )}\r\n {miniBreakoff && this.hasBreakoff && (\r\n \r\n {`${this.multipleOf} `}\r\n  x\r\n \r\n )}\r\n \r\n {\r\n const NUMBER_DOT_COMMA = /^[\\d,.]*$/;\r\n const fieldValue = (e.target as any).value;\r\n const fieldHasCommaOrDot = fieldValue.includes('.') || fieldValue.includes(',');\r\n const keyIsCommaOrDot = e.key === '.' || e.key === ',';\r\n\r\n if (!NUMBER_DOT_COMMA.test(e.key) || (keyIsCommaOrDot && fieldHasCommaOrDot)) {\r\n e.preventDefault();\r\n }\r\n\r\n const separator = getDecimalSeparator(this.props.locale);\r\n const replace = separator === '.' ? ',' : '.';\r\n (e as any).target.value = fieldValue.replace(replace, separator);\r\n }}\r\n aria-live='polite'\r\n aria-label={`${this.props.inputQuantityAriaLabel}`}\r\n role='spinbutton'\r\n aria-valuemin={1}\r\n aria-valuemax={this.maximum}\r\n aria-valuenow={Number.parseFloat(currentValue.toString()) || 0}\r\n ref={this.inputRef}\r\n disabled={this.props.disabled}\r\n data-nomodalcss\r\n />\r\n \r\n
\r\n \r\n = {this.totalFormatted} \r\n \r\n \r\n
\r\n {!hideUnitConversion && (\r\n <>\r\n
\r\n 1 = \r\n {`${this.multipleOf} `}\r\n \r\n
\r\n
\r\n {this._getUnitOfMeasureConversion()}\r\n
\r\n \r\n )}\r\n
\r\n );\r\n }\r\n\r\n private _getUnitOfMeasureConversion = (): JSX.Element | undefined => {\r\n if (!this.props.unitConversions || !this.props.product?.DefaultUnitOfMeasure) {\r\n return undefined;\r\n }\r\n\r\n const conversions = this.props.unitConversions?.filter(x => x.FromUnitOfMeasureSymbol === this.props.product?.DefaultUnitOfMeasure);\r\n const conversion = getMostRelevantConversion(conversions);\r\n\r\n if (!conversion) {\r\n return undefined;\r\n }\r\n\r\n const factor = getRoundedFactor(conversion).toLocaleString(this.props.locale, {\r\n minimumFractionDigits: getMinimumDecimals(conversion.ToUnitOfMeasureSymbol),\r\n maximumFractionDigits: 2,\r\n useGrouping: false\r\n });\r\n const defaultUOM = humanizeUnitOfMeasure(this.props.context, this.props.product?.DefaultUnitOfMeasure, this.props.product);\r\n const conversionUOM = humanizeUnitOfMeasure(this.props.context, conversion.ToUnitOfMeasureSymbol).toLocaleLowerCase();\r\n\r\n return (\r\n
\r\n 1 {defaultUOM} = {`${factor} ${conversionUOM}`}\r\n
\r\n );\r\n };\r\n\r\n private _convertIncomingQuantity = (quantity: number): number => {\r\n return quantity / this.multipleOf;\r\n };\r\n\r\n private _convertOutgoingQuantity = (quantity: number): number => {\r\n const outgoing = quantity * this.multipleOf;\r\n // We need to always round to nearest 2 decimal places to avoid floating point errors in quantity validation\r\n return Math.round((outgoing + Number.EPSILON) * 1000) / 1000;\r\n };\r\n\r\n private _onToggleBreakoff = (checked: boolean): void => {\r\n this.setState({ breakoff: checked });\r\n this.props.onBreakoffChange?.(checked);\r\n };\r\n\r\n private _onIncrementalChange(amount: number): void {\r\n const updatedQuantity = this.state.parsedCurrentInput + amount;\r\n\r\n if (this._isValidNewQuantity(updatedQuantity)) {\r\n this.props.onChange?.(this._convertOutgoingQuantity(updatedQuantity));\r\n }\r\n }\r\n\r\n private readonly _clamp = (total: number): number => {\r\n if (this.productMinimumQuantity && total >= 1 && total < this.productMinimumQuantity) {\r\n return this.productMinimumQuantity / this.multipleOf;\r\n } else if (this.productMaximumQuantity && total > this.productMaximumQuantity) {\r\n return this.productMaximumQuantity / this.multipleOf;\r\n } else {\r\n return total / this.multipleOf;\r\n }\r\n };\r\n\r\n private readonly _isValidNewQuantity = (newQuantity: number): boolean => {\r\n if (newQuantity === 0 && this.props.allowZero) {\r\n return true;\r\n }\r\n return !isNaN(newQuantity) && newQuantity >= this.minimum && newQuantity <= this.maximum;\r\n };\r\n\r\n private _handleChange(e: React.ChangeEvent): void {\r\n let newValue: string | number = e.target.value;\r\n\r\n e.persist();\r\n this.setState({ currentInput: newValue }, () => {\r\n if (typeof newValue === 'string') {\r\n newValue = Number.parseFloat(newValue.replace(',', '.'));\r\n }\r\n\r\n if (this._isValidNewQuantity(newValue)) {\r\n this.props.onChange?.(this._convertOutgoingQuantity(newValue));\r\n }\r\n });\r\n }\r\n\r\n private _validateQuantity(e: React.FocusEvent): void {\r\n const currentValue = Number.parseFloat(e.target.value.replace(',', '.') || '0');\r\n const total = this.multipleOf * currentValue;\r\n const newValue = Math.max(this._clamp(total) ?? 0, Number(!this.props.allowZero));\r\n\r\n e.persist();\r\n this.setState({ currentInput: newValue }, () => {\r\n this.props.onChange?.(this._convertOutgoingQuantity(newValue));\r\n });\r\n }\r\n}\r\n","/*!\n * Copyright (c) Microsoft Corporation.\n * All rights reserved. See LICENSE in the project root for license information.\n */\n\n/* eslint-disable no-duplicate-imports */\nimport { Autosuggestions } from '@msdyn365-commerce/commerce-entities';\nimport {\n CacheType,\n createObservableDataAction,\n getCatalogId,\n IAction,\n IActionContext,\n IActionInput,\n ICreateActionContext\n} from '@msdyn365-commerce/core';\nimport {\n AttributeDataType,\n ChannelInventoryConfiguration,\n ProductRefinerSource,\n ProductRefinerValue,\n ProductSearchCriteria,\n SearchSuggestion,\n SearchSuggestionCriteria\n} from '@msdyn365-commerce/retail-proxy';\nimport {\n getInventoryConfigurationAsync,\n getSearchSuggestionsAsync\n} from '@msdyn365-commerce/retail-proxy/dist/DataActions/StoreOperationsDataActions.g';\nimport { generateImageUrl } from '@msdyn365-commerce-modules/retail-actions';\nimport { addAllAttributeRefiners, addOrUpdateZeroPriceRefiner } from '../../../shared-utils/refiner-utils';\nimport { addAlcoholRefiner, shouldFilterAlcohol } from '../../../shared-utils/refiner-utils.alcohol';\n\nexport enum SuggestionType {\n Category = 'ScopedCategory',\n Keyword = 'Keyword',\n Product = 'Product',\n None = 'None'\n}\n\n/**\n * This setting defines inventory filtering options.\n */\nexport enum ProductListInventoryFilteringOptions {\n /**\n * Filter out all products out of stock.\n */\n HideOOS = 'hideOOS',\n\n /**\n * Sort products by availability, OOS goes last.\n */\n SortOOS = 'sortOOS',\n\n /**\n * No filtering selected.\n */\n Default = 'default'\n}\n\n/**\n * Input class for auto suggest search input.\n */\nexport class AutoSuggestInput implements IActionInput {\n public searchQuery?: string;\n\n public topResultsCount?: number;\n\n public suggestionType?: string;\n\n public hitPrefix?: string;\n\n public hitSuffix?: string;\n\n public constructor(searchText?: string, top?: number, suggestionType?: string, hitPrefix?: string, hitSuffix?: string) {\n this.searchQuery = searchText;\n this.topResultsCount = top;\n this.suggestionType = suggestionType;\n this.hitPrefix = hitPrefix;\n this.hitSuffix = hitSuffix;\n }\n\n public getCacheKey = () => 'AutoSuggestSearchSuggestions';\n\n public getCacheObjectType = () => 'AutoSuggestSearchSuggestions';\n\n public dataCacheType = (): CacheType => 'none';\n}\n\nconst createInput = (inputData: ICreateActionContext) => {\n return new AutoSuggestInput();\n};\n\n/**\n * Calls the Retail API and returns a auto-suggest suggestions.\n * @param input\n * @param ctx\n */\nexport async function getSearchSuggestionsAction(input: AutoSuggestInput, ctx: IActionContext): Promise {\n // If no input is provided fail out\n if (!input || !input.searchQuery) {\n throw new Error('[getSearchSuggestionsAction]No valid Input was provided, failing');\n }\n\n const autosuggest: Autosuggestions = {};\n\n const autoSuggestPromises = [_getAutoSuggest(input, autosuggest, ctx)];\n return Promise.all(autoSuggestPromises).then(() => {\n return autosuggest;\n });\n}\n\n/**\n * Returns inventory in stock sortable refiner value.\n * @param channelInventoryConfiguration - The channelInventoryConfiguration.\n * @param isInStock - The flag indicating whether is getting in-stock refiner or out-of-stock refiner.\n * @returns Refiners.\n */\nconst getInventorySortableRefinerValue = (\n channelInventoryConfiguration: ChannelInventoryConfiguration,\n isInStock: boolean\n): ProductRefinerValue | undefined => {\n if (channelInventoryConfiguration && channelInventoryConfiguration.ProductAvailabilitySortableAttributeRecordId) {\n return {\n RefinerRecordId: channelInventoryConfiguration.ProductAvailabilitySortableAttributeRecordId,\n DataTypeValue: AttributeDataType.TrueFalse,\n LeftValueBoundString: isInStock ? 'true' : 'false',\n RightValueBoundString: isInStock ? 'true' : 'false',\n UnitText: '',\n RowNumber: 0,\n Count: 0,\n ExtensionProperties: [],\n RefinerSourceValue: ProductRefinerSource.Attribute\n };\n }\n return undefined;\n};\n\nasync function _getAutoSuggest(input: AutoSuggestInput, autosuggest: Autosuggestions, ctx: IActionContext): Promise {\n const catalogId = getCatalogId(ctx.requestContext);\n let productSearchCriteria: ProductSearchCriteria = {\n SearchCondition: input.searchQuery && input.searchQuery.length > 0 ? input.searchQuery : '',\n Context: {\n ChannelId: +ctx.requestContext.apiSettings.channelId,\n CatalogId: catalogId\n }\n };\n\n if (ctx.requestContext.app.config?.productListInventoryDisplay === ProductListInventoryFilteringOptions.HideOOS) {\n const channelInventoryConfiguration = await getInventoryConfigurationAsync({ callerContext: ctx });\n const isInStockRefiner = true;\n const inventoryRefinerValue = getInventorySortableRefinerValue(channelInventoryConfiguration, isInStockRefiner);\n\n if (inventoryRefinerValue) {\n productSearchCriteria = {\n ...productSearchCriteria,\n Refinement: [inventoryRefinerValue]\n };\n }\n }\n\n const searchCriteria: SearchSuggestionCriteria = {\n ProductSearchCriteria: productSearchCriteria,\n HitPrefix: input.hitPrefix,\n HitSuffix: input.hitSuffix,\n SuggestionType: input.suggestionType\n };\n\n searchCriteria.ProductSearchCriteria!.Refinement = addOrUpdateZeroPriceRefiner(ctx, searchCriteria.ProductSearchCriteria?.Refinement);\n\n if (shouldFilterAlcohol(ctx)) {\n await addAlcoholRefiner(ctx, searchCriteria.ProductSearchCriteria!);\n }\n\n await addAllAttributeRefiners(ctx, searchCriteria.ProductSearchCriteria!);\n\n const searchSuggestions = await getSearchSuggestionsAsync(\n { callerContext: ctx, queryResultSettings: { Paging: { Top: input.topResultsCount } } },\n searchCriteria\n );\n\n if (searchSuggestions && searchSuggestions.length > 0) {\n searchSuggestions.map((item: SearchSuggestion) => {\n // Generate image url\n item.ImageUrl = item.ImageUrl ? generateImageUrl(item.ImageUrl, ctx.requestContext.apiSettings) : '';\n\n // Hide price. Active price will be retrieved later\n if (item.Value3?.Value?.DecimalValue) {\n item.Value3.Value.DecimalValue = undefined;\n }\n });\n\n autosuggest.AllSearchResults = searchSuggestions;\n } else {\n ctx.telemetry.error(\n `[getSearchSuggestionsAction] unable to get availabilites for search with suggestion type ${searchCriteria.SuggestionType}`\n );\n }\n}\n\nexport const getSearchSuggestionsActionDataAction = createObservableDataAction({\n id: '@msdyn365-commerce-modules/search/get-auto-suggest-suggestions',\n action: >getSearchSuggestionsAction,\n input: createInput\n});\n\nexport default getSearchSuggestionsActionDataAction;\n","/*!\n * Copyright (c) Microsoft Corporation.\n * All rights reserved. See LICENSE in the project root for license information.\n */\n\n/* eslint-disable no-duplicate-imports */\n/* eslint-disable security/detect-non-literal-regexp */\nimport MsDyn365, { getRichTextHtml } from '@msdyn365-commerce/core';\nimport { ProductRefiner, ProductRefinerSource, ProductRefinerValue, SearchSuggestion } from '@msdyn365-commerce/retail-proxy';\nimport { format, getPayloadObject, getTelemetryAttributes, IPayLoad, ITelemetryContent } from '@msdyn365-commerce-modules/utilities';\nimport * as React from 'react';\n\nimport { IVinhusetSearchData } from '../vinhuset-search.data';\nimport { IVinhusetSearchProps } from '../vinhuset-search.props.autogenerated';\nimport { formatString } from '../../../shared-utils/string-utils';\n\nexport interface ISearchCategorySuggestProps {\n searchCategorySuggestClass: string;\n searchPageURL: string;\n searchQsp: string | undefined;\n hitPrefix: string;\n hitSuffix: string;\n autoSuggestProps: IVinhusetSearchProps;\n searchText: string;\n searchRefiners: ProductRefiner[] | undefined;\n suggestions: SearchSuggestion[] | undefined;\n telemetryContent?: ITelemetryContent;\n shouldShowFullPath?: boolean;\n searchTermCompleted: string | undefined;\n categorySuggestionProductCount: string;\n categorySuggestionProductCountPlural: string;\n categorySuggestionJoinerText: string;\n}\n\nexport interface ISearchCategoryViewProps {\n title: React.ReactNode;\n text: React.ReactNode[];\n}\n\nlet payLoad: IPayLoad;\n\n/**\n * CategorySuggestionsComponent.\n * @param props\n */\nexport const CategorySuggestionsComponent = (props: ISearchCategorySuggestProps): ISearchCategoryViewProps | undefined => {\n const {\n suggestions,\n searchText,\n autoSuggestProps: {\n resources: { categorySuggestionHeading }\n }\n } = props;\n\n const reactNodes: React.ReactNode[] = [];\n payLoad = getPayloadObject('click', props.telemetryContent!, '');\n\n suggestions?.map(item => {\n reactNodes.push(_assembleNode(item, props));\n });\n\n // @ts-ignore\n const titleNode = _renderTitle(categorySuggestionHeading, searchText);\n\n return { title: null, text: reactNodes };\n};\n\nconst _renderTitle = (categorySuggestionHeading: string, searchText: string) => {\n const categoryAutoSuggestionHeading = categorySuggestionHeading\n ? format(categorySuggestionHeading, searchText)\n : `Search \"${searchText}\" in categories`;\n\n return
  • {categoryAutoSuggestionHeading}
  • ;\n};\n\nconst _assembleNode = (item: SearchSuggestion, props: ISearchCategorySuggestProps) => {\n const { searchText, hitPrefix, hitSuffix, shouldShowFullPath } = props;\n\n const splitValue = shouldShowFullPath ? item.Value?.replace(/\\|/g, ', ') : item.Value && item.Value.split('|').pop();\n const ariaLabel = splitValue\n ? splitValue.replace(new RegExp(`[${hitPrefix}]`, 'gi'), '').replace(new RegExp(`[${hitSuffix}]`, 'gi'), '')\n : item.Value && item.Value.replace(new RegExp(`[${hitPrefix}]`, 'gi'), '').replace(new RegExp(`[${hitSuffix}]`, 'gi'), '');\n const fullText = `${props.searchTermCompleted?.toUpperCase()} ${props.categorySuggestionJoinerText} ${ariaLabel}`;\n payLoad.contentAction.etext = item.Value;\n const attribute = getTelemetryAttributes(props.telemetryContent!, payLoad);\n const count = item.Value3?.Value?.IntegerValue;\n const productCountLabel = count === 1\n ? props.categorySuggestionProductCount\n : props.categorySuggestionProductCountPlural;\n return (\n
  • \n \n \n {props.searchTermCompleted?.toUpperCase()}\n   {props.categorySuggestionJoinerText}  \n {_generateLink(item, searchText, props) && _getHighlightedText(splitValue ? splitValue : '', hitPrefix, hitSuffix)}\n \n
    ({formatString(productCountLabel, item.Value3?.Value?.IntegerValue)})
    \n
    \n
  • \n );\n};\n\nconst _generateLink = (suggestion: SearchSuggestion, searchText: string, props: ISearchCategorySuggestProps): string => {\n return suggestion && suggestion.Id ? _getCategoryLink(suggestion.Id, searchText, props) : '';\n};\n\nconst _getCategoryLink = (id: string, searchText: string, props: ISearchCategorySuggestProps): string => {\n const { searchPageURL, searchQsp, searchRefiners } = props;\n\n if (!MsDyn365.isBrowser) {\n return '';\n }\n\n const queryUrl = new URL(searchPageURL, window.location.href);\n\n if (searchQsp && searchText) {\n queryUrl.searchParams.set(searchQsp, searchText);\n }\n\n const categoryRefiners = searchRefiners?.find(refiners => {\n return refiners.SourceValue === ProductRefinerSource.Category;\n });\n const refiner = categoryRefiners?.Values?.find(item => {\n return item.RefinerRecordId === Number.parseInt(id, 10);\n });\n\n const encodedRefiner = refiner && JSON.stringify(compressRefiners([refiner]));\n if (encodedRefiner) {\n queryUrl.searchParams.set('refiners', encodedRefiner);\n }\n\n return queryUrl.href;\n};\n\nconst _getHighlightedText = (suggestion: string, hitPrefix: string, hitSuffix: string): JSX.Element => {\n const formattedText = suggestion\n .replace(new RegExp(`[${hitPrefix}]`, 'gi'), '')\n .replace(new RegExp(`[${hitSuffix}]`, 'gi'), '');\n\n // eslint-disable-next-line react/no-danger\n return ;\n};\n\n// TODO: This code is currently duplicated in categoryautosuggest need to either remove one of these files\n// or move this code to a common place\nconst compressedRefinerKeys = [\n 'DataTypeValue',\n 'LeftValueBoundString',\n 'LeftValueBoundLocalizedString',\n 'RefinerRecordId',\n 'RefinerSourceValue',\n 'RightValueBoundString',\n 'RightValueBoundLocalizedString',\n 'UnitText',\n 'RowNumber'\n];\n\n/**\n * Compressed a list of refiners for use in URLs.\n * @param refiners The uncompressed refiners.\n */\nconst compressRefiners = (refiners: ProductRefinerValue[]) => {\n const compressedRefiners: (string | number)[][] = [];\n\n refiners.forEach(refiner => {\n const compressedRefiner: (string | number)[] = [];\n compressedRefinerKeys.forEach(refinerKey => {\n compressedRefiner.push(refiner[refinerKey]);\n });\n compressedRefiners.push(compressedRefiner);\n });\n\n return compressedRefiners;\n};\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\nimport { ICoreContext, getAsset } from '@msdyn365-commerce/core';\r\nimport { Button } from '@msdyn365-commerce-modules/utilities';\r\nimport * as React from 'react';\r\nimport classnames from 'classnames';\r\n\r\nexport interface ISearchFormProps {\r\n context: ICoreContext;\r\n disableSubmitSearch: boolean | undefined;\r\n searchTextInput: React.RefObject;\r\n maxChars: number;\r\n searchQsp: string;\r\n searchPlaceholder: string;\r\n query: string;\r\n ariaLabelCancel: string;\r\n ariaLabelSearch: string;\r\n ariaLabelSubmit: string;\r\n handleCancelSearchChange(): void;\r\n handleScannerButtonClick(): void;\r\n handleInputChange(query: string): void;\r\n}\r\n\r\nexport interface ISearchFormViewProps {\r\n input: React.ReactNode;\r\n submitBtn: React.ReactNode;\r\n cancelBtn: React.ReactNode;\r\n scannerBtn?: React.ReactNode;\r\n}\r\n\r\n/**\r\n * On Input Change functionality.\r\n * @param handleInputChange -Input change function.\r\n * @returns Set updated input value.\r\n */\r\nconst onInputChangeFunction = (handleInputChange: (query: string) => void) => (event: React.ChangeEvent) => {\r\n handleInputChange(event.target.value || '');\r\n};\r\nexport const FormComponent = (props: ISearchFormProps): ISearchFormViewProps => {\r\n const {\r\n context,\r\n searchQsp,\r\n searchPlaceholder,\r\n searchTextInput,\r\n handleInputChange,\r\n maxChars,\r\n disableSubmitSearch,\r\n handleCancelSearchChange,\r\n handleScannerButtonClick,\r\n query,\r\n ariaLabelCancel,\r\n ariaLabelSearch,\r\n ariaLabelSubmit\r\n } = props;\r\n\r\n const onInputChange = onInputChangeFunction(handleInputChange);\r\n\r\n const inputNode = (\r\n \r\n );\r\n\r\n const submitBtnNode = !disableSubmitSearch &&\r\n \r\n ;\r\n\r\n const cancelBtNoden = (\r\n \r\n );\r\n\r\n const scannerBtnNode = (\r\n \r\n \r\n \r\n );\r\n\r\n return { input: inputNode, cancelBtn: cancelBtNoden, submitBtn: submitBtnNode, scannerBtn: scannerBtnNode };\r\n};\r\n","/*!\n * Copyright (c) Microsoft Corporation.\n * All rights reserved. See LICENSE in the project root for license information.\n */\n\n/* eslint-disable no-duplicate-imports */\n/* eslint-disable security/detect-non-literal-regexp */\nimport MsDyn365, { getRichTextHtml } from '@msdyn365-commerce/core';\nimport { SearchSuggestion } from '@msdyn365-commerce/retail-proxy';\nimport { getPayloadObject, getTelemetryAttributes, IPayLoad, ITelemetryContent } from '@msdyn365-commerce-modules/utilities';\nimport * as React from 'react';\n\nimport { IVinhusetSearchData } from '../vinhuset-search.data';\nimport { IVinhusetSearchProps } from '../vinhuset-search.props.autogenerated';\n\nexport interface ISearchKeywordSuggestProps {\n searchKeywordSuggestClass: string;\n searchPageURL: string;\n searchQsp: string | undefined;\n hitPrefix: string;\n hitSuffix: string;\n autoSuggestProps: IVinhusetSearchProps;\n searchText: string;\n searchTermCompleted: string | undefined;\n suggestions: SearchSuggestion[] | undefined;\n telemetryContent?: ITelemetryContent;\n}\n\nexport interface ISearchKeywordViewProps {\n text: React.ReactNode[];\n}\n\nlet payLoad: IPayLoad;\n\n/**\n * KeywordSuggestionsComponent.\n * @param props\n */\nexport const KeywordSuggestionsComponent = (props: ISearchKeywordSuggestProps): ISearchKeywordViewProps | undefined => {\n const { searchTermCompleted, suggestions, hitPrefix, hitSuffix } = props;\n\n payLoad = getPayloadObject('click', props.telemetryContent!, '');\n\n const reactNodes: React.ReactNode[] = [];\n\n if (suggestions && searchTermCompleted) {\n suggestions.splice(0, 0, {\n Id: 'permanent_query',\n Value: `${hitPrefix}${searchTermCompleted.toUpperCase()}${hitSuffix}`\n });\n\n suggestions?.slice(0, 1).map(item => {\n reactNodes.push(_assembleNode(item, hitPrefix, hitSuffix, props));\n });\n }\n\n /* suggestions?.map(item => {\n reactNodes.push(_assembleNode(item, hitPrefix, hitSuffix, props));\n }); */\n\n return { text: reactNodes };\n};\n\nconst _assembleNode = (item: SearchSuggestion, hitPrefix: string, hitSuffix: string, props: ISearchKeywordSuggestProps) => {\n const ariaLabel =\n item.Value && item.Value.replace(new RegExp(`[${hitPrefix}]`, 'gi'), '').replace(new RegExp(`[${hitSuffix}]`, 'gi'), '');\n payLoad.contentAction.etext = ariaLabel;\n const attribute = getTelemetryAttributes(props.telemetryContent!, payLoad);\n return (\n
  • \n \n {_generateLink(item, hitPrefix, hitSuffix, props) &&\n _getHighlightedText(item.Value ? item.Value : '', hitPrefix, hitSuffix)}\n \n
  • \n );\n};\n\nconst _generateLink = (suggestion: SearchSuggestion, hitPrefix: string, hitSuffix: string, props: ISearchKeywordSuggestProps): string => {\n const { searchPageURL, searchQsp } = props;\n\n const formattedLink = (suggestion.Value as string)\n .replace(new RegExp(`[${hitPrefix}]`, 'gi'), '')\n .replace(new RegExp(`[${hitSuffix}]`, 'gi'), '');\n\n if (!MsDyn365.isBrowser) {\n return '';\n }\n\n const queryUrl = new URL(searchPageURL, window.location.href);\n if (searchQsp && formattedLink) {\n queryUrl.searchParams.set(searchQsp, formattedLink);\n }\n\n return queryUrl.href;\n};\n\nconst _getHighlightedText = (suggestion: string, hitPrefix: string, hitSuffix: string): JSX.Element => {\n const formattedText = suggestion\n .replace(new RegExp(`[${hitPrefix}]`, 'gi'), '')\n .replace(new RegExp(`[${hitSuffix}]`, 'gi'), '');\n\n // eslint-disable-next-line react/no-danger\n return ;\n};\n","import * as React from 'react';\r\nimport {\r\n format,\r\n Tooltip\r\n} from '@msdyn365-commerce-modules/utilities';\r\nimport { ICartState } from '@msdyn365-commerce/global-state';\r\n\r\nexport interface ICartCountProps {\r\n productId: number;\r\n cart: ICartState;\r\n inCartTooltipText?: string;\r\n}\r\n\r\nconst CartCount = (props: ICartCountProps) => {\r\n const { cart, productId, inCartTooltipText } = props;\r\n const [showCartCountTooltip, setShowCartCountTooltip] = React.useState(false);\r\n\r\n // const cartQuantity = cart?.cart.CartLines?.find(x => x.ProductId === productId)?.Quantity;\r\n const cartQuantity = cart?.cart.CartLines?.filter(x => x.ProductId === productId).reduce((acc, val) => acc + (val.Quantity || 0), 0);\r\n\r\n if (!cartQuantity) {\r\n return null;\r\n }\r\n\r\n const cartCountId = `productResults-item-cart-count-${productId}`;\r\n const tooltipString = inCartTooltipText || '{0} i handlekurven';\r\n const tooltipText = format(tooltipString, cartQuantity);\r\n\r\n return (\r\n setShowCartCountTooltip(true)}\r\n onMouseOut={() => setShowCartCountTooltip(false)}\r\n onTouchStart={() => setShowCartCountTooltip(true)}\r\n >\r\n {cartQuantity}\r\n \r\n {tooltipText}\r\n \r\n \r\n );\r\n};\r\n\r\nexport default CartCount;\r\n","import * as React from 'react';\r\nimport { ICoreContext } from '@msdyn365-commerce/core';\r\nimport { ProductPrice, SimpleProduct } from '@msdyn365-commerce/retail-proxy';\r\nimport { ICartState } from '@msdyn365-commerce/global-state';\r\nimport ProductListOrderQuantity from '../../../components/common/product-list-order-quantity';\r\nimport { AddToCartComponent, IAddToCartToastResources } from '../../vinhuset-buybox/common/add-to-cart.component';\r\nimport { ProductSearchResultExt } from '../../vinhuset-search-result-container/components';\r\nimport CartCount from './cart-count';\r\nimport PQueue from 'p-queue';\r\nimport { BuyValidationResult } from '../../../themes/vinhuset-adventureworks/views/components/product.component';\r\nimport { IVinhusetSearchResources } from '../vinhuset-search.props.autogenerated';\r\n\r\ninterface IBuySectionProps {\r\n context: ICoreContext;\r\n id: string;\r\n typeName: string;\r\n resources: IVinhusetSearchResources;\r\n productRecordId: number;\r\n simpleProduct: SimpleProduct | undefined;\r\n productPrice: ProductPrice | undefined;\r\n cart: ICartState;\r\n cartQueue: PQueue | undefined;\r\n inCartTooltipText: string | undefined;\r\n onBuyValidate: (product: ProductSearchResultExt, quantity: number) => Promise;\r\n onBreakoffChange?: (productRecordId: number, breakoff: boolean) => void;\r\n}\r\n\r\nconst BuySection = (props: IBuySectionProps) => {\r\n const {\r\n id,\r\n typeName,\r\n context,\r\n resources,\r\n productRecordId,\r\n simpleProduct,\r\n productPrice,\r\n cart,\r\n cartQueue,\r\n inCartTooltipText\r\n } = props;\r\n const [quantity, setQuantity] = React.useState(0);\r\n const [breakoff, setBreakoff] = React.useState(false);\r\n const [forceUpdate , setForceUpdate] = React.useState(0);\r\n\r\n const onContainerClick = React.useCallback((e: React.MouseEvent) => {\r\n if ((e.target as HTMLElement).closest('.vinhuset-switch')) {\r\n // No need to prevent default if the click is on the switch and will in fact break the switch\r\n return;\r\n }\r\n\r\n e.preventDefault();\r\n e.stopPropagation();\r\n }, []);\r\n\r\n const toastStrings: IAddToCartToastResources = {\r\n errorHeader: resources.toastErrorHeader,\r\n productsAddedToCart: resources.productsAddedToCart,\r\n productsRemovedFromCart: resources.productsRemovedFromCart,\r\n productsUpdatedInCart: resources.productsUpdatedInCart,\r\n goToCart: resources.toastGoToCart,\r\n noAccessToProduct: resources.toastNoAccessToProduct\r\n };\r\n\r\n const productSearchResult: ProductSearchResultExt = {\r\n RecordId: productRecordId,\r\n Price: productPrice?.CustomerContextualPrice || 0\r\n };\r\n\r\n return (\r\n
    e.preventDefault()} onClick={onContainerClick}>\r\n {\r\n setBreakoff(value);\r\n props.onBreakoffChange?.(props.productRecordId, value);\r\n }}\r\n />\r\n\r\n {simpleProduct && (\r\n
    \r\n \r\n { setForceUpdate(forceUpdate + 1); }}\r\n />\r\n
    \r\n )}\r\n
    \r\n );\r\n};\r\n\r\nexport default BuySection;\r\n","/*!\n * Copyright (c) Microsoft Corporation.\n * All rights reserved. See LICENSE in the project root for license information.\n */\n\n/* eslint-disable no-duplicate-imports */\n/* eslint-disable security/detect-non-literal-regexp */\nimport { PriceComponent } from '@msdyn365-commerce/components';\nimport { getRichTextHtml, IActionContext, IImageSettings, Image, ITelemetry } from '@msdyn365-commerce/core';\nimport { format, ProductPrice, SearchSuggestion, SimpleProduct } from '@msdyn365-commerce/retail-proxy';\nimport { getProductPageUrlSync } from '@msdyn365-commerce-modules/retail-actions';\nimport {\n getPayloadObject,\n getTelemetryAttributes,\n INodeProps,\n IPayLoad,\n ITelemetryContent,\n NodeTag\n} from '@msdyn365-commerce-modules/utilities';\nimport { ICartState } from '@msdyn365-commerce/global-state';\nimport * as React from 'react';\n\nimport { IVinhusetSearchData } from '../vinhuset-search.data';\nimport { IVinhusetSearchProps, IVinhusetSearchResources } from '../vinhuset-search.props.autogenerated';\nimport BuySection from './buy-section';\nimport PQueue from 'p-queue';\nimport { BuyValidationResult } from '../../../themes/vinhuset-adventureworks/views/components/product.component';\nimport { ProductSearchResultExt } from '../../vinhuset-search-result-container/components';\nimport { multiplyPriceBy } from '../../../shared-utils/price-utils';\nimport { humanizeUnitOfMeasure } from '../../../components/unit-of-measure';\n\n/**\n * Search product suggest resources.\n */\nexport interface ISearchProductSuggestResources {\n freePriceText: string;\n inCartTooltipText: string;\n pricePerText: string;\n}\n\nexport interface ISearchProductSuggestProps {\n searchProductSuggestClass: string;\n searchPageURL: string;\n searchQsp: string | undefined;\n hitPrefix: string;\n hitSuffix: string;\n autoSuggestProps: IVinhusetSearchProps;\n searchText: string;\n suggestions: SearchSuggestion[] | undefined;\n telemetry: ITelemetry;\n moduleType: string;\n moduleId: string;\n telemetryContent?: ITelemetryContent;\n locale: string;\n resources?: ISearchProductSuggestResources;\n activePrices: { [key: string]: ProductPrice };\n simpleProducts: SimpleProduct[];\n cart: ICartState | undefined;\n cartQueue: PQueue | undefined;\n breakoffProducts: { [key: number]: boolean };\n onBuyValidate: (product: ProductSearchResultExt, quantity: number) => Promise;\n onBreakoffChange?: (productRecordId: number, breakoff: boolean) => void;\n}\n\nexport interface ISearchProductViewProps {\n title: React.ReactNode;\n items: ISearchProductItemViewProps[];\n}\n\nexport interface ISearchProductItemViewProps {\n text: React.ReactNode;\n thumbnail: React.ReactNode;\n price: React.ReactNode;\n buySection: React.ReactNode;\n LiProduct: INodeProps;\n AProduct: INodeProps;\n id: string | undefined;\n}\n\nlet payLoad: IPayLoad;\nlet telemetryContent: ITelemetryContent | undefined;\n\n/**\n * ProductSuggestionsComponent.\n * @param props\n */\nexport const ProductSuggestionsComponent = (props: ISearchProductSuggestProps): ISearchProductViewProps | undefined => {\n const {\n suggestions,\n hitSuffix,\n hitPrefix,\n autoSuggestProps: {\n context: { actionContext },\n resources: { productSuggestionHeading }\n },\n moduleType,\n moduleId\n } = props;\n const reactNodes: ISearchProductItemViewProps[] = [];\n telemetryContent = props.telemetryContent;\n payLoad = getPayloadObject('click', props.telemetryContent!, '');\n\n suggestions?.map(item => {\n reactNodes.push(_assembleNode(item, hitPrefix, hitSuffix, actionContext, props, moduleType, moduleId));\n });\n\n const titleNode = _renderTitle(productSuggestionHeading);\n\n return { title: titleNode, items: reactNodes };\n};\n\nconst _renderTitle = (productSuggestionHeading: string) => {\n const productAutoSuggestionHeading = productSuggestionHeading ? productSuggestionHeading : 'Go to products';\n\n return
  • {productAutoSuggestionHeading}
  • ;\n};\n\nconst _assembleNode = (\n item: SearchSuggestion,\n hitPrefix: string,\n hitSuffix: string,\n actionContext: IActionContext,\n props: ISearchProductSuggestProps,\n moduleType: string,\n moduleId: string\n): ISearchProductItemViewProps => {\n const altText =\n item.Value && item.Value.replace(new RegExp(`[${hitPrefix}]`, 'gi'), '').replace(new RegExp(`[${hitSuffix}]`, 'gi'), '');\n\n const price = props.activePrices[item.Id!];\n const simpleProduct = props.simpleProducts.find(product => product.RecordId === parseInt(item.Id!, 10));\n\n return {\n text: _getHighlightedText(item.Value ? item.Value : '', hitPrefix, hitSuffix),\n thumbnail: _renderThumbnail(item, altText ? altText : '', props),\n price: _renderPrice(price, simpleProduct, moduleId, moduleType, props),\n buySection: _renderBuySection(item.Id!, props),\n LiProduct: _getLiWrapper(),\n AProduct: _getAWrapper(item, hitPrefix, hitSuffix, actionContext, props),\n id: item.Id\n };\n};\n\nconst _getLiWrapper = () => {\n return {\n className: 'msc-autoSuggest__productResults-item',\n tag: 'li' as NodeTag\n };\n};\n\nconst _getAWrapper = (\n item: SearchSuggestion,\n hitPrefix: string,\n hitSuffix: string,\n actionContext: IActionContext,\n props: ISearchProductSuggestProps\n) => {\n const {\n autoSuggestProps: { context }\n } = props;\n const ariaLabel =\n item.Value && item.Value.replace(new RegExp(`[${hitPrefix}]`, 'gi'), '').replace(new RegExp(`[${hitSuffix}]`, 'gi'), '');\n\n payLoad.contentAction.recid = item.Id;\n const attribute = getTelemetryAttributes(telemetryContent!, payLoad);\n const productPrice = item.Value3?.Value?.DecimalValue ? context.cultureFormatter.formatCurrency(item.Value3.Value.DecimalValue) : undefined;\n\n return {\n className: 'msc-autoSuggest__productResults-item',\n tag: 'a' as NodeTag,\n 'aria-label': `${ariaLabel!} ${productPrice || ''}`,\n href: _generateLink(item, hitPrefix, hitSuffix, actionContext),\n ...attribute\n };\n};\n\nconst _generateLink = (suggestion: SearchSuggestion, hitPrefix: string, hitSuffix: string, actionContext: IActionContext) => {\n const formattedLink = (suggestion.Value as string)\n .replace(new RegExp(`[${hitPrefix}]`, 'gi'), '')\n .replace(new RegExp(`[${hitSuffix}]`, 'gi'), '');\n return suggestion.Value && suggestion.Id\n ? getProductPageUrlSync(formattedLink, (suggestion.Id as unknown) as number, actionContext, undefined)\n : '';\n};\n\nconst _getHighlightedText = (suggestion: string, hitPrefix: string, hitSuffix: string): JSX.Element => {\n const formattedText = suggestion\n .replace(new RegExp(`[${hitPrefix}]`, 'gi'), '')\n .replace(new RegExp(`[${hitSuffix}]`, 'gi'), '');\n\n return (\n // eslint-disable-next-line react/no-danger\n \n );\n};\n\nconst _renderPrice = (\n price: ProductPrice | undefined,\n simpleProduct: SimpleProduct | undefined,\n moduleId: string,\n moduleType: string,\n props: ISearchProductSuggestProps\n): JSX.Element | null => {\n const {\n autoSuggestProps: { context }\n } = props;\n\n if (!price || !simpleProduct) {\n return (\n \n \n ...\n \n \n );\n }\n\n let productPrice = price;\n\n if (!props.breakoffProducts[simpleProduct.RecordId] && simpleProduct.Behavior?.DefaultQuantity) {\n productPrice = multiplyPriceBy(productPrice, simpleProduct.Behavior.DefaultQuantity);\n }\n\n return (\n
    \n \n {!props.breakoffProducts[simpleProduct.RecordId] && simpleProduct.Behavior?.DefaultQuantity && (\n
    \n \n \n  \n {format(props.resources?.pricePerText || 'pr. {0}', humanizeUnitOfMeasure(props.locale, simpleProduct.DefaultUnitOfMeasure, simpleProduct))}\n \n
    \n )}\n
    \n );\n};\n\nconst _renderBuySection = (itemId: string, props: ISearchProductSuggestProps): JSX.Element | null => {\n const productId = parseInt(itemId, 10);\n\n if (isNaN(productId) || !props.cart) {\n return null;\n }\n\n if (!props.autoSuggestProps.context.request.user.isAuthenticated) {\n return null;\n }\n\n const {\n id,\n typeName,\n context\n } = props.autoSuggestProps;\n const simpleProduct = props.simpleProducts.find(product => product.RecordId === productId);\n const productPrice = props.activePrices[itemId];\n\n return (\n \n );\n};\n\nconst _renderThumbnail = (suggestion: SearchSuggestion, altText: string, props: ISearchProductSuggestProps): JSX.Element | null => {\n const {\n autoSuggestProps: {\n context: {\n request: { gridSettings }\n },\n config: { imageSettings }\n }\n } = props;\n if (imageSettings) {\n imageSettings.cropFocalRegion = true;\n }\n\n if (!suggestion || !suggestion.ImageUrl) {\n props.telemetry.error('Search suggestion content is empty, module wont render.');\n return null;\n }\n\n const defaultImageSettings: IImageSettings = {\n viewports: {\n lg: { q: 'w=64&h=64&m=0&f=webp', w: 64, h: 64 },\n md: { q: 'w=64&h=64&m=0&f=webp', w: 64, h: 64 },\n sm: { q: 'w=64&h=64&m=0&f=webp', w: 64, h: 64 },\n xl: { q: 'w=64&h=64&m=0&f=webp', w: 64, h: 64 },\n xs: { q: 'w=64&h=64&m=0&f=webp', w: 64, h: 64 }\n },\n lazyload: true,\n cropFocalRegion: true\n };\n\n if (imageSettings) {\n imageSettings.viewports = defaultImageSettings.viewports;\n }\n\n return (\n \n );\n};\n","/**\r\n * Copyright (c) Microsoft Corporation\r\n * All rights reserved. See License.txt in the project root for license information.\r\n * IVinhusetSearch contentModule Interface Properties\r\n * THIS FILE IS AUTO-GENERATED - MANUAL MODIFICATIONS WILL BE LOST\r\n */\r\n\r\nimport * as Msdyn365 from '@msdyn365-commerce/core';\r\n\r\nexport interface IVinhusetSearchConfig extends Msdyn365.IModuleConfig {\r\n suggestionTypeCriterion?: ISuggestionTypeCriterionData[];\r\n topResultsCount?: number;\r\n imageSettings?: Msdyn365.IImageSettings;\r\n disableSubmitSearch?: boolean;\r\n searchplaceholderText?: string;\r\n shouldShowFullCategoryPath?: boolean;\r\n noSearchResultImage?: Msdyn365.IImageData;\r\n className?: string;\r\n clientRender?: boolean;\r\n}\r\n\r\nexport interface IVinhusetSearchResources {\r\n searchtext: string;\r\n searchLabelArialLabel: string;\r\n cancelBtnAriaLabel: string;\r\n searchBtnAriaLabel: string;\r\n submitBtnAriaLabel: string;\r\n autoSuggestFoundMessage: string;\r\n noAutoSuggestionMessage: string;\r\n productSuggestionHeading: string;\r\n categorySuggestionHeading: string;\r\n autoSuggestResultLoadingMessage: string;\r\n freePriceText: string;\r\n searchSuggestionHeading: string;\r\n keywordsHeading: string;\r\n noResultText: string;\r\n noResultContentHeadingText: string;\r\n noResultContentParagraphText: string;\r\n clearSearchButtonText: string;\r\n emptyMobileSearchTextHeading: string;\r\n emptyMobileSearchText: string;\r\n categorySuggestionProductCount: string;\r\n categorySuggestionProductCountPlural: string;\r\n categorySuggestionJoinerText: string;\r\n inCartTooltipText: string;\r\n addToCartButtonText: string;\r\n productsAddedToCart: string;\r\n productsRemovedFromCart: string;\r\n productsUpdatedInCart: string;\r\n toastErrorHeader: string;\r\n toastGoToCart: string;\r\n toastNoAccessToProduct: string;\r\n pricePerText: string;\r\n modalCloseButtonText: string;\r\n noCameraDevicesFoundText: string;\r\n errorGettingDevicesText: string;\r\n chooseCameraText: string;\r\n changeCameraText: string;\r\n expiredText: string;\r\n}\r\n\r\nexport const enum SuggestionTypeCriterionSuggestionType {\r\n product = 'product',\r\n keyword = 'keyword',\r\n scopedCategory = 'scopedCategory'\r\n}\r\n\r\nexport interface ISuggestionTypeCriterionData {\r\n SuggestionType?: SuggestionTypeCriterionSuggestionType;\r\n}\r\n\r\nexport interface IVinhusetSearchProps extends Msdyn365.IModule {\r\n resources: IVinhusetSearchResources;\r\n config: IVinhusetSearchConfig;\r\n}\r\n","import * as React from 'react';\r\nimport { ICoreContext, getAsset } from '@msdyn365-commerce/core';\r\nimport { Button, Modal, ModalBody, ModalFooter } from '@msdyn365-commerce-modules/utilities';\r\nimport type { CameraDevice, Html5Qrcode } from 'html5-qrcode';\r\n\r\nconst qrcodeRegionId = \"html5qr-code-full-region\";\r\nlet cachedModule: typeof import('html5-qrcode') | undefined;\r\n\r\nasync function getScannerModule() {\r\n if (!cachedModule) {\r\n cachedModule = await import('html5-qrcode');\r\n }\r\n return cachedModule;\r\n}\r\n\r\nexport interface IBarcodeScannerResources {\r\n noCameraDevicesFound?: string;\r\n errorGettingDevices?: string;\r\n loading?: string;\r\n chooseCamera?: string;\r\n changeCamera?: string;\r\n close?: string;\r\n}\r\n\r\nexport interface IBarcodeScannerProps {\r\n context: ICoreContext;\r\n modalIsOpen: boolean;\r\n onClose: () => void;\r\n onFound: (text: string) => void;\r\n resources?: IBarcodeScannerResources;\r\n}\r\n\r\nconst DefaultResources: IBarcodeScannerResources = {\r\n noCameraDevicesFound: 'No camera devices found',\r\n errorGettingDevices: 'Error getting devices',\r\n loading: 'Loading...',\r\n chooseCamera: 'Choose camera to use:',\r\n changeCamera: 'Change device',\r\n close: 'Close'\r\n};\r\n\r\nconst BarcodeScanner = (props: IBarcodeScannerProps) => {\r\n const { context, modalIsOpen } = props;\r\n const resources = { ...DefaultResources, ...props.resources };\r\n const [devices, setDevices] = React.useState(undefined);\r\n const [working, setWorking] = React.useState(true);\r\n const [error, setError] = React.useState(undefined);\r\n const [selectedDeviceId, setSelectedDeviceId] = React.useState(undefined);\r\n\r\n const scanner = React.useRef(null);\r\n\r\n React.useEffect(() => {\r\n if (!modalIsOpen) {\r\n if (scanner.current?.isScanning) {\r\n scanner.current?.stop().then(() => {\r\n scanner.current?.clear();\r\n });\r\n }\r\n setWorking(true);\r\n setError(undefined);\r\n setSelectedDeviceId(undefined);\r\n return;\r\n }\r\n\r\n if (devices) {\r\n setWorking(false);\r\n\r\n const deviceId = localStorage.getItem('barcodeScannerDeviceId');\r\n if (deviceId && devices.some(d => d.id === deviceId)) {\r\n setSelectedDeviceId(deviceId);\r\n }\r\n\r\n return;\r\n }\r\n\r\n // Get all devices\r\n const work = async () => {\r\n const { Html5Qrcode } = await getScannerModule();\r\n\r\n try {\r\n const devices = await Html5Qrcode.getCameras();\r\n setDevices(devices.length > 0 ? devices : undefined);\r\n\r\n /* if (devices.some(d => d.label.toLowerCase().includes('front') || d.label.toLowerCase().includes('back'))) {\r\n setMode('mobile');\r\n } */\r\n\r\n // 2 modes. If there are no devices with front/back/environment/user in label, then assume desktop mode.\r\n // If there are devices with front/back/environment/user in label, then assume mobile mode.\r\n // - Desktop mode: Show all devices and let the user choose.\r\n // - Mobile mode: Sort devices by label since it appears normal lenses are at the start (unverified) and pick the first front or back camera\r\n\r\n // Example from a Samsung device:\r\n /* ['camera2 1, facing front',\r\n 'camera2 3, facing front',\r\n 'camera2 2, facing back',\r\n 'camera2 0, facing back']; */\r\n\r\n if (devices.length === 0) {\r\n setError(resources.noCameraDevicesFound);\r\n } else if (devices.length === 1) {\r\n setSelectedDeviceId(devices[0].id);\r\n }\r\n\r\n const deviceId = localStorage.getItem('barcodeScannerDeviceId');\r\n if (deviceId && devices.some(d => d.id === deviceId)) {\r\n setSelectedDeviceId(deviceId);\r\n }\r\n } catch (error) {\r\n console.error(\"Error getting devices\", error);\r\n setError(resources.errorGettingDevices);\r\n } finally {\r\n setWorking(false);\r\n }\r\n };\r\n void work();\r\n }, [modalIsOpen]);\r\n\r\n React.useEffect(() => {\r\n if (!selectedDeviceId) {\r\n if (scanner.current?.isScanning) {\r\n scanner.current?.stop();\r\n }\r\n return;\r\n }\r\n\r\n const work = async () => {\r\n const { Html5Qrcode } = await getScannerModule();\r\n\r\n scanner.current = new Html5Qrcode(qrcodeRegionId);\r\n void scanner.current.start(selectedDeviceId, {\r\n fps: 10,\r\n // qrbox: 250\r\n qrbox: (viewFinderWidth, viewFinderHeight) => {\r\n const minEdgePercentage = 0.7;\r\n const minEdgeSize = Math.min(viewFinderWidth, viewFinderHeight);\r\n const qrboxSize = Math.min(Math.floor(minEdgeSize * minEdgePercentage), 250);\r\n return {\r\n width: qrboxSize,\r\n height: qrboxSize\r\n };\r\n }\r\n }, onScanSuccess, undefined);\r\n };\r\n void work();\r\n }, [selectedDeviceId]);\r\n\r\n const onScanSuccess = (decodedText: string) => {\r\n // Call the callback\r\n props.onFound(decodedText);\r\n };\r\n\r\n const baseClassName = 'vh-barcode-scanner';\r\n const shouldShowScanner = !working && !error && devices && selectedDeviceId;\r\n\r\n const onSelectDevice = (deviceId: string) => {\r\n setSelectedDeviceId(deviceId);\r\n // Save device to local storage\r\n localStorage.setItem('barcodeScannerDeviceId', deviceId);\r\n };\r\n\r\n return (\r\n \r\n \r\n
    {resources.loading}
    \r\n\r\n
    {error}
    \r\n\r\n
    \r\n
    {resources.chooseCamera}
    \r\n
      \r\n {devices?.map((device, index) => (\r\n
    • \r\n \r\n
    • \r\n ))}\r\n
    \r\n
    \r\n\r\n
    \r\n
    \r\n {/*
    */}\r\n
    \r\n \r\n \r\n setSelectedDeviceId(undefined)}\r\n style={{ display: selectedDeviceId && (devices?.length || 0) > 1 ? 'block' : 'none' }}\r\n >\r\n {resources.changeCamera}\r\n \r\n \r\n \r\n \r\n );\r\n};\r\n\r\nexport default BarcodeScanner;\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\n/* eslint-disable no-duplicate-imports */\r\nimport { Autosuggestions } from '@msdyn365-commerce/commerce-entities';\r\nimport MsDyn365, { getCatalogId, getUrlSync } from '@msdyn365-commerce/core';\r\nimport { ProductPrice, ProductRefiner, ProductRefinerSource, ProductSearchResult, ProductsDataActions, ProjectionDomain, SimpleProduct } from '@msdyn365-commerce/retail-proxy';\r\nimport { ArrayExtensions, ObjectExtensions, Random, validateCatalogId } from '@msdyn365-commerce-modules/retail-actions';\r\nimport { createSearchStateInput } from '@msdyn365-commerce-modules/search-utilities';\r\nimport { getTelemetryObject, IModuleProps, INodeProps, ITelemetryContent, KeyCodes } from '@msdyn365-commerce-modules/utilities';\r\nimport classnames from 'classnames';\r\nimport { debounce } from 'lodash';\r\nimport { Spinner, SpinnerSize } from 'office-ui-fabric-react';\r\nimport * as React from 'react';\r\n\r\nimport getSearchSuggestionsAction, { AutoSuggestInput, SuggestionType } from './actions/get-auto-suggest-suggestions';\r\nimport {\r\n CategorySuggestionsComponent,\r\n FormComponent,\r\n ISearchCategoryViewProps,\r\n ISearchKeywordViewProps,\r\n ISearchProductViewProps,\r\n KeywordSuggestionsComponent,\r\n ProductSuggestionsComponent\r\n} from './components';\r\nimport { IVinhusetSearchData } from './vinhuset-search.data';\r\nimport { IVinhusetSearchProps, ISuggestionTypeCriterionData, SuggestionTypeCriterionSuggestionType } from './vinhuset-search.props.autogenerated';\r\nimport { getActivePricesAsync, searchByCriteriaAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\r\nimport PQueue from 'p-queue';\r\nimport { ProductSearchResultExt } from '../vinhuset-search-result-container/components';\r\nimport { BuyValidationResult } from '../../themes/vinhuset-adventureworks/views/components/product.component';\r\nimport { onBuyHasAccessValidator } from '../../shared-utils/attributes/on-buy-access-validator';\r\nimport BarcodeScanner from '../../components/barcode-scanner/barcode-scanner';\r\n\r\nexport interface ISearchState {\r\n searchText: string;\r\n searchKeywordSuggestClass: string;\r\n searchProductSuggestClass: string;\r\n searchCategorySuggestClass: string;\r\n suggestions: Autosuggestions | undefined;\r\n searchRefiners?: ProductRefiner[] | undefined;\r\n autoSuggestAriaLabel: string;\r\n isInitialState: boolean;\r\n isLoadingAutoSuggest?: boolean;\r\n searchTermCompleted?: string;\r\n activePrices: { [key: string]: ProductPrice };\r\n simpleProducts: SimpleProduct[];\r\n productSearchResults: ProductSearchResult[];\r\n breakoffProducts: { [key: number]: boolean };\r\n showScannerModal: boolean;\r\n}\r\n\r\nexport interface ISearchViewProps extends IVinhusetSearchProps {\r\n Search: IModuleProps;\r\n AutoSuggestAriaLabel: INodeProps;\r\n AutoSuggestAriaLabelText: string;\r\n searchText: string;\r\n AutoSuggest: INodeProps;\r\n KeywordSuggest: INodeProps;\r\n ProductSuggest: INodeProps;\r\n CategorySuggest: INodeProps;\r\n SearchForm: INodeProps;\r\n FormWrapper: INodeProps;\r\n UlKeyword: INodeProps;\r\n UlProduct: INodeProps;\r\n UlCategory: INodeProps;\r\n form: React.ReactNode;\r\n autosuggestKeyword?: ISearchKeywordViewProps;\r\n autosuggestProduct?: ISearchProductViewProps;\r\n autosuggestCategory?: ISearchCategoryViewProps;\r\n callbacks: {\r\n handleCancelSearchChange(): void;\r\n handleCancelSearchFocused?(): void;\r\n };\r\n isLoadingAutoSuggest?: boolean;\r\n isLoadingNode?: React.ReactNode;\r\n searchTermCompleted?: string;\r\n scannerModal?: React.ReactNode;\r\n}\r\n\r\n/**\r\n *\r\n * Search module.\r\n * @extends {React.Component, ISearchState>}\r\n */\r\nclass Search extends React.Component, ISearchState> {\r\n private readonly searchTextInput: React.RefObject;\r\n\r\n private readonly formReference: React.RefObject;\r\n\r\n private readonly maxChars: number;\r\n\r\n private readonly topResultsCount?: number;\r\n\r\n private readonly hitPrefix: string = '{';\r\n\r\n private readonly hitSuffix: string = '}';\r\n\r\n private readonly waitTime: number = 500;\r\n\r\n private readonly autoSuggestResultScreenReaderDiv: React.RefObject;\r\n\r\n private readonly autoSuggestResultDiv: React.RefObject;\r\n\r\n private readonly searchFormClass: string;\r\n\r\n private readonly telemetryContent: ITelemetryContent;\r\n\r\n private loadSuggestionsRequestId?: string;\r\n\r\n private inputSuggestionType: ISuggestionTypeCriterionData[];\r\n\r\n // @ts-expect-error\r\n private cancellabelDebounce: debounce;\r\n\r\n private cartQueue = new PQueue({ concurrency: 1 });\r\n\r\n public constructor(props: IVinhusetSearchProps) {\r\n super(props);\r\n this.searchTextInput = React.createRef();\r\n this.autoSuggestResultScreenReaderDiv = React.createRef();\r\n this.autoSuggestResultDiv = React.createRef();\r\n this.formReference = React.createRef();\r\n this.state = {\r\n searchText: '',\r\n searchKeywordSuggestClass: 'ms-search__autoSuggest__keyword',\r\n searchProductSuggestClass: 'ms-search__autoSuggest__product',\r\n searchCategorySuggestClass: 'ms-search__autoSuggest__category',\r\n suggestions: undefined,\r\n searchRefiners: undefined,\r\n autoSuggestAriaLabel: '',\r\n isInitialState: true,\r\n isLoadingAutoSuggest: false,\r\n activePrices: {},\r\n simpleProducts: [],\r\n productSearchResults: [],\r\n breakoffProducts: {},\r\n showScannerModal: false\r\n };\r\n this.maxChars =\r\n (this.props.context &&\r\n this.props.context.app &&\r\n this.props.context.app.config &&\r\n this.props.context.app.config.searchInputMaxLength) ||\r\n 50;\r\n\r\n this.inputSuggestionType = [];\r\n this.topResultsCount = this.props.config && this.props.config.topResultsCount ? this.props.config.topResultsCount : 5;\r\n this.searchFormClass = 'ms-search__form';\r\n this.telemetryContent = getTelemetryObject(\r\n this.props.context.request.telemetryPageName!,\r\n this.props.friendlyName,\r\n this.props.telemetry\r\n );\r\n\r\n this._initSuggestionTypes();\r\n }\r\n\r\n public async componentDidMount(): Promise {\r\n document.body && document.body.addEventListener('mousedown', this._focusOutTarget);\r\n window && window.addEventListener('keyup', this._keyup);\r\n }\r\n\r\n public componentWillUnmount(): void {\r\n document.body && document.body.removeEventListener('mousedown', this._focusOutTarget, false);\r\n window && window.removeEventListener('keyup', this._keyup, false);\r\n }\r\n\r\n public componentDidUpdate(): void {\r\n void this._getActivePrices();\r\n void this._getSimpleProducts();\r\n }\r\n\r\n public shouldComponentUpdate(nextProps: IVinhusetSearchProps, nextState: ISearchState): boolean {\r\n if (this.state === nextState && this.props === nextProps) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n // eslint-disable-next-line complexity -- ignore complexity.\r\n public render(): JSX.Element {\r\n const {\r\n context,\r\n resources: { cancelBtnAriaLabel, searchBtnAriaLabel, submitBtnAriaLabel },\r\n config: { disableSubmitSearch, searchplaceholderText, shouldShowFullCategoryPath, className = '' }\r\n } = this.props;\r\n\r\n const {\r\n searchText,\r\n searchKeywordSuggestClass,\r\n searchProductSuggestClass,\r\n searchCategorySuggestClass,\r\n suggestions,\r\n searchRefiners,\r\n isLoadingAutoSuggest\r\n } = this.state;\r\n\r\n const searchQsp = (context && context.app && context.app.config && context.app.config.searchQueryStringParameter) || 'q';\r\n const searchPageURL = getUrlSync('search', context && context.actionContext) || '';\r\n const searchURL = this._appendQueryParams(searchPageURL, searchText, searchQsp);\r\n const searchPlaceholder = searchplaceholderText && searchplaceholderText.length > 0 ? searchplaceholderText : 'Search in Fabrikam';\r\n\r\n const keywordSuggestions = suggestions?.AllSearchResults?.filter(\r\n suggestion => suggestion.SuggestionType === SuggestionType.Keyword || suggestion.SuggestionType === SuggestionType.None\r\n );\r\n const productSuggestions = suggestions?.AllSearchResults?.filter(\r\n suggestion => suggestion.SuggestionType === SuggestionType.Product\r\n );\r\n const categoryRefiners = searchRefiners?.find(refiner => {\r\n return refiner.SourceValue === ProductRefinerSource.Category;\r\n });\r\n const categorySuggestions = suggestions?.AllSearchResults?.filter(suggestion => {\r\n if (suggestion.SuggestionType !== SuggestionType.Category) {\r\n return false;\r\n }\r\n const refiner = categoryRefiners?.Values?.find(item => {\r\n return `${item.RefinerRecordId ?? 0}` === suggestion.Id;\r\n });\r\n\r\n return !ObjectExtensions.isNullOrUndefined(refiner);\r\n });\r\n\r\n const viewProps: ISearchViewProps = {\r\n ...(this.props as IVinhusetSearchProps),\r\n\r\n Search: {\r\n moduleProps: this.props,\r\n className: `${classnames('ms-search', className)} ${disableSubmitSearch ? 'no-submit' : 'with-submit'}`\r\n },\r\n AutoSuggestAriaLabel: {\r\n tag: 'div',\r\n className: 'msc-autoSuggest__screen-reader',\r\n 'aria-live': 'assertive',\r\n ref: this.autoSuggestResultScreenReaderDiv\r\n },\r\n AutoSuggestAriaLabelText: this.state.autoSuggestAriaLabel,\r\n searchText: this.state.searchText,\r\n AutoSuggest: {\r\n ref: this.autoSuggestResultDiv,\r\n className: classnames('ms-search__autoSuggest', { show: this.state.searchTermCompleted, hide: !this.state.searchTermCompleted })\r\n },\r\n KeywordSuggest: {\r\n className: searchKeywordSuggestClass\r\n },\r\n ProductSuggest: {\r\n className: searchProductSuggestClass\r\n },\r\n CategorySuggest: {\r\n className: searchCategorySuggestClass\r\n },\r\n SearchForm: {\r\n className: `${this.searchFormClass}`\r\n },\r\n FormWrapper: {\r\n tag: 'form',\r\n ref: this.formReference,\r\n className: 'ms-search__searchForm',\r\n 'aria-label': 'Search',\r\n name: 'searchForm',\r\n role: 'search',\r\n action: searchURL,\r\n autoComplete: 'off',\r\n onSubmit: this._handleSubmit\r\n },\r\n UlKeyword: {\r\n tag: 'ul',\r\n className: classnames('msc-autoSuggest__keywordResults-items', className)\r\n },\r\n UlProduct: {\r\n tag: 'ul',\r\n className: classnames('msc-autoSuggest__productResults-items', className)\r\n },\r\n UlCategory: {\r\n tag: 'ul',\r\n className: classnames('msc-autoSuggest__categoryResults-items', className)\r\n },\r\n form: FormComponent({\r\n context: this.props.context,\r\n ariaLabelCancel: cancelBtnAriaLabel,\r\n ariaLabelSearch: searchBtnAriaLabel,\r\n ariaLabelSubmit: submitBtnAriaLabel,\r\n searchTextInput: this.searchTextInput,\r\n disableSubmitSearch,\r\n handleInputChange: this._handleInputChange,\r\n handleCancelSearchChange: this._handleCancelSearchChange,\r\n handleScannerButtonClick: this._handleScannerButtonClick,\r\n maxChars: this.maxChars,\r\n searchQsp,\r\n searchPlaceholder,\r\n query: searchText\r\n }),\r\n autosuggestKeyword:\r\n searchText &&\r\n searchText.length > 0 &&\r\n (isLoadingAutoSuggest || (keywordSuggestions && ArrayExtensions.hasElements(keywordSuggestions)))\r\n ? KeywordSuggestionsComponent({\r\n searchKeywordSuggestClass,\r\n searchPageURL,\r\n searchQsp,\r\n hitPrefix: this.hitPrefix,\r\n hitSuffix: this.hitSuffix,\r\n autoSuggestProps: this.props,\r\n searchText,\r\n searchTermCompleted: this.state.searchTermCompleted,\r\n suggestions: keywordSuggestions,\r\n telemetryContent: this.telemetryContent\r\n })\r\n : undefined,\r\n autosuggestProduct:\r\n searchText &&\r\n searchText.length > 0 &&\r\n (isLoadingAutoSuggest || (productSuggestions && ArrayExtensions.hasElements(productSuggestions)))\r\n ? ProductSuggestionsComponent({\r\n searchProductSuggestClass,\r\n searchPageURL,\r\n searchQsp,\r\n hitPrefix: this.hitPrefix,\r\n hitSuffix: this.hitSuffix,\r\n autoSuggestProps: this.props,\r\n searchText,\r\n suggestions: productSuggestions,\r\n telemetry: this.props.telemetry,\r\n moduleType: this.props.typeName,\r\n moduleId: this.props.id,\r\n telemetryContent: this.telemetryContent,\r\n locale: this.props.context.request.locale,\r\n resources: this.props.resources,\r\n activePrices: this.state.activePrices,\r\n simpleProducts: this.state.simpleProducts,\r\n cart: this.props.data.cart.result,\r\n cartQueue: this.cartQueue,\r\n breakoffProducts: this.state.breakoffProducts,\r\n onBuyValidate: this._onBuyValidate,\r\n onBreakoffChange: this._onBreakoffChange\r\n })\r\n : undefined,\r\n autosuggestCategory:\r\n searchText &&\r\n searchText.length > 0 &&\r\n (isLoadingAutoSuggest || (categorySuggestions && ArrayExtensions.hasElements(categorySuggestions)))\r\n ? CategorySuggestionsComponent({\r\n searchCategorySuggestClass,\r\n searchPageURL,\r\n searchQsp,\r\n hitPrefix: this.hitPrefix,\r\n hitSuffix: this.hitSuffix,\r\n autoSuggestProps: this.props,\r\n searchText,\r\n suggestions: categorySuggestions,\r\n searchRefiners,\r\n telemetryContent: this.telemetryContent,\r\n shouldShowFullPath: shouldShowFullCategoryPath,\r\n searchTermCompleted: this.state.searchTermCompleted,\r\n categorySuggestionProductCount: this.props.resources.categorySuggestionProductCount,\r\n categorySuggestionProductCountPlural: this.props.resources.categorySuggestionProductCountPlural,\r\n categorySuggestionJoinerText: this.props.resources.categorySuggestionJoinerText\r\n })\r\n : undefined,\r\n callbacks: {\r\n handleCancelSearchChange: this._handleCancelSearchChange,\r\n handleCancelSearchFocused: this._handleCancelSearchFocused\r\n },\r\n isLoadingAutoSuggest,\r\n isLoadingNode: this._isLoadingNode(),\r\n searchTermCompleted: this.state.searchTermCompleted,\r\n scannerModal: this._renderScannerModal()\r\n };\r\n\r\n return this.props.renderView(viewProps) as React.ReactElement;\r\n }\r\n\r\n private _initSuggestionTypes() {\r\n const suggestionTypes = this.props.config.suggestionTypeCriterion;\r\n\r\n const suggestions = ArrayExtensions.unique(ArrayExtensions.validValues(suggestionTypes));\r\n if (!ArrayExtensions.hasElements(suggestions)) {\r\n this.inputSuggestionType = [\r\n { SuggestionType: SuggestionTypeCriterionSuggestionType.keyword },\r\n { SuggestionType: SuggestionTypeCriterionSuggestionType.product },\r\n { SuggestionType: SuggestionTypeCriterionSuggestionType.scopedCategory }\r\n ];\r\n return;\r\n }\r\n\r\n const validSuggestions = suggestions.filter(suggestion => suggestion.SuggestionType);\r\n if (ArrayExtensions.hasElements(validSuggestions)) {\r\n this.inputSuggestionType = validSuggestions;\r\n return;\r\n }\r\n\r\n this.inputSuggestionType = [];\r\n }\r\n\r\n /**\r\n * Function to create the ReactNode for loading Autosuggest result.\r\n * @returns ReachNode for loading Autosuggest result.\r\n */\r\n private readonly _isLoadingNode = (): React.ReactNode => {\r\n const loadingText = this.props.resources.autoSuggestResultLoadingMessage;\r\n return ;\r\n };\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n private readonly _focusOutTarget = (e: any): void => {\r\n const { suggestions } = this.state;\r\n\r\n if (suggestions && suggestions.AllSearchResults && e.target.closest('.ms-search') === null) {\r\n this._clearAutoSuggestState();\r\n }\r\n };\r\n\r\n private readonly _keyup = (e: KeyboardEvent): void => {\r\n const { suggestions } = this.state;\r\n\r\n if (suggestions && suggestions.AllSearchResults && e.keyCode === KeyCodes.Escape) {\r\n this._clearAutoSuggestState();\r\n }\r\n\r\n if (\r\n !(\r\n (this.formReference.current && this.formReference.current.contains((e.target as unknown) as Node)) ||\r\n (this.autoSuggestResultDiv.current && this.autoSuggestResultDiv.current.contains((e.target as unknown) as Node))\r\n )\r\n ) {\r\n if (suggestions && suggestions.AllSearchResults) {\r\n this._clearAutoSuggestState();\r\n }\r\n }\r\n };\r\n\r\n private readonly _clearAutoSuggestState = (): void => {\r\n const {\r\n context: { actionContext },\r\n data: { searchState }\r\n } = this.props;\r\n\r\n if (this.searchTextInput.current && this.searchTextInput.current.value.length > 0) {\r\n searchState.searchText = '';\r\n searchState.defaultBasicSearchUrl = '';\r\n searchState.searchQueryStringParameter = '';\r\n actionContext ? actionContext.update(createSearchStateInput(searchState), searchState) : null;\r\n this.searchTextInput.current.value = '';\r\n }\r\n\r\n this.setState({ searchText: '', suggestions: undefined, searchRefiners: undefined, searchTermCompleted: '' });\r\n };\r\n\r\n private async _getActivePrices() {\r\n const { context } = this.props;\r\n const missingPrices = this.state.suggestions?.AllSearchResults?.filter(x => x.SuggestionType === 'Product' && !this.state.activePrices[x.Id!]);\r\n const projectDomain: ProjectionDomain = { ChannelId: +context.request.apiSettings.channelId, CatalogId: context.request.apiSettings.catalogId };\r\n\r\n if (!missingPrices || missingPrices.length === 0) {\r\n return;\r\n }\r\n\r\n const prices = await getActivePricesAsync({ callerContext: context.actionContext },\r\n projectDomain,\r\n missingPrices.map(x => +x.Id!),\r\n new Date(),\r\n null,\r\n undefined,\r\n true);\r\n\r\n const newActivePrices = { ...this.state.activePrices };\r\n prices.forEach(x => {\r\n if (x.ProductId && x.CustomerContextualPrice) {\r\n newActivePrices[x.ProductId.toString()] = x;\r\n }\r\n });\r\n\r\n this.setState({ activePrices: newActivePrices });\r\n }\r\n\r\n private async _getSimpleProducts() {\r\n const { context } = this.props;\r\n const missingProducts = this.state.suggestions?.AllSearchResults\r\n ?.filter(x => x.Id && x.SuggestionType === 'Product' && !this.state.simpleProducts.find(y => y.RecordId === parseInt(x.Id!, 10)));\r\n\r\n if (!missingProducts || missingProducts.length === 0) {\r\n return;\r\n }\r\n\r\n const simpleProducts = await ProductsDataActions.getByIdsAsync(\r\n { callerContext: context.actionContext },\r\n context.request.apiSettings.channelId,\r\n missingProducts.filter(x => x.Id).map(x => parseInt(x.Id!, 10))\r\n );\r\n const newSimpleProducts = [ ...this.state.simpleProducts, ...simpleProducts ];\r\n\r\n this.setState({ simpleProducts: newSimpleProducts });\r\n }\r\n\r\n private async _getSearchSuggestions(loadSuggestionsRequestId: string, query: string) {\r\n try {\r\n const searchSuggestions = await getSearchSuggestionsAction(\r\n new AutoSuggestInput(query, this.topResultsCount, this._getSuggestionType(), this.hitPrefix, this.hitSuffix),\r\n this.props.context.actionContext\r\n );\r\n if (loadSuggestionsRequestId !== this.loadSuggestionsRequestId) {\r\n return undefined;\r\n }\r\n return searchSuggestions;\r\n } catch (error) {\r\n if (loadSuggestionsRequestId !== this.loadSuggestionsRequestId) {\r\n return undefined;\r\n }\r\n this.setState({ suggestions: undefined, searchRefiners: undefined, autoSuggestAriaLabel: this._setAutoSuggestResultCount() });\r\n this.props.telemetry.exception(error);\r\n this.props.telemetry.debug('Unable to get auto suggest results');\r\n return undefined;\r\n }\r\n }\r\n\r\n private async _updateSearchRefiners(loadSuggestionsRequestId: string, query: string, suggestions: Autosuggestions | undefined) {\r\n try {\r\n const refiners = await this._getSearchRefiners(query);\r\n if (loadSuggestionsRequestId !== this.loadSuggestionsRequestId) {\r\n return;\r\n }\r\n this.setState({\r\n suggestions,\r\n searchRefiners: refiners,\r\n autoSuggestAriaLabel: this._setAutoSuggestResultCount(suggestions),\r\n isLoadingAutoSuggest: false,\r\n searchTermCompleted: query\r\n });\r\n } catch (error) {\r\n if (loadSuggestionsRequestId !== this.loadSuggestionsRequestId) {\r\n return;\r\n }\r\n this.setState({ suggestions, searchRefiners: undefined, autoSuggestAriaLabel: this._setAutoSuggestResultCount(suggestions) });\r\n this.props.telemetry.exception(error);\r\n this.props.telemetry.debug('Unable to get refiners results');\r\n }\r\n }\r\n\r\n private _loadSuggestions(query: string) {\r\n this.cancellabelDebounce = debounce(async () => {\r\n this.setState({ isLoadingAutoSuggest: true });\r\n const loadSuggestionsRequestId = Random.Guid.generateGuid();\r\n this.loadSuggestionsRequestId = loadSuggestionsRequestId;\r\n const searchSuggestions = await this._getSearchSuggestions(loadSuggestionsRequestId, query);\r\n await this._updateSearchRefiners(loadSuggestionsRequestId, query, searchSuggestions);\r\n }, this.waitTime);\r\n\r\n setTimeout(() => {\r\n this.cancellabelDebounce();\r\n }, 0);\r\n }\r\n\r\n private readonly _handleInputChange = (query: string): void => {\r\n if (!query || query.length <= this.maxChars) {\r\n this.setState({ searchText: query });\r\n }\r\n\r\n if (this.cancellabelDebounce) {\r\n this.cancellabelDebounce.cancel();\r\n }\r\n\r\n const {\r\n context,\r\n data: { searchState }\r\n } = this.props;\r\n\r\n if (context) {\r\n if (query && query.length > 0) {\r\n if (query.length > this.maxChars) {\r\n return;\r\n }\r\n\r\n if (ArrayExtensions.hasElements(this.inputSuggestionType)) {\r\n this._loadSuggestions(query);\r\n }\r\n\r\n searchState.searchText = query;\r\n } else {\r\n this.setState({ suggestions: undefined, searchRefiners: undefined });\r\n searchState.searchText = '';\r\n }\r\n context.actionContext.update(createSearchStateInput(searchState), searchState);\r\n }\r\n };\r\n\r\n private _getSuggestionType(): string {\r\n const distinctSuggestionTypes: string[] = this.inputSuggestionType.map(\r\n suggestionTypeItem => suggestionTypeItem.SuggestionType!.charAt(0).toUpperCase() + suggestionTypeItem.SuggestionType!.slice(1)\r\n );\r\n return distinctSuggestionTypes.join(',');\r\n }\r\n\r\n private async _getSearchRefiners(searchText: string): Promise {\r\n const { actionContext: ctx } = this.props.context;\r\n const catalogId = getCatalogId(ctx.requestContext);\r\n validateCatalogId(catalogId);\r\n return ProductsDataActions.getProductSearchRefinersAsync(\r\n { callerContext: ctx },\r\n {\r\n SearchCondition: searchText,\r\n Context: {\r\n ChannelId: +ctx.requestContext.apiSettings.channelId,\r\n CatalogId: catalogId\r\n }\r\n }\r\n );\r\n }\r\n\r\n private readonly _handleSubmit = (\r\n e: React.MouseEvent | React.KeyboardEvent | React.FormEvent | undefined\r\n ): void => {\r\n const {\r\n config: { disableSubmitSearch },\r\n context: {\r\n actionContext,\r\n app: {\r\n config: { searchQueryStringParameter }\r\n }\r\n }\r\n } = this.props;\r\n\r\n const query = this.searchTextInput.current && this.searchTextInput.current.value;\r\n e?.preventDefault();\r\n\r\n if (!query || (query && query.length === 0) || disableSubmitSearch) {\r\n this.searchTextInput && this.searchTextInput.current && this.searchTextInput.current.focus();\r\n } else {\r\n const searchQsp = searchQueryStringParameter || 'q';\r\n const searchURL = this._appendQueryParams(getUrlSync('search', actionContext) || '', query, searchQsp);\r\n document.location.href = searchURL;\r\n }\r\n };\r\n\r\n private readonly _handleCancelSearchChange = (): void => {\r\n const { suggestions } = this.state;\r\n\r\n if (suggestions && suggestions.AllSearchResults) {\r\n this._clearAutoSuggestState();\r\n }\r\n\r\n // This might be redundant if the check above always returns true\r\n this.setState({\r\n searchText: '',\r\n isInitialState: false,\r\n searchTermCompleted: ''\r\n });\r\n };\r\n\r\n private readonly _handleScannerButtonClick = (): void => {\r\n this.setState({ showScannerModal: true });\r\n };\r\n\r\n private readonly _handleCancelSearchFocused = (): void => {\r\n const { suggestions } = this.state;\r\n if (!(suggestions && suggestions.AllSearchResults)) {\r\n this._clearAutoSuggestState();\r\n }\r\n };\r\n\r\n private readonly _appendQueryParams = (route: string, query: string, qsp: string): string => {\r\n if (!MsDyn365.isBrowser) {\r\n return '';\r\n }\r\n\r\n const queryUrl = new URL(route, window.location.href);\r\n if (qsp && query) {\r\n queryUrl.searchParams.set(qsp, query);\r\n }\r\n\r\n return queryUrl.href;\r\n };\r\n\r\n private readonly _setAutoSuggestResultCount = (result?: Autosuggestions) => {\r\n if (this.autoSuggestResultScreenReaderDiv.current !== null) {\r\n const ariaLiveRegion = this.autoSuggestResultScreenReaderDiv.current;\r\n const suggestResultString = this.props.resources.autoSuggestFoundMessage;\r\n const emptyResultString = this.props.resources.noAutoSuggestionMessage;\r\n ariaLiveRegion.innerText =\r\n result && result.AllSearchResults && result.AllSearchResults.length > 0 ? suggestResultString : emptyResultString;\r\n ariaLiveRegion.setAttribute('aria-live', 'assertive');\r\n return ariaLiveRegion.innerText;\r\n }\r\n return '';\r\n };\r\n\r\n private readonly _onBuyValidate = async (product: ProductSearchResultExt, quantity: number): Promise => {\r\n const { context, data, resources } = this.props;\r\n\r\n // Buy validation happens on attributes, so we need to get the full product details.\r\n // Check if we already have the product details in the state and if not fetch them. Fetches all products at the same time to reduce the time needed instead of doing one by one.\r\n const missingProducts = this.state.suggestions?.AllSearchResults\r\n ?.filter(x => x.Id && x.SuggestionType === 'Product' && !this.state.productSearchResults.find(y => y.RecordId === parseInt(x.Id!, 10)));\r\n\r\n if (missingProducts && missingProducts.length > 0) {\r\n // Get full product details including attributes for the missing products\r\n const searchResults = await searchByCriteriaAsync(\r\n { callerContext: context.actionContext },\r\n {\r\n Context: {\r\n CatalogId: getCatalogId(context.actionContext.requestContext),\r\n ChannelId: +context.actionContext.requestContext.apiSettings.channelId\r\n },\r\n Ids: missingProducts.map(x => parseInt(x.Id!, 10)),\r\n IncludeAttributes: true\r\n });\r\n\r\n this.setState({ productSearchResults: [...this.state.productSearchResults, ...searchResults] });\r\n }\r\n\r\n return onBuyHasAccessValidator(\r\n context,\r\n data.orgInformation.result,\r\n this.state.productSearchResults.find(x => x.RecordId === product.RecordId) as ProductSearchResultExt,\r\n resources.toastNoAccessToProduct\r\n );\r\n };\r\n\r\n private readonly _onBreakoffChange = (productRecordId: number, breakoff: boolean): void => {\r\n this.setState((prevState) => ({\r\n breakoffProducts: ({ ...prevState.breakoffProducts, [productRecordId]: breakoff })\r\n }));\r\n };\r\n\r\n private readonly _renderScannerModal = (): React.ReactNode => {\r\n return (\r\n this.setState({ showScannerModal: false })}\r\n onFound={(text: string) => {\r\n this._handleInputChange(text);\r\n this._handleSubmit(undefined);\r\n this.setState({ showScannerModal: false });\r\n }}\r\n resources={{\r\n noCameraDevicesFound: this.props.resources.noCameraDevicesFoundText,\r\n errorGettingDevices: this.props.resources.errorGettingDevicesText,\r\n loading: this.props.resources.autoSuggestResultLoadingMessage,\r\n chooseCamera: this.props.resources.chooseCameraText,\r\n changeCamera: this.props.resources.changeCameraText,\r\n close: this.props.resources.modalCloseButtonText\r\n }}\r\n />\r\n );\r\n };\r\n}\r\n\r\nexport default Search;\r\n","import * as React from 'react';\r\nimport { ISearchViewProps } from '../vinhuset-search';\r\nimport { ISearchFormViewProps } from './vinhuset-search.form';\r\n\r\ntype BlackoutOverlayResult = [ boolean, React.CSSProperties, React.Dispatch> ];\r\n\r\nexport const useBlackoutOverlay = (\r\n searchProps: ISearchViewProps,\r\n searchDivRef: React.MutableRefObject,\r\n isMobilePort: boolean,\r\n isSearchText: boolean,\r\n disableOverlay?: boolean\r\n): BlackoutOverlayResult => {\r\n const [popupPosition, setPopupPosition] = React.useState({});\r\n const [isInputFocused, setIsInputFocused] = React.useState(false);\r\n\r\n const searchInputRef = ((searchProps.form as ISearchFormViewProps).input as any).ref as React.RefObject;\r\n\r\n const updatePopupPosition = () => {\r\n if (!searchDivRef.current) {\r\n return;\r\n }\r\n\r\n setPopupPosition({\r\n top: searchDivRef.current.offsetTop + searchDivRef.current.offsetHeight + 10,\r\n left: searchDivRef.current.offsetLeft,\r\n width: searchDivRef.current.offsetWidth\r\n });\r\n };\r\n\r\n React.useEffect(() => {\r\n if (!searchInputRef.current) {\r\n return;\r\n }\r\n\r\n const focus = () => { setIsInputFocused(true); };\r\n const blur = () => { setIsInputFocused(false); };\r\n\r\n searchInputRef.current.addEventListener('focus', focus);\r\n searchInputRef.current.addEventListener('blur', blur);\r\n\r\n return () => {\r\n searchInputRef.current!.removeEventListener('focus', focus);\r\n searchInputRef.current!.removeEventListener('blur', blur);\r\n };\r\n }, [searchInputRef.current]);\r\n\r\n React.useEffect(() => {\r\n if (!searchDivRef.current) {\r\n return;\r\n }\r\n\r\n const resize = () => {\r\n updatePopupPosition();\r\n };\r\n\r\n window.addEventListener('resize', resize);\r\n\r\n return () => {\r\n window.removeEventListener('resize', resize);\r\n };\r\n }, [searchDivRef, searchDivRef.current, setPopupPosition]);\r\n\r\n const shouldShowOverlay = React.useMemo(() =>\r\n !disableOverlay && (isInputFocused || isSearchText),\r\n [disableOverlay, isInputFocused, isSearchText, isMobilePort]\r\n );\r\n\r\n React.useEffect(() => {\r\n if (!shouldShowOverlay) {\r\n updatePopupPosition();\r\n return;\r\n }\r\n\r\n document.body.style.position = 'fixed';\r\n document.body.style.top = '0px';\r\n document.body.style.right = '17px';\r\n document.body.style.left = '0px';\r\n document.body.setAttribute('data-popup', 'true');\r\n\r\n updatePopupPosition();\r\n\r\n return () => {\r\n document.body.style.position = '';\r\n document.body.style.top = '';\r\n document.body.style.right = '';\r\n document.body.style.left = '';\r\n document.body.removeAttribute('data-popup');\r\n };\r\n }, [shouldShowOverlay, searchDivRef.current]);\r\n\r\n if (disableOverlay) {\r\n return [ false, popupPosition, setIsInputFocused ];\r\n }\r\n\r\n return [ shouldShowOverlay, popupPosition, setIsInputFocused ];\r\n};\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\n/* eslint-disable no-duplicate-imports */\r\nimport { INodeProps, Module, Node, isMobile, VariantType } from '@msdyn365-commerce-modules/utilities';\r\nimport * as React from 'react';\r\n\r\nimport { ISearchCategoryViewProps, ISearchFormViewProps, ISearchKeywordViewProps, ISearchProductViewProps } from './components';\r\nimport { ISearchViewProps } from './vinhuset-search';\r\nimport { useBlackoutOverlay } from './components/vinhuset-search.hooks';\r\n\r\nconst SearchView: React.FC = props => {\r\n const {\r\n context,\r\n Search,\r\n AutoSuggestAriaLabel,\r\n AutoSuggestAriaLabelText,\r\n searchText,\r\n AutoSuggest,\r\n KeywordSuggest,\r\n ProductSuggest,\r\n CategorySuggest,\r\n UlKeyword,\r\n UlProduct,\r\n UlCategory,\r\n form,\r\n autosuggestCategory,\r\n autosuggestKeyword,\r\n autosuggestProduct,\r\n SearchForm,\r\n FormWrapper,\r\n isLoadingAutoSuggest,\r\n isLoadingNode,\r\n searchTermCompleted,\r\n scannerModal,\r\n callbacks: { handleCancelSearchFocused }\r\n } = props;\r\n\r\n const [isMobilePort, setIsMobile] = React.useState(false);\r\n const overlayDivRef = React.useRef(null);\r\n const searchDivRef = React.useRef(null);\r\n const [\r\n shouldShowOverlay,\r\n popupPosition,\r\n setIsInputFocused\r\n ] = useBlackoutOverlay(props, searchDivRef, isMobilePort, Boolean(searchText), true);\r\n\r\n React.useEffect(() => {\r\n const onResize = () => {\r\n const isMobileView = isMobile({ variant: VariantType.Browser, context: context.request }) === 'xs';\r\n setIsMobile(isMobileView);\r\n };\r\n onResize(); // Call to set initial value\r\n\r\n window.addEventListener('resize', onResize);\r\n return () => {\r\n window.removeEventListener('resize', onResize);\r\n };\r\n }, [context]);\r\n\r\n return (\r\n <>\r\n \r\n {_renderForm(form as ISearchFormViewProps, SearchForm, FormWrapper, searchText, searchTermCompleted, scannerModal)}\r\n \r\n {searchText && searchText.length > 0 ? {AutoSuggestAriaLabelText} : ''}\r\n\r\n {searchTermCompleted && (\r\n \r\n {_renderKeywordSuggestions(KeywordSuggest, UlKeyword, autosuggestKeyword, isLoadingAutoSuggest, isLoadingNode)}\r\n {_renderCategorySuggestions(CategorySuggest, UlCategory, autosuggestCategory, isLoadingAutoSuggest, isLoadingNode)}\r\n {_renderProductSuggestions(ProductSuggest, UlProduct, autosuggestProduct, isLoadingAutoSuggest, isLoadingNode)}\r\n \r\n )}\r\n \r\n \r\n {shouldShowOverlay && (\r\n
    {\r\n if (event.target === overlayDivRef.current) {\r\n setIsInputFocused(false);\r\n handleCancelSearchFocused?.();\r\n }\r\n }} />\r\n )}\r\n \r\n );\r\n};\r\n\r\nconst _renderForm = (\r\n form: ISearchFormViewProps,\r\n SearchForm: INodeProps,\r\n FormWrapper: INodeProps,\r\n searchText: string | undefined,\r\n searchTermCompleted: string | undefined,\r\n scannerModal: React.ReactNode\r\n) => {\r\n return (\r\n \r\n \r\n {form.submitBtn}\r\n {form.input}\r\n {form.scannerBtn}\r\n {scannerModal}\r\n \r\n \r\n );\r\n};\r\n\r\nconst _renderKeywordSuggestions = (\r\n KeywordSuggest: INodeProps,\r\n UlKeyword: INodeProps,\r\n keywordSuggestions?: ISearchKeywordViewProps,\r\n isLoadingAutoSuggest?: boolean,\r\n isLoadingNode?: React.ReactNode\r\n) => {\r\n return (\r\n keywordSuggestions && (\r\n \r\n \r\n {/* {isLoadingAutoSuggest && isLoadingNode} */}\r\n {!isLoadingAutoSuggest &&\r\n keywordSuggestions.text.map(text => {\r\n return text;\r\n })}\r\n \r\n \r\n )\r\n );\r\n};\r\n\r\nconst _renderProductSuggestions = (\r\n ProductSuggest: INodeProps,\r\n UlProduct: INodeProps,\r\n productSuggestions?: ISearchProductViewProps,\r\n isLoadingAutoSuggest?: boolean,\r\n isLoadingNode?: React.ReactNode\r\n) => {\r\n return (\r\n productSuggestions && (\r\n \r\n \r\n {productSuggestions.title}\r\n {isLoadingAutoSuggest && isLoadingNode}\r\n {!isLoadingAutoSuggest &&\r\n productSuggestions.items.map((item, index) => {\r\n return (\r\n \r\n \r\n {item.thumbnail}\r\n
    \r\n {item.text}\r\n
    \r\n {item.price}\r\n {item.buySection}\r\n
    \r\n
    \r\n
    \r\n
    \r\n );\r\n })}\r\n
    \r\n
    \r\n )\r\n );\r\n};\r\n\r\nconst _renderCategorySuggestions = (\r\n CategorySuggest: INodeProps,\r\n UlCategory: INodeProps,\r\n categorySuggestions?: ISearchCategoryViewProps,\r\n isLoadingAutoSuggest?: boolean,\r\n isLoadingNode?: React.ReactNode\r\n) => {\r\n return (\r\n categorySuggestions && (\r\n \r\n \r\n {categorySuggestions.title}\r\n {isLoadingAutoSuggest && isLoadingNode}\r\n {!isLoadingAutoSuggest &&\r\n categorySuggestions.text.map(text => {\r\n return text;\r\n })}\r\n \r\n \r\n )\r\n );\r\n};\r\n\r\nexport default SearchView;\r\n","import { ICoreContext } from '@msdyn365-commerce/core';\r\nimport nbNO from './nb-NO.json';\r\nimport enUS from './en-US.json';\r\n\r\n// Generate with https://jvilk.com/MakeTypes/\r\nexport interface IAttributeLocale {\r\n notFound: string;\r\n specialBadges: string;\r\n labels: IAttributeLocaleLabels;\r\n prefixedAttributes: IAttributeLocalePrefixedAttributes;\r\n groups: IAttributeLocaleGroups;\r\n country: string;\r\n district: string;\r\n underDistrict: string;\r\n alcoholPercent: string;\r\n volumeCl: string;\r\n producer: string;\r\n description: string;\r\n fitsWith: string;\r\n flavorProfile: IFlavorProfile;\r\n taste: string;\r\n rawMaterial: string;\r\n ingredients: string;\r\n sugar: string;\r\n acid: string;\r\n alternative: IAlternative;\r\n vintage: string;\r\n organic: string;\r\n screwCap: string;\r\n inventory: string;\r\n subCategory: string;\r\n}\r\n\r\nexport interface IAttributeLocaleLabels {\r\n yes: string;\r\n no: string;\r\n alcoholPercentage: string;\r\n unitOfMeasure: string;\r\n aboutProduct: string;\r\n productInformation: string;\r\n}\r\n\r\nexport interface IAttributeLocalePrefixedAttributes {\r\n alcoholPercent: string;\r\n volumeCl: string;\r\n producer: string;\r\n country: string;\r\n district: string;\r\n vintage: string;\r\n}\r\n\r\nexport interface IAttributeLocaleGroups {\r\n aboutProduct: string;\r\n}\r\n\r\nexport interface IFlavorProfile {\r\n body: string;\r\n freshness: string;\r\n sweetness: string;\r\n bitterness: string;\r\n tannins: string;\r\n oak: string;\r\n smoke: string;\r\n spiceHerb: string;\r\n fruit: string;\r\n}\r\n\r\nexport interface IAlternative {\r\n prefixed: IAlternativePrefixed;\r\n alcoholPercent: string;\r\n sugar: string;\r\n volumeCl: string;\r\n}\r\n\r\nexport interface IAlternativePrefixed {\r\n producer: string;\r\n country: string;\r\n district: string;\r\n volumeCl: string;\r\n}\r\n\r\nexport function getLocale(langOrContext: string | ICoreContext): IAttributeLocale {\r\n const lang = typeof langOrContext === 'string' ? langOrContext : langOrContext.request.locale;\r\n\r\n switch (lang) {\r\n case 'nb-NO':\r\n return nbNO;\r\n case 'en-US':\r\n return {...nbNO, ...enUS};\r\n default:\r\n return nbNO;\r\n }\r\n}\r\n","import { ICoreContext } from '@msdyn365-commerce/core';\r\nimport { ProductSearchResultExt } from \"../../modules/vinhuset-search-result-container/components\";\r\nimport { Customer } from '@msdyn365-commerce/retail-proxy';\r\nimport { hasAccessToBuy } from '.';\r\n\r\nexport interface OnBuyHasAccessValidatorResult {\r\n isValid: boolean;\r\n message?: string;\r\n}\r\n\r\nexport async function onBuyHasAccessValidator(\r\n context: ICoreContext,\r\n customer: Customer | undefined,\r\n product: ProductSearchResultExt,\r\n validationMessage: string | undefined\r\n): Promise {\r\n if (!product || !product.AttributeValues) {\r\n return { isValid: true };\r\n }\r\n\r\n const hasAccess = hasAccessToBuy(context, customer, product.AttributeValues);\r\n\r\n return {\r\n isValid: hasAccess,\r\n message: hasAccess ? undefined : validationMessage\r\n };\r\n}\r\n","import { ProductPrice } from \"@msdyn365-commerce/retail-proxy\";\r\n\r\nexport function multiplyPriceBy(price: ProductPrice, multiplier: number) {\r\n const newPrice = { ...price };\r\n\r\n if (newPrice.AdjustedPrice) {\r\n newPrice.AdjustedPrice *= multiplier;\r\n }\r\n\r\n if (newPrice.BasePrice) {\r\n newPrice.BasePrice *= multiplier;\r\n }\r\n\r\n if (newPrice.TradeAgreementPrice) {\r\n newPrice.TradeAgreementPrice *= multiplier;\r\n }\r\n\r\n if (newPrice.CustomerContextualPrice) {\r\n newPrice.CustomerContextualPrice *= multiplier;\r\n }\r\n\r\n if (newPrice.DiscountAmount) {\r\n newPrice.DiscountAmount *= multiplier;\r\n }\r\n\r\n if (newPrice.DiscountLines && newPrice.DiscountLines.length > 0) {\r\n newPrice.DiscountLines.forEach((line) => {\r\n if (line.EffectiveAmount) {\r\n line.EffectiveAmount *= multiplier;\r\n }\r\n });\r\n }\r\n\r\n return newPrice;\r\n}\r\n\r\nexport function dividePriceBy(price: ProductPrice, divisor: number) {\r\n return multiplyPriceBy(price, 1 / divisor);\r\n}\r\n","import { IActionContext } from '@msdyn365-commerce/core';\r\nimport { ProductRefinerValue, ProductSearchCriteria } from '@msdyn365-commerce/retail-proxy';\r\nimport getOrganizationCustomer, { GetOrganizationCustomerInput } from '../actions/get-organization-customer';\r\n\r\nexport function shouldFilterAlcohol(context: IActionContext): boolean {\r\n const doAlcoholFiltering = context.requestContext.url.requestUrl.searchParams.get('alcohol')?.toLowerCase() !== 'false';\r\n const alcoholRefinerRecordId = Number(context.requestContext.app.config?.alcoholRefinerRecordId);\r\n\r\n return doAlcoholFiltering && !isNaN(alcoholRefinerRecordId) && alcoholRefinerRecordId > 0;\r\n}\r\n\r\nexport async function getAlcoholRefiners(context: IActionContext): Promise {\r\n const alcoholGroupAttributeId = Number(context.requestContext.app.config?.alcoholRefinerRecordId);\r\n\r\n if (isNaN(alcoholGroupAttributeId) || alcoholGroupAttributeId === 0) {\r\n return [];\r\n }\r\n\r\n const result: ProductRefinerValue[] = [];\r\n const alcoholRefiner: ProductRefinerValue = {\r\n DataTypeValue: 5,\r\n LeftValueBoundString: '0',\r\n RefinerRecordId: alcoholGroupAttributeId,\r\n RefinerSourceValue: 1,\r\n RightValueBoundString: '0',\r\n UnitText: ''\r\n };\r\n\r\n result.push(alcoholRefiner);\r\n\r\n try {\r\n let alcoholLicenseValue = 0;\r\n\r\n if (context.requestContext.user.isAuthenticated) {\r\n // Get Customer attributes\r\n // const customer = await getCustomer(new GetCustomerInput(context.requestContext.apiSettings, context.requestContext.user.customerAccountNumber), context);\r\n const customer = await getOrganizationCustomer(new GetOrganizationCustomerInput(context.requestContext.apiSettings, context.requestContext.user.customerAccountNumber!), context);\r\n const alcoholLicense = Number(customer.Attributes?.find(x => x.RecordId === alcoholGroupAttributeId)?.AttributeValue?.StringValue);\r\n\r\n if (isNaN(alcoholLicense)) {\r\n // Throw NaN error\r\n console.warn('Alcohol license value is missing or not a number.');\r\n } else {\r\n alcoholLicenseValue = alcoholLicense;\r\n }\r\n } else {\r\n // If user is not logged in show all products\r\n alcoholLicenseValue = 3;\r\n }\r\n\r\n // TODO: Verify we can do ranges like this on text attributes\r\n // If we can do range on text attributes use this:\r\n //alcoholRefiner.RightValueBoundString = alcoholLicense?.AttributeValue?.StringValue ?? '0';\r\n\r\n // Add a refiner for each alcohol group\r\n Array(alcoholLicenseValue).fill(0).forEach((_, index) => {\r\n result.push({\r\n ...alcoholRefiner,\r\n LeftValueBoundString: (index + 1).toString(),\r\n RightValueBoundString: (index + 1).toString()\r\n });\r\n });\r\n } catch (error) {\r\n console.warn('Failed to get customer attributes for alcohol license or parse value of attribute. No alcohol license applied to search.', error);\r\n }\r\n\r\n return result;\r\n}\r\n\r\nexport async function addAlcoholRefiner(context: IActionContext, searchCriteriaInput: ProductSearchCriteria): Promise {\r\n const alcoholGroupAttributeId = Number(context.requestContext.app.config?.alcoholRefinerRecordId);\r\n\r\n if (isNaN(alcoholGroupAttributeId) || alcoholGroupAttributeId === 0) {\r\n return;\r\n }\r\n\r\n if (searchCriteriaInput.Refinement!.some(x => x.RefinerRecordId === alcoholGroupAttributeId)) {\r\n // Remove existing, shouldn't be here\r\n searchCriteriaInput.Refinement = searchCriteriaInput.Refinement!.filter(x => x.RefinerRecordId !== alcoholGroupAttributeId);\r\n }\r\n\r\n const refiners = await getAlcoholRefiners(context);\r\n\r\n searchCriteriaInput.Refinement = searchCriteriaInput.Refinement!.concat(refiners);\r\n\r\n return Promise.resolve();\r\n}\r\n","import { IActionContext, ICoreContext } from '@msdyn365-commerce/core';\r\nimport { IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\r\nimport { AttributeDataType, Customer, ProductRefinerSource, ProductRefinerValue, ProductSearchCriteria } from '@msdyn365-commerce/retail-proxy';\r\nimport getOrganizationCustomer, { GetOrganizationCustomerInput } from '../actions/get-organization-customer';\r\nimport { getLocale } from './attributes/locale';\r\n\r\nfunction isGodmodeEnabled(context: IActionContext): boolean {\r\n const godmode = context.requestContext.url.requestUrl.searchParams.get('godmode')?.toLowerCase();\r\n\r\n return godmode === '1' || godmode === 'true';\r\n}\r\n\r\nexport function addOrUpdateZeroPriceRefiner(context: IActionContext, refiners?: ProductRefinerValue[]): ProductRefinerValue[] {\r\n const enableZeroPriceFilterConfig = context.requestContext.app.config?.enableZeroPriceFilter as boolean;\r\n\r\n // Check criteria for allowing user to see zero price products. Example:\r\n // - Has ?godmode=true in url\r\n const allowZeroPriceProducts = isGodmodeEnabled(context) || enableZeroPriceFilterConfig;\r\n\r\n if (!allowZeroPriceProducts) {\r\n const result = refiners ? [...refiners] : [];\r\n\r\n // Make sure we don't show zero price products\r\n const priceRefiner = result.find(x => x.RefinerRecordId === 0);\r\n\r\n if (priceRefiner) {\r\n // There is a price refiner, make sure it has a min value of 0.01 or more\r\n if (!priceRefiner.LeftValueBoundString || Number(priceRefiner.LeftValueBoundString) < 0.01) {\r\n priceRefiner.LeftValueBoundString = '0.01';\r\n }\r\n } else {\r\n // No price refiner, add one\r\n result.push({\r\n '@odata.type': '#Microsoft.Dynamics.Commerce.Runtime.DataModel.ProductRefinerValue',\r\n Count: 0,\r\n DataTypeValue: 1,\r\n LeftValueBoundString: '0.01',\r\n ExtensionProperties: [],\r\n RefinerRecordId: 0,\r\n RefinerSourceValue: 3,\r\n RightValueBoundString: '1000000000',\r\n RowNumber: 0,\r\n UnitText: context.requestContext.channel?.Currency\r\n } as ProductRefinerValue);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n return refiners || [];\r\n}\r\n\r\nexport async function getAttributeRefiners(context: IActionContext, customer: Customer | undefined, attributeRecordId: number, friendlyName?: string): Promise {\r\n const result: ProductRefinerValue[] = [];\r\n const refiner: ProductRefinerValue = {\r\n DataTypeValue: 5,\r\n LeftValueBoundString: '0',\r\n RefinerRecordId: attributeRecordId,\r\n RefinerSourceValue: 1,\r\n RightValueBoundString: '0',\r\n UnitText: ''\r\n };\r\n\r\n result.push(refiner);\r\n\r\n try {\r\n let attributeValue = 0;\r\n\r\n if (customer) {\r\n const attribute = Number(customer.Attributes?.find(x => x.RecordId === attributeRecordId)?.AttributeValue?.StringValue);\r\n\r\n if (isNaN(attribute)) {\r\n // Throw NaN error\r\n if (friendlyName) {\r\n console.warn(`${friendlyName} attribute value is missing or not a number.`);\r\n } else {\r\n console.warn(`Attribute with record id ${attributeRecordId} is missing a value or not a number.`);\r\n }\r\n } else {\r\n attributeValue = attribute;\r\n }\r\n } else {\r\n // If user is not logged in show all products\r\n attributeValue = 1;\r\n }\r\n\r\n if (attributeValue !== 0) {\r\n result.push({\r\n ...refiner,\r\n LeftValueBoundString: attributeValue.toString(),\r\n RightValueBoundString: attributeValue.toString()\r\n });\r\n }\r\n } catch (error) {\r\n if (friendlyName) {\r\n console.warn(`Failed to get ${friendlyName} customer attribute or parse value of attribute. No filter applied to search.`, error);\r\n } else {\r\n console.warn(`Failed to get customer attribute (record id: ${attributeRecordId}) or parse value of attribute. No filter applied to search.`, error);\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction getCustomerSpecificRefiners(context: IActionContext, customer: Customer | undefined): ProductRefinerValue[] | undefined {\r\n const attributeRecordId = Number(context.requestContext.app.config?.customerSpecificRefinerRecordId);\r\n\r\n if (isNaN(attributeRecordId) || attributeRecordId <= 0) {\r\n return undefined;\r\n }\r\n\r\n const allProductsRefiner: ProductRefinerValue = {\r\n DataTypeValue: AttributeDataType.Text,\r\n LeftValueBoundString: '0',\r\n RefinerRecordId: attributeRecordId,\r\n RefinerSourceValue: ProductRefinerSource.Attribute,\r\n RightValueBoundString: '0',\r\n UnitText: ''\r\n };\r\n\r\n if (customer) {\r\n return [\r\n allProductsRefiner,\r\n {\r\n ...allProductsRefiner,\r\n LeftValueBoundString: customer.AccountNumber,\r\n RightValueBoundString: customer.AccountNumber\r\n }\r\n ];\r\n }\r\n\r\n return [allProductsRefiner];\r\n}\r\n\r\nexport async function addAttributeRefiner(context: IActionContext, customer: Customer | undefined, searchCriteriaInput: ProductSearchCriteria, attributeRecordId: number): Promise {\r\n if (searchCriteriaInput.Refinement!.some(x => x.RefinerRecordId === attributeRecordId)) {\r\n // Remove existing, shouldn't be here\r\n searchCriteriaInput.Refinement = searchCriteriaInput.Refinement!.filter(x => x.RefinerRecordId !== attributeRecordId);\r\n }\r\n\r\n const refiners = await getAttributeRefiners(context, customer, attributeRecordId);\r\n\r\n searchCriteriaInput.Refinement = searchCriteriaInput.Refinement!.concat(refiners);\r\n}\r\n\r\nexport async function addAllAttributeRefiners(context: IActionContext, searchCriteriaInput: ProductSearchCriteria): Promise {\r\n const godmode = isGodmodeEnabled(context);\r\n\r\n if (godmode) {\r\n return;\r\n }\r\n\r\n const attributeRecordIds: string[] = [\r\n context.requestContext.app.config?.tobaccoRefinerRecordId\r\n ];\r\n const { apiSettings, user: { customerAccountNumber } } = context.requestContext;\r\n let customer: Customer | undefined;\r\n\r\n if (context.requestContext.user.isAuthenticated) {\r\n customer = await getOrganizationCustomer(new GetOrganizationCustomerInput(apiSettings, customerAccountNumber!), context);\r\n }\r\n\r\n for (const attributeRecordId of attributeRecordIds) {\r\n const id = Number(attributeRecordId);\r\n\r\n // Make sure it's a number and above 0\r\n if (!isNaN(id) && id > 0) {\r\n await addAttributeRefiner(context, customer, searchCriteriaInput, id);\r\n }\r\n }\r\n\r\n // Add customer specific refiner\r\n const customerSpecificRefiners = getCustomerSpecificRefiners(context, customer);\r\n if (customerSpecificRefiners) {\r\n searchCriteriaInput.Refinement = searchCriteriaInput.Refinement!.concat(customerSpecificRefiners);\r\n }\r\n}\r\n\r\nexport async function getAllAttributeRefiners(context: IActionContext) {\r\n const godmode = isGodmodeEnabled(context);\r\n\r\n if (godmode) {\r\n return [];\r\n }\r\n\r\n const attributeRecordIds: string[] = [\r\n context.requestContext.app.config?.tobaccoRefinerRecordId\r\n ];\r\n const { apiSettings, user: { customerAccountNumber } } = context.requestContext;\r\n let customer: Customer | undefined;\r\n\r\n if (context.requestContext.user.isAuthenticated) {\r\n customer = await getOrganizationCustomer(new GetOrganizationCustomerInput(apiSettings, customerAccountNumber!), context);\r\n }\r\n\r\n const result: ProductRefinerValue[] = [];\r\n\r\n for (const attributeRecordId of attributeRecordIds) {\r\n const id = Number(attributeRecordId);\r\n\r\n // Make sure it's a number and above 0\r\n if (!isNaN(id) && id > 0) {\r\n const refiners = await getAttributeRefiners(context, customer, id);\r\n result.push(...refiners);\r\n }\r\n }\r\n\r\n // Add customer specific refiner\r\n const customerSpecificRefiners = getCustomerSpecificRefiners(context, customer);\r\n if (customerSpecificRefiners) {\r\n result.push(...customerSpecificRefiners);\r\n }\r\n\r\n return result;\r\n}\r\n\r\nexport function getPredefinedOrder(context: ICoreContext): string[] {\r\n const locale = getLocale(context);\r\n\r\n return [\r\n locale.subCategory,\r\n locale.country,\r\n locale.district,\r\n locale.underDistrict,\r\n locale.vintage,\r\n locale.organic,\r\n locale.screwCap,\r\n locale.inventory\r\n ];\r\n}\r\n\r\nexport function sortByPredefinedOrder(context: ICoreContext): (a: IProductRefinerHierarchy, b:IProductRefinerHierarchy) => number {\r\n const predefinedOrder = getPredefinedOrder(context);\r\n const orderMap = new Map(predefinedOrder.map((item, index) => [item.toLowerCase(), index]));\r\n\r\n return (a, b) => {\r\n const indexA = orderMap.has(a.KeyName?.toLowerCase() || '') ? orderMap.get(a.KeyName?.toLowerCase() || '')! : Infinity;\r\n const indexB = orderMap.has(b.KeyName?.toLowerCase() || '') ? orderMap.get(b.KeyName?.toLowerCase() || '')! : Infinity;\r\n\r\n return indexA - indexB;\r\n };\r\n}\r\n","import { format } from '@msdyn365-commerce/retail-proxy';\r\nimport {\r\n IProductInventoryInformation\r\n} from '@msdyn365-commerce-modules/retail-actions';\r\n\r\nfunction getWeekNumber(date: Date): number {\r\n // Copy the given date so that we don't modify the original\r\n const currentDate = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));\r\n\r\n // Set to the nearest Thursday: current date + 4 - current day number\r\n // Make Sunday's day number 7 (ISO 8601 standard)\r\n const dayNumber = (currentDate.getUTCDay() + 6) % 7;\r\n\r\n // Thursday of the current week\r\n currentDate.setUTCDate(currentDate.getUTCDate() - dayNumber + 3);\r\n\r\n // First Thursday of the year\r\n const firstThursday = new Date(Date.UTC(currentDate.getUTCFullYear(), 0, 4));\r\n\r\n // Adjust if the first week starts in the previous year\r\n if (firstThursday.getUTCDay() !== 4) {\r\n firstThursday.setUTCDate(firstThursday.getUTCDate() - ((firstThursday.getUTCDay() + 6) % 7));\r\n }\r\n\r\n // Calculate full weeks to nearest Thursday\r\n const weekNumber = Math.ceil(((currentDate.getTime() - firstThursday.getTime()) / 86400000 + 1) / 7);\r\n\r\n return weekNumber > 0 ? weekNumber : 1;\r\n}\r\n\r\nexport function formatString(template: string, ...values: any[]): string {\r\n if (!template) {\r\n return '';\r\n }\r\n return template.replace(/{(\\d+)}/g, (match, index) => {\r\n const valueIndex = parseInt(index, 10);\r\n return values[valueIndex] !== undefined ? values[valueIndex] : match;\r\n });\r\n}\r\n\r\nexport function addInventoryVisibilityInfo(\r\n labelToExpand: string,\r\n inventoryInformation: IProductInventoryInformation | undefined,\r\n expectedInventoryDateWithQuantityText: string | undefined,\r\n expectedInventoryDateText: string | undefined\r\n): string {\r\n const expectedInventoryDate = inventoryInformation?.ProductAvailableQuantity.ExtensionProperties\r\n ?.find(x => x.Key === 'ATPDATE')?.Value?.DateTimeOffsetValue;\r\n\r\n // Not using this value for now while we're investgating incorrect values\r\n // const expectedInventoryQuantity = inventoryInformation?.ProductAvailableQuantity.ExtensionProperties\r\n // ?.find(x => x.Key === 'ATPQTY')?.Value?.DecimalValue;\r\n\r\n const expectedInventoryQuantity = inventoryInformation?.ProductAvailableQuantity.AvailableQuantity;\r\n\r\n if (expectedInventoryDate) {\r\n /* const formattedDate = new Date(expectedInventoryDate).toLocaleDateString('nb-NO', {\r\n day: '2-digit',\r\n month: '2-digit'\r\n }); */\r\n const weekNumber = getWeekNumber(new Date(expectedInventoryDate));\r\n\r\n if (expectedInventoryQuantity) {\r\n const text = expectedInventoryDateWithQuantityText || '{0} forventet på lager i uke {1}';\r\n labelToExpand += `${labelToExpand ? '. ' : ''}${format(text, expectedInventoryQuantity, weekNumber)}`;\r\n } else {\r\n const text = expectedInventoryDateText || 'Forventet på lager i uke {0}';\r\n labelToExpand += `${labelToExpand ? '. ' : ''}${format(text, weekNumber)}`;\r\n }\r\n\r\n if (labelToExpand.endsWith('.')) {\r\n labelToExpand = labelToExpand.slice(0, -1);\r\n }\r\n }\r\n\r\n return labelToExpand;\r\n}\r\n","import { UnitOfMeasureConversion } from \"@msdyn365-commerce/retail-proxy\";\r\n\r\nexport function getMostRelevantConversion(conversions: UnitOfMeasureConversion[]): UnitOfMeasureConversion | undefined {\r\n // Accepted units, sorted by priority\r\n const acceptedToUnits = [\r\n 'stk',\r\n 'Stykk',\r\n 'Stk-BS',\r\n 'Kilogram',\r\n 'kg',\r\n 'Liter',\r\n '100_meter'\r\n ];\r\n\r\n for (const unit of acceptedToUnits) {\r\n const find = conversions?.find(conversion => conversion.ToUnitOfMeasureSymbol === unit);\r\n if (find) {\r\n return find;\r\n }\r\n }\r\n\r\n return undefined;\r\n}\r\n\r\nexport function getKilogramConversion(defaultUnitOfMeasure: string | undefined, conversions: UnitOfMeasureConversion[]): UnitOfMeasureConversion | undefined {\r\n if (!defaultUnitOfMeasure) {\r\n return undefined;\r\n }\r\n\r\n const acceptedToUnits = [\r\n 'Kilogram',\r\n 'kg'\r\n ];\r\n return conversions?.find(conversion =>\r\n conversion.FromUnitOfMeasureSymbol === defaultUnitOfMeasure &&\r\n conversion.ToUnitOfMeasureSymbol && acceptedToUnits.includes(conversion.ToUnitOfMeasureSymbol));\r\n}\r\n\r\nexport function getPcsConversion(conversions: UnitOfMeasureConversion[]): UnitOfMeasureConversion | undefined {\r\n const acceptedFromUnits = [\r\n 'Krt-M1',\r\n 'Krt-BS'\r\n ];\r\n const acceptedToUnits = [\r\n 'stk',\r\n 'Stykk',\r\n 'Stk-BS',\r\n 'Pose-BS'\r\n ];\r\n\r\n return conversions?.find(conversion =>\r\n (conversion.FromUnitOfMeasureSymbol && acceptedFromUnits.includes(conversion.FromUnitOfMeasureSymbol)) &&\r\n (conversion.ToUnitOfMeasureSymbol && acceptedToUnits.includes(conversion.ToUnitOfMeasureSymbol)));\r\n}\r\n\r\nexport function getRoundedFactor(conversion: UnitOfMeasureConversion): number {\r\n // Only round if the conversion is kg/Kilogram\r\n if (conversion.Factor && (conversion.ToUnitOfMeasureSymbol === 'kg' || conversion.ToUnitOfMeasureSymbol === 'Kilogram')) {\r\n return Math.round((conversion.Factor + Number.EPSILON) * 100) / 100;\r\n } else {\r\n return conversion.Factor || 0;\r\n }\r\n}\r\n\r\nexport function getMinimumDecimals(unitOfMeasure: string | undefined): number {\r\n const units = [\r\n 'kg',\r\n 'Kilogram'\r\n ];\r\n return units.includes(unitOfMeasure || '') ? 2 : 0;\r\n}\r\n","const binding = { modules: {}, dataActions: {} };\n\n const registerActionId = (actionPath) => {\n if (binding.dataActions[actionPath] &&\n binding.dataActions[actionPath].default &&\n binding.dataActions[actionPath].default.prototype &&\n binding.dataActions[actionPath].default.prototype.id) {\n binding.dataActions[binding.dataActions[actionPath].default.prototype.id] = binding.dataActions[actionPath];\n } else {\n Object.keys(binding.dataActions[actionPath] || {}).forEach(exportName => {\n if (binding.dataActions[actionPath][exportName] &&\n binding.dataActions[actionPath][exportName].prototype &&\n binding.dataActions[actionPath][exportName].prototype.Action) {\n binding.dataActions[binding.dataActions[actionPath][exportName].prototype.id] = binding.dataActions[actionPath][exportName];\n }\n })\n }\n };\n\n const registerSanitizedActionPath = (sanitizedActionPath, dataAction) => {\n if (process.env.NODE_ENV === 'development') {\n if (!dataAction.default) {\n throw new Error('Data action path does not have a default export');\n }\n if (!(dataAction.default.prototype.id && binding.dataActions[dataAction.default.prototype.id]) || !binding.dataActions[sanitizedActionPath]) {\n binding.dataActions[sanitizedActionPath] = dataAction;\n }\n } else {\n binding.dataActions[sanitizedActionPath] = dataAction;\n if (!binding.dataActions[sanitizedActionPath].default) {\n throw new Error('Data action path ' + sanitizedActionPath + ' does not have a default export');\n }\n binding.dataActions[sanitizedActionPath].default.prototype.RegistrationId = sanitizedActionPath;\n if (binding.dataActions[sanitizedActionPath].default.prototype.id) {\n binding.dataActions[binding.dataActions[sanitizedActionPath].default.prototype.id] = sanitizedActionPath;\n }\n }\n };\n \n\n (binding.modules['vinhuset-search'] = {\n c: () => require('partner/modules/vinhuset-search/vinhuset-search.tsx'),\n $type: 'contentModule',\n da: [{name:'cart', path:'@msdyn365-commerce/global-state/dist/lib/data-actions/cart-state-data-action', runOn: 0},{name:'orgInformation', path:'actions/get-organization-customer', runOn: 0},{name:'searchState', path:'@msdyn365-commerce-modules/search-utilities/dist/lib/search-state-data-action', runOn: 1}],\n \n iNM: false,\n ns: '__local__',\n n: 'vinhuset-search',\n p: '__local__',\n \n pdp: '',\n \n \n md: 'src/modules/vinhuset-search'\n });\n \n\n {\n const sanitizedActionPath = '@msdyn365-commerce-modules/search-utilities/dist/lib/search-state-data-action';\n let dataAction = require('@msdyn365-commerce-modules/search-utilities/dist/lib/search-state-data-action');\n registerSanitizedActionPath(sanitizedActionPath, dataAction);\n }\n \n\n {\n const sanitizedActionPath = '@msdyn365-commerce/global-state/dist/lib/data-actions/cart-state-data-action';\n let dataAction = require('@msdyn365-commerce/global-state/dist/lib/data-actions/cart-state-data-action');\n registerSanitizedActionPath(sanitizedActionPath, dataAction);\n }\n \n\n {\n const sanitizedActionPath = 'actions/get-organization-customer';\n let dataAction = require('partner/actions/get-organization-customer');\n registerSanitizedActionPath(sanitizedActionPath, dataAction);\n }\n \n\n \n window.__bindings__ = window.__bindings__ || {};\n window.__bindings__.modules = {\n ...window.__bindings__.modules || {},\n ...binding.modules\n };\n \n window.__bindings__.dataActions = {\n ...window.__bindings__.dataActions || {},\n ...binding.dataActions\n };\n export const viewDictionary = {};\n viewDictionary['__local__|__local__|modules|vinhuset-search|vinhuset-search'] = {\n c: () => require('partner/modules/vinhuset-search/vinhuset-search.view.tsx'),\n cn: '__local__-__local__-vinhuset-search'\n };\nwindow.__bindings__ = window.__bindings__ || {};\nwindow.__bindings__.viewDictionary = {\n ...window.__bindings__.viewDictionary || {},\n ...viewDictionary\n };","/*!\n * Copyright (c) Microsoft Corporation.\n * All rights reserved. See LICENSE in the project root for license information.\n */\n\nimport { observable } from 'mobx';\n\n/**\n * State information related to what is needed to succesfully perform a autosuggest.\n */\nexport class SearchState {\n @observable public searchText?: string;\n\n @observable public defaultBasicSearchUrl?: string;\n\n @observable public searchQueryStringParameter?: string;\n}\n","/*!\n * Copyright (c) Microsoft Corporation.\n * All rights reserved. See LICENSE in the project root for license information.\n */\n\nimport { createObservableDataAction, IAction, IActionInput, IAny, ICreateActionContext, IGeneric } from '@msdyn365-commerce/core';\nimport { GenericInput, getGenericAction } from '@msdyn365-commerce-modules/retail-actions';\n\nimport { SearchState } from './search-state';\n\nexport function createSearchStateInput(result: SearchState): GenericInput {\n return new GenericInput('searchState', result, 'SearchState');\n}\n\nconst createsearchStateInputInternal = (inputData: ICreateActionContext>): IActionInput => {\n return createSearchStateInput({ searchText: '' });\n};\n\nexport const getGenericActionDataAction = createObservableDataAction({\n action: >getGenericAction,\n input: createsearchStateInputInternal\n});\n\nexport default getGenericActionDataAction;\n","module.exports = React;","module.exports = ReactDOM;"],"names":["GetOrganizationCustomerInput","constructor","apiSettings","user","getDataServiceRequest","this","query","createDataServiceRequestForOperation","Entities","bypassCache","returnEntity","shouldCacheOutput","getCacheKey","getCacheObjectType","dataCacheType","DataServiceQuery","getOrganizationCustomerAction","async","input","ctx","requestContext","isAuthenticated","callActionOrExecute","getOrganizationCustomer","createObservableDataAction","id","action","inputData","_user$customerAccount","customerAccountNumber","_ref","className","label","checked","onChange","mini","miniLabel","internalChecked","setInternalChecked","React","Boolean","classnames","title","type","event","target","getInitialBreakoffState","initialValue","product","_product$Behavior","multiplier","Behavior","DefaultQuantity","factor","Math","round","Number","EPSILON","breakoff","ProductListOrderQuantity","props","super","inputRef","_getUnitOfMeasureConversion","_this$props$product","_this$props$unitConve","_this$props$product3","unitConversions","DefaultUnitOfMeasure","conversions","filter","x","_this$props$product2","FromUnitOfMeasureSymbol","conversion","getMostRelevantConversion","getRoundedFactor","toLocaleString","locale","minimumFractionDigits","getMinimumDecimals","ToUnitOfMeasureSymbol","maximumFractionDigits","useGrouping","defaultUOM","humanizeUnitOfMeasure","context","conversionUOM","toLocaleLowerCase","_convertIncomingQuantity","quantity","multipleOf","_convertOutgoingQuantity","outgoing","_onToggleBreakoff","_this$props$onBreakof","_this$props","setState","onBreakoffChange","call","_clamp","total","productMinimumQuantity","productMaximumQuantity","_isValidNewQuantity","newQuantity","allowZero","isNaN","minimum","maximum","currentCount","_this$productMinimumQ","hasBreakoff","breakoffState","state","currentInput","parsedCurrentInput","parseFloat","bind","_handleChange","_validateQuantity","_this$props$product4","productMultipleOfQuantity","productDefaultQuantity","_this$props$product5","_this$props$product6","MaximumQuantity","_this$props$product7","MinimumQuantity","_this$props$product8","MultipleOfQuantity","_this$props$product9","_this$props$product10","uom","includes","componentDidMount","when","undefined","_this$productMinimumQ2","multipler","reaction","_this$props$currentCo","replace","oldQuantity","newValue","_this$props$currentCo2","newInput","_this$props$currentCo3","_this$props$product11","showDecimals","toString","render","_product$Behavior2","_product$Behavior3","hideUnitConversion","disabled","incDisabled","currentValue","baseClassName","miniBreakoff","legacyBreakoff","extraClass","getChangeHandler","amount","calcTotal","change","newAmount","newTotal","_onIncrementalChange","Switch","decrementButtonAriaLabel","onClick","tabIndex","color","pattern","value","onBlur","onKeyPress","e","fieldValue","fieldHasCommaOrDot","keyIsCommaOrDot","key","test","preventDefault","separator","_Intl$NumberFormat$fo","Intl","NumberFormat","formatToParts","find","part","getDecimalSeparator","inputQuantityAriaLabel","role","ref","incrementButtonAriaLabel","totalFormatted","UnitOfMeasure","simpleProduct","updatedQuantity","_this$props$onChange","_this$props2","persist","_this$props$onChange2","_this$props3","_this$_clamp","max","_this$props$onChange3","_this$props4","defaultProps","decrementGlyphClass","incrementGlyphClass","__decorate","computed","observer","SuggestionType","ProductListInventoryFilteringOptions","AutoSuggestInput","searchText","top","suggestionType","hitPrefix","hitSuffix","searchQuery","topResultsCount","_getAutoSuggest","autosuggest","_ctx$requestContext$a","_searchCriteria$Produ","catalogId","getCatalogId","productSearchCriteria","SearchCondition","length","Context","ChannelId","channelId","CatalogId","app","config","productListInventoryDisplay","HideOOS","inventoryRefinerValue","getInventorySortableRefinerValue","channelInventoryConfiguration","isInStock","ProductAvailabilitySortableAttributeRecordId","RefinerRecordId","DataTypeValue","AttributeDataType","TrueFalse","LeftValueBoundString","RightValueBoundString","UnitText","RowNumber","Count","ExtensionProperties","RefinerSourceValue","ProductRefinerSource","Attribute","getInventoryConfigurationAsync","callerContext","_objectSpread","Refinement","searchCriteria","ProductSearchCriteria","HitPrefix","HitSuffix","addOrUpdateZeroPriceRefiner","shouldFilterAlcohol","addAlcoholRefiner","addAllAttributeRefiners","searchSuggestions","getSearchSuggestionsAsync","queryResultSettings","Paging","Top","map","item","_item$Value","ImageUrl","generateImageUrl","Value3","Value","DecimalValue","AllSearchResults","telemetry","error","Error","autoSuggestPromises","Promise","all","then","payLoad","CategorySuggestionsComponent","suggestions","autoSuggestProps","resources","categorySuggestionHeading","reactNodes","getPayloadObject","telemetryContent","push","_assembleNode","_renderTitle","text","categoryAutoSuggestionHeading","format","_props$searchTermComp","_item$Value2","_props$searchTermComp2","_item$Value3","shouldShowFullPath","splitValue","split","pop","ariaLabel","RegExp","fullText","searchTermCompleted","toUpperCase","categorySuggestionJoinerText","contentAction","etext","attribute","getTelemetryAttributes","productCountLabel","IntegerValue","categorySuggestionProductCount","categorySuggestionProductCountPlural","Id","Object","assign","href","_generateLink","_getHighlightedText","formatString","suggestion","_getCategoryLink","_categoryRefiners$Val","searchPageURL","searchQsp","searchRefiners","MsDyn365","isBrowser","queryUrl","URL","window","location","searchParams","set","categoryRefiners","refiners","SourceValue","Category","refiner","Values","parseInt","encodedRefiner","JSON","stringify","compressRefiners","formattedText","dangerouslySetInnerHTML","getRichTextHtml","compressedRefinerKeys","compressedRefiners","forEach","compressedRefiner","refinerKey","FormComponent","searchPlaceholder","searchTextInput","handleInputChange","maxChars","disableSubmitSearch","handleCancelSearchChange","handleScannerButtonClick","ariaLabelCancel","ariaLabelSearch","ariaLabelSubmit","onInputChange","onInputChangeFunction","inputNode","name","placeholder","maxLength","submitBtnNode","Button","src","getAsset","request","cancelBtn","submitBtn","scannerBtn","width","height","KeywordSuggestionsComponent","splice","slice","formattedLink","_cart$cart$CartLines","cart","productId","inCartTooltipText","showCartCountTooltip","setShowCartCountTooltip","cartQuantity","CartLines","ProductId","reduce","acc","val","Quantity","cartCountId","tooltipString","tooltipText","onMouseOver","onMouseOut","onTouchStart","Tooltip","isOpen","typeName","productRecordId","productPrice","cartQueue","setQuantity","setBreakoff","forceUpdate","setForceUpdate","onContainerClick","closest","stopPropagation","toastStrings","errorHeader","toastErrorHeader","productsAddedToCart","productsRemovedFromCart","productsUpdatedInCart","goToCart","toastGoToCart","noAccessToProduct","toastNoAccessToProduct","productSearchResult","RecordId","Price","CustomerContextualPrice","draggable","onDragStart","_props$onBreakoffChan","CartCount","AddToCartComponent","onUpdateQuantity","data","price","productSearch","buyAlwaysAdd","addToCartText","addToCartButtonText","removeFromCartText","updateCartText","expiredText","onBuyValidate","onAdd","ProductSuggestionsComponent","actionContext","productSuggestionHeading","moduleType","moduleId","items","productAutoSuggestionHeading","altText","activePrices","simpleProducts","thumbnail","_renderThumbnail","_renderPrice","buySection","_renderBuySection","LiProduct","_getLiWrapper","AProduct","_getAWrapper","tag","recid","cultureFormatter","formatCurrency","getProductPageUrlSync","_simpleProduct$Behavi","_props$resources","_simpleProduct$Behavi2","_props$resources2","_props$resources3","breakoffProducts","multiplyPriceBy","PriceComponent","freePriceText","pricePerText","itemId","_props$resources4","BuySection","gridSettings","imageSettings","cropFocalRegion","defaultImageSettings","viewports","lg","q","w","h","md","sm","xl","xs","lazyload","Image","loadFailureBehavior","SuggestionTypeCriterionSuggestionType","qrcodeRegionId","cachedModule","getScannerModule","DefaultResources","noCameraDevicesFound","errorGettingDevices","loading","chooseCamera","changeCamera","close","modalIsOpen","devices","setDevices","working","setWorking","setError","selectedDeviceId","setSelectedDeviceId","scanner","_scanner$current","_scanner$current2","current","isScanning","stop","_scanner$current3","clear","deviceId","localStorage","getItem","some","d","Html5Qrcode","getCameras","console","work","_scanner$current4","_scanner$current5","start","fps","qrbox","viewFinderWidth","viewFinderHeight","minEdgeSize","min","qrboxSize","floor","onScanSuccess","decodedText","onFound","shouldShowScanner","Modal","modalClassName","toggle","onClose","ModalBody","style","display","device","index","onSelectDevice","setItem","position","ModalFooter","nativeEvent","stopImmediatePropagation","Search","waitTime","PQueue","concurrency","_isLoadingNode","loadingText","autoSuggestResultLoadingMessage","Spinner","size","SpinnerSize","medium","labelPosition","_focusOutTarget","_clearAutoSuggestState","_keyup","keyCode","KeyCodes","Escape","formReference","contains","autoSuggestResultDiv","searchState","defaultBasicSearchUrl","searchQueryStringParameter","update","createSearchStateInput","_handleInputChange","cancellabelDebounce","cancel","ArrayExtensions","hasElements","inputSuggestionType","_loadSuggestions","_handleSubmit","focus","searchURL","_appendQueryParams","getUrlSync","document","_handleCancelSearchChange","isInitialState","_handleScannerButtonClick","showScannerModal","_handleCancelSearchFocused","route","qsp","_setAutoSuggestResultCount","result","autoSuggestResultScreenReaderDiv","ariaLiveRegion","suggestResultString","autoSuggestFoundMessage","emptyResultString","noAutoSuggestionMessage","innerText","setAttribute","_onBuyValidate","_this$state$suggestio","missingProducts","productSearchResults","y","searchResults","searchByCriteriaAsync","Ids","IncludeAttributes","onBuyHasAccessValidator","orgInformation","_onBreakoffChange","prevState","_renderScannerModal","BarcodeScanner","noCameraDevicesFoundText","errorGettingDevicesText","chooseCameraText","changeCameraText","modalCloseButtonText","searchKeywordSuggestClass","searchProductSuggestClass","searchCategorySuggestClass","autoSuggestAriaLabel","isLoadingAutoSuggest","searchInputMaxLength","searchFormClass","getTelemetryObject","telemetryPageName","friendlyName","_initSuggestionTypes","body","addEventListener","componentWillUnmount","removeEventListener","componentDidUpdate","_getActivePrices","_getSimpleProducts","shouldComponentUpdate","nextProps","nextState","_suggestions$AllSearc","_suggestions$AllSearc2","_suggestions$AllSearc3","cancelBtnAriaLabel","searchBtnAriaLabel","submitBtnAriaLabel","searchplaceholderText","shouldShowFullCategoryPath","keywordSuggestions","Keyword","None","productSuggestions","Product","categorySuggestions","_item$RefinerRecordId","ObjectExtensions","isNullOrUndefined","viewProps","moduleProps","AutoSuggestAriaLabel","AutoSuggestAriaLabelText","AutoSuggest","show","hide","KeywordSuggest","ProductSuggest","CategorySuggest","SearchForm","FormWrapper","autoComplete","onSubmit","UlKeyword","UlProduct","UlCategory","form","autosuggestKeyword","autosuggestProduct","autosuggestCategory","callbacks","handleCancelSearchFocused","isLoadingNode","scannerModal","renderView","suggestionTypes","suggestionTypeCriterion","unique","validValues","keyword","scopedCategory","validSuggestions","_this$state$suggestio2","missingPrices","projectDomain","prices","getActivePricesAsync","Date","newActivePrices","_this$state$suggestio3","ProductsDataActions","newSimpleProducts","loadSuggestionsRequestId","getSearchSuggestionsAction","_getSuggestionType","exception","debug","_getSearchRefiners","_debounce","Random","Guid","generateGuid","_getSearchSuggestions","_updateSearchRefiners","setTimeout","suggestionTypeItem","charAt","join","validateCatalogId","_renderForm","Node","_renderKeywordSuggestions","_renderProductSuggestions","_renderCategorySuggestions","isMobilePort","setIsMobile","overlayDivRef","searchDivRef","shouldShowOverlay","popupPosition","setIsInputFocused","useBlackoutOverlay","searchProps","isSearchText","disableOverlay","setPopupPosition","isInputFocused","searchInputRef","updatePopupPosition","offsetTop","offsetHeight","left","offsetLeft","offsetWidth","blur","resize","right","removeAttribute","onResize","isMobileView","isMobile","variant","VariantType","Browser","Module","getLocale","langOrContext","nbNO","enUS","customer","validationMessage","AttributeValues","isValid","hasAccess","hasAccessToBuy","message","newPrice","AdjustedPrice","BasePrice","TradeAgreementPrice","DiscountAmount","DiscountLines","line","EffectiveAmount","dividePriceBy","divisor","_context$requestConte","_context$requestConte2","doAlcoholFiltering","url","requestUrl","get","toLowerCase","alcoholRefinerRecordId","getAlcoholRefiners","_context$requestConte3","alcoholGroupAttributeId","alcoholRefiner","alcoholLicenseValue","_customer$Attributes","alcoholLicense","Attributes","AttributeValue","StringValue","warn","Array","fill","_","searchCriteriaInput","_context$requestConte4","concat","resolve","isGodmodeEnabled","godmode","enableZeroPriceFilterConfig","enableZeroPriceFilter","priceRefiner","channel","Currency","getAttributeRefiners","attributeRecordId","attributeValue","getCustomerSpecificRefiners","customerSpecificRefinerRecordId","allProductsRefiner","Text","AccountNumber","addAttributeRefiner","_context$requestConte5","attributeRecordIds","tobaccoRefinerRecordId","customerSpecificRefiners","getAllAttributeRefiners","_context$requestConte6","sortByPredefinedOrder","predefinedOrder","subCategory","country","district","underDistrict","vintage","organic","screwCap","inventory","getPredefinedOrder","orderMap","Map","a","b","_a$KeyName","_a$KeyName2","_b$KeyName","_b$KeyName2","has","KeyName","Infinity","template","_len","arguments","values","_key","match","valueIndex","addInventoryVisibilityInfo","labelToExpand","inventoryInformation","expectedInventoryDateWithQuantityText","expectedInventoryDateText","_inventoryInformation","expectedInventoryDate","ProductAvailableQuantity","Key","DateTimeOffsetValue","expectedInventoryQuantity","AvailableQuantity","weekNumber","date","currentDate","UTC","getFullYear","getMonth","getDate","dayNumber","getUTCDay","setUTCDate","getUTCDate","firstThursday","getUTCFullYear","ceil","getTime","getWeekNumber","endsWith","acceptedToUnits","unit","getKilogramConversion","defaultUnitOfMeasure","getPcsConversion","acceptedFromUnits","Factor","unitOfMeasure","binding","modules","dataActions","registerSanitizedActionPath","sanitizedActionPath","dataAction","default","prototype","RegistrationId","c","require","$type","da","path","runOn","iNM","ns","n","p","pdp","__bindings__","viewDictionary","cn","SearchState","observable","GenericInput","getGenericActionDataAction","getGenericAction","module","exports","ReactDOM"],"sourceRoot":""}