{"version":3,"file":"static/js/1de1449e09a3323915f8.bundle.js","mappings":";geA+BM,MAAOA,EAGTC,YAAYC,EAAmCC,GAIxC,KAAAC,mBAAqB,IAAc,sBACnC,KAAAC,YAAc,KAAcC,EAAAA,EAAAA,4BAA2B,sBAAuBC,KAAKJ,gBACnF,KAAAK,cAAgB,IAAiB,UALpCD,KAAKL,OAASA,GAAU,GACxBK,KAAKJ,eAAiBA,GAmB9B,MAmIA,GAAeM,EAAAA,EAAAA,IAA2B,CACtCC,GAAI,gEACJC,OArIWC,MAAOC,EAAiCC,KACnD,MAAM,OAAEZ,GAAWW,EAIbE,EACFD,EAAQX,eAAea,IAAId,OAAOe,cAClC,mFAEEC,QAAiBC,EAAAA,GAA0BJ,EAAU,OAC3D,IAAIK,EACJ,IACIA,QAA8BC,EAAAA,EAAAA,oBAzBCC,CAAAA,IACnC,GAAIA,GAAaA,EAAUnB,eACvB,OAAO,IAAIoB,EAAAA,qBAAqBD,EAAUnB,gBAE9C,MAAM,IAAIqB,MAAM,uDAqBqCC,CAA8BX,GAAUA,GAC3F,MAAAY,IAGF,MAAMC,EAAab,EAAQX,eAAeyB,IAAIC,WAAWC,KACzD,IAAIC,EAAoB,GACpBC,EAAqB,GACrBC,EAAqB,GACzB,GACInB,EAAQX,eAAea,IAAId,OAAOgC,2BAClCC,MAAMC,QAAQtB,EAAQX,eAAea,IAAId,OAAOgC,2BAEhD,IAAK,MAAMG,KAAyBvB,EAAQX,eAAea,IAAId,OAAOgC,2BAC9DP,EAAWW,SAASD,EAAsBE,kBAAoBZ,IAAeU,EAAsBE,mBACnGR,EAAoBM,EAAsBG,aAC1CR,EAAqBK,EAAsBI,cAC3CR,EAAqBI,EAAsBK,sBAIvD,GAAItB,EAAuB,CACvB,MAAMuB,uWAAeC,CAAA,GAAQxB,GAC7B,IAAIyB,EACJ,IAEI,MAAMC,GAAYC,EAAAA,EAAAA,IAAgBjC,EAAQX,eAAe6C,OAAQL,EAAgBM,kBAC3EC,EAAkBP,EAAgBQ,iBAAmBR,EAAgBS,KAC3ET,EAAgBS,KAAON,EACvBH,EAAgBQ,gBAAkBD,EAClCL,GAAcQ,EAAAA,EAAAA,gBAAeV,GAC7B,MAAMW,EAAkBxC,EAAQX,eAAemD,gBAC/C,GAAIT,GAAeS,EAAiB,CAChCT,EAAc,WAAWS,IAAkBT,IAAcU,oBACzD,MAAMC,GAhDAlC,EAgDyBR,IA/CvBQ,EAAUnB,gBAAkBmB,EAAUnB,eAAesD,OAASnC,EAAUnB,eAAesD,MAAMC,KAgD/FC,EAAM,IAAIC,IAAIf,GACdgB,EAA6B,IAAIC,gBAAgBH,EAAII,QACvDP,GACAK,EAAUG,IAAI,OAAQR,GAE1BG,EAAII,OAASF,EAAUI,WACvBpB,EAAcc,EAAIM,WAClBpB,GAAcqB,EAAAA,EAAAA,wBAAuBrB,EAAa/B,EAAQX,qBAE1D0C,OAAcsB,EAEpB,MAAAC,GACEvB,OAAcsB,EAElB,MAAME,GAAShB,EAAAA,EAAAA,gBAAeV,GAExB2B,EADepD,EAASqD,KACSC,MAAM,MAC7C,IACIC,EADAC,EAAQ/B,EAAgBS,KAExBuB,EAAY9B,EAChB,IAAK,MAAM+B,KAAWN,EAAmB,CACrC,IAAKM,IAAYA,EAAQC,OACrB,SAEJ,MAAMC,EAAcF,EAAQC,OAAOL,MAAM,MACnCO,EAAOD,EAAY,GACzB,GAAIT,IAAWA,IAAWU,GAAQV,MAAAA,GAAAA,EAAQ/B,SAASyC,IAASA,EAAKzC,SAAS+B,IAOtE,OANAK,EAAQI,EAAYE,OAAS,EAAIF,EAAY,GAAKnC,EAAgBS,KAClEqB,EAAOK,EAAYE,OAAS,EAAIF,EAAY,QAAKX,EAC7CjE,EAAO+E,kBAAoBR,IAC3BA,EAAOA,EAAKS,UAAU,EAAGhF,EAAO+E,mBAEpCN,EAAYG,EAAYE,OAAS,EAAIF,EAAY,GAAKjC,EAC/C,CACH6B,MAAOA,EACPS,YAAaV,EACbW,gBAAiBzC,EAAgB0C,aACjC7C,aAAcmC,EACdW,WAAYpF,GAAUA,EAAOoF,YAOzC,OAHIpF,EAAO+E,kBAAoBR,IAC3BA,EAAOA,EAAKS,UAAU,EAAGhF,EAAO+E,mBAE7B,CACHP,MAAOA,EACPS,YAAaV,IAEPvE,EAAOqF,2BACPrF,EAAOqF,2BACP,kJACNH,gBAAiBzC,EAAgB0C,aACjC7C,aAAcmC,EACdW,WAAYpF,GAAUA,EAAOoF,YAW9B,OAAIvD,GAAqBC,GACxB9B,EAAO+E,kBAAoBhD,IAC3BA,EAAqBA,EAAmBiD,UAAU,EAAGhF,EAAO+E,mBAEzD,CACHP,MAAO1C,EACPmD,YAAalD,EACbmD,gBAAiBlF,EAAOsF,cAAgBtF,EAAOsF,aAAaC,IAC5DjD,aAAcT,EACduD,WAAYpF,GAAUA,EAAOoF,aAE1BpF,EACA,CACHwE,MAAOxE,EAAOwE,MACdU,gBAAiBlF,EAAOsF,cAAgBtF,EAAOsF,aAAaC,IAC5DH,WAAYpF,GAAUA,EAAOoF,YAG9B,GApIX,IAAsBhE,GAyIlBT,MAAQ6E,GACG,IAAI1F,EAAoD0F,EAAKxF,OAAQwF,EAAKvF,gKC1JnF,MAAOwF,EAST1F,YACIC,EACA0F,EACAC,EACA1F,GAWG,KAAAC,mBAAqB,IAAc,qBAEnC,KAAAC,YAAc,SAAAyF,EAAA,MACjB,IAAGC,EAAAA,EAAAA,eAAc,qBAAsBxF,KAAKqF,gBAAgBrF,KAAKL,OAAOwE,SAASnE,KAAKsF,aAA2B,QAAlBC,EAAIvF,KAAKyF,iBAAS,IAAAF,EAAAA,EAAI,KAElH,KAAAtF,cAAgB,IAAiB,cAdpCD,KAAKL,OAASA,GAAU,GACxBK,KAAKqF,YAAcA,EACnBrF,KAAKsF,UAAYA,EAEb1F,IACAI,KAAKyF,WAAYC,EAAAA,EAAAA,IAAa9F,KAkB1C,MA2JA,GAAeM,EAAAA,EAAAA,IAA2B,CACtCC,GAAI,+DACJC,OAvHWC,MAAOC,EAAgCC,KAClD,MAAM,OAAEZ,EAAM,UAAE2F,EAAS,YAAED,GAAgB/E,EAKrCE,EACFD,EAAQX,eAAea,IAAId,OAAOgG,cAClC,mFACEhF,QAAiBC,EAAAA,GAA0BJ,EAAU,OACrDoF,EAASN,EAAU5B,WAGzB,IAAImC,EACJ,IAAI,IAAAC,EACAD,EAAqBE,EAAAA,gBAAgBC,kBAC3BC,EAAAA,EAAAA,eACF,CACIC,cAAe3F,EACf4F,oBAAqBC,EAAAA,yBAAyBC,qCAAqC9F,IAEvF8E,EAAYiB,UACZ,CAAChB,GACD,KACe,QADXQ,EACJxF,EAAMmF,iBAAS,IAAAK,EAAAA,EAAI,IAG7B,MAAA3E,IAGF,GAAI4E,EAAAA,gBAAgBQ,YAAYV,GAAqB,CACjD,MAAMW,EAAoBX,EAAmB,GAC7C,IAAIY,EAaAC,EAZJ,IACID,GAAaE,EAAAA,EAAAA,mBAAkBH,EAAmBjG,GAClD,MAAMwC,EAAkBxC,EAAQX,eAAemD,gBAC3C0D,GAAc1D,GACd0D,EAAa,WAAW1D,IAAkB0D,IAAazD,oBACvDyD,GAAa9C,EAAAA,EAAAA,wBAAuB8C,EAAYlG,EAAQX,iBAExD6G,OAAa7C,EAEnB,MAAAC,GACE4C,OAAa7C,EAGjB,IAAI,IAAAgD,EACAF,OAtEYrG,OACpBE,EACAsG,EACAP,EACAb,KAEA,MAAMqB,QAA0BC,EAAAA,EAAAA,yBAC5B,CACIb,cAAe3F,EACf4F,oBAAqBC,EAAAA,yBAAyBC,qCAAqC9F,IAEvFsG,EACAP,EACAb,GAEJ,IAAK,MAAMuB,KAAoBF,EAC3B,GAA8B,UAA1BE,EAAiBnE,KACjB,OAAOmE,EAAiBC,WAqDHC,CAAgB3G,EAAS+E,EAAWD,EAAYiB,UAA0B,QAAjBM,EAAEtG,EAAMmF,iBAAS,IAAAmB,EAAAA,EAAI,GACrG,MAAAO,GACET,OAAe9C,EAEnB,MACMG,EADepD,EAASqD,KACSC,MAAM,MAC7C,IAAIE,EAAQqC,EAAkB3D,KAC1BqB,EAAOsC,EAAkBY,YAAcZ,EAAkBY,YAAcZ,EAAkB3D,KACzFuB,EAAYqC,EAChB,IAAK,MAAMpC,KAAWN,EAAmB,CACrC,IAAKM,IAAYA,EAAQC,OACrB,SAEJ,MAAMC,EAAcF,EAAQC,OAAOL,MAAM,MACnCO,EAAOD,EAAY,GACzB,GAAIqB,IAAWA,IAAWpB,GAAQA,EAAKzC,SAAS6D,IAO5C,OANAzB,EAAQI,EAAYE,OAAS,EAAIF,EAAY,GAAKiC,EAAkB3D,KACpEqB,EAAOK,EAAYE,OAAS,EAAIF,EAAY,GAAKiC,EAAkBY,YACnEhD,EAAYG,EAAYE,OAAS,EAAIF,EAAY,GAAKkC,EAClD9G,EAAO+E,kBAAoBR,IAC3BA,EAAOA,EAAKS,UAAU,EAAGhF,EAAO+E,mBAE7B,CACHP,MAAOA,EACPS,YAAaV,EACbW,iBAAiBwC,EAAAA,EAAAA,kBAAiBb,EAAkBc,gBAAiBjC,GACrEpD,aAAcmC,EACdW,WAAYpF,GAAUA,EAAOoF,WAC7BO,UAAWkB,EAAkBe,SAC7BC,MAAOhB,EAAkBiB,cACzBf,aAAAA,GAOZ,OAHI/G,EAAO+E,kBAAoBR,IAC3BA,EAAOA,EAAKS,UAAU,EAAGhF,EAAO+E,mBAE7B,CACHP,MAAOA,EACPS,YAAaV,EACbW,iBAAiBwC,EAAAA,EAAAA,kBAAiBb,EAAkBc,gBAAiBjC,GACrEpD,aAAcmC,EACdW,WAAYpF,GAAUA,EAAOoF,WAC7BO,UAAWkB,EAAkBe,SAC7BC,MAAOhB,EAAkBiB,cACzBf,aAAAA,GAcW,IAAAgB,EAAZ,OAAI/H,EACA,CACHwE,MAAOxE,EAAOwE,MACdS,YAAajF,EAAO+E,iBAAqC,QAArBgD,EAAG/H,EAAOiF,mBAAW,IAAA8C,OAAA,EAAlBA,EAAoB/C,UAAU,EAAGhF,EAAO+E,kBAAoB/E,EAAOiF,YAC1GC,gBAAiBlF,EAAOsF,cAAgBtF,EAAOsF,aAAaC,IAC5DH,WAAYpF,GAAUA,EAAOoF,YAG9B,IAMPzE,MA9JiB6E,IACjB,MAAMG,GAAYqC,EAAAA,EAAAA,qCAAoCxC,GAEtD,GAAIG,EACA,OAAO,IAAIF,EAC2BD,EAAKxF,OACvCwF,EAAKvF,eAAeyF,aACnBC,EACDH,EAAKvF,gBAGb,MAAM,IAAIqB,MAAM,sUC7Ed,SAAU2G,EAAUC,GACtB,OAAOjG,MAAMkG,KAAK,IAAIC,IAAIF,ICwCxB,MAAOG,EAGTtI,YAAY2F,GAIL,KAAAvF,YAAc,KAAM0F,EAAAA,EAAAA,eAAc,kCAAmCxF,KAAKqF,aAC1E,KAAAxF,mBAAqB,IAAM,kCAC3B,KAAAI,cAAgB,IAAiB,OALpCD,KAAKqF,YAAcA,GAQ3B,MAWM4C,EAAkB,SACpBC,GAIA,IAAAC,EAAA,IAHAC,EAAAC,UAAA5D,OAAA,QAAAb,IAAAyE,UAAA,IAAAA,UAAA,GACAC,EAA+DD,UAAA5D,OAAA,EAAA4D,UAAA,QAAAzE,EAC/D2E,EAA2BF,UAAA5D,OAAA,EAAA4D,UAAA,QAAAzE,EAE3B,OAAKwE,EAIDF,EAASM,gBACTF,MAAAA,GAAoD,QAAzBH,EAA3BG,EAA6BG,+BAAuB,IAAAN,OAAA,EAApDA,EAAsDO,MAAKC,GAAgBA,IAAiBT,EAASM,gBAJ9FN,EAASM,eAAiBD,GAyBlClI,eAAeuI,EAClBtI,EACAuI,GAAmB,IAAAC,EAGnB,IAAKxI,EACD,MAAM,IAAIW,MAAM,2EAEpB,MAAM8H,EAA4B,GAC5BC,EAAyB,GAE/B,IAAIC,EAAwD,GAE5D,IAAIX,EAEJ,MACMY,SADkBC,EAAAA,EAAAA,cAAaN,IACdK,KACjBE,QAA6BC,EAAAA,EAAAA,IAA6B,CAAEnD,cAAe2C,IAC3ES,QAAiBC,EAAAA,EAAAA,6BAA4B,IAAIC,EAAAA,wBAA2BX,GAQlF,MAAMY,QAHNpJ,eAA+BE,GAC3B,OAAOmJ,EAAAA,EAAAA,uBAAsB,IAAIC,EAAAA,kBAAqBpJ,GAE/BqJ,CAAgBf,GACrCgB,EAAoCJ,MAAAA,GAAuE,QAA3DX,EAAZW,EAAcf,MAAKoB,GAfvB,oEAe+BA,EAAKjH,cAAuC,IAAAiG,OAAA,EAAvEA,EAAyEiB,UAC/GF,IACAvB,QAAoC0B,EAAAA,EAAAA,4CAA2C,CAAE9D,cAAe2C,KAGpG,MAAMoB,EAAyBb,EAAqBa,uBAC9CC,EAAwBd,EAAqBc,sBACnD,IAAKhB,IAASE,IAAyBE,GAAgC,IAApBA,EAAS7E,OAExD,OADAoE,EAAIsB,MAAM,2GAC6B,GAG3C,GAAIjB,GAAQA,EAAKkB,IAAMlB,EAAKmB,WAAanB,EAAKmB,UAAU5F,OAAS,GAAK2E,EAClE,IAAK,MAAMlB,KAAYgB,EAAKmB,UAEpBnC,EAASM,cACiB,KAA1BN,EAASM,cACTP,EAAgBC,EAAU2B,EAAmCvB,EAA6B2B,GAE1FjB,EAAWsB,KAAKpC,GACTA,EAASM,eAAiB0B,GACjCnB,EAAcuB,KAAKpC,GAK/B,GAAIa,GAAiBA,EAActE,OAAS,EAAG,CAC3C,MAAM8F,EAA+B,GAErC,IAAIC,EAAazB,EAAc0B,KAAIC,GAAKA,EAAEC,YAC1CH,EAAa5C,EAAO4C,GAEpBA,SA5ERnK,eAAiCuK,EAAkBtK,EAA8CuI,GAAmB,IAAAgC,EAahH,OAZ2B9E,EAAAA,gBAAgBC,kBACjCC,EAAAA,EAAAA,eACF,CACIC,cAAe2C,EACf1C,oBAAqBC,EAAAA,yBAAyBC,qCAAqCwC,IAEvFA,EAAIjJ,eAAeyF,YAAYiB,UAC/BsE,EACA,KACwC,QADpCC,EACJhC,EAAIjJ,eAAeyF,YAAYI,iBAAS,IAAAoF,EAAAA,EAAI,IAiEhBC,CAAkBN,EAAYlK,EAAOuI,IACtC4B,KAAIM,GAC5BA,EAAGC,iBAAmBD,EAAGC,kBAAoBD,EAAGxD,UAC/CgD,EAAiBD,KAAK,CAACS,EAAGC,gBAAiBD,EAAGxD,WACvCwD,EAAGC,iBAEHD,EAAGxD,WAKlB,MACI3H,gBACIa,KACId,QAAQ,2BAAEsL,EAA0B,YAAEC,EAAW,aAAEC,MAG3DtC,EAEJ,IAAIuC,EAAkC,GAClCC,EAAkC,GAClCC,EAAiC,GACjCC,EAA6C,GAEjD,GAAIf,EAAW/F,OAAS,EAAG,CAEvB,MAAM+G,QAAyBC,EAAoB5C,EAAK2B,EAAYD,GACpEa,EAAwBI,EAAiBJ,sBACzCC,EAAwBG,EAAiBE,eACzCJ,EAAuBE,EAAiBF,qBACxCC,EAAsBC,EAAiBG,aAG3C,MAAMC,QAAqCC,EAAiChD,EAAKyC,EAAsBD,GAGnGO,GACAA,EAA6BE,yCAC7BF,EAA6BE,wCAAwCrH,OAAS,IAE9EwE,GAAwB8C,EAAAA,EAAAA,IACpBlD,EACA+C,EAA6BE,6CAC7BlI,EACA2H,IAKRH,EAAsBX,KAAInF,IAEtB2D,EAAsBqB,KAAK,CACvB0B,oBAAoB,EACpBC,yBAA0B,CAAEtB,UAAWrF,EAAW4G,kBAAmBjB,GACrEkB,eAAgBjB,EAChBkB,gBAAiBjB,EACjBkB,iBAAkBjD,EAAqBkD,oBAMnD,MAAMC,QAAiCC,EAA0B3D,EAAKI,EAAuBD,GAE7F,OAAIuD,GAA4BA,EAAyB9H,OAAS,EACvD8H,GAGX1D,EAAIsB,MAAM,+EAC6B,IAM3C,MAsCMqC,EAA4BnM,MAC9BwI,EACAI,EACAD,KAEA,GAAIA,GAAcA,EAAWvE,OAAS,EAAG,CACrC,IAAK,MAAMgI,KAAazD,EAAY,CAChC,MAAM0D,EAAqC,CACvC/B,UAAW8B,EAAU9B,UACrB0B,iBAAkBI,EAAUE,aAG5B9D,EAAIjJ,eAAegN,SAAW/D,EAAIjJ,eAAegN,QAAQC,2BACzDH,EAAiBI,WAAajE,EAAIjJ,eAAegN,QAAQC,0BAE7D,MAAME,QAAiCC,EAAAA,EAAAA,+CACnC,CAAE9G,cAAe2C,EAAKoE,YAAa,MAAO9G,oBAAqB,IAC/D,CAACuG,IAEL,GACIK,GACAA,EAAyBjB,yCACzBiB,EAAyBjB,wCAAwCrH,OAAS,EAC5E,CACE,MAAMyI,GAA0BnB,EAAAA,EAAAA,IAC5BlD,EACAkE,GAA4BA,EAAyBjB,yCAEzD,GAAIoB,GAA2BA,EAAwBzI,OACnD,IAAK,MAAMqF,KAAQoD,EACfjE,EAAsBqB,KAAKR,IAK3C,OAAOb,EAEX,OAAOA,GAILwC,EAAsBpL,MACxBwI,EACA2B,EACAD,KAOA,MAAMa,EAAkC,GAClCM,EAA2B,GAC3BJ,EAAiC,GAEjCpF,EAAgB2C,GAElBjJ,gBACIyF,aAAa,UAAEiB,EAAS,UAAEb,GAC1BhF,KACId,QAAQ,yBAAEwN,EAAwB,8BAAEC,MAG5CvE,EACEwE,EAA6C,GACnDA,EAAoBC,QAAU,CAAEC,UAAWjH,EAAWkH,UAAW/H,GACjE4H,EAAoBI,IAAMjD,EAC1B6C,EAAoBK,mBAAoB,EAExC,MAAM/B,QAAqBgC,EAAAA,EAAAA,uBAAsB,CAAEzH,cAAAA,EAAeC,oBAAqB,IAAMkH,GAgD7F,OA/CA1B,EAAalB,KAAImD,IACb,IAAI,SAAErG,EAAQ,gBAAEsG,GAAoBD,EACpC,GAAIrD,EACA,IAAI,MAAMuD,KAAMvD,EACRuD,EAAG,KAAOvG,IACVA,EAAWuG,EAAG,GACdF,EAAQrG,SAAWuG,EAAG,IAIlC,MAAMC,EAAaF,EACbG,EACFD,GACAA,EAAWrF,MAAKuF,GAEa,yBADHA,EAAUpL,MAAQoL,EAAUpL,KAAKyB,OAAO4J,iBAOtE,GAHIF,GACAA,EAAyB/G,WACmC,QAA5D+G,EAAyB/G,UAAU3C,OAAO4J,cAE1C9C,EAAsBd,KAAK/C,OACxB,KAAA4G,EACH,MAAMC,EAAgBjB,EAChBA,EACKzJ,WACAwK,cACA5J,OACL,kBACA+J,EAAqBjB,EACrBA,EACK1J,WACAwK,cACA5J,OACL,SAEAgK,EAA2BP,GAAcA,EAAWrF,MAAKuF,IAAS,IAAAM,EAAA,OAAIN,MAAAA,GAAe,QAANM,EAATN,EAAWpL,YAAI,IAAA0L,OAAA,EAAfA,EAAiBL,iBAAkBE,KACpFE,IAA8D,QAAlCH,EAAAG,EAAyBrH,iBAAS,IAAAkH,OAAA,EAAlCA,EAAoCD,iBAAkBG,EAEzG3C,EAAepB,KAAK/C,GAEpB+D,EAAqBhB,KAAK/C,OAK/B,CACH6D,sBAAuBA,EACvBM,eAAgBA,EAChBJ,qBAAsBA,EACtBK,aAAcA,IAOhBE,EAAmCxL,MACrCwI,EACAyC,EACAD,KAEA,IACI,IAAIO,EAAqE,CACrEE,wCAAyC,GACzC0C,oBAAqB,IAGzB,GAAIlD,GAAwBA,EAAqB7G,QAAU6G,EAAqB7G,OAAS,EAAG,CACxF,MAAMgK,EAAoB7G,EAAO0D,GAC3BoD,QAAkCC,EAAAA,EAAAA,+BACpC,CAAEzI,cAAe2C,EAAKoE,YAAa,OACnC,CAAE2B,WAAYH,EAAmBI,sBAAsB,IAIvDH,EAA0B5C,yCAC1B4C,EAA0B5C,wCAAwCrH,OAAS,IAE3EmH,EAA+B8C,GAGvC,GAAIrD,GAAyBA,EAAsB5G,QAAU4G,EAAsB5G,OAAS,EAAG,CAE3F,MAAMgK,EAAoB7G,EAAOyD,GAC3ByD,QAAmCH,EAAAA,EAAAA,+BACrC,CAAEzI,cAAe2C,EAAKoE,YAAa,OACnC,CAAE2B,WAAYH,EAAmBI,sBAAsB,EAAOE,iCAAiC,IAI/FD,EAA2BhD,yCAC3BgD,EAA2BhD,wCAAwCrH,OAAS,GAG5EgK,EAAkBhE,KAAIuE,IAAe,IAAAC,EAEjC,MAAMC,EAA0BJ,EAA2BhD,wCA9M1CqD,EACjCtG,EACAiD,EACAxG,KAGA,MACI1F,gBACIa,KACId,QAAQ,2BAAEyP,MAGlBvG,EAEJ,IAAIwG,EAAsC,EAC1C,MAAMC,EAA0CF,EAmBhD,OAhBAtD,EAAwCyD,QAAOC,GAGvCF,GACAA,EAAkB5G,MAAK+G,GACZD,EAAanD,kBAAoBmD,EAAanD,iBAAiB6B,gBAAkBuB,EAAMvB,iBAGzEsB,GAAgBA,EAAa7E,YAAcrF,IACzEmF,KAAI+E,IACCA,EAAaE,oBACbL,GAAuCG,EAAaE,sBAKrDL,GA6KeF,CACItG,EACAiG,EAA2BhD,wCAC3BkD,GAEJ,EAGAW,EAA+BC,EAAqC/G,EAAKmG,EAAcE,GAGzB,QAApED,EAAArD,EAA6BE,+CAAuC,IAAAmD,GAApEA,EAAsE3E,KAAKqF,MAKvF,OAAO/D,EACT,MAAOiE,GACLhH,EAAIiH,UAAU3F,MAAM0F,GAExB,MAAO,IAMLD,EAAuCA,CACzC/G,EACAvD,EACAyK,KAEA,MACInQ,gBACIa,KACId,QAAQ,YAAEuL,EAAW,aAAEC,EAAY,eAAE6E,EAAc,gBAAEC,MAG7DpH,EAEJ,MAAO,CACHwD,iBAAkB,OAClB1B,UAAWrF,EACX4K,kBAAmB,EACnBC,eAAgBJ,EAChBK,kCAAmCL,EAAiB,EAAI5E,EAAe8E,EACvEI,iCAAkCN,EAAiB,EAAI7E,EAAc8E,EACrEN,kBAAmBK,EACnBO,qCAAsCP,EAAiB,EAAI5E,EAAe8E,EAC1EM,oCAAqCR,EAAiB,EAAI7E,EAAc8E,IAIhF,GAAe9P,EAAAA,EAAAA,IAA2B,CACtCC,GAAI,yEACJC,OAAiDwI,EACjDtI,MAtbiBS,GACV,IAAIiH,EAAsCjH,EAAUnB,eAAeyF,sSCtCxE,MAAOmL,EAWT9Q,YAAmBa,EAA0BkQ,EAA4BC,GAAiB,IAAAC,EAanF,KAAA7Q,YAAc,KACjB8Q,EAAAA,EAAAA,kBACI5Q,KAAK6Q,gBAAgBxL,YACrB,CAAEyL,IAAK,MAAOjJ,MAAO7H,KAAK0Q,UAC1B,CAAEI,IAAK,YAAajJ,MAAO7H,KAAKyF,YAOjC,KAAA5F,mBAAqB,IAAeG,KAAK+Q,mBAAqB,oBAAsB,WAMpF,KAAA9Q,cAAgB,IAAiB,cA7BpCD,KAAK6Q,gBAAkBtQ,EACvBP,KAAK+Q,mBAAqBN,EAC1BzQ,KAAK0Q,SAAWA,GAAY,IAE5B1Q,KAAKsG,UAAY/F,MAAAA,GAAoB,QAAboQ,EAAPpQ,EAAS8E,mBAAW,IAAAsL,GAApBA,EAAsBrK,UAAY0K,OAAOzQ,EAAQ8E,YAAYiB,WAAa,EAC3FtG,KAAKyF,WAAYC,EAAAA,EAAAA,IAAanF,IA2C/BF,eAAe4Q,EAAkB3Q,EAAwBuI,GAC5D,aAAeqI,EAAAA,sBAAAA,mBACX,CACIhL,cAAe2C,GAEnBvI,EAAMgG,UACNhG,EAAMmF,YAO6BvF,EAAAA,EAAAA,IAA2B,CAClEC,GAAI,2DACJC,OAAQ6Q,EACR3Q,MA3BkCS,IAAiE,IAAAoQ,EACnG,MAAMC,GAA2B,QAAhBD,EAAApQ,EAAUpB,cAAM,IAAAwR,OAAA,EAAhBA,EAAkBE,gBAAiBL,OAAOM,SAASvQ,EAAUpB,OAAO0R,cAAe,IACpG,OAAO,IAAIb,EAAgBzP,EAAUnB,gBAAgB,EAAOwR,2kBC/C1D,MAAOZ,EAiBT9Q,YAAmBa,EAA0BkQ,EAA4BC,EAAmBa,GAWrF,KAAAzR,YAAc,KACjB8Q,EAAAA,EAAAA,kBACI5Q,KAAKqF,YACL,CAAEyL,IAAK,WAAYjJ,MAAO7H,KAAKwR,UAC/B,CAAEV,IAAK,sBAAuBjJ,MAAO7H,KAAKuR,qBAC1C,CAAET,IAAK,MAAOjJ,MAAO7H,KAAK0Q,UAC1B,CAAEI,IAAK,YAAajJ,MAAO7H,KAAKyF,WAChC,CAAEqL,IAAK,SAAUjJ,MAAO7H,KAAKyC,SAG9B,KAAA5C,mBAAqB,IAAOG,KAAK+Q,mBAAqB,oBAAsB,WAI5E,KAAAU,UAAY,IAAczR,KAAKyC,QAAU,GAEzC,KAAAxC,cAAgB,IAAiB,OA1BpCD,KAAK+Q,mBAAqBN,EAC1BzQ,KAAKuR,oBAAsBA,EAC3BvR,KAAK0Q,SAAWA,GAAY,IAC5B1Q,KAAKsG,UAAY/F,GAAWA,EAAQ8E,aAAe9E,EAAQ8E,YAAYiB,WAAa/F,EAAQ8E,YAAYiB,UAAY,EACpHtG,KAAKwR,SAAYjR,GAAWA,EAAQiR,UAAa,GACjDxR,KAAKqF,YAAc9E,EAAQ8E,YAC3BrF,KAAKyC,OAASlC,EAAQkC,QAAU,GAChCzC,KAAKyF,WAAYC,EAAAA,EAAAA,IAAanF,IAsBtC,MAAMiC,EAAkBA,CAACC,EAAiBiP,KACtC,IAAIC,EAKJ,OAJIlP,GAAUiP,GAAoBA,EAAiBjN,OAAS,IACxDkN,EAAkBD,EAAiBhJ,MAAKoB,GAAQA,EAAK8H,SAAU1D,gBAAkBzL,EAAOyL,iBAGrFyD,GAAmBA,EAAgBE,MAcjCC,EAAyBA,CAClCC,EACAlJ,EACApG,EACA8O,KACqB,IAAAS,EACrB,IAAKD,GAAwC,IAAxBA,EAAatN,OAC9B,MAAO,GAGX,MAAMwN,EAA4B,GAElC,IAAK,MAAMC,KAAYH,EAAc,CACjC,MAAMxP,EAAYC,EAAgBC,EAAQyP,EAASxP,kBAC7CyP,EAAiB9P,EAAA,GAA2B6P,GAClDC,EAAkBvP,gBAAkBsP,EAASrP,KAC7CsP,EAAkBtP,KAAON,GAAa4P,EAAkBvP,gBACxDqP,EAAYC,EAAS3K,UAAY4K,EAGrC,IAAIC,EAEJ,IAAK,MAAMF,KAAYG,OAAOC,OAAOL,GAAc,CAC/C,MAAMM,EAAWL,EAASM,eAE1B,GADAN,EAAS9O,KAAMN,EAAAA,EAAAA,gBAAeoP,EAAUrJ,EAAKoJ,GAC5B,IAAbM,EAAgB,CAChBH,EAAeF,EACf,SAGJ,MAAMO,EAASF,GAAYN,EAAYM,GACnCE,IACAA,EAAOC,SAAWD,EAAOC,UAAY,GACrCD,EAAOC,SAASpI,KAAK4H,IAI7B,IAAKE,EACD,MAAO,GAGX,GAAIb,EAAqB,CACrB,MAAMY,EAAyC,GAE/C,OADAA,EAAkB7H,KAAK8H,GAChBD,EAGX,OAA4B,QAA5BH,EAAOI,EAAaM,gBAAQ,IAAAV,EAAAA,EAAI,IAOvBW,EAAkC5R,IAC3C,MAAMqQ,EAAWrQ,EAAUpB,QAAUoB,EAAUpB,OAAO0R,eAAiBL,OAAOM,SAASvQ,EAAUpB,OAAO0R,cAAe,IACvH,OAAO,IAAIb,EAAgBzP,EAAUnB,gBAAgB,EAAMwR,IAQxD/Q,eAAeuS,EAA2BtS,EAAwBuI,GACrE,MAAMgK,QAAmB5B,EAAkB,IAAI6B,EAAmBjK,EAAIjJ,gBAAgB,EAAOU,EAAMoQ,UAAW7H,GAE9G,OADyBiJ,EAAuBe,EAAYhK,EAAKvI,EAAMmR,YAAanR,EAAMiR,qBAIvF,MAAMwB,GAAuC7S,EAAAA,EAAAA,IAA2B,CAC3EC,GAAI,qEACJC,OAAsCwS,EACtCtS,MAAOqS,IAGX,8QClJM,MAAOK,UAAsCxC,EAAAA,gBAG/C9Q,YAAmBa,EAA0BkQ,EAA4BC,EAAmBuC,GACxFC,MAAM3S,EAASkQ,EAAmBC,GAM/B,KAAA7Q,mBAAqB,IAAM,2BAE3B,KAAAC,YAAc,IAAM,GAAGE,KAAKiT,oBAAoBjT,KAAKsG,YAErD,KAAArG,cAAgB,IAAiB,OARpCD,KAAKiT,iBAAmBA,MAAAA,EAAAA,EADQ,GAgBjC,MAAMN,EAAkC5R,IAAiE,IAAAoQ,EAAAgC,EAAAC,EAC5G,MAAMhC,GAA2B,QAAhBD,EAAApQ,EAAUpB,cAAM,IAAAwR,OAAA,EAAhBA,EAAkBE,gBAAiBL,OAAOM,SAASvQ,EAAUpB,OAAO0R,cAAe,IACpG,IAAI4B,EACgD,aAAhDlS,EAAUnB,eAAeyT,UAAUC,SAA0BvS,EAAUnB,eAAeyT,UAAUE,YAAS3P,EAC7GqP,EAAmC,QAAnBE,EAAGF,SAAgB,IAAAE,EAAAA,EAAkC,QAAlCC,EAAIrS,EAAUnB,eAAesD,aAAK,IAAAkQ,OAAA,EAA9BA,EAAgCI,WACvE,MAAMC,EAAyBR,EAAmBjC,OAAOM,SAAS2B,EAAkB,SAAMrP,EAE1F,OAAO,IAAIoP,EAA8BjS,EAAUnB,gBAAgB,EAAMwR,EAAUqC,IASjFC,EAAwBA,CAACb,EAAiCW,KAC5D,IAAK,MAAMtB,KAAYW,EAAY,CAC/B,GAAIX,EAAS3K,WAAaiM,EACtB,MAAO,CAACtB,GAGZ,GAAInM,EAAAA,gBAAgBQ,YAAY2L,EAASQ,UAAW,CAChD,MAAMiB,EAAyBD,EAAsBxB,EAASQ,SAAUc,GACxE,GAAIzN,EAAAA,gBAAgBQ,YAAYoN,GAE5B,OADAA,EAAuBrJ,KAAK4H,GACrByB,GAKnB,OAAO,MASJtT,eAAeuT,EAClBtT,EACAuI,GAAmB,IAAAgL,EAKf,MAAMC,QAAgDlB,EAAAA,EAAAA,4BAA2B,IAAIE,EAAAA,gBAAmBjK,EAAIjJ,gBAAgB,EAAMU,EAAMoQ,UAAW7H,GAGnJ,OAF4G,QAAzFgL,EAAGH,EAAsBI,EAAyCxT,EAAM2S,yBAAiB,IAAAY,EAAAA,EAAI,IACtEE,UAI3C,MAAMC,GAA8C9T,EAAAA,EAAAA,IAA2B,CAClFC,GAAI,2EACJC,OAAQwT,EACRtT,MAAOqS,IAGX,4GC7FM,MAAOsB,EAAbvU,cAGW,KAAAI,YAAc,IAAM,kBACpB,KAAAD,mBAAqB,IAAM,kBAC3B,KAAAI,cAAgB,IAA0B,WAsBrD,QAAeW,EAAAA,GAAoC,CAC/CR,OALJC,eAAsBC,EAAgCuI,GAClD,MAAO,CAAEqL,eAAWtQ,IAKpBzD,GAAI,qBACJG,MAdiB6E,GACV,IAAI8O,iNCZT,MAAOtK,EAAbjK,cACoB,KAAAyU,aAAyB,CACrC,oDACA,kEACA,kEACA,yDAGG,KAAArU,YAAc,IAAM,eACpB,KAAAD,mBAAqB,IAAM,eAC3B,KAAAI,cAAgB,IAAiB,eAOrC,MAAMmU,EAA8BrT,GAChC,IAAI4I,EAQRtJ,eAAeqJ,EAAsBpJ,EAA0BuI,GAElE,aAD2BwL,EAAAA,EAAAA,uBAAsB,CAAEnO,cAAe2C,GAAOvI,EAAM6T,cAS5E,MAAMG,GAAkCpU,EAAAA,EAAAA,IAA2C,CACtFC,GAAI,8DACJC,OAAiCsJ,EACjCpJ,MAAO8T,IAEX,0WClBM,MAAOG,EAeT7U,YACI8U,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,GAWG,KAAAhV,YAAc,IAAM,4CAEpB,KAAAD,mBAAqB,IAAM,uCAE3B,KAAAI,cAAgB,IAAiB,OAbpCD,KAAKsF,UAAYkP,EACjBxU,KAAK+U,SAAWN,EAChBzU,KAAKgV,UAAYN,EACjB1U,KAAKiV,OAASN,EACd3U,KAAKkV,kBAAoBN,EACzB5U,KAAKmV,eAAiBN,EACtB7U,KAAKoV,iBAAmBN,GAezB,MAAMO,EACTtU,GAEO,IAAIwT,EAQRlU,eAAeuJ,EAAgBrJ,GAClC,OAAOmJ,EAAAA,EAAAA,uBAAsB,IAAIC,EAAAA,kBAAqBpJ,GASnDF,eAAeiV,EAClBhV,EACAuI,GAAmB,IAAAC,EAGnB,IAAKxI,EAAMgF,UACP,OAGJ,MAAOhF,EAAM2U,QAA2B,IAAjB3U,EAAM2U,SAAkB3U,EAAMyU,UAAazU,EAAM0U,WAAe1U,EAAM6U,gBAEzF,MAAO,GAGX,MAAMI,EAAyB,CAC3BC,SAAUlV,EAAMyU,SAChBU,UAAWnV,EAAM0U,UACjBU,OAAQpV,EAAM2U,OACdC,kBAAmB5U,EAAM4U,mBAAqB,GAG5CzL,QAAqBG,EAAgBf,GACrC8M,EAAoClM,MAAAA,GAEzC,QAFqDX,EAAZW,EAAcf,MACpDoB,GAAsB,oEAAdA,EAAKjH,cAChB,IAAAiG,OAAA,EAFyCA,EAEvCiB,UACG6L,GAAiBC,EAAAA,EAAAA,2CAA0ChN,EAAK,CAACvI,EAAMgF,YAAY,GAAO,EAAMiQ,EAAY/M,EAAAA,EAAasN,QAC/H,OAAOnH,EAAAA,EAAAA,+BAA8B,CAAEzI,cAAe2C,GAAO+M,GACxDG,MAAK1V,MAAAA,IAEF,MAAM2V,GAA8BjK,EAAAA,EAAAA,gCAChClD,EACAoN,EAA4BnK,yCAEhC,OAAOoK,EAAAA,EAAAA,IAA+B,CAAEhQ,cAAe2C,GAAO0M,EAAYY,EAAAA,uBAAuBC,MAC5FL,MAAK1V,MAAAA,IAAoC,IAAAgW,EAEtC,MAAMC,EAAW,IAAIC,IACrBC,EAAOC,SAAQhH,IACPA,EAAMiH,qBACNJ,EAAS7S,IAAIgM,EAAMiH,oBAAqBjH,MAIhD,IAAIkH,EAA+D,GAGnE,GAAIhB,EAAmC,CACnC,MAAMiB,EAAiBJ,EAAO/L,KAAIgF,GAASA,EAAMlC,YACjDoJ,QA2GxBtW,eACIwW,EACAhO,GAEA,GAAkC,KAA9BgO,MAAAA,OAAiB,EAAjBA,EAAmBpS,cAAsCb,IAAtBiT,EACnC,OAGJ,MAAMC,EAA0B,GAQhC,OAPAD,MAAAA,GAAAA,EAAmBpM,KAAItK,SACRyD,IAAPzD,GACA2W,EAAcxM,KAAKnK,OAKpB4W,EAAAA,EAAAA,IAA+B,CAAE7Q,cAAe2C,GAAOiO,EAAe,GACxEf,MAAMiB,IACH,GAAIA,KAA4BA,aAAkC/V,OAC9D,OAAO+V,KAKdC,OAAOpH,IACJhH,EAAIsB,MACA,8HAEJtB,EAAIsB,MAAM0F,EAAMqH,SAChBrO,EAAIiH,UAAUqH,UAAUtH,GACxBhH,EAAIiH,UAAUsH,MACV,+HAEG,MA5IqCC,CAAgCT,EAAgB/N,GAGpF,MAAMyO,EAAuC,QAAzBjB,EAAG/V,EAAM8U,wBAAgB,IAAAiB,EAAAA,EAAI,GAI3CkB,EAHiBf,EAClBjH,QAAOE,IAAU6H,EAAevV,SAAS0N,EAAMlC,aAC/CiK,MAAK,CAACC,EAAGC,IAAMD,EAAEE,YAAaC,cAAcF,EAAEC,eACJlN,KAAIgF,IAAQ,IAAAoI,EACvD,MAAMC,EAAgD,QAA1BD,EAAGlB,SAAuB,IAAAkB,OAAA,EAAvBA,EAAyBnP,MACpDqP,GAA0BA,EAAuBxK,YAAckC,EAAMlC,YAEzE,OAmCxBlN,eACI2X,EACAhC,EACAM,EACAzN,EACAoP,GAEA,IAAKD,IAAoBA,EAAgBE,cACrC,MAAO,CAAEC,yBAAqBvU,GAGlC,OAAOwU,EAAAA,EAAAA,IAAmB,CAAElS,cAAe2C,GAAOmP,EAAgBE,eAC7DnC,MAAMsC,IACH,MAAMC,EAAyC,GAC3CtC,GAA+BM,GAC/BN,EAA4BS,SAAQ8B,IAK9B,IAAAC,EAHED,EAAQlM,kBACRiK,EAASmC,IAAIF,EAAQlM,mBACrBkM,EAAQlM,mBAAqB2L,EAAgBtB,qBAE7C4B,EAAmBhO,KAAK,CAAE4B,kBAAmD,QAAlCsM,EAAED,EAAQtM,gCAAwB,IAAAuM,OAAA,EAAhCA,EAAkCtM,uBAK3F,MAAMsD,EAAoC,CACtCkJ,gBAAiBV,EACjBW,mBAAoBL,GAGxB,OAAID,GAAWA,aAAiBpX,MASzB,CACHkX,oBAAqB3I,EACrBoJ,4BAA6B5C,EAC7B6C,2BAA4BZ,GAXrB,CACHE,oBAAqB3I,EACrBsJ,WAAYT,EACZO,4BAA6B5C,EAC7B6C,2BAA4BZ,MAUvChB,OAAOpH,IACJhH,EAAIsB,MAAM,2EACVtB,EAAIsB,MAAM0F,EAAMqH,SAChBrO,EAAIiH,UAAUqH,UAAUtH,GACxBhH,EAAIiH,UAAUsH,MAAM,2EACb,CAAEe,oBAAqB,OAtFXY,CAA0BtJ,EAAOuG,EAA6BM,EAAUzN,EAAKiP,MAGxF,OAAOkB,QAAQC,IAAI1B,MAEtBN,OAAOpH,IACJhH,EAAIsB,MAAM,8EACVtB,EAAIsB,MAAM0F,EAAMqH,SAChBrO,EAAIiH,UAAUD,MAAMA,EAAMqH,SAC1BrO,EAAIiH,UAAUsH,MAAM,8EACb,SAGlBH,OAAOpH,IACJhH,EAAIsB,MACA,8HAEJtB,EAAIsB,MAAM0F,EAAMqH,SAChBrO,EAAIiH,UAAUD,MAAMA,EAAMqH,SAC1BrO,EAAIiH,UAAUsH,MACV,8HAEG,MAkHZ,MAAM8B,GAAkDhZ,EAAAA,EAAAA,IAA2B,CACtFC,GAAI,gFACJC,OAAyDkV,EACzDhV,MAAO+U,IAGX,+MC5RM,MAAO8D,EAKTzZ,YAAY2F,EAAmC+T,GAKxC,KAAAtZ,YAAc,KAAM0F,EAAAA,EAAAA,eAAc,kBAAkBxF,KAAKoZ,oBAAqBpZ,KAAKqF,aAEnF,KAAAxF,mBAAqB,IAAM,iBAE3B,KAAAI,cAAgB,IAAiB,UARpCD,KAAKoZ,kBAAoBA,EACzBpZ,KAAKqF,YAAcA,GAcpB,MAAMgU,EAA6BtY,IACtC,MAAM,eAAEnB,GAAmBmB,EAC3B,IAAKnB,EAAe0Z,KAAKC,gBACrB,MAAM,IAAItY,MAAM,wEAGpB,OAAO,IAAIkY,EAAoBpY,EAAUnB,eAAeyF,YAAatE,EAAUnB,eAAe0Z,KAAKE,wBAQhGnZ,eAAeoZ,EAAiBnZ,EAA4BuI,GAC/D,OAAO6Q,EAAAA,EAAAA,8BAA6B,CAAExT,cAAe2C,EAAK1C,oBAAqB,IAAM7F,EAAM8Y,mBAAqB,MAC3GrD,MAAK4D,IACF,IAAKA,GAA0B,IAAjBA,EAAMlV,OAChB,MAAoB,GAGxB,MAAMmV,EAAWD,EAAMjR,MAAKmR,GAAqC,IAA7BA,EAAKC,sBACzC,IAAKF,EAAU,MAAM,IAAI3Y,MAAM,qCAC/B,MAAM8Y,EAAYH,EAGlB,OAAOI,EAAAA,EAAAA,qBAAoB,CAAE9T,cAAe2C,GAAOkR,EAAUE,YACxDlE,MAAK8D,IACFA,EAAKK,sBAAwBH,EAAUG,sBACvCL,EAAKM,2BAA6BJ,EAAUI,2BACrCN,KAGV5C,OAAMpH,IAGH,MAFAhH,EAAIiH,UAAUqH,UAAUtH,GACxBhH,EAAIiH,UAAUsH,MAAM,8BACd,IAAInW,MAAM,oCAG3BgW,OAAMpH,IAGH,MAFAhH,EAAIiH,UAAUqH,UAAUtH,EAAMqH,SAC9BrO,EAAIiH,UAAUsH,MAAM,wCACd,IAAInW,MAAM,2CAQrB,MAAMmZ,GAA6Bla,EAAAA,EAAAA,IAAwC,CAC9EC,GAAI,6DACJC,OAA8BqZ,EAC9BnZ,MAAqD+Y,IAGzD,sUCxEM,MAAOgB,EAIT3a,YAAY4F,EAA4BgB,GAKjC,KAAAxG,YAAc,IAAM,0CACpB,KAAAD,mBAAqB,IAAM,wBAC3B,KAAAI,cAAgB,IAAiB,OANpCD,KAAKsF,UAAiC,iBAAdA,GAA0BA,EAAYA,EAC9DtF,KAAKsG,UAAYA,GAYlB,MAAMgU,EACTvZ,IAEA,MAAMuE,GAAYqC,EAAAA,EAAAA,qCAAoC5G,GAEtD,GAAIuE,EACA,OAAO,IAAI+U,GAA8C/U,GAAYvE,EAAUnB,eAAeyF,YAAYiB,WAE1G,MAAM,IAAIrF,MAAM,gHAQjBZ,eAAeka,EAClBja,EACAuI,GAEA,MAAM2R,EAAuB,IAAIC,EAAAA,qBAAqBna,EAAMgF,UAAWhF,EAAMgG,WAK7E,OAAOoU,EAAAA,EAAAA,oBAAmBF,EAAsB3R,GAC3CkN,MAAK1V,MAAAA,IACF,GACIsa,GALa,IAQbA,EAAcC,cAGd,IAGI,MACIhb,gBACIa,KACId,QAAQ,2BAAEsL,EAA0B,yBAAEkC,EAAwB,8BAAEC,MAGxEvE,EAEJ,IAAImN,EAGJ,MAAMlP,QAA0BC,EAAAA,EAAAA,yBAC5B,CAAEb,cAAe2C,GACjBvI,EAAMgF,UACNhF,EAAMgG,UACNuC,EAAIjJ,eAAeyF,YAAYI,WAE7BoV,EAAwB/T,EAAkB4B,MAAKuF,GAExB,yBADHA,EAAUpL,MAAQoL,EAAUpL,KAAKyB,OAAO4J,iBAK5D4M,EAAYhU,EAAkB4B,MAAKuF,GAEZ,aADHA,EAAUpL,MAAQoL,EAAUpL,KAAKyB,OAAO4J,gBACA,QAAxBD,EAAUhH,YAIpD,GACI4T,GACAA,EAAsB5T,WAC4B,QAAlD4T,EAAsB5T,UAAUiH,cAClC,CACE,MAAM6M,EAA6D,GAUnE,OARAA,EAA2BzQ,KAAK,CAC5B0B,oBAAoB,EACpBC,yBAA0B,CACtBC,kBAAmBjB,EACnBN,UAAWgQ,EAAcpT,YAI1BwT,EACJ,KAAA5M,EACH,MAAMC,EAAgBjB,EAChBA,EACKzJ,WACAwK,cACA5J,OACL,kBACA+J,EAAqBjB,EACrBA,EACK1J,WACAwK,cACA5J,OACL,SAEAgK,EACFxH,GACAA,EAAkB4B,MAAKuF,IAAY,IAAAM,EAC/B,OAAON,MAAAA,GAAe,QAANM,EAATN,EAAWpL,YAAI,IAAA0L,OAAA,EAAfA,EAAiBL,iBAAkBE,KAI5C4M,KADF1M,IAA8D,QAAlCH,EAAAG,EAAyBrH,iBAAS,IAAAkH,OAAA,EAAlCA,EAAoCD,iBAAkBG,GAGtF,OAAOM,EAAAA,EAAAA,+BACH,CAAEzI,cAAe2C,GACjB,CACI+F,WAAY,CAAC+L,EAAcpT,UAC3BsH,sBAAuBmM,EACvBjM,gCAAiCiM,IAEvCjF,MAAK1V,MAAAA,IACH,GACI4a,GACAA,EAASnP,yCACTmP,EAASnP,wCAAwCrH,OAEjD,GAAIuW,EAAiB,CAEjB,MAAME,EAA0BC,EAC5BtS,EACAoS,EAASnP,yCAGbkK,GAA8BjK,EAAAA,EAAAA,IAA+BlD,EAAKqS,QAElElF,GAA8BjK,EAAAA,EAAAA,IAC1BlD,EACAoS,EAASnP,wCACTgP,EAAY,iBAAmB,IAK3C,OAAO9E,MAGjB,MAAOnG,GAIL,MAHAhH,EAAIsB,MAAO0F,EAAgBqH,SAC3BrO,EAAIiH,UAAUqH,UAAUtH,GACxBhH,EAAIiH,UAAUsH,MAAM,yDACd,IAAInW,MAAM,yDAGxB,MAAO,MAEVgW,OAAOpH,IAEJhH,EAAIiH,UAAUqH,UAAUtH,GACxBhH,EAAIiH,UAAUsH,MAAM,+DAQ1B,SAAUgE,EACZC,GAEA,MAAMC,EAA+C,GACrD,GAAID,GAA8BA,EAA2B5W,OAAS,EAClE,IAAK,MAAMmJ,KAAWyN,OACazX,IAA3BgK,EAAQuC,qBAAsDvM,IAAtBgK,EAAQjD,WAChD2Q,EAAiBhR,KAAK,CAAEK,UAAWiD,EAAQjD,UAAWuB,kBAAmB0B,EAAQuC,iBAI7F,OAAOmL,EAMX,MAAMH,EAA6BA,CAC/BtS,EACAiD,KAGA,MACIlM,gBACIa,KACId,QAAQ,2BAAEyP,MAGlBvG,EAEJ,IAAI0S,EAA0B,EAC9B,MAAMjM,EAA0CF,EAgBhD,OAdAtD,EAAwCyD,QAAOC,GAGvCF,GACAA,EAAkB5G,MAAK+G,GACZD,EAAanD,kBAAoBmD,EAAanD,iBAAiB6B,gBAAkBuB,EAAMvB,kBAGvGzD,KAAI+E,IACCA,EAAaE,oBACb6L,GAA2B/L,EAAaE,sBAIzC8L,EAA4C3S,EAAKiD,EAAyCyP,IAO/FC,EAA8CA,CAChD3S,EACAiD,EACAyP,KAGA,MACI3b,gBACIa,KACId,QAAQ,YAAEuL,EAAW,aAAEC,EAAY,eAAE6E,EAAc,gBAAEC,MAG7DpH,EAEE4S,EAAsB3P,EAAwC,GAEpE,MAAO,CACH,CACInB,UAAW8Q,EAAoB9Q,UAC/BmC,WAAY2O,EAAoB3O,WAChCoD,kBAAmB,EACnBC,eAAgBoL,EAChBnL,kCAAmCmL,EAA0B,EAAIpQ,EAAe6E,EAChFK,iCAAkCkL,EAA0B,EAAIrQ,EAAc+E,EAC9EP,kBAAmB6L,EACnBjL,qCAAsCiL,EAA0B,EAAIpQ,EAAe8E,EACnFM,oCAAqCgL,EAA0B,EAAIrQ,EAAc8E,KAQ7F,GAAe9P,EAAAA,EAAAA,IAA2B,CACtCC,GAAI,4FACJC,OAAwDma,EACxDja,MAAOga,+LC9QL,MAAO9Q,EAAb9J,cACW,KAAAI,YAAc,IAAM,qBACpB,KAAAD,mBAAqB,IAAM,qBAC3B,KAAAI,cAAgB,IAAiB,QAYrCI,eAAekJ,EAA4BjJ,EAAgCuI,GAE9E,IAAKvI,EACD,MAAM,IAAIW,MAAM,mEAGpB,MAAMya,QAAkBvS,EAAAA,EAAAA,cAAaN,GAC/BK,EAAOwS,EAAUxS,KAIvB,aA6KJ7I,eAAmDwI,GAAmB,IAAAgC,EAClE,MAAM8Q,EAAgE,QAAzB9Q,EAAGhC,EAAIjJ,eAAea,WAAG,IAAAoK,GAAU,QAAVA,EAAtBA,EAAwB+Q,gBAAQ,IAAA/Q,OAAA,EAAhCA,EAAkCgR,iCAClF,GAAgD,SAA5CF,EACA,OAAO3C,QAAQ8C,SAAQ,GAG3B,MAAMC,QAAsBnS,EAAAA,EAAAA,kBAAgBwK,EAAAA,EAAAA,4BAA2BvL,GAAMA,GAC7E,IAAImT,GAAqC,EACO,IAAAC,EAA5ClW,EAAAA,gBAAgBQ,YAAYwV,KAC5BC,GAGK,QAFDC,EAAAF,EAAcrT,MACTe,GAAqD,oEAAtBA,EAAa5G,cAChD,IAAAoZ,OAAA,EAFDA,EAEGlS,aAAa,GAGxB,IAAKiS,EACD,OAAO,EAGX,GAAgD,QAA5CL,EACA,OAAO3C,QAAQ8C,SAAQ,GAG3B,OAAOI,EAAAA,EAAAA,aAAY,IAAIC,EAAAA,iBAAiBtT,EAAIjJ,eAAeyF,aAAcwD,GACpEkN,MAAKqG,KAEIA,IAC4C,QAA5CT,GAAqDS,EAAaC,OACnB,QAA5CV,IAAsDS,EAAaC,SAG/EpF,OAAOpH,IACJhH,EAAIiH,UAAUwM,QAAQzM,EAAMqH,SAC5BrO,EAAIiH,UAAUsH,MAAM,gCACb,KAjNoCmF,CAAoC1T,GA6I3FxI,eAAwE6I,EAAYL,GAAmB,IAAA2T,EACnG,MAAMC,EAAiD,IAAIlG,IAC3D,IAAImG,EAAkC,GAMtC,OALc,QAAdF,EAAAtT,EAAKmB,iBAAS,IAAAmS,GAAdA,EAAgB/F,SAAQvO,IAAQ,IAAAyU,EAAA,OAC5BF,EAAwBhE,IAAIvQ,EAASyE,aACmB,QADNgQ,EAC5CF,EAAwBG,IAAI1U,EAASyE,oBAAa,IAAAgQ,OAAA,EAAlDA,EAAoDrS,KAAKpC,EAASyC,WAClE8R,EAAwBhZ,IAAIyE,EAASyE,YAAc,CAACzE,EAASyC,eAEhEqO,QAAQC,IACX,IAAIwD,GAAyBhS,KAAIoS,IAAwC,IAAtCC,EAAkBC,GAAgBF,EACjE,OAAO/R,EAAAA,EAAAA,mBACaiS,EACXtS,KAAInF,IACD,GAAIA,EACA,OAAO,IAAI0X,EAAAA,aAAa1X,EAAWuD,EAAIjJ,eAAeyF,iBAAazB,EAAWkZ,MAIrFvN,OAAO0N,SACZpU,GACFkN,MAAMzM,IACAA,IACAoT,EAAiBpT,EAAS4T,QAAO,CAACC,EAAOvP,KACjCA,GACAuP,EAAM7S,KAAKsD,GAERuP,IACRT,WAIjB3G,MAAK,IAAM2G,IAzKFU,CAAyDlU,EAAML,IAIrE6S,EAAU2B,gBAAkBnU,GAAQA,EAAKmB,WAAanB,EAAKmB,UAAU5F,OAAS,GAC/EoE,EAAIsB,MAAM,wCACHW,EAAAA,EAAAA,mBACa5B,EAAKmB,UAAUI,KAAIvC,IAC/B,GAAIA,EAASyC,UACT,OAAO,IAAIqS,EAAAA,aAAa9U,EAASyC,UAAW9B,EAAIjJ,eAAeyF,gBAGpEkK,OAAO0N,SACVpU,GAECkN,MAAMzM,IACH,GAAIA,EAAU,CAEV,MAAMgU,EAAwBC,EAAuB1U,EAAKS,GAC1D,OAAIgU,GAGGhU,EAGP,MAAO,MAGd2N,OAAOpH,IAIJ,MAHAhH,EAAIsB,MAAM0F,EAAMnM,YAChBmF,EAAIiH,UAAUD,MAAMA,EAAMqH,SAC1BrO,EAAIiH,UAAUsH,MAAM,8EACd,IAAInW,MAAM,mFAI5B4H,EAAIsB,MAAM,wDACc,IAG5B,MAAMoT,EAAyBld,MAAOmd,EAA+BlU,KACjE,MAAMpD,EAAgBsX,GAElB5d,gBACIyF,aAAa,UAAEiB,EAAS,UAAEb,KAE9B+X,EACJ,GAAIlU,EAAU,CACV,MAAM+D,EAA6C,GACnDA,EAAoBC,QAAU,CAAEC,UAAWjH,EAAWkH,UAAW/H,GACjE,MAAM+E,EAAuB,GACvBD,EAA+B,GACrCjB,EAASmB,KAAImD,IACLA,EAAQ5C,iBAAmB4C,EAAQrG,WAAaqG,EAAQ5C,iBACxDT,EAAiBD,KAAK,CAACsD,EAAQ5C,gBAAiB4C,EAAQrG,WACxDiD,EAAWF,KAAKsD,EAAQ5C,kBAExBR,EAAWF,KAAKsD,EAAQrG,aAGhC8F,EAAoBI,IAAMjD,EAC1B6C,EAAoBK,mBAAoB,EACxC,MAAM/B,QAAqBgC,EAAAA,EAAAA,uBAAsB,CAAEzH,cAAAA,EAAeC,oBAAqB,IAAMkH,GAIvFoQ,QAA2BC,EAAAA,EAAAA,GAAsB/R,EAAc6R,EAAc5d,eAAeyF,YAAYsY,SA6D9G,OA5DAhS,EAAalB,KAAImD,IACb,IAAK,MAAME,KAAMvD,EACTuD,EAAG,KAAOF,EAAQrG,WAClBqG,EAAQrG,SAAWuG,EAAG,IAI9B,MACM8P,EAAmC,CAAEC,IAAK,sBAAuBC,MAAO,CAAEC,eADpDN,EAAmB/U,MAAKpD,GAAaA,IAAcsI,EAAQrG,aAGjFwG,EAAaH,EAAQC,gBACrBG,EACFD,GACAA,EAAWrF,MAAKuF,GAEa,yBADHA,EAAUpL,MAAQoL,EAAUpL,KAAKyB,OAAO4J,iBAGhE8P,EACFhQ,GACAA,EAAyB/G,WACmC,QAA5D+G,EAAyB/G,UAAU3C,OAAO4J,cACxC+P,EAA0C,GAChD,GAAID,EAAgB,CAChB,MAAME,EACFnQ,GACAA,EAAWwB,QAAOtB,IACd,MAAMG,EAAgBH,EAAUpL,MAAQoL,EAAUpL,KAAKyB,OAAO4J,cACxDiQ,EAAwBlQ,EAAUhH,UACxC,OACImH,GACA+P,IACmB,eAAlB/P,GAAoD,0BAAlBA,MAG/C,GAAI8P,GAAsBA,EAAmBzZ,OAAS,EAClDyZ,GACIA,EAAmBzT,KAAI2T,IACnB,MAAMC,EAA+C,CAAEC,YAAaF,EAAkBnX,WAChFsX,EAAqC,CAAEV,IAAKO,EAAkBvb,KAAMib,MAAOO,GACjFJ,EAAoB3T,KAAKiU,UAE9B,CACH,MAAMC,EAA+B,CAAEX,IAAK,aAAcC,MAAO,CAAEQ,YAAa,kBAC1EG,EAA0C,CAC5CZ,IAAK,wBACLC,MAAO,CAAEQ,YAAa,kBAE1BL,EAAoB3T,KAAKkU,GACzBP,EAAoB3T,KAAKmU,QAE1B,CACH,MAAMD,EAA+B,CAAEX,IAAK,aAAcC,MAAO,CAAEQ,iBAAa1a,IAC1E6a,EAA0C,CAAEZ,IAAK,wBAAyBC,MAAO,CAAEQ,iBAAa1a,IACtGqa,EAAoB3T,KAAKkU,GACzBP,EAAoB3T,KAAKmU,GAG7BR,EAAoB3T,KAAKsT,GACzBhQ,EAAQY,oBAAsByP,KAEVtS,EAE5B,MAAO,IAGX,GAAezL,EAAAA,EAAAA,IAA2B,CACtCC,GAAI,wEACJC,OAAkCmJ,EAClCjJ,MA5JiBS,GACV,IAAIyI,6ICxBR,MAoBMkV,EAA0BA,CACnC9Q,EACAvI,IAtB4BgC,EAACsX,EAA8BtZ,IACvDsZ,EAEIA,EAASC,WAAW,QACbD,EAIJtZ,EAAYwZ,aAAeC,mBAAmBH,QAGrD,EAaGtX,CAAiBuG,EAAQtG,gBAAiBjC,wkBCT/C,MAAOoV,EAKT/a,YAAY4F,EAAmBgB,EAAmByY,GAM3C,KAAAjf,YAAc,IAAM,kBACpB,KAAAD,mBAAqB,IAAM,gBAC3B,KAAAI,cAAgB,IAAiB,cAPpCD,KAAKsF,UAAYA,EACjBtF,KAAKsG,UAAYA,EACjBtG,KAAK+e,wBAA0BA,GAA2B,IAyHlE,SAAe7e,EAAAA,EAAAA,IAA2B,CACtCC,GAAI,iEACJC,OAhGJC,eAAwCC,EAA6BuI,GACjE,IAAI+E,EAAgC,KAEpC,MAAMqN,QAAiB+D,EAAAA,EAAAA,cAAa,CAAE9Y,cAAe2C,GAAOvI,EAAMgF,UAAWhF,EAAMgG,WAC7E2Y,EAA6Brd,MAAMC,QAAQoZ,GAAYA,EAAS,GAAKA,EAS3E,GAFArN,EAAUqR,GAAW5c,EAAA,GAAS4c,GAE1BrR,EAAS,KAAAsR,EACT,IAAIC,GAA4C,EAehD,GAdIvR,EAAQwR,YACRxR,EAAQwR,WAAW3U,KAAI4U,IAAY,IAAAC,EAC/B,MAAMC,EAAsD,QAAhCD,EAAGhf,EAAMye,+BAAuB,IAAAO,OAAA,EAA7BA,EAA+B5W,MAC1D8W,GAAmBA,EAAgBC,qBAAuBJ,EAAUI,qBAGpEF,EACAF,EAAUK,eAAiBH,EAAuBG,eAElDP,GAAmC,MAK1CA,IAAiE,QAA7BD,EAAA5e,EAAMye,+BAAuB,IAAAG,OAAA,EAA7BA,EAA+Bza,QAAS,EAAG,CAChF,MAAMkb,QAAiBC,EAAAA,EAAAA,mCACnB,CAAE1Z,cAAe2C,EAAK1C,oBAAqB,IAC3C8Y,MAAAA,OAAW,EAAXA,EAAa1X,SACbjH,EAAMgG,UACNhG,EAAMye,yBAA2B,IAGjCY,GAAYA,EAASlb,OAAS,IAC9BmJ,EAAU+R,EAAS,IAW3B,MAAME,QAAyBC,EAAAA,EAAAA,2BAC3B,CAAE5Z,cAAe2C,EAAK1C,oBAAqB,IAC3C8Y,MAAAA,OAAW,EAAXA,EAAa1X,SACbjH,EAAMgG,WAGV,GAAIuZ,GAAoBA,EAAiBpb,OAAS,EAAG,CACjD,MAAMsb,QAA4BC,EAAAA,EAAAA,qCAC9B,CAAE9Z,cAAe2C,EAAK1C,oBAAqB,IAC3C8Y,MAAAA,OAAW,EAAXA,EAAa1X,SACbjH,EAAMgG,UACN,IAGJ,GAAIyZ,EAAoBtb,QAAUsb,EAAoBtb,OAAS,EAAG,KAAAwb,EAC9D,MAAMC,EAAkC,QAAzBD,EAAGF,EAAoB,UAAE,IAAAE,OAAA,EAAtBA,EAAwB1Y,SACpC4Y,QAAsBnB,EAAAA,EAAAA,cAAa,CAAE9Y,cAAe2C,GAAOqX,EAAW5f,EAAMgG,WAI5E8Z,EAH4Bxe,MAAMC,QAAQse,GAAiBA,EAAc,GAAKA,EAIpFC,EAAkBvd,KAAOoc,EAAYpc,KACrCud,EAAkBhZ,YAAc6X,EAAY7X,YAE5CwG,EAAOvL,EAAA,GAAQ+d,IAQvB,MAAMC,EAAc3B,EAAwB9Q,EAAS/E,EAAIjJ,eAAeyF,aAEpEgb,IACAzS,EAAQtG,gBAAkB+Y,GAIlC,OAAOzS,GAAW,MASlBtN,MAhHiBS,IACjB,MAAMuE,GAAYqC,EAAAA,EAAAA,qCAAoC5G,GAEtD,GAAIuE,EACA,OAAO,IAAImV,GAAsBnV,GAAYvE,EAAUnB,eAAeyF,YAAYiB,UAAW,IAE7F,MAAM,IAAIrF,MAAM,uUCpBlB,MAAOqf,EAOT5gB,YAAY6gB,EAAoBC,EAAqBC,EAAkB7L,EAA6BC,GAQ7F,KAAA/U,YAAc,IAAM,iCACpB,KAAAD,mBAAqB,IAAM,iCAC3B,KAAAI,cAAgB,IAAiB,OATpCD,KAAKwV,SAAW+K,EAChBvgB,KAAKyV,UAAY+K,EACjBxgB,KAAK0V,OAAS+K,EACdzgB,KAAKkV,kBAAoBN,EACzB5U,KAAKmV,eAAiBN,GAYvB,MAAM6L,EAAwC3f,GAC1C,IAAIuf,EAMRjgB,eAAeuJ,EAAgBrJ,GAClC,OAAOmJ,EAAAA,EAAAA,uBAAsB,IAAIC,EAAAA,kBAAqBpJ,GAQnDF,eAAesgB,EAClBrgB,EACAuI,GAAmB,IAAAC,EAEnB,UAAsBlF,IAAjBtD,EAAMoV,QAAyBpV,EAAMkV,UAAalV,EAAMmV,WAAenV,EAAM6U,gBAE9E,MAAO,GAGX,MAAMI,EAAyB,CAC3BC,SAAUlV,EAAMkV,SAChBC,UAAWnV,EAAMmV,UACjBC,OAAQpV,EAAMoV,OACdR,kBAAmB5U,EAAM4U,mBAAqB,GAG5CzL,QAAqBG,EAAgBf,GACrC8M,EAAoClM,MAAAA,GAEzC,QAFqDX,EAAZW,EAAcf,MACpDoB,GAAsB,oEAAdA,EAAKjH,cAChB,IAAAiG,OAAA,EAFyCA,EAEvCiB,UAEH,OAAOmM,EAAAA,EAAAA,IAA+B,CAAEhQ,cAAe2C,GAAO0M,GACzDQ,MAAK1V,MAAAA,IAEF,MAAMugB,EAA6BpK,MAAAA,OAAM,EAANA,EAAQgB,MAAK,CAACC,EAAGC,IAAMD,EAAEE,YAAaC,cAAcF,EAAEC,eAIzF,IAAIhB,EAA+D,GAEnE,GAAIhB,EAAmC,CACnC,MAAMiB,EAAiBgK,EAA2BnW,KAAIgF,GAASA,EAAMlC,YACrEoJ,QAoEhBtW,eACIwW,EACAhO,GAEA,GAAkC,KAA9BgO,MAAAA,OAAiB,EAAjBA,EAAmBpS,cAAsCb,IAAtBiT,EACnC,OAEJ,MAAMC,EAA0B,GAOhC,OANAD,MAAAA,GAAAA,EAAmBpM,KAAItK,SACRyD,IAAPzD,GACA2W,EAAcxM,KAAKnK,OAIpB4W,EAAAA,EAAAA,IAA+B,CAAE7Q,cAAe2C,GAAOiO,EAAe,GACxEf,MAAMiB,IACH,GAAIA,KAA4BA,aAAkC/V,OAC9D,OAAO+V,KAIdC,OAAOpH,IACJhH,EAAIsB,MACA,8HAEJtB,EAAIsB,MAAM0F,EAAMqH,SAChBrO,EAAIiH,UAAUqH,UAAUtH,GACxBhH,EAAIiH,UAAUsH,MACV,+HAEG,MAlG6BC,CAAgCT,EAAgB/N,GAEpF,MAAMgY,EAAsBD,EAA2BnW,KAAIgF,IAAQ,IAAAoI,EAC/D,MAAMC,EAAgD,QAA1BD,EAAGlB,SAAuB,IAAAkB,OAAA,EAAvBA,EAAyBnP,MACpDqP,GAA0BA,EAAuBxK,YAAckC,EAAMlC,YAEzE,OAoBhBlN,eACI2X,EACAC,EACApP,GAEA,IAAKmP,IAAoBA,EAAgBE,cACrC,MAAO,CAAEC,yBAAqBvU,GAGlC,OAAOwU,EAAAA,EAAAA,IAAmB,CAAElS,cAAe2C,GAAOmP,EAAgBE,eAC7DnC,MAAMsC,IACH,MAAM7I,EAAoC,CACtCkJ,gBAAiBV,GAGrB,OAAIK,GAAWA,aAAiBpX,MAQzB,CACHkX,oBAAqB3I,EACrBqJ,2BAA4BZ,GATrB,CACHE,oBAAqB3I,EACrBsJ,WAAYT,EACZQ,2BAA4BZ,MASvChB,OAAOpH,IACJhH,EAAIsB,MAAM,2EACVtB,EAAIsB,MAAM0F,EAAMqH,SAChBrO,EAAIiH,UAAUqH,UAAUtH,GACxBhH,EAAIiH,UAAUsH,MAAM,2EACb,CAAEe,oBAAqB,OArDnB2I,CAAsBrR,EAAOqI,EAAwBjP,MAGhE,OAAOmQ,QAAQC,IAAI4H,MAEtB5J,OAAOpH,IACJhH,EAAIsB,MAAM,uDACVtB,EAAIsB,MAAM0F,EAAMqH,SAChBrO,EAAIiH,UAAUD,MAAMA,EAAMqH,SAC1BrO,EAAIiH,UAAUsH,MAAM,uDACb,MAyFnB,SAAelX,EAAAA,EAAAA,IAA2B,CACtCC,GAAI,2EACJC,OAAyDugB,EACzDrgB,MAAOogB,+yBChML,SAAUK,EAA4BC,EAAoBC,GAE5D,OADAD,EAASE,UAAYC,EAAiB9e,EAAC,GAAK4e,GAAW,IAAKD,EAASE,WAAa,KAC3EF,EAGJ3gB,eAAe+gB,EAA2B9gB,EAAgCuI,GAAmB,IAAAwY,EAChG,MAAM,QAAEJ,GAAY3gB,EAEd0gB,QAAiBM,EAAAA,EAAAA,WAAU,CAAEpb,cAAe2C,EAAKoE,YAAa,OAAS,IAE7E,IAAK+T,EACD,MAAM,IAAI/f,MAAM,2BAGpB+f,EAASE,UAAYC,EAAiB9e,EAAC,GAAK4e,GAAW,IAAuB,QAAtBI,EAAIL,EAASE,iBAAS,IAAAG,EAAAA,EAAI,KAClF,MAAME,QAAwBC,EAAAA,EAAAA,aAAY,CAAEtb,cAAe2C,GAAOmY,GAElE,IAAKO,EACD,MAAM,IAAItgB,MAAM,6BAKpB,OAFA4H,EAAI4Y,OAAO,IAAItF,EAAAA,iBAAiBtT,EAAIjJ,eAAeyF,aAAckc,GAE1DA,EAAgBL,WAAa,GASjC,MAAMQ,GAAuCxhB,EAAAA,EAAAA,IAAsC,CACtFC,GAAI,mEACJC,OAA4BghB,EAC5B9gB,MAA4DqhB,EAAAA,GAC5DC,WAAW,IAEf,IAEMT,EAAoBA,CAACU,EAA2B3N,IAC3CA,EAAUzJ,KAAIqX,IACbA,EAAKva,WAAasa,EAAiBta,SACnCua,EAAKC,WAAY,EAEjBD,EAAKC,WAAY,EAEdD,iCCtDR,IAAKtZ,EASAwZ,mBATZ,SAAYxZ,GACRA,EAAAA,EAAA,iCACAA,EAAAA,EAAA,uBACAA,EAAAA,EAAA,mBAHJ,CAAYA,IAAAA,EAAY,KASxB,SAAYwZ,GACRA,EAAA,sCACAA,EAAA,gCACAA,EAAA,sBAHJ,CAAYA,IAAAA,EAAe,wDCJpB,MAAMjW,EAAiCA,CAC1ClD,EACAwS,EACAP,EACAvP,KAEA,MACI3L,gBACIa,KACId,QAAQ,iBAAEsiB,EAAgB,eAAEC,MAGpCrZ,EAEEmN,EAA8D,GAEpE,QAAyBpS,IAArBqe,IAAuD,IAArBA,EAClC,OAAOjM,EAGX,GAAIqF,GAA8BA,EAA2B5W,OAAS,EAClE,IAAK,MAAMmJ,KAAWyN,EAA4B,KAAA8G,EAAAC,EAAAC,EAC9C,MAAMC,EAAkB/W,MAAAA,OAAmB,EAAnBA,EAAqB7C,MAAK6Z,GAAQA,EAAKhb,WAAaqG,EAAQjD,YAC9E6X,EAAUF,MAAAA,GAAgC,QAAjBH,EAAfG,EAAiBzU,uBAAe,IAAAsU,OAAA,EAAhCA,EAAkCzZ,MAAK+Z,GAA4B,YAAjBA,EAAQ5f,MAA4C,QAAtB4f,EAAQxb,YAClGyb,EAAsBJ,MAAAA,GAAgC,QAAjBF,EAAfE,EAAiBzU,uBAAe,IAAAuU,OAAA,EAAhCA,EAAkC1Z,MAAK+Z,GAA4B,wBAAjBA,EAAQ5f,MAAwD,OAAtB4f,EAAQxb,YAC1H0b,EAAkBL,MAAAA,GAAgC,QAAjBD,EAAfC,EAAiBzU,uBAAe,IAAAwU,OAAA,EAAhCA,EAAkC3Z,MAAK+Z,GAA4B,oBAAjBA,EAAQ5f,MAAoD,WAAtB4f,EAAQxb,YACxH,OAAQ6T,GAAgC0H,GAAWE,GAAuBC,EAAtD,iBAA4FT,GAC5G,IAAK,oBAED,MAAMU,EAAqBC,EAAsCha,EAAK+E,GAClEgV,GACA5M,EAA4B1L,KAAKsY,GAErC,MACJ,IAAK,iBAED,MAAME,EAA2BC,EAA4Cla,EAAK+E,GAC9EkV,GACA9M,EAA4B1L,KAAKwY,GAErC,MACJ,QAEI,MAAME,EAAaC,EAAiCpa,EAAK+E,GACrDoV,GACAhN,EAA4B1L,KAAK0Y,IAKrD,OAAOhN,GAGEiN,EAAmCA,CAC5Cpa,EACAqa,KAEA,GACIA,GACAA,EAAsCvY,gBACmB/G,IAAzDsf,EAAsC/S,eACxC,CACE,MAAMgT,EAAaD,EAAsC/S,eAAiBtH,EAAIjJ,eAAea,IAAId,OAAOyjB,oBAClGC,EAA2B,CAC7B1Y,UAAWuY,EAAsCvY,UACjDuB,kBAAmBiX,EAAa,EAAIA,EAAa,GAErD,MAAO,CACHlX,yBAA0BoX,EAC1BrX,sBAAoBqX,EAAyBnX,mBAAqBmX,EAAyBnX,kBAAoB,GAC/GG,iBAAkB6W,EAAsC7W,kBAGhE,OAAO,MAGEwW,EAAwCA,CACjDha,EACAqa,KAEA,MAAMI,EAAoBC,EAAoB1a,EAAKqa,EAAsC3S,qCACzF,GACI2S,GACAA,EAAsCvY,gBACmB/G,IAAzDsf,EAAsC/S,eACxC,CAGE,MAAMqT,EAC4E,QAA9EN,EAAsC3S,oCAChC,EACA2S,EAAsCxT,kBAC1C2T,EAA2B,CAC7B1Y,UAAWuY,EAAsCvY,UACjDuB,kBAAmBsX,GAEvB,MAAO,CACHvX,yBAA0BoX,EAC1BlX,eAAgBmX,EAAoBJ,EAAsC3S,yCAAsC3M,EAChHwI,gBAAiBkX,EAAoBJ,EAAsC5S,0CAAuC1M,EAClHoI,wBAAmEpI,IAA/Cyf,EAAyBnX,mBAAmCmX,EAAyBnX,kBAAoB,EAC7HG,iBAAkB6W,EAAsC7W,kBAGhE,OAAO,MAGE0W,EAA8CA,CACvDla,EACAqa,KAEA,MAAMI,EAAoBC,EAAoB1a,EAAKqa,EAAsC7S,kCACzF,GACI6S,GACAA,EAAsCvY,gBACmB/G,IAAzDsf,EAAsC/S,eACxC,CAGE,MAAMqT,EACyE,QAA3EN,EAAsC7S,iCAChC,EACA6S,EAAsC/S,eAC1CkT,EAA2B,CAC7B1Y,UAAWuY,EAAsCvY,UACjDuB,kBAAmBsX,GAEvB,MAAO,CACHvX,yBAA0BoX,EAC1BlX,eAAgBmX,EAAoBJ,EAAsC7S,sCAAmCzM,EAC7GwI,gBAAiBkX,EAAoBJ,EAAsC9S,uCAAoCxM,EAC/GoI,wBAAmEpI,IAA/Cyf,EAAyBnX,mBAAmCmX,EAAyBnX,kBAAoB,EAC7HG,iBAAkB6W,EAAsC7W,kBAGhE,OAAO,MAGEkX,EAAsBA,CAAC1a,EAAqB4a,KACrD,IAAKA,EACD,OAAO,EAEX,OAAQ5a,EAAIjJ,eAAea,IAAId,OAAO+jB,iBAClC,IAAK,mBACD,GAAsB,UAAlBD,EACA,OAAO,EAEX,MACJ,IAAK,aACD,GAAsB,QAAlBA,EACA,OAAO,EAEX,MACJ,IAAK,MACD,OAAO,EACX,QACI,OAAO,EAEf,OAAO,8DC5KPE,EAAQC,EAAQ,KAEb,MAAMlG,EAAwBrd,MAAOsL,EAAsCkY,KAC9E,MAAMpG,EAA+B,GACrC,IAAK,MAAM7P,KAAWjC,EAAc,CAChC,MAAMoC,QAAmB+V,EAAwBlW,EAAQrG,SAAUsc,GACnE9V,GACIA,EAAWtD,KAAKsZ,IACZ,GAAIA,MAAAA,GAAAA,EAAMlhB,MAAsB,uBAAdkhB,EAAKlhB,MAAiCkhB,EAAK9c,UAAW,CAE9C+c,KAAKC,MAAMF,MAAAA,OAAI,EAAJA,EAAM9c,WAAWid,mBAChCzf,OAAS,GACvBgZ,EAAmBnT,KAAKsD,EAAQrG,cAMpD,OAAOkW,GAGEqG,EAA0BzjB,MAAOiF,EAAmBue,KAE7D,IAAIlkB,EAAS,CACTwkB,OAAQ,MACR9iB,IAHMwiB,EAAoB,GAAGA,sBAAsCve,oFAA6F,2EAA2EA,oFAI3O8e,QAAS,CACLC,UAAWR,EAAoBA,EAAkB5f,MAAM,OAAO,GAAK,gDACnEqgB,OAAQ,mBACR,kBAAmB,QACnBC,aAAc,yBACd,gBAAiB,WACjB,eAAgB,mBAChBC,YAAa,mBACb,gBAAiB,OACjB,mBAAoB,MACpB,gBAAiB,MACjBC,IAAK,OACLC,OAAQ,WACRC,OAAQ,wBACRC,UAAW,qCACXC,cAAe,2BAIvB,IAEI,aADuBlB,EAAMhkB,IACbqE,KAAK6D,MACvB,MAAOgI,GAEL,MADAiV,QAAQC,IAAI,MAAOlV,GACbA,omBCnDd,MAAMmV,EAAU,CAAEC,QAAS,GAAIC,YAAa,IAElCC,EAAoBC,IAClBJ,EAAQE,YAAYE,IACpBJ,EAAQE,YAAYE,GAAYC,SAChCL,EAAQE,YAAYE,GAAYC,QAAQC,WACxCN,EAAQE,YAAYE,GAAYC,QAAQC,UAAUnlB,GAClD6kB,EAAQE,YAAYF,EAAQE,YAAYE,GAAYC,QAAQC,UAAUnlB,IAAM6kB,EAAQE,YAAYE,GAEhG/S,OAAOkT,KAAKP,EAAQE,YAAYE,IAAe,IAAI3O,SAAQ+O,IACnDR,EAAQE,YAAYE,GAAYI,IAChCR,EAAQE,YAAYE,GAAYI,GAAYF,WAC5CN,EAAQE,YAAYE,GAAYI,GAAYF,UAAUG,SACtDT,EAAQE,YAAYF,EAAQE,YAAYE,GAAYI,GAAYF,UAAUnlB,IAAM6kB,EAAQE,YAAYE,GAAYI,QA2B5H,CACI,MAAMJ,EAAa,6EACnBJ,EAAQE,YAAYE,GAAcxB,EAAQ,KAC1CuB,EAAiBC,GAGrB,CACI,MAAMA,EAAa,2EACnBJ,EAAQE,YAAYE,GAAcxB,EAAQ,KAC1CuB,EAAiBC,GAGrB,CACI,MAAMA,EAAa,sEACnBJ,EAAQE,YAAYE,GAAcxB,EAAQ,KAC1CuB,EAAiBC,GAGrB,CACI,MAAMA,EAAa,kEACnBJ,EAAQE,YAAYE,GAAcxB,EAAQ,MAC1CuB,EAAiBC,GAGrB,CACI,MAAMA,EAAa,wEACnBJ,EAAQE,YAAYE,GAAcxB,EAAQ,MAC1CuB,EAAiBC,GAGrB,CACI,MAAMA,EAAa,qDACnBJ,EAAQE,YAAYE,GAAcxB,EAAQ,KAC1CuB,EAAiBC,GAGrB,CACI,MAAMA,EAAa,2DACnBJ,EAAQE,YAAYE,GAAcxB,EAAQ,KAC1CuB,EAAiBC,GAGrB,CACI,MAAMA,EAAa,6EACnBJ,EAAQE,YAAYE,GAAcxB,EAAQ,MAC1CuB,EAAiBC,GAGrB,CACI,MAAMA,EAAa,0DACnBJ,EAAQE,YAAYE,GAAcxB,EAAQ,KAC1CuB,EAAiBC,GAGrB,CACI,MAAMA,EAAa,yFACnBJ,EAAQE,YAAYE,GAAcxB,EAAQ,MAC1CuB,EAAiBC,GAGrB,CACI,MAAMA,EAAa,qEACnBJ,EAAQE,YAAYE,GAAcxB,EAAQ,MAC1CuB,EAAiBC,GAGrB,CACI,MAAMA,EAAa,8DACnBJ,EAAQE,YAAYE,GAAcxB,EAAQ,MAC1CuB,EAAiBC,GAGrB,CACI,MAAMA,EAAa,wEACnBJ,EAAQE,YAAYE,GAAcxB,EAAQ,MAC1CuB,EAAiBC,GAGrB,CACI,MAAMA,EAAa,gEACnBJ,EAAQE,YAAYE,GAAcxB,EAAQ,MAC1CuB,EAAiBC,GAIzBM,OAAOC,aAAeD,OAAOC,cAAgB,GAC7CD,OAAOC,aAAaV,QAAO5iB,EAAAA,EAAA,GACpBqjB,OAAOC,aAAaV,SAAW,IAC/BD,EAAQC,SAGXS,OAAOC,aAAaC,mBAAqB,GACzCF,OAAOC,aAAaC,mBAA8B,UAACvjB,EAAA,GAC5C2iB,EAAQE,iCCrIvBW,EAAOC,QAAUC,2BCAjBF,EAAOC,QAAUE","sources":["webpack://Dobbies.Commerce/./src/modules/dobbies-category-page-summary/dobbies-category-page-summary.action.ts?c3db","webpack://Dobbies.Commerce/./src/modules/dobbies-product-page-summary/dobbies-product-page-summary.action.ts?fc19","webpack://Dobbies.Commerce/./src/themes/dobbies/actions/utilities/arrayExtensions.ts?e01e","webpack://Dobbies.Commerce/./src/themes/dobbies/actions/get-availabilities-cartlines.override.action.ts?b758","webpack://Dobbies.Commerce/./src/themes/dobbies/actions/get-categories.ts?084c","webpack://Dobbies.Commerce/./src/themes/dobbies/actions/get-categories-hierarchy.override.action.ts?67f6","webpack://Dobbies.Commerce/./src/themes/dobbies/actions/get-current-category-hierarchy.override.action.ts?7edf","webpack://Dobbies.Commerce/./src/themes/dobbies/actions/get-customer-address.action.ts?75be","webpack://Dobbies.Commerce/./src/themes/dobbies/actions/get-feature-state.override.action.ts?6984","webpack://Dobbies.Commerce/./src/themes/dobbies/actions/get-full-available-inventory-nearby.override.action.ts?8735","webpack://Dobbies.Commerce/./src/themes/dobbies/actions/get-loyalty-card.override.action.ts?a600","webpack://Dobbies.Commerce/./src/themes/dobbies/actions/get-product-availabilities-for-selected-variant.override.action.ts?3e5e","webpack://Dobbies.Commerce/./src/themes/dobbies/actions/get-products-in-active-cart.override.action.ts?d217","webpack://Dobbies.Commerce/./src/themes/dobbies/actions/utilities/get-image-url.ts?c93b","webpack://Dobbies.Commerce/./src/themes/dobbies/actions/get-selected-variant.override.action.ts?eca5","webpack://Dobbies.Commerce/./src/themes/dobbies/actions/get-store-location-information.override.action.ts?6d2a","webpack://Dobbies.Commerce/./src/themes/dobbies/actions/update-primary-address.override.action.ts?61d8","webpack://Dobbies.Commerce/./src/themes/dobbies/actions/utilities/product-inventory-information.ts?064d","webpack://Dobbies.Commerce/./src/themes/dobbies/utilities/inventory/product-inventory-utils.ts?3772","webpack://Dobbies.Commerce/./src/themes/dobbies/utilities/post-code-restriction/get-restricted-products.tsx?5e6d","webpack://Dobbies.Commerce/./lib/__local__/module-registration.js?8a42","webpack://Dobbies.Commerce/external var \"React\"?0d3b","webpack://Dobbies.Commerce/external var \"ReactDOM\"?853b"],"sourcesContent":["/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n/* eslint-disable no-duplicate-imports */\r\nimport {\r\n CacheType,\r\n createObservableDataAction,\r\n getFriendlyName,\r\n IAction,\r\n IActionContext,\r\n IActionInput,\r\n IAny,\r\n ICreateActionContext,\r\n IGeneric,\r\n IRequestContext\r\n} from '@msdyn365-commerce/core';\r\nimport * as Msdyn365 from '@msdyn365-commerce/core';\r\nimport {\r\n buildCacheKeyWithUrlTokens,\r\n CurrentCategoryInput,\r\n getCategoryUrl,\r\n getCurrentCategory,\r\n removeDomainQspFromUrl\r\n} from '@msdyn365-commerce-modules/retail-actions';\r\nimport { IDefaultPageSummaryConfig } from '@msdyn365-commerce-modules/page-summary';\r\nimport { IPageSummaryData } from '@msdyn365-commerce-modules/page-summary';\r\nimport { IDobbiesCategoryPageSummaryConfig } from './dobbies-category-page-summary.props.autogenerated';\r\n/**\r\n * Category Page Summary Input\r\n */\r\nexport class CategoryPageSummaryInput implements IActionInput {\r\n public requestContext: IRequestContext;\r\n public config: IDobbiesCategoryPageSummaryConfig;\r\n constructor(config: IDefaultPageSummaryConfig, requestContext: IRequestContext) {\r\n this.config = config || {};\r\n this.requestContext = requestContext;\r\n }\r\n public getCacheObjectType = (): string => 'CategoryPageSummary';\r\n public getCacheKey = (): string => buildCacheKeyWithUrlTokens('CategoryPageSummary', this.requestContext);\r\n public dataCacheType = (): CacheType => 'request';\r\n}\r\nconst createGetCurrentCategoryInput = (inputData: IActionContext): CurrentCategoryInput => {\r\n if (inputData && inputData.requestContext) {\r\n return new CurrentCategoryInput(inputData.requestContext);\r\n }\r\n throw new Error('Please specify categoryId query string in request.');\r\n};\r\n/**\r\n * Get skip count.\r\n * @param inputData\r\n */\r\nfunction getSkipCount(inputData: ICreateActionContext, IGeneric>): string | undefined {\r\n return inputData && inputData.requestContext && inputData.requestContext.query && inputData.requestContext.query.skip;\r\n}\r\nconst action = async (input: CategoryPageSummaryInput, context: IActionContext): Promise => {\r\n const { config } = input;\r\n // const jsonUrl =\r\n // context.requestContext.app.config.plpSeoJsonUrl ||\r\n // 'https://files-eu-prod.cms.commerce.dynamics.com/cms/api/ctdwmwnctb/binary/MD4Pav';\r\n const excelUrl =\r\n context.requestContext.app.config.plpSeoTSVUrl ||\r\n 'https://files-eu-prod.cms.commerce.dynamics.com/cms/api/ctdwmwnctb/binary/MD8w5X';\r\n // const res = await Msdyn365.sendRequest(jsonUrl, 'get');\r\n const excelRes = await Msdyn365.sendRequest(excelUrl, 'get');\r\n let currentCategoryResult;\r\n try {\r\n currentCategoryResult = await getCurrentCategory(createGetCurrentCategoryInput(context), context);\r\n } catch {\r\n // Do nothing, if the action fails fallback to values defined in data\r\n }\r\n const currCatUrl = context.requestContext.url.requestUrl.href;\r\n let configCategoryUrl = '';\r\n let configCategoryName = '';\r\n let configCategoryDesc = '';\r\n if (\r\n context.requestContext.app.config.canonicalUrlForCategories &&\r\n Array.isArray(context.requestContext.app.config.canonicalUrlForCategories)\r\n ) {\r\n for (const canonicalUrlCatConfig of context.requestContext.app.config.canonicalUrlForCategories) {\r\n if (currCatUrl.includes(canonicalUrlCatConfig.categoryIDOrUrl) || currCatUrl === canonicalUrlCatConfig.categoryIDOrUrl) {\r\n configCategoryUrl = canonicalUrlCatConfig.canonicalUrl;\r\n configCategoryName = canonicalUrlCatConfig.canonicalName;\r\n configCategoryDesc = canonicalUrlCatConfig.canonicalDescription;\r\n }\r\n }\r\n }\r\n if (currentCategoryResult) {\r\n const currentCategory = { ...currentCategoryResult };\r\n let categoryUrl: string | undefined;\r\n try {\r\n // Reset category's name neutralizedName\r\n const localName = getFriendlyName(context.requestContext.locale, currentCategory.NameTranslations);\r\n const neutralizedName = currentCategory.NeutralizedName || currentCategory.Name;\r\n currentCategory.Name = localName;\r\n currentCategory.NeutralizedName = neutralizedName;\r\n categoryUrl = getCategoryUrl(currentCategory);\r\n const canonicalDomain = context.requestContext.canonicalDomain;\r\n if (categoryUrl && canonicalDomain) {\r\n categoryUrl = `https://${canonicalDomain}${categoryUrl}`.toLocaleLowerCase();\r\n const skipCount = getSkipCount(context);\r\n const Url = new URL(categoryUrl);\r\n const urlParams: URLSearchParams = new URLSearchParams(Url.search);\r\n if (skipCount) {\r\n urlParams.set('skip', skipCount);\r\n }\r\n Url.search = urlParams.toString();\r\n categoryUrl = Url.toString();\r\n categoryUrl = removeDomainQspFromUrl(categoryUrl, context.requestContext);\r\n } else {\r\n categoryUrl = undefined;\r\n }\r\n } catch {\r\n categoryUrl = undefined;\r\n }\r\n const catUrl = getCategoryUrl(currentCategory);\r\n const excelDataStr = excelRes.data as string;\r\n const splittedExcelData = excelDataStr.split('\\n');\r\n let title = currentCategory.Name;\r\n let desc: string | undefined;\r\n let canonical = categoryUrl;\r\n for (const dataRow of splittedExcelData) {\r\n if (!dataRow || !dataRow.trim()) {\r\n continue;\r\n }\r\n const rowSplitted = dataRow.trim().split('\\t');\r\n const curl = rowSplitted[0];\r\n if (catUrl && (catUrl === curl || catUrl?.includes(curl) || curl.includes(catUrl))) {\r\n title = rowSplitted.length > 1 ? rowSplitted[1] : currentCategory.Name;\r\n desc = rowSplitted.length > 2 ? rowSplitted[2] : undefined;\r\n if (config.descriptionLimit && desc) {\r\n desc = desc.substring(0, config.descriptionLimit);\r\n }\r\n canonical = rowSplitted.length > 3 ? rowSplitted[3] : categoryUrl;\r\n return {\r\n title: title,\r\n description: desc,\r\n sharingImageUrl: currentCategory.OfflineImage,\r\n canonicalUrl: canonical,\r\n faviconUrl: config && config.faviconUrl\r\n };\r\n }\r\n }\r\n if (config.descriptionLimit && desc) {\r\n desc = desc.substring(0, config.descriptionLimit);\r\n }\r\n return {\r\n title: title,\r\n description: desc\r\n ? desc\r\n : config.defaultCategoryDescription\r\n ? config.defaultCategoryDescription\r\n : 'Dobbies Garden Centres are proud to provide the very best in horticultural products and expert gardening advice to gardeners throughout the UK',\r\n sharingImageUrl: currentCategory.OfflineImage,\r\n canonicalUrl: canonical,\r\n faviconUrl: config && config.faviconUrl\r\n };\r\n // const plpSeoData = res.data && catUrl && res.data[catUrl];\r\n // return {\r\n // title: plpSeoData ? plpSeoData.title : currentCategory.Name,\r\n // description: plpSeoData && plpSeoData.description,\r\n // sharingImageUrl: currentCategory.OfflineImage,\r\n // canonicalUrl: plpSeoData ? plpSeoData.canonicalUrl : categoryUrl,\r\n // faviconUrl: config && config.faviconUrl\r\n // };\r\n // If the action fails fallback to values defined from data\r\n } else if (configCategoryUrl && configCategoryName) {\r\n if (config.descriptionLimit && configCategoryDesc) {\r\n configCategoryDesc = configCategoryDesc.substring(0, config.descriptionLimit);\r\n }\r\n return {\r\n title: configCategoryName,\r\n description: configCategoryDesc,\r\n sharingImageUrl: config.sharingImage && config.sharingImage.src,\r\n canonicalUrl: configCategoryUrl,\r\n faviconUrl: config && config.faviconUrl\r\n };\r\n } else if (config) {\r\n return {\r\n title: config.title,\r\n sharingImageUrl: config.sharingImage && config.sharingImage.src,\r\n faviconUrl: config && config.faviconUrl\r\n };\r\n }\r\n return {};\r\n};\r\nexport default createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/page-summary/category-page-summary',\r\n action: >action,\r\n input: (args: ICreateActionContext) => {\r\n return new CategoryPageSummaryInput(args.config, args.requestContext);\r\n }\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 {\r\n CacheType,\r\n createObservableDataAction,\r\n getCatalogId,\r\n IAction,\r\n IActionContext,\r\n IActionInput,\r\n ICommerceApiSettings,\r\n ICreateActionContext,\r\n IRequestContext\r\n} from '@msdyn365-commerce/core';\r\nimport * as Msdyn365 from '@msdyn365-commerce/core';\r\nimport { SimpleProduct } from '@msdyn365-commerce/retail-proxy';\r\nimport { getAttributeValuesAsync, getByIdsAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\r\nimport {\r\n ArrayExtensions,\r\n buildCacheKey,\r\n generateImageUrl,\r\n getProductUrlSync,\r\n getSelectedProductIdFromActionInput,\r\n QueryResultSettingsProxy,\r\n removeDomainQspFromUrl\r\n} from '@msdyn365-commerce-modules/retail-actions';\r\n\r\nimport { IPageSummaryData } from '@msdyn365-commerce-modules/page-summary';\r\nimport { IDobbiesProductPageSummaryConfig } from './dobbies-product-page-summary.props.autogenerated';\r\n\r\n/**\r\n * Product Page Summary Input.\r\n */\r\nexport class ProductPageSummaryInput implements IActionInput {\r\n public apiSettings: ICommerceApiSettings;\r\n\r\n public config: IDobbiesProductPageSummaryConfig;\r\n\r\n public productId: number;\r\n\r\n public catalogId?: number;\r\n\r\n public constructor(\r\n config: IDobbiesProductPageSummaryConfig,\r\n apiSettings: ICommerceApiSettings,\r\n productId: number,\r\n requestContext?: IRequestContext\r\n ) {\r\n this.config = config || {};\r\n this.apiSettings = apiSettings;\r\n this.productId = productId;\r\n\r\n if (requestContext) {\r\n this.catalogId = getCatalogId(requestContext);\r\n }\r\n }\r\n\r\n public getCacheObjectType = (): string => 'ProductPageSummary';\r\n\r\n public getCacheKey = (): string =>\r\n `${buildCacheKey('ProductPageSummary', this.apiSettings)}-${this.config.title}-${this.productId}-${this.catalogId ?? 0}`;\r\n\r\n public dataCacheType = (): CacheType => 'application';\r\n}\r\n\r\nexport interface IProductPageSummary extends IPageSummaryData {\r\n price?: number;\r\n productId?: number;\r\n productBrand?: string;\r\n}\r\n\r\nconst createInput = (args: ICreateActionContext) => {\r\n const productId = getSelectedProductIdFromActionInput(args);\r\n\r\n if (productId) {\r\n return new ProductPageSummaryInput(\r\n args.config,\r\n args.requestContext.apiSettings,\r\n +productId,\r\n args.requestContext\r\n );\r\n }\r\n throw new Error('Unable to create ProductPageSummaryAction input, no productId found on module config or query');\r\n};\r\n\r\n// Checks product attributes for the presence of brand attribute to extract the brand name for product metadata\r\nconst getProductBrand = async (\r\n context: IActionContext,\r\n recordId: number,\r\n channelId: number,\r\n catalogId: number\r\n): Promise => {\r\n const productAttributes = await getAttributeValuesAsync(\r\n {\r\n callerContext: context,\r\n queryResultSettings: QueryResultSettingsProxy.getPagingFromInputDataOrDefaultValue(context)\r\n },\r\n recordId,\r\n channelId,\r\n catalogId\r\n );\r\n for (const productAttribute of productAttributes) {\r\n if (productAttribute.Name === 'Brand') {\r\n return productAttribute.TextValue;\r\n }\r\n }\r\n return;\r\n};\r\n\r\nconst action = async (input: ProductPageSummaryInput, context: IActionContext): Promise => {\r\n const { config, productId, apiSettings } = input;\r\n // const jsonUrl =\r\n // context.requestContext.app.config.pdpSeoJsonUrl ||\r\n // 'https://files-eu-prod.cms.commerce.dynamics.com/cms/api/ctdwmwnctb/binary/MD4Pas';\r\n // const res = await Msdyn365.sendRequest(jsonUrl, 'get');\r\n const excelUrl =\r\n context.requestContext.app.config.pdpSeoTSVUrl ||\r\n 'https://files-eu-prod.cms.commerce.dynamics.com/cms/api/ctdwmwnctb/binary/MD8qTr';\r\n const excelRes = await Msdyn365.sendRequest(excelUrl, 'get');\r\n const prodID = productId.toString();\r\n // const pdpSeoData = res.data && res.data[prodID];\r\n\r\n let simpleProductsData: SimpleProduct[] | undefined;\r\n try {\r\n simpleProductsData = ArrayExtensions.validValues(\r\n await getByIdsAsync(\r\n {\r\n callerContext: context,\r\n queryResultSettings: QueryResultSettingsProxy.getPagingFromInputDataOrDefaultValue(context)\r\n },\r\n apiSettings.channelId,\r\n [productId],\r\n null,\r\n input.catalogId ?? 0\r\n )\r\n );\r\n } catch {\r\n // Do nothing, if there's an error we fall back to values defined from config\r\n }\r\n if (ArrayExtensions.hasElements(simpleProductsData)) {\r\n const simpleProductData = simpleProductsData[0];\r\n let productUrl: string | undefined;\r\n try {\r\n productUrl = getProductUrlSync(simpleProductData, context);\r\n const canonicalDomain = context.requestContext.canonicalDomain;\r\n if (productUrl && canonicalDomain) {\r\n productUrl = `https://${canonicalDomain}${productUrl}`.toLocaleLowerCase();\r\n productUrl = removeDomainQspFromUrl(productUrl, context.requestContext);\r\n } else {\r\n productUrl = undefined;\r\n }\r\n } catch {\r\n productUrl = undefined;\r\n }\r\n let productBrand: string | undefined;\r\n try {\r\n productBrand = await getProductBrand(context, productId, apiSettings.channelId, input.catalogId ?? 0);\r\n } catch {\r\n productBrand = undefined;\r\n }\r\n const excelDataStr = excelRes.data as string;\r\n const splittedExcelData = excelDataStr.split('\\n');\r\n let title = simpleProductData.Name;\r\n let desc = simpleProductData.Description ? simpleProductData.Description : simpleProductData.Name;\r\n let canonical = productUrl;\r\n for (const dataRow of splittedExcelData) {\r\n if (!dataRow || !dataRow.trim()) {\r\n continue;\r\n }\r\n const rowSplitted = dataRow.trim().split('\\t');\r\n const curl = rowSplitted[0];\r\n if (prodID && (prodID === curl || curl.includes(prodID))) {\r\n title = rowSplitted.length > 1 ? rowSplitted[1] : simpleProductData.Name;\r\n desc = rowSplitted.length > 2 ? rowSplitted[2] : simpleProductData.Description;\r\n canonical = rowSplitted.length > 3 ? rowSplitted[3] : productUrl;\r\n if (config.descriptionLimit && desc) {\r\n desc = desc.substring(0, config.descriptionLimit);\r\n }\r\n return {\r\n title: title,\r\n description: desc,\r\n sharingImageUrl: generateImageUrl(simpleProductData.PrimaryImageUrl, apiSettings),\r\n canonicalUrl: canonical,\r\n faviconUrl: config && config.faviconUrl,\r\n productId: simpleProductData.RecordId,\r\n price: simpleProductData.AdjustedPrice,\r\n productBrand\r\n };\r\n }\r\n }\r\n if (config.descriptionLimit && desc) {\r\n desc = desc.substring(0, config.descriptionLimit);\r\n }\r\n return {\r\n title: title,\r\n description: desc,\r\n sharingImageUrl: generateImageUrl(simpleProductData.PrimaryImageUrl, apiSettings),\r\n canonicalUrl: canonical,\r\n faviconUrl: config && config.faviconUrl,\r\n productId: simpleProductData.RecordId,\r\n price: simpleProductData.AdjustedPrice,\r\n productBrand\r\n };\r\n // return {\r\n // title: pdpSeoData ? pdpSeoData.title : simpleProductData.Name,\r\n // description: pdpSeoData ? pdpSeoData.description : simpleProductData.Description,\r\n // sharingImageUrl: generateImageUrl(simpleProductData.PrimaryImageUrl, apiSettings),\r\n // canonicalUrl: pdpSeoData ? pdpSeoData.canonicalUrl : productUrl,\r\n // faviconUrl: config && config.faviconUrl,\r\n // productId: simpleProductData.RecordId,\r\n // price: simpleProductData.AdjustedPrice,\r\n // productBrand\r\n // };\r\n\r\n // If the action fails fallback to values defined from config\r\n } else if (config) {\r\n return {\r\n title: config.title,\r\n description: config.descriptionLimit ? config.description?.substring(0, config.descriptionLimit) : config.description,\r\n sharingImageUrl: config.sharingImage && config.sharingImage.src,\r\n faviconUrl: config && config.faviconUrl\r\n };\r\n }\r\n return {};\r\n};\r\n\r\nexport default createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/page-summary/product-page-summary',\r\n action: >action,\r\n input: createInput\r\n});\r\n","/*\r\n * @name - unique\r\n * @description - Remove duplicate elements in the array.\r\n * @export\r\n * @public\r\n * @param {array} value - The array to examine.\r\n * @returns {array} - An array with only unique elements.\r\n */\r\nexport function unique(value: T[]): T[] {\r\n return Array.from(new Set(value));\r\n}\r\n","import {\r\n ActiveCartProductsInput,\r\n buildCacheKey,\r\n getActiveCartProductsAction,\r\n IProductInventoryInformation\r\n // mapProductInventoryInformation\r\n} from '@msdyn365-commerce-modules/retail-actions';\r\nimport { mapProductInventoryInformation } from '../utilities/inventory/product-inventory-utils';\r\n\r\nimport {\r\n CacheType,\r\n createObservableDataAction,\r\n IAction,\r\n IActionContext,\r\n IActionInput,\r\n IAny,\r\n ICommerceApiSettings,\r\n ICreateActionContext,\r\n IGeneric\r\n} from '@msdyn365-commerce/core';\r\nimport { getCartState } from '@msdyn365-commerce/global-state';\r\nimport {\r\n CartLine,\r\n ChannelDeliveryOptionConfiguration,\r\n FeatureState,\r\n ProductSearchCriteria,\r\n ProductWarehouse,\r\n ProductWarehouseInventoryInformation,\r\n SimpleProduct\r\n} from '@msdyn365-commerce/retail-proxy';\r\nimport { getOrgUnitConfigurationAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/OrgUnitsDataActions.g';\r\nimport {\r\n getEstimatedAvailabilityAsync,\r\n getEstimatedProductWarehouseAvailabilityAsync,\r\n searchByCriteriaAsync\r\n} from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\r\nimport { getChannelDeliveryOptionConfigurationAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/StoreOperationsDataActions.g';\r\nimport { ProductSearchResult, ProductWarehouseInventoryAvailability } from '@msdyn365-commerce/retail-proxy/dist/Entities/CommerceTypes.g';\r\nimport { FeatureStateInput, getFeatureStateAction } from './get-feature-state.override.action';\r\nimport { unique } from './utilities';\r\nimport { getByIdsAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\r\nimport {\r\n ArrayExtensions,\r\n QueryResultSettingsProxy\r\n} from '@msdyn365-commerce-modules/retail-actions';\r\n\r\n/**\r\n * Input class for availabilites for items in cart\r\n */\r\nexport class ProductAvailabilitiesForCartLineItems implements IActionInput {\r\n private apiSettings: ICommerceApiSettings;\r\n\r\n constructor(apiSettings: ICommerceApiSettings) {\r\n this.apiSettings = apiSettings;\r\n }\r\n\r\n public getCacheKey = () => buildCacheKey(`ActiveCartLineItemsAvailability`, this.apiSettings);\r\n public getCacheObjectType = () => 'ActiveCartLineItemsAvailability';\r\n public dataCacheType = (): CacheType => 'none';\r\n}\r\n\r\nconst createInput = (inputData: ICreateActionContext>) => {\r\n return new ProductAvailabilitiesForCartLineItems(inputData.requestContext.apiSettings);\r\n};\r\n\r\n/**\r\n * Calls the Retail API to get the product availabilites for items in the cart\r\n */\r\n/* Upgraded to 10.0.20 - START */\r\n/**\r\n * Calls the Retail Feature State API and returns a list of feature with isEnabled flag.\r\n */\r\nconst getDeliveryMode = (\r\n cartLine: CartLine,\r\n featureSate: boolean = false,\r\n channelDeliveryOptionConfig: ChannelDeliveryOptionConfiguration,\r\n pickupDeliveryMode?: string\r\n) => {\r\n if (!featureSate) {\r\n return cartLine.DeliveryMode === pickupDeliveryMode;\r\n }\r\n return (\r\n cartLine.DeliveryMode ===\r\n channelDeliveryOptionConfig?.PickupDeliveryModeCodes?.find(deliveryMode => deliveryMode === cartLine.DeliveryMode)\r\n );\r\n};\r\n\r\nasync function getSimpleProducts(prodIds:number[], input: ProductAvailabilitiesForCartLineItems, ctx: IActionContext): Promise {\r\n const simpleProductsData = ArrayExtensions.validValues(\r\n await getByIdsAsync(\r\n {\r\n callerContext: ctx,\r\n queryResultSettings: QueryResultSettingsProxy.getPagingFromInputDataOrDefaultValue(ctx)\r\n },\r\n ctx.requestContext.apiSettings.channelId,\r\n prodIds,\r\n null,\r\n ctx.requestContext.apiSettings.catalogId ?? 0\r\n )\r\n );\r\n return simpleProductsData;\r\n}\r\n\r\n/* Upgraded to 10.0.20 - END */\r\nexport async function getAvailabilitiesForCartLineItems(\r\n input: ProductAvailabilitiesForCartLineItems,\r\n ctx: IActionContext\r\n): Promise {\r\n // If no input is provided fail out\r\n if (!input) {\r\n throw new Error('[getAvailabilitiesForCartLineItems]No valid Input was provided, failing');\r\n }\r\n const shippingItems: CartLine[] = [];\r\n const bopisItems: CartLine[] = [];\r\n\r\n let productAvailabilities: IProductInventoryInformation[] = [];\r\n const multiplePickupStoreSwitchName = 'Dynamics.AX.Application.RetailMultiplePickupDeliveryModeFeature';\r\n let channelDeliveryOptionConfig: any;\r\n\r\n const cartState = await getCartState(ctx);\r\n const cart = cartState.cart;\r\n const channelConfiguration = await getOrgUnitConfigurationAsync({ callerContext: ctx });\r\n const products = await getActiveCartProductsAction(new ActiveCartProductsInput(), ctx);\r\n /* Upgraded to 10.0.20 - START */\r\n /**\r\n * Calls the Retail Feature State API and returns a list of feature with isEnabled flag.\r\n */\r\n async function getFeatureState(context: IActionContext): Promise {\r\n return getFeatureStateAction(new FeatureStateInput(), context);\r\n }\r\n const featureState = await getFeatureState(ctx);\r\n const retailMultiplePickUpOptionEnabled = featureState?.find(item => item.Name === multiplePickupStoreSwitchName)?.IsEnabled;\r\n if (retailMultiplePickUpOptionEnabled) {\r\n channelDeliveryOptionConfig = await getChannelDeliveryOptionConfigurationAsync({ callerContext: ctx });\r\n }\r\n /* Upgraded to 10.0.20 - END */\r\n const PickupDeliveryModeCode = channelConfiguration.PickupDeliveryModeCode;\r\n const EmailDeliveryModeCode = channelConfiguration.EmailDeliveryModeCode; // Upgraded to 10.0.16\r\n if (!cart || !channelConfiguration || !products || products.length === 0) {\r\n ctx.trace('[getAvailabilitiesForCartLineItems] Not able to get cart OR channelConfiguration or no products in cart');\r\n return [];\r\n }\r\n\r\n if (cart && cart.Id && cart.CartLines && cart.CartLines.length > 0 && channelConfiguration) {\r\n for (const cartLine of cart.CartLines) {\r\n if (\r\n cartLine.DeliveryMode &&\r\n cartLine.DeliveryMode !== '' &&\r\n getDeliveryMode(cartLine, retailMultiplePickUpOptionEnabled, channelDeliveryOptionConfig, PickupDeliveryModeCode)\r\n ) {\r\n bopisItems.push(cartLine);\r\n } else if (cartLine.DeliveryMode !== EmailDeliveryModeCode) {\r\n shippingItems.push(cartLine);\r\n }\r\n }\r\n }\r\n\r\n if (shippingItems && shippingItems.length > 0) {\r\n const masterProductIds: number[][] = [];\r\n \r\n let productIds = shippingItems.map(x => x.ProductId!);\r\n productIds = unique(productIds);\r\n const simpleProductData = await getSimpleProducts(productIds, input, ctx);\r\n productIds = simpleProductData.map(sp => {\r\n if(sp.MasterProductId && sp.MasterProductId !== sp.RecordId) {\r\n masterProductIds.push([sp.MasterProductId, sp.RecordId]);\r\n return sp.MasterProductId;\r\n } else {\r\n return sp.RecordId;\r\n }\r\n });\r\n\r\n /* VSI Customization - START - 21/12/20 */\r\n const {\r\n requestContext: {\r\n app: {\r\n config: { maxQuantityForCartLineItem, inStockCode, inStockLabel }\r\n }\r\n }\r\n } = ctx;\r\n\r\n let vendorShippedProducts: number[] = []; // List of vendorShip products\r\n let dobbiesPlantsProducts: number[] = []; // List of Dobbies plants products\r\n let dobbiesOtherProducts: number[] = []; // List of Dobbies all products except plants\r\n let dobbiesProductsData: ProductSearchResult[] = [];\r\n\r\n if (productIds.length > 0) {\r\n // First divide products into 2 categories to not call getEstimatedAvailabilityAsync for vendorShip items but just for dobbies products\r\n const productsByVendor = await _getProductsByTypes(ctx, productIds, masterProductIds);\r\n vendorShippedProducts = productsByVendor.vendorShippedProducts;\r\n dobbiesPlantsProducts = productsByVendor.plantsProducts;\r\n dobbiesOtherProducts = productsByVendor.dobbiesOtherProducts;\r\n dobbiesProductsData = productsByVendor.productsData;\r\n }\r\n\r\n const shippingProductAvailabilites = await getShippingProductAvailabilities(ctx, dobbiesOtherProducts, dobbiesPlantsProducts);\r\n\r\n if (\r\n shippingProductAvailabilites &&\r\n shippingProductAvailabilites.ProductWarehouseInventoryAvailabilities &&\r\n shippingProductAvailabilites.ProductWarehouseInventoryAvailabilities.length > 0\r\n ) {\r\n productAvailabilities = mapProductInventoryInformation(\r\n ctx,\r\n shippingProductAvailabilites.ProductWarehouseInventoryAvailabilities,\r\n undefined,\r\n dobbiesProductsData\r\n );\r\n }\r\n\r\n // Set maxQuantityForCartLineItem as limit for vendorShip items\r\n vendorShippedProducts.map(productId => {\r\n // Now map it into IProductInventoryInformation type\r\n productAvailabilities.push({\r\n IsProductAvailable: true,\r\n ProductAvailableQuantity: { ProductId: productId, AvailableQuantity: maxQuantityForCartLineItem },\r\n StockLevelCode: inStockCode,\r\n StockLevelLabel: inStockLabel,\r\n InventLocationId: channelConfiguration.InventLocation\r\n });\r\n });\r\n /* VSI Customization - END */\r\n }\r\n // Add bopis item availability\r\n const allProductAvailabilities = await _getBopisItemAvailability(ctx, productAvailabilities, bopisItems);\r\n\r\n if (allProductAvailabilities && allProductAvailabilities.length > 0) {\r\n return allProductAvailabilities;\r\n }\r\n\r\n ctx.trace('[getAvailabilitiesForCartLineItems] unable to get availabilites for product');\r\n return [];\r\n}\r\n\r\n/**\r\n * The function that returns the sum of all warehousees' PhysicalAvailable for plants Category\r\n */\r\nconst getAccumulatedTotalAvailable = (\r\n ctx: IActionContext,\r\n ProductWarehouseInventoryAvailabilities: ProductWarehouseInventoryAvailability[],\r\n productId: number\r\n) => {\r\n // Just check inventory in warehouseIdsForFulfillment\r\n const {\r\n requestContext: {\r\n app: {\r\n config: { warehouseIdsForFulfillment }\r\n }\r\n }\r\n } = ctx;\r\n\r\n let accumulatedProductPhysicalAvailable = 0;\r\n const fulfillmentStores: string[] | undefined = warehouseIdsForFulfillment; // ['S011', 'S040']\r\n\r\n // First find product's warehouse Info in ProductWarehouseInventoryAvailabilities and then calculates their inventory's sum\r\n ProductWarehouseInventoryAvailabilities.filter(availability => {\r\n // First check if it is one of the warehouseIdsForFulfillment, only then add inventory\r\n const isFulfillmentStore =\r\n fulfillmentStores &&\r\n fulfillmentStores.find(store => {\r\n return availability.InventLocationId && availability.InventLocationId.toLowerCase() === store.toLowerCase();\r\n });\r\n\r\n return isFulfillmentStore && availability && availability.ProductId === productId;\r\n }).map(availability => {\r\n if (availability.PhysicalAvailable) {\r\n accumulatedProductPhysicalAvailable += availability.PhysicalAvailable;\r\n }\r\n });\r\n\r\n // Now just create an object with this product availability info and returns it\r\n return accumulatedProductPhysicalAvailable;\r\n};\r\n\r\n/* Following function checks inventory for bopis items */\r\nconst _getBopisItemAvailability = async (\r\n ctx: IActionContext,\r\n productAvailabilities: IProductInventoryInformation[],\r\n bopisItems: CartLine[]\r\n): Promise => {\r\n if (bopisItems && bopisItems.length > 0) {\r\n for (const bopisItem of bopisItems) {\r\n const productWarehouse: ProductWarehouse = {\r\n ProductId: bopisItem.ProductId,\r\n InventLocationId: bopisItem.WarehouseId\r\n };\r\n\r\n if (ctx.requestContext.channel && ctx.requestContext.channel.InventLocationDataAreaId) {\r\n productWarehouse.DataAreaId = ctx.requestContext.channel.InventLocationDataAreaId;\r\n }\r\n const getProductWarehouseAvail = await getEstimatedProductWarehouseAvailabilityAsync(\r\n { callerContext: ctx, bypassCache: 'get', queryResultSettings: {} },\r\n [productWarehouse]\r\n );\r\n if (\r\n getProductWarehouseAvail &&\r\n getProductWarehouseAvail.ProductWarehouseInventoryAvailabilities &&\r\n getProductWarehouseAvail.ProductWarehouseInventoryAvailabilities.length > 0\r\n ) {\r\n const productWarehouseMapping = mapProductInventoryInformation(\r\n ctx,\r\n getProductWarehouseAvail && getProductWarehouseAvail.ProductWarehouseInventoryAvailabilities\r\n );\r\n if (productWarehouseMapping && productWarehouseMapping.length) {\r\n for (const item of productWarehouseMapping) {\r\n productAvailabilities.push(item);\r\n }\r\n }\r\n }\r\n }\r\n return productAvailabilities;\r\n }\r\n return productAvailabilities;\r\n};\r\n\r\n/* Following function divides products into 3 categories 1. VendorShipProducts 2. DobbiesPlantProducts 3. DobbiesAllOtherProducts */\r\nconst _getProductsByTypes = async (\r\n ctx: IActionContext,\r\n productIds: number[],\r\n masterProductIds?: number[][]\r\n): Promise<{\r\n vendorShippedProducts: number[];\r\n plantsProducts: number[];\r\n dobbiesOtherProducts: number[];\r\n productsData: ProductSearchResult[]\r\n}> => {\r\n const vendorShippedProducts: number[] = [];\r\n const plantsProducts: number[] = [];\r\n const dobbiesOtherProducts: number[] = [];\r\n\r\n const callerContext = ctx;\r\n const {\r\n requestContext: {\r\n apiSettings: { channelId, catalogId },\r\n app: {\r\n config: { fulfillmentAttributeName, fulfillmentAttributeTextValue }\r\n }\r\n }\r\n } = ctx;\r\n const searchCriteriaInput: ProductSearchCriteria = {};\r\n searchCriteriaInput.Context = { ChannelId: channelId, CatalogId: catalogId };\r\n searchCriteriaInput.Ids = productIds;\r\n searchCriteriaInput.IncludeAttributes = true;\r\n // store product IDs in vendorShippedProducts array if product is vendor shipped\r\n const productsData = await searchByCriteriaAsync({ callerContext, queryResultSettings: {} }, searchCriteriaInput);\r\n productsData.map(product => {\r\n let { RecordId, AttributeValues } = product;\r\n if (masterProductIds) {\r\n for(const mp of masterProductIds) {\r\n if (mp[0] === RecordId) {\r\n RecordId = mp[1];\r\n product.RecordId = mp[1];\r\n }\r\n }\r\n }\r\n const attributes = AttributeValues;\r\n const isvendorShippedAttribute =\r\n attributes &&\r\n attributes.find(attribute => {\r\n const attributeName = attribute.Name && attribute.Name.trim().toLowerCase();\r\n return attributeName === 'isvendershipproduct';\r\n });\r\n const isVendorShipped =\r\n isvendorShippedAttribute &&\r\n isvendorShippedAttribute.TextValue &&\r\n isvendorShippedAttribute.TextValue.trim().toLowerCase() === 'yes';\r\n if (isVendorShipped) {\r\n vendorShippedProducts.push(RecordId);\r\n } else {\r\n const attributeName = fulfillmentAttributeName\r\n ? fulfillmentAttributeName\r\n .toString()\r\n .toLowerCase()\r\n .trim()\r\n : 'fulfillmenttype';\r\n const attributeTextValue = fulfillmentAttributeTextValue\r\n ? fulfillmentAttributeTextValue\r\n .toString()\r\n .toLowerCase()\r\n .trim()\r\n : 'plants';\r\n\r\n const fulfillmentTypeAttribute = attributes && attributes.find(attribute => attribute?.Name?.toLowerCase() === attributeName);\r\n const isPlantFulfillment = fulfillmentTypeAttribute && fulfillmentTypeAttribute.TextValue?.toLowerCase() === attributeTextValue;\r\n if (isPlantFulfillment) {\r\n plantsProducts.push(RecordId);\r\n } else {\r\n dobbiesOtherProducts.push(RecordId);\r\n }\r\n }\r\n });\r\n\r\n return {\r\n vendorShippedProducts: vendorShippedProducts,\r\n plantsProducts: plantsProducts,\r\n dobbiesOtherProducts: dobbiesOtherProducts,\r\n productsData: productsData\r\n };\r\n};\r\n\r\n/* Following function uses 2 separate call to check availability\r\n * For plants products (fulfillment category), get availability from all warehouses with filtered by FilterByChannelFulfillmentGroup\r\n * For all other products of dobbies, check inventory from default warehouse only */\r\nconst getShippingProductAvailabilities = async (\r\n ctx: IActionContext,\r\n dobbiesOtherProducts: number[],\r\n dobbiesPlantsProducts: number[]\r\n): Promise => {\r\n try {\r\n let shippingProductAvailabilites: ProductWarehouseInventoryInformation = {\r\n ProductWarehouseInventoryAvailabilities: [],\r\n ExtensionProperties: []\r\n };\r\n\r\n if (dobbiesOtherProducts && dobbiesOtherProducts.length && dobbiesOtherProducts.length > 0) {\r\n const uniqueProductList = unique(dobbiesOtherProducts);\r\n const otherProductAvailablities = await getEstimatedAvailabilityAsync(\r\n { callerContext: ctx, bypassCache: 'get' },\r\n { ProductIds: uniqueProductList, DefaultWarehouseOnly: true }\r\n );\r\n\r\n if (\r\n otherProductAvailablities.ProductWarehouseInventoryAvailabilities &&\r\n otherProductAvailablities.ProductWarehouseInventoryAvailabilities.length > 0\r\n ) {\r\n shippingProductAvailabilites = otherProductAvailablities;\r\n }\r\n }\r\n if (dobbiesPlantsProducts && dobbiesPlantsProducts.length && dobbiesPlantsProducts.length > 0) {\r\n // Now call for plants products\r\n const uniqueProductList = unique(dobbiesPlantsProducts);\r\n const plantsProductAvailablities = await getEstimatedAvailabilityAsync(\r\n { callerContext: ctx, bypassCache: 'get' },\r\n { ProductIds: uniqueProductList, DefaultWarehouseOnly: false, FilterByChannelFulfillmentGroup: true }\r\n );\r\n\r\n if (\r\n plantsProductAvailablities.ProductWarehouseInventoryAvailabilities &&\r\n plantsProductAvailablities.ProductWarehouseInventoryAvailabilities.length > 0\r\n ) {\r\n // Get ProductWarehouseInventoryAvailabilities as a sum of all warehouse inventory for this product and use it\r\n uniqueProductList.map(plantProduct => {\r\n // Get accumulated inventory for each of product and map into an object of ProductWarehouseInventoryAvailability type\r\n const accumulatedInventorySum = plantsProductAvailablities.ProductWarehouseInventoryAvailabilities\r\n ? getAccumulatedTotalAvailable(\r\n ctx,\r\n plantsProductAvailablities.ProductWarehouseInventoryAvailabilities,\r\n plantProduct\r\n )\r\n : 0;\r\n\r\n // Now map it into ProductWarehouseInventoryAvailability type\r\n const productInventoryAvailability = _mapToWarehouseInventoryAvailability(ctx, plantProduct, accumulatedInventorySum);\r\n\r\n // Now add it into shippingProductAvailabilites\r\n shippingProductAvailabilites.ProductWarehouseInventoryAvailabilities?.push(productInventoryAvailability);\r\n });\r\n }\r\n }\r\n\r\n return shippingProductAvailabilites;\r\n } catch (error) {\r\n ctx.telemetry.trace(error);\r\n }\r\n return {};\r\n};\r\n\r\n/**\r\n * The function returns an object of ProductWarehouseInventoryAvailability using\r\n */\r\nconst _mapToWarehouseInventoryAvailability = (\r\n ctx: IActionContext,\r\n productId: number,\r\n totalAvailable: number\r\n): ProductWarehouseInventoryAvailability => {\r\n const {\r\n requestContext: {\r\n app: {\r\n config: { inStockCode, inStockLabel, outOfStockCode, outOfStockLabel }\r\n }\r\n }\r\n } = ctx;\r\n\r\n return {\r\n InventLocationId: 'ECOM',\r\n ProductId: productId,\r\n PhysicalInventory: 0,\r\n TotalAvailable: totalAvailable,\r\n TotalAvailableInventoryLevelLabel: totalAvailable > 0 ? inStockLabel : outOfStockLabel,\r\n TotalAvailableInventoryLevelCode: totalAvailable > 0 ? inStockCode : outOfStockCode,\r\n PhysicalAvailable: totalAvailable,\r\n PhysicalAvailableInventoryLevelLabel: totalAvailable > 0 ? inStockLabel : outOfStockLabel,\r\n PhysicalAvailableInventoryLevelCode: totalAvailable > 0 ? inStockCode : outOfStockCode\r\n };\r\n};\r\n/* VSI Customization - END */\r\nexport default createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/retail-actions/get-availabilities-cartlines',\r\n action: >getAvailabilitiesForCartLineItems,\r\n input: createInput\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\nimport { CategoryHierarchy } from '@msdyn365-commerce/commerce-entities';\r\nimport {\r\n CacheType,\r\n createObservableDataAction,\r\n getCatalogId,\r\n IAction,\r\n IActionContext,\r\n IActionInput,\r\n IAny,\r\n ICreateActionContext,\r\n IGeneric,\r\n IRequestContext\r\n} from '@msdyn365-commerce/core';\r\nimport { CategoriesDataActions } from '@msdyn365-commerce/retail-proxy';\r\nimport { generateCacheKey } from '@msdyn365-commerce-modules/retail-actions';\r\n\r\n/**\r\n * Input for get-categories data action.\r\n */\r\nexport class CategoriesInput implements IActionInput {\r\n public readonly maxItems: number;\r\n\r\n public readonly channelId: number;\r\n\r\n public readonly catalogId?: number;\r\n\r\n private readonly _requestContext: IRequestContext;\r\n\r\n private readonly _mappedToHierarchy: boolean;\r\n\r\n public constructor(context: IRequestContext, mappedToHierarchy: boolean, maxItems?: number) {\r\n this._requestContext = context;\r\n this._mappedToHierarchy = mappedToHierarchy;\r\n this.maxItems = maxItems || 250;\r\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- Required.\r\n this.channelId = context?.apiSettings?.channelId ? Number(context.apiSettings.channelId) : 0;\r\n this.catalogId = getCatalogId(context);\r\n }\r\n\r\n /**\r\n * Get Cache Key.\r\n * @returns - Cache key string.\r\n */\r\n public getCacheKey = (): string =>\r\n generateCacheKey(\r\n this._requestContext.apiSettings,\r\n { key: 'Top', value: this.maxItems },\r\n { key: 'CatalogId', value: this.catalogId }\r\n );\r\n\r\n /**\r\n * Get Cache type Name.\r\n * @returns - Cache name string.\r\n */\r\n public getCacheObjectType = (): string => (this._mappedToHierarchy ? 'CategoryHierarchy' : 'Category');\r\n\r\n /**\r\n * Get Cache type.\r\n * @returns - CacheType enum.\r\n */\r\n public dataCacheType = (): CacheType => 'application';\r\n}\r\n\r\n/**\r\n * Creates the input required to make the retail api call.\r\n * @param inputData -- Input data.\r\n * @returns -- IActionInput.\r\n */\r\nexport const createCategoriesInput = (inputData: ICreateActionContext>): IActionInput => {\r\n const topItems = inputData.config?.topCategories && Number.parseInt(inputData.config.topCategories, 10);\r\n return new CategoriesInput(inputData.requestContext, false, topItems);\r\n};\r\n\r\n/**\r\n * Calls the Retail API and returns all the categories as a flat list.\r\n * @param input - Input.\r\n * @param ctx - Context.\r\n * @returns - CategoryHierarchy.\r\n */\r\nexport async function getCategoryAction(input: CategoriesInput, ctx: IActionContext): Promise {\r\n return ((await CategoriesDataActions.getCategoriesAsync(\r\n {\r\n callerContext: ctx\r\n },\r\n input.channelId,\r\n input.catalogId\r\n )) as unknown) as CategoryHierarchy[];\r\n}\r\n\r\n/**\r\n * The getCategory Data Action.\r\n */\r\nexport const getCategoryActionDataAction = createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/retail-actions/get-categories',\r\n action: getCategoryAction as IAction,\r\n input: createCategoriesInput\r\n});\r\n\r\nexport default getCategoryActionDataAction;\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 { CategoryHierarchy } from '@msdyn365-commerce/commerce-entities';\r\nimport {\r\n CacheType,\r\n createObservableDataAction,\r\n getCatalogId,\r\n IAction,\r\n IActionContext,\r\n IActionInput,\r\n IAny,\r\n ICommerceApiSettings,\r\n ICreateActionContext,\r\n IGeneric,\r\n IRequestContext\r\n} from '@msdyn365-commerce/core';\r\nimport { Category, TextValueTranslation } from '@msdyn365-commerce/retail-proxy';\r\n\r\nimport { getCategoryAction, CategoriesInput as RawCategoriesInput } from './get-categories';\r\nimport { getCategoryUrl } from '@msdyn365-commerce-modules/retail-actions';\r\nimport { generateCacheKey } from '@msdyn365-commerce-modules/retail-actions';\r\n\r\n/**\r\n * Input for get-categories data action.\r\n */\r\nexport class CategoriesInput implements IActionInput {\r\n public readonly maxItems: number;\r\n\r\n public readonly channelId: number;\r\n\r\n public includeRootCategory?: boolean;\r\n\r\n private readonly catalogId: number;\r\n\r\n private readonly sitePath: string;\r\n\r\n private readonly _mappedToHierarchy: boolean;\r\n\r\n private readonly apiSettings: ICommerceApiSettings;\r\n\r\n private readonly locale?: string;\r\n\r\n public constructor(context: IRequestContext, mappedToHierarchy: boolean, maxItems?: number, includeRootCategory?: boolean) {\r\n this._mappedToHierarchy = mappedToHierarchy;\r\n this.includeRootCategory = includeRootCategory;\r\n this.maxItems = maxItems || 250;\r\n this.channelId = context && context.apiSettings && context.apiSettings.channelId ? +context.apiSettings.channelId : 0;\r\n this.sitePath = (context && context.sitePath) || '';\r\n this.apiSettings = context.apiSettings;\r\n this.locale = context.locale || '';\r\n this.catalogId = getCatalogId(context);\r\n }\r\n\r\n public getCacheKey = () =>\r\n generateCacheKey(\r\n this.apiSettings,\r\n { key: 'SitePath', value: this.sitePath },\r\n { key: 'IncludeRootCategory', value: this.includeRootCategory },\r\n { key: 'Top', value: this.maxItems },\r\n { key: 'CatalogId', value: this.catalogId },\r\n { key: 'Locale', value: this.locale }\r\n );\r\n\r\n public getCacheObjectType = () => (this._mappedToHierarchy ? 'CategoryHierarchy' : 'Category');\r\n\r\n //public dataCacheType = (): CacheType => 'request';\r\n\r\n public getLocale = (): string => this.locale || '';\r\n\r\n public dataCacheType = (): CacheType => 'none';\r\n}\r\n\r\nconst getFriendlyName = (locale?: string, nameTranslations?: TextValueTranslation[]): string | undefined => {\r\n let nameTranslation: TextValueTranslation | undefined;\r\n if (locale && nameTranslations && nameTranslations.length > 0) {\r\n nameTranslation = nameTranslations.find(item => item.Language!.toLowerCase() === locale.toLowerCase());\r\n }\r\n\r\n return nameTranslation && nameTranslation.Text;\r\n};\r\n\r\nexport interface ICategoryMap {\r\n [RecordId: number]: CategoryHierarchy;\r\n}\r\n\r\n/**\r\n * Creates a hierarchy of categories based on the ParentCategory property.\r\n * @param categoryList Categories that will be converted into a hierarchy.\r\n * @param ctx\r\n * @param locale\r\n * @returns Hierarchy of categories in array.\r\n */\r\nexport const mapCategoryToHierarchy = (\r\n categoryList: Category[],\r\n ctx: IActionContext,\r\n locale?: string,\r\n includeRootCategory?: boolean\r\n): CategoryHierarchy[] => {\r\n if (!categoryList || categoryList.length === 0) {\r\n return [];\r\n }\r\n\r\n const categoryMap: ICategoryMap = {};\r\n\r\n for (const category of categoryList) {\r\n const localName = getFriendlyName(locale, category.NameTranslations);\r\n const categoryHierarchy = { ...category };\r\n categoryHierarchy.NeutralizedName = category.Name;\r\n categoryHierarchy.Name = localName || categoryHierarchy.NeutralizedName;\r\n categoryMap[category.RecordId] = categoryHierarchy;\r\n }\r\n\r\n let rootCategory: CategoryHierarchy | undefined;\r\n\r\n for (const category of Object.values(categoryMap)) {\r\n const parentId = category.ParentCategory;\r\n category.Url = getCategoryUrl(category, ctx, categoryMap);\r\n if (parentId === 0) {\r\n rootCategory = category;\r\n continue;\r\n }\r\n\r\n const parent = parentId && categoryMap[parentId];\r\n if (parent) {\r\n parent.Children = parent.Children || [];\r\n parent.Children.push(category);\r\n }\r\n }\r\n\r\n if (!rootCategory) {\r\n return [];\r\n }\r\n\r\n if (includeRootCategory) {\r\n const categoryHierarchy: CategoryHierarchy[] = [];\r\n categoryHierarchy.push(rootCategory);\r\n return categoryHierarchy;\r\n }\r\n\r\n return rootCategory.Children ?? [];\r\n};\r\n\r\n/**\r\n * Creates the input required to make the retail api call.\r\n * @param inputData\r\n */\r\nexport const createCategoriesHierarchyInput = (inputData: ICreateActionContext>): IActionInput => {\r\n const topItems = inputData.config && inputData.config.topCategories && Number.parseInt(inputData.config.topCategories, 10);\r\n return new CategoriesInput(inputData.requestContext, true, topItems);\r\n};\r\n\r\n/**\r\n * Calls the Retail API and returns all the categories as a hierarchy.\r\n * @param input\r\n * @param ctx\r\n */\r\nexport async function getCategoryHierarchyAction(input: CategoriesInput, ctx: IActionContext): Promise {\r\n const categories = await getCategoryAction(new RawCategoriesInput(ctx.requestContext, false, input.maxItems), ctx);\r\n const mappedCategories = mapCategoryToHierarchy(categories, ctx, input.getLocale(), input.includeRootCategory);\r\n return mappedCategories;\r\n}\r\n\r\nexport const getCategoryHierarchyActionDataAction = createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/retail-actions/get-categories-hierarchy',\r\n action: >getCategoryHierarchyAction,\r\n input: createCategoriesHierarchyInput\r\n});\r\n\r\nexport default getCategoryHierarchyActionDataAction;\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 { CategoryHierarchy } from '@msdyn365-commerce/commerce-entities';\r\nimport {\r\n createObservableDataAction,\r\n IAction,\r\n IActionContext,\r\n IActionInput,\r\n IAny,\r\n ICreateActionContext,\r\n IGeneric,\r\n IRequestContext\r\n} from '@msdyn365-commerce/core';\r\n\r\nimport { CategoriesInput } from '@msdyn365-commerce-modules/retail-actions';\r\n// import { } from './dobbies-get-categories-hierarchy';\r\nimport { ArrayExtensions } from '@msdyn365-commerce-modules/retail-actions';\r\nimport { CacheType } from '@msdyn365-commerce/retail-proxy';\r\nimport { getCategoryHierarchyAction, CategoriesInput as RawCategoriesInput } from './get-categories-hierarchy.override.action';\r\n/**\r\n * Action Input Class for get-current-category-hierarchy.\r\n */\r\nexport class CurrentCategoryHierarchyInput extends CategoriesInput {\r\n public activeCategoryId: number;\r\n\r\n public constructor(context: IRequestContext, mappedToHierarchy: boolean, maxItems?: number, activeCategoryId?: number) {\r\n super(context, mappedToHierarchy, maxItems);\r\n const defaultActiveCategoryId = 0;\r\n this.activeCategoryId = activeCategoryId ?? defaultActiveCategoryId;\r\n }\r\n\r\n // @ts-expect-error: Overriding cache object type\r\n public getCacheObjectType = () => 'CurrentCategoryHierarchy';\r\n\r\n public getCacheKey = () => `${this.activeCategoryId}-${this.channelId}`;\r\n\r\n public dataCacheType = (): CacheType => 'none';\r\n}\r\n\r\n/**\r\n * Creates the input required for the data action.\r\n * @param inputData\r\n */\r\nexport const createCategoriesHierarchyInput = (inputData: ICreateActionContext>): IActionInput => {\r\n const topItems = inputData.config?.topCategories && Number.parseInt(inputData.config.topCategories, 10);\r\n let activeCategoryId =\r\n inputData.requestContext.urlTokens.pageType === 'Category' ? inputData.requestContext.urlTokens.itemId : undefined;\r\n activeCategoryId = activeCategoryId ?? inputData.requestContext.query?.categoryId;\r\n const activeCategoryParsedId = activeCategoryId ? Number.parseInt(activeCategoryId, 10) : undefined;\r\n\r\n return new CurrentCategoryHierarchyInput(inputData.requestContext, true, topItems, activeCategoryParsedId);\r\n};\r\n\r\n/**\r\n * Finds the given category in the list of categories and returns an array with the info on where it's located.\r\n * @param categories - Categories list to search from.\r\n * @param categoryId - The category id to find.\r\n * @returns A list of categories starting from the given category id, ending up the root parent.\r\n */\r\nconst findCategoryHierarchy = (categories: CategoryHierarchy[], categoryId: number): CategoryHierarchy[] | null => {\r\n for (const category of categories) {\r\n if (category.RecordId === categoryId) {\r\n return [category];\r\n }\r\n\r\n if (ArrayExtensions.hasElements(category.Children)) {\r\n const innerCategoryHierarchy = findCategoryHierarchy(category.Children, categoryId);\r\n if (ArrayExtensions.hasElements(innerCategoryHierarchy)) {\r\n innerCategoryHierarchy.push(category);\r\n return innerCategoryHierarchy;\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n};\r\n\r\n/**\r\n * Get the hierarchy of categories that are currently active as a parent -> child array.\r\n * Return will be as follows: [ParentCategory, Child, SubChild, SubSubChild].\r\n * @param input\r\n * @param ctx\r\n */\r\nexport async function getCurrentCategoryHierarchyAction(\r\n input: CurrentCategoryHierarchyInput,\r\n ctx: IActionContext\r\n): Promise {\r\n // try {\r\n //const fullCategoryHierarchy = await getCategoriesHierarchy(new CategoriesInput(ctx.requestContext, true, input.maxItems), ctx);\r\n // const fullCategoryHierarchy = await getCategoriesHierarchy(new CategoriesInput(ctx.requestContext, true, input.maxItems), ctx);\r\n const fullCategoryHierarchyWithCallableAction = await getCategoryHierarchyAction(new RawCategoriesInput(ctx.requestContext, true, input.maxItems), ctx);\r\n const categoryArray = findCategoryHierarchy(fullCategoryHierarchyWithCallableAction, input.activeCategoryId) ?? [];\r\n const sortedCategoryArray = categoryArray.reverse();\r\n return sortedCategoryArray;\r\n}\r\n\r\nexport const getCurrentCategoryHierarchyActionDataAction = createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/retail-actions/get-current-category-hierarchy',\r\n action: getCurrentCategoryHierarchyAction as IAction,\r\n input: createCategoriesHierarchyInput\r\n});\r\n\r\nexport default getCurrentCategoryHierarchyActionDataAction;\r\n","/*---------------------------------------------------------------------------------------------\r\n * Copyright (c) Microsoft Corporation. All rights reserved.\r\n * Licensed under the MIT License. See License.txt in the project root for license information.\r\n *--------------------------------------------------------------------------------------------*/\r\n\r\nimport * as Msdyn365 from '@msdyn365-commerce/core';\r\nimport { Address } from '@msdyn365-commerce/retail-proxy';\r\n\r\n/**\r\n * GetCustomerAddress Input Action\r\n */\r\n\r\nexport class GetCustomerAddressInput implements Msdyn365.IActionInput {\r\n // TODO: Determine if the results of this get action should cache the results and if so provide\r\n // a cache object type and an appropriate cache key\r\n public getCacheKey = () => `customerAddress`;\r\n public getCacheObjectType = () => 'customerAddress';\r\n public dataCacheType = (): Msdyn365.CacheType => 'request';\r\n}\r\n\r\n// TODO: Create a data model here or import one to capture the response of the action\r\nexport interface IGetCustomerAddressData {\r\n addresses: Address[] | undefined;\r\n}\r\n\r\n/**\r\n * TODO: Use this function to create the input required to make the action call\r\n */\r\nconst createInput = (args: Msdyn365.ICreateActionContext): Msdyn365.IActionInput => {\r\n return new GetCustomerAddressInput();\r\n};\r\n\r\n/**\r\n * TODO: Use this function to call your action and process the results as needed\r\n */\r\nasync function action(input: GetCustomerAddressInput, ctx: Msdyn365.IActionContext): Promise {\r\n return { addresses: undefined };\r\n}\r\n\r\nexport default Msdyn365.createObservableDataAction({\r\n action: >action,\r\n id: 'GetCustomerAddress',\r\n input: createInput\r\n});\r\n","import {\r\n CacheType,\r\n createObservableDataAction,\r\n IAction,\r\n IActionContext,\r\n IActionInput,\r\n IAny,\r\n ICreateActionContext,\r\n IGeneric\r\n} from '@msdyn365-commerce/core';\r\nimport { FeatureState } from '@msdyn365-commerce/retail-proxy';\r\n\r\nimport { getFeatureStatesAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/StoreOperationsDataActions.g';\r\n\r\n/**\r\n * Input class for the getFeatureState data action\r\n */\r\nexport class FeatureStateInput implements IActionInput {\r\n public readonly featureNames: string[] = [\r\n 'Dynamics.AX.Application.RetailB2BEcommerceFeature',\r\n 'Dynamics.AX.Application.RetailDefaultOrderQuantityLimitsFeature',\r\n 'Dynamics.AX.Application.RetailMultiplePickupDeliveryModeFeature',\r\n 'Dynamics.AX.Application.RetailSearchPriceRangeFeature'\r\n ];\r\n\r\n public getCacheKey = () => `FeatureState`;\r\n public getCacheObjectType = () => 'FeatureState';\r\n public dataCacheType = (): CacheType => 'application';\r\n}\r\n\r\n/**\r\n * createInput method for the getFeatureState method\r\n * @param inputData The input data passed to the createInput method\r\n */\r\nexport const createGetFeatureStateInput = (inputData: ICreateActionContext>): IActionInput => {\r\n return new FeatureStateInput();\r\n};\r\n\r\n/**\r\n * The action method for the getFeatureState data action\r\n * @param input The action input\r\n * @param ctx The action context\r\n */\r\nexport async function getFeatureStateAction(input: FeatureStateInput, ctx: IActionContext): Promise {\r\n const featureState = await getFeatureStatesAsync({ callerContext: ctx }, input.featureNames);\r\n return featureState;\r\n}\r\n\r\n/**\r\n * The getFeatureState data action\r\n * Gets the feature state via the read RetailServer API\r\n * Returns address information associated with the retrieved customer\r\n */\r\nexport const getFeatureStateActionDataAction = createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/retail-actions/get-feature-state',\r\n action: >getFeatureStateAction,\r\n input: createGetFeatureStateInput\r\n});\r\nexport default getFeatureStateActionDataAction;\r\n","/*--------------------------------------------------------------\r\n * Copyright (c) Microsoft Corporation. All rights reserved.\r\n * See License.txt in the project root for license information.\r\n *--------------------------------------------------------------*/\r\n\r\nimport {\r\n CacheType,\r\n createObservableDataAction,\r\n IAction,\r\n IActionContext,\r\n IActionInput,\r\n IAny,\r\n ICreateActionContext,\r\n IGeneric\r\n} from '@msdyn365-commerce/core';\r\nimport {\r\n ChannelDeliveryOption,\r\n FeatureState,\r\n DeliveryModeTypeFilter,\r\n ItemAvailability,\r\n OrgUnitAvailability,\r\n OrgUnitLocation,\r\n ProductWarehouseInventoryInformation,\r\n SearchArea,\r\n StoreHours\r\n} from '@msdyn365-commerce/retail-proxy';\r\nimport {\r\n getChannelDeliveryOptionsAsync,\r\n getOrgUnitLocationsByAreaAsync,\r\n getStoreHoursAsync\r\n} from '@msdyn365-commerce/retail-proxy/dist/DataActions/OrgUnitsDataActions.g';\r\nimport { getEstimatedAvailabilityAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\r\nimport { IFullOrgUnitAvailability } from './utilities/full-org-unit-availability';\r\nimport { DeliveryMode, IProductInventoryInformation } from './utilities/product-inventory-information';\r\nimport { FeatureStateInput, getFeatureStateAction } from './get-feature-state.override.action';\r\nimport { createInventoryAvailabilitySearchCriteria, mapProductInventoryInformation } from '@msdyn365-commerce-modules/retail-actions';\r\n\r\n/**\r\n * Get selected variant action input class.\r\n */\r\nexport class GetFullAvailableInventoryNearbyInput implements IActionInput {\r\n public latitude?: number;\r\n\r\n public longitude?: number;\r\n\r\n public radius?: number;\r\n\r\n public productId?: number;\r\n\r\n public DistanceUnitValue?: number;\r\n\r\n public IgnoreLocation?: boolean;\r\n\r\n public ExcludeLocations?: (number | undefined)[];\r\n\r\n constructor(\r\n _productId?: number,\r\n _latitude?: number,\r\n _longitude?: number,\r\n _radius?: number,\r\n _DistanceUnitValue?: number,\r\n _IgnoreLocation?: boolean,\r\n _ExcludeLocations?: (number | undefined)[]\r\n ) {\r\n this.productId = _productId;\r\n this.latitude = _latitude;\r\n this.longitude = _longitude;\r\n this.radius = _radius;\r\n this.DistanceUnitValue = _DistanceUnitValue;\r\n this.IgnoreLocation = _IgnoreLocation;\r\n this.ExcludeLocations = _ExcludeLocations;\r\n }\r\n\r\n public getCacheKey = () => 'GetFullAvailableInventoryNearbyInputCache';\r\n\r\n public getCacheObjectType = () => 'GetFullAvailableInventoryNearbyInput';\r\n\r\n public dataCacheType = (): CacheType => 'none';\r\n}\r\n\r\n/**\r\n * CreateInput method for the getSelectedVariant data action.\r\n * @param inputData - The input data passed to the createInput method.\r\n * @returns GetFullAvailableInventoryNearbyInput - The action input.\r\n */\r\nexport const createGetFullAvailableInventoryNearbyInput = (\r\n inputData: ICreateActionContext>\r\n): GetFullAvailableInventoryNearbyInput => {\r\n return new GetFullAvailableInventoryNearbyInput();\r\n};\r\n\r\n/**\r\n * Calls the Retail Feature State API and returns a list of feature with isEnabled flag.\r\n * @param context - The context.\r\n * @returns FeatureState - The feature state.\r\n */\r\nexport async function getFeatureState(context: IActionContext): Promise {\r\n return getFeatureStateAction(new FeatureStateInput(), context);\r\n}\r\n\r\n/**\r\n * Action method for the getSelectedVariant data aciton.\r\n * @param input - The action input class.\r\n * @param ctx - The action context.\r\n * @returns IFullOrgUnitAvailability - The full org unit availability.\r\n */\r\nexport async function getFullAvailableInventoryNearbyAction(\r\n input: GetFullAvailableInventoryNearbyInput,\r\n ctx: IActionContext\r\n): Promise {\r\n // No valid product we want to return undefined so module knows there are no results yet\r\n if (!input.productId) {\r\n return undefined;\r\n }\r\n\r\n if (((!input.radius && input.radius !== 0) || !input.latitude || !input.longitude) && !input.IgnoreLocation) {\r\n // No valid location we want to return empty array so module can show no locations message\r\n return [];\r\n }\r\n\r\n const searchArea: SearchArea = {\r\n Latitude: input.latitude,\r\n Longitude: input.longitude,\r\n Radius: input.radius,\r\n DistanceUnitValue: input.DistanceUnitValue || 0 // 0 is miles\r\n };\r\n\r\n const featureState = await getFeatureState(ctx);\r\n const retailMulitplePickupMFeatureState = featureState?.find(\r\n item => item.Name === 'Dynamics.AX.Application.RetailMultiplePickupDeliveryModeFeature'\r\n )?.IsEnabled;\r\n const searchCriteria = createInventoryAvailabilitySearchCriteria(ctx, [input.productId], false, true, searchArea, DeliveryMode.pickup);\r\n return getEstimatedAvailabilityAsync({ callerContext: ctx }, searchCriteria)\r\n .then(async (productWarehouseInformation: ProductWarehouseInventoryInformation) => {\r\n // For store selector, inventory should always come from an individual store\r\n const productInventoryInformation = mapProductInventoryInformation(\r\n ctx,\r\n productWarehouseInformation.ProductWarehouseInventoryAvailabilities\r\n );\r\n return getOrgUnitLocationsByAreaAsync({ callerContext: ctx }, searchArea, DeliveryModeTypeFilter.None)\r\n .then(async (stores: OrgUnitLocation[]) => {\r\n // Constructing a store mapping based on the InventoryId.\r\n const storeMap = new Map();\r\n stores.forEach(store => {\r\n if (store.InventoryLocationId) {\r\n storeMap.set(store.InventoryLocationId, store);\r\n }\r\n });\r\n\r\n let locationDeliveryOptions: ChannelDeliveryOption[] | undefined = [];\r\n\r\n // If multiple pickup mode is enable then call getchanneldeliveryoption\r\n if (retailMulitplePickupMFeatureState) {\r\n const orgUnitChannel = stores.map(store => store.ChannelId);\r\n locationDeliveryOptions = await _getLocationPickUpDeliveryModes(orgUnitChannel, ctx);\r\n }\r\n\r\n const excludedStores = input.ExcludeLocations ?? [];\r\n const filteredStores = stores\r\n .filter(store => !excludedStores.includes(store.ChannelId))\r\n .sort((a, b) => a.OrgUnitName!.localeCompare(b.OrgUnitName!));\r\n const availabilityPromiseList = filteredStores.map(store => {\r\n const locationDeliveryOption = locationDeliveryOptions?.find(\r\n _channeldeliveryoption => _channeldeliveryoption.ChannelId === store.ChannelId\r\n );\r\n return _getAvailabilityWithHours(store, productInventoryInformation, storeMap, ctx, locationDeliveryOption);\r\n });\r\n\r\n return Promise.all(availabilityPromiseList);\r\n })\r\n .catch((error: Error) => {\r\n ctx.trace('[GetFullAvailableInventoryNearby] error getting Available Inventory Nearby');\r\n ctx.trace(error.message);\r\n ctx.telemetry.error(error.message);\r\n ctx.telemetry.debug('[GetFullAvailableInventoryNearby] error getting Available Inventory Nearby');\r\n return [];\r\n });\r\n })\r\n .catch((error: Error) => {\r\n ctx.trace(\r\n '[GetFullAvailableInventoryNearby][getEstimatedAvailabilityAsync] error getting availability product warehouse information.'\r\n );\r\n ctx.trace(error.message);\r\n ctx.telemetry.error(error.message);\r\n ctx.telemetry.debug(\r\n '[GetFullAvailableInventoryNearby][getEstimatedAvailabilityAsync] error getting availability product warehouse information.'\r\n );\r\n return [];\r\n });\r\n}\r\n\r\n/**\r\n * Action method that obtains the store information along with store hours and product availability.\r\n * @param orgUnitLocation - The org unit location.\r\n * @param productInventoryInformation - The product inventory information.\r\n * @param storeMap - A map that contains store information group by the inventory location id.\r\n * @param ctx The action context.\r\n * @param channelDeleiveryOptions - The channel delivery options.\r\n * @returns IFullOrgUnitAvailability - The full org unit availability.\r\n */\r\nasync function _getAvailabilityWithHours(\r\n orgUnitLocation: OrgUnitLocation,\r\n productInventoryInformation: IProductInventoryInformation[],\r\n storeMap: Map,\r\n ctx: IActionContext,\r\n channelDeleiveryOptions: ChannelDeliveryOption | undefined\r\n): Promise {\r\n if (!orgUnitLocation || !orgUnitLocation.OrgUnitNumber) {\r\n return { OrgUnitAvailability: undefined };\r\n }\r\n\r\n return getStoreHoursAsync({ callerContext: ctx }, orgUnitLocation.OrgUnitNumber)\r\n .then((hours: StoreHours) => {\r\n const itemAvailabilities: ItemAvailability[] = [];\r\n if (productInventoryInformation && storeMap) {\r\n productInventoryInformation.forEach(element => {\r\n if (\r\n element.InventLocationId &&\r\n storeMap.has(element.InventLocationId) &&\r\n element.InventLocationId === orgUnitLocation.InventoryLocationId\r\n ) {\r\n itemAvailabilities.push({ AvailableQuantity: element.ProductAvailableQuantity?.AvailableQuantity });\r\n }\r\n });\r\n }\r\n\r\n const availability: OrgUnitAvailability = {\r\n OrgUnitLocation: orgUnitLocation,\r\n ItemAvailabilities: itemAvailabilities\r\n };\r\n\r\n if (hours && !(hours instanceof Error)) {\r\n return {\r\n OrgUnitAvailability: availability,\r\n StoreHours: hours,\r\n ProductInventoryInformation: productInventoryInformation,\r\n OrgUnitPickUpDeliveryModes: channelDeleiveryOptions\r\n };\r\n }\r\n\r\n return {\r\n OrgUnitAvailability: availability,\r\n ProductInventoryInformation: productInventoryInformation,\r\n OrgUnitPickUpDeliveryModes: channelDeleiveryOptions\r\n };\r\n })\r\n .catch((error: Error) => {\r\n ctx.trace('[GetFullAvailableInventoryNearby] error getting availability with hours');\r\n ctx.trace(error.message);\r\n ctx.telemetry.exception(error);\r\n ctx.telemetry.debug('[GetFullAvailableInventoryNearby] error getting availability with hours');\r\n return { OrgUnitAvailability: {} };\r\n });\r\n}\r\n\r\n/**\r\n * Action method that obtains the channel delivery option information.\r\n * @param channelCollection - The org unit channel Id list.\r\n * @param ctx - The action context.\r\n * @returns ChannelDeliveryOption - The channel delivery option collection.\r\n */\r\nasync function _getLocationPickUpDeliveryModes(\r\n channelCollection: (number | undefined)[],\r\n ctx: IActionContext\r\n): Promise {\r\n if (channelCollection?.length === 0 || channelCollection === undefined) {\r\n return undefined;\r\n }\r\n\r\n const channelIdList: number[] = [];\r\n channelCollection?.map(id => {\r\n if (id !== undefined) {\r\n channelIdList.push(id);\r\n }\r\n });\r\n\r\n // To get all channel pickup delivery mode filterOption should be 4\r\n return getChannelDeliveryOptionsAsync({ callerContext: ctx }, channelIdList, 4)\r\n .then((channelDeliveryOptions: ChannelDeliveryOption[]) => {\r\n if (channelDeliveryOptions && !(channelDeliveryOptions instanceof Error)) {\r\n return channelDeliveryOptions;\r\n }\r\n\r\n return undefined;\r\n })\r\n .catch((error: Error) => {\r\n ctx.trace(\r\n '[GetFullAvailableInventoryNearby][getChannelDeliveryOptionsAsync] error getting availability with channel delivery options'\r\n );\r\n ctx.trace(error.message);\r\n ctx.telemetry.exception(error);\r\n ctx.telemetry.debug(\r\n '[GetFullAvailableInventoryNearby] [getChannelDeliveryOptionsAsync] error getting availability with channel delivery options'\r\n );\r\n return [];\r\n });\r\n}\r\n\r\n/**\r\n * The complete getFullAvailableInventoryNearby data action.\r\n */\r\nexport const getFullAvailableInventoryNearbyActionDataAction = createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/retail-actions/get-full-available-inventory-nearby',\r\n action: >getFullAvailableInventoryNearbyAction,\r\n input: createGetFullAvailableInventoryNearbyInput\r\n});\r\n\r\nexport default getFullAvailableInventoryNearbyActionDataAction;\r\n","/*--------------------------------------------------------------\r\n * Copyright (c) Microsoft Corporation. All rights reserved.\r\n * See License.txt in the project root for license information.\r\n *--------------------------------------------------------------*/\r\n\r\nimport {\r\n CacheType,\r\n createObservableDataAction,\r\n IAction,\r\n IActionContext,\r\n IActionInput,\r\n ICommerceApiSettings,\r\n ICreateActionContext\r\n} from '@msdyn365-commerce/core';\r\nimport { LoyaltyCard } from '@msdyn365-commerce/retail-proxy';\r\nimport {\r\n getCustomerLoyaltyCardsAsync,\r\n getLoyaltyCardAsync\r\n} from '@msdyn365-commerce/retail-proxy/dist/DataActions/StoreOperationsDataActions.g';\r\nimport { buildCacheKey } from '@msdyn365-commerce-modules/retail-actions';\r\n/**\r\n * Input class for the getLoyaltyCard data action.\r\n */\r\nexport class GetLoyaltyCardInput implements IActionInput {\r\n public userAccountNumber?: string;\r\n\r\n public apiSettings: ICommerceApiSettings;\r\n\r\n constructor(apiSettings: ICommerceApiSettings, userAccountNumber?: string) {\r\n this.userAccountNumber = userAccountNumber;\r\n this.apiSettings = apiSettings;\r\n }\r\n\r\n public getCacheKey = () => buildCacheKey(`GetLoyaltyCard-${this.userAccountNumber}`, this.apiSettings);\r\n\r\n public getCacheObjectType = () => 'GetLoyaltyCard';\r\n\r\n public dataCacheType = (): CacheType => 'request';\r\n}\r\n\r\n/**\r\n * CreateInput method for the getLoyaltyCard method.\r\n * @param inputData The input data passed to the createInput method.\r\n */\r\nexport const createGetLoyaltyCardInput = (inputData: ICreateActionContext): GetLoyaltyCardInput => {\r\n const { requestContext } = inputData;\r\n if (!requestContext.user.isAuthenticated) {\r\n throw new Error('Unable to create get loyalty card input. User is not authenticated.');\r\n }\r\n\r\n return new GetLoyaltyCardInput(inputData.requestContext.apiSettings, inputData.requestContext.user.customerAccountNumber);\r\n};\r\n\r\n/**\r\n * The action method for the getLoyaltyCard data action.\r\n * @param input The action input.\r\n * @param ctx The action context.\r\n */\r\nexport async function getLoyaltyAction(input: GetLoyaltyCardInput, ctx: IActionContext): Promise {\r\n return getCustomerLoyaltyCardsAsync({ callerContext: ctx, queryResultSettings: {} }, input.userAccountNumber || null)\r\n .then(cards => {\r\n if (!cards || cards.length === 0) {\r\n return {};\r\n }\r\n\r\n const tempCard = cards.find(card => card.CardTenderTypeValue !== 3);\r\n if (!tempCard) throw new Error('Unable to find a non-blocked card');\r\n const firstCard = tempCard;\r\n // const firstCard = cards[0];\r\n\r\n return getLoyaltyCardAsync({ callerContext: ctx }, firstCard.CardNumber)\r\n .then(card => {\r\n card.LoyaltyEnrollmentDate = firstCard.LoyaltyEnrollmentDate;\r\n card.LoyaltyEnrollmentDateLocal = firstCard.LoyaltyEnrollmentDateLocal;\r\n return card;\r\n })\r\n\r\n .catch(error => {\r\n ctx.telemetry.exception(error);\r\n ctx.telemetry.debug('Unable to get loyalty card');\r\n throw new Error('Unable to get loyalty card');\r\n });\r\n })\r\n .catch(error => {\r\n ctx.telemetry.exception(error.message);\r\n ctx.telemetry.debug('Unable to get customers loyalty card');\r\n throw new Error('Unable to get customers loyalty card');\r\n });\r\n}\r\n\r\n/**\r\n * The getLoyaltyCard data action\r\n * Returns the loyalty card belonging to the customer.\r\n */\r\nexport const getLoyaltyActionDataAction = createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/retail-actions/get-loyalty-card',\r\n action: >getLoyaltyAction,\r\n input: <(args: ICreateActionContext) => IActionInput>createGetLoyaltyCardInput\r\n});\r\n\r\nexport default getLoyaltyActionDataAction;\r\n","import {\r\n getSelectedProductIdFromActionInput,\r\n getSelectedVariant,\r\n IProductInventoryInformation,\r\n // mapProductInventoryInformation,\r\n SelectedVariantInput\r\n} from '@msdyn365-commerce-modules/retail-actions';\r\nimport { mapProductInventoryInformation } from '../utilities/inventory/product-inventory-utils';\r\n\r\nimport {\r\n CacheType,\r\n createObservableDataAction,\r\n IAction,\r\n IActionContext,\r\n IActionInput,\r\n IAny,\r\n ICreateActionContext,\r\n IGeneric\r\n} from '@msdyn365-commerce/core';\r\nimport { ProductWarehouseInventoryAvailability, ReleasedProductType } from '@msdyn365-commerce/retail-proxy';\r\nimport {\r\n getAttributeValuesAsync,\r\n getEstimatedAvailabilityAsync\r\n} from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\r\nimport { ProductAvailableQuantity } from '@msdyn365-commerce/retail-proxy/dist/Entities/CommerceTypes.g';\r\n/**\r\n * Input class for the getProductAvailabilitiesForSelectedVariant Data Action\r\n */\r\nexport class ProductAvailabilitiesForSelectedVariantInput implements IActionInput {\r\n public productId: number;\r\n public channelId: number;\r\n\r\n constructor(productId: number | string, channelId: number) {\r\n this.productId = typeof productId === 'string' ? +productId : productId;\r\n this.channelId = channelId;\r\n }\r\n\r\n public getCacheKey = () => `ProductAvailabilitiesForSelectedVariant`;\r\n public getCacheObjectType = () => 'ProductAvailabilities';\r\n public dataCacheType = (): CacheType => 'none';\r\n}\r\n\r\n/**\r\n * createInput method for the getProductAvailabilitiesForSelectedVariant data action.\r\n * @param inputData The input data passed to the createInput method\r\n */\r\nexport const createProductAvailabilitiesForSelectedVariantInput = (\r\n inputData: ICreateActionContext>\r\n): ProductAvailabilitiesForSelectedVariantInput => {\r\n const productId = getSelectedProductIdFromActionInput(inputData);\r\n\r\n if (productId) {\r\n return new ProductAvailabilitiesForSelectedVariantInput(+productId, +inputData.requestContext.apiSettings.channelId);\r\n } else {\r\n throw new Error('Unable to create ProductAvailabilitiesForSelectedVariantInput, no productId found on module config or query');\r\n }\r\n};\r\n\r\n/**\r\n * The action method for the getProductAvailabilitiesForSelectedVariant data action\r\n */\r\n// tslint:disable-next-line: max-func-body-length\r\nexport async function getProductAvailabilitiesForSelectedVariantAction(\r\n input: ProductAvailabilitiesForSelectedVariantInput,\r\n ctx: IActionContext\r\n): Promise {\r\n const selectedVariantInput = new SelectedVariantInput(input.productId, input.channelId);\r\n /* Upgraded to 10.0.16 - START */\r\n // tslint:disable-next-line:prefer-type-cast\r\n const PRODUCTASSERVICE = 2 as ReleasedProductType.Service;\r\n /* Upgraded to 10.0.16 - END */\r\n return getSelectedVariant(selectedVariantInput, ctx)\r\n .then(async productResult => {\r\n if (\r\n productResult &&\r\n /* Upgraded to 10.0.16 - START - Add following condition */\r\n // As we just have master products only so will comment this condition\r\n productResult.ItemTypeValue !== PRODUCTASSERVICE /* && productResult.ProductTypeValue !== ProductType.Master */\r\n /* Upgraded to 10.0.16 - END */\r\n ) {\r\n try {\r\n /* VSI Customization - START - 09/04/21 */\r\n // Check if product is vendorShipped we dont need getEstimatedAvailabilityAsync call as we'll just display instock with maxCartLineQty limit\r\n const {\r\n requestContext: {\r\n app: {\r\n config: { maxQuantityForCartLineItem, fulfillmentAttributeName, fulfillmentAttributeTextValue }\r\n }\r\n }\r\n } = ctx;\r\n\r\n let productInventoryInformation: IProductInventoryInformation[];\r\n\r\n // Make vendorShip products in stock by default\r\n const productAttributes = await getAttributeValuesAsync(\r\n { callerContext: ctx },\r\n input.productId,\r\n input.channelId,\r\n ctx.requestContext.apiSettings.catalogId\r\n );\r\n const isVendorShipAttribute = productAttributes.find(attribute => {\r\n const attributeName = attribute.Name && attribute.Name.trim().toLowerCase();\r\n return attributeName === 'isvendershipproduct';\r\n });\r\n\r\n /* VSI Customization - START - Check PreSale product attribute for TotalAvailable */\r\n const isPreSale = productAttributes.find(attribute => {\r\n const attributeName = attribute.Name && attribute.Name.trim().toLowerCase();\r\n return attributeName === 'presale' && attribute.TextValue === \"Yes\";\r\n });\r\n /* VSI-Customization -- END */\r\n\r\n if (\r\n isVendorShipAttribute &&\r\n isVendorShipAttribute.TextValue &&\r\n isVendorShipAttribute.TextValue.toLowerCase() === 'yes'\r\n ) {\r\n const vendorShipProductInventory: IProductInventoryInformation[] = [];\r\n\r\n vendorShipProductInventory.push({\r\n IsProductAvailable: true,\r\n ProductAvailableQuantity: {\r\n AvailableQuantity: maxQuantityForCartLineItem,\r\n ProductId: productResult.RecordId\r\n }\r\n });\r\n\r\n return vendorShipProductInventory;\r\n } else {\r\n const attributeName = fulfillmentAttributeName\r\n ? fulfillmentAttributeName\r\n .toString()\r\n .toLowerCase()\r\n .trim()\r\n : 'fulfillmenttype';\r\n const attributeTextValue = fulfillmentAttributeTextValue\r\n ? fulfillmentAttributeTextValue\r\n .toString()\r\n .toLowerCase()\r\n .trim()\r\n : 'plants';\r\n\r\n const fulfillmentTypeAttribute =\r\n productAttributes &&\r\n productAttributes.find(attribute => {\r\n return attribute?.Name?.toLowerCase() === attributeName;\r\n });\r\n const isPlantFulfillment =\r\n fulfillmentTypeAttribute && fulfillmentTypeAttribute.TextValue?.toLowerCase() === attributeTextValue;\r\n const isPlantCategory = isPlantFulfillment ? true : false;\r\n /* VSI Customization - END - 09/04/21 */\r\n return getEstimatedAvailabilityAsync(\r\n { callerContext: ctx },\r\n {\r\n ProductIds: [productResult.RecordId],\r\n DefaultWarehouseOnly: !isPlantCategory,\r\n FilterByChannelFulfillmentGroup: isPlantCategory\r\n }\r\n ).then(async response => {\r\n if (\r\n response &&\r\n response.ProductWarehouseInventoryAvailabilities &&\r\n response.ProductWarehouseInventoryAvailabilities.length\r\n ) {\r\n if (isPlantCategory) {\r\n // Get ProductWarehouseInventoryAvailabilities as a sum of all warehouse inventory and use it\r\n const accumulatedAvailability = getAccumulatedAvailability(\r\n ctx,\r\n response.ProductWarehouseInventoryAvailabilities\r\n );\r\n\r\n productInventoryInformation = mapProductInventoryInformation(ctx, accumulatedAvailability);\r\n } else {\r\n productInventoryInformation = mapProductInventoryInformation(\r\n ctx,\r\n response.ProductWarehouseInventoryAvailabilities,\r\n isPreSale ? \"totalAvailable\" : \"\"\r\n );\r\n }\r\n }\r\n /* VSI Customization - END */\r\n return productInventoryInformation;\r\n });\r\n }\r\n } catch (error) {\r\n ctx.trace((error as Error).message);\r\n ctx.telemetry.exception(error as Error);\r\n ctx.telemetry.debug(`[getEstimatedAvailabilityAsync]Error executing action`);\r\n throw new Error('[getEstimatedAvailabilityAsync]Error executing action');\r\n }\r\n }\r\n return [];\r\n })\r\n .catch((error: Error) => {\r\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument -- can't assign type to the error variable.\r\n ctx.telemetry.exception(error);\r\n ctx.telemetry.debug('[getPriceForSelectedVariantAction]Error executing action');\r\n return undefined;\r\n });\r\n}\r\n\r\n/**\r\n * The function that maps a ProductWareHouse object into a ProductAvailabilityQuantity\r\n */\r\nexport function mergeProductWarehouseToProductAvailabities(\r\n productsWarehouseInventory: ProductWarehouseInventoryAvailability[]\r\n): ProductAvailableQuantity[] {\r\n const productAvailable: ProductAvailableQuantity[] = [];\r\n if (productsWarehouseInventory && productsWarehouseInventory.length > 0) {\r\n for (const product of productsWarehouseInventory) {\r\n if (product.TotalAvailable !== undefined && product.ProductId !== undefined) {\r\n productAvailable.push({ ProductId: product.ProductId, AvailableQuantity: product.TotalAvailable });\r\n }\r\n }\r\n }\r\n return productAvailable;\r\n}\r\n\r\n/**\r\n * The function that adds all warehouse's PhysicalAvailable for plants Category and return that ProductWarehouseInventoryAvailabilities\r\n */\r\nconst getAccumulatedAvailability = (\r\n ctx: IActionContext,\r\n ProductWarehouseInventoryAvailabilities: ProductWarehouseInventoryAvailability[]\r\n) => {\r\n // Just check inventory in warehouseIdsForFulfillment\r\n const {\r\n requestContext: {\r\n app: {\r\n config: { warehouseIdsForFulfillment }\r\n }\r\n }\r\n } = ctx;\r\n\r\n let accumulatedProductCount = 0;\r\n const fulfillmentStores: string[] | undefined = warehouseIdsForFulfillment; // ['S011', 'S040']\r\n // We'll just check the PhysicalAvailable for plants fulfillment\r\n ProductWarehouseInventoryAvailabilities.filter(availability => {\r\n // First check if it is one of the warehouseIdsForFulfillment, only then add inventory\r\n return (\r\n fulfillmentStores &&\r\n fulfillmentStores.find(store => {\r\n return availability.InventLocationId && availability.InventLocationId.toLowerCase() === store.toLowerCase();\r\n })\r\n );\r\n }).map(availability => {\r\n if (availability.PhysicalAvailable) {\r\n accumulatedProductCount += availability.PhysicalAvailable;\r\n }\r\n });\r\n // Now just create an object with this product availability info and returns it\r\n return mapWarehouseAvailabilityForAccumulatedCount(ctx, ProductWarehouseInventoryAvailabilities, accumulatedProductCount);\r\n};\r\n\r\n/**\r\n * The function that creates an object of type ProductWarehouseInventoryAvailability with new provided accumulatedProductCount\r\n * and return it as an array of type\r\n */\r\nconst mapWarehouseAvailabilityForAccumulatedCount = (\r\n ctx: IActionContext,\r\n ProductWarehouseInventoryAvailabilities: ProductWarehouseInventoryAvailability[],\r\n accumulatedProductCount: number\r\n): ProductWarehouseInventoryAvailability[] => {\r\n // Use labels from app.settings for both in stock & out of stock cases\r\n const {\r\n requestContext: {\r\n app: {\r\n config: { inStockCode, inStockLabel, outOfStockCode, outOfStockLabel }\r\n }\r\n }\r\n } = ctx;\r\n\r\n const productAvailability = ProductWarehouseInventoryAvailabilities[0];\r\n\r\n return [\r\n {\r\n ProductId: productAvailability.ProductId,\r\n DataAreaId: productAvailability.DataAreaId,\r\n PhysicalInventory: 0,\r\n TotalAvailable: accumulatedProductCount,\r\n TotalAvailableInventoryLevelLabel: accumulatedProductCount > 0 ? inStockLabel : outOfStockCode,\r\n TotalAvailableInventoryLevelCode: accumulatedProductCount > 0 ? inStockCode : outOfStockLabel,\r\n PhysicalAvailable: accumulatedProductCount,\r\n PhysicalAvailableInventoryLevelLabel: accumulatedProductCount > 0 ? inStockLabel : outOfStockLabel,\r\n PhysicalAvailableInventoryLevelCode: accumulatedProductCount > 0 ? inStockCode : outOfStockCode\r\n }\r\n ];\r\n};\r\n/*** The complete getProductAvailabilitiesForSelectedVariant data action\r\n * Get the currently selected variant via the getSelectedVariant data action, and\r\n * then gets the availabilities for the variant via the getProductAvailabilities RetailServer API\r\n ****/\r\nexport default createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/retail-actions/get-product-availabilities-for-selected-variant',\r\n action: >getProductAvailabilitiesForSelectedVariantAction,\r\n input: createProductAvailabilitiesForSelectedVariantInput\r\n});\r\n","import {\r\n getSimpleProducts,\r\n ProductInput,\r\n createGetFeatureStateInput,\r\n getCustomer,\r\n GetCustomerInput,\r\n getFeatureState,\r\n ArrayExtensions\r\n} from '@msdyn365-commerce-modules/retail-actions';\r\nimport {\r\n CacheType,\r\n createObservableDataAction,\r\n IAction,\r\n IActionContext,\r\n IActionInput,\r\n ICreateActionContext\r\n} from '@msdyn365-commerce/core';\r\nimport { getCartState } from '@msdyn365-commerce/global-state';\r\nimport { CommerceProperty, CommercePropertyValue, ProductSearchCriteria, FeatureState } from '@msdyn365-commerce/retail-proxy';\r\nimport { searchByCriteriaAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\r\nimport { Cart, SimpleProduct } from '@msdyn365-commerce/retail-proxy/dist/Entities/CommerceTypes.g';\r\nimport { getRestrictedProducts } from '../utilities/post-code-restriction/get-restricted-products';\r\n/**\r\n * Input class for activeCartWithProducts data action\r\n */\r\nexport class ActiveCartProductsInput implements IActionInput {\r\n public getCacheKey = () => `ActiveCartProducts`;\r\n public getCacheObjectType = () => 'ActiveCartProducts';\r\n public dataCacheType = (): CacheType => 'none';\r\n}\r\n\r\nconst createInput = (inputData: ICreateActionContext) => {\r\n return new ActiveCartProductsInput();\r\n};\r\n\r\n/**\r\n * Calls the Retail API and returns a cart object based on the passed GetCartInput\r\n * @param input\r\n * @param ctx\r\n */\r\nexport async function getActiveCartProductsAction(input: ActiveCartProductsInput, ctx: IActionContext): Promise {\r\n // If no cart ID is provided in input, we need to create a cart object\r\n if (!input) {\r\n throw new Error('[getActiveCartWithProducts]No valid Input was provided, failing');\r\n }\r\n\r\n const cartState = await getCartState(ctx);\r\n const cart = cartState.cart;\r\n\r\n const isQuantityLimitsFeatureIsOn: boolean = await isOrderQuantityLimitsFeatureEnabled(ctx);\r\n\r\n if (isQuantityLimitsFeatureIsOn) {\r\n return getActiveCartProductsActionWhenQuantityLimitsFeatureIsOn(cart, ctx);\r\n }\r\n\r\n // If there are cart lines, make call to get products\r\n if (!cartState.hasInvoiceLine && cart && cart.CartLines && cart.CartLines.length > 0) {\r\n ctx.trace('Getting cart product information...');\r\n return getSimpleProducts(\r\n cart.CartLines.map(cartLine => {\r\n if (cartLine.ProductId) {\r\n return new ProductInput(cartLine.ProductId, ctx.requestContext.apiSettings);\r\n }\r\n return undefined;\r\n }).filter(Boolean),\r\n ctx\r\n )\r\n .then((products: SimpleProduct[]) => {\r\n if (products) {\r\n /* VSI Customization - START - 15/12/20 */\r\n const productWithVendorInfo = _getProductsVendorInfo(ctx, products);\r\n if (productWithVendorInfo) {\r\n return productWithVendorInfo;\r\n }\r\n return products;\r\n /* VSI Customization - END */\r\n } else {\r\n return [];\r\n }\r\n })\r\n .catch((error: Error) => {\r\n ctx.trace(error.toString());\r\n ctx.telemetry.error(error.message);\r\n ctx.telemetry.debug(`[getActiveCartWithProducts]Unable to hydrate cart with product information`);\r\n throw new Error('[getActiveCartWithProducts]Unable to hydrate cart with product information');\r\n });\r\n }\r\n\r\n ctx.trace('[getActiveCartWithProducts]No Products Found in cart');\r\n return [];\r\n}\r\n/* VSI Customization - START - 15/12/20 */\r\nconst _getProductsVendorInfo = async (actionContext: IActionContext, products: SimpleProduct[]) => {\r\n const callerContext = actionContext;\r\n const {\r\n requestContext: {\r\n apiSettings: { channelId, catalogId }\r\n }\r\n } = actionContext;\r\n if (products) {\r\n const searchCriteriaInput: ProductSearchCriteria = {};\r\n searchCriteriaInput.Context = { ChannelId: channelId, CatalogId: catalogId };\r\n const productIds: number[] = [];\r\n const masterProductIds: number[][] = [];\r\n products.map(product => {\r\n if (product.MasterProductId && product.RecordId !== product.MasterProductId) {\r\n masterProductIds.push([product.MasterProductId, product.RecordId]);\r\n productIds.push(product.MasterProductId);\r\n } else {\r\n productIds.push(product.RecordId);\r\n }\r\n });\r\n searchCriteriaInput.Ids = productIds;\r\n searchCriteriaInput.IncludeAttributes = true;\r\n const productsData = await searchByCriteriaAsync({ callerContext, queryResultSettings: {} }, searchCriteriaInput);\r\n \r\n \r\n // Get restricted products list\r\n const restrictedProducts = await getRestrictedProducts(productsData, actionContext.requestContext.apiSettings.baseUrl);\r\n productsData.map(product => {\r\n for (const mp of masterProductIds) {\r\n if (mp[0] === product.RecordId) {\r\n product.RecordId = mp[1];\r\n }\r\n }\r\n // Check if it is restricted product, add it in its ExtensionProperties\r\n const isRestrictedProduct = restrictedProducts.find(productId => productId === product.RecordId);\r\n const restrictedInfo: CommerceProperty = { Key: 'isRestrictedProduct', Value: { BooleanValue: !!isRestrictedProduct } };\r\n\r\n const attributes = product.AttributeValues;\r\n const isvendorShippedAttribute =\r\n attributes &&\r\n attributes.find(attribute => {\r\n const attributeName = attribute.Name && attribute.Name.trim().toLowerCase();\r\n return attributeName === 'isvendershipproduct'; // \"IsVendershipProduct\"\r\n });\r\n const isVendorShiped =\r\n isvendorShippedAttribute &&\r\n isvendorShippedAttribute.TextValue &&\r\n isvendorShippedAttribute.TextValue.trim().toLowerCase() === 'yes';\r\n const extensionProperties: CommerceProperty[] = [];\r\n if (isVendorShiped) {\r\n const selectedAttributes =\r\n attributes &&\r\n attributes.filter(attribute => {\r\n const attributeName = attribute.Name && attribute.Name.trim().toLowerCase();\r\n const isVendorNameAvailable = attribute.TextValue; // if vendor name is not undefined\r\n return (\r\n attributeName &&\r\n isVendorNameAvailable &&\r\n (attributeName === 'vendorname' || attributeName === 'estimatedshippingtime')\r\n );\r\n });\r\n if (selectedAttributes && selectedAttributes.length > 0) {\r\n selectedAttributes &&\r\n selectedAttributes.map(selectedAttribute => {\r\n const commercePropertyValue: CommercePropertyValue = { StringValue: selectedAttribute.TextValue };\r\n const commerceProperty: CommerceProperty = { Key: selectedAttribute.Name, Value: commercePropertyValue };\r\n extensionProperties.push(commerceProperty);\r\n });\r\n } else {\r\n const vendorname: CommerceProperty = { Key: 'vendorname', Value: { StringValue: 'Not Available' } };\r\n const estimatedShippingTime: CommerceProperty = {\r\n Key: 'estimatedshippingtime',\r\n Value: { StringValue: 'Not Available' }\r\n };\r\n extensionProperties.push(vendorname);\r\n extensionProperties.push(estimatedShippingTime);\r\n }\r\n } else {\r\n const vendorname: CommerceProperty = { Key: 'vendorname', Value: { StringValue: undefined } };\r\n const estimatedShippingTime: CommerceProperty = { Key: 'estimatedshippingtime', Value: { StringValue: undefined } };\r\n extensionProperties.push(vendorname);\r\n extensionProperties.push(estimatedShippingTime);\r\n }\r\n // Add restricted info against each cartLine\r\n extensionProperties.push(restrictedInfo);\r\n product.ExtensionProperties = extensionProperties;\r\n });\r\n return productsData;\r\n }\r\n return [];\r\n};\r\n/* VSI Customizatoin - END */\r\nexport default createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/retail-actions/get-products-in-active-cart',\r\n action: >getActiveCartProductsAction,\r\n input: createInput\r\n});\r\n\r\nasync function getActiveCartProductsActionWhenQuantityLimitsFeatureIsOn(cart: Cart, ctx: IActionContext): Promise {\r\n const productIdsByWarehouseId: Map = new Map();\r\n let resultProducts: SimpleProduct[] = [];\r\n cart.CartLines?.forEach(cartLine =>\r\n productIdsByWarehouseId.has(cartLine.WarehouseId!)\r\n ? productIdsByWarehouseId.get(cartLine.WarehouseId!)?.push(cartLine.ProductId!)\r\n : productIdsByWarehouseId.set(cartLine.WarehouseId!, [cartLine.ProductId!])\r\n );\r\n return Promise.all(\r\n [...productIdsByWarehouseId].map(([entryWarehouseId, entryProductIds]) => {\r\n return getSimpleProducts(\r\n entryProductIds\r\n .map(productId => {\r\n if (productId) {\r\n return new ProductInput(productId, ctx.requestContext.apiSettings, undefined, entryWarehouseId);\r\n }\r\n return undefined;\r\n })\r\n .filter(Boolean),\r\n ctx\r\n ).then((products: SimpleProduct[]) => {\r\n if (products) {\r\n resultProducts = products.reduce((accum, product) => {\r\n if (product) {\r\n accum.push(product);\r\n }\r\n return accum;\r\n }, resultProducts);\r\n }\r\n });\r\n })\r\n ).then(() => resultProducts);\r\n}\r\n\r\nasync function isOrderQuantityLimitsFeatureEnabled(ctx: IActionContext): Promise {\r\n const defaultOrderQuantityLimitsFeatureConfig = ctx.requestContext.app?.platform?.enableDefaultOrderQuantityLimits;\r\n if (defaultOrderQuantityLimitsFeatureConfig === 'none') {\r\n return Promise.resolve(false);\r\n }\r\n\r\n const featureStates = await getFeatureState(createGetFeatureStateInput(ctx), ctx);\r\n let isQuantityLimitsFeatureEnabledInHq = false;\r\n if (ArrayExtensions.hasElements(featureStates)) {\r\n isQuantityLimitsFeatureEnabledInHq =\r\n featureStates.find(\r\n (featureState: FeatureState) => featureState.Name === 'Dynamics.AX.Application.RetailDefaultOrderQuantityLimitsFeature'\r\n )?.IsEnabled || false;\r\n }\r\n\r\n if (!isQuantityLimitsFeatureEnabledInHq) {\r\n return false;\r\n }\r\n\r\n if (defaultOrderQuantityLimitsFeatureConfig === 'all') {\r\n return Promise.resolve(true);\r\n }\r\n\r\n return getCustomer(new GetCustomerInput(ctx.requestContext.apiSettings), ctx)\r\n .then(customerInfo => {\r\n return (\r\n !!customerInfo &&\r\n ((defaultOrderQuantityLimitsFeatureConfig === 'b2b' && customerInfo.IsB2b) ||\r\n (defaultOrderQuantityLimitsFeatureConfig === 'b2c' && !customerInfo.IsB2b))\r\n );\r\n })\r\n .catch((error: Error) => {\r\n ctx.telemetry.warning(error.message);\r\n ctx.telemetry.debug('Unable to get customer info');\r\n return false;\r\n });\r\n}\r\n","import { ICommerceApiSettings } from '@msdyn365-commerce/core';\r\nimport { ProductSearchResult, SimpleProduct } from '@msdyn365-commerce/retail-proxy';\r\n\r\n/**\r\n * Generates a Image URL based on data return from retail server\r\n * @param imageUrl The image url returned by Retail Server\r\n * @param ctx The request context\r\n */\r\nexport const generateImageUrl = (imageUrl: string | undefined, apiSettings: ICommerceApiSettings): string | undefined => {\r\n if (imageUrl) {\r\n // Images hosted in CMS include schema\r\n if (imageUrl.startsWith('http')) {\r\n return imageUrl;\r\n }\r\n\r\n // Images hosted in Retail Server must be encoded and joined with the base image url\r\n return apiSettings.baseImageUrl + encodeURIComponent(imageUrl);\r\n } else {\r\n // d365Commerce.telemetry.warning(`Unable to generate a proper Image URL for Product: ${product.RecordId}`);\r\n return undefined;\r\n }\r\n};\r\n\r\n/**\r\n * Generates a Image URL for a product based on data return from retail server\r\n * @param product The Product returned by Retail Server\r\n * @param ctx The request context\r\n */\r\nexport const generateProductImageUrl = (\r\n product: SimpleProduct | ProductSearchResult,\r\n apiSettings: ICommerceApiSettings\r\n): string | undefined => {\r\n return generateImageUrl(product.PrimaryImageUrl, apiSettings);\r\n};\r\n","import { getSelectedProductIdFromActionInput } from '@msdyn365-commerce-modules/retail-actions';\r\nimport {\r\n CacheType,\r\n createObservableDataAction,\r\n IAction,\r\n IActionContext,\r\n IActionInput,\r\n IAny,\r\n ICreateActionContext,\r\n IGeneric\r\n} from '@msdyn365-commerce/core';\r\n\r\nimport {\r\n getByIdAsync,\r\n getDefaultComponentsAsync,\r\n getVariantsByComponentsInSlotsAsync,\r\n getVariantsByDimensionValuesAsync\r\n} from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\r\nimport { ProductDimension, SimpleProduct } from '@msdyn365-commerce/retail-proxy/dist/Entities/CommerceTypes.g';\r\nimport { generateProductImageUrl } from './utilities/get-image-url';\r\n/**\r\n * Get selected variant action input class\r\n */\r\nexport class SelectedVariantInput implements IActionInput {\r\n public productId: number;\r\n public channelId: number;\r\n public matchingDimensionValues: ProductDimension[];\r\n\r\n constructor(productId: number, channelId: number, matchingDimensionValues?: ProductDimension[]) {\r\n this.productId = productId;\r\n this.channelId = channelId;\r\n this.matchingDimensionValues = matchingDimensionValues || [];\r\n }\r\n\r\n public getCacheKey = () => `SelectedVariant`;\r\n public getCacheObjectType = () => 'SimpleProduct';\r\n public dataCacheType = (): CacheType => 'application';\r\n}\r\n\r\n/**\r\n * CreateInput method for the getSelectedVariant data action\r\n * @param inputData The input data passed to the createInput method\r\n */\r\nconst createInput = (inputData: ICreateActionContext>): SelectedVariantInput => {\r\n const productId = getSelectedProductIdFromActionInput(inputData);\r\n\r\n if (productId) {\r\n return new SelectedVariantInput(+productId, +inputData.requestContext.apiSettings.channelId, []);\r\n } else {\r\n throw new Error('Unable to create SelectedVariantInput, no productId found on module config or query');\r\n }\r\n};\r\n\r\n/**\r\n * Action method for the getSelectedVariant data aciton\r\n * @param input The action input class\r\n * @param ctx The action context\r\n */\r\nasync function getSelectedVariantAction(input: SelectedVariantInput, ctx: IActionContext): Promise {\r\n let product: SimpleProduct | null = null;\r\n\r\n const response = await getByIdAsync({ callerContext: ctx }, input.productId, input.channelId);\r\n const baseProduct: SimpleProduct = Array.isArray(response) ? response[0] : response;\r\n\r\n // Need to dereference this before editing it. Otherwise we might not\r\n // properly get the mobx events because if things aren't properly observable\r\n // they won't fire when you set them, and then if you don't deref the value in\r\n // the cache will match the value when you try to save it, so it won't detect any\r\n // changes there either\r\n product = baseProduct && { ...baseProduct };\r\n\r\n if (product) {\r\n let baseProductHadUnmatchedDimension: boolean = false;\r\n if (product.Dimensions) {\r\n product.Dimensions.map(dimension => {\r\n const matchedTargetDimension = input.matchingDimensionValues?.find(\r\n targetDimension => targetDimension.DimensionTypeValue === dimension.DimensionTypeValue\r\n );\r\n\r\n if (matchedTargetDimension) {\r\n dimension.DimensionValue = matchedTargetDimension.DimensionValue;\r\n } else {\r\n baseProductHadUnmatchedDimension = true;\r\n }\r\n });\r\n }\r\n\r\n if (!baseProductHadUnmatchedDimension && input.matchingDimensionValues?.length > 0) {\r\n const variants = await getVariantsByDimensionValuesAsync(\r\n { callerContext: ctx, queryResultSettings: {} },\r\n baseProduct?.RecordId,\r\n input.channelId,\r\n input.matchingDimensionValues || []\r\n );\r\n\r\n if (variants && variants.length > 0) {\r\n product = variants[0];\r\n }\r\n }\r\n\r\n /**\r\n * VSI Customization -- STARTS\r\n * Check if the product is Kit through getDefaultComponentsAsync\r\n * If it is kit product then fetch and load it's variant instead of master product.\r\n * Assuming there will be only one vaiant of kit product.\r\n */\r\n\r\n const defaultComponent = await getDefaultComponentsAsync(\r\n { callerContext: ctx, queryResultSettings: {} },\r\n baseProduct?.RecordId,\r\n input.channelId\r\n );\r\n\r\n if (defaultComponent && defaultComponent.length > 0) {\r\n const variantsByComponent = await getVariantsByComponentsInSlotsAsync(\r\n { callerContext: ctx, queryResultSettings: {} },\r\n baseProduct?.RecordId,\r\n input.channelId,\r\n []\r\n );\r\n\r\n if (variantsByComponent.length && variantsByComponent.length > 0) {\r\n const variantId = variantsByComponent[0]?.RecordId;\r\n const simpleProduct = await getByIdAsync({ callerContext: ctx }, variantId, input.channelId);\r\n const kitProduct: SimpleProduct = Array.isArray(simpleProduct) ? simpleProduct[0] : simpleProduct;\r\n // Will use master product's details as that would be up-to-date\r\n /* As description & title doesn't get updated for variants but for master products so using master product's details */\r\n const updatedKitProduct = kitProduct;\r\n updatedKitProduct.Name = baseProduct.Name;\r\n updatedKitProduct.Description = baseProduct.Description;\r\n\r\n product = { ...updatedKitProduct };\r\n }\r\n }\r\n\r\n /**\r\n * VSI Customization -- ENDS\r\n */\r\n\r\n const newImageUrl = generateProductImageUrl(product, ctx.requestContext.apiSettings);\r\n\r\n if (newImageUrl) {\r\n product.PrimaryImageUrl = newImageUrl;\r\n }\r\n }\r\n\r\n return product || null;\r\n}\r\n\r\n/**\r\n * The complete getSelectedVariant data action\r\n */\r\nexport default createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/retail-actions/get-selected-variant',\r\n action: >getSelectedVariantAction,\r\n input: createInput\r\n});\r\n","import { IFullOrgUnitAvailability } from '@msdyn365-commerce-modules/retail-actions';\r\nimport {\r\n CacheType,\r\n createObservableDataAction,\r\n IAction,\r\n IActionContext,\r\n IActionInput,\r\n IAny,\r\n ICreateActionContext,\r\n IGeneric\r\n} from '@msdyn365-commerce/core';\r\nimport {\r\n ChannelDeliveryOption,\r\n FeatureState,\r\n OrgUnitAvailability,\r\n OrgUnitLocation,\r\n SearchArea,\r\n StoreHours\r\n} from '@msdyn365-commerce/retail-proxy';\r\nimport {\r\n getChannelDeliveryOptionsAsync,\r\n getOrgUnitLocationsByAreaAsync,\r\n getStoreHoursAsync\r\n} from '@msdyn365-commerce/retail-proxy/dist/DataActions/OrgUnitsDataActions.g';\r\nimport { FeatureStateInput, getFeatureStateAction } from './get-feature-state.override.action';\r\n\r\n/**\r\n * Get selected variant action input class\r\n */\r\nexport class GetOrgUnitLocationsByAreaInput implements IActionInput {\r\n public Latitude?: number;\r\n public Longitude?: number;\r\n public Radius?: number;\r\n public DistanceUnitValue?: number;\r\n public IgnoreLocation?: boolean;\r\n\r\n constructor(_Latitude?: number, _Longitude?: number, _Radius?: number, _DistanceUnitValue?: number, _IgnoreLocation?: boolean) {\r\n this.Latitude = _Latitude;\r\n this.Longitude = _Longitude;\r\n this.Radius = _Radius;\r\n this.DistanceUnitValue = _DistanceUnitValue;\r\n this.IgnoreLocation = _IgnoreLocation;\r\n }\r\n\r\n public getCacheKey = () => `GetOrgUnitLocationsByAreaInput`;\r\n public getCacheObjectType = () => 'GetOrgUnitLocationsByAreaInput';\r\n public dataCacheType = (): CacheType => 'none';\r\n}\r\n\r\n/**\r\n * CreateInput method for the getSelectedVariant data action\r\n * @param inputData The input data passed to the createInput method\r\n */\r\nexport const createGetOrgUnitLocationsByAreaInput = (inputData: ICreateActionContext>): GetOrgUnitLocationsByAreaInput => {\r\n return new GetOrgUnitLocationsByAreaInput();\r\n};\r\n/* Upgraded to 10.0.16 - START */\r\n/**\r\n * Calls the Retail Feature State API and returns a list of feature with isEnabled flag.\r\n */\r\nexport async function getFeatureState(context: IActionContext): Promise {\r\n return getFeatureStateAction(new FeatureStateInput(), context);\r\n}\r\n/* Upgraded to 10.0.16 - END */\r\n/**\r\n * Action method for the getSelectedVariant data action\r\n * @param input The action input class\r\n * @param ctx The action context\r\n */\r\nexport async function getOrgUnitLocationsByArea(\r\n input: GetOrgUnitLocationsByAreaInput,\r\n ctx: IActionContext\r\n): Promise {\r\n if ((input.Radius === undefined || !input.Latitude || !input.Longitude) && !input.IgnoreLocation) {\r\n // No valid location we want to return empty array so module can show no locations message\r\n return [];\r\n }\r\n\r\n const searchArea: SearchArea = {\r\n Latitude: input.Latitude,\r\n Longitude: input.Longitude,\r\n Radius: input.Radius,\r\n DistanceUnitValue: input.DistanceUnitValue || 0 // 0 is miles\r\n };\r\n /* Upgraded to 10.0.16 - START */\r\n const featureState = await getFeatureState(ctx);\r\n const retailMulitplePickupMFeatureState = featureState?.find(\r\n item => item.Name === 'Dynamics.AX.Application.RetailMultiplePickupDeliveryModeFeature'\r\n )?.IsEnabled;\r\n /* Upgraded to 10.0.16 - END */\r\n return getOrgUnitLocationsByAreaAsync({ callerContext: ctx }, searchArea)\r\n .then(async (stores: OrgUnitLocation[]) => {\r\n // VSI-Customization START - stores sorted in alphabetically order.\r\n const alphabeticallySortedStores = stores?.sort((a, b) => a.OrgUnitName!.localeCompare(b.OrgUnitName!));\r\n // VSI-Customization END\r\n /* Upgraded to 10.0.16 - START */\r\n /* const locationPromiseList = alphabeticallySortedStores.map(store => _getLocationWithHours(store, ctx)); */\r\n let locationDeliveryOptions: ChannelDeliveryOption[] | undefined = [];\r\n // if mulitple pickup mode is enable then call getchanneldeliveryoption\r\n if (retailMulitplePickupMFeatureState) {\r\n const orgUnitChannel = alphabeticallySortedStores.map(store => store.ChannelId);\r\n locationDeliveryOptions = await _getLocationPickUpDeliveryModes(orgUnitChannel, ctx);\r\n }\r\n const locationPromiseList = alphabeticallySortedStores.map(store => {\r\n const locationDeliveryOption = locationDeliveryOptions?.find(\r\n _channeldeliveryoption => _channeldeliveryoption.ChannelId === store.ChannelId\r\n );\r\n return _getLocationWithHours(store, locationDeliveryOption, ctx);\r\n });\r\n /* Upgraded to 10.0.16 - END */\r\n return Promise.all(locationPromiseList);\r\n })\r\n .catch((error: Error) => {\r\n ctx.trace('[GetOrgUnitLocationsByArea] error getting Locations');\r\n ctx.trace(error.message);\r\n ctx.telemetry.error(error.message);\r\n ctx.telemetry.debug(`[GetOrgUnitLocationsByArea] error getting Locations`);\r\n return [];\r\n });\r\n}\r\n\r\n/**\r\n * Action method that obtains the store information\r\n * @param orgUnitLocation The org unit location\r\n * @param storeMap a map that contains store information group by the inventory location id\r\n * @param ctx The action context\r\n */\r\nasync function _getLocationWithHours(\r\n orgUnitLocation: OrgUnitLocation,\r\n channelDeleiveryOptions: ChannelDeliveryOption | undefined, // Upgraded to 10.0.16\r\n ctx: IActionContext\r\n): Promise {\r\n if (!orgUnitLocation || !orgUnitLocation.OrgUnitNumber) {\r\n return { OrgUnitAvailability: undefined };\r\n }\r\n\r\n return getStoreHoursAsync({ callerContext: ctx }, orgUnitLocation.OrgUnitNumber)\r\n .then((hours: StoreHours) => {\r\n const availability: OrgUnitAvailability = {\r\n OrgUnitLocation: orgUnitLocation\r\n };\r\n\r\n if (hours && !(hours instanceof Error)) {\r\n return {\r\n OrgUnitAvailability: availability,\r\n StoreHours: hours,\r\n OrgUnitPickUpDeliveryModes: channelDeleiveryOptions /* Upgraded to 10.0.16 */\r\n };\r\n }\r\n\r\n return {\r\n OrgUnitAvailability: availability,\r\n OrgUnitPickUpDeliveryModes: channelDeleiveryOptions /* Upgraded to 10.0.16 */\r\n };\r\n })\r\n .catch((error: Error) => {\r\n ctx.trace('[GetFullAvailableInventoryNearby] error getting availability with hours');\r\n ctx.trace(error.message);\r\n ctx.telemetry.exception(error);\r\n ctx.telemetry.debug(`[GetFullAvailableInventoryNearby] error getting availability with hours`);\r\n return { OrgUnitAvailability: {} };\r\n });\r\n}\r\n/* Upgraded to 10.0.16 - START */\r\n/**\r\n * Action method that obtains the store information\r\n * @param channelCollection The org unit channel Id list\r\n * @param ctx The action context\r\n */\r\nasync function _getLocationPickUpDeliveryModes(\r\n channelCollection: (number | undefined)[],\r\n ctx: IActionContext\r\n): Promise {\r\n if (channelCollection?.length === 0 || channelCollection === undefined) {\r\n return undefined;\r\n }\r\n const channelIdList: number[] = [];\r\n channelCollection?.map(id => {\r\n if (id !== undefined) {\r\n channelIdList.push(id);\r\n }\r\n });\r\n // to get all channel pickup delivery mode filterOption should be 4\r\n return getChannelDeliveryOptionsAsync({ callerContext: ctx }, channelIdList, 4)\r\n .then((channelDeliveryOptions: ChannelDeliveryOption[]) => {\r\n if (channelDeliveryOptions && !(channelDeliveryOptions instanceof Error)) {\r\n return channelDeliveryOptions;\r\n }\r\n return undefined;\r\n })\r\n .catch((error: Error) => {\r\n ctx.trace(\r\n '[GetFullAvailableInventoryNearby][getChannelDeliveryOptionsAsync] error getting availability with channel delivery options'\r\n );\r\n ctx.trace(error.message);\r\n ctx.telemetry.exception(error);\r\n ctx.telemetry.debug(\r\n `[GetFullAvailableInventoryNearby] [getChannelDeliveryOptionsAsync] error getting availability with channel delivery options`\r\n );\r\n return [];\r\n });\r\n}\r\n/* Upgraded to 10.0.16 - END */\r\n/**\r\n * The complete getOrgUnitLocationsByArea data action\r\n */\r\nexport default createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/retail-actions/get-store-location-information',\r\n action: >getOrgUnitLocationsByArea,\r\n input: createGetOrgUnitLocationsByAreaInput\r\n});\r\n","/*--------------------------------------------------------------\r\n * Copyright (c) Microsoft Corporation. All rights reserved.\r\n * See License.txt in the project root for license information.\r\n *--------------------------------------------------------------*/\r\n\r\nimport { createObservableDataAction, IAction, IActionContext, IActionInput, IAny, ICreateActionContext } from '@msdyn365-commerce/core';\r\nimport { readAsync, updateAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/CustomersDataActions.g';\r\nimport { Address, Customer } from '@msdyn365-commerce/retail-proxy/dist/Entities/CommerceTypes.g';\r\n\r\nimport { IAddressManagementInput } from '@msdyn365-commerce-modules/retail-actions/dist/types/add-address';\r\n\r\n// @ts-ignore\r\nimport { GetCustomerInput } from '@msdyn365-commerce-modules/retail-actions/dist/lib/get-customer';\r\n\r\n// @ts-ignore\r\nimport { createAddressManagementInput } from '@msdyn365-commerce-modules/retail-actions/dist/lib/add-address';\r\n\r\nexport function updatePrimaryAddressHandler(customer: Customer, address: Address): Customer {\r\n customer.Addresses = setPrimaryAddress({ ...address }, [...(customer.Addresses || [])]);\r\n return customer;\r\n}\r\n\r\nexport async function updatePrimaryAddressAction(input: IAddressManagementInput, ctx: IActionContext): Promise {\r\n const { address } = input;\r\n\r\n const customer = await readAsync({ callerContext: ctx, bypassCache: 'get' }, '');\r\n\r\n if (!customer) {\r\n throw new Error('Unable to find customer');\r\n }\r\n\r\n customer.Addresses = setPrimaryAddress({ ...address }, [...(customer.Addresses ?? [])]);\r\n const updatedCustomer = await updateAsync({ callerContext: ctx }, customer);\r\n\r\n if (!updatedCustomer) {\r\n throw new Error('Unable to update customer');\r\n }\r\n\r\n ctx.update(new GetCustomerInput(ctx.requestContext.apiSettings), updatedCustomer);\r\n\r\n return updatedCustomer.Addresses || [];\r\n}\r\n\r\n/**\r\n * The updatePrimaryAddress data action\r\n * Calls the read RetailServer API to get information about a customer\r\n * Merge the passed address information with the address information from\r\n * the retireved customer, and then updates that customer via the update RetailServer API.\r\n */\r\nexport const updatePrimaryAddressActionDataAction = createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/retail-actions/update-primary-address',\r\n action: >updatePrimaryAddressAction,\r\n input: <(args: ICreateActionContext) => IActionInput>(createAddressManagementInput),\r\n isBatched: false\r\n});\r\nexport default updatePrimaryAddressActionDataAction;\r\n\r\nconst setPrimaryAddress = (primaryAddresses: Address, addresses: Address[]): Address[] => {\r\n return addresses.map(addr => {\r\n if (addr.RecordId === primaryAddresses.RecordId) {\r\n addr.IsPrimary = true;\r\n } else {\r\n addr.IsPrimary = false;\r\n }\r\n return addr;\r\n });\r\n};\r\n","/*--------------------------------------------------------------\r\n * Copyright (c) Microsoft Corporation. All rights reserved.\r\n * See License.txt in the project root for license information.\r\n *--------------------------------------------------------------*/\r\n\r\nimport { ProductAvailableQuantity } from '@msdyn365-commerce/retail-proxy';\r\n\r\n/**\r\n * This setting defines the delivery modes supported.\r\n */\r\nexport enum DeliveryMode {\r\n allWareHouses = 0,\r\n shipping = 1,\r\n pickup = 2\r\n}\r\n\r\n/**\r\n * This setting defines the inventory levels supported.\r\n */\r\nexport enum InventoryLevels {\r\n physicalAvailable = 'physicalAvailable',\r\n totalAvailable = 'totalAvailable',\r\n threshold = 'threshold'\r\n}\r\n\r\n/**\r\n * Product inventory information class.\r\n */\r\nexport interface IProductInventoryInformation {\r\n ProductAvailableQuantity: ProductAvailableQuantity;\r\n StockLevelCode?: string;\r\n StockLevelLabel?: string;\r\n IsProductAvailable: boolean;\r\n InventLocationId?: string;\r\n deliveryType?: DeliveryMode;\r\n}\r\n","import { IActionContext } from '@msdyn365-commerce/core';\r\nimport { ProductAvailableQuantity, ProductSearchResult, ProductWarehouseInventoryAvailability } from '@msdyn365-commerce/retail-proxy';\r\n/**\r\n * Product inventory information class\r\n */\r\nexport interface IProductInventoryInformation {\r\n ProductAvailableQuantity: ProductAvailableQuantity;\r\n StockLevelCode?: string;\r\n StockLevelLabel?: string;\r\n IsProductAvailable: boolean;\r\n InventLocationId?: string;\r\n}\r\n/**\r\n * The function that maps a ProductWareHouse object into a ProductAvailabilityQuantity\r\n */\r\nexport const mapProductInventoryInformation = (\r\n ctx: IActionContext,\r\n productsWarehouseInventory: ProductWarehouseInventoryAvailability[],\r\n isPreSale?: string,\r\n dobbiesProductsData?: ProductSearchResult[]\r\n): IProductInventoryInformation[] => {\r\n const {\r\n requestContext: {\r\n app: {\r\n config: { enableStockCheck, inventoryLevel }\r\n }\r\n }\r\n } = ctx;\r\n\r\n const productInventoryInformation: IProductInventoryInformation[] = [];\r\n\r\n if (enableStockCheck === undefined || enableStockCheck === false) {\r\n return productInventoryInformation;\r\n }\r\n\r\n if (productsWarehouseInventory && productsWarehouseInventory.length > 0) {\r\n for (const product of productsWarehouseInventory) {\r\n const filteredProduct = dobbiesProductsData?.find(prod => prod.RecordId === product.ProductId);\r\n const presell = filteredProduct?.AttributeValues?.find(proAttr => proAttr.Name === \"PreSale\" && proAttr.TextValue === \"Yes\")\r\n const IsVendershipProduct = filteredProduct?.AttributeValues?.find(proAttr => proAttr.Name === \"IsVendershipProduct\" && proAttr.TextValue === \"No\")\r\n const FulfillmentType = filteredProduct?.AttributeValues?.find(proAttr => proAttr.Name === \"FulfillmentType\" && proAttr.TextValue !== \"Plants\")\r\n switch (isPreSale ? \"totalAvailable\" : (presell && IsVendershipProduct && FulfillmentType) ? \"totalAvailable\" : inventoryLevel) {\r\n case 'physicalAvailable':\r\n // Inventory level is enabled with Physical inventory\r\n const physicalProductMap = mapInventoryWithPhysicalBufferEnabled(ctx, product);\r\n if (physicalProductMap) {\r\n productInventoryInformation.push(physicalProductMap);\r\n }\r\n break;\r\n case 'totalAvailable':\r\n // Inventory level is enabled with Total available inventory\r\n const totalAvailableProductMap = mapInventoryWithTotalAvailableBufferEnabled(ctx, product);\r\n if (totalAvailableProductMap) {\r\n productInventoryInformation.push(totalAvailableProductMap);\r\n }\r\n break;\r\n default:\r\n // when inventory level is inventoryThreshold or not defined\r\n const productMap = mapInventoryWithThresholdEnabled(ctx, product);\r\n if (productMap) {\r\n productInventoryInformation.push(productMap);\r\n }\r\n }\r\n }\r\n }\r\n return productInventoryInformation;\r\n};\r\n\r\nexport const mapInventoryWithThresholdEnabled = (\r\n ctx: IActionContext,\r\n productWarehouseInventoryAvailability: ProductWarehouseInventoryAvailability\r\n) => {\r\n if (\r\n productWarehouseInventoryAvailability &&\r\n productWarehouseInventoryAvailability.ProductId &&\r\n productWarehouseInventoryAvailability.TotalAvailable !== undefined\r\n ) {\r\n const productQty = productWarehouseInventoryAvailability.TotalAvailable - ctx.requestContext.app.config.outOfStockThreshold;\r\n const productAvailableQuantity = {\r\n ProductId: productWarehouseInventoryAvailability.ProductId,\r\n AvailableQuantity: productQty > 0 ? productQty : 0\r\n };\r\n return {\r\n ProductAvailableQuantity: productAvailableQuantity,\r\n IsProductAvailable: productAvailableQuantity.AvailableQuantity && productAvailableQuantity.AvailableQuantity > 0 ? true : false,\r\n InventLocationId: productWarehouseInventoryAvailability.InventLocationId\r\n };\r\n }\r\n return null;\r\n};\r\n\r\nexport const mapInventoryWithPhysicalBufferEnabled = (\r\n ctx: IActionContext,\r\n productWarehouseInventoryAvailability: ProductWarehouseInventoryAvailability\r\n) => {\r\n const shouldRenderLabel = displayLabelEnabled(ctx, productWarehouseInventoryAvailability.PhysicalAvailableInventoryLevelCode);\r\n if (\r\n productWarehouseInventoryAvailability &&\r\n productWarehouseInventoryAvailability.ProductId &&\r\n productWarehouseInventoryAvailability.TotalAvailable !== undefined\r\n ) {\r\n // As per the new buffer logic from RS,\r\n // if code is out of stock then we set the available quantity to 0 regardless of the actual value from API\r\n const productQuantity =\r\n productWarehouseInventoryAvailability.PhysicalAvailableInventoryLevelCode === 'OOS'\r\n ? 0\r\n : productWarehouseInventoryAvailability.PhysicalAvailable;\r\n const productAvailableQuantity = {\r\n ProductId: productWarehouseInventoryAvailability.ProductId,\r\n AvailableQuantity: productQuantity\r\n };\r\n return {\r\n ProductAvailableQuantity: productAvailableQuantity,\r\n StockLevelCode: shouldRenderLabel ? productWarehouseInventoryAvailability.PhysicalAvailableInventoryLevelCode : undefined,\r\n StockLevelLabel: shouldRenderLabel ? productWarehouseInventoryAvailability.PhysicalAvailableInventoryLevelLabel : undefined,\r\n IsProductAvailable: productAvailableQuantity.AvailableQuantity !== undefined && productAvailableQuantity.AvailableQuantity > 0,\r\n InventLocationId: productWarehouseInventoryAvailability.InventLocationId\r\n };\r\n }\r\n return null;\r\n};\r\n\r\nexport const mapInventoryWithTotalAvailableBufferEnabled = (\r\n ctx: IActionContext,\r\n productWarehouseInventoryAvailability: ProductWarehouseInventoryAvailability\r\n) => {\r\n const shouldRenderLabel = displayLabelEnabled(ctx, productWarehouseInventoryAvailability.TotalAvailableInventoryLevelCode);\r\n if (\r\n productWarehouseInventoryAvailability &&\r\n productWarehouseInventoryAvailability.ProductId &&\r\n productWarehouseInventoryAvailability.TotalAvailable !== undefined\r\n ) {\r\n // As per the new buffer logic from RS,\r\n // if code is out of stock then we set the available quantity to 0 regardless of the actual value from API\r\n const productQuantity =\r\n productWarehouseInventoryAvailability.TotalAvailableInventoryLevelCode === 'OOS'\r\n ? 0\r\n : productWarehouseInventoryAvailability.TotalAvailable;\r\n const productAvailableQuantity = {\r\n ProductId: productWarehouseInventoryAvailability.ProductId,\r\n AvailableQuantity: productQuantity\r\n };\r\n return {\r\n ProductAvailableQuantity: productAvailableQuantity,\r\n StockLevelCode: shouldRenderLabel ? productWarehouseInventoryAvailability.TotalAvailableInventoryLevelCode : undefined,\r\n StockLevelLabel: shouldRenderLabel ? productWarehouseInventoryAvailability.TotalAvailableInventoryLevelLabel : undefined,\r\n IsProductAvailable: productAvailableQuantity.AvailableQuantity !== undefined && productAvailableQuantity.AvailableQuantity > 0,\r\n InventLocationId: productWarehouseInventoryAvailability.InventLocationId\r\n };\r\n }\r\n return null;\r\n};\r\n\r\nexport const displayLabelEnabled = (ctx: IActionContext, inventoryCode: string | undefined) => {\r\n if (!inventoryCode) {\r\n return false;\r\n }\r\n switch (ctx.requestContext.app.config.inventoryRanges) {\r\n case 'lowAndOutofStock':\r\n if (inventoryCode !== 'AVAIL') {\r\n return true;\r\n }\r\n break;\r\n case 'outOfStock':\r\n if (inventoryCode === 'OOS') {\r\n return true;\r\n }\r\n break;\r\n case 'all':\r\n return true;\r\n default:\r\n return false;\r\n }\r\n return false;\r\n};\r\n","import { ProductSearchResult } from '@msdyn365-commerce/retail-proxy';\r\nvar axios = require('axios');\r\n\r\nexport const getRestrictedProducts = async (productsData: ProductSearchResult[], attributesBaseUrl?: string): Promise => {\r\n const restrictedProducts: number[] = [];\r\n for (const product of productsData) {\r\n const attributes = await _getRestrictedPostCodes(product.RecordId, attributesBaseUrl);\r\n attributes &&\r\n attributes.map((attr: any) => {\r\n if (attr?.Name && attr.Name === 'RestrictedPostCode' && attr.TextValue) {\r\n // @ts-ignore\r\n const postcodesTemp = JSON.parse(attr?.TextValue).RestrictedPostCode;\r\n if (postcodesTemp.length > 0) {\r\n restrictedProducts.push(product.RecordId);\r\n }\r\n }\r\n });\r\n }\r\n\r\n return restrictedProducts;\r\n};\r\n\r\nexport const _getRestrictedPostCodes = async (productId: number, attributesBaseUrl?: string): Promise => {\r\n let url = attributesBaseUrl ? `${attributesBaseUrl}Commerce/Products(${productId})/GetAttributeValues(channelId=5637147577,catalogId=0)?$top=1000&api-version=7.3`: `https://scu40oznal298244666-rs.su.retail.dynamics.com/Commerce/Products(${productId})/GetAttributeValues(channelId=5637147577,catalogId=0)?$top=1000&api-version=7.3`;\r\n var config = {\r\n method: 'get',\r\n url: url,\r\n headers: {\r\n authority: attributesBaseUrl ? attributesBaseUrl.split('://')[1] : 'scu40oznal298244666-rs.su.retail.dynamics.com',\r\n accept: 'application/json',\r\n 'accept-language': 'en-GB',\r\n appsessionid: 'OtVVxv4TZOd4WbCSDTkvYH',\r\n 'cache-control': 'no-cache',\r\n 'content-type': 'application/json',\r\n contenttype: 'application/json',\r\n 'from-keystone': 'true',\r\n 'odata-maxversion': '4.0',\r\n 'odata-version': '4.0',\r\n oun: 'Y100',\r\n pragma: 'no-cache',\r\n prefer: 'return=representation',\r\n requestid: 'e42018722d257bb82e53ad56d5d963fc/2',\r\n usersessionid: 'ADCehL+M8YWP9iwro4TOSA'\r\n }\r\n };\r\n\r\n try {\r\n const response = await axios(config);\r\n return response.data.value;\r\n } catch (error) {\r\n console.log('err', error);\r\n throw error; // rethrow the error if needed\r\n }\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 { \n const actionPath = 'modules/dobbies-category-page-summary/dobbies-category-page-summary.action';\n binding.dataActions[actionPath] = require('partner/modules/dobbies-category-page-summary/dobbies-category-page-summary.action');\n registerActionId(actionPath);\n }\n\n { \n const actionPath = 'modules/dobbies-product-page-summary/dobbies-product-page-summary.action';\n binding.dataActions[actionPath] = require('partner/modules/dobbies-product-page-summary/dobbies-product-page-summary.action');\n registerActionId(actionPath);\n }\n\n { \n const actionPath = 'themes/dobbies/actions/get-availabilities-cartlines.override.action';\n binding.dataActions[actionPath] = require('partner/themes/dobbies/actions/get-availabilities-cartlines.override.action');\n registerActionId(actionPath);\n }\n\n { \n const actionPath = 'themes/dobbies/actions/get-categories-hierarchy.override.action';\n binding.dataActions[actionPath] = require('partner/themes/dobbies/actions/get-categories-hierarchy.override.action');\n registerActionId(actionPath);\n }\n\n { \n const actionPath = 'themes/dobbies/actions/get-current-category-hierarchy.override.action';\n binding.dataActions[actionPath] = require('partner/themes/dobbies/actions/get-current-category-hierarchy.override.action');\n registerActionId(actionPath);\n }\n\n { \n const actionPath = 'themes/dobbies/actions/get-customer-address.action';\n binding.dataActions[actionPath] = require('partner/themes/dobbies/actions/get-customer-address.action');\n registerActionId(actionPath);\n }\n\n { \n const actionPath = 'themes/dobbies/actions/get-feature-state.override.action';\n binding.dataActions[actionPath] = require('partner/themes/dobbies/actions/get-feature-state.override.action');\n registerActionId(actionPath);\n }\n\n { \n const actionPath = 'themes/dobbies/actions/get-full-available-inventory-nearby.override.action';\n binding.dataActions[actionPath] = require('partner/themes/dobbies/actions/get-full-available-inventory-nearby.override.action');\n registerActionId(actionPath);\n }\n\n { \n const actionPath = 'themes/dobbies/actions/get-loyalty-card.override.action';\n binding.dataActions[actionPath] = require('partner/themes/dobbies/actions/get-loyalty-card.override.action');\n registerActionId(actionPath);\n }\n\n { \n const actionPath = 'themes/dobbies/actions/get-product-availabilities-for-selected-variant.override.action';\n binding.dataActions[actionPath] = require('partner/themes/dobbies/actions/get-product-availabilities-for-selected-variant.override.action');\n registerActionId(actionPath);\n }\n\n { \n const actionPath = 'themes/dobbies/actions/get-products-in-active-cart.override.action';\n binding.dataActions[actionPath] = require('partner/themes/dobbies/actions/get-products-in-active-cart.override.action');\n registerActionId(actionPath);\n }\n\n { \n const actionPath = 'themes/dobbies/actions/get-selected-variant.override.action';\n binding.dataActions[actionPath] = require('partner/themes/dobbies/actions/get-selected-variant.override.action');\n registerActionId(actionPath);\n }\n\n { \n const actionPath = 'themes/dobbies/actions/get-store-location-information.override.action';\n binding.dataActions[actionPath] = require('partner/themes/dobbies/actions/get-store-location-information.override.action');\n registerActionId(actionPath);\n }\n\n { \n const actionPath = 'themes/dobbies/actions/update-primary-address.override.action';\n binding.dataActions[actionPath] = require('partner/themes/dobbies/actions/update-primary-address.override.action');\n registerActionId(actionPath);\n }\n\n \n window.__bindings__ = window.__bindings__ || {};\n window.__bindings__.modules = {\n ...window.__bindings__.modules || {},\n ...binding.modules\n };\n \n window.__bindings__.packageDataActions = {};\n window.__bindings__.packageDataActions['__local__'] = {\n ...binding.dataActions\n };","module.exports = React;","module.exports = ReactDOM;"],"names":["CategoryPageSummaryInput","constructor","config","requestContext","getCacheObjectType","getCacheKey","buildCacheKeyWithUrlTokens","this","dataCacheType","createObservableDataAction","id","action","async","input","context","excelUrl","app","plpSeoTSVUrl","excelRes","Msdyn365","currentCategoryResult","getCurrentCategory","inputData","CurrentCategoryInput","Error","createGetCurrentCategoryInput","_unused","currCatUrl","url","requestUrl","href","configCategoryUrl","configCategoryName","configCategoryDesc","canonicalUrlForCategories","Array","isArray","canonicalUrlCatConfig","includes","categoryIDOrUrl","canonicalUrl","canonicalName","canonicalDescription","currentCategory","_objectSpread","categoryUrl","localName","getFriendlyName","locale","NameTranslations","neutralizedName","NeutralizedName","Name","getCategoryUrl","canonicalDomain","toLocaleLowerCase","skipCount","query","skip","Url","URL","urlParams","URLSearchParams","search","set","toString","removeDomainQspFromUrl","undefined","_unused2","catUrl","splittedExcelData","data","split","desc","title","canonical","dataRow","trim","rowSplitted","curl","length","descriptionLimit","substring","description","sharingImageUrl","OfflineImage","faviconUrl","defaultCategoryDescription","sharingImage","src","args","ProductPageSummaryInput","apiSettings","productId","_this$catalogId","buildCacheKey","catalogId","getCatalogId","pdpSeoTSVUrl","prodID","simpleProductsData","_input$catalogId","ArrayExtensions","validValues","getByIdsAsync","callerContext","queryResultSettings","QueryResultSettingsProxy","getPagingFromInputDataOrDefaultValue","channelId","hasElements","simpleProductData","productUrl","productBrand","getProductUrlSync","_input$catalogId2","recordId","productAttributes","getAttributeValuesAsync","productAttribute","TextValue","getProductBrand","_unused3","Description","generateImageUrl","PrimaryImageUrl","RecordId","price","AdjustedPrice","_config$description","getSelectedProductIdFromActionInput","unique","value","from","Set","ProductAvailabilitiesForCartLineItems","getDeliveryMode","cartLine","_channelDeliveryOptio","featureSate","arguments","channelDeliveryOptionConfig","pickupDeliveryMode","DeliveryMode","PickupDeliveryModeCodes","find","deliveryMode","getAvailabilitiesForCartLineItems","ctx","_featureState$find","shippingItems","bopisItems","productAvailabilities","cart","getCartState","channelConfiguration","getOrgUnitConfigurationAsync","products","getActiveCartProductsAction","ActiveCartProductsInput","featureState","getFeatureStateAction","FeatureStateInput","getFeatureState","retailMultiplePickUpOptionEnabled","item","IsEnabled","getChannelDeliveryOptionConfigurationAsync","PickupDeliveryModeCode","EmailDeliveryModeCode","trace","Id","CartLines","push","masterProductIds","productIds","map","x","ProductId","prodIds","_ctx$requestContext$a","getSimpleProducts","sp","MasterProductId","maxQuantityForCartLineItem","inStockCode","inStockLabel","vendorShippedProducts","dobbiesPlantsProducts","dobbiesOtherProducts","dobbiesProductsData","productsByVendor","_getProductsByTypes","plantsProducts","productsData","shippingProductAvailabilites","getShippingProductAvailabilities","ProductWarehouseInventoryAvailabilities","mapProductInventoryInformation","IsProductAvailable","ProductAvailableQuantity","AvailableQuantity","StockLevelCode","StockLevelLabel","InventLocationId","InventLocation","allProductAvailabilities","_getBopisItemAvailability","bopisItem","productWarehouse","WarehouseId","channel","InventLocationDataAreaId","DataAreaId","getProductWarehouseAvail","getEstimatedProductWarehouseAvailabilityAsync","bypassCache","productWarehouseMapping","fulfillmentAttributeName","fulfillmentAttributeTextValue","searchCriteriaInput","Context","ChannelId","CatalogId","Ids","IncludeAttributes","searchByCriteriaAsync","product","AttributeValues","mp","attributes","isvendorShippedAttribute","attribute","toLowerCase","_fulfillmentTypeAttri","attributeName","attributeTextValue","fulfillmentTypeAttribute","_attribute$Name","ExtensionProperties","uniqueProductList","otherProductAvailablities","getEstimatedAvailabilityAsync","ProductIds","DefaultWarehouseOnly","plantsProductAvailablities","FilterByChannelFulfillmentGroup","plantProduct","_shippingProductAvail","accumulatedInventorySum","getAccumulatedTotalAvailable","warehouseIdsForFulfillment","accumulatedProductPhysicalAvailable","fulfillmentStores","filter","availability","store","PhysicalAvailable","productInventoryAvailability","_mapToWarehouseInventoryAvailability","error","telemetry","totalAvailable","outOfStockCode","outOfStockLabel","PhysicalInventory","TotalAvailable","TotalAvailableInventoryLevelLabel","TotalAvailableInventoryLevelCode","PhysicalAvailableInventoryLevelLabel","PhysicalAvailableInventoryLevelCode","CategoriesInput","mappedToHierarchy","maxItems","_context$apiSettings","generateCacheKey","_requestContext","key","_mappedToHierarchy","Number","getCategoryAction","CategoriesDataActions","_inputData$config","topItems","topCategories","parseInt","includeRootCategory","sitePath","getLocale","nameTranslations","nameTranslation","Language","Text","mapCategoryToHierarchy","categoryList","_rootCategory$Childre","categoryMap","category","categoryHierarchy","rootCategory","Object","values","parentId","ParentCategory","parent","Children","createCategoriesHierarchyInput","getCategoryHierarchyAction","categories","RawCategoriesInput","getCategoryHierarchyActionDataAction","CurrentCategoryHierarchyInput","activeCategoryId","super","_activeCategoryId","_inputData$requestCon","urlTokens","pageType","itemId","categoryId","activeCategoryParsedId","findCategoryHierarchy","innerCategoryHierarchy","getCurrentCategoryHierarchyAction","_findCategoryHierarch","fullCategoryHierarchyWithCallableAction","reverse","getCurrentCategoryHierarchyActionDataAction","GetCustomerAddressInput","addresses","featureNames","createGetFeatureStateInput","getFeatureStatesAsync","getFeatureStateActionDataAction","GetFullAvailableInventoryNearbyInput","_productId","_latitude","_longitude","_radius","_DistanceUnitValue","_IgnoreLocation","_ExcludeLocations","latitude","longitude","radius","DistanceUnitValue","IgnoreLocation","ExcludeLocations","createGetFullAvailableInventoryNearbyInput","getFullAvailableInventoryNearbyAction","searchArea","Latitude","Longitude","Radius","retailMulitplePickupMFeatureState","searchCriteria","createInventoryAvailabilitySearchCriteria","pickup","then","productInventoryInformation","productWarehouseInformation","getOrgUnitLocationsByAreaAsync","DeliveryModeTypeFilter","None","_input$ExcludeLocatio","storeMap","Map","stores","forEach","InventoryLocationId","locationDeliveryOptions","orgUnitChannel","channelCollection","channelIdList","getChannelDeliveryOptionsAsync","channelDeliveryOptions","catch","message","exception","debug","_getLocationPickUpDeliveryModes","excludedStores","availabilityPromiseList","sort","a","b","OrgUnitName","localeCompare","_locationDeliveryOpti","locationDeliveryOption","_channeldeliveryoption","orgUnitLocation","channelDeleiveryOptions","OrgUnitNumber","OrgUnitAvailability","getStoreHoursAsync","hours","itemAvailabilities","element","_element$ProductAvail","has","OrgUnitLocation","ItemAvailabilities","ProductInventoryInformation","OrgUnitPickUpDeliveryModes","StoreHours","_getAvailabilityWithHours","Promise","all","getFullAvailableInventoryNearbyActionDataAction","GetLoyaltyCardInput","userAccountNumber","createGetLoyaltyCardInput","user","isAuthenticated","customerAccountNumber","getLoyaltyAction","getCustomerLoyaltyCardsAsync","cards","tempCard","card","CardTenderTypeValue","firstCard","getLoyaltyCardAsync","CardNumber","LoyaltyEnrollmentDate","LoyaltyEnrollmentDateLocal","getLoyaltyActionDataAction","ProductAvailabilitiesForSelectedVariantInput","createProductAvailabilitiesForSelectedVariantInput","getProductAvailabilitiesForSelectedVariantAction","selectedVariantInput","SelectedVariantInput","getSelectedVariant","productResult","ItemTypeValue","isVendorShipAttribute","isPreSale","vendorShipProductInventory","isPlantCategory","response","accumulatedAvailability","getAccumulatedAvailability","mergeProductWarehouseToProductAvailabities","productsWarehouseInventory","productAvailable","accumulatedProductCount","mapWarehouseAvailabilityForAccumulatedCount","productAvailability","cartState","defaultOrderQuantityLimitsFeatureConfig","platform","enableDefaultOrderQuantityLimits","resolve","featureStates","isQuantityLimitsFeatureEnabledInHq","_featureStates$find","getCustomer","GetCustomerInput","customerInfo","IsB2b","warning","isOrderQuantityLimitsFeatureEnabled","_cart$CartLines","productIdsByWarehouseId","resultProducts","_productIdsByWarehous","get","_ref","entryWarehouseId","entryProductIds","ProductInput","Boolean","reduce","accum","getActiveCartProductsActionWhenQuantityLimitsFeatureIsOn","hasInvoiceLine","productWithVendorInfo","_getProductsVendorInfo","actionContext","restrictedProducts","getRestrictedProducts","baseUrl","restrictedInfo","Key","Value","BooleanValue","isVendorShiped","extensionProperties","selectedAttributes","isVendorNameAvailable","selectedAttribute","commercePropertyValue","StringValue","commerceProperty","vendorname","estimatedShippingTime","generateProductImageUrl","imageUrl","startsWith","baseImageUrl","encodeURIComponent","matchingDimensionValues","getByIdAsync","baseProduct","_input$matchingDimens2","baseProductHadUnmatchedDimension","Dimensions","dimension","_input$matchingDimens","matchedTargetDimension","targetDimension","DimensionTypeValue","DimensionValue","variants","getVariantsByDimensionValuesAsync","defaultComponent","getDefaultComponentsAsync","variantsByComponent","getVariantsByComponentsInSlotsAsync","_variantsByComponent$","variantId","simpleProduct","updatedKitProduct","newImageUrl","GetOrgUnitLocationsByAreaInput","_Latitude","_Longitude","_Radius","createGetOrgUnitLocationsByAreaInput","getOrgUnitLocationsByArea","alphabeticallySortedStores","locationPromiseList","_getLocationWithHours","updatePrimaryAddressHandler","customer","address","Addresses","setPrimaryAddress","updatePrimaryAddressAction","_customer$Addresses","readAsync","updatedCustomer","updateAsync","update","updatePrimaryAddressActionDataAction","createAddressManagementInput","isBatched","primaryAddresses","addr","IsPrimary","InventoryLevels","enableStockCheck","inventoryLevel","_filteredProduct$Attr","_filteredProduct$Attr2","_filteredProduct$Attr3","filteredProduct","prod","presell","proAttr","IsVendershipProduct","FulfillmentType","physicalProductMap","mapInventoryWithPhysicalBufferEnabled","totalAvailableProductMap","mapInventoryWithTotalAvailableBufferEnabled","productMap","mapInventoryWithThresholdEnabled","productWarehouseInventoryAvailability","productQty","outOfStockThreshold","productAvailableQuantity","shouldRenderLabel","displayLabelEnabled","productQuantity","inventoryCode","inventoryRanges","axios","require","attributesBaseUrl","_getRestrictedPostCodes","attr","JSON","parse","RestrictedPostCode","method","headers","authority","accept","appsessionid","contenttype","oun","pragma","prefer","requestid","usersessionid","console","log","binding","modules","dataActions","registerActionId","actionPath","default","prototype","keys","exportName","Action","window","__bindings__","packageDataActions","module","exports","React","ReactDOM"],"sourceRoot":""}