@clickview/lite 0.69.1-dev.0 → 0.69.1-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/dist/bundles.json +1 -1
  2. package/dist/css/{2636-lite-f995954232.chunk.css → 6078-lite-4d1b877b3f.chunk.css} +4 -0
  3. package/dist/css/{1239-lite-8152f713c8.chunk.css → 7210-lite-a568e8ec1e.chunk.css} +1 -0
  4. package/dist/scripts/1210-7afb28caac-lite.chunk.js +2 -0
  5. package/dist/scripts/1210-7afb28caac-lite.chunk.js.map +1 -0
  6. package/dist/scripts/232-1522c00252-lite.chunk.js +3 -0
  7. package/dist/scripts/232-1522c00252-lite.chunk.js.map +1 -0
  8. package/dist/scripts/300-3d9f3cd4e3-lite.chunk.js +2 -0
  9. package/dist/scripts/300-3d9f3cd4e3-lite.chunk.js.map +1 -0
  10. package/dist/scripts/3079-0a333d6805-lite.chunk.js +2 -0
  11. package/dist/scripts/3079-0a333d6805-lite.chunk.js.map +1 -0
  12. package/dist/scripts/3110-eee18143c6-lite.chunk.js +2 -0
  13. package/dist/scripts/3110-eee18143c6-lite.chunk.js.map +1 -0
  14. package/dist/scripts/312-693aa30814-lite.chunk.js +2 -0
  15. package/dist/scripts/312-693aa30814-lite.chunk.js.map +1 -0
  16. package/dist/scripts/4229-477b1858dc-lite.chunk.js +2 -0
  17. package/dist/scripts/4229-477b1858dc-lite.chunk.js.map +1 -0
  18. package/dist/scripts/{4845-f3646fb657-lite.chunk.js → 4845-9b4657e696-lite.chunk.js} +2 -2
  19. package/dist/scripts/4845-9b4657e696-lite.chunk.js.map +1 -0
  20. package/dist/scripts/5679-b40a221c78-lite.chunk.js +2 -0
  21. package/dist/scripts/5679-b40a221c78-lite.chunk.js.map +1 -0
  22. package/dist/scripts/6046-104677f08c-lite.chunk.js +2 -0
  23. package/dist/scripts/6046-104677f08c-lite.chunk.js.map +1 -0
  24. package/dist/scripts/6078-0bc71f8768-lite.chunk.js +2 -0
  25. package/dist/scripts/6078-0bc71f8768-lite.chunk.js.map +1 -0
  26. package/dist/scripts/{6188-e108abca25-lite.chunk.js → 6188-77fc2f3ec5-lite.chunk.js} +2 -2
  27. package/dist/scripts/6188-77fc2f3ec5-lite.chunk.js.map +1 -0
  28. package/dist/scripts/6351-dff9edbb16-lite.chunk.js +3 -0
  29. package/dist/scripts/6351-dff9edbb16-lite.chunk.js.map +1 -0
  30. package/dist/scripts/6973-c4cb114bd7-lite.chunk.js +2 -0
  31. package/dist/scripts/6973-c4cb114bd7-lite.chunk.js.map +1 -0
  32. package/dist/scripts/7210-d8fa7ca624-lite.chunk.js +3 -0
  33. package/dist/scripts/7210-d8fa7ca624-lite.chunk.js.map +1 -0
  34. package/dist/scripts/7482-13e6f78c32-lite.chunk.js +2 -0
  35. package/dist/scripts/7482-13e6f78c32-lite.chunk.js.map +1 -0
  36. package/dist/scripts/9040-be65e4eb1e-lite.chunk.js +2 -0
  37. package/dist/scripts/9040-be65e4eb1e-lite.chunk.js.map +1 -0
  38. package/dist/scripts/{bundle-90d3c7fd15.min.js → bundle-bad2e20859.min.js} +3 -3
  39. package/dist/scripts/{bundle-90d3c7fd15.min.js.map → bundle-bad2e20859.min.js.map} +1 -1
  40. package/package.json +1 -1
  41. package/dist/scripts/1210-3cbdc62b0a-lite.chunk.js +0 -2
  42. package/dist/scripts/1210-3cbdc62b0a-lite.chunk.js.map +0 -1
  43. package/dist/scripts/1239-ed9b8aadb4-lite.chunk.js +0 -3
  44. package/dist/scripts/1239-ed9b8aadb4-lite.chunk.js.map +0 -1
  45. package/dist/scripts/2636-63e5f2c9e6-lite.chunk.js +0 -2
  46. package/dist/scripts/2636-63e5f2c9e6-lite.chunk.js.map +0 -1
  47. package/dist/scripts/3036-d18c598435-lite.chunk.js +0 -2
  48. package/dist/scripts/3036-d18c598435-lite.chunk.js.map +0 -1
  49. package/dist/scripts/4229-75ba28a266-lite.chunk.js +0 -2
  50. package/dist/scripts/4229-75ba28a266-lite.chunk.js.map +0 -1
  51. package/dist/scripts/4266-e856b96643-lite.chunk.js +0 -3
  52. package/dist/scripts/4266-e856b96643-lite.chunk.js.map +0 -1
  53. package/dist/scripts/4598-f326dc1aec-lite.chunk.js +0 -2
  54. package/dist/scripts/4598-f326dc1aec-lite.chunk.js.map +0 -1
  55. package/dist/scripts/4845-f3646fb657-lite.chunk.js.map +0 -1
  56. package/dist/scripts/6046-44c115a89c-lite.chunk.js +0 -2
  57. package/dist/scripts/6046-44c115a89c-lite.chunk.js.map +0 -1
  58. package/dist/scripts/6188-e108abca25-lite.chunk.js.map +0 -1
  59. package/dist/scripts/6317-49be898c73-lite.chunk.js +0 -2
  60. package/dist/scripts/6317-49be898c73-lite.chunk.js.map +0 -1
  61. package/dist/scripts/6973-ede6601614-lite.chunk.js +0 -2
  62. package/dist/scripts/6973-ede6601614-lite.chunk.js.map +0 -1
  63. package/dist/scripts/7075-9a76ce47c9-lite.chunk.js +0 -3
  64. package/dist/scripts/7075-9a76ce47c9-lite.chunk.js.map +0 -1
  65. package/dist/scripts/9040-9393c59004-lite.chunk.js +0 -2
  66. package/dist/scripts/9040-9393c59004-lite.chunk.js.map +0 -1
  67. /package/dist/css/{3036-lite-1b3e9aa905.chunk.css → 3079-lite-1b3e9aa905.chunk.css} +0 -0
  68. /package/dist/css/{7075-lite-a377febbb0.chunk.css → 6351-lite-a377febbb0.chunk.css} +0 -0
  69. /package/dist/scripts/{4266-e856b96643-lite.chunk.js.LICENSE.txt → 232-1522c00252-lite.chunk.js.LICENSE.txt} +0 -0
  70. /package/dist/scripts/{1239-ed9b8aadb4-lite.chunk.js.LICENSE.txt → 6351-dff9edbb16-lite.chunk.js.LICENSE.txt} +0 -0
  71. /package/dist/scripts/{7075-9a76ce47c9-lite.chunk.js.LICENSE.txt → 7210-d8fa7ca624-lite.chunk.js.LICENSE.txt} +0 -0
  72. /package/dist/scripts/{bundle-90d3c7fd15.min.js.LICENSE.txt → bundle-bad2e20859.min.js.LICENSE.txt} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scripts/3079-0a333d6805-lite.chunk.js","mappings":"kMACA,SAAgB,QAAU,QAAQ,OAAS,S,sGCQ3C,IAAMA,EAAY,2BAEZC,EAAc,UAIdC,EAAe,UAAa,CAHf,UACA,YAIbC,EAAgB,CAAE,EAAG,IAAM,IAAM,GAAK,IAAM,GAElD,SAASC,EAAmBC,EAAeC,GACzC,OAAKD,EAGEH,EAAaG,EAAQC,GAAKC,MAFxBN,CAGX,CAEA,SAASO,EAAYC,EAAgBH,GAGnC,IAFA,IAAMI,EAAqB,GAElBC,EAAI,EAAGA,EAAIF,EAAKG,OAAQD,IAAK,CACpC,IAAME,EAAgBF,EAAI,GAAKF,EAAKE,EAAI,GAClCG,EAAeL,EAAKE,GACpBI,EAAYJ,EAAIF,EAAKG,OAAS,GAAKH,EAAKE,EAAI,GAM9CG,IAAiBD,GAAiBC,IAAiBC,GAGvDL,EAASM,KAAK,GAAD,OAAIZ,EAAmBU,EAAcR,GAAI,YAAI,IAAMG,EAAKG,OAASD,EAAC,KAChF,CAED,MAAO,6BAAP,OAAoCD,EAASO,KAAK,KAAI,IACxD,CAEM,SAAUC,IACd,IAAMZ,EAAMa,KAAKb,IAAG,MAARa,KAAYhB,GAClBiB,EAA8B,IAAMjB,EAAcS,OAExD,OACE,uBAAKS,UAAU,wCACb,gBAACC,EAAA,EAAI,CAACtB,UAAWA,EAAWuB,OAAO,SACnC,uBAAKF,UAAS,kCAA6B,WACxClB,EAAcqB,KAAI,SAACC,EAAKC,GAAG,OAC1B,uBACEC,IAAKD,EACLE,MAAO,CACLC,MAAO,GAAF,OAAKT,EAA2B,KACrCU,gBAAiB1B,EAAmBqB,EAAKnB,KAE3C,KAGN,gBAACgB,EAAA,EAAI,CAACtB,UAAWA,EAAWuB,OAAO,SAGzC,CAQM,SAAUQ,EAAkBC,G,UAC1BC,GAAU,OAAeD,EAAME,YAC/B5B,EAAe,QAAT,EAAA0B,EAAM1B,WAAG,QAAIa,KAAKb,IAAG,MAARa,K,+CAAYc,I,mjBAErC,OACE,uBACEZ,UAAS,yBAAoB,UAAc,YAAmB,QAAf,EAAAW,EAAMX,iBAAS,QAAI,IAClEO,MAAO,CACLO,WAAY3B,EAAYyB,EAAS3B,KAIzC,C,2FC9EM8B,EAAY,qBADA,yBAuBZ,SAAUC,EAAkBC,EAAyBC,GACzD,OAAKD,EAGAC,GAGE,SA3BqBC,EA2BqB,cAAeF,EAAOA,EAAKG,YAAcH,EAAKE,GAlBzFE,GAAQ,GAAD,OAAIF,GAAE,OAAGrB,KAAKwB,OAAO,IAAIC,MAAQC,aAAe,IAEtD,CACLC,aAAc,CAAE,KAAQ,MACxBC,UAAW,IACXnC,OAAQ,EACRgB,MAAO,UACPc,KAAAA,KASO,cAAeJ,EAAOA,EAAKG,YAAc,gBAAuBH,GAHhE,GAtBX,IAA8BE,EAStBE,CAmBR,CAEM,SAAUM,EAAeC,EAAmBC,GAChD,IAAMC,EAAW,CACfF,UAAWA,EACXR,YAAaL,EAAU,kBAGzB,OAAKa,GAAcC,GAGCA,EAAaD,IAFxBE,CAQX,CAEM,SAAUC,EAAqBC,EAAwBH,GAC3D,OAAIG,EAAOf,KACFe,EAAOf,KAETU,EAAeK,EAAOJ,UAAWC,EAC1C,C,iBC1DM,SAAUI,EAAepB,GAC7B,OAAQ,IAAIqB,MAAMpC,KAAKqC,KAAKtB,EAAWuB,gBAAiBC,KAAK,MAAMlC,KAAI,SAACmC,EAAGjC,GAAG,OAAKQ,EAAWD,QAAQP,IAAQ,CAAC,GACjH,C,+DC0CYkC,E,8BA3BZ,SAASC,EAAe7B,GACtB,IAAM8B,EAAM,eAAkB,SAACC,GAC7B,GAAKA,EAAL,CAGA,IAAMC,EAASD,EAAOE,EAAEC,QAAQ7D,MAC1B8D,EAAgB,EAAIhD,KAAKiD,GAAKJ,EAC9BK,EAASF,EAAgBnC,EAAMsC,WAAaH,EAElDJ,EAAOnC,MAAM2C,gBAAkB,GAAH,OAAMJ,EAAa,YAAIA,GACnDJ,EAAOnC,MAAM4C,iBAAmBH,EAAOI,UAP/B,CAQV,GAAG,CAACzC,EAAMsC,aAEV,OACE,2BACE,0BAAQL,GAAG,QAAgBjC,EAAM0C,MAAOrD,UAAW,yBACjD,QAAUW,EAAMsC,aAChB,0BACER,IAAKA,EACLG,GAAG,QAAgBjC,EAAM0C,MACzBrD,WAAW,QAAmBW,EAAMsC,WAAYtC,EAAM2C,mBAKhE,CAsBM,SAAUC,EAAoB5C,G,MAC5B6C,GAAoB,QAAqB7C,EAAMsC,YAE/CI,EAAO1C,EAAM0C,OAChB1C,EAAM8C,SAAWlB,EAA0BmB,YACxC,WACA,YAGAC,EAAQhD,EAAMiD,cAAe,QAAuBJ,GAE1D,OAAI7C,EAAM8C,SAAWlB,EAA0BsB,UAE3C,wBAAM7D,WAAW,QAA0BwD,IACxCG,GAKL,uBAAK3D,UAAS,4DAAsE,QAAf,EAAAW,EAAMX,iBAAS,QAAI,KACrFW,EAAM8C,SAAWlB,EAA0BuB,aAC1C,wBAAM9D,UAAU,QACb2D,GAGL,uBAAK3D,WAAW,QAA4BqD,EAAMG,IAChD,gBAAChB,EAAc,CAACS,WAAYO,EAAmBH,KAAMA,EAAMC,gBAAiB3C,EAAM2C,kBACjF3C,EAAM8C,SAAWlB,EAA0BmB,aAC1C,wBAAM1D,UAAW,2BACd2D,IAMb,EAvDA,SAAYpB,GACV,2BACA,yBACA,6BACA,4BACD,CALD,CAAYA,IAAAA,EAAyB,KAgBrCgB,EAAoBQ,aAAe,CACjCN,OAAQlB,EAA0ByB,W,6uBC3DpC,IAKYC,EAHNC,EAAsB,GACtBC,EAAyB,KAE/B,SAAYF,GACV,gBACA,gBACA,yBACD,CAJD,CAAYA,IAAAA,EAAkB,KAM9B,IAAMG,EAAwB,EAAH,OACxBH,EAAmBI,WAAa,CAC/BhB,KAbiB,IAelBY,EAAmBK,MAAQ,CAC1BjB,KAhBiB,IAkBlBY,EAAmBM,MAAQ,CAC1BlB,KAlBoB,MAyBlB,SAAUmB,EAAgBnB,GAC9B,IAAM7C,EAAQ4D,EAAsBf,GAAMA,KACpCoB,EAAcpB,IAASY,EAAmBM,MAAQJ,EAAyBD,EACjF,MAAO,GAAP,OAAU1D,EAAQ,EAAkB,EAAdiE,EAAe,MACvC,CAEM,SAAUC,EACdzB,GACyD,IAAzDK,EAAA,uDAAmC,IAEnC,OAAIL,GAAcK,EAAgBqB,KACzB,kBAEL1B,GAAcK,EAAgBsB,SACzB,kBAEF,gBACT,CAEM,SAAUC,EACd5B,GACyD,IAAzDK,EAAA,uDAAmC,IAEnC,OAAIL,GAAcK,EAAgBqB,KACzB,eAEL1B,GAAcK,EAAgBsB,SACzB,eAEF,aACT,CAEM,SAAUE,EAA4BzB,EAA0BJ,GACpE,IAAIjD,EAAY,kBAAH,OAAqB,qBAWlC,OATIqD,IAASY,EAAmBM,QAC9BvE,GAAa,IAAJ,OAAQ,wBAEfqD,IAASY,EAAmBI,aAC9BrE,GAAa,IAAJ,OAAQ,wBAEf+E,EAAU9B,KACZjD,GAAa,IAAJ,OAAQ,oBAEZA,CACT,CAEM,SAAUgF,EAAqB/B,GACnC,IAAI8B,EAAU9B,GAGd,OAAQA,EAAWgC,QAAQ,EAC7B,CAEM,SAAUC,EAAuBjC,GACrC,OAAI8B,EAAU9B,GACL,MAEF,GAAP,OAAUnD,KAAKqF,MAAmB,IAAblC,GAAiB,IACxC,CAEM,SAAU8B,EAAU9B,GACxB,MAA6B,iBAAfA,CAChB,C,2CC5FO,IAAMmC,EAA0C,CACrDT,KAAM,IACNC,SAAU,IAGCS,EAA0C,CACrDV,KAAM,GACNC,SAAU,G,mCCVL,IAAMU,EAAuB,CAClCC,YAAW,WACT,MAAO,CACLC,IAAK,mCACLlF,IAAK,mBACLmF,WAAW,EAEf,EAEAC,oBAAmB,WACjB,MAAO,CACLF,IAAK,4CACLlF,IAAK,4BACLmF,WAAW,EAEf,EAEAE,mBAAkB,WAChB,MAAO,CACLH,IAAK,2CACLlF,IAAK,2BACLmF,WAAW,EAEf,EAEAG,WAAU,WACR,MAAO,CACLJ,IAAK,mCACLlF,IAAK,mBACLmF,WAAW,EAEf,EAEAI,MAAK,WACH,MAAO,CACLL,IAAK,6BACLlF,IAAK,aACLmF,WAAW,EAEf,EAEAK,kBAAiB,WACf,MAAO,CACLN,IAAK,0CACLlF,IAAK,0BACLmF,WAAW,EAEf,EAEAM,iBAAgB,WACd,MAAO,CACLP,IAAK,yCACLlF,IAAK,yBACLmF,WAAW,EAEf,E,6DCrDI,SAAUO,IACd,aAAgB,WAEd,OADA,uBACO,kBAAM,wBAAiC,CAChD,GAAG,GACL,C,8GCMMjF,EAAY,qBADA,yBAKLkF,EAAyC,CACpDC,MAAO,CACLC,QAAS,gBACTC,KAAM,UAERC,aAAc,KACdC,gBAAiB,KACjBC,WAAY,aAAoB,IAAIhF,KATR,EASuC,QAAQiF,cAC3EC,UAAW,IAGPC,EAAsC,CAC1CC,YAAa,cACbC,OAAQ,wCAGGC,EAAsC,CACjDC,QAAS,eACTnD,MAAO5C,EAAU,gBACjBgG,QAASL,EACTM,MAAO,WACPhH,UAAW,uB,iWCtBPrB,EAAY,yBACZoC,EAAYkG,EAAA,mBAAiCtI,GAO7C,SAAUuI,EAAcvG,GAC5B,IAAMwG,EAAgBxG,EAAMyG,OAC1BC,EAAA,iBAA+B,CAC7BC,OAAQ3G,EAAMyG,MACdG,aAAc5G,EAAMyG,MAAMI,OAC1BC,eAAe,EACfC,oBAAqB,KACrBC,eAAgB,KAChBC,QAAS,CACPA,QAAS,SACTC,sBAAsB,GAExBC,OAAQC,EAAA,SACRC,WAAY,OAGhB,OACE,uBAAKhI,UAAU,QACb,sBAAIA,UAAU,MAAK,gBAACC,EAAA,EAAI,CAACtB,UAAWA,EAAWuB,OAAO,eAEtD,uBAAKF,UAAU,0EACb,uBAAKA,UAAU,mCACb,gBAACiI,EAAA,EAAY,CACX3B,gBAAiB,KACjB4B,YAAavH,EAAMuH,YACnBC,cAAc,EACdC,WAAY,EACZjB,cAAeA,aAAa,EAAbA,EAAekB,OAC9B,IAEF,qBAAGrI,UAAU,SAAQ,QAAW,iBAAoC,IAEpE,qBAAGA,UAAU,QAAO,gBAACC,EAAA,EAAI,CAACtB,UAAWA,EAAWuB,OAAO,QAAQoI,QAAS,CAAEC,MAAO,mBAEnF,gBAACC,EAAA,EAAO,CAACrH,GAAG,cAAcsH,MAAO1H,EAAU,YAAa2H,UAAQ,GAC9D,gBAACC,EAAA,EAAU,CACT5B,SAAS,QAAgBpG,EAAMyG,OAC/BN,QAAS,WACT9G,UAAU,4CAEV,gBAACC,EAAA,EAAI,CAACtB,UAAWA,EAAWuB,OAAO,aAM/C,C,2IChDA,IACM,EAAY+G,EAAA,mBADA,4CAGZ,SAAU2B,I,kBACPC,G,GAAkB,OAAsBC,EAAA,mB,EAAoC,E,o4BAA9D,IAErB,EAAA9C,EAAA,KAEA,IAAM+C,EAAc,kBAAkCC,EAAA,iBAChDC,EAAS,kBAA6BC,EAAA,YAEtCxD,EAAsB,kBAC1BJ,EAAA,yBAGIC,EAAc,kBAAkCD,EAAA,iBAEhD6D,EAAwB,+BACxBC,EAAyB,gCAEzBC,EAAU,kBAA2C/D,EAAA,wBAErDgE,EACyC,KAAb,QAAhC,EAAAH,EAAsBI,kBAAU,eAAEhK,WAAsD,QAArC,EAAA4J,EAAsBK,uBAAe,eAAEjK,QACtFkK,EAAoB,kBAAoDH,GAC5EI,EAAA,uBAAuCC,EAAA,QAAkBR,EAAsBI,cAE3EK,EAAsB,kBAC1BtE,EAAA,sBAGIM,EAAa,kBACjBN,EAAA,iBAGF,EAAAuE,EAAA,GAAmB,CAAEpB,MAAO/C,EAAoBtG,KAAO,EAAU,YAAa,CAAEgI,MAA+B,QAAxB,EAAA1B,EAAoBtG,YAAI,eAAE0K,OAAU,OAE3H,IAAMC,EACJhB,EAAY3J,MACZ6J,EAAO7J,MACPsG,EAAoBtG,MACpBmG,EAAYnG,MACZiK,EAAQjK,QACNkK,GAAuBG,EAAkBrK,OAC3CwK,EAAoBxK,QAClBwG,EAAWxG,KAET4K,EAAS,OAAH,wBACPb,GACAC,GAECa,ECtEF,SAAyC9I,EAAY6I,GACzD,MAAO,CACLE,eAAgB,CACdvD,YAAa,cACbC,OAAQ,uCACRuD,KAAM,CDkER,ICjEEH,OAAAA,GAEFI,iBAAkB,CAChBzD,YAAa,cACbC,OAAQ,wCACRuD,KAAM,CD4DR,IC3DEH,OAAAA,GAEFK,eAAgB,CACd1D,YAAa,cACbC,OAAQ,sCACRuD,KAAM,CDsDR,ICrDEH,OAAAA,GAGN,CDiDsCM,CAClC,EACAN,GAGF,OACE,uBAAKhK,UAAU,QACb,gBAACuK,EAAA,EAAc,CACbnD,MAAO1B,EAAoBtG,KAC3BoL,MAAM,QAAuD,QAAxB,EAAA9E,EAAoBtG,YAAI,eAAE+B,GAAI,WAAY6I,GAC/EZ,uBAAwBA,EACxBqB,QAAM,IAGR,gBAACvD,EAAa,CAACE,MAAO1B,EAAoBtG,KAAM8I,YAAwB,QAAX,EAAAe,EAAO7J,YAAI,eAAE8I,cAE1E,gBAACwC,EAAA,EAA2B,CAC1Bd,oBAAqBA,EAAoBxK,KACzCmG,YAAaA,EAAYnG,KACzBsG,oBAAqBA,EAAoBtG,KACzCqK,kBAAmBA,EAAkBrK,KACrCiK,QAASA,EAAQjK,KACjBwG,WAAYA,EAAWxG,KACvB6J,OAAQA,EAAO7J,KACf6K,4BAA6BA,EAC7BX,qBAAqB,EACrBT,eAAgBA,EAChBmB,OAAQA,EACRD,cAAeA,EACfY,WAAW,IAInB,C,kBE5GA,IAAYC,E,iBAAZ,SAAYA,GACV,cACA,wBACA,cACA,aACD,CALD,CAAYA,IAAAA,EAAS,I,iCCCrB,SAAgB,gBAAkB,QAAQ,iBAAmB,QAAQ,cAAgB,QAAQ,cAAgB,QAAQ,aAAe,QAAQ,kBAAoB,QAAQ,kBAAoB,QAAQ,cAAgB,QAAQ,sBAAwB,Q","sources":["file:///app/packages/libs/shared/src/apps/analytics/components/engagement-heat-map/engagement-heat-map.scss","file:///app/packages/libs/shared/src/apps/analytics/components/engagement-heat-map/EngagementHeatMap.tsx","file:///app/packages/libs/shared/src/apps/analytics/utils/AnonymiseUserUtils.ts","file:///app/packages/libs/shared/src/apps/analytics/utils/EngagementUtils.ts","file:///app/packages/libs/shared/src/components/percentage-indicator/PercentageIndicator.tsx","file:///app/packages/libs/shared/src/components/percentage-indicator/PercentageIndicatorUtils.ts","file:///app/packages/libs/shared/src/constants/ScoreThresholds.ts","file:///app/packages/libs/shared/src/flight-requests/InsightsDemoRequests.ts","file:///app/packages/libs/shared/src/hooks/useLockContentWidth.ts","file:///app/packages/projects/lite/src/apps/my-shares/constants/MySharesDemoInsights.ts","file:///app/packages/projects/lite/src/apps/my-shares/components/share-info/ShareInfoDemo.tsx","file:///app/packages/projects/lite/src/apps/my-shares/views/demo/overview/InteractiveInsightsOverviewDemoView.tsx","file:///app/packages/projects/lite/src/apps/my-shares/views/demo/overview/InteractiveInsightsOverviewDemoUtils.ts","file:///app/packages/projects/lite/src/apps/share-v2/enums/ShareType.ts","file:///app/packages/libs/shared/src/components/percentage-indicator/percentage-indicator.scss"],"sourcesContent":["// extracted by mini-css-extract-plugin\nexport default {\"heatMap\":\"epapa\",\"legend\":\"uhH4p\"};","import React from 'react';\nimport chroma from 'chroma-js';\n\nimport { getFullHeatMap } from 'libs/shared/apps/analytics/utils/EngagementUtils';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Engagement } from 'libs/shared/interfaces';\n\nimport styles from './engagement-heat-map.scss';\n\nconst namespace = 'shared.engagementHeatMap';\n\nconst ZERO_COLOUR = '#f1f1f1';\nconst MIN_COLOUR = '#daf07d';\nconst MAX_COLOUR = '#08bd1a';\n\nconst COLOUR_SCALE = chroma.scale([ MIN_COLOUR, MAX_COLOUR ]);\n\nconst LEGEND_VALUES = [ 0, 0.01, 0.25, 0.5, 0.75, 1 ];\n\nfunction getBackgroundColor(value: number, max: number): string {\n if (!value)\n return ZERO_COLOUR;\n\n return COLOUR_SCALE(value / max).hex();\n}\n\nfunction getGradient(data: number[], max: number): string {\n const gradient: string[] = [];\n\n for (let i = 0; i < data.length; i++) {\n const previousValue = i > 0 && data[i - 1];\n const currentValue = data[i];\n const nextValue = i < data.length - 1 && data[i + 1];\n\n /**\n * We want to capture colour changes but if a value has the same value\n * of both of its neighbours, we can skip it.\n */\n if (currentValue === previousValue && currentValue === nextValue)\n continue;\n\n gradient.push(`${getBackgroundColor(currentValue, max)} ${100 / data.length * i}%`);\n }\n\n return `linear-gradient(to right, ${gradient.join(',')})`;\n}\n\nexport function EngagementHeatMapLegend(): JSX.Element {\n const max = Math.max(...LEGEND_VALUES);\n const legendSquareWidthPercentage = 100 / LEGEND_VALUES.length;\n\n return (\n <div className='d-flex justify-content-between w-100'>\n <Text namespace={namespace} phrase='less' />\n <div className={`d-flex mx-1 flex-grow-1 ${styles.legend}`}>\n {LEGEND_VALUES.map((val, idx) => (\n <div\n key={idx}\n style={{\n width: `${legendSquareWidthPercentage}%`,\n backgroundColor: getBackgroundColor(val, max)\n }}\n />\n ))}\n </div>\n <Text namespace={namespace} phrase='more' />\n </div>\n );\n}\n\ninterface EngagementHeatMapProps {\n engagement: Engagement;\n max?: number;\n className?: string;\n}\n\nexport function EngagementHeatMap(props: EngagementHeatMapProps): JSX.Element {\n const heatMap = getFullHeatMap(props.engagement);\n const max = props.max ?? Math.max(...heatMap);\n\n return (\n <div\n className={`border rounded ${styles.heatMap} ${props.className ?? ''}`}\n style={{\n background: getGradient(heatMap, max)\n }}\n />\n );\n}","import { animals, colors, Config as UniqueNamesConfig, uniqueNamesGenerator } from 'unique-names-generator';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { AnonSession, AnonSessions } from 'libs/shared/apps/analytics/hooks/UseAnonSessions';\nimport { UserOrAnonSession } from 'libs/shared/apps/analytics/interfaces/UserOrAnonSession';\nimport { StudentResults } from 'libs/shared/interfaces';\nimport { UserHelper } from 'libs/shared/utils/UserHelper';\n\nconst namespace = 'shared.analyticsUtils';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nfunction getUniqueNamesConfig(id: string): UniqueNamesConfig {\n /**\n * Generate a seed that is unique to each user but changes every 5 minutes.\n * \n * We use a seed so that if the same user's name is anonymised multiple times\n * in quick succession (e.g. multiple renders), the same name will be returned each time.\n * \n * We change the seed every 5 minutes so that students don't always have the same name.\n */\n const seed = +`${id}${Math.floor((new Date()).getMinutes() / 5)}`;\n\n return {\n dictionaries: [ colors, animals ],\n separator: ' ',\n length: 2,\n style: 'capital',\n seed\n };\n}\n\nexport function anonymiseUserName(user: UserOrAnonSession, shouldAnonymise: boolean): string {\n if (!user)\n return '';\n\n if (!shouldAnonymise)\n return 'sessionId' in user ? user.sessionName : UserHelper.getFullName(user);\n\n return uniqueNamesGenerator(getUniqueNamesConfig('sessionId' in user ? user.sessionName : user.id));\n}\n\nexport function getAnonSession(sessionId: string, anonSessions: AnonSessions): AnonSession {\n const fallback = {\n sessionId: sessionId,\n sessionName: getPhrase('anonymousUser')\n };\n\n if (!sessionId || !anonSessions)\n return fallback;\n\n const anonSession = anonSessions[sessionId];\n\n if (anonSession)\n return anonSession;\n\n return fallback;\n}\n\nexport function getUserOrAnonSession(result: StudentResults, anonSessions: AnonSessions): UserOrAnonSession {\n if (result.user)\n return result.user;\n\n return getAnonSession(result.sessionId, anonSessions);\n}\n","import { Engagement } from 'libs/shared/interfaces';\n\n/**\n * The heat map in the API response won't contain trailing zeros so we need to add those\n * in manually.\n */\nexport function getFullHeatMap(engagement: Engagement): number[] {\n return (new Array(Math.ceil(engagement.videoDuration))).fill(null).map((t, idx) => engagement.heatMap[idx] || 0);\n}","import React from 'react';\n\nimport { ScoreThresholds } from 'libs/shared/constants/ScoreThresholds';\n\nimport {\n getCircleClassName,\n getCircleContainerClassName,\n getCircleRadius,\n getColouredLabelClassName,\n getFormattedPercentage,\n getPercentageToFixed,\n isPending,\n ProgressCircleSize\n} from './PercentageIndicatorUtils';\n\nimport styles from './percentage-indicator.scss';\n\ninterface ProgressCircleProps {\n size: ProgressCircleSize;\n scoreThresholds?: ScoreThresholds;\n percentage?: number;\n}\n\nfunction ProgressCircle(props: ProgressCircleProps): JSX.Element {\n const ref = React.useCallback((circle: SVGCircleElement) => {\n if (!circle)\n return;\n\n const radius = circle.r.baseVal.value;\n const circumference = 2 * Math.PI * radius;\n const offset = circumference - props.percentage * circumference;\n\n circle.style.strokeDasharray = `${circumference} ${circumference}`;\n circle.style.strokeDashoffset = offset.toString();\n }, [props.percentage]);\n\n return (\n <svg>\n <circle r={getCircleRadius(props.size)} className={styles.backgroundCircle} />\n {!isPending(props.percentage) &&\n <circle\n ref={ref}\n r={getCircleRadius(props.size)}\n className={getCircleClassName(props.percentage, props.scoreThresholds)}\n />\n }\n </svg>\n );\n}\n\nexport enum PercentageIndicatorLayout {\n CircleOnly = 'circle_only',\n LabelOnly = 'label_only',\n LabelBefore = 'label_before',\n LabelInside = 'label_inside'\n}\n\ninterface PercentageIndicatorProps {\n layout: PercentageIndicatorLayout;\n percentage?: number; // Between 0 and 1 or undefined for pending\n className?: string;\n customLabel?: string;\n scoreThresholds?: ScoreThresholds;\n size?: ProgressCircleSize;\n}\n\nPercentageIndicator.defaultProps = {\n layout: PercentageIndicatorLayout.CircleOnly\n};\n\nexport function PercentageIndicator(props: PercentageIndicatorProps): JSX.Element {\n const percentageToFixed = getPercentageToFixed(props.percentage);\n\n const size = props.size ||\n (props.layout === PercentageIndicatorLayout.LabelInside\n ? ProgressCircleSize.Large\n : ProgressCircleSize.Small\n );\n\n const label = props.customLabel || getFormattedPercentage(percentageToFixed);\n\n if (props.layout === PercentageIndicatorLayout.LabelOnly)\n return (\n <span className={getColouredLabelClassName(percentageToFixed)}>\n {label}\n </span>\n );\n\n return (\n <div className={`d-flex align-items-center justify-content-between ${props.className ?? ''}`}>\n {props.layout === PercentageIndicatorLayout.LabelBefore &&\n <span className='me-2'>\n {label}\n </span>\n }\n <div className={getCircleContainerClassName(size, percentageToFixed)}>\n <ProgressCircle percentage={percentageToFixed} size={size} scoreThresholds={props.scoreThresholds} />\n {props.layout === PercentageIndicatorLayout.LabelInside &&\n <span className={styles.centredPercentageText}>\n {label}\n </span>\n }\n </div>\n </div>\n );\n}","import { ScoreThresholdDefaults, ScoreThresholds } from 'libs/shared/constants/ScoreThresholds';\n\nimport styles from './percentage-indicator.scss';\n\n/**\n * Values for width and strokeWidth are taken from progress-circle.scss.\n * If either are changed, they must be updated in both places.\n */\nconst CIRCLE_WIDTH = 2; // rem\nconst CIRCLE_WIDTH_LG = 5.8; // rem\nconst CIRCLE_STROKE_WIDTH = 0.2; // rem\nconst CIRCLE_STROKE_WIDTH_LG = 0.36; // rem\n \nexport enum ProgressCircleSize {\n Small = 'small',\n Large = 'large',\n ExtraSmall = 'extraSmall'\n}\n\nconst ProgressCircleSizeMap = {\n [ProgressCircleSize.ExtraSmall]: {\n size: CIRCLE_WIDTH\n },\n [ProgressCircleSize.Small]: {\n size: CIRCLE_WIDTH\n },\n [ProgressCircleSize.Large]: {\n size: CIRCLE_WIDTH_LG\n }\n};\n\n/**\n * radius = width / 2 - strokeWidth * 2\n */\nexport function getCircleRadius(size: ProgressCircleSize): string {\n const width = ProgressCircleSizeMap[size].size;\n const strokeWidth = size === ProgressCircleSize.Large ? CIRCLE_STROKE_WIDTH_LG : CIRCLE_STROKE_WIDTH;\n return `${width / 2 - strokeWidth * 2}rem`;\n}\n \nexport function getCircleClassName(\n percentage: number,\n scoreThresholds: ScoreThresholds = ScoreThresholdDefaults\n): string {\n if (percentage >= scoreThresholds.HIGH)\n return styles.circleSuccess;\n \n if (percentage >= scoreThresholds.MODERATE)\n return styles.circleWarning;\n \n return styles.circleDanger;\n}\n \nexport function getColouredLabelClassName(\n percentage: number,\n scoreThresholds: ScoreThresholds = ScoreThresholdDefaults\n): string {\n if (percentage >= scoreThresholds.HIGH)\n return 'text-success';\n \n if (percentage >= scoreThresholds.MODERATE)\n return 'text-warning';\n \n return 'text-danger';\n}\n \nexport function getCircleContainerClassName(size: ProgressCircleSize, percentage?: number): string {\n let className = `d-inline-block ${styles.circleContainer}`;\n \n if (size === ProgressCircleSize.Large)\n className += ` ${styles.lgCircleContainer}`;\n\n if (size === ProgressCircleSize.ExtraSmall)\n className += ` ${styles.xsCircleContainer}`;\n\n if (isPending(percentage))\n className += ` ${styles.pendingCircle}`;\n \n return className;\n}\n\nexport function getPercentageToFixed(percentage?: number): number | undefined {\n if (isPending(percentage))\n return;\n \n return +percentage.toFixed(2);\n}\n \nexport function getFormattedPercentage(percentage?: number): string {\n if (isPending(percentage))\n return `--%`;\n\n return `${Math.round(percentage * 100)}%`;\n}\n\nexport function isPending(percentage?: number): boolean {\n return typeof percentage !== 'number';\n}","export interface ScoreThresholds {\n HIGH: number;\n MODERATE: number;\n}\n\nexport const ScoreThresholdDefaults: ScoreThresholds = {\n HIGH: 0.75,\n MODERATE: 0.5\n};\n\nexport const ScoreThresholdInsights: ScoreThresholds = {\n HIGH: 0.7,\n MODERATE: 0.7\n};","import { Flight } from 'libs/common/react/index';\n\nexport const InsightsDemoRequests = {\n interactive(): Flight.Request {\n return {\n url: `/mocks/insights/interactive.json`,\n key: `demo:interactive`,\n normalize: false\n };\n },\n\n interactiveMetadata(): Flight.Request {\n return {\n url: `/mocks/insights/interactive-metadata.json`,\n key: `demo:interactive:metadata`,\n normalize: false\n };\n },\n\n interactiveResults(): Flight.Request {\n return {\n url: `/mocks/insights/interactive-results.json`,\n key: `demo:interactive:results`,\n normalize: false\n };\n },\n\n videoViews(): Flight.Request {\n return {\n url: `/mocks/insights/video-views.json`,\n key: `demo:video:views`,\n normalize: false\n };\n },\n\n users(): Flight.Request {\n return {\n url: `/mocks/insights/users.json`,\n key: `demo:users`,\n normalize: false\n };\n },\n\n individualHeatmap(): Flight.Request {\n return {\n url: `/mocks/insights/individual-heatmap.json`,\n key: `demo:individual:heatmap`,\n normalize: false\n };\n },\n\n aggregateHeatmap(): Flight.Request {\n return {\n url: `/mocks/insights/aggregate-heatmap.json`,\n key: `demo:aggregate:heatmap`,\n normalize: false\n };\n }\n};","import React from 'react';\n\nimport { LayoutHelper } from 'libs/shared/utils/LayoutHelper';\n\nexport function useLockContentWidth(): void {\n React.useEffect(() => {\n LayoutHelper.lockContentWidth();\n return () => LayoutHelper.unlockContentWidth();\n }, []);\n}","import { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { DateHelper } from 'libs/common/react/utils/DateHelper';\n\nimport { ActionOptions } from 'libs/shared/components/actions/Actions';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nimport { MySharesTableData } from 'apps/my-shares/components/my-shares-table/MySharesTableUtils';\nimport { ShareType } from 'apps/share-v2/enums/ShareType';\nimport { ShareLink } from 'apps/share-v2/interfaces/ShareLink';\n\nconst namespace = 'myShares.demoInsights';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nconst DEMO_INSIGHT_DAYS_AGO = 7;\n\nexport const DEMO_INSIGHTS_SHARE: MySharesTableData = {\n share: {\n shareId: 'demo-insights',\n type: ShareType.Link\n } as ShareLink,\n sharedObject: null,\n shareRecipients: null,\n dateShared: DateHelper.subtract(new Date(), DEMO_INSIGHT_DAYS_AGO, 'days').toISOString(),\n viewCount: 23\n};\n\nconst DEMO_INSIGHTS_APPLINK: Core.AppLink = {\n application: AppChannels.MY_SHARES,\n action: Actions.MyShares.INTERACTIVE_OVERVIEW_DEMO\n};\n\nexport const DEMO_INSIGHTS_ACTION: ActionOptions = {\n svgName: cvSvgLibrary.Analytics,\n label: getPhrase('demoInsights'),\n appLink: DEMO_INSIGHTS_APPLINK,\n group: 'insights',\n className: 'btn btn-outline-dark'\n};\n","import React from 'react';\nimport { format as formatDate } from 'timeago.js';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { ShareLinkHelper } from 'libs/shared/apps/share/utils/ShareLinkHelper';\nimport { IconButton } from 'libs/shared/components/icon-button/IconButton';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { ShareLinkStatus } from 'libs/shared/enums/ShareLinkStatus';\nimport { VideoTypes } from 'libs/shared/interfaces';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nimport { getShareAppLink } from 'shared/utils/ObjectAppLinkHelper';\n\nimport { SharedToPill } from 'apps/my-shares/components/shared-to-pill/SharedToPill';\nimport { DEMO_INSIGHTS_SHARE } from 'apps/my-shares/constants/MySharesDemoInsights';\n\nconst namespace = 'insights.shareInfoDemo';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface ShareInfoDemoProps {\n video: VideoTypes;\n imageCdnUrl: string;\n}\n\nexport function ShareInfoDemo(props: ShareInfoDemoProps) {\n const shareLinkText = props.video &&\n ShareLinkHelper.getIconAndText({\n entity: props.video,\n entityTypeId: props.video.typeId,\n hasStudentExp: false,\n isPasswordProtected: null,\n linkExpireDate: null,\n privacy: {\n privacy: 'public',\n overrideRestrictions: false\n },\n status: ShareLinkStatus.Active,\n yearGroups: null\n });\n\n return (\n <div className='mb-4'>\n <h2 className='h4'><Text namespace={namespace} phrase='shareInfo' /></h2>\n\n <div className='d-flex border p-3 rounded-3 align-items-center justify-content-between'>\n <div className='d-flex align-items-center gap-2'>\n <SharedToPill\n shareRecipients={null}\n imageCdnUrl={props.imageCdnUrl}\n hasShareLink={true}\n maxAvatars={4}\n shareLinkText={shareLinkText?.text}\n />\n ·\n <p className='mb-0'>{formatDate(DEMO_INSIGHTS_SHARE.dateShared)}</p>\n ·\n <p className='mb-0'><Text namespace={namespace} phrase='views' options={{ count: DEMO_INSIGHTS_SHARE.viewCount }} /></p>\n </div>\n <Tooltip id='shareButton' title={getPhrase('demoOnly')} spanHack>\n <IconButton\n appLink={getShareAppLink(props.video)}\n svgName={cvSvgLibrary.Share}\n className='btn btn-outline-dark pointer-events-none'\n >\n <Text namespace={namespace} phrase='share' />\n </IconButton>\n </Tooltip>\n </div>\n </div>\n );\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { useViewModel } from 'libs/common/react/hooks/UseViewModel';\nimport { Flight } from 'libs/common/react/index';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { BaseAnalyticsEventResponse } from 'libs/shared/apps/analytics/interfaces/BaseAnalyticsEvent';\nimport { AnalyticsFilterHelper } from 'libs/shared/apps/analytics/utils/AnalyticsFilterUtils';\nimport { SharedViewModelKeys } from 'libs/shared/constants/SharedViewModelKeys';\nimport { ConfigRequests } from 'libs/shared/flight-requests/ConfigRequests';\nimport { InsightsDemoRequests } from 'libs/shared/flight-requests/InsightsDemoRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useLockContentWidth } from 'libs/shared/hooks/useLockContentWidth';\nimport { useSetPageMetadata } from 'libs/shared/hooks/useSetPageMetadata';\nimport { BasePaginatedCollection, Config, CurrentUser, Engagement, Interactive, InteractiveMetadata, InteractiveResultSet, User } from 'libs/shared/interfaces';\n\nimport { ClassroomRequests } from 'apps/classrooms/flight-requests/ClassroomRequests';\nimport { InsightsHeader } from 'apps/my-shares/components/insights-header/InsightsHeader';\nimport { InteractiveInsightsOverview } from 'apps/my-shares/components/interactive-insights-overview/InteractiveInsightsOverview';\nimport { ShareInfoDemo } from 'apps/my-shares/components/share-info/ShareInfoDemo';\nimport { getInsightsDemoInteractiveTabs } from 'apps/my-shares/utils/InsightsAppLinkUtils';\nimport { getInteractiveInsightsAppLinks } from 'apps/my-shares/views/demo/overview/InteractiveInsightsOverviewDemoUtils';\n\nconst namespace = 'insights.interactiveInsightsOverviewView';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport function InteractiveInsightsOverviewDemoView() {\n const [anonymiseUsers] = useViewModel<boolean>(SharedViewModelKeys.ANONYMISE_USERS);\n\n useLockContentWidth();\n\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n\n const interactiveMetadata = Flight.useBasicFetch<InteractiveMetadata>(\n InsightsDemoRequests.interactiveMetadata()\n );\n\n const interactive = Flight.useBasicFetch<Interactive>(InsightsDemoRequests.interactive());\n\n const audienceAppLinkParams = AnalyticsFilterHelper.getAudienceAppLinkParams();\n const dateRangeAppLinkParams = AnalyticsFilterHelper.getDateRangeAppLinkParams();\n\n const results = Flight.useBasicFetch<InteractiveResultSet>(InsightsDemoRequests.interactiveResults());\n\n const classroomFilterOnly =\n audienceAppLinkParams.classrooms?.length === 1 && !audienceAppLinkParams.classroomGroups?.length;\n const classroomStudents = Flight.useBasicFetch<BasePaginatedCollection<User>>(classroomFilterOnly &&\n ClassroomRequests.getClassroomStudents(ArrayHelper.first(audienceAppLinkParams.classrooms)));\n\n const aggregateEngagement = Flight.useBasicFetch<Engagement>(\n InsightsDemoRequests.aggregateHeatmap()\n );\n\n const videoViews = Flight.useBasicFetch<BaseAnalyticsEventResponse>(\n InsightsDemoRequests.videoViews()\n );\n\n useSetPageMetadata({ title: interactiveMetadata.data ? getPhrase('pageTitle', { video: interactiveMetadata.data?.name }) : null });\n\n const hasDataLoaded =\n currentUser.data &&\n config.data &&\n interactiveMetadata.data &&\n interactive.data &&\n results.data &&\n (!classroomFilterOnly || classroomStudents.data) &&\n aggregateEngagement.data &&\n !!videoViews.data;\n\n const params = {\n ...audienceAppLinkParams,\n ...dateRangeAppLinkParams\n };\n const interactiveInsightsAppLinks = getInteractiveInsightsAppLinks(\n '',\n params\n );\n\n return (\n <div className='px-3'>\n <InsightsHeader\n video={interactiveMetadata.data}\n tabs={getInsightsDemoInteractiveTabs(interactiveMetadata.data?.id, 'insights', params)}\n dateRangeAppLinkParams={dateRangeAppLinkParams}\n isDemo\n />\n\n <ShareInfoDemo video={interactiveMetadata.data} imageCdnUrl={config.data?.imageCdnUrl} />\n\n <InteractiveInsightsOverview\n aggregateEngagement={aggregateEngagement.data}\n interactive={interactive.data}\n interactiveMetadata={interactiveMetadata.data}\n classroomStudents={classroomStudents.data}\n results={results.data}\n videoViews={videoViews.data}\n config={config.data}\n interactiveInsightsAppLinks={interactiveInsightsAppLinks}\n classroomFilterOnly={false}\n anonymiseUsers={anonymiseUsers}\n params={params}\n hasDataLoaded={hasDataLoaded}\n hasShared={true}\n />\n </div>\n );\n}","import { HashObject } from 'libs/common/react/interfaces';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nexport function getInteractiveInsightsAppLinks(id: string, params?: HashObject) {\n return {\n resultsAppLink: {\n application: AppChannels.MY_SHARES,\n action: Actions.MyShares.INTERACTIVE_STUDENTS_DEMO,\n args: [id],\n params\n },\n questionsAppLink: {\n application: AppChannels.MY_SHARES,\n action: Actions.MyShares.INTERACTIVE_QUESTIONS_DEMO,\n args: [id],\n params\n },\n heatmapAppLink: {\n application: AppChannels.MY_SHARES,\n action: Actions.MyShares.INTERACTIVE_HEATMAP_DEMO,\n args: [id],\n params\n }\n };\n}","export enum ShareType {\n Link = 'Link',\n Classroom = 'Classroom',\n Open = 'Open',\n Live = 'Live'\n}","// extracted by mini-css-extract-plugin\nexport default {\"circleContainer\":\"p8Vgz\",\"backgroundCircle\":\"asGGE\",\"circleSuccess\":\"PXLNj\",\"circleWarning\":\"ZckRN\",\"circleDanger\":\"slBRg\",\"lgCircleContainer\":\"N8KCI\",\"xsCircleContainer\":\"RPqZ2\",\"pendingCircle\":\"DKrcq\",\"centredPercentageText\":\"tpmLR\"};"],"names":["namespace","ZERO_COLOUR","COLOUR_SCALE","LEGEND_VALUES","getBackgroundColor","value","max","hex","getGradient","data","gradient","i","length","previousValue","currentValue","nextValue","push","join","EngagementHeatMapLegend","Math","legendSquareWidthPercentage","className","Text","phrase","map","val","idx","key","style","width","backgroundColor","EngagementHeatMap","props","heatMap","engagement","background","getPhrase","anonymiseUserName","user","shouldAnonymise","id","sessionName","seed","floor","Date","getMinutes","dictionaries","separator","getAnonSession","sessionId","anonSessions","fallback","getUserOrAnonSession","result","getFullHeatMap","Array","ceil","videoDuration","fill","t","PercentageIndicatorLayout","ProgressCircle","ref","circle","radius","r","baseVal","circumference","PI","offset","percentage","strokeDasharray","strokeDashoffset","toString","size","scoreThresholds","PercentageIndicator","percentageToFixed","layout","LabelInside","label","customLabel","LabelOnly","LabelBefore","defaultProps","CircleOnly","ProgressCircleSize","CIRCLE_STROKE_WIDTH","CIRCLE_STROKE_WIDTH_LG","ProgressCircleSizeMap","ExtraSmall","Small","Large","getCircleRadius","strokeWidth","getCircleClassName","HIGH","MODERATE","getColouredLabelClassName","getCircleContainerClassName","isPending","getPercentageToFixed","toFixed","getFormattedPercentage","round","ScoreThresholdDefaults","ScoreThresholdInsights","InsightsDemoRequests","interactive","url","normalize","interactiveMetadata","interactiveResults","videoViews","users","individualHeatmap","aggregateHeatmap","useLockContentWidth","DEMO_INSIGHTS_SHARE","share","shareId","type","sharedObject","shareRecipients","dateShared","toISOString","viewCount","DEMO_INSIGHTS_APPLINK","application","action","DEMO_INSIGHTS_ACTION","svgName","appLink","group","LanguageService","ShareInfoDemo","shareLinkText","video","ShareLinkHelper","entity","entityTypeId","typeId","hasStudentExp","isPasswordProtected","linkExpireDate","privacy","overrideRestrictions","status","ShareLinkStatus","yearGroups","SharedToPill","imageCdnUrl","hasShareLink","maxAvatars","text","options","count","Tooltip","title","spanHack","IconButton","InteractiveInsightsOverviewDemoView","anonymiseUsers","SharedViewModelKeys","currentUser","UserRequests","config","ConfigRequests","audienceAppLinkParams","dateRangeAppLinkParams","results","classroomFilterOnly","classrooms","classroomGroups","classroomStudents","ClassroomRequests","ArrayHelper","aggregateEngagement","useSetPageMetadata","name","hasDataLoaded","params","interactiveInsightsAppLinks","resultsAppLink","args","questionsAppLink","heatmapAppLink","getInteractiveInsightsAppLinks","InsightsHeader","tabs","isDemo","InteractiveInsightsOverview","hasShared","ShareType"],"sourceRoot":""}
@@ -0,0 +1,2 @@
1
+ "use strict";(self.webpackChunk_clickview_lite=self.webpackChunk_clickview_lite||[]).push([[3110],{38307:(e,n,r)=>{r.d(n,{c:()=>p,l:()=>v});var t=r(32735),a=r(232),o=r.n(a),i=r(8604),c=r(83345);const l={heatMap:"epapa",legend:"uhH4p"};function s(e,n){(null==n||n>e.length)&&(n=e.length);for(var r=0,t=Array(n);r<n;r++)t[r]=e[r];return t}var u="shared.engagementHeatMap",d="#f1f1f1",f=o().scale(["#daf07d","#08bd1a"]),m=[0,.01,.25,.5,.75,1];function y(e,n){return e?f(e/n).hex():d}function g(e,n){for(var r=[],t=0;t<e.length;t++){var a=t>0&&e[t-1],o=e[t],i=t<e.length-1&&e[t+1];o===a&&o===i||r.push("".concat(y(o,n)," ").concat(100/e.length*t,"%"))}return"linear-gradient(to right, ".concat(r.join(","),")")}function v(){var e=Math.max.apply(Math,m),n=100/m.length;return t.createElement("div",{className:"d-flex justify-content-between w-100"},t.createElement(c.x,{namespace:u,phrase:"less"}),t.createElement("div",{className:"d-flex mx-1 flex-grow-1 ".concat(l.legend)},m.map((function(r,a){return t.createElement("div",{key:a,style:{width:"".concat(n,"%"),backgroundColor:y(r,e)}})}))),t.createElement(c.x,{namespace:u,phrase:"more"}))}function p(e){var n,r,a,o=(0,i.O)(e.engagement),c=null!==(n=e.max)&&void 0!==n?n:Math.max.apply(Math,function(e){if(Array.isArray(e))return s(e)}(a=o)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(a)||function(e,n){if(e){if("string"==typeof e)return s(e,n);var r={}.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?s(e,n):void 0}}(a)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}());return t.createElement("div",{className:"border rounded ".concat(l.heatMap," ").concat(null!==(r=e.className)&&void 0!==r?r:""),style:{background:g(o,c)}})}},5255:(e,n,r)=>{r.d(n,{Y:()=>i});var t=r(20354),a=r(30439);function o(e){return o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},o(e)}function i(e){var n,r=t.a.useBasicFetch(e&&a.o.getAnonSessions(e));return(null===(n=r.data)||void 0===n?void 0:n.length)?r.data.reduce((function(e,n){return Object.assign(Object.assign({},e),(r={},t=n.sessionId,a=n,(t=function(e){var n=function(e){if("object"!=o(e)||!e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,"string");if("object"!=o(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==o(n)?n:n+""}(t))in r?Object.defineProperty(r,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):r[t]=a,r));var r,t,a}),{}):{}}},26136:(e,n,r)=>{r.d(n,{B2:()=>c,DV:()=>s,jP:()=>l});var t=r(76198),a=r(23481),o=r(64818),i=a.T.encloseNamespace("shared.analyticsUtils");function c(e,n){return e?n?(0,t._8)((r="sessionId"in e?e.sessionName:e.id,a=+"".concat(r).concat(Math.floor((new Date).getMinutes()/5)),{dictionaries:[t.O9,t.yd],separator:" ",length:2,style:"capital",seed:a})):"sessionId"in e?e.sessionName:o.l.getFullName(e):"";var r,a}function l(e,n){var r={sessionId:e,sessionName:i("anonymousUser")};return e&&n&&n[e]||r}function s(e,n){return e.user?e.user:l(e.sessionId,n)}},74901:(e,n,r)=>{function t(e){return function(e){if(Array.isArray(e))return a(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,n){if(e){if("string"==typeof e)return a(e,n);var r={}.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?a(e,n):void 0}}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function a(e,n){(null==n||n>e.length)&&(n=e.length);for(var r=0,t=Array(n);r<n;r++)t[r]=e[r];return t}r.d(n,{K:()=>o});var o=function(e){var n=[],r=[];return e.users&&n.push.apply(n,t(e.users)),e.classrooms&&r.push.apply(r,t(e.classrooms)),e.classroomGroups&&r.push.apply(r,t(e.classroomGroups)),{userId:n,groupId:r}}},8604:(e,n,r)=>{function t(e){return new Array(Math.ceil(e.videoDuration)).fill(null).map((function(n,r){return e.heatMap[r]||0}))}r.d(n,{O:()=>t})},40782:(e,n,r)=>{r.d(n,{I:()=>t,O:()=>l});var t,a=r(32735),o=r(2606),i=r(362);function c(e){var n=a.useCallback((function(n){if(n){var r=n.r.baseVal.value,t=2*Math.PI*r,a=t-e.percentage*t;n.style.strokeDasharray="".concat(t," ").concat(t),n.style.strokeDashoffset=a.toString()}}),[e.percentage]);return a.createElement("svg",null,a.createElement("circle",{r:(0,o.pu)(e.size),className:i.Z.backgroundCircle}),!(0,o.zR)(e.percentage)&&a.createElement("circle",{ref:n,r:(0,o.pu)(e.size),className:(0,o.V4)(e.percentage,e.scoreThresholds)}))}function l(e){var n,r=(0,o.Ki)(e.percentage),l=e.size||(e.layout===t.LabelInside?o.Mk.Large:o.Mk.Small),s=e.customLabel||(0,o.DV)(r);return e.layout===t.LabelOnly?a.createElement("span",{className:(0,o.IA)(r)},s):a.createElement("div",{className:"d-flex align-items-center justify-content-between ".concat(null!==(n=e.className)&&void 0!==n?n:"")},e.layout===t.LabelBefore&&a.createElement("span",{className:"me-2"},s),a.createElement("div",{className:(0,o.tw)(l,r)},a.createElement(c,{percentage:r,size:l,scoreThresholds:e.scoreThresholds}),e.layout===t.LabelInside&&a.createElement("span",{className:i.Z.centredPercentageText},s)))}!function(e){e.CircleOnly="circle_only",e.LabelOnly="label_only",e.LabelBefore="label_before",e.LabelInside="label_inside"}(t||(t={})),l.defaultProps={layout:t.CircleOnly}},2606:(e,n,r)=>{r.d(n,{DV:()=>v,IA:()=>m,Ki:()=>g,Mk:()=>c,V4:()=>f,pu:()=>d,tw:()=>y,zR:()=>p});var t=r(94892),a=r(362);function o(e){return o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},o(e)}function i(e,n,r){return(n=function(e){var n=function(e){if("object"!=o(e)||!e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,"string");if("object"!=o(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==o(n)?n:n+""}(n))in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}var c,l=.2,s=.36;!function(e){e.Small="small",e.Large="large",e.ExtraSmall="extraSmall"}(c||(c={}));var u=i(i(i({},c.ExtraSmall,{size:2}),c.Small,{size:2}),c.Large,{size:5.8});function d(e){var n=u[e].size,r=e===c.Large?s:l;return"".concat(n/2-2*r,"rem")}function f(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:t.i;return e>=n.HIGH?a.Z.circleSuccess:e>=n.MODERATE?a.Z.circleWarning:a.Z.circleDanger}function m(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:t.i;return e>=n.HIGH?"text-success":e>=n.MODERATE?"text-warning":"text-danger"}function y(e,n){var r="d-inline-block ".concat(a.Z.circleContainer);return e===c.Large&&(r+=" ".concat(a.Z.lgCircleContainer)),e===c.ExtraSmall&&(r+=" ".concat(a.Z.xsCircleContainer)),p(n)&&(r+=" ".concat(a.Z.pendingCircle)),r}function g(e){if(!p(e))return+e.toFixed(2)}function v(e){return p(e)?"--%":"".concat(Math.round(100*e),"%")}function p(e){return"number"!=typeof e}},94892:(e,n,r)=>{r.d(n,{T:()=>a,i:()=>t});var t={HIGH:.75,MODERATE:.5},a={HIGH:.7,MODERATE:.7}},94644:(e,n,r)=>{r.d(n,{r:()=>u});var t=r(50242),a=r(81886),o=r(67058),i=r(14553),c=r(49267),l=r(49075),s={notFound:o.d,forbidden:{rating:i.q,yearLevel:i.q,region:c.a,privacy:i.q},badRequest:l._,internalServerError:l._};function u(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if(e){var o;o="number"==typeof e?e:e.status;var i=Object.assign(Object.assign({},s),n);o&&a.Q.Ry.isStatusCodeError(o)&&(o!==t.o.InternalServer?o!==t.o.NotFound?o!==t.o.Forbidden?r.badRequest||a.Q.Ry.throw(new i.badRequest):r.forbidden||a.Q.Ry.throw(new i.forbidden.privacy):r.notFound||a.Q.Ry.throw(new i.notFound):r.internalServerError||a.Q.Ry.throw(new l._))}}},17913:(e,n,r)=>{r.d(n,{u:()=>i});var t=r(97395),a=r(110),o=r(62875),i={individualEngagement:function(e,n,r,a){var i=Object.assign({objectId:e},n);return r&&(i.sharerId=r),a&&(i.includeAnonViews=!0),{url:t._.urlBuilder("{gateway}/v1/analytics/heat-map",i),key:(0,o.H)("engagement:".concat(e,":").concat(a),n,r),formatData:function(e){var n;return Object.assign(Object.assign({},e),{data:null===(n=e.data)||void 0===n?void 0:n.map((function(e){var n;return Object.assign(Object.assign({},e),{heatMap:null!==(n=e.heatMap)&&void 0!==n?n:[]})}))})},normalize:!1}},aggregateEngagement:function(e,n,r,a){var i=Object.assign({objectId:e},n);return r&&(i.sharerId=r),a&&(i.includeAnonViews=!0),{url:t._.urlBuilder("{gateway}/v1/analytics/heat-map/aggregations",i),key:(0,o.H)("aggregate:engagement:".concat(e,":").concat(a),n,r),formatData:function(e){var n;return Object.assign(Object.assign({},e),{heatMap:null!==(n=e.heatMap)&&void 0!==n?n:[]})},normalize:!1}},views:function(e,n,r,i){var c=Object.assign(Object.assign({},e),{timeOffset:a.O.getTimezoneOffset()});return n&&(c.objectId=n),r&&(c.sharerId=r),i&&(c.includeAnonViews=!0),{url:t._.urlBuilder("{gateway}/v1/analytics/video-views",c),key:(0,o.H)("video:views:".concat(n,":").concat(i),e,r),normalize:!1}}}},91286:(e,n,r)=>{r.d(n,{v:()=>i});var t=r(32735),a=r(94644);function o(e){return e.map((function(e){return e.statusCode})).join(":")}function i(e,n,r){var i=Array.isArray(e)?e:[e];(0,t.useEffect)((function(){i.forEach((function(e){(0,a.r)(e.statusCode,n,r)}))}),[o(i),n,r])}},93322:(e,n,r)=>{r.d(n,{F:()=>o});var t=r(32735),a=r(13126);function o(){t.useEffect((function(){return a.e.lockContentWidth(),function(){return a.e.unlockContentWidth()}}),[])}},62875:(e,n,r)=>{function t(e,n,r){var t="".concat(e,":").concat(n.start,":").concat(n.end),a=Array.isArray(n.userId)?n.userId.sort().join(":"):n.userId,o=Array.isArray(n.groupId)?n.groupId.sort().join(":"):n.groupId;return a&&(t+=":".concat(a)),o&&(t+=":".concat(o)),r&&(t+=":".concat(r)),t}r.d(n,{H:()=>t})},362:(e,n,r)=>{r.d(n,{Z:()=>t});const t={circleContainer:"p8Vgz",backgroundCircle:"asGGE",circleSuccess:"PXLNj",circleWarning:"ZckRN",circleDanger:"slBRg",lgCircleContainer:"N8KCI",xsCircleContainer:"RPqZ2",pendingCircle:"DKrcq",centredPercentageText:"tpmLR"}}}]);
2
+ //# sourceMappingURL=3110-eee18143c6-lite.chunk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scripts/3110-eee18143c6-lite.chunk.js","mappings":"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","sources":["file:///app/packages/libs/shared/src/apps/analytics/components/engagement-heat-map/engagement-heat-map.scss","file:///app/packages/libs/shared/src/apps/analytics/components/engagement-heat-map/EngagementHeatMap.tsx","file:///app/packages/libs/shared/src/apps/analytics/hooks/UseAnonSessions.ts","file:///app/packages/libs/shared/src/apps/analytics/utils/AnonymiseUserUtils.ts","file:///app/packages/libs/shared/src/apps/analytics/utils/AudienceUtils.ts","file:///app/packages/libs/shared/src/apps/analytics/utils/EngagementUtils.ts","file:///app/packages/libs/shared/src/components/percentage-indicator/PercentageIndicator.tsx","file:///app/packages/libs/shared/src/components/percentage-indicator/PercentageIndicatorUtils.ts","file:///app/packages/libs/shared/src/constants/ScoreThresholds.ts","file:///app/packages/libs/shared/src/errors/handlers/HttpErrorHandlers.ts","file:///app/packages/libs/shared/src/flight-requests/VideoViewRequests.ts","file:///app/packages/libs/shared/src/hooks/UseHandleObjectError.ts","file:///app/packages/libs/shared/src/hooks/useLockContentWidth.ts","file:///app/packages/libs/shared/src/utils/AnalyticsRequestUtils.ts","file:///app/packages/libs/shared/src/components/percentage-indicator/percentage-indicator.scss"],"sourcesContent":["// extracted by mini-css-extract-plugin\nexport default {\"heatMap\":\"epapa\",\"legend\":\"uhH4p\"};","import React from 'react';\nimport chroma from 'chroma-js';\n\nimport { getFullHeatMap } from 'libs/shared/apps/analytics/utils/EngagementUtils';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Engagement } from 'libs/shared/interfaces';\n\nimport styles from './engagement-heat-map.scss';\n\nconst namespace = 'shared.engagementHeatMap';\n\nconst ZERO_COLOUR = '#f1f1f1';\nconst MIN_COLOUR = '#daf07d';\nconst MAX_COLOUR = '#08bd1a';\n\nconst COLOUR_SCALE = chroma.scale([ MIN_COLOUR, MAX_COLOUR ]);\n\nconst LEGEND_VALUES = [ 0, 0.01, 0.25, 0.5, 0.75, 1 ];\n\nfunction getBackgroundColor(value: number, max: number): string {\n if (!value)\n return ZERO_COLOUR;\n\n return COLOUR_SCALE(value / max).hex();\n}\n\nfunction getGradient(data: number[], max: number): string {\n const gradient: string[] = [];\n\n for (let i = 0; i < data.length; i++) {\n const previousValue = i > 0 && data[i - 1];\n const currentValue = data[i];\n const nextValue = i < data.length - 1 && data[i + 1];\n\n /**\n * We want to capture colour changes but if a value has the same value\n * of both of its neighbours, we can skip it.\n */\n if (currentValue === previousValue && currentValue === nextValue)\n continue;\n\n gradient.push(`${getBackgroundColor(currentValue, max)} ${100 / data.length * i}%`);\n }\n\n return `linear-gradient(to right, ${gradient.join(',')})`;\n}\n\nexport function EngagementHeatMapLegend(): JSX.Element {\n const max = Math.max(...LEGEND_VALUES);\n const legendSquareWidthPercentage = 100 / LEGEND_VALUES.length;\n\n return (\n <div className='d-flex justify-content-between w-100'>\n <Text namespace={namespace} phrase='less' />\n <div className={`d-flex mx-1 flex-grow-1 ${styles.legend}`}>\n {LEGEND_VALUES.map((val, idx) => (\n <div\n key={idx}\n style={{\n width: `${legendSquareWidthPercentage}%`,\n backgroundColor: getBackgroundColor(val, max)\n }}\n />\n ))}\n </div>\n <Text namespace={namespace} phrase='more' />\n </div>\n );\n}\n\ninterface EngagementHeatMapProps {\n engagement: Engagement;\n max?: number;\n className?: string;\n}\n\nexport function EngagementHeatMap(props: EngagementHeatMapProps): JSX.Element {\n const heatMap = getFullHeatMap(props.engagement);\n const max = props.max ?? Math.max(...heatMap);\n\n return (\n <div\n className={`border rounded ${styles.heatMap} ${props.className ?? ''}`}\n style={{\n background: getGradient(heatMap, max)\n }}\n />\n );\n}","import { Flight } from 'libs/common/react/index';\n\nimport { ShareRequests } from 'libs/shared/apps/share/flight-requests/ShareRequests';\n\nexport interface AnonSession {\n sessionId: string;\n sessionName: string;\n}\n\nexport interface AnonSessions extends Record<string, AnonSession> {}\n\nexport function useAnonSessions(shareId: string): AnonSessions {\n const anonSessions = Flight.useBasicFetch<AnonSession[]>(shareId && ShareRequests.getAnonSessions(shareId));\n\n if (!anonSessions.data?.length)\n return {};\n\n return anonSessions.data.reduce((prev, current) => ({ ...prev, [current.sessionId]: current }), {});\n}","import { animals, colors, Config as UniqueNamesConfig, uniqueNamesGenerator } from 'unique-names-generator';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { AnonSession, AnonSessions } from 'libs/shared/apps/analytics/hooks/UseAnonSessions';\nimport { UserOrAnonSession } from 'libs/shared/apps/analytics/interfaces/UserOrAnonSession';\nimport { StudentResults } from 'libs/shared/interfaces';\nimport { UserHelper } from 'libs/shared/utils/UserHelper';\n\nconst namespace = 'shared.analyticsUtils';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nfunction getUniqueNamesConfig(id: string): UniqueNamesConfig {\n /**\n * Generate a seed that is unique to each user but changes every 5 minutes.\n * \n * We use a seed so that if the same user's name is anonymised multiple times\n * in quick succession (e.g. multiple renders), the same name will be returned each time.\n * \n * We change the seed every 5 minutes so that students don't always have the same name.\n */\n const seed = +`${id}${Math.floor((new Date()).getMinutes() / 5)}`;\n\n return {\n dictionaries: [ colors, animals ],\n separator: ' ',\n length: 2,\n style: 'capital',\n seed\n };\n}\n\nexport function anonymiseUserName(user: UserOrAnonSession, shouldAnonymise: boolean): string {\n if (!user)\n return '';\n\n if (!shouldAnonymise)\n return 'sessionId' in user ? user.sessionName : UserHelper.getFullName(user);\n\n return uniqueNamesGenerator(getUniqueNamesConfig('sessionId' in user ? user.sessionName : user.id));\n}\n\nexport function getAnonSession(sessionId: string, anonSessions: AnonSessions): AnonSession {\n const fallback = {\n sessionId: sessionId,\n sessionName: getPhrase('anonymousUser')\n };\n\n if (!sessionId || !anonSessions)\n return fallback;\n\n const anonSession = anonSessions[sessionId];\n\n if (anonSession)\n return anonSession;\n\n return fallback;\n}\n\nexport function getUserOrAnonSession(result: StudentResults, anonSessions: AnonSessions): UserOrAnonSession {\n if (result.user)\n return result.user;\n\n return getAnonSession(result.sessionId, anonSessions);\n}\n","import { AudienceQueryParams } from 'libs/shared/apps/analytics/interfaces/AudienceQueryParams';\n\nexport const getAudienceParams = (queryParams: AudienceQueryParams) => {\n const userId: string[] = [];\n const groupId: string[] = [];\n\n if (queryParams.users)\n userId.push(...queryParams.users);\n\n if (queryParams.classrooms)\n groupId.push(...queryParams.classrooms);\n\n if (queryParams.classroomGroups)\n groupId.push(...queryParams.classroomGroups);\n return {\n userId,\n groupId\n };\n};","import { Engagement } from 'libs/shared/interfaces';\n\n/**\n * The heat map in the API response won't contain trailing zeros so we need to add those\n * in manually.\n */\nexport function getFullHeatMap(engagement: Engagement): number[] {\n return (new Array(Math.ceil(engagement.videoDuration))).fill(null).map((t, idx) => engagement.heatMap[idx] || 0);\n}","import React from 'react';\n\nimport { ScoreThresholds } from 'libs/shared/constants/ScoreThresholds';\n\nimport {\n getCircleClassName,\n getCircleContainerClassName,\n getCircleRadius,\n getColouredLabelClassName,\n getFormattedPercentage,\n getPercentageToFixed,\n isPending,\n ProgressCircleSize\n} from './PercentageIndicatorUtils';\n\nimport styles from './percentage-indicator.scss';\n\ninterface ProgressCircleProps {\n size: ProgressCircleSize;\n scoreThresholds?: ScoreThresholds;\n percentage?: number;\n}\n\nfunction ProgressCircle(props: ProgressCircleProps): JSX.Element {\n const ref = React.useCallback((circle: SVGCircleElement) => {\n if (!circle)\n return;\n\n const radius = circle.r.baseVal.value;\n const circumference = 2 * Math.PI * radius;\n const offset = circumference - props.percentage * circumference;\n\n circle.style.strokeDasharray = `${circumference} ${circumference}`;\n circle.style.strokeDashoffset = offset.toString();\n }, [props.percentage]);\n\n return (\n <svg>\n <circle r={getCircleRadius(props.size)} className={styles.backgroundCircle} />\n {!isPending(props.percentage) &&\n <circle\n ref={ref}\n r={getCircleRadius(props.size)}\n className={getCircleClassName(props.percentage, props.scoreThresholds)}\n />\n }\n </svg>\n );\n}\n\nexport enum PercentageIndicatorLayout {\n CircleOnly = 'circle_only',\n LabelOnly = 'label_only',\n LabelBefore = 'label_before',\n LabelInside = 'label_inside'\n}\n\ninterface PercentageIndicatorProps {\n layout: PercentageIndicatorLayout;\n percentage?: number; // Between 0 and 1 or undefined for pending\n className?: string;\n customLabel?: string;\n scoreThresholds?: ScoreThresholds;\n size?: ProgressCircleSize;\n}\n\nPercentageIndicator.defaultProps = {\n layout: PercentageIndicatorLayout.CircleOnly\n};\n\nexport function PercentageIndicator(props: PercentageIndicatorProps): JSX.Element {\n const percentageToFixed = getPercentageToFixed(props.percentage);\n\n const size = props.size ||\n (props.layout === PercentageIndicatorLayout.LabelInside\n ? ProgressCircleSize.Large\n : ProgressCircleSize.Small\n );\n\n const label = props.customLabel || getFormattedPercentage(percentageToFixed);\n\n if (props.layout === PercentageIndicatorLayout.LabelOnly)\n return (\n <span className={getColouredLabelClassName(percentageToFixed)}>\n {label}\n </span>\n );\n\n return (\n <div className={`d-flex align-items-center justify-content-between ${props.className ?? ''}`}>\n {props.layout === PercentageIndicatorLayout.LabelBefore &&\n <span className='me-2'>\n {label}\n </span>\n }\n <div className={getCircleContainerClassName(size, percentageToFixed)}>\n <ProgressCircle percentage={percentageToFixed} size={size} scoreThresholds={props.scoreThresholds} />\n {props.layout === PercentageIndicatorLayout.LabelInside &&\n <span className={styles.centredPercentageText}>\n {label}\n </span>\n }\n </div>\n </div>\n );\n}","import { ScoreThresholdDefaults, ScoreThresholds } from 'libs/shared/constants/ScoreThresholds';\n\nimport styles from './percentage-indicator.scss';\n\n/**\n * Values for width and strokeWidth are taken from progress-circle.scss.\n * If either are changed, they must be updated in both places.\n */\nconst CIRCLE_WIDTH = 2; // rem\nconst CIRCLE_WIDTH_LG = 5.8; // rem\nconst CIRCLE_STROKE_WIDTH = 0.2; // rem\nconst CIRCLE_STROKE_WIDTH_LG = 0.36; // rem\n \nexport enum ProgressCircleSize {\n Small = 'small',\n Large = 'large',\n ExtraSmall = 'extraSmall'\n}\n\nconst ProgressCircleSizeMap = {\n [ProgressCircleSize.ExtraSmall]: {\n size: CIRCLE_WIDTH\n },\n [ProgressCircleSize.Small]: {\n size: CIRCLE_WIDTH\n },\n [ProgressCircleSize.Large]: {\n size: CIRCLE_WIDTH_LG\n }\n};\n\n/**\n * radius = width / 2 - strokeWidth * 2\n */\nexport function getCircleRadius(size: ProgressCircleSize): string {\n const width = ProgressCircleSizeMap[size].size;\n const strokeWidth = size === ProgressCircleSize.Large ? CIRCLE_STROKE_WIDTH_LG : CIRCLE_STROKE_WIDTH;\n return `${width / 2 - strokeWidth * 2}rem`;\n}\n \nexport function getCircleClassName(\n percentage: number,\n scoreThresholds: ScoreThresholds = ScoreThresholdDefaults\n): string {\n if (percentage >= scoreThresholds.HIGH)\n return styles.circleSuccess;\n \n if (percentage >= scoreThresholds.MODERATE)\n return styles.circleWarning;\n \n return styles.circleDanger;\n}\n \nexport function getColouredLabelClassName(\n percentage: number,\n scoreThresholds: ScoreThresholds = ScoreThresholdDefaults\n): string {\n if (percentage >= scoreThresholds.HIGH)\n return 'text-success';\n \n if (percentage >= scoreThresholds.MODERATE)\n return 'text-warning';\n \n return 'text-danger';\n}\n \nexport function getCircleContainerClassName(size: ProgressCircleSize, percentage?: number): string {\n let className = `d-inline-block ${styles.circleContainer}`;\n \n if (size === ProgressCircleSize.Large)\n className += ` ${styles.lgCircleContainer}`;\n\n if (size === ProgressCircleSize.ExtraSmall)\n className += ` ${styles.xsCircleContainer}`;\n\n if (isPending(percentage))\n className += ` ${styles.pendingCircle}`;\n \n return className;\n}\n\nexport function getPercentageToFixed(percentage?: number): number | undefined {\n if (isPending(percentage))\n return;\n \n return +percentage.toFixed(2);\n}\n \nexport function getFormattedPercentage(percentage?: number): string {\n if (isPending(percentage))\n return `--%`;\n\n return `${Math.round(percentage * 100)}%`;\n}\n\nexport function isPending(percentage?: number): boolean {\n return typeof percentage !== 'number';\n}","export interface ScoreThresholds {\n HIGH: number;\n MODERATE: number;\n}\n\nexport const ScoreThresholdDefaults: ScoreThresholds = {\n HIGH: 0.75,\n MODERATE: 0.5\n};\n\nexport const ScoreThresholdInsights: ScoreThresholds = {\n HIGH: 0.7,\n MODERATE: 0.7\n};","import { BaseError } from 'libs/common/backbone/core/BaseError';\nimport { HttpStatus } from 'libs/common/backbone/enums/HttpStatus';\nimport { Xhr } from 'libs/common/backbone/interfaces';\nimport { Core } from 'libs/common/core';\n\nimport { NotFoundError } from 'libs/shared/errors/general/not-found/NotFoundError';\nimport { PrivateResourceError } from 'libs/shared/errors/general/private-resource/PrivateResourceError';\nimport { RegionLockedResourceError } from 'libs/shared/errors/general/region-locked-resource/RegionLockedResourceError';\nimport { UnspecifiedError } from 'libs/shared/errors/general/unspecified-error/UnspecifiedError';\nimport { VideoTypes } from 'libs/shared/interfaces';\n\nexport interface HttpErrorMap {\n notFound?: new () => BaseError;\n forbidden?: {\n rating?: new (description: string) => BaseError;\n yearLevel?: new (description: string) => BaseError;\n region?: new () => BaseError;\n privacy?: new (video?: VideoTypes) => BaseError;\n };\n badRequest?: new () => BaseError;\n internalServerError?: new () => BaseError;\n}\n\nexport type IgnoreHttpErrorMap = {\n [key in keyof HttpErrorMap]: boolean;\n};\n\nconst defaultErrors: HttpErrorMap = {\n notFound: NotFoundError,\n forbidden: {\n rating: PrivateResourceError,\n yearLevel: PrivateResourceError,\n region: RegionLockedResourceError,\n privacy: PrivateResourceError\n },\n badRequest: UnspecifiedError,\n internalServerError: UnspecifiedError\n};\n\nexport function handleHttpError(\n info: HttpStatus | Xhr,\n customErrorMap: HttpErrorMap = {},\n /**\n * Prevent certain errors in the errorMap from being thrown\n * so that you may implement your own handler\n */\n ignoreMap: IgnoreHttpErrorMap = {}\n): void {\n if (!info)\n return;\n\n let statusCode: HttpStatus;\n\n if (typeof(info) === 'number') {\n statusCode = info;\n } else {\n statusCode = info.status;\n }\n\n const errorMap = {\n ...defaultErrors,\n ...customErrorMap\n };\n\n if (!statusCode)\n return;\n\n if (!Core.ErrorHelper.isStatusCodeError(statusCode))\n return;\n\n if (statusCode === HttpStatus.InternalServer) {\n if (!ignoreMap.internalServerError)\n Core.ErrorHelper.throw(new UnspecifiedError());\n return;\n }\n\n if (statusCode === HttpStatus.NotFound) {\n if (!ignoreMap.notFound)\n Core.ErrorHelper.throw(new errorMap.notFound());\n return;\n }\n\n if (statusCode === HttpStatus.Forbidden) {\n /**\n * TODO: Work out how to go about handling all forbidden errors, such as region locking, year levels,\n * ratings, and privacy.\n */\n if (!ignoreMap.forbidden)\n Core.ErrorHelper.throw(new errorMap.forbidden.privacy());\n return;\n }\n\n if (!ignoreMap.badRequest)\n Core.ErrorHelper.throw(new errorMap.badRequest());\n}\n\nexport function handleXhrError(xhr: Xhr, customErrorMap?: HttpErrorMap): void {\n handleHttpError(xhr.status, customErrorMap);\n}","import { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\nimport { HashObject } from 'libs/common/react/interfaces';\nimport { DateHelper } from 'libs/common/react/utils/DateHelper';\n\nimport { AnalyticsRequestFilter, Engagement } from 'libs/shared/interfaces';\nimport { getAnalyticsRequestKey } from 'libs/shared/utils/AnalyticsRequestUtils';\n\nexport const VideoViewRequests = {\n individualEngagement(\n objectId: string,\n filter: AnalyticsRequestFilter,\n sharerId?: string,\n includeAnonViews?: boolean\n ): Flight.Request {\n const queryParams: HashObject = {\n objectId,\n ...filter\n };\n\n if (sharerId)\n queryParams.sharerId = sharerId;\n\n if (includeAnonViews)\n queryParams.includeAnonViews = true;\n\n return {\n url: UrlHelper.urlBuilder('{gateway}/v1/analytics/heat-map', queryParams),\n key: getAnalyticsRequestKey(`engagement:${objectId}:${includeAnonViews}`, filter, sharerId),\n formatData: (data: any) => {\n return {\n ...data,\n data: data.data?.map((d: any) => ({\n ...d,\n heatMap: d.heatMap ?? []\n }))\n };\n },\n normalize: false\n };\n },\n \n aggregateEngagement(\n objectId: string,\n filter: AnalyticsRequestFilter,\n sharerId?: string,\n includeAnonViews?: boolean\n ): Flight.Request {\n const queryParams: HashObject = {\n objectId,\n ...filter\n };\n\n if (sharerId)\n queryParams.sharerId = sharerId;\n \n if (includeAnonViews)\n queryParams.includeAnonViews = true;\n\n return {\n url: UrlHelper.urlBuilder('{gateway}/v1/analytics/heat-map/aggregations', queryParams),\n key: getAnalyticsRequestKey(`aggregate:engagement:${objectId}:${includeAnonViews}`, filter, sharerId),\n formatData: (data: Engagement) => {\n return {\n ...data,\n heatMap: data.heatMap ?? []\n };\n },\n normalize: false\n };\n },\n \n views(\n filter: AnalyticsRequestFilter,\n objectId?: string,\n sharerId?: string,\n includeAnonViews?: boolean\n ): Flight.Request {\n const queryParams: HashObject = {\n ...filter,\n timeOffset: DateHelper.getTimezoneOffset()\n };\n\n if (objectId)\n queryParams.objectId = objectId;\n\n if (sharerId)\n queryParams.sharerId = sharerId;\n \n if (includeAnonViews)\n queryParams.includeAnonViews = true;\n\n return {\n url: UrlHelper.urlBuilder('{gateway}/v1/analytics/video-views', queryParams),\n key: getAnalyticsRequestKey(`video:views:${objectId}:${includeAnonViews}`, filter, sharerId),\n normalize: false\n };\n }\n};","import { useEffect } from 'react';\n\nimport { Flight } from 'libs/common/flight';\n\nimport { handleHttpError, HttpErrorMap, IgnoreHttpErrorMap } from 'libs/shared/errors/handlers/HttpErrorHandlers';\n\nfunction generateCacheKey(flightObjs: Array<Flight.Response<any>>): string {\n return flightObjs.map(obj => obj.statusCode).join(':');\n}\n\n// TODO: Change this to just `useHandleHttpError` and only accept a status code.\nexport function useHandleObjectError(\n _flightObjs: Flight.Response<any> | Array<Flight.Response<any>>,\n customErrors?: HttpErrorMap,\n ignoreErrors?: IgnoreHttpErrorMap\n): void {\n const flightObjs = Array.isArray(_flightObjs) ? _flightObjs : [_flightObjs];\n\n useEffect(() => {\n flightObjs.forEach(obj => {\n handleHttpError(obj.statusCode, customErrors, ignoreErrors);\n });\n }, [ generateCacheKey(flightObjs), customErrors, ignoreErrors ]);\n}","import React from 'react';\n\nimport { LayoutHelper } from 'libs/shared/utils/LayoutHelper';\n\nexport function useLockContentWidth(): void {\n React.useEffect(() => {\n LayoutHelper.lockContentWidth();\n return () => LayoutHelper.unlockContentWidth();\n }, []);\n}","import { AnalyticsRequestFilter } from 'libs/shared/interfaces';\n\nexport function getAnalyticsRequestKey(baseKey: string, filter: AnalyticsRequestFilter, sharerId?: string): string {\n let key = `${baseKey}:${filter.start}:${filter.end}`;\n\n const userIdKey = Array.isArray(filter.userId) ? filter.userId.sort().join(':') : filter.userId;\n const groupIdKey = Array.isArray(filter.groupId) ? filter.groupId.sort().join(':') : filter.groupId;\n\n if (userIdKey)\n key += `:${userIdKey}`;\n\n if (groupIdKey)\n key += `:${groupIdKey}`;\n\n if (sharerId)\n key += `:${sharerId}`;\n\n return key;\n}","// extracted by mini-css-extract-plugin\nexport default {\"circleContainer\":\"p8Vgz\",\"backgroundCircle\":\"asGGE\",\"circleSuccess\":\"PXLNj\",\"circleWarning\":\"ZckRN\",\"circleDanger\":\"slBRg\",\"lgCircleContainer\":\"N8KCI\",\"xsCircleContainer\":\"RPqZ2\",\"pendingCircle\":\"DKrcq\",\"centredPercentageText\":\"tpmLR\"};"],"names":["namespace","ZERO_COLOUR","COLOUR_SCALE","LEGEND_VALUES","getBackgroundColor","value","max","hex","getGradient","data","gradient","i","length","previousValue","currentValue","nextValue","push","join","EngagementHeatMapLegend","Math","legendSquareWidthPercentage","className","Text","phrase","map","val","idx","key","style","width","backgroundColor","EngagementHeatMap","props","heatMap","engagement","background","useAnonSessions","shareId","anonSessions","reduce","prev","current","sessionId","getPhrase","anonymiseUserName","user","shouldAnonymise","id","sessionName","seed","floor","Date","getMinutes","dictionaries","separator","getAnonSession","fallback","getUserOrAnonSession","result","getAudienceParams","queryParams","userId","groupId","users","classrooms","classroomGroups","getFullHeatMap","Array","ceil","videoDuration","fill","t","PercentageIndicatorLayout","ProgressCircle","ref","circle","radius","r","baseVal","circumference","PI","offset","percentage","strokeDasharray","strokeDashoffset","toString","size","scoreThresholds","PercentageIndicator","percentageToFixed","layout","LabelInside","label","customLabel","LabelOnly","LabelBefore","defaultProps","CircleOnly","ProgressCircleSize","CIRCLE_STROKE_WIDTH","CIRCLE_STROKE_WIDTH_LG","ProgressCircleSizeMap","ExtraSmall","Small","Large","getCircleRadius","strokeWidth","getCircleClassName","HIGH","MODERATE","getColouredLabelClassName","getCircleContainerClassName","isPending","getPercentageToFixed","toFixed","getFormattedPercentage","round","ScoreThresholdDefaults","ScoreThresholdInsights","defaultErrors","notFound","forbidden","rating","yearLevel","region","privacy","badRequest","internalServerError","handleHttpError","info","customErrorMap","ignoreMap","statusCode","status","errorMap","VideoViewRequests","individualEngagement","objectId","filter","sharerId","includeAnonViews","url","formatData","d","normalize","aggregateEngagement","views","timeOffset","generateCacheKey","flightObjs","obj","useHandleObjectError","_flightObjs","customErrors","ignoreErrors","isArray","useEffect","forEach","useLockContentWidth","getAnalyticsRequestKey","baseKey","start","end","userIdKey","sort","groupIdKey"],"sourceRoot":""}