@cornerstonejs/core 0.25.0 → 0.26.0

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","mappings":"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I,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,OAGpBC,IAAK,CACHlQ,KAAM,MACNmQ,UAAW,IACXF,OAAQ,CACN,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,GAAI,EAAG,KACX,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,IAAK,GAAI,KACb,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,OAGpBG,aAAc,CACZpQ,KAAM,iBACNmQ,UAAW,IACXF,OAAQ,CACN,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,OAGpBI,UAAW,CACTrQ,KAAM,cACNmQ,UAAW,IACXF,OAAQ,CACN,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CA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QAAS,MACTC,cAAe,KAEjB,CACE5S,KAAM,WACNoS,gBAAiB,iBACjBC,cAAe,IACfC,cAAe,6CACfC,SAAU,IACVC,MAAO,IACPC,QAAS,MACTC,cACE,2FACFC,QAAS,IACTC,cAAe,KAEjB,CACE5S,KAAM,aACNoS,gBAAiB,cACjBC,cAAe,KACfC,cACE,sFACFC,SAAU,MACVC,MAAO,IACPC,QAAS,MACTC,cACE,+JACFC,QAAS,MACTC,cAAe,KAEjB,CACE5S,KAAM,cACNoS,gBAAiB,cACjBC,cAAe,KACfC,cACE,qFACFC,SAAU,MACVC,MAAO,IACPC,QAAS,MACTC,cACE,qJACFC,QAAS,MACTC,cAAe,KAEjB,CACE5S,KAAM,cACNoS,gBAAiB,cACjBC,cAAe,KACfC,cACE,0GACFC,SAAU,MACVC,MAAO,IACPC,QAAS,MACTC,cACE,2IACFC,QAAS,MACTC,cAAe,KAEjB,CACE5S,KAAM,6BACNoS,gBAAiB,cACjBC,cAAe,KACfC,cACE,oEACFC,SAAU,MACVC,MAAO,IACPC,QAAS,MACTC,cACE,yIACFC,QAAS,MACTC,cAAe,KAEjB,CACE5S,KAAM,mBACNoS,gBAAiB,cACjBC,cAAe,IACfC,cACE,qEACFC,SAAU,IACVC,MAAO,IACPC,QAAS,MACTC,cACE,0IACFC,QAAS,IACTC,cAAe,KAEjB,CACE5S,KAAM,uBACNoS,gBAAiB,cACjBC,cAAe,IACfC,cACE,+EACFC,SAAU,IACVC,MAAO,IACPC,QAAS,MACTC,cACE,4HACFC,QAAS,IACTC,cAAe,KAEjB,CACE5S,KAAM,yBACNoS,gBAAiB,cACjBC,cAAe,IACfC,cACE,sGACFC,SAAU,IACVC,MAAO,IACPC,QAAS,MACTC,cACE,iKACFC,QAAS,IACTC,cAAe,KAEjB,CACE5S,KAAM,yBACNoS,gBAAiB,cACjBC,cAAe,KACfC,cACE,mGACFC,SAAU,MACVC,MAAO,IACPC,QAAS,MACTC,cACE,yKACFC,QAAS,MACTC,cAAe,KAEjB,CACE5S,KAAM,yBACNoS,gBAAiB,cACjBC,cAAe,IACfC,cAAe,yCACfC,SAAU,IAC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","sources":["webpack://cornerstone3D/webpack/universalModuleDefinition","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/regeneratorRuntime.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/typeof.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/regenerator/index.js","webpack://cornerstone3D/../../node_modules/lodash.clonedeep/index.js","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Common/Core/DataArray\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Common/Core/DataArray/Constants\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Common/Core/Math\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Common/Core/MatrixBuilder\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Common/Core/Points\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Common/DataModel/ImageData\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Common/DataModel/PiecewiseFunction\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Common/DataModel/Plane\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Common/DataModel/PolyData\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/Actor\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/Camera\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/ColorTransferFunction\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/ImageMapper\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/ImageSlice\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/Mapper\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/Property/Constants\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/RenderWindow\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/RenderWindowInteractor\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/Renderer\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/Volume\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/VolumeMapper\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/VolumeMapper/Constants\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/Actor\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/Actor2D\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/Camera\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/Glyph3DMapper\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/ImageMapper\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/ImageSlice\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/PixelSpaceCallbackMapper\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/PolyDataMapper\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/RenderWindow\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/Renderer\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/Skybox\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/SphereMapper\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/StickMapper\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/Texture\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/Texture/Constants\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/Volume\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/VolumeMapper\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Profiles/Volume\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/SceneGraph/ViewNodeFactory\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/macros\"","webpack://cornerstone3D/external umd {\"root\":\"window\",\"commonjs\":\"gl-matrix\",\"commonjs2\":\"gl-matrix\",\"amd\":\"gl-matrix\"}","webpack://cornerstone3D/webpack/bootstrap","webpack://cornerstone3D/webpack/runtime/compat get default export","webpack://cornerstone3D/webpack/runtime/define property getters","webpack://cornerstone3D/webpack/runtime/global","webpack://cornerstone3D/webpack/runtime/hasOwnProperty shorthand","webpack://cornerstone3D/webpack/runtime/make namespace object","webpack://cornerstone3D/webpack/runtime/node module decorator","webpack://cornerstone3D/./src/enums/Events.ts","webpack://cornerstone3D/./src/enums/RequestType.ts","webpack://cornerstone3D/./src/enums/ViewportType.ts","webpack://cornerstone3D/./src/enums/InterpolationType.ts","webpack://cornerstone3D/./src/enums/BlendModes.ts","webpack://cornerstone3D/./src/enums/OrientationAxis.ts","webpack://cornerstone3D/./src/constants/cpuColormaps.ts","webpack://cornerstone3D/./src/constants/rendering.ts","webpack://cornerstone3D/./src/constants/epsilon.ts","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/typeof.js","webpack://cornerstone3D/./src/utilities/deepFreeze.ts","webpack://cornerstone3D/./src/constants/mprCameraValues.ts","webpack://cornerstone3D/./src/constants/viewportPresets.ts","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/createClass.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/classCallCheck.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/defineProperty.js","webpack://cornerstone3D/./src/RenderingEngine/vtkClasses/vtkStreamingOpenGLTexture.js","webpack://cornerstone3D/./src/cache/classes/ImageVolume.ts","webpack://cornerstone3D/./src/eventTarget.ts","webpack://cornerstone3D/./src/utilities/triggerEvent.ts","webpack://cornerstone3D/./src/utilities/imageIdToURI.ts","webpack://cornerstone3D/./src/cache/cache.ts","webpack://cornerstone3D/./src/utilities/uuidv4.ts","webpack://cornerstone3D/./src/volumeLoader.ts","webpack://cornerstone3D/./src/RenderingEngine/vtkClasses/vtkSharedVolumeMapper.js","webpack://cornerstone3D/./src/RenderingEngine/helpers/createVolumeMapper.ts","webpack://cornerstone3D/./src/requestPool/requestPoolManager.ts","webpack://cornerstone3D/./src/requestPool/imageLoadPoolManager.ts","webpack://cornerstone3D/./src/imageLoader.ts","webpack://cornerstone3D/./src/metaData.ts","webpack://cornerstone3D/./src/utilities/windowLevel.ts","webpack://cornerstone3D/./src/utilities/getMinMax.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/setDefaultVolumeVOI.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/createVolumeActor.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/getOrCreateCanvas.ts","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/arrayLikeToArray.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/unsupportedIterableToArray.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/toConsumableArray.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/arrayWithoutHoles.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/iterableToArray.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/nonIterableSpread.js","webpack://cornerstone3D/./src/RenderingEngine/renderingEngineCache.ts","webpack://cornerstone3D/./src/RenderingEngine/vtkClasses/vtkStreamingOpenGLVolumeMapper.js","webpack://cornerstone3D/./src/RenderingEngine/vtkClasses/vtkStreamingOpenGLViewNodeFactory.js","webpack://cornerstone3D/./src/RenderingEngine/vtkClasses/vtkStreamingOpenGLRenderWindow.js","webpack://cornerstone3D/./src/RenderingEngine/vtkClasses/vtkOffscreenMultiRenderWindow.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/superPropBase.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/get.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/inherits.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/possibleConstructorReturn.js","webpack://cornerstone3D/./src/cache/index.ts","webpack://cornerstone3D/./src/utilities/transformWorldToIndex.ts","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/slicedToArray.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/arrayWithHoles.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/iterableToArrayLimit.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/nonIterableRest.js","webpack://cornerstone3D/./src/utilities/isImageActor.ts","webpack://cornerstone3D/./src/utilities/planar.ts","webpack://cornerstone3D/./src/utilities/hasNaNValues.ts","webpack://cornerstone3D/./src/RenderingEngine/Viewport.ts","webpack://cornerstone3D/./src/utilities/getVolumeActorCorners.ts","webpack://cornerstone3D/./src/utilities/getSliceRange.ts","webpack://cornerstone3D/./src/utilities/getSpacingInNormalDirection.ts","webpack://cornerstone3D/./src/utilities/getTargetVolumeAndSpacingInNormalDir.ts","webpack://cornerstone3D/./src/utilities/getImageSliceDataForVolumeViewport.ts","webpack://cornerstone3D/./src/RenderingEngine/getRenderingEngine.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/volumeNewImageEventDispatcher.ts","webpack://cornerstone3D/./src/RenderingEngine/vtkClasses/vtkSlabCamera.js","webpack://cornerstone3D/../../node_modules/detect-gpu/dist/detect-gpu.esm.js","webpack://cornerstone3D/./src/init.ts","webpack://cornerstone3D/./src/RenderingEngine/BaseVolumeViewport.ts","webpack://cornerstone3D/./src/RenderingEngine/VolumeViewport.ts","webpack://cornerstone3D/./src/utilities/invertRgbTransferFunction.ts","webpack://cornerstone3D/./src/utilities/isEqual.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/now.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/getVOILut.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/transform.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/calculateTransform.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/setToPixelCoordinateSystem.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/doesImageNeedToBeRendered.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/initializeRenderCanvas.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/saveLastRendered.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/renderColorImage.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/generateColorLUT.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/storedRGBAPixelDataToCanvasImageData.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/storedColorPixelDataToCanvasImageData.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageData.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPET.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataRGBA.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/lutMatches.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/getLut.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/computeAutoVoi.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/generateLut.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/getModalityLut.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/renderGrayscaleImage.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/colors/lookupTable.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/colors/colormap.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/renderPseudoColorImage.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPseudocolorLUTPET.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPseudocolorLUT.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/drawImageSync.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/getTransform.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/canvasToPixel.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/pixelToCanvas.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/setDefaultViewport.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/validator.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/getImageSize.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/getImageFitScale.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/getDefaultViewport.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/createViewport.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/fitToWindow.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/resize.ts","webpack://cornerstone3D/./src/RenderingEngine/StackViewport.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/correctShift.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/isRgbaSourceRgbDest.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/resetCamera.ts","webpack://cornerstone3D/./src/RenderingEngine/VolumeViewport3D.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/viewportTypeToViewportClass.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/viewportTypeUsesCustomRenderingPipeline.ts","webpack://cornerstone3D/./src/RenderingEngine/RenderingEngine.ts","webpack://cornerstone3D/./src/RenderingEngine/index.ts","webpack://cornerstone3D/./src/requestPool/imageRetrievalPoolManager.ts","webpack://cornerstone3D/./src/getEnabledElement.ts","webpack://cornerstone3D/./src/Settings.ts","webpack://cornerstone3D/./src/utilities/scaleRgbTransferFunction.ts","webpack://cornerstone3D/./src/utilities/getRuntimeId.ts","webpack://cornerstone3D/./src/utilities/calibratedPixelSpacingMetadataProvider.ts","webpack://cornerstone3D/./src/utilities/isOpposite.ts","webpack://cornerstone3D/./src/utilities/createUint8SharedArray.ts","webpack://cornerstone3D/./src/utilities/createFloat32SharedArray.ts","webpack://cornerstone3D/./src/utilities/getClosestImageId.ts","webpack://cornerstone3D/./src/utilities/indexWithinDimensions.ts","webpack://cornerstone3D/./src/utilities/getVolumeViewportsContainingSameVolumes.ts","webpack://cornerstone3D/./src/utilities/getViewportsWithVolumeId.ts","webpack://cornerstone3D/./src/utilities/renderToCanvas.ts","webpack://cornerstone3D/./src/utilities/loadImageToCanvas.ts","webpack://cornerstone3D/./src/utilities/worldToImageCoords.ts","webpack://cornerstone3D/./src/utilities/imageToWorldCoords.ts","webpack://cornerstone3D/./src/utilities/snapFocalPointToSlice.ts","webpack://cornerstone3D/./src/utilities/getViewportsWithImageURI.ts","webpack://cornerstone3D/./src/utilities/getClosestStackImageIndexForPoint.ts","webpack://cornerstone3D/./src/utilities/spatialRegistrationMetadataProvider.ts","webpack://cornerstone3D/./src/utilities/calculateViewportsSpatialRegistration.ts","webpack://cornerstone3D/./src/utilities/getViewportImageCornersInWorld.ts","webpack://cornerstone3D/./src/utilities/applyPreset.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/setVolumesForViewports.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/addVolumesToViewports.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"@kitware/vtk.js/Rendering/Core/VolumeMapper/Constants\"), require(\"@kitware/vtk.js/macros\"), require(\"@kitware/vtk.js/Rendering/Core/Camera\"), require(\"gl-matrix\"), require(\"@kitware/vtk.js/Common/Core/Math\"), require(\"@kitware/vtk.js/Common/Core/MatrixBuilder\"), require(\"@kitware/vtk.js/Rendering/Core/Volume\"), require(\"@kitware/vtk.js/Rendering/Profiles/Volume\"), require(\"@kitware/vtk.js/Common/DataModel/ImageData\"), require(\"@kitware/vtk.js/Common/Core/DataArray\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Texture\"), require(\"@kitware/vtk.js/Rendering/Core/VolumeMapper\"), require(\"@kitware/vtk.js/Common/DataModel/Plane\"), require(\"@kitware/vtk.js/Rendering/Core/ImageMapper\"), require(\"@kitware/vtk.js/Rendering/Core/ImageSlice\"), require(\"@kitware/vtk.js/Rendering/Core/ColorTransferFunction\"), require(\"@kitware/vtk.js/Rendering/Core/Renderer\"), require(\"@kitware/vtk.js/Rendering/Core/RenderWindow\"), require(\"@kitware/vtk.js/Rendering/Core/RenderWindowInteractor\"), require(\"@kitware/vtk.js/Common/Core/Points\"), require(\"@kitware/vtk.js/Common/DataModel/PolyData\"), require(\"@kitware/vtk.js/Rendering/Core/Actor\"), require(\"@kitware/vtk.js/Rendering/Core/Mapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/RenderWindow\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Actor\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Actor2D\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Camera\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Glyph3DMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/ImageMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/ImageSlice\"), require(\"@kitware/vtk.js/Rendering/OpenGL/PixelSpaceCallbackMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/PolyDataMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Renderer\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Skybox\"), require(\"@kitware/vtk.js/Rendering/OpenGL/SphereMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/StickMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Volume\"), require(\"@kitware/vtk.js/Rendering/OpenGL/VolumeMapper\"), require(\"@kitware/vtk.js/Rendering/SceneGraph/ViewNodeFactory\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Texture/Constants\"), require(\"@kitware/vtk.js/Common/Core/DataArray/Constants\"), require(\"@kitware/vtk.js/Rendering/Core/Property/Constants\"), require(\"@kitware/vtk.js/Common/DataModel/PiecewiseFunction\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"@kitware/vtk.js/Rendering/Core/VolumeMapper/Constants\", \"@kitware/vtk.js/macros\", \"@kitware/vtk.js/Rendering/Core/Camera\", \"gl-matrix\", \"@kitware/vtk.js/Common/Core/Math\", \"@kitware/vtk.js/Common/Core/MatrixBuilder\", \"@kitware/vtk.js/Rendering/Core/Volume\", \"@kitware/vtk.js/Rendering/Profiles/Volume\", \"@kitware/vtk.js/Common/DataModel/ImageData\", \"@kitware/vtk.js/Common/Core/DataArray\", \"@kitware/vtk.js/Rendering/OpenGL/Texture\", \"@kitware/vtk.js/Rendering/Core/VolumeMapper\", \"@kitware/vtk.js/Common/DataModel/Plane\", \"@kitware/vtk.js/Rendering/Core/ImageMapper\", \"@kitware/vtk.js/Rendering/Core/ImageSlice\", \"@kitware/vtk.js/Rendering/Core/ColorTransferFunction\", \"@kitware/vtk.js/Rendering/Core/Renderer\", \"@kitware/vtk.js/Rendering/Core/RenderWindow\", \"@kitware/vtk.js/Rendering/Core/RenderWindowInteractor\", \"@kitware/vtk.js/Common/Core/Points\", \"@kitware/vtk.js/Common/DataModel/PolyData\", \"@kitware/vtk.js/Rendering/Core/Actor\", \"@kitware/vtk.js/Rendering/Core/Mapper\", \"@kitware/vtk.js/Rendering/OpenGL/RenderWindow\", \"@kitware/vtk.js/Rendering/OpenGL/Actor\", \"@kitware/vtk.js/Rendering/OpenGL/Actor2D\", \"@kitware/vtk.js/Rendering/OpenGL/Camera\", \"@kitware/vtk.js/Rendering/OpenGL/Glyph3DMapper\", \"@kitware/vtk.js/Rendering/OpenGL/ImageMapper\", \"@kitware/vtk.js/Rendering/OpenGL/ImageSlice\", \"@kitware/vtk.js/Rendering/OpenGL/PixelSpaceCallbackMapper\", \"@kitware/vtk.js/Rendering/OpenGL/PolyDataMapper\", \"@kitware/vtk.js/Rendering/OpenGL/Renderer\", \"@kitware/vtk.js/Rendering/OpenGL/Skybox\", \"@kitware/vtk.js/Rendering/OpenGL/SphereMapper\", \"@kitware/vtk.js/Rendering/OpenGL/StickMapper\", \"@kitware/vtk.js/Rendering/OpenGL/Volume\", \"@kitware/vtk.js/Rendering/OpenGL/VolumeMapper\", \"@kitware/vtk.js/Rendering/SceneGraph/ViewNodeFactory\", \"@kitware/vtk.js/Rendering/OpenGL/Texture/Constants\", \"@kitware/vtk.js/Common/Core/DataArray/Constants\", \"@kitware/vtk.js/Rendering/Core/Property/Constants\", \"@kitware/vtk.js/Common/DataModel/PiecewiseFunction\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"cornerstone3D\"] = factory(require(\"@kitware/vtk.js/Rendering/Core/VolumeMapper/Constants\"), require(\"@kitware/vtk.js/macros\"), require(\"@kitware/vtk.js/Rendering/Core/Camera\"), require(\"gl-matrix\"), require(\"@kitware/vtk.js/Common/Core/Math\"), require(\"@kitware/vtk.js/Common/Core/MatrixBuilder\"), require(\"@kitware/vtk.js/Rendering/Core/Volume\"), require(\"@kitware/vtk.js/Rendering/Profiles/Volume\"), require(\"@kitware/vtk.js/Common/DataModel/ImageData\"), require(\"@kitware/vtk.js/Common/Core/DataArray\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Texture\"), require(\"@kitware/vtk.js/Rendering/Core/VolumeMapper\"), require(\"@kitware/vtk.js/Common/DataModel/Plane\"), require(\"@kitware/vtk.js/Rendering/Core/ImageMapper\"), require(\"@kitware/vtk.js/Rendering/Core/ImageSlice\"), require(\"@kitware/vtk.js/Rendering/Core/ColorTransferFunction\"), require(\"@kitware/vtk.js/Rendering/Core/Renderer\"), require(\"@kitware/vtk.js/Rendering/Core/RenderWindow\"), require(\"@kitware/vtk.js/Rendering/Core/RenderWindowInteractor\"), require(\"@kitware/vtk.js/Common/Core/Points\"), require(\"@kitware/vtk.js/Common/DataModel/PolyData\"), require(\"@kitware/vtk.js/Rendering/Core/Actor\"), require(\"@kitware/vtk.js/Rendering/Core/Mapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/RenderWindow\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Actor\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Actor2D\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Camera\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Glyph3DMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/ImageMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/ImageSlice\"), require(\"@kitware/vtk.js/Rendering/OpenGL/PixelSpaceCallbackMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/PolyDataMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Renderer\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Skybox\"), require(\"@kitware/vtk.js/Rendering/OpenGL/SphereMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/StickMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Volume\"), require(\"@kitware/vtk.js/Rendering/OpenGL/VolumeMapper\"), require(\"@kitware/vtk.js/Rendering/SceneGraph/ViewNodeFactory\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Texture/Constants\"), require(\"@kitware/vtk.js/Common/Core/DataArray/Constants\"), require(\"@kitware/vtk.js/Rendering/Core/Property/Constants\"), require(\"@kitware/vtk.js/Common/DataModel/PiecewiseFunction\"));\n\telse\n\t\troot[\"cornerstone3D\"] = factory(root[\"@kitware/vtk.js/Rendering/Core/VolumeMapper/Constants\"], root[\"@kitware/vtk.js/macros\"], root[\"@kitware/vtk.js/Rendering/Core/Camera\"], root[\"window\"], root[\"@kitware/vtk.js/Common/Core/Math\"], root[\"@kitware/vtk.js/Common/Core/MatrixBuilder\"], root[\"@kitware/vtk.js/Rendering/Core/Volume\"], root[\"@kitware/vtk.js/Rendering/Profiles/Volume\"], root[\"@kitware/vtk.js/Common/DataModel/ImageData\"], root[\"@kitware/vtk.js/Common/Core/DataArray\"], root[\"@kitware/vtk.js/Rendering/OpenGL/Texture\"], root[\"@kitware/vtk.js/Rendering/Core/VolumeMapper\"], root[\"@kitware/vtk.js/Common/DataModel/Plane\"], root[\"@kitware/vtk.js/Rendering/Core/ImageMapper\"], root[\"@kitware/vtk.js/Rendering/Core/ImageSlice\"], root[\"@kitware/vtk.js/Rendering/Core/ColorTransferFunction\"], root[\"@kitware/vtk.js/Rendering/Core/Renderer\"], root[\"@kitware/vtk.js/Rendering/Core/RenderWindow\"], root[\"@kitware/vtk.js/Rendering/Core/RenderWindowInteractor\"], root[\"@kitware/vtk.js/Common/Core/Points\"], root[\"@kitware/vtk.js/Common/DataModel/PolyData\"], root[\"@kitware/vtk.js/Rendering/Core/Actor\"], root[\"@kitware/vtk.js/Rendering/Core/Mapper\"], root[\"@kitware/vtk.js/Rendering/OpenGL/RenderWindow\"], root[\"@kitware/vtk.js/Rendering/OpenGL/Actor\"], root[\"@kitware/vtk.js/Rendering/OpenGL/Actor2D\"], root[\"@kitware/vtk.js/Rendering/OpenGL/Camera\"], root[\"@kitware/vtk.js/Rendering/OpenGL/Glyph3DMapper\"], root[\"@kitware/vtk.js/Rendering/OpenGL/ImageMapper\"], root[\"@kitware/vtk.js/Rendering/OpenGL/ImageSlice\"], root[\"@kitware/vtk.js/Rendering/OpenGL/PixelSpaceCallbackMapper\"], root[\"@kitware/vtk.js/Rendering/OpenGL/PolyDataMapper\"], root[\"@kitware/vtk.js/Rendering/OpenGL/Renderer\"], root[\"@kitware/vtk.js/Rendering/OpenGL/Skybox\"], root[\"@kitware/vtk.js/Rendering/OpenGL/SphereMapper\"], root[\"@kitware/vtk.js/Rendering/OpenGL/StickMapper\"], root[\"@kitware/vtk.js/Rendering/OpenGL/Volume\"], root[\"@kitware/vtk.js/Rendering/OpenGL/VolumeMapper\"], root[\"@kitware/vtk.js/Rendering/SceneGraph/ViewNodeFactory\"], root[\"@kitware/vtk.js/Rendering/OpenGL/Texture/Constants\"], root[\"@kitware/vtk.js/Common/Core/DataArray/Constants\"], root[\"@kitware/vtk.js/Rendering/Core/Property/Constants\"], root[\"@kitware/vtk.js/Common/DataModel/PiecewiseFunction\"]);\n})(self, function(__WEBPACK_EXTERNAL_MODULE__468__, __WEBPACK_EXTERNAL_MODULE__197__, __WEBPACK_EXTERNAL_MODULE__821__, __WEBPACK_EXTERNAL_MODULE__976__, __WEBPACK_EXTERNAL_MODULE__807__, __WEBPACK_EXTERNAL_MODULE__847__, __WEBPACK_EXTERNAL_MODULE__739__, __WEBPACK_EXTERNAL_MODULE__215__, __WEBPACK_EXTERNAL_MODULE__283__, __WEBPACK_EXTERNAL_MODULE__785__, __WEBPACK_EXTERNAL_MODULE__953__, __WEBPACK_EXTERNAL_MODULE__9__, __WEBPACK_EXTERNAL_MODULE__864__, __WEBPACK_EXTERNAL_MODULE__896__, __WEBPACK_EXTERNAL_MODULE__861__, __WEBPACK_EXTERNAL_MODULE__795__, __WEBPACK_EXTERNAL_MODULE__281__, __WEBPACK_EXTERNAL_MODULE__329__, __WEBPACK_EXTERNAL_MODULE__673__, __WEBPACK_EXTERNAL_MODULE__348__, __WEBPACK_EXTERNAL_MODULE__70__, __WEBPACK_EXTERNAL_MODULE__474__, __WEBPACK_EXTERNAL_MODULE__610__, __WEBPACK_EXTERNAL_MODULE__21__, __WEBPACK_EXTERNAL_MODULE__643__, __WEBPACK_EXTERNAL_MODULE__128__, __WEBPACK_EXTERNAL_MODULE__664__, __WEBPACK_EXTERNAL_MODULE__973__, __WEBPACK_EXTERNAL_MODULE__394__, __WEBPACK_EXTERNAL_MODULE__582__, __WEBPACK_EXTERNAL_MODULE__482__, __WEBPACK_EXTERNAL_MODULE__343__, __WEBPACK_EXTERNAL_MODULE__363__, __WEBPACK_EXTERNAL_MODULE__982__, __WEBPACK_EXTERNAL_MODULE__130__, __WEBPACK_EXTERNAL_MODULE__298__, __WEBPACK_EXTERNAL_MODULE__398__, __WEBPACK_EXTERNAL_MODULE__388__, __WEBPACK_EXTERNAL_MODULE__120__, __WEBPACK_EXTERNAL_MODULE__395__, __WEBPACK_EXTERNAL_MODULE__948__, __WEBPACK_EXTERNAL_MODULE__478__, __WEBPACK_EXTERNAL_MODULE__441__) {\nreturn ","var _typeof = require(\"./typeof.js\")[\"default\"];\n\nfunction _regeneratorRuntime() {\n \"use strict\";\n /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */\n\n module.exports = _regeneratorRuntime = function _regeneratorRuntime() {\n return exports;\n }, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;\n var exports = {},\n Op = Object.prototype,\n hasOwn = Op.hasOwnProperty,\n $Symbol = \"function\" == typeof Symbol ? Symbol : {},\n iteratorSymbol = $Symbol.iterator || \"@@iterator\",\n asyncIteratorSymbol = $Symbol.asyncIterator || \"@@asyncIterator\",\n toStringTagSymbol = $Symbol.toStringTag || \"@@toStringTag\";\n\n function define(obj, key, value) {\n return Object.defineProperty(obj, key, {\n value: value,\n enumerable: !0,\n configurable: !0,\n writable: !0\n }), obj[key];\n }\n\n try {\n define({}, \"\");\n } catch (err) {\n define = function define(obj, key, value) {\n return obj[key] = value;\n };\n }\n\n function wrap(innerFn, outerFn, self, tryLocsList) {\n var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator,\n generator = Object.create(protoGenerator.prototype),\n context = new Context(tryLocsList || []);\n return generator._invoke = function (innerFn, self, context) {\n var state = \"suspendedStart\";\n return function (method, arg) {\n if (\"executing\" === state) throw new Error(\"Generator is already running\");\n\n if (\"completed\" === state) {\n if (\"throw\" === method) throw arg;\n return doneResult();\n }\n\n for (context.method = method, context.arg = arg;;) {\n var delegate = context.delegate;\n\n if (delegate) {\n var delegateResult = maybeInvokeDelegate(delegate, context);\n\n if (delegateResult) {\n if (delegateResult === ContinueSentinel) continue;\n return delegateResult;\n }\n }\n\n if (\"next\" === context.method) context.sent = context._sent = context.arg;else if (\"throw\" === context.method) {\n if (\"suspendedStart\" === state) throw state = \"completed\", context.arg;\n context.dispatchException(context.arg);\n } else \"return\" === context.method && context.abrupt(\"return\", context.arg);\n state = \"executing\";\n var record = tryCatch(innerFn, self, context);\n\n if (\"normal\" === record.type) {\n if (state = context.done ? \"completed\" : \"suspendedYield\", record.arg === ContinueSentinel) continue;\n return {\n value: record.arg,\n done: context.done\n };\n }\n\n \"throw\" === record.type && (state = \"completed\", context.method = \"throw\", context.arg = record.arg);\n }\n };\n }(innerFn, self, context), generator;\n }\n\n function tryCatch(fn, obj, arg) {\n try {\n return {\n type: \"normal\",\n arg: fn.call(obj, arg)\n };\n } catch (err) {\n return {\n type: \"throw\",\n arg: err\n };\n }\n }\n\n exports.wrap = wrap;\n var ContinueSentinel = {};\n\n function Generator() {}\n\n function GeneratorFunction() {}\n\n function GeneratorFunctionPrototype() {}\n\n var IteratorPrototype = {};\n define(IteratorPrototype, iteratorSymbol, function () {\n return this;\n });\n var getProto = Object.getPrototypeOf,\n NativeIteratorPrototype = getProto && getProto(getProto(values([])));\n NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype);\n var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype);\n\n function defineIteratorMethods(prototype) {\n [\"next\", \"throw\", \"return\"].forEach(function (method) {\n define(prototype, method, function (arg) {\n return this._invoke(method, arg);\n });\n });\n }\n\n function AsyncIterator(generator, PromiseImpl) {\n function invoke(method, arg, resolve, reject) {\n var record = tryCatch(generator[method], generator, arg);\n\n if (\"throw\" !== record.type) {\n var result = record.arg,\n value = result.value;\n return value && \"object\" == _typeof(value) && hasOwn.call(value, \"__await\") ? PromiseImpl.resolve(value.__await).then(function (value) {\n invoke(\"next\", value, resolve, reject);\n }, function (err) {\n invoke(\"throw\", err, resolve, reject);\n }) : PromiseImpl.resolve(value).then(function (unwrapped) {\n result.value = unwrapped, resolve(result);\n }, function (error) {\n return invoke(\"throw\", error, resolve, reject);\n });\n }\n\n reject(record.arg);\n }\n\n var previousPromise;\n\n this._invoke = function (method, arg) {\n function callInvokeWithMethodAndArg() {\n return new PromiseImpl(function (resolve, reject) {\n invoke(method, arg, resolve, reject);\n });\n }\n\n return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg();\n };\n }\n\n function maybeInvokeDelegate(delegate, context) {\n var method = delegate.iterator[context.method];\n\n if (undefined === method) {\n if (context.delegate = null, \"throw\" === context.method) {\n if (delegate.iterator[\"return\"] && (context.method = \"return\", context.arg = undefined, maybeInvokeDelegate(delegate, context), \"throw\" === context.method)) return ContinueSentinel;\n context.method = \"throw\", context.arg = new TypeError(\"The iterator does not provide a 'throw' method\");\n }\n\n return ContinueSentinel;\n }\n\n var record = tryCatch(method, delegate.iterator, context.arg);\n if (\"throw\" === record.type) return context.method = \"throw\", context.arg = record.arg, context.delegate = null, ContinueSentinel;\n var info = record.arg;\n return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, \"return\" !== context.method && (context.method = \"next\", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = \"throw\", context.arg = new TypeError(\"iterator result is not an object\"), context.delegate = null, ContinueSentinel);\n }\n\n function pushTryEntry(locs) {\n var entry = {\n tryLoc: locs[0]\n };\n 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry);\n }\n\n function resetTryEntry(entry) {\n var record = entry.completion || {};\n record.type = \"normal\", delete record.arg, entry.completion = record;\n }\n\n function Context(tryLocsList) {\n this.tryEntries = [{\n tryLoc: \"root\"\n }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0);\n }\n\n function values(iterable) {\n if (iterable) {\n var iteratorMethod = iterable[iteratorSymbol];\n if (iteratorMethod) return iteratorMethod.call(iterable);\n if (\"function\" == typeof iterable.next) return iterable;\n\n if (!isNaN(iterable.length)) {\n var i = -1,\n next = function next() {\n for (; ++i < iterable.length;) {\n if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next;\n }\n\n return next.value = undefined, next.done = !0, next;\n };\n\n return next.next = next;\n }\n }\n\n return {\n next: doneResult\n };\n }\n\n function doneResult() {\n return {\n value: undefined,\n done: !0\n };\n }\n\n return GeneratorFunction.prototype = GeneratorFunctionPrototype, define(Gp, \"constructor\", GeneratorFunctionPrototype), define(GeneratorFunctionPrototype, \"constructor\", GeneratorFunction), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, \"GeneratorFunction\"), exports.isGeneratorFunction = function (genFun) {\n var ctor = \"function\" == typeof genFun && genFun.constructor;\n return !!ctor && (ctor === GeneratorFunction || \"GeneratorFunction\" === (ctor.displayName || ctor.name));\n }, exports.mark = function (genFun) {\n return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, \"GeneratorFunction\")), genFun.prototype = Object.create(Gp), genFun;\n }, exports.awrap = function (arg) {\n return {\n __await: arg\n };\n }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () {\n return this;\n }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) {\n void 0 === PromiseImpl && (PromiseImpl = Promise);\n var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl);\n return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) {\n return result.done ? result.value : iter.next();\n });\n }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, \"Generator\"), define(Gp, iteratorSymbol, function () {\n return this;\n }), define(Gp, \"toString\", function () {\n return \"[object Generator]\";\n }), exports.keys = function (object) {\n var keys = [];\n\n for (var key in object) {\n keys.push(key);\n }\n\n return keys.reverse(), function next() {\n for (; keys.length;) {\n var key = keys.pop();\n if (key in object) return next.value = key, next.done = !1, next;\n }\n\n return next.done = !0, next;\n };\n }, exports.values = values, Context.prototype = {\n constructor: Context,\n reset: function reset(skipTempReset) {\n if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = \"next\", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) {\n \"t\" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined);\n }\n },\n stop: function stop() {\n this.done = !0;\n var rootRecord = this.tryEntries[0].completion;\n if (\"throw\" === rootRecord.type) throw rootRecord.arg;\n return this.rval;\n },\n dispatchException: function dispatchException(exception) {\n if (this.done) throw exception;\n var context = this;\n\n function handle(loc, caught) {\n return record.type = \"throw\", record.arg = exception, context.next = loc, caught && (context.method = \"next\", context.arg = undefined), !!caught;\n }\n\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i],\n record = entry.completion;\n if (\"root\" === entry.tryLoc) return handle(\"end\");\n\n if (entry.tryLoc <= this.prev) {\n var hasCatch = hasOwn.call(entry, \"catchLoc\"),\n hasFinally = hasOwn.call(entry, \"finallyLoc\");\n\n if (hasCatch && hasFinally) {\n if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0);\n if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc);\n } else if (hasCatch) {\n if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0);\n } else {\n if (!hasFinally) throw new Error(\"try statement without catch or finally\");\n if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc);\n }\n }\n }\n },\n abrupt: function abrupt(type, arg) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n\n if (entry.tryLoc <= this.prev && hasOwn.call(entry, \"finallyLoc\") && this.prev < entry.finallyLoc) {\n var finallyEntry = entry;\n break;\n }\n }\n\n finallyEntry && (\"break\" === type || \"continue\" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null);\n var record = finallyEntry ? finallyEntry.completion : {};\n return record.type = type, record.arg = arg, finallyEntry ? (this.method = \"next\", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record);\n },\n complete: function complete(record, afterLoc) {\n if (\"throw\" === record.type) throw record.arg;\n return \"break\" === record.type || \"continue\" === record.type ? this.next = record.arg : \"return\" === record.type ? (this.rval = this.arg = record.arg, this.method = \"return\", this.next = \"end\") : \"normal\" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel;\n },\n finish: function finish(finallyLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel;\n }\n },\n \"catch\": function _catch(tryLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n\n if (entry.tryLoc === tryLoc) {\n var record = entry.completion;\n\n if (\"throw\" === record.type) {\n var thrown = record.arg;\n resetTryEntry(entry);\n }\n\n return thrown;\n }\n }\n\n throw new Error(\"illegal catch attempt\");\n },\n delegateYield: function delegateYield(iterable, resultName, nextLoc) {\n return this.delegate = {\n iterator: values(iterable),\n resultName: resultName,\n nextLoc: nextLoc\n }, \"next\" === this.method && (this.arg = undefined), ContinueSentinel;\n }\n }, exports;\n}\n\nmodule.exports = _regeneratorRuntime, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;","function _typeof(obj) {\n \"@babel/helpers - typeof\";\n\n return (module.exports = _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (obj) {\n return typeof obj;\n } : function (obj) {\n return obj && \"function\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n }, module.exports.__esModule = true, module.exports[\"default\"] = module.exports), _typeof(obj);\n}\n\nmodule.exports = _typeof, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;","// TODO(Babel 8): Remove this file.\n\nvar runtime = require(\"../helpers/regeneratorRuntime\")();\nmodule.exports = runtime;\n\n// Copied from https://github.com/facebook/regenerator/blob/main/packages/runtime/runtime.js#L736=\ntry {\n regeneratorRuntime = runtime;\n} catch (accidentalStrictMode) {\n if (typeof globalThis === \"object\") {\n globalThis.regeneratorRuntime = runtime;\n } else {\n Function(\"r\", \"regeneratorRuntime = r\")(runtime);\n }\n}\n","/**\n * lodash (Custom Build) <https://lodash.com/>\n * Build: `lodash modularize exports=\"npm\" -o ./`\n * Copyright jQuery Foundation and other contributors <https://jquery.org/>\n * Released under MIT license <https://lodash.com/license>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n\n/** Used as the size to enable large array optimizations. */\nvar LARGE_ARRAY_SIZE = 200;\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n objectTag = '[object Object]',\n promiseTag = '[object Promise]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]',\n weakMapTag = '[object WeakMap]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n/**\n * Used to match `RegExp`\n * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n */\nvar reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g;\n\n/** Used to match `RegExp` flags from their coerced string values. */\nvar reFlags = /\\w*$/;\n\n/** Used to detect host constructors (Safari). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/** Used to identify `toStringTag` values supported by `_.clone`. */\nvar cloneableTags = {};\ncloneableTags[argsTag] = cloneableTags[arrayTag] =\ncloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =\ncloneableTags[boolTag] = cloneableTags[dateTag] =\ncloneableTags[float32Tag] = cloneableTags[float64Tag] =\ncloneableTags[int8Tag] = cloneableTags[int16Tag] =\ncloneableTags[int32Tag] = cloneableTags[mapTag] =\ncloneableTags[numberTag] = cloneableTags[objectTag] =\ncloneableTags[regexpTag] = cloneableTags[setTag] =\ncloneableTags[stringTag] = cloneableTags[symbolTag] =\ncloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =\ncloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;\ncloneableTags[errorTag] = cloneableTags[funcTag] =\ncloneableTags[weakMapTag] = false;\n\n/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/**\n * Adds the key-value `pair` to `map`.\n *\n * @private\n * @param {Object} map The map to modify.\n * @param {Array} pair The key-value pair to add.\n * @returns {Object} Returns `map`.\n */\nfunction addMapEntry(map, pair) {\n // Don't return `map.set` because it's not chainable in IE 11.\n map.set(pair[0], pair[1]);\n return map;\n}\n\n/**\n * Adds `value` to `set`.\n *\n * @private\n * @param {Object} set The set to modify.\n * @param {*} value The value to add.\n * @returns {Object} Returns `set`.\n */\nfunction addSetEntry(set, value) {\n // Don't return `set.add` because it's not chainable in IE 11.\n set.add(value);\n return set;\n}\n\n/**\n * A specialized version of `_.forEach` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns `array`.\n */\nfunction arrayEach(array, iteratee) {\n var index = -1,\n length = array ? array.length : 0;\n\n while (++index < length) {\n if (iteratee(array[index], index, array) === false) {\n break;\n }\n }\n return array;\n}\n\n/**\n * Appends the elements of `values` to `array`.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to append.\n * @returns {Array} Returns `array`.\n */\nfunction arrayPush(array, values) {\n var index = -1,\n length = values.length,\n offset = array.length;\n\n while (++index < length) {\n array[offset + index] = values[index];\n }\n return array;\n}\n\n/**\n * A specialized version of `_.reduce` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {*} [accumulator] The initial value.\n * @param {boolean} [initAccum] Specify using the first element of `array` as\n * the initial value.\n * @returns {*} Returns the accumulated value.\n */\nfunction arrayReduce(array, iteratee, accumulator, initAccum) {\n var index = -1,\n length = array ? array.length : 0;\n\n if (initAccum && length) {\n accumulator = array[++index];\n }\n while (++index < length) {\n accumulator = iteratee(accumulator, array[index], index, array);\n }\n return accumulator;\n}\n\n/**\n * The base implementation of `_.times` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\nfunction baseTimes(n, iteratee) {\n var index = -1,\n result = Array(n);\n\n while (++index < n) {\n result[index] = iteratee(index);\n }\n return result;\n}\n\n/**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction getValue(object, key) {\n return object == null ? undefined : object[key];\n}\n\n/**\n * Checks if `value` is a host object in IE < 9.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a host object, else `false`.\n */\nfunction isHostObject(value) {\n // Many host objects are `Object` objects that can coerce to strings\n // despite having improperly defined `toString` methods.\n var result = false;\n if (value != null && typeof value.toString != 'function') {\n try {\n result = !!(value + '');\n } catch (e) {}\n }\n return result;\n}\n\n/**\n * Converts `map` to its key-value pairs.\n *\n * @private\n * @param {Object} map The map to convert.\n * @returns {Array} Returns the key-value pairs.\n */\nfunction mapToArray(map) {\n var index = -1,\n result = Array(map.size);\n\n map.forEach(function(value, key) {\n result[++index] = [key, value];\n });\n return result;\n}\n\n/**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\nfunction overArg(func, transform) {\n return function(arg) {\n return func(transform(arg));\n };\n}\n\n/**\n * Converts `set` to an array of its values.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the values.\n */\nfunction setToArray(set) {\n var index = -1,\n result = Array(set.size);\n\n set.forEach(function(value) {\n result[++index] = value;\n });\n return result;\n}\n\n/** Used for built-in method references. */\nvar arrayProto = Array.prototype,\n funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to detect overreaching core-js shims. */\nvar coreJsData = root['__core-js_shared__'];\n\n/** Used to detect methods masquerading as native. */\nvar maskSrcKey = (function() {\n var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n return uid ? ('Symbol(src)_1.' + uid) : '';\n}());\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/** Built-in value references. */\nvar Buffer = moduleExports ? root.Buffer : undefined,\n Symbol = root.Symbol,\n Uint8Array = root.Uint8Array,\n getPrototype = overArg(Object.getPrototypeOf, Object),\n objectCreate = Object.create,\n propertyIsEnumerable = objectProto.propertyIsEnumerable,\n splice = arrayProto.splice;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeGetSymbols = Object.getOwnPropertySymbols,\n nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,\n nativeKeys = overArg(Object.keys, Object);\n\n/* Built-in method references that are verified to be native. */\nvar DataView = getNative(root, 'DataView'),\n Map = getNative(root, 'Map'),\n Promise = getNative(root, 'Promise'),\n Set = getNative(root, 'Set'),\n WeakMap = getNative(root, 'WeakMap'),\n nativeCreate = getNative(Object, 'create');\n\n/** Used to detect maps, sets, and weakmaps. */\nvar dataViewCtorString = toSource(DataView),\n mapCtorString = toSource(Map),\n promiseCtorString = toSource(Promise),\n setCtorString = toSource(Set),\n weakMapCtorString = toSource(WeakMap);\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;\n\n/**\n * Creates a hash object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Hash(entries) {\n var index = -1,\n length = entries ? entries.length : 0;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n/**\n * Removes all key-value entries from the hash.\n *\n * @private\n * @name clear\n * @memberOf Hash\n */\nfunction hashClear() {\n this.__data__ = nativeCreate ? nativeCreate(null) : {};\n}\n\n/**\n * Removes `key` and its value from the hash.\n *\n * @private\n * @name delete\n * @memberOf Hash\n * @param {Object} hash The hash to modify.\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction hashDelete(key) {\n return this.has(key) && delete this.__data__[key];\n}\n\n/**\n * Gets the hash value for `key`.\n *\n * @private\n * @name get\n * @memberOf Hash\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction hashGet(key) {\n var data = this.__data__;\n if (nativeCreate) {\n var result = data[key];\n return result === HASH_UNDEFINED ? undefined : result;\n }\n return hasOwnProperty.call(data, key) ? data[key] : undefined;\n}\n\n/**\n * Checks if a hash value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Hash\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction hashHas(key) {\n var data = this.__data__;\n return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key);\n}\n\n/**\n * Sets the hash `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Hash\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the hash instance.\n */\nfunction hashSet(key, value) {\n var data = this.__data__;\n data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;\n return this;\n}\n\n// Add methods to `Hash`.\nHash.prototype.clear = hashClear;\nHash.prototype['delete'] = hashDelete;\nHash.prototype.get = hashGet;\nHash.prototype.has = hashHas;\nHash.prototype.set = hashSet;\n\n/**\n * Creates an list cache object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction ListCache(entries) {\n var index = -1,\n length = entries ? entries.length : 0;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n/**\n * Removes all key-value entries from the list cache.\n *\n * @private\n * @name clear\n * @memberOf ListCache\n */\nfunction listCacheClear() {\n this.__data__ = [];\n}\n\n/**\n * Removes `key` and its value from the list cache.\n *\n * @private\n * @name delete\n * @memberOf ListCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction listCacheDelete(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n return false;\n }\n var lastIndex = data.length - 1;\n if (index == lastIndex) {\n data.pop();\n } else {\n splice.call(data, index, 1);\n }\n return true;\n}\n\n/**\n * Gets the list cache value for `key`.\n *\n * @private\n * @name get\n * @memberOf ListCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction listCacheGet(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n return index < 0 ? undefined : data[index][1];\n}\n\n/**\n * Checks if a list cache value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf ListCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction listCacheHas(key) {\n return assocIndexOf(this.__data__, key) > -1;\n}\n\n/**\n * Sets the list cache `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf ListCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the list cache instance.\n */\nfunction listCacheSet(key, value) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n data.push([key, value]);\n } else {\n data[index][1] = value;\n }\n return this;\n}\n\n// Add methods to `ListCache`.\nListCache.prototype.clear = listCacheClear;\nListCache.prototype['delete'] = listCacheDelete;\nListCache.prototype.get = listCacheGet;\nListCache.prototype.has = listCacheHas;\nListCache.prototype.set = listCacheSet;\n\n/**\n * Creates a map cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction MapCache(entries) {\n var index = -1,\n length = entries ? entries.length : 0;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n/**\n * Removes all key-value entries from the map.\n *\n * @private\n * @name clear\n * @memberOf MapCache\n */\nfunction mapCacheClear() {\n this.__data__ = {\n 'hash': new Hash,\n 'map': new (Map || ListCache),\n 'string': new Hash\n };\n}\n\n/**\n * Removes `key` and its value from the map.\n *\n * @private\n * @name delete\n * @memberOf MapCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction mapCacheDelete(key) {\n return getMapData(this, key)['delete'](key);\n}\n\n/**\n * Gets the map value for `key`.\n *\n * @private\n * @name get\n * @memberOf MapCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction mapCacheGet(key) {\n return getMapData(this, key).get(key);\n}\n\n/**\n * Checks if a map value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf MapCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction mapCacheHas(key) {\n return getMapData(this, key).has(key);\n}\n\n/**\n * Sets the map `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf MapCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the map cache instance.\n */\nfunction mapCacheSet(key, value) {\n getMapData(this, key).set(key, value);\n return this;\n}\n\n// Add methods to `MapCache`.\nMapCache.prototype.clear = mapCacheClear;\nMapCache.prototype['delete'] = mapCacheDelete;\nMapCache.prototype.get = mapCacheGet;\nMapCache.prototype.has = mapCacheHas;\nMapCache.prototype.set = mapCacheSet;\n\n/**\n * Creates a stack cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Stack(entries) {\n this.__data__ = new ListCache(entries);\n}\n\n/**\n * Removes all key-value entries from the stack.\n *\n * @private\n * @name clear\n * @memberOf Stack\n */\nfunction stackClear() {\n this.__data__ = new ListCache;\n}\n\n/**\n * Removes `key` and its value from the stack.\n *\n * @private\n * @name delete\n * @memberOf Stack\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction stackDelete(key) {\n return this.__data__['delete'](key);\n}\n\n/**\n * Gets the stack value for `key`.\n *\n * @private\n * @name get\n * @memberOf Stack\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction stackGet(key) {\n return this.__data__.get(key);\n}\n\n/**\n * Checks if a stack value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Stack\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction stackHas(key) {\n return this.__data__.has(key);\n}\n\n/**\n * Sets the stack `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Stack\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the stack cache instance.\n */\nfunction stackSet(key, value) {\n var cache = this.__data__;\n if (cache instanceof ListCache) {\n var pairs = cache.__data__;\n if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {\n pairs.push([key, value]);\n return this;\n }\n cache = this.__data__ = new MapCache(pairs);\n }\n cache.set(key, value);\n return this;\n}\n\n// Add methods to `Stack`.\nStack.prototype.clear = stackClear;\nStack.prototype['delete'] = stackDelete;\nStack.prototype.get = stackGet;\nStack.prototype.has = stackHas;\nStack.prototype.set = stackSet;\n\n/**\n * Creates an array of the enumerable property names of the array-like `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @param {boolean} inherited Specify returning inherited property names.\n * @returns {Array} Returns the array of property names.\n */\nfunction arrayLikeKeys(value, inherited) {\n // Safari 8.1 makes `arguments.callee` enumerable in strict mode.\n // Safari 9 makes `arguments.length` enumerable in strict mode.\n var result = (isArray(value) || isArguments(value))\n ? baseTimes(value.length, String)\n : [];\n\n var length = result.length,\n skipIndexes = !!length;\n\n for (var key in value) {\n if ((inherited || hasOwnProperty.call(value, key)) &&\n !(skipIndexes && (key == 'length' || isIndex(key, length)))) {\n result.push(key);\n }\n }\n return result;\n}\n\n/**\n * Assigns `value` to `key` of `object` if the existing value is not equivalent\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction assignValue(object, key, value) {\n var objValue = object[key];\n if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||\n (value === undefined && !(key in object))) {\n object[key] = value;\n }\n}\n\n/**\n * Gets the index at which the `key` is found in `array` of key-value pairs.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} key The key to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction assocIndexOf(array, key) {\n var length = array.length;\n while (length--) {\n if (eq(array[length][0], key)) {\n return length;\n }\n }\n return -1;\n}\n\n/**\n * The base implementation of `_.assign` without support for multiple sources\n * or `customizer` functions.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @returns {Object} Returns `object`.\n */\nfunction baseAssign(object, source) {\n return object && copyObject(source, keys(source), object);\n}\n\n/**\n * The base implementation of `_.clone` and `_.cloneDeep` which tracks\n * traversed objects.\n *\n * @private\n * @param {*} value The value to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @param {boolean} [isFull] Specify a clone including symbols.\n * @param {Function} [customizer] The function to customize cloning.\n * @param {string} [key] The key of `value`.\n * @param {Object} [object] The parent object of `value`.\n * @param {Object} [stack] Tracks traversed objects and their clone counterparts.\n * @returns {*} Returns the cloned value.\n */\nfunction baseClone(value, isDeep, isFull, customizer, key, object, stack) {\n var result;\n if (customizer) {\n result = object ? customizer(value, key, object, stack) : customizer(value);\n }\n if (result !== undefined) {\n return result;\n }\n if (!isObject(value)) {\n return value;\n }\n var isArr = isArray(value);\n if (isArr) {\n result = initCloneArray(value);\n if (!isDeep) {\n return copyArray(value, result);\n }\n } else {\n var tag = getTag(value),\n isFunc = tag == funcTag || tag == genTag;\n\n if (isBuffer(value)) {\n return cloneBuffer(value, isDeep);\n }\n if (tag == objectTag || tag == argsTag || (isFunc && !object)) {\n if (isHostObject(value)) {\n return object ? value : {};\n }\n result = initCloneObject(isFunc ? {} : value);\n if (!isDeep) {\n return copySymbols(value, baseAssign(result, value));\n }\n } else {\n if (!cloneableTags[tag]) {\n return object ? value : {};\n }\n result = initCloneByTag(value, tag, baseClone, isDeep);\n }\n }\n // Check for circular references and return its corresponding clone.\n stack || (stack = new Stack);\n var stacked = stack.get(value);\n if (stacked) {\n return stacked;\n }\n stack.set(value, result);\n\n if (!isArr) {\n var props = isFull ? getAllKeys(value) : keys(value);\n }\n arrayEach(props || value, function(subValue, key) {\n if (props) {\n key = subValue;\n subValue = value[key];\n }\n // Recursively populate clone (susceptible to call stack limits).\n assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack));\n });\n return result;\n}\n\n/**\n * The base implementation of `_.create` without support for assigning\n * properties to the created object.\n *\n * @private\n * @param {Object} prototype The object to inherit from.\n * @returns {Object} Returns the new object.\n */\nfunction baseCreate(proto) {\n return isObject(proto) ? objectCreate(proto) : {};\n}\n\n/**\n * The base implementation of `getAllKeys` and `getAllKeysIn` which uses\n * `keysFunc` and `symbolsFunc` to get the enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @param {Function} symbolsFunc The function to get the symbols of `object`.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction baseGetAllKeys(object, keysFunc, symbolsFunc) {\n var result = keysFunc(object);\n return isArray(object) ? result : arrayPush(result, symbolsFunc(object));\n}\n\n/**\n * The base implementation of `getTag`.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction baseGetTag(value) {\n return objectToString.call(value);\n}\n\n/**\n * The base implementation of `_.isNative` without bad shim checks.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function,\n * else `false`.\n */\nfunction baseIsNative(value) {\n if (!isObject(value) || isMasked(value)) {\n return false;\n }\n var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor;\n return pattern.test(toSource(value));\n}\n\n/**\n * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeys(object) {\n if (!isPrototype(object)) {\n return nativeKeys(object);\n }\n var result = [];\n for (var key in Object(object)) {\n if (hasOwnProperty.call(object, key) && key != 'constructor') {\n result.push(key);\n }\n }\n return result;\n}\n\n/**\n * Creates a clone of `buffer`.\n *\n * @private\n * @param {Buffer} buffer The buffer to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Buffer} Returns the cloned buffer.\n */\nfunction cloneBuffer(buffer, isDeep) {\n if (isDeep) {\n return buffer.slice();\n }\n var result = new buffer.constructor(buffer.length);\n buffer.copy(result);\n return result;\n}\n\n/**\n * Creates a clone of `arrayBuffer`.\n *\n * @private\n * @param {ArrayBuffer} arrayBuffer The array buffer to clone.\n * @returns {ArrayBuffer} Returns the cloned array buffer.\n */\nfunction cloneArrayBuffer(arrayBuffer) {\n var result = new arrayBuffer.constructor(arrayBuffer.byteLength);\n new Uint8Array(result).set(new Uint8Array(arrayBuffer));\n return result;\n}\n\n/**\n * Creates a clone of `dataView`.\n *\n * @private\n * @param {Object} dataView The data view to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned data view.\n */\nfunction cloneDataView(dataView, isDeep) {\n var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;\n return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);\n}\n\n/**\n * Creates a clone of `map`.\n *\n * @private\n * @param {Object} map The map to clone.\n * @param {Function} cloneFunc The function to clone values.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned map.\n */\nfunction cloneMap(map, isDeep, cloneFunc) {\n var array = isDeep ? cloneFunc(mapToArray(map), true) : mapToArray(map);\n return arrayReduce(array, addMapEntry, new map.constructor);\n}\n\n/**\n * Creates a clone of `regexp`.\n *\n * @private\n * @param {Object} regexp The regexp to clone.\n * @returns {Object} Returns the cloned regexp.\n */\nfunction cloneRegExp(regexp) {\n var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));\n result.lastIndex = regexp.lastIndex;\n return result;\n}\n\n/**\n * Creates a clone of `set`.\n *\n * @private\n * @param {Object} set The set to clone.\n * @param {Function} cloneFunc The function to clone values.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned set.\n */\nfunction cloneSet(set, isDeep, cloneFunc) {\n var array = isDeep ? cloneFunc(setToArray(set), true) : setToArray(set);\n return arrayReduce(array, addSetEntry, new set.constructor);\n}\n\n/**\n * Creates a clone of the `symbol` object.\n *\n * @private\n * @param {Object} symbol The symbol object to clone.\n * @returns {Object} Returns the cloned symbol object.\n */\nfunction cloneSymbol(symbol) {\n return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};\n}\n\n/**\n * Creates a clone of `typedArray`.\n *\n * @private\n * @param {Object} typedArray The typed array to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned typed array.\n */\nfunction cloneTypedArray(typedArray, isDeep) {\n var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;\n return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);\n}\n\n/**\n * Copies the values of `source` to `array`.\n *\n * @private\n * @param {Array} source The array to copy values from.\n * @param {Array} [array=[]] The array to copy values to.\n * @returns {Array} Returns `array`.\n */\nfunction copyArray(source, array) {\n var index = -1,\n length = source.length;\n\n array || (array = Array(length));\n while (++index < length) {\n array[index] = source[index];\n }\n return array;\n}\n\n/**\n * Copies properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy properties from.\n * @param {Array} props The property identifiers to copy.\n * @param {Object} [object={}] The object to copy properties to.\n * @param {Function} [customizer] The function to customize copied values.\n * @returns {Object} Returns `object`.\n */\nfunction copyObject(source, props, object, customizer) {\n object || (object = {});\n\n var index = -1,\n length = props.length;\n\n while (++index < length) {\n var key = props[index];\n\n var newValue = customizer\n ? customizer(object[key], source[key], key, object, source)\n : undefined;\n\n assignValue(object, key, newValue === undefined ? source[key] : newValue);\n }\n return object;\n}\n\n/**\n * Copies own symbol properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy symbols from.\n * @param {Object} [object={}] The object to copy symbols to.\n * @returns {Object} Returns `object`.\n */\nfunction copySymbols(source, object) {\n return copyObject(source, getSymbols(source), object);\n}\n\n/**\n * Creates an array of own enumerable property names and symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction getAllKeys(object) {\n return baseGetAllKeys(object, keys, getSymbols);\n}\n\n/**\n * Gets the data for `map`.\n *\n * @private\n * @param {Object} map The map to query.\n * @param {string} key The reference key.\n * @returns {*} Returns the map data.\n */\nfunction getMapData(map, key) {\n var data = map.__data__;\n return isKeyable(key)\n ? data[typeof key == 'string' ? 'string' : 'hash']\n : data.map;\n}\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n var value = getValue(object, key);\n return baseIsNative(value) ? value : undefined;\n}\n\n/**\n * Creates an array of the own enumerable symbol properties of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\nvar getSymbols = nativeGetSymbols ? overArg(nativeGetSymbols, Object) : stubArray;\n\n/**\n * Gets the `toStringTag` of `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nvar getTag = baseGetTag;\n\n// Fallback for data views, maps, sets, and weak maps in IE 11,\n// for data views in Edge < 14, and promises in Node.js.\nif ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||\n (Map && getTag(new Map) != mapTag) ||\n (Promise && getTag(Promise.resolve()) != promiseTag) ||\n (Set && getTag(new Set) != setTag) ||\n (WeakMap && getTag(new WeakMap) != weakMapTag)) {\n getTag = function(value) {\n var result = objectToString.call(value),\n Ctor = result == objectTag ? value.constructor : undefined,\n ctorString = Ctor ? toSource(Ctor) : undefined;\n\n if (ctorString) {\n switch (ctorString) {\n case dataViewCtorString: return dataViewTag;\n case mapCtorString: return mapTag;\n case promiseCtorString: return promiseTag;\n case setCtorString: return setTag;\n case weakMapCtorString: return weakMapTag;\n }\n }\n return result;\n };\n}\n\n/**\n * Initializes an array clone.\n *\n * @private\n * @param {Array} array The array to clone.\n * @returns {Array} Returns the initialized clone.\n */\nfunction initCloneArray(array) {\n var length = array.length,\n result = array.constructor(length);\n\n // Add properties assigned by `RegExp#exec`.\n if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {\n result.index = array.index;\n result.input = array.input;\n }\n return result;\n}\n\n/**\n * Initializes an object clone.\n *\n * @private\n * @param {Object} object The object to clone.\n * @returns {Object} Returns the initialized clone.\n */\nfunction initCloneObject(object) {\n return (typeof object.constructor == 'function' && !isPrototype(object))\n ? baseCreate(getPrototype(object))\n : {};\n}\n\n/**\n * Initializes an object clone based on its `toStringTag`.\n *\n * **Note:** This function only supports cloning values with tags of\n * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n *\n * @private\n * @param {Object} object The object to clone.\n * @param {string} tag The `toStringTag` of the object to clone.\n * @param {Function} cloneFunc The function to clone values.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the initialized clone.\n */\nfunction initCloneByTag(object, tag, cloneFunc, isDeep) {\n var Ctor = object.constructor;\n switch (tag) {\n case arrayBufferTag:\n return cloneArrayBuffer(object);\n\n case boolTag:\n case dateTag:\n return new Ctor(+object);\n\n case dataViewTag:\n return cloneDataView(object, isDeep);\n\n case float32Tag: case float64Tag:\n case int8Tag: case int16Tag: case int32Tag:\n case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:\n return cloneTypedArray(object, isDeep);\n\n case mapTag:\n return cloneMap(object, isDeep, cloneFunc);\n\n case numberTag:\n case stringTag:\n return new Ctor(object);\n\n case regexpTag:\n return cloneRegExp(object);\n\n case setTag:\n return cloneSet(object, isDeep, cloneFunc);\n\n case symbolTag:\n return cloneSymbol(object);\n }\n}\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n length = length == null ? MAX_SAFE_INTEGER : length;\n return !!length &&\n (typeof value == 'number' || reIsUint.test(value)) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\n/**\n * Checks if `value` is suitable for use as unique object key.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n */\nfunction isKeyable(value) {\n var type = typeof value;\n return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n ? (value !== '__proto__')\n : (value === null);\n}\n\n/**\n * Checks if `func` has its source masked.\n *\n * @private\n * @param {Function} func The function to check.\n * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n */\nfunction isMasked(func) {\n return !!maskSrcKey && (maskSrcKey in func);\n}\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n}\n\n/**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to process.\n * @returns {string} Returns the source code.\n */\nfunction toSource(func) {\n if (func != null) {\n try {\n return funcToString.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n}\n\n/**\n * This method is like `_.clone` except that it recursively clones `value`.\n *\n * @static\n * @memberOf _\n * @since 1.0.0\n * @category Lang\n * @param {*} value The value to recursively clone.\n * @returns {*} Returns the deep cloned value.\n * @see _.clone\n * @example\n *\n * var objects = [{ 'a': 1 }, { 'b': 2 }];\n *\n * var deep = _.cloneDeep(objects);\n * console.log(deep[0] === objects[0]);\n * // => false\n */\nfunction cloneDeep(value) {\n return baseClone(value, true, true);\n}\n\n/**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n return value === other || (value !== value && other !== other);\n}\n\n/**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n * else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\nfunction isArguments(value) {\n // Safari 8.1 makes `arguments.callee` enumerable in strict mode.\n return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&\n (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);\n}\n\n/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n return value != null && isLength(value.length) && !isFunction(value);\n}\n\n/**\n * This method is like `_.isArrayLike` except that it also checks if `value`\n * is an object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array-like object,\n * else `false`.\n * @example\n *\n * _.isArrayLikeObject([1, 2, 3]);\n * // => true\n *\n * _.isArrayLikeObject(document.body.children);\n * // => true\n *\n * _.isArrayLikeObject('abc');\n * // => false\n *\n * _.isArrayLikeObject(_.noop);\n * // => false\n */\nfunction isArrayLikeObject(value) {\n return isObjectLike(value) && isArrayLike(value);\n}\n\n/**\n * Checks if `value` is a buffer.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.\n * @example\n *\n * _.isBuffer(new Buffer(2));\n * // => true\n *\n * _.isBuffer(new Uint8Array(2));\n * // => false\n */\nvar isBuffer = nativeIsBuffer || stubFalse;\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 8-9 which returns 'object' for typed array and other constructors.\n var tag = isObject(value) ? objectToString.call(value) : '';\n return tag == funcTag || tag == genTag;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return !!value && typeof value == 'object';\n}\n\n/**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\nfunction keys(object) {\n return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);\n}\n\n/**\n * This method returns a new empty array.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {Array} Returns the new empty array.\n * @example\n *\n * var arrays = _.times(2, _.stubArray);\n *\n * console.log(arrays);\n * // => [[], []]\n *\n * console.log(arrays[0] === arrays[1]);\n * // => false\n */\nfunction stubArray() {\n return [];\n}\n\n/**\n * This method returns `false`.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {boolean} Returns `false`.\n * @example\n *\n * _.times(2, _.stubFalse);\n * // => [false, false]\n */\nfunction stubFalse() {\n return false;\n}\n\nmodule.exports = cloneDeep;\n","module.exports = __WEBPACK_EXTERNAL_MODULE__785__;","module.exports = __WEBPACK_EXTERNAL_MODULE__948__;","module.exports = __WEBPACK_EXTERNAL_MODULE__807__;","module.exports = __WEBPACK_EXTERNAL_MODULE__847__;","module.exports = __WEBPACK_EXTERNAL_MODULE__348__;","module.exports = __WEBPACK_EXTERNAL_MODULE__283__;","module.exports = __WEBPACK_EXTERNAL_MODULE__441__;","module.exports = __WEBPACK_EXTERNAL_MODULE__864__;","module.exports = __WEBPACK_EXTERNAL_MODULE__70__;","module.exports = __WEBPACK_EXTERNAL_MODULE__474__;","module.exports = __WEBPACK_EXTERNAL_MODULE__821__;","module.exports = __WEBPACK_EXTERNAL_MODULE__795__;","module.exports = __WEBPACK_EXTERNAL_MODULE__896__;","module.exports = __WEBPACK_EXTERNAL_MODULE__861__;","module.exports = __WEBPACK_EXTERNAL_MODULE__610__;","module.exports = __WEBPACK_EXTERNAL_MODULE__478__;","module.exports = __WEBPACK_EXTERNAL_MODULE__329__;","module.exports = __WEBPACK_EXTERNAL_MODULE__673__;","module.exports = __WEBPACK_EXTERNAL_MODULE__281__;","module.exports = __WEBPACK_EXTERNAL_MODULE__739__;","module.exports = __WEBPACK_EXTERNAL_MODULE__9__;","module.exports = __WEBPACK_EXTERNAL_MODULE__468__;","module.exports = __WEBPACK_EXTERNAL_MODULE__643__;","module.exports = __WEBPACK_EXTERNAL_MODULE__128__;","module.exports = __WEBPACK_EXTERNAL_MODULE__664__;","module.exports = __WEBPACK_EXTERNAL_MODULE__973__;","module.exports = __WEBPACK_EXTERNAL_MODULE__394__;","module.exports = __WEBPACK_EXTERNAL_MODULE__582__;","module.exports = __WEBPACK_EXTERNAL_MODULE__482__;","module.exports = __WEBPACK_EXTERNAL_MODULE__343__;","module.exports = __WEBPACK_EXTERNAL_MODULE__21__;","module.exports = __WEBPACK_EXTERNAL_MODULE__363__;","module.exports = __WEBPACK_EXTERNAL_MODULE__982__;","module.exports = __WEBPACK_EXTERNAL_MODULE__130__;","module.exports = __WEBPACK_EXTERNAL_MODULE__298__;","module.exports = __WEBPACK_EXTERNAL_MODULE__953__;","module.exports = __WEBPACK_EXTERNAL_MODULE__395__;","module.exports = __WEBPACK_EXTERNAL_MODULE__398__;","module.exports = __WEBPACK_EXTERNAL_MODULE__388__;","module.exports = __WEBPACK_EXTERNAL_MODULE__215__;","module.exports = __WEBPACK_EXTERNAL_MODULE__120__;","module.exports = __WEBPACK_EXTERNAL_MODULE__197__;","module.exports = __WEBPACK_EXTERNAL_MODULE__976__;","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\tid: moduleId,\n\t\tloaded: false,\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Flag the module as loaded\n\tmodule.loaded = true;\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = function(module) {\n\tvar getter = module && module.__esModule ?\n\t\tfunction() { return module['default']; } :\n\t\tfunction() { return module; };\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","// define __esModule on exports\n__webpack_require__.r = function(exports) {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","__webpack_require__.nmd = function(module) {\n\tmodule.paths = [];\n\tif (!module.children) module.children = [];\n\treturn module;\n};","/**\n * Cornerstone Core events\n */\nenum Events {\n /**\n * ERROR CODES\n */\n\n /**\n * Error that is thrown when the ImageCache exceeds its max cache size.\n * This can happen for both volumes and stack images.\n */\n CACHE_SIZE_EXCEEDED = 'CACHE_SIZE_EXCEEDED',\n /**\n * Happens if an image (either a single image in stack viewport) or a slice\n * of a volume fails to load by the image/volume loaders.\n */\n IMAGE_LOAD_ERROR = 'IMAGE_LOAD_ERROR',\n\n /**\n * Triggers on the HTML element when the viewport camera changes.\n *\n * Make use of {@link EventTypes.CameraModifiedEvent | CameraModified Event Type } for typing your event listeners for CAMERA_MODIFIED event,\n * and see what event detail is included in {@link EventTypes.CameraModifiedEventDetail | CameraModified Event Detail }\n */\n CAMERA_MODIFIED = 'CORNERSTONE_CAMERA_MODIFIED',\n /**\n * Triggers on the HTML element when the viewport camera resets\n *\n * Make use of {@link EventTypes.CameraResetEvent | CameraReset Event Type } for typing your event listeners for CAMERA_RESET event,\n * and see what event detail is included in {@link EventTypes.CameraResetEventDetail | CameraReset Event Detail }\n */\n CAMERA_RESET = 'CORNERSTONE_CAMERA_RESET',\n /**\n * Triggers on the HTML element when viewport modifies its VOI\n *\n * Make use of {@link EventTypes.VoiModifiedEvent | VoiModified Event Type } for typing your event listeners for VOI_MODIFIED event,\n * and see what event detail is included in {@link EventTypes.VoiModifiedEventDetail | VoiModified Event Detail }\n */\n VOI_MODIFIED = 'CORNERSTONE_VOI_MODIFIED',\n /**\n * Triggers on the eventTarget when the element is disabled\n *\n * Make use of {@link EventTypes.ElementDisabledEvent | ElementDisabled Event Type } for typing your event listeners for ELEMENT_DISABLED event,\n * and see what event detail is included in {@link EventTypes.ElementDisabledEventDetail | ElementDisabled Event Detail }\n */\n ELEMENT_DISABLED = 'CORNERSTONE_ELEMENT_DISABLED',\n /**\n * Triggers on the eventTarget when the element is enabled\n *\n * Make use of {@link EventTypes.ElementEnabledEvent | ElementEnabled Event Type } for typing your event listeners for ELEMENT_ENABLED event,\n * and see what event detail is included in {@link EventTypes.ElementEnabledEventDetail | ElementEnabled Event Detail }\n */\n ELEMENT_ENABLED = 'CORNERSTONE_ELEMENT_ENABLED',\n /**\n * Triggers on the element when the image in the element has been rendered\n *\n * Make use of {@link EventTypes.ImageRenderedEvent | ImageRendered Event Type } for typing your event listeners for IMAGE_RENDERED event,\n * and see what event detail is included in {@link EventTypes.ImageRenderedEventDetail | ImageRendered Event Detail }\n */\n IMAGE_RENDERED = 'CORNERSTONE_IMAGE_RENDERED',\n /**\n * Triggers on the eventTarget when the image volume data is modified. This happens\n * in the streamingImageLoader when each frame is loaded and inserted into a volume.\n *\n *\n * Make use of {@link EventTypes.ImageVolumeModifiedEvent | ImageVolumeModified Event Type } for typing your event listeners for IMAGE_VOLUME_MODIFIED event,\n * and see what event detail is included in {@link EventTypes.ImageVolumeModifiedEventDetail | ImageVolumeModified Event Detail }\n */\n IMAGE_VOLUME_MODIFIED = 'CORNERSTONE_IMAGE_VOLUME_MODIFIED',\n /**\n * Triggers on the eventTarget when the image has successfully loaded by imageLoaders\n *\n * Make use of {@link EventTypes.ImageLoadedEvent | ImageLoaded Event Type } for typing your event listeners for IMAGE_LOADED event,\n * and see what event detail is included in {@link EventTypes.ImageLoadedEventDetail | ImageLoaded Event Detail }\n */\n IMAGE_LOADED = 'CORNERSTONE_IMAGE_LOADED',\n /**\n * Triggers on the eventTarget when the image has failed loading by imageLoaders\n *\n * Make use of {@link EventTypes.ImageLoadedFailedEvent | ImageLoadedFailed Event Type } for typing your event listeners for IMAGE_LOADED_FAILED event,\n * and see what event detail is included in {@link EventTypes.ImageLoadedFailedEventDetail | ImageLoadedFailed Event Detail }\n */\n IMAGE_LOAD_FAILED = 'CORNERSTONE_IMAGE_LOAD_FAILED',\n /**\n * Triggers on element when a new voluem is set on the volume viewport\n */\n VOLUME_VIEWPORT_NEW_VOLUME = 'CORNERSTONE_VOLUME_VIEWPORT_NEW_VOLUME',\n\n /**\n * Triggers on the eventTarget when the volume has successfully loaded by volumeLoaders\n *\n * Make use of {@link EventTypes.VolumeLoadedEvent | VolumeLoaded Event Type } for typing your event listeners for VOLUME_LOADED event,\n * and see what event detail is included in {@link EventTypes.VolumeLoadedEventDetail | VolumeLoaded Event Detail }\n */\n VOLUME_LOADED = 'CORNERSTONE_VOLUME_LOADED',\n /**\n * Triggers on the eventTarget when the image has failed loading by volumeLoaders\n *\n * Make use of {@link EventTypes.VolumeLoadedFailedEvent | VolumeLoadedFailed Event Type } for typing your event listeners for VOLUME_LOADED_FAILED event,\n * and see what event detail is included in {@link EventTypes.VolumeLoadedFailedEventDetail | VolumeLoadedFailed Event Detail }\n */\n VOLUME_LOADED_FAILED = 'CORNERSTONE_VOLUME_LOADED_FAILED',\n /**\n * Triggers on the eventTarget when an image is added to the image cache\n *\n * Make use of {@link EventTypes.ImageCacheImageAddedEvent | ImageCacheAdded Event Type } for typing your event listeners for IMAGE_CACHE_ADDED event,\n * and see what event detail is included in {@link EventTypes.ImageCacheImageAddedEventDetail | ImageCacheAdded Event Detail }\n */\n IMAGE_CACHE_IMAGE_ADDED = 'CORNERSTONE_IMAGE_CACHE_IMAGE_ADDED',\n /**\n * Triggers on the eventTarget when an image is removed from the image cache\n *\n * Make use of {@link EventTypes.ImageCacheImageRemovedEvent | ImageCacheRemoved Event Type } for typing your event listeners for IMAGE_CACHE_REMOVED event,\n * and see what event detail is included in {@link EventTypes.ImageCacheImageRemovedEventDetail | ImageCacheRemoved Event Detail }\n */\n IMAGE_CACHE_IMAGE_REMOVED = 'CORNERSTONE_IMAGE_CACHE_IMAGE_REMOVED',\n /**\n * Triggers on the eventTarget when a volume is added to the volume cache\n *\n * Make use of {@link EventTypes.VolumeCacheVolumeAddedEvent | VolumeCacheAdded Event Type } for typing your event listeners for VOLUME_CACHE_ADDED event,\n * and see what event detail is included in {@link EventTypes.VolumeCacheVolumeAddedEventDetail | VolumeCacheAdded Event Detail }\n */\n VOLUME_CACHE_VOLUME_ADDED = 'CORNERSTONE_VOLUME_CACHE_VOLUME_ADDED',\n /**\n * Triggers on the eventTarget when a volume is removed from the volume cache\n *\n * Make use of {@link EventTypes.VolumeCacheVolumeRemovedEvent | VolumeCacheRemoved Event Type } for typing your event listeners for VOLUME_CACHE_REMOVED event,\n * and see what event detail is included in {@link EventTypes.VolumeCacheVolumeRemovedEventDetail | VolumeCacheRemoved Event Detail }\n */\n VOLUME_CACHE_VOLUME_REMOVED = 'CORNERSTONE_VOLUME_CACHE_VOLUME_REMOVED',\n /**\n * Triggers on the element when a new image is set on the stackViewport\n *\n * Make use of {@link EventTypes.StackNewImageEvent | StackNewImage Event Type } for typing your event listeners for STACK_NEW_IMAGE event,\n * and see what event detail is included in {@link EventTypes.StackNewImageEventDetail | StackNewImage Event Detail }\n */\n STACK_NEW_IMAGE = 'CORNERSTONE_STACK_NEW_IMAGE',\n\n /**\n * Triggers on the element when a new image is set on the volumeViewport, this can be due to scrolling or other\n * tools that change the camera position or focal point.\n *\n * Make use of {@link EventTypes.VolumeNewImageEvent | VolumeNewImage Event Type } for typing your event listeners for VOLUME_NEW_IMAGE event,\n * and see what event detail is included in {@link EventTypes.VolumeNewImageEventDetail | VolumeNewImage Event Detail }\n */\n VOLUME_NEW_IMAGE = 'CORNERSTONE_VOLUME_NEW_IMAGE',\n\n /**\n * Triggers on the element when a new image is about to be set on the stackViewport, pre display\n *\n * Make use of {@link EventTypes.PreStackNewImageEvent | PreStackNewImage Event Type } for typing your event listeners for PRE_STACK_NEW_IMAGE event,\n * and see what event detail is included in {@link EventTypes.PreStackNewImageEventDetail | PreStackNewImage Event Detail }\n */\n PRE_STACK_NEW_IMAGE = 'CORNERSTONE_PRE_STACK_NEW_IMAGE',\n /**\n * Triggers on the element when the viewport's image has calibrated its pixel spacings\n *\n * Make use of {@link EventTypes.ImageSpacingCalibratedEvent | ImageSpacingCalibrated Event Type } for typing your event listeners for IMAGE_SPACING_CALIBRATED event,\n * and see what event detail is included in {@link EventTypes.ImageSpacingCalibratedEventDetail | ImageSpacingCalibrated Event Detail }\n */\n IMAGE_SPACING_CALIBRATED = 'CORNERSTONE_IMAGE_SPACING_CALIBRATED',\n /**\n * Triggers on the eventTarget when there is a progress in the image load process. Note: this event\n * is being used in the Cornerstone-WADO-Image-Loader repository. See {@link https://github.com/cornerstonejs/cornerstoneWADOImageLoader/blob/master/src/imageLoader/internal/xhrRequest.js | here}\n *\n * Make use of {@link EventTypes.ImageLoadProgress | ImageLoadProgress Event Type } for typing your event listeners for IMAGE_LOAD_PROGRESS event,\n * and see what event detail is included in {@link EventTypes.ImageLoadProgressEventDetail | ImageLoadProgress Event Detail }\n */\n IMAGE_LOAD_PROGRESS = 'CORNERSTONE_IMAGE_LOAD_PROGRESS',\n\n /**\n * Triggers on the event target when a new stack is set on its stack viewport.\n * Make use of {@link EventTypes.StackViewportNewStack | StackViewportNewStack Event Type } for typing your event listeners for STACK_VIEWPORT_NEW_STACK event,\n * and see what event detail is included in {@link EventTypes.StackViewportNewStackEventDetail | StackViewportNewStack Event Detail }\n */\n STACK_VIEWPORT_NEW_STACK = 'CORNERSTONE_STACK_VIEWPORT_NEW_STACK',\n\n /**\n * Triggers on the element when the underlying StackViewport is scrolled.\n * Make use of {@link EventTypes.StackViewportScroll | StackViewportScroll Event Type } for typing your event listeners for STACK_VIEWPORT_SCROLL event,\n * and see what event detail is included in {@link EventTypes.StackViewportScrollEventDetail | StackViewportScroll Event Detail }\n */\n STACK_VIEWPORT_SCROLL = 'CORNERSTONE_STACK_VIEWPORT_SCROLL',\n\n // IMAGE_CACHE_FULL = 'CORNERSTONE_IMAGE_CACHE_FULL',\n // PRE_RENDER = 'CORNERSTONE_PRE_RENDER',\n // ELEMENT_RESIZED = 'CORNERSTONE_ELEMENT_RESIZED',\n}\n\nexport default Events;\n","/**\n * Request types for requesting images from the imageLoadPoolManager\n */\nenum RequestType {\n /** Highest priority for loading*/\n Interaction = 'interaction',\n /** Second highest priority for loading*/\n Thumbnail = 'thumbnail',\n /** Lowest priority for loading*/\n Prefetch = 'prefetch',\n}\n\nexport default RequestType;\n","/**\n * ViewportType enum for cornerstone-render which defines the type of viewport.\n * It can be either STACK, PERSPECTIVE, ORTHOGRAPHIC.\n */\nenum ViewportType {\n /**\n * - Suitable for rendering a stack of images, that might or might not belong to the same image.\n * - Stack can include 2D images of different shapes, size and direction\n */\n STACK = 'stack',\n /**\n * - Suitable for rendering a volumetric data which is considered as one 3D image.\n * - Having a VolumeViewport enables Multi-planar reformation or reconstruction (MPR) by design, in which you can visualize the volume from various different orientations without addition of performance costs.\n */\n ORTHOGRAPHIC = 'orthographic',\n /** Perspective Viewport: Not Implemented yet */\n PERSPECTIVE = 'perspective',\n VOLUME_3D = 'volume3d',\n}\n\nexport default ViewportType;\n","/**\n * Interpolation types for image rendering\n */\nenum InterpolationType {\n /** nearest neighbor interpolation */\n NEAREST,\n /** linear interpolation - Default */\n LINEAR,\n /** */\n FAST_LINEAR,\n}\n\nexport default InterpolationType;\n","import vtkConstants from '@kitware/vtk.js/Rendering/Core/VolumeMapper/Constants';\n\nconst { BlendMode } = vtkConstants;\n\n/**\n * Enums for blendModes for viewport images based on vtk.js\n *\n * It should be noted that if crosshairs are enabled and can modify the slab thickness,\n * then it will not show any difference unless MAXIMUM_INTENSITY_BLEND is set on the viewport\n * as the blend.\n */\nenum BlendModes {\n /** composite blending - suitable for compositing multiple images */\n COMPOSITE = BlendMode.COMPOSITE_BLEND,\n /** maximum intensity projection */\n MAXIMUM_INTENSITY_BLEND = BlendMode.MAXIMUM_INTENSITY_BLEND,\n /** minimum intensity projection */\n MINIMUM_INTENSITY_BLEND = BlendMode.MINIMUM_INTENSITY_BLEND,\n /** average intensity projection */\n AVERAGE_INTENSITY_BLEND = BlendMode.AVERAGE_INTENSITY_BLEND,\n}\n\nexport default BlendModes;\n","enum OrientationAxis {\n AXIAL = 'axial',\n CORONAL = 'coronal',\n SAGITTAL = 'sagittal',\n ACQUISITION = 'acquisition',\n}\n\nexport default OrientationAxis;\n","import { CPUFallbackColormapsData } from '../types';\n\n// Colormaps\n//\n// Hot Iron, PET, Hot Metal Blue and PET 20 Step are color palettes\n// Defined by the DICOM standard\n// http://dicom.nema.org/dicom/2013/output/chtml/part06/chapter_B.html\n//\n// All Linear Segmented Colormaps were copied from matplotlib\n// https://github.com/stefanv/matplotlib/blob/master/lib/matplotlib/_cm.py\n\nconst colormapsData: CPUFallbackColormapsData = {\n hotIron: {\n name: 'Hot Iron',\n numOfColors: 256,\n colors: [\n [0, 0, 0, 255],\n [2, 0, 0, 255],\n [4, 0, 0, 255],\n [6, 0, 0, 255],\n [8, 0, 0, 255],\n [10, 0, 0, 255],\n [12, 0, 0, 255],\n [14, 0, 0, 255],\n [16, 0, 0, 255],\n [18, 0, 0, 255],\n [20, 0, 0, 255],\n [22, 0, 0, 255],\n [24, 0, 0, 255],\n [26, 0, 0, 255],\n [28, 0, 0, 255],\n [30, 0, 0, 255],\n [32, 0, 0, 255],\n [34, 0, 0, 255],\n [36, 0, 0, 255],\n [38, 0, 0, 255],\n [40, 0, 0, 255],\n [42, 0, 0, 255],\n [44, 0, 0, 255],\n [46, 0, 0, 255],\n [48, 0, 0, 255],\n [50, 0, 0, 255],\n [52, 0, 0, 255],\n [54, 0, 0, 255],\n [56, 0, 0, 255],\n [58, 0, 0, 255],\n [60, 0, 0, 255],\n [62, 0, 0, 255],\n [64, 0, 0, 255],\n [66, 0, 0, 255],\n [68, 0, 0, 255],\n [70, 0, 0, 255],\n [72, 0, 0, 255],\n [74, 0, 0, 255],\n [76, 0, 0, 255],\n [78, 0, 0, 255],\n [80, 0, 0, 255],\n [82, 0, 0, 255],\n [84, 0, 0, 255],\n [86, 0, 0, 255],\n [88, 0, 0, 255],\n [90, 0, 0, 255],\n [92, 0, 0, 255],\n [94, 0, 0, 255],\n [96, 0, 0, 255],\n [98, 0, 0, 255],\n [100, 0, 0, 255],\n [102, 0, 0, 255],\n [104, 0, 0, 255],\n [106, 0, 0, 255],\n [108, 0, 0, 255],\n [110, 0, 0, 255],\n [112, 0, 0, 255],\n [114, 0, 0, 255],\n [116, 0, 0, 255],\n [118, 0, 0, 255],\n [120, 0, 0, 255],\n [122, 0, 0, 255],\n [124, 0, 0, 255],\n [126, 0, 0, 255],\n [128, 0, 0, 255],\n [130, 0, 0, 255],\n [132, 0, 0, 255],\n [134, 0, 0, 255],\n [136, 0, 0, 255],\n [138, 0, 0, 255],\n [140, 0, 0, 255],\n [142, 0, 0, 255],\n [144, 0, 0, 255],\n [146, 0, 0, 255],\n [148, 0, 0, 255],\n [150, 0, 0, 255],\n [152, 0, 0, 255],\n [154, 0, 0, 255],\n [156, 0, 0, 255],\n [158, 0, 0, 255],\n [160, 0, 0, 255],\n [162, 0, 0, 255],\n [164, 0, 0, 255],\n [166, 0, 0, 255],\n [168, 0, 0, 255],\n [170, 0, 0, 255],\n [172, 0, 0, 255],\n [174, 0, 0, 255],\n [176, 0, 0, 255],\n [178, 0, 0, 255],\n [180, 0, 0, 255],\n [182, 0, 0, 255],\n [184, 0, 0, 255],\n [186, 0, 0, 255],\n [188, 0, 0, 255],\n [190, 0, 0, 255],\n [192, 0, 0, 255],\n [194, 0, 0, 255],\n [196, 0, 0, 255],\n [198, 0, 0, 255],\n [200, 0, 0, 255],\n [202, 0, 0, 255],\n [204, 0, 0, 255],\n [206, 0, 0, 255],\n [208, 0, 0, 255],\n [210, 0, 0, 255],\n [212, 0, 0, 255],\n [214, 0, 0, 255],\n [216, 0, 0, 255],\n [218, 0, 0, 255],\n [220, 0, 0, 255],\n [222, 0, 0, 255],\n [224, 0, 0, 255],\n [226, 0, 0, 255],\n [228, 0, 0, 255],\n [230, 0, 0, 255],\n [232, 0, 0, 255],\n [234, 0, 0, 255],\n [236, 0, 0, 255],\n [238, 0, 0, 255],\n [240, 0, 0, 255],\n [242, 0, 0, 255],\n [244, 0, 0, 255],\n [246, 0, 0, 255],\n [248, 0, 0, 255],\n [250, 0, 0, 255],\n [252, 0, 0, 255],\n [254, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 2, 0, 255],\n [255, 4, 0, 255],\n [255, 6, 0, 255],\n [255, 8, 0, 255],\n [255, 10, 0, 255],\n [255, 12, 0, 255],\n [255, 14, 0, 255],\n [255, 16, 0, 255],\n [255, 18, 0, 255],\n [255, 20, 0, 255],\n [255, 22, 0, 255],\n [255, 24, 0, 255],\n [255, 26, 0, 255],\n [255, 28, 0, 255],\n [255, 30, 0, 255],\n [255, 32, 0, 255],\n [255, 34, 0, 255],\n [255, 36, 0, 255],\n [255, 38, 0, 255],\n [255, 40, 0, 255],\n [255, 42, 0, 255],\n [255, 44, 0, 255],\n [255, 46, 0, 255],\n [255, 48, 0, 255],\n [255, 50, 0, 255],\n [255, 52, 0, 255],\n [255, 54, 0, 255],\n [255, 56, 0, 255],\n [255, 58, 0, 255],\n [255, 60, 0, 255],\n [255, 62, 0, 255],\n [255, 64, 0, 255],\n [255, 66, 0, 255],\n [255, 68, 0, 255],\n [255, 70, 0, 255],\n [255, 72, 0, 255],\n [255, 74, 0, 255],\n [255, 76, 0, 255],\n [255, 78, 0, 255],\n [255, 80, 0, 255],\n [255, 82, 0, 255],\n [255, 84, 0, 255],\n [255, 86, 0, 255],\n [255, 88, 0, 255],\n [255, 90, 0, 255],\n [255, 92, 0, 255],\n [255, 94, 0, 255],\n [255, 96, 0, 255],\n [255, 98, 0, 255],\n [255, 100, 0, 255],\n [255, 102, 0, 255],\n [255, 104, 0, 255],\n [255, 106, 0, 255],\n [255, 108, 0, 255],\n [255, 110, 0, 255],\n [255, 112, 0, 255],\n [255, 114, 0, 255],\n [255, 116, 0, 255],\n [255, 118, 0, 255],\n [255, 120, 0, 255],\n [255, 122, 0, 255],\n [255, 124, 0, 255],\n [255, 126, 0, 255],\n [255, 128, 4, 255],\n [255, 130, 8, 255],\n [255, 132, 12, 255],\n [255, 134, 16, 255],\n [255, 136, 20, 255],\n [255, 138, 24, 255],\n [255, 140, 28, 255],\n [255, 142, 32, 255],\n [255, 144, 36, 255],\n [255, 146, 40, 255],\n [255, 148, 44, 255],\n [255, 150, 48, 255],\n [255, 152, 52, 255],\n [255, 154, 56, 255],\n [255, 156, 60, 255],\n [255, 158, 64, 255],\n [255, 160, 68, 255],\n [255, 162, 72, 255],\n [255, 164, 76, 255],\n [255, 166, 80, 255],\n [255, 168, 84, 255],\n [255, 170, 88, 255],\n [255, 172, 92, 255],\n [255, 174, 96, 255],\n [255, 176, 100, 255],\n [255, 178, 104, 255],\n [255, 180, 108, 255],\n [255, 182, 112, 255],\n [255, 184, 116, 255],\n [255, 186, 120, 255],\n [255, 188, 124, 255],\n [255, 190, 128, 255],\n [255, 192, 132, 255],\n [255, 194, 136, 255],\n [255, 196, 140, 255],\n [255, 198, 144, 255],\n [255, 200, 148, 255],\n [255, 202, 152, 255],\n [255, 204, 156, 255],\n [255, 206, 160, 255],\n [255, 208, 164, 255],\n [255, 210, 168, 255],\n [255, 212, 172, 255],\n [255, 214, 176, 255],\n [255, 216, 180, 255],\n [255, 218, 184, 255],\n [255, 220, 188, 255],\n [255, 222, 192, 255],\n [255, 224, 196, 255],\n [255, 226, 200, 255],\n [255, 228, 204, 255],\n [255, 230, 208, 255],\n [255, 232, 212, 255],\n [255, 234, 216, 255],\n [255, 236, 220, 255],\n [255, 238, 224, 255],\n [255, 240, 228, 255],\n [255, 242, 232, 255],\n [255, 244, 236, 255],\n [255, 246, 240, 255],\n [255, 248, 244, 255],\n [255, 250, 248, 255],\n [255, 252, 252, 255],\n [255, 255, 255, 255],\n ],\n },\n pet: {\n name: 'PET',\n numColors: 256,\n colors: [\n [0, 0, 0, 255],\n [0, 2, 1, 255],\n [0, 4, 3, 255],\n [0, 6, 5, 255],\n [0, 8, 7, 255],\n [0, 10, 9, 255],\n [0, 12, 11, 255],\n [0, 14, 13, 255],\n [0, 16, 15, 255],\n [0, 18, 17, 255],\n [0, 20, 19, 255],\n [0, 22, 21, 255],\n [0, 24, 23, 255],\n [0, 26, 25, 255],\n [0, 28, 27, 255],\n [0, 30, 29, 255],\n [0, 32, 31, 255],\n [0, 34, 33, 255],\n [0, 36, 35, 255],\n [0, 38, 37, 255],\n [0, 40, 39, 255],\n [0, 42, 41, 255],\n [0, 44, 43, 255],\n [0, 46, 45, 255],\n [0, 48, 47, 255],\n [0, 50, 49, 255],\n [0, 52, 51, 255],\n [0, 54, 53, 255],\n [0, 56, 55, 255],\n [0, 58, 57, 255],\n [0, 60, 59, 255],\n [0, 62, 61, 255],\n [0, 65, 63, 255],\n [0, 67, 65, 255],\n [0, 69, 67, 255],\n [0, 71, 69, 255],\n [0, 73, 71, 255],\n [0, 75, 73, 255],\n [0, 77, 75, 255],\n [0, 79, 77, 255],\n [0, 81, 79, 255],\n [0, 83, 81, 255],\n [0, 85, 83, 255],\n [0, 87, 85, 255],\n [0, 89, 87, 255],\n [0, 91, 89, 255],\n [0, 93, 91, 255],\n [0, 95, 93, 255],\n [0, 97, 95, 255],\n [0, 99, 97, 255],\n [0, 101, 99, 255],\n [0, 103, 101, 255],\n [0, 105, 103, 255],\n [0, 107, 105, 255],\n [0, 109, 107, 255],\n [0, 111, 109, 255],\n [0, 113, 111, 255],\n [0, 115, 113, 255],\n [0, 117, 115, 255],\n [0, 119, 117, 255],\n [0, 121, 119, 255],\n [0, 123, 121, 255],\n [0, 125, 123, 255],\n [0, 128, 125, 255],\n [1, 126, 127, 255],\n [3, 124, 129, 255],\n [5, 122, 131, 255],\n [7, 120, 133, 255],\n [9, 118, 135, 255],\n [11, 116, 137, 255],\n [13, 114, 139, 255],\n [15, 112, 141, 255],\n [17, 110, 143, 255],\n [19, 108, 145, 255],\n [21, 106, 147, 255],\n [23, 104, 149, 255],\n [25, 102, 151, 255],\n [27, 100, 153, 255],\n [29, 98, 155, 255],\n [31, 96, 157, 255],\n [33, 94, 159, 255],\n [35, 92, 161, 255],\n [37, 90, 163, 255],\n [39, 88, 165, 255],\n [41, 86, 167, 255],\n [43, 84, 169, 255],\n [45, 82, 171, 255],\n [47, 80, 173, 255],\n [49, 78, 175, 255],\n [51, 76, 177, 255],\n [53, 74, 179, 255],\n [55, 72, 181, 255],\n [57, 70, 183, 255],\n [59, 68, 185, 255],\n [61, 66, 187, 255],\n [63, 64, 189, 255],\n [65, 63, 191, 255],\n [67, 61, 193, 255],\n [69, 59, 195, 255],\n [71, 57, 197, 255],\n [73, 55, 199, 255],\n [75, 53, 201, 255],\n [77, 51, 203, 255],\n [79, 49, 205, 255],\n [81, 47, 207, 255],\n [83, 45, 209, 255],\n [85, 43, 211, 255],\n [86, 41, 213, 255],\n [88, 39, 215, 255],\n [90, 37, 217, 255],\n [92, 35, 219, 255],\n [94, 33, 221, 255],\n [96, 31, 223, 255],\n [98, 29, 225, 255],\n [100, 27, 227, 255],\n [102, 25, 229, 255],\n [104, 23, 231, 255],\n [106, 21, 233, 255],\n [108, 19, 235, 255],\n [110, 17, 237, 255],\n [112, 15, 239, 255],\n [114, 13, 241, 255],\n [116, 11, 243, 255],\n [118, 9, 245, 255],\n [120, 7, 247, 255],\n [122, 5, 249, 255],\n [124, 3, 251, 255],\n [126, 1, 253, 255],\n [128, 0, 255, 255],\n [130, 2, 252, 255],\n [132, 4, 248, 255],\n [134, 6, 244, 255],\n [136, 8, 240, 255],\n [138, 10, 236, 255],\n [140, 12, 232, 255],\n [142, 14, 228, 255],\n [144, 16, 224, 255],\n [146, 18, 220, 255],\n [148, 20, 216, 255],\n [150, 22, 212, 255],\n [152, 24, 208, 255],\n [154, 26, 204, 255],\n [156, 28, 200, 255],\n [158, 30, 196, 255],\n [160, 32, 192, 255],\n [162, 34, 188, 255],\n [164, 36, 184, 255],\n [166, 38, 180, 255],\n [168, 40, 176, 255],\n [170, 42, 172, 255],\n [171, 44, 168, 255],\n [173, 46, 164, 255],\n [175, 48, 160, 255],\n [177, 50, 156, 255],\n [179, 52, 152, 255],\n [181, 54, 148, 255],\n [183, 56, 144, 255],\n [185, 58, 140, 255],\n [187, 60, 136, 255],\n [189, 62, 132, 255],\n [191, 64, 128, 255],\n [193, 66, 124, 255],\n [195, 68, 120, 255],\n [197, 70, 116, 255],\n [199, 72, 112, 255],\n [201, 74, 108, 255],\n [203, 76, 104, 255],\n [205, 78, 100, 255],\n [207, 80, 96, 255],\n [209, 82, 92, 255],\n [211, 84, 88, 255],\n [213, 86, 84, 255],\n [215, 88, 80, 255],\n [217, 90, 76, 255],\n [219, 92, 72, 255],\n [221, 94, 68, 255],\n [223, 96, 64, 255],\n [225, 98, 60, 255],\n [227, 100, 56, 255],\n [229, 102, 52, 255],\n [231, 104, 48, 255],\n [233, 106, 44, 255],\n [235, 108, 40, 255],\n [237, 110, 36, 255],\n [239, 112, 32, 255],\n [241, 114, 28, 255],\n [243, 116, 24, 255],\n [245, 118, 20, 255],\n [247, 120, 16, 255],\n [249, 122, 12, 255],\n [251, 124, 8, 255],\n [253, 126, 4, 255],\n [255, 128, 0, 255],\n [255, 130, 4, 255],\n [255, 132, 8, 255],\n [255, 134, 12, 255],\n [255, 136, 16, 255],\n [255, 138, 20, 255],\n [255, 140, 24, 255],\n [255, 142, 28, 255],\n [255, 144, 32, 255],\n [255, 146, 36, 255],\n [255, 148, 40, 255],\n [255, 150, 44, 255],\n [255, 152, 48, 255],\n [255, 154, 52, 255],\n [255, 156, 56, 255],\n [255, 158, 60, 255],\n [255, 160, 64, 255],\n [255, 162, 68, 255],\n [255, 164, 72, 255],\n [255, 166, 76, 255],\n [255, 168, 80, 255],\n [255, 170, 85, 255],\n [255, 172, 89, 255],\n [255, 174, 93, 255],\n [255, 176, 97, 255],\n [255, 178, 101, 255],\n [255, 180, 105, 255],\n [255, 182, 109, 255],\n [255, 184, 113, 255],\n [255, 186, 117, 255],\n [255, 188, 121, 255],\n [255, 190, 125, 255],\n [255, 192, 129, 255],\n [255, 194, 133, 255],\n [255, 196, 137, 255],\n [255, 198, 141, 255],\n [255, 200, 145, 255],\n [255, 202, 149, 255],\n [255, 204, 153, 255],\n [255, 206, 157, 255],\n [255, 208, 161, 255],\n [255, 210, 165, 255],\n [255, 212, 170, 255],\n [255, 214, 174, 255],\n [255, 216, 178, 255],\n [255, 218, 182, 255],\n [255, 220, 186, 255],\n [255, 222, 190, 255],\n [255, 224, 194, 255],\n [255, 226, 198, 255],\n [255, 228, 202, 255],\n [255, 230, 206, 255],\n [255, 232, 210, 255],\n [255, 234, 214, 255],\n [255, 236, 218, 255],\n [255, 238, 222, 255],\n [255, 240, 226, 255],\n [255, 242, 230, 255],\n [255, 244, 234, 255],\n [255, 246, 238, 255],\n [255, 248, 242, 255],\n [255, 250, 246, 255],\n [255, 252, 250, 255],\n [255, 255, 255, 255],\n ],\n },\n hotMetalBlue: {\n name: 'Hot Metal Blue',\n numColors: 256,\n colors: [\n [0, 0, 0, 255],\n [0, 0, 2, 255],\n [0, 0, 4, 255],\n [0, 0, 6, 255],\n [0, 0, 8, 255],\n [0, 0, 10, 255],\n [0, 0, 12, 255],\n [0, 0, 14, 255],\n [0, 0, 16, 255],\n [0, 0, 17, 255],\n [0, 0, 19, 255],\n [0, 0, 21, 255],\n [0, 0, 23, 255],\n [0, 0, 25, 255],\n [0, 0, 27, 255],\n [0, 0, 29, 255],\n [0, 0, 31, 255],\n [0, 0, 33, 255],\n [0, 0, 35, 255],\n [0, 0, 37, 255],\n [0, 0, 39, 255],\n [0, 0, 41, 255],\n [0, 0, 43, 255],\n [0, 0, 45, 255],\n [0, 0, 47, 255],\n [0, 0, 49, 255],\n [0, 0, 51, 255],\n [0, 0, 53, 255],\n [0, 0, 55, 255],\n [0, 0, 57, 255],\n [0, 0, 59, 255],\n [0, 0, 61, 255],\n [0, 0, 63, 255],\n [0, 0, 65, 255],\n [0, 0, 67, 255],\n [0, 0, 69, 255],\n [0, 0, 71, 255],\n [0, 0, 73, 255],\n [0, 0, 75, 255],\n [0, 0, 77, 255],\n [0, 0, 79, 255],\n [0, 0, 81, 255],\n [0, 0, 83, 255],\n [0, 0, 84, 255],\n [0, 0, 86, 255],\n [0, 0, 88, 255],\n [0, 0, 90, 255],\n [0, 0, 92, 255],\n [0, 0, 94, 255],\n [0, 0, 96, 255],\n [0, 0, 98, 255],\n [0, 0, 100, 255],\n [0, 0, 102, 255],\n [0, 0, 104, 255],\n [0, 0, 106, 255],\n [0, 0, 108, 255],\n [0, 0, 110, 255],\n [0, 0, 112, 255],\n [0, 0, 114, 255],\n [0, 0, 116, 255],\n [0, 0, 117, 255],\n [0, 0, 119, 255],\n [0, 0, 121, 255],\n [0, 0, 123, 255],\n [0, 0, 125, 255],\n [0, 0, 127, 255],\n [0, 0, 129, 255],\n [0, 0, 131, 255],\n [0, 0, 133, 255],\n [0, 0, 135, 255],\n [0, 0, 137, 255],\n [0, 0, 139, 255],\n [0, 0, 141, 255],\n [0, 0, 143, 255],\n [0, 0, 145, 255],\n [0, 0, 147, 255],\n [0, 0, 149, 255],\n [0, 0, 151, 255],\n [0, 0, 153, 255],\n [0, 0, 155, 255],\n [0, 0, 157, 255],\n [0, 0, 159, 255],\n [0, 0, 161, 255],\n [0, 0, 163, 255],\n [0, 0, 165, 255],\n [0, 0, 167, 255],\n [3, 0, 169, 255],\n [6, 0, 171, 255],\n [9, 0, 173, 255],\n [12, 0, 175, 255],\n [15, 0, 177, 255],\n [18, 0, 179, 255],\n [21, 0, 181, 255],\n [24, 0, 183, 255],\n [26, 0, 184, 255],\n [29, 0, 186, 255],\n [32, 0, 188, 255],\n [35, 0, 190, 255],\n [38, 0, 192, 255],\n [41, 0, 194, 255],\n [44, 0, 196, 255],\n [47, 0, 198, 255],\n [50, 0, 200, 255],\n [52, 0, 197, 255],\n [55, 0, 194, 255],\n [57, 0, 191, 255],\n [59, 0, 188, 255],\n [62, 0, 185, 255],\n [64, 0, 182, 255],\n [66, 0, 179, 255],\n [69, 0, 176, 255],\n [71, 0, 174, 255],\n [74, 0, 171, 255],\n [76, 0, 168, 255],\n [78, 0, 165, 255],\n [81, 0, 162, 255],\n [83, 0, 159, 255],\n [85, 0, 156, 255],\n [88, 0, 153, 255],\n [90, 0, 150, 255],\n [93, 2, 144, 255],\n [96, 4, 138, 255],\n [99, 6, 132, 255],\n [102, 8, 126, 255],\n [105, 9, 121, 255],\n [108, 11, 115, 255],\n [111, 13, 109, 255],\n [114, 15, 103, 255],\n [116, 17, 97, 255],\n [119, 19, 91, 255],\n [122, 21, 85, 255],\n [125, 23, 79, 255],\n [128, 24, 74, 255],\n [131, 26, 68, 255],\n [134, 28, 62, 255],\n [137, 30, 56, 255],\n [140, 32, 50, 255],\n [143, 34, 47, 255],\n [146, 36, 44, 255],\n [149, 38, 41, 255],\n [152, 40, 38, 255],\n [155, 41, 35, 255],\n [158, 43, 32, 255],\n [161, 45, 29, 255],\n [164, 47, 26, 255],\n [166, 49, 24, 255],\n [169, 51, 21, 255],\n [172, 53, 18, 255],\n [175, 55, 15, 255],\n [178, 56, 12, 255],\n [181, 58, 9, 255],\n [184, 60, 6, 255],\n [187, 62, 3, 255],\n [190, 64, 0, 255],\n [194, 66, 0, 255],\n [198, 68, 0, 255],\n [201, 70, 0, 255],\n [205, 72, 0, 255],\n [209, 73, 0, 255],\n [213, 75, 0, 255],\n [217, 77, 0, 255],\n [221, 79, 0, 255],\n [224, 81, 0, 255],\n [228, 83, 0, 255],\n [232, 85, 0, 255],\n [236, 87, 0, 255],\n [240, 88, 0, 255],\n [244, 90, 0, 255],\n [247, 92, 0, 255],\n [251, 94, 0, 255],\n [255, 96, 0, 255],\n [255, 98, 3, 255],\n [255, 100, 6, 255],\n [255, 102, 9, 255],\n [255, 104, 12, 255],\n [255, 105, 15, 255],\n [255, 107, 18, 255],\n [255, 109, 21, 255],\n [255, 111, 24, 255],\n [255, 113, 26, 255],\n [255, 115, 29, 255],\n [255, 117, 32, 255],\n [255, 119, 35, 255],\n [255, 120, 38, 255],\n [255, 122, 41, 255],\n [255, 124, 44, 255],\n [255, 126, 47, 255],\n [255, 128, 50, 255],\n [255, 130, 53, 255],\n [255, 132, 56, 255],\n [255, 134, 59, 255],\n [255, 136, 62, 255],\n [255, 137, 65, 255],\n [255, 139, 68, 255],\n [255, 141, 71, 255],\n [255, 143, 74, 255],\n [255, 145, 76, 255],\n [255, 147, 79, 255],\n [255, 149, 82, 255],\n [255, 151, 85, 255],\n [255, 152, 88, 255],\n [255, 154, 91, 255],\n [255, 156, 94, 255],\n [255, 158, 97, 255],\n [255, 160, 100, 255],\n [255, 162, 103, 255],\n [255, 164, 106, 255],\n [255, 166, 109, 255],\n [255, 168, 112, 255],\n [255, 169, 115, 255],\n [255, 171, 118, 255],\n [255, 173, 121, 255],\n [255, 175, 124, 255],\n [255, 177, 126, 255],\n [255, 179, 129, 255],\n [255, 181, 132, 255],\n [255, 183, 135, 255],\n [255, 184, 138, 255],\n [255, 186, 141, 255],\n [255, 188, 144, 255],\n [255, 190, 147, 255],\n [255, 192, 150, 255],\n [255, 194, 153, 255],\n [255, 196, 156, 255],\n [255, 198, 159, 255],\n [255, 200, 162, 255],\n [255, 201, 165, 255],\n [255, 203, 168, 255],\n [255, 205, 171, 255],\n [255, 207, 174, 255],\n [255, 209, 176, 255],\n [255, 211, 179, 255],\n [255, 213, 182, 255],\n [255, 215, 185, 255],\n [255, 216, 188, 255],\n [255, 218, 191, 255],\n [255, 220, 194, 255],\n [255, 222, 197, 255],\n [255, 224, 200, 255],\n [255, 226, 203, 255],\n [255, 228, 206, 255],\n [255, 229, 210, 255],\n [255, 231, 213, 255],\n [255, 233, 216, 255],\n [255, 235, 219, 255],\n [255, 237, 223, 255],\n [255, 239, 226, 255],\n [255, 240, 229, 255],\n [255, 242, 232, 255],\n [255, 244, 236, 255],\n [255, 246, 239, 255],\n [255, 248, 242, 255],\n [255, 250, 245, 255],\n [255, 251, 249, 255],\n [255, 253, 252, 255],\n [255, 255, 255, 255],\n ],\n },\n pet20Step: {\n name: 'PET 20 Step',\n numColors: 256,\n colors: [\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n ],\n },\n gray: {\n name: 'Gray',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0, 0],\n [1, 1, 1],\n ],\n green: [\n [0, 0, 0],\n [1, 1, 1],\n ],\n blue: [\n [0, 0, 0],\n [1, 1, 1],\n ],\n },\n },\n jet: {\n name: 'Jet',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0, 0],\n [0.35, 0, 0],\n [0.66, 1, 1],\n [0.89, 1, 1],\n [1, 0.5, 0.5],\n ],\n green: [\n [0, 0, 0],\n [0.125, 0, 0],\n [0.375, 1, 1],\n [0.64, 1, 1],\n [0.91, 0, 0],\n [1, 0, 0],\n ],\n blue: [\n [0, 0.5, 0.5],\n [0.11, 1, 1],\n [0.34, 1, 1],\n [0.65, 0, 0],\n [1, 0, 0],\n ],\n },\n },\n hsv: {\n name: 'HSV',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 1, 1],\n [0.15873, 1, 1],\n [0.174603, 0.96875, 0.96875],\n [0.333333, 0.03125, 0.03125],\n [0.349206, 0, 0],\n [0.666667, 0, 0],\n [0.68254, 0.03125, 0.03125],\n [0.84127, 0.96875, 0.96875],\n [0.857143, 1, 1],\n [1, 1, 1],\n ],\n green: [\n [0, 0, 0],\n [0.15873, 0.9375, 0.9375],\n [0.174603, 1, 1],\n [0.507937, 1, 1],\n [0.666667, 0.0625, 0.0625],\n [0.68254, 0, 0],\n [1, 0, 0],\n ],\n blue: [\n [0, 0, 0],\n [0.333333, 0, 0],\n [0.349206, 0.0625, 0.0625],\n [0.507937, 1, 1],\n [0.84127, 1, 1],\n [0.857143, 0.9375, 0.9375],\n [1, 0.09375, 0.09375],\n ],\n },\n },\n hot: {\n name: 'Hot',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0.0416, 0.0416],\n [0.365079, 1, 1],\n [1, 1, 1],\n ],\n green: [\n [0, 0, 0],\n [0.365079, 0, 0],\n [0.746032, 1, 1],\n [1, 1, 1],\n ],\n blue: [\n [0, 0, 0],\n [0.746032, 0, 0],\n [1, 1, 1],\n ],\n },\n },\n cool: {\n name: 'Cool',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0, 0],\n [1, 1, 1],\n ],\n green: [\n [0, 1, 1],\n [1, 0, 0],\n ],\n blue: [\n [0, 1, 1],\n [1, 1, 1],\n ],\n },\n },\n spring: {\n name: 'Spring',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 1, 1],\n [1, 1, 1],\n ],\n green: [\n [0, 0, 0],\n [1, 1, 1],\n ],\n blue: [\n [0, 1, 1],\n [1, 0, 0],\n ],\n },\n },\n summer: {\n name: 'Summer',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0, 0],\n [1, 1, 1],\n ],\n green: [\n [0, 0.5, 0.5],\n [1, 1, 1],\n ],\n blue: [\n [0, 0.4, 0.4],\n [1, 0.4, 0.4],\n ],\n },\n },\n autumn: {\n name: 'Autumn',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 1, 1],\n [1, 1, 1],\n ],\n green: [\n [0, 0, 0],\n [1, 1, 1],\n ],\n blue: [\n [0, 0, 0],\n [1, 0, 0],\n ],\n },\n },\n winter: {\n name: 'Winter',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0, 0],\n [1, 0, 0],\n ],\n green: [\n [0, 0, 0],\n [1, 1, 1],\n ],\n blue: [\n [0, 1, 1],\n [1, 0.5, 0.5],\n ],\n },\n },\n bone: {\n name: 'Bone',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0, 0],\n [0.746032, 0.652778, 0.652778],\n [1, 1, 1],\n ],\n green: [\n [0, 0, 0],\n [0.365079, 0.319444, 0.319444],\n [0.746032, 0.777778, 0.777778],\n [1, 1, 1],\n ],\n blue: [\n [0, 0, 0],\n [0.365079, 0.444444, 0.444444],\n [1, 1, 1],\n ],\n },\n },\n copper: {\n name: 'Copper',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0, 0],\n [0.809524, 1, 1],\n [1, 1, 1],\n ],\n green: [\n [0, 0, 0],\n [1, 0.7812, 0.7812],\n ],\n blue: [\n [0, 0, 0],\n [1, 0.4975, 0.4975],\n ],\n },\n },\n spectral: {\n name: 'Spectral',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0, 0],\n [0.05, 0.4667, 0.4667],\n [0.1, 0.5333, 0.5333],\n [0.15, 0, 0],\n [0.2, 0, 0],\n [0.25, 0, 0],\n [0.3, 0, 0],\n [0.35, 0, 0],\n [0.4, 0, 0],\n [0.45, 0, 0],\n [0.5, 0, 0],\n [0.55, 0, 0],\n [0.6, 0, 0],\n [0.65, 0.7333, 0.7333],\n [0.7, 0.9333, 0.9333],\n [0.75, 1, 1],\n [0.8, 1, 1],\n [0.85, 1, 1],\n [0.9, 0.8667, 0.8667],\n [0.95, 0.8, 0.8],\n [1, 0.8, 0.8],\n ],\n green: [\n [0, 0, 0],\n [0.05, 0, 0],\n [0.1, 0, 0],\n [0.15, 0, 0],\n [0.2, 0, 0],\n [0.25, 0.4667, 0.4667],\n [0.3, 0.6, 0.6],\n [0.35, 0.6667, 0.6667],\n [0.4, 0.6667, 0.6667],\n [0.45, 0.6, 0.6],\n [0.5, 0.7333, 0.7333],\n [0.55, 0.8667, 0.8667],\n [0.6, 1, 1],\n [0.65, 1, 1],\n [0.7, 0.9333, 0.9333],\n [0.75, 0.8, 0.8],\n [0.8, 0.6, 0.6],\n [0.85, 0, 0],\n [0.9, 0, 0],\n [0.95, 0, 0],\n [1, 0.8, 0.8],\n ],\n blue: [\n [0, 0, 0],\n [0.05, 0.5333, 0.5333],\n [0.1, 0.6, 0.6],\n [0.15, 0.6667, 0.6667],\n [0.2, 0.8667, 0.8667],\n [0.25, 0.8667, 0.8667],\n [0.3, 0.8667, 0.8667],\n [0.35, 0.6667, 0.6667],\n [0.4, 0.5333, 0.5333],\n [0.45, 0, 0],\n [0.5, 0, 0],\n [0.55, 0, 0],\n [0.6, 0, 0],\n [0.65, 0, 0],\n [0.7, 0, 0],\n [0.75, 0, 0],\n [0.8, 0, 0],\n [0.85, 0, 0],\n [0.9, 0, 0],\n [0.95, 0, 0],\n [1, 0.8, 0.8],\n ],\n },\n },\n coolwarm: {\n name: 'CoolWarm',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0.2298057, 0.2298057],\n [0.03125, 0.26623388, 0.26623388],\n [0.0625, 0.30386891, 0.30386891],\n [0.09375, 0.342804478, 0.342804478],\n [0.125, 0.38301334, 0.38301334],\n [0.15625, 0.424369608, 0.424369608],\n [0.1875, 0.46666708, 0.46666708],\n [0.21875, 0.509635204, 0.509635204],\n [0.25, 0.552953156, 0.552953156],\n [0.28125, 0.596262162, 0.596262162],\n [0.3125, 0.639176211, 0.639176211],\n [0.34375, 0.681291281, 0.681291281],\n [0.375, 0.722193294, 0.722193294],\n [0.40625, 0.761464949, 0.761464949],\n [0.4375, 0.798691636, 0.798691636],\n [0.46875, 0.833466556, 0.833466556],\n [0.5, 0.865395197, 0.865395197],\n [0.53125, 0.897787179, 0.897787179],\n [0.5625, 0.924127593, 0.924127593],\n [0.59375, 0.944468518, 0.944468518],\n [0.625, 0.958852946, 0.958852946],\n [0.65625, 0.96732803, 0.96732803],\n [0.6875, 0.969954137, 0.969954137],\n [0.71875, 0.966811177, 0.966811177],\n [0.75, 0.958003065, 0.958003065],\n [0.78125, 0.943660866, 0.943660866],\n [0.8125, 0.923944917, 0.923944917],\n [0.84375, 0.89904617, 0.89904617],\n [0.875, 0.869186849, 0.869186849],\n [0.90625, 0.834620542, 0.834620542],\n [0.9375, 0.795631745, 0.795631745],\n [0.96875, 0.752534934, 0.752534934],\n [1, 0.705673158, 0.705673158],\n ],\n green: [\n [0, 0.298717966, 0.298717966],\n [0.03125, 0.353094838, 0.353094838],\n [0.0625, 0.406535296, 0.406535296],\n [0.09375, 0.458757618, 0.458757618],\n [0.125, 0.50941904, 0.50941904],\n [0.15625, 0.558148092, 0.558148092],\n [0.1875, 0.604562568, 0.604562568],\n [0.21875, 0.648280772, 0.648280772],\n [0.25, 0.688929332, 0.688929332],\n [0.28125, 0.726149107, 0.726149107],\n [0.3125, 0.759599947, 0.759599947],\n [0.34375, 0.788964712, 0.788964712],\n [0.375, 0.813952739, 0.813952739],\n [0.40625, 0.834302879, 0.834302879],\n [0.4375, 0.849786142, 0.849786142],\n [0.46875, 0.860207984, 0.860207984],\n [0.5, 0.86541021, 0.86541021],\n [0.53125, 0.848937047, 0.848937047],\n [0.5625, 0.827384882, 0.827384882],\n [0.59375, 0.800927443, 0.800927443],\n [0.625, 0.769767752, 0.769767752],\n [0.65625, 0.734132809, 0.734132809],\n [0.6875, 0.694266682, 0.694266682],\n [0.71875, 0.650421156, 0.650421156],\n [0.75, 0.602842431, 0.602842431],\n [0.78125, 0.551750968, 0.551750968],\n [0.8125, 0.49730856, 0.49730856],\n [0.84375, 0.439559467, 0.439559467],\n [0.875, 0.378313092, 0.378313092],\n [0.90625, 0.312874446, 0.312874446],\n [0.9375, 0.24128379, 0.24128379],\n [0.96875, 0.157246067, 0.157246067],\n [1, 0.01555616, 0.01555616],\n ],\n blue: [\n [0, 0.753683153, 0.753683153],\n [0.03125, 0.801466763, 0.801466763],\n [0.0625, 0.84495867, 0.84495867],\n [0.09375, 0.883725899, 0.883725899],\n [0.125, 0.917387822, 0.917387822],\n [0.15625, 0.945619588, 0.945619588],\n [0.1875, 0.968154911, 0.968154911],\n [0.21875, 0.98478814, 0.98478814],\n [0.25, 0.995375608, 0.995375608],\n [0.28125, 0.999836203, 0.999836203],\n [0.3125, 0.998151185, 0.998151185],\n [0.34375, 0.990363227, 0.990363227],\n [0.375, 0.976574709, 0.976574709],\n [0.40625, 0.956945269, 0.956945269],\n [0.4375, 0.931688648, 0.931688648],\n [0.46875, 0.901068838, 0.901068838],\n [0.5, 0.865395561, 0.865395561],\n [0.53125, 0.820880546, 0.820880546],\n [0.5625, 0.774508472, 0.774508472],\n [0.59375, 0.726736146, 0.726736146],\n [0.625, 0.678007945, 0.678007945],\n [0.65625, 0.628751763, 0.628751763],\n [0.6875, 0.579375448, 0.579375448],\n [0.71875, 0.530263762, 0.530263762],\n [0.75, 0.481775914, 0.481775914],\n [0.78125, 0.434243684, 0.434243684],\n [0.8125, 0.387970225, 0.387970225],\n [0.84375, 0.343229596, 0.343229596],\n [0.875, 0.300267182, 0.300267182],\n [0.90625, 0.259301199, 0.259301199],\n [0.9375, 0.220525627, 0.220525627],\n [0.96875, 0.184115123, 0.184115123],\n [1, 0.150232812, 0.150232812],\n ],\n },\n },\n blues: {\n name: 'Blues',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0.9686274528503418, 0.9686274528503418],\n [0.125, 0.87058824300765991, 0.87058824300765991],\n [0.25, 0.7764706015586853, 0.7764706015586853],\n [0.375, 0.61960786581039429, 0.61960786581039429],\n [0.5, 0.41960784792900085, 0.41960784792900085],\n [0.625, 0.25882354378700256, 0.25882354378700256],\n [0.75, 0.12941177189350128, 0.12941177189350128],\n [0.875, 0.031372550874948502, 0.031372550874948502],\n [1, 0.031372550874948502, 0.031372550874948502],\n ],\n green: [\n [0, 0.9843137264251709, 0.9843137264251709],\n [0.125, 0.92156863212585449, 0.92156863212585449],\n [0.25, 0.85882353782653809, 0.85882353782653809],\n [0.375, 0.7921568751335144, 0.7921568751335144],\n [0.5, 0.68235296010971069, 0.68235296010971069],\n [0.625, 0.57254904508590698, 0.57254904508590698],\n [0.75, 0.44313725829124451, 0.44313725829124451],\n [0.875, 0.31764706969261169, 0.31764706969261169],\n [1, 0.18823529779911041, 0.18823529779911041],\n ],\n blue: [\n [0, 1, 1],\n [0.125, 0.9686274528503418, 0.9686274528503418],\n [0.25, 0.93725490570068359, 0.93725490570068359],\n [0.375, 0.88235294818878174, 0.88235294818878174],\n [0.5, 0.83921569585800171, 0.83921569585800171],\n [0.625, 0.7764706015586853, 0.7764706015586853],\n [0.75, 0.70980393886566162, 0.70980393886566162],\n [0.875, 0.61176472902297974, 0.61176472902297974],\n [1, 0.41960784792900085, 0.41960784792900085],\n ],\n },\n },\n};\n\nexport default colormapsData;\n","const RENDERING_DEFAULTS = {\n MINIMUM_SLAB_THICKNESS: 5e-2,\n MAXIMUM_RAY_DISTANCE: 1e6,\n};\n\nObject.freeze(RENDERING_DEFAULTS);\n\nexport default RENDERING_DEFAULTS;\n","const EPSILON = 1e-3;\n\nexport default EPSILON;\n","export default function _typeof(obj) {\n \"@babel/helpers - typeof\";\n\n return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (obj) {\n return typeof obj;\n } : function (obj) {\n return obj && \"function\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n }, _typeof(obj);\n}","// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#examples\nfunction deepFreeze(object) {\n // Retrieve the property names defined on object\n const propNames = Object.getOwnPropertyNames(object);\n\n // Freeze properties before freezing self\n\n for (const name of propNames) {\n const value = object[name];\n\n if (value && typeof value === 'object') {\n deepFreeze(value);\n }\n }\n\n return Object.freeze(object);\n}\n\nexport default deepFreeze;\n","import deepFreeze from '../utilities/deepFreeze';\n\nconst MPR_CAMERA_VALUES = {\n axial: {\n viewPlaneNormal: [0, 0, -1],\n viewUp: [0, -1, 0],\n },\n sagittal: {\n viewPlaneNormal: [1, 0, 0],\n viewUp: [0, 0, 1],\n },\n coronal: {\n viewPlaneNormal: [0, -1, 0],\n viewUp: [0, 0, 1],\n },\n};\n\n// Note: Object.freeze is only shallow, so we need to deepFreeze\nconst mprCameraValues = deepFreeze(MPR_CAMERA_VALUES);\nexport default mprCameraValues;\n","import { ViewportPreset } from '../types';\n\nconst presets: ViewportPreset[] = [\n {\n name: 'CT-AAA',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity:\n '12 -3024 0 143.556 0 166.222 0.686275 214.389 0.696078 419.736 0.833333 3071 0.803922',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer:\n '24 -3024 0 0 0 143.556 0.615686 0.356863 0.184314 166.222 0.882353 0.603922 0.290196 214.389 1 1 1 419.736 1 0.937033 0.954531 3071 0.827451 0.658824 1',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'CT-AAA2',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity:\n '16 -3024 0 129.542 0 145.244 0.166667 157.02 0.5 169.918 0.627451 395.575 0.8125 1578.73 0.8125 3071 0.8125',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer:\n '32 -3024 0 0 0 129.542 0.54902 0.25098 0.14902 145.244 0.6 0.627451 0.843137 157.02 0.890196 0.47451 0.6 169.918 0.992157 0.870588 0.392157 395.575 1 0.886275 0.658824 1578.73 1 0.829256 0.957922 3071 0.827451 0.658824 1',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'CT-Bone',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity: '8 -3024 0 -16.4458 0 641.385 0.715686 3071 0.705882',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer:\n '16 -3024 0 0 0 -16.4458 0.729412 0.254902 0.301961 641.385 0.905882 0.815686 0.552941 3071 1 1 1',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'CT-Bones',\n gradientOpacity: '4 0 1 985.12 1',\n specularPower: '1',\n scalarOpacity: '8 -1000 0 152.19 0 278.93 0.190476 952 0.2',\n specular: '0',\n shade: '1',\n ambient: '0.2',\n colorTransfer:\n '20 -1000 0.3 0.3 1 -488 0.3 1 0.3 463.28 1 0 0 659.15 1 0.912535 0.0374849 953 1 0.3 0.3',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'CT-Cardiac',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity:\n '12 -3024 0 -77.6875 0 94.9518 0.285714 179.052 0.553571 260.439 0.848214 3071 0.875',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer:\n '24 -3024 0 0 0 -77.6875 0.54902 0.25098 0.14902 94.9518 0.882353 0.603922 0.290196 179.052 1 0.937033 0.954531 260.439 0.615686 0 0 3071 0.827451 0.658824 1',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'CT-Cardiac2',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity:\n '12 -3024 0 42.8964 0 163.488 0.428571 277.642 0.776786 1587 0.754902 3071 0.754902',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer:\n '24 -3024 0 0 0 42.8964 0.54902 0.25098 0.14902 163.488 0.917647 0.639216 0.0588235 277.642 1 0.878431 0.623529 1587 1 1 1 3071 0.827451 0.658824 1',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'CT-Cardiac3',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity:\n '14 -3024 0 -86.9767 0 45.3791 0.169643 139.919 0.589286 347.907 0.607143 1224.16 0.607143 3071 0.616071',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer:\n '28 -3024 0 0 0 -86.9767 0 0.25098 1 45.3791 1 0 0 139.919 1 0.894893 0.894893 347.907 1 1 0.25098 1224.16 1 1 1 3071 0.827451 0.658824 1',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'CT-Chest-Contrast-Enhanced',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity:\n '10 -3024 0 67.0106 0 251.105 0.446429 439.291 0.625 3071 0.616071',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer:\n '20 -3024 0 0 0 67.0106 0.54902 0.25098 0.14902 251.105 0.882353 0.603922 0.290196 439.291 1 0.937033 0.954531 3071 0.827451 0.658824 1',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'CT-Chest-Vessels',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '1',\n scalarOpacity:\n '10 -3024 0 -1278.35 0 22.8277 0.428571 439.291 0.625 3071 0.616071',\n specular: '0',\n shade: '1',\n ambient: '0.2',\n colorTransfer:\n '20 -3024 0 0 0 -1278.35 0.54902 0.25098 0.14902 22.8277 0.882353 0.603922 0.290196 439.291 1 0.937033 0.954531 3071 0.827451 0.658824 1',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'CT-Coronary-Arteries',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '1',\n scalarOpacity:\n '12 -2048 0 136.47 0 159.215 0.258929 318.43 0.571429 478.693 0.776786 3661 1',\n specular: '0',\n shade: '0',\n ambient: '0.2',\n colorTransfer:\n '24 -2048 0 0 0 136.47 0 0 0 159.215 0.159804 0.159804 0.159804 318.43 0.764706 0.764706 0.764706 478.693 1 1 1 3661 1 1 1',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'CT-Coronary-Arteries-2',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '1',\n scalarOpacity:\n '14 -2048 0 142.677 0 145.016 0.116071 192.174 0.5625 217.24 0.776786 384.347 0.830357 3661 0.830357',\n specular: '0',\n shade: '1',\n ambient: '0.2',\n colorTransfer:\n '28 -2048 0 0 0 142.677 0 0 0 145.016 0.615686 0 0.0156863 192.174 0.909804 0.454902 0 217.24 0.972549 0.807843 0.611765 384.347 0.909804 0.909804 1 3661 1 1 1',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'CT-Coronary-Arteries-3',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity:\n '14 -2048 0 128.643 0 129.982 0.0982143 173.636 0.669643 255.884 0.857143 584.878 0.866071 3661 1',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer:\n '28 -2048 0 0 0 128.643 0 0 0 129.982 0.615686 0 0.0156863 173.636 0.909804 0.454902 0 255.884 0.886275 0.886275 0.886275 584.878 0.968627 0.968627 0.968627 3661 1 1 1',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'CT-Cropped-Volume-Bone',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '1',\n scalarOpacity: '10 -2048 0 -451 0 -450 1 1050 1 3661 1',\n specular: '0',\n shade: '0',\n ambient: '0.2',\n colorTransfer:\n '20 -2048 0 0 0 -451 0 0 0 -450 0.0556356 0.0556356 0.0556356 1050 1 1 1 3661 1 1 1',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'CT-Fat',\n gradientOpacity: '6 0 1 985.12 1 988 1',\n specularPower: '1',\n scalarOpacity: '14 -1000 0 -100 0 -99 0.15 -60 0.15 -59 0 101.2 0 952 0',\n specular: '0',\n shade: '0',\n ambient: '0.2',\n colorTransfer:\n '36 -1000 0.3 0.3 1 -497.5 0.3 1 0.3 -99 0 0 1 -76.946 0 1 0 -65.481 0.835431 0.888889 0.0165387 83.89 1 0 0 463.28 1 0 0 659.15 1 0.912535 0.0374849 2952 1 0.300267 0.299886',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'CT-Liver-Vasculature',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '1',\n scalarOpacity:\n '14 -2048 0 149.113 0 157.884 0.482143 339.96 0.660714 388.526 0.830357 1197.95 0.839286 3661 0.848214',\n specular: '0',\n shade: '0',\n ambient: '0.2',\n colorTransfer:\n '28 -2048 0 0 0 149.113 0 0 0 157.884 0.501961 0.25098 0 339.96 0.695386 0.59603 0.36886 388.526 0.854902 0.85098 0.827451 1197.95 1 1 1 3661 1 1 1',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'CT-Lung',\n gradientOpacity: '6 0 1 985.12 1 988 1',\n specularPower: '1',\n scalarOpacity: '12 -1000 0 -600 0 -599 0.15 -400 0.15 -399 0 2952 0',\n specular: '0',\n shade: '1',\n ambient: '0.2',\n colorTransfer:\n '24 -1000 0.3 0.3 1 -600 0 0 1 -530 0.134704 0.781726 0.0724558 -460 0.929244 1 0.109473 -400 0.888889 0.254949 0.0240258 2952 1 0.3 0.3',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'CT-MIP',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity: '8 -3024 0 -637.62 0 700 1 3071 1',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer: '16 -3024 0 0 0 -637.62 1 1 1 700 1 1 1 3071 1 1 1',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'CT-Muscle',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity:\n '10 -3024 0 -155.407 0 217.641 0.676471 419.736 0.833333 3071 0.803922',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer:\n '20 -3024 0 0 0 -155.407 0.54902 0.25098 0.14902 217.641 0.882353 0.603922 0.290196 419.736 1 0.937033 0.954531 3071 0.827451 0.658824 1',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'CT-Pulmonary-Arteries',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '1',\n scalarOpacity:\n '14 -2048 0 -568.625 0 -364.081 0.0714286 -244.813 0.401786 18.2775 0.607143 447.798 0.830357 3592.73 0.839286',\n specular: '0',\n shade: '1',\n ambient: '0.2',\n colorTransfer:\n '28 -2048 0 0 0 -568.625 0 0 0 -364.081 0.396078 0.301961 0.180392 -244.813 0.611765 0.352941 0.0705882 18.2775 0.843137 0.0156863 0.156863 447.798 0.752941 0.752941 0.752941 3592.73 1 1 1',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'CT-Soft-Tissue',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '1',\n scalarOpacity: '10 -2048 0 -167.01 0 -160 1 240 1 3661 1',\n specular: '0',\n shade: '0',\n ambient: '0.2',\n colorTransfer:\n '20 -2048 0 0 0 -167.01 0 0 0 -160 0.0556356 0.0556356 0.0556356 240 1 1 1 3661 1 1 1',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'CT-Air',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity: '8 -3024 0.705882 -900.0 0.715686 -500.0 0 3071 0',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer:\n '16 -3024 1 1 1 -900.0 0.2 1.0 1.0 -500.0 0.3 0.3 1.0 3071 0 0 0 ',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'MR-Angio',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '1',\n scalarOpacity:\n '12 -2048 0 151.354 0 158.279 0.4375 190.112 0.580357 200.873 0.732143 3661 0.741071',\n specular: '0',\n shade: '1',\n ambient: '0.2',\n colorTransfer:\n '24 -2048 0 0 0 151.354 0 0 0 158.279 0.74902 0.376471 0 190.112 1 0.866667 0.733333 200.873 0.937255 0.937255 0.937255 3661 1 1 1',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'MR-Default',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '1',\n scalarOpacity: '12 0 0 20 0 40 0.15 120 0.3 220 0.375 1024 0.5',\n specular: '0',\n shade: '1',\n ambient: '0.2',\n colorTransfer:\n '24 0 0 0 0 20 0.168627 0 0 40 0.403922 0.145098 0.0784314 120 0.780392 0.607843 0.380392 220 0.847059 0.835294 0.788235 1024 1 1 1',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'MR-MIP',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '1',\n scalarOpacity: '8 0 0 98.3725 0 416.637 1 2800 1',\n specular: '0',\n shade: '0',\n ambient: '0.2',\n colorTransfer: '16 0 1 1 1 98.3725 1 1 1 416.637 1 1 1 2800 1 1 1',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'MR-T2-Brain',\n gradientOpacity: '4 0 1 160.25 1',\n specularPower: '40',\n scalarOpacity: '10 0 0 36.05 0 218.302 0.171429 412.406 1 641 1',\n specular: '0.5',\n shade: '1',\n ambient: '0.3',\n colorTransfer:\n '16 0 0 0 0 98.7223 0.956863 0.839216 0.192157 412.406 0 0.592157 0.807843 641 1 1 1',\n diffuse: '0.6',\n interpolation: '1',\n },\n {\n name: 'DTI-FA-Brain',\n gradientOpacity: '4 0 1 0.9950 1',\n specularPower: '40',\n scalarOpacity:\n '16 0 0 0 0 0.3501 0.0158 0.49379 0.7619 0.6419 1 0.9920 1 0.9950 0 0.9950 0',\n specular: '0.5',\n shade: '1',\n ambient: '0.3',\n colorTransfer:\n '28 0 1 0 0 0 1 0 0 0.24974 0.4941 1 0 0.49949 0 0.9882 1 0.7492 0.51764 0 1 0.9950 1 0 0 0.9950 1 0 0',\n diffuse: '0.9',\n interpolation: '1',\n },\n];\n\nexport default presets;\n","function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {\n try {\n var info = gen[key](arg);\n var value = info.value;\n } catch (error) {\n reject(error);\n return;\n }\n\n if (info.done) {\n resolve(value);\n } else {\n Promise.resolve(value).then(_next, _throw);\n }\n}\n\nexport default function _asyncToGenerator(fn) {\n return function () {\n var self = this,\n args = arguments;\n return new Promise(function (resolve, reject) {\n var gen = fn.apply(self, args);\n\n function _next(value) {\n asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"next\", value);\n }\n\n function _throw(err) {\n asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"throw\", err);\n }\n\n _next(undefined);\n });\n };\n}","function _defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n}\n\nexport default function _createClass(Constructor, protoProps, staticProps) {\n if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n if (staticProps) _defineProperties(Constructor, staticProps);\n Object.defineProperty(Constructor, \"prototype\", {\n writable: false\n });\n return Constructor;\n}","export default function _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n}","export default function _defineProperty(obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n}","import macro from '@kitware/vtk.js/macros';\nimport vtkOpenGLTexture from '@kitware/vtk.js/Rendering/OpenGL/Texture';\n\n/**\n * vtkStreamingOpenGLTexture - A dervied class of the core vtkOpenGLTexture.\n * This class has methods to update the texture memory on the GPU slice by slice\n * in an efficient yet GPU-architecture friendly manner.\n *\n *\n * @param {*} publicAPI The public API to extend\n * @param {*} model The private model to extend.\n */\nfunction vtkStreamingOpenGLTexture(publicAPI, model) {\n model.classHierarchy.push('vtkStreamingOpenGLTexture');\n\n const superCreate3DFilterableFromRaw = publicAPI.create3DFilterableFromRaw;\n\n publicAPI.create3DFilterableFromRaw = (\n width,\n height,\n depth,\n numComps,\n dataType,\n data\n ) => {\n model.inputDataType = dataType;\n model.inputNumComps = numComps;\n\n superCreate3DFilterableFromRaw(\n width,\n height,\n depth,\n numComps,\n dataType,\n data\n );\n };\n\n /**\n * This function updates the GPU texture memory to match the current\n * representation of data held in RAM.\n *\n * @param {Float32Array|Uint8Array} data The data array which has been updated.\n */\n publicAPI.update3DFromRaw = (data) => {\n const { updatedFrames } = model;\n\n if (!updatedFrames.length) {\n return;\n }\n\n model._openGLRenderWindow.activateTexture(publicAPI);\n publicAPI.createTexture();\n publicAPI.bind();\n\n let bytesPerVoxel;\n let TypedArrayConstructor;\n\n if (data instanceof Uint8Array) {\n bytesPerVoxel = 1;\n TypedArrayConstructor = Uint8Array;\n } else if (data instanceof Int16Array) {\n bytesPerVoxel = 2;\n TypedArrayConstructor = Int16Array;\n } else if (data instanceof Float32Array) {\n bytesPerVoxel = 4;\n TypedArrayConstructor = Float32Array;\n } else {\n throw new Error(`No support for given TypedArray.`);\n }\n\n for (let i = 0; i < updatedFrames.length; i++) {\n if (updatedFrames[i]) {\n model.fillSubImage3D(data, i, bytesPerVoxel, TypedArrayConstructor);\n }\n }\n\n // Reset updatedFrames\n model.updatedFrames = [];\n\n if (model.generateMipmap) {\n model.context.generateMipmap(model.target);\n }\n\n publicAPI.deactivate();\n return true;\n };\n\n /**\n * This function updates the GPU texture memory to match the current\n * representation of data held in RAM.\n *\n * @param {Float32Array|Uint8Array} data The data array which has been updated.\n * @param {number} frameIndex The frame to load in.\n * @param {number} BytesPerVoxel The number of bytes per voxel in the data, so we don't have to constantly\n * check the array type.\n * @param {object} TypedArrayConstructor The constructor for the array type. Again so we don't have to constantly check.\n */\n model.fillSubImage3D = (\n data,\n frameIndex,\n bytesPerVoxel,\n TypedArrayConstructor\n ) => {\n const buffer = data.buffer;\n\n const frameLength = model.width * model.height;\n const frameLengthInBytes = frameLength * model.components * bytesPerVoxel;\n\n const zOffset = frameIndex * frameLengthInBytes;\n const rowLength = model.width * model.components;\n\n const gl = model.context;\n\n /**\n * It appears that the implementation of texSubImage3D uses 2D textures to do the texture copy if\n * MAX_TEXTURE_SIZE is greater than MAX_TEXTURE_SIZE_3D. As such if you make a single block too big\n * the transfer messes up cleanly and you render a black box or some data if you are lucky.\n *\n * This block-size based on 2D texture size seems like the safest approach that should work on most systems.\n *\n * There are certainly further optimizations that could be done here, we can do bigger chunks with other systems\n * But we need to find the _exact_ criteria. And then its not even guaranteed it'll be much faster.\n */\n const MAX_TEXTURE_SIZE = gl.getParameter(gl.MAX_TEXTURE_SIZE);\n let blockHeight = Math.floor(\n (bytesPerVoxel * MAX_TEXTURE_SIZE) / model.width\n );\n\n // Cap to actual frame height:\n blockHeight = Math.min(blockHeight, model.height);\n\n const multiRowBlockLength = rowLength * blockHeight;\n const multiRowBlockLengthInBytes = multiRowBlockLength * bytesPerVoxel;\n\n const normalBlocks = Math.floor(model.height / blockHeight);\n\n const lastBlockHeight = model.height % blockHeight;\n const multiRowLastBlockLength = rowLength * lastBlockHeight;\n\n // Perform most blocks.\n for (let block = 0; block < normalBlocks; block++) {\n const yOffset = block * blockHeight;\n\n // Dataview of block\n const dataView = new TypedArrayConstructor(\n buffer,\n zOffset + block * multiRowBlockLengthInBytes,\n multiRowBlockLength\n );\n\n gl.texSubImage3D(\n model.target, // target\n 0, // mipMap level (always zero)\n 0, // xOffset\n yOffset, // yOffset\n frameIndex,\n model.width,\n blockHeight, //model.height,\n 1, // numFramesInBlock,\n model.format,\n model.openGLDataType,\n dataView\n );\n }\n\n // perform last block if present\n\n if (lastBlockHeight !== 0) {\n const yOffset = normalBlocks * blockHeight;\n\n // Dataview of last block\n const dataView = new TypedArrayConstructor(\n buffer,\n zOffset + normalBlocks * multiRowBlockLengthInBytes,\n multiRowLastBlockLength\n );\n\n gl.texSubImage3D(\n model.target, // target\n 0, // mipMap level (always zero)\n 0, // xOffset\n yOffset, // yOffset\n frameIndex,\n model.width,\n lastBlockHeight, //model.height,\n 1, // numFramesInBlock,\n model.format,\n model.openGLDataType,\n dataView\n );\n }\n };\n\n publicAPI.getTextureParameters = () => {\n return {\n width: model.width,\n height: model.height,\n depth: model.depth,\n numComps: model.inputNumComps,\n dataType: model.inputDataType,\n };\n };\n\n /**\n * Called when a frame is loaded so that on next render we know which data to load in.\n * @param {number} frameIndex The frame to load in.\n */\n publicAPI.setUpdatedFrame = (frameIndex) => {\n model.updatedFrames[frameIndex] = true;\n };\n}\n\n// ----------------------------------------------------------------------------\n// Object factory\n// ----------------------------------------------------------------------------\n\n// ----------------------------------------------------------------------------\n\nconst DEFAULT_VALUES = {\n updatedFrames: [],\n};\n\nexport function extend(publicAPI, model, initialValues = {}) {\n Object.assign(model, DEFAULT_VALUES, initialValues);\n\n vtkOpenGLTexture.extend(publicAPI, model, initialValues);\n\n // Object methods\n vtkStreamingOpenGLTexture(publicAPI, model);\n}\n\n// ----------------------------------------------------------------------------\n\nexport const newInstance = macro.newInstance(\n extend,\n 'vtkStreamingOpenGLTexture'\n);\n\n// ----------------------------------------------------------------------------\n\nexport default { newInstance, extend };\n","import { vtkStreamingOpenGLTexture } from '../../RenderingEngine/vtkClasses';\nimport { IVolume, Metadata, Point3, IImageVolume, Mat3 } from '../../types';\n\n/** The base class for volume data. It includes the volume metadata\n * and the volume data along with the loading status.\n */\nexport class ImageVolume implements IImageVolume {\n /** Read-only unique identifier for the volume */\n readonly volumeId: string;\n /** Dimensions of the volume */\n dimensions: Point3;\n /** volume direction in world space */\n direction: Mat3;\n /** volume metadata */\n metadata: Metadata;\n /** volume origin, Note this is an opinionated origin for the volume */\n origin: Point3;\n /** volume scalar data */\n scalarData: Float32Array | Uint8Array;\n /** Whether preScaling has been performed on the volume */\n isPrescaled = false;\n /** volume scaling parameters if it contains scaled data */\n scaling?: {\n PET?: {\n // @TODO: Do these values exist?\n SUVlbmFactor?: number;\n SUVbsaFactor?: number;\n // accessed in ProbeTool\n suvbwToSuvlbm?: number;\n suvbwToSuvbsa?: number;\n };\n };\n /** volume size in bytes */\n sizeInBytes?: number; // Seems weird to pass this in? Why not grab it from scalarData.byteLength\n /** volume spacing in 3d world space */\n spacing: Point3;\n /** volume number of voxels */\n numVoxels: number;\n /** volume image data */\n imageData?: any;\n /** open gl texture for the volume */\n vtkOpenGLTexture: any; // No good way of referencing vtk classes as they aren't classes.\n /** load status object for the volume */\n loadStatus?: Record<string, any>;\n /** optional image ids for the volume if it is made of separated images */\n imageIds?: Array<string>;\n /** optional reference volume id if the volume is derived from another volume */\n referencedVolumeId?: string;\n /** whether the metadata for the pixel spacing is not undefined */\n hasPixelSpacing: boolean;\n\n constructor(props: IVolume) {\n this.volumeId = props.volumeId;\n this.metadata = props.metadata;\n this.dimensions = props.dimensions;\n this.spacing = props.spacing;\n this.origin = props.origin;\n this.direction = props.direction;\n this.imageData = props.imageData;\n this.scalarData = props.scalarData;\n this.sizeInBytes = props.sizeInBytes;\n this.vtkOpenGLTexture = vtkStreamingOpenGLTexture.newInstance();\n this.numVoxels =\n this.dimensions[0] * this.dimensions[1] * this.dimensions[2];\n\n if (props.scaling) {\n this.scaling = props.scaling;\n }\n\n if (props.referencedVolumeId) {\n this.referencedVolumeId = props.referencedVolumeId;\n }\n }\n\n cancelLoading: () => void;\n}\n\nexport default ImageVolume;\n","/**\n * EventTarget - Provides the [EventTarget](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget) interface\n */\nclass CornerstoneEventTarget implements EventTarget {\n private listeners;\n\n constructor() {\n this.listeners = {};\n }\n\n public reset() {\n this.listeners = {};\n }\n\n public addEventListener(type, callback) {\n if (!this.listeners[type]) {\n this.listeners[type] = [];\n }\n\n // prevent multiple callbacks from firing\n if (this.listeners[type].indexOf(callback) !== -1) {\n return;\n }\n\n this.listeners[type].push(callback);\n }\n\n public removeEventListener(type, callback) {\n if (!this.listeners[type]) {\n return;\n }\n\n const stack = this.listeners[type];\n const stackLength = stack.length;\n\n for (let i = 0; i < stackLength; i++) {\n if (stack[i] === callback) {\n stack.splice(i, 1);\n\n return;\n }\n }\n }\n\n dispatchEvent(event) {\n if (!this.listeners[event.type]) {\n //console.warn(`Skipping dispatch since there are no listeners for ${event.type}`);\n return;\n }\n\n const stack = this.listeners[event.type].slice();\n const stackLength = stack.length;\n\n for (let i = 0; i < stackLength; i++) {\n stack[i].call(this, event);\n }\n\n return !event.defaultPrevented;\n }\n}\n\n/**\n * EventTarget - Provides the [EventTarget](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget) interface\n */\nconst eventTarget = new CornerstoneEventTarget();\n\nexport default eventTarget;\n","import eventTarget from '../eventTarget';\n\n/**\n * Small utility to trigger a custom event for a given EventTarget.\n *\n * @example\n *\n * ```javascript\n * triggerEvent(element, Events.IMAGE_RENDERED, { element })\n * ```\n * or it can trigger event on the eventTarget itself\n *\n * ```javascript\n * triggerEvent(eventTarget, CSTOOLS_EVENTS.ANNOTATION_MODIFIED, { viewportId, annotationUID })\n * ```\n *\n * @param el - The element or EventTarget to trigger the event upon\n * @param type - The event type name\n * @param detail - The event detail to be sent\n * @returns false if event is cancelable and at least one of the event handlers\n * which received event called Event.preventDefault(). Otherwise it returns true.\n */\nexport default function triggerEvent(\n el: EventTarget = eventTarget,\n type: string,\n detail: unknown = null\n): boolean {\n if (!type) {\n throw new Error('Event type was not defined');\n }\n\n const event = new CustomEvent(type, {\n detail,\n cancelable: true,\n });\n\n return el.dispatchEvent(event);\n}\n","/**\n * Removes the data loader scheme from the imageId\n *\n * @param imageId - Image ID\n * @returns imageId without the data loader scheme\n */\nexport default function imageIdToURI(imageId: string): string {\n const colonIndex = imageId.indexOf(':');\n return imageId.substring(colonIndex + 1);\n}\n","import {\n ICache,\n IImage,\n IImageVolume,\n IImageLoadObject,\n IVolumeLoadObject,\n ICachedImage,\n ICachedVolume,\n EventTypes,\n} from '../types';\nimport { triggerEvent, imageIdToURI } from '../utilities';\nimport eventTarget from '../eventTarget';\nimport Events from '../enums/Events';\n\nconst MAX_CACHE_SIZE_1GB = 1073741824;\n\nclass Cache implements ICache {\n private readonly _imageCache: Map<string, ICachedImage>; // volatile space\n private readonly _volumeCache: Map<string, ICachedVolume>; // non-volatile space\n private _imageCacheSize: number;\n private _volumeCacheSize: number;\n private _maxCacheSize: number;\n\n constructor() {\n this._imageCache = new Map();\n this._volumeCache = new Map();\n this._imageCacheSize = 0;\n this._volumeCacheSize = 0;\n this._maxCacheSize = MAX_CACHE_SIZE_1GB; // Default 1GB\n }\n\n /**\n * Set the maximum cache Size\n *\n * Maximum cache size should be set before adding the data; otherwise, it\n * will throw an error.\n *\n * @param newMaxCacheSize - new maximum cache size\n *\n */\n public setMaxCacheSize = (newMaxCacheSize: number): void => {\n if (!newMaxCacheSize || typeof newMaxCacheSize !== 'number') {\n const errorMessage = `New max cacheSize ${this._maxCacheSize} should be defined and should be a number.`;\n throw new Error(errorMessage);\n }\n\n this._maxCacheSize = newMaxCacheSize;\n };\n\n /**\n * Checks if there is enough space in the cache for requested byte size\n *\n * It throws error, if the sum of volatile (image) cache and unallocated cache\n * is less than the requested byteLength\n *\n * @param byteLength - byte length of requested byte size\n *\n * @returns - boolean indicating if there is enough space in the cache\n */\n public isCacheable = (byteLength: number): boolean => {\n const unallocatedSpace = this.getBytesAvailable();\n const imageCacheSize = this._imageCacheSize;\n const availableSpace = unallocatedSpace + imageCacheSize;\n\n return availableSpace > byteLength;\n };\n\n /**\n * Returns maximum CacheSize allowed\n *\n * @returns maximum allowed cache size\n */\n public getMaxCacheSize = (): number => this._maxCacheSize;\n\n /**\n * Returns current size of the cache\n *\n * @returns current size of the cache\n */\n public getCacheSize = (): number =>\n this._imageCacheSize + this._volumeCacheSize;\n\n /**\n * Returns the unallocated size of the cache\n *\n */\n public getBytesAvailable(): number {\n return this.getMaxCacheSize() - this.getCacheSize();\n }\n\n /**\n * Deletes the imageId from the image cache\n *\n * @param imageId - imageId\n *\n */\n private _decacheImage = (imageId: string) => {\n const { imageLoadObject } = this._imageCache.get(imageId);\n\n // Cancel any in-progress loading\n if (imageLoadObject.cancelFn) {\n imageLoadObject.cancelFn();\n }\n\n if (imageLoadObject.decache) {\n imageLoadObject.decache();\n }\n\n this._imageCache.delete(imageId);\n };\n\n /**\n * Deletes the volumeId from the volume cache\n *\n * @param volumeId - volumeId\n *\n */\n private _decacheVolume = (volumeId: string) => {\n const cachedVolume = this._volumeCache.get(volumeId);\n const { volumeLoadObject, volume } = cachedVolume;\n\n if (volume.cancelLoading) {\n volume.cancelLoading();\n }\n\n if (volume.imageData) {\n volume.imageData = null;\n }\n\n if (volumeLoadObject.cancelFn) {\n // Cancel any in-progress loading\n volumeLoadObject.cancelFn();\n }\n\n if (volumeLoadObject.decache) {\n volumeLoadObject.decache();\n }\n\n this._volumeCache.delete(volumeId);\n };\n\n /**\n * Deletes all the images and volumes in the cache\n *\n * Relevant events are fired for each decached image (IMAGE_CACHE_IMAGE_REMOVED) and\n * the decached volume (VOLUME_CACHE_VOLUME_REMOVED).\n *\n * @fires Events.IMAGE_CACHE_IMAGE_REMOVED\n * @fires Events.VOLUME_CACHE_VOLUME_REMOVED\n *\n */\n public purgeCache = (): void => {\n const imageIterator = this._imageCache.keys();\n\n /* eslint-disable no-constant-condition */\n while (true) {\n const { value: imageId, done } = imageIterator.next();\n\n if (done) {\n break;\n }\n\n this.removeImageLoadObject(imageId);\n\n triggerEvent(eventTarget, Events.IMAGE_CACHE_IMAGE_REMOVED, { imageId });\n }\n\n this.purgeVolumeCache();\n };\n\n /**\n * Deletes all the volumes in the cache\n */\n public purgeVolumeCache = (): void => {\n const volumeIterator = this._volumeCache.keys();\n\n /* eslint-disable no-constant-condition */\n while (true) {\n const { value: volumeId, done } = volumeIterator.next();\n\n if (done) {\n break;\n }\n\n this.removeVolumeLoadObject(volumeId);\n\n triggerEvent(eventTarget, Events.VOLUME_CACHE_VOLUME_REMOVED, {\n volumeId,\n });\n }\n };\n\n /**\n * Purges the cache if necessary based on the requested number of bytes\n *\n * 1) it sorts the volatile (image) cache based on the most recent used images\n * and starts purging from the oldest ones.\n * Note: for a volume, if the volume-related image Ids is provided, it starts\n * by purging the none-related image Ids (those that are not related to the\n * current volume)\n * 2) For a volume, if we purge all images that won't be included in this volume and still\n * don't have enough unallocated space, purge images that will be included\n * in this volume until we have enough space. These will need to be\n * re-fetched, but we must do this not to straddle over the given memory\n * limit, even for a short time, as this may crash the application.\n *\n * @fires Events.IMAGE_CACHE_IMAGE_REMOVED\n *\n * @param numBytes - Number of bytes for the image/volume that is\n * going to be stored inside the cache\n * @param volumeImageIds - list of imageIds that correspond to the\n * volume whose numberOfBytes we want to store in the cache.\n * @returns bytesAvailable or undefined in purging cache\n * does not successfully make enough space for the requested number of bytes\n */\n public decacheIfNecessaryUntilBytesAvailable(\n numBytes: number,\n volumeImageIds?: Array<string>\n ): number | undefined {\n let bytesAvailable = this.getBytesAvailable();\n\n // If max cache size has not been exceeded, do nothing\n if (bytesAvailable >= numBytes) {\n return bytesAvailable;\n }\n\n let cachedImages = Array.from(this._imageCache.values());\n\n // Cache size has been exceeded, create list of images sorted by timeStamp\n // So we can purge the least recently used image\n function compare(a, b) {\n if (a.timeStamp > b.timeStamp) {\n return 1;\n }\n if (a.timeStamp < b.timeStamp) {\n return -1;\n }\n\n return 0;\n }\n\n cachedImages.sort(compare);\n let cachedImageIds = cachedImages.map((im) => im.imageId);\n\n let imageIdsToPurge = cachedImageIds;\n\n // if we are making space for a volume, we start by purging the imageIds\n // that are not related to the volume\n if (volumeImageIds) {\n imageIdsToPurge = cachedImageIds.filter(\n (id) => !volumeImageIds.includes(id)\n );\n }\n\n // Remove images (that are not related to the volume) from volatile cache\n // until the requested number of bytes become available\n for (const imageId of imageIdsToPurge) {\n this.removeImageLoadObject(imageId);\n\n triggerEvent(eventTarget, Events.IMAGE_CACHE_IMAGE_REMOVED, { imageId });\n\n bytesAvailable = this.getBytesAvailable();\n if (bytesAvailable >= numBytes) {\n return bytesAvailable;\n }\n }\n\n // Remove the imageIds (both volume related and not related)\n cachedImages = Array.from(this._imageCache.values());\n cachedImageIds = cachedImages.map((im) => im.imageId);\n\n // Remove volume-image Ids from volatile cache until the requested number of bytes\n // become available\n for (const imageId of cachedImageIds) {\n this.removeImageLoadObject(imageId);\n\n triggerEvent(eventTarget, Events.IMAGE_CACHE_IMAGE_REMOVED, { imageId });\n\n bytesAvailable = this.getBytesAvailable();\n if (bytesAvailable >= numBytes) {\n return bytesAvailable;\n }\n }\n\n // Technically we should not reach here, since isCacheable will throw an\n // error if unallocated + volatile (image) cache cannot fit the upcoming\n // number of bytes\n }\n\n /**\n * Puts a new image load object into the cache\n *\n * First, it creates a CachedImage object and put it inside the imageCache for\n * the imageId. After the imageLoadObject promise resolves to an image,\n * it: 1) adds the image into the correct CachedImage object 2) increments the\n * cache size, 3) triggers IMAGE_CACHE_IMAGE_ADDED 4) Purge the cache if\n * necessary -- if the cache size is greater than the maximum cache size, it\n * iterates over the imageCache and decache them one by one until the cache\n * size becomes less than the maximum allowed cache size\n *\n * @fires Events.IMAGE_CACHE_IMAGE_ADDED\n * @fires Events.CACHE_SIZE_EXCEEDED if the cache size exceeds the maximum\n *\n * @param imageId - ImageId for the image\n * @param imageLoadObject - The object that is loading or loaded the image\n */\n public putImageLoadObject(\n imageId: string,\n imageLoadObject: IImageLoadObject\n ): Promise<any> {\n if (imageId === undefined) {\n throw new Error('putImageLoadObject: imageId must not be undefined');\n }\n\n if (imageLoadObject.promise === undefined) {\n throw new Error(\n 'putImageLoadObject: imageLoadObject.promise must not be undefined'\n );\n }\n\n if (this._imageCache.has(imageId)) {\n throw new Error('putImageLoadObject: imageId already in cache');\n }\n\n if (\n imageLoadObject.cancelFn &&\n typeof imageLoadObject.cancelFn !== 'function'\n ) {\n throw new Error(\n 'putImageLoadObject: imageLoadObject.cancel must be a function'\n );\n }\n\n const cachedImage: ICachedImage = {\n loaded: false,\n imageId,\n sharedCacheKey: undefined, // The sharedCacheKey for this imageId. undefined by default\n imageLoadObject,\n timeStamp: Date.now(),\n sizeInBytes: 0,\n };\n\n this._imageCache.set(imageId, cachedImage);\n\n return imageLoadObject.promise\n .then((image: IImage) => {\n if (!this._imageCache.get(imageId)) {\n // If the image has been purged before being loaded, we stop here.\n console.warn(\n 'The image was purged from the cache before it completed loading.'\n );\n return;\n }\n\n if (image.sizeInBytes === undefined) {\n throw new Error(\n 'putImageLoadObject: image.sizeInBytes must not be undefined'\n );\n }\n if (image.sizeInBytes.toFixed === undefined) {\n throw new Error(\n 'putImageLoadObject: image.sizeInBytes is not a number'\n );\n }\n\n // check if there is enough space in unallocated + image Cache\n if (!this.isCacheable(image.sizeInBytes)) {\n throw new Error(Events.CACHE_SIZE_EXCEEDED);\n }\n\n // if there is, decache if necessary\n this.decacheIfNecessaryUntilBytesAvailable(image.sizeInBytes);\n\n cachedImage.loaded = true;\n cachedImage.image = image;\n cachedImage.sizeInBytes = image.sizeInBytes;\n this._incrementImageCacheSize(cachedImage.sizeInBytes);\n\n const eventDetails: EventTypes.ImageCacheImageAddedEventDetail = {\n image: cachedImage,\n };\n\n triggerEvent(eventTarget, Events.IMAGE_CACHE_IMAGE_ADDED, eventDetails);\n\n cachedImage.sharedCacheKey = image.sharedCacheKey;\n })\n .catch((error) => {\n // console.warn(error)\n this._imageCache.delete(imageId);\n throw error;\n });\n }\n\n /**\n * Returns the object that is loading a given imageId\n *\n * @param imageId - Image ID\n * @returns IImageLoadObject\n */\n public getImageLoadObject(imageId: string): IImageLoadObject {\n if (imageId === undefined) {\n throw new Error('getImageLoadObject: imageId must not be undefined');\n }\n const cachedImage = this._imageCache.get(imageId);\n\n if (cachedImage === undefined) {\n return;\n }\n\n // Bump time stamp for cached image\n cachedImage.timeStamp = Date.now();\n\n return cachedImage.imageLoadObject;\n }\n\n /**\n * It checks the imageCache for the provided imageId, and returns true\n * if the image is loaded, false otherwise. Note, this only checks the imageCache\n * and does not check the volume cache.\n * @param imageId - image Id to check\n * @returns boolean\n */\n public isImageIdCached(imageId: string): boolean {\n const cachedImage = this._imageCache.get(imageId);\n\n if (!cachedImage) {\n return false;\n }\n\n return cachedImage.loaded;\n }\n\n /**\n * Returns the volume that contains the requested imageId. It will check the\n * imageIds inside the volume to find a match.\n *\n * @param imageId - ImageId\n * @returns - Volume object\n */\n public getVolumeContainingImageId(imageId: string): {\n volume: IImageVolume;\n imageIdIndex: number;\n } {\n const volumeIds = Array.from(this._volumeCache.keys());\n const imageIdToUse = imageIdToURI(imageId);\n\n for (const volumeId of volumeIds) {\n const cachedVolume = this._volumeCache.get(volumeId);\n\n if (!cachedVolume.volume) {\n return;\n }\n\n let { imageIds } = cachedVolume.volume;\n\n if (!imageIds || imageIds.length === 0) {\n continue;\n }\n\n imageIds = imageIds.map((id) => imageIdToURI(id));\n\n const imageIdIndex = imageIds.indexOf(imageIdToUse);\n if (imageIdIndex > -1) {\n return { volume: cachedVolume.volume, imageIdIndex };\n }\n }\n }\n\n /**\n * Returns the cached image from the imageCache for the requested imageId.\n * It first strips the imageId to remove the data loading scheme.\n *\n * @param imageId - Image ID\n * @returns cached image\n */\n public getCachedImageBasedOnImageURI(\n imageId: string\n ): ICachedImage | undefined {\n const imageURIToUse = imageIdToURI(imageId);\n\n const cachedImageIds = Array.from(this._imageCache.keys());\n const foundImageId = cachedImageIds.find((imageId) => {\n return imageIdToURI(imageId) === imageURIToUse;\n });\n\n if (!foundImageId) {\n return;\n }\n\n return this._imageCache.get(foundImageId);\n }\n /**\n * Puts a new image load object into the cache\n *\n * First, it creates a CachedVolume object and put it inside the volumeCache for\n * the volumeId. After the volumeLoadObject promise resolves to a volume,\n * it: 1) adds the volume into the correct CachedVolume object inside volumeCache\n * 2) increments the cache size, 3) triggers VOLUME_CACHE_VOLUME_ADDED 4) Purge\n * the cache if necessary -- if the cache size is greater than the maximum cache size, it\n * iterates over the imageCache (not volumeCache) and decache them one by one\n * until the cache size becomes less than the maximum allowed cache size\n *\n * @fires Events.VOLUME_CACHE_VOLUME_ADDED\n *\n * @param volumeId - volumeId of the volume\n * @param volumeLoadObject - The object that is loading or loaded the volume\n */\n public putVolumeLoadObject(\n volumeId: string,\n volumeLoadObject: IVolumeLoadObject\n ): Promise<any> {\n if (volumeId === undefined) {\n throw new Error('putVolumeLoadObject: volumeId must not be undefined');\n }\n if (volumeLoadObject.promise === undefined) {\n throw new Error(\n 'putVolumeLoadObject: volumeLoadObject.promise must not be undefined'\n );\n }\n if (this._volumeCache.has(volumeId)) {\n throw new Error(\n `putVolumeLoadObject: volumeId:${volumeId} already in cache`\n );\n }\n if (\n volumeLoadObject.cancelFn &&\n typeof volumeLoadObject.cancelFn !== 'function'\n ) {\n throw new Error(\n 'putVolumeLoadObject: volumeLoadObject.cancel must be a function'\n );\n }\n\n // todo: @Erik there are two loaded flags, one inside cachedVolume and the other\n // inside the volume.loadStatus.loaded, the actual all pixelData loaded is the\n // loadStatus one. This causes confusion\n const cachedVolume: ICachedVolume = {\n loaded: false,\n volumeId,\n volumeLoadObject,\n timeStamp: Date.now(),\n sizeInBytes: 0,\n };\n\n this._volumeCache.set(volumeId, cachedVolume);\n\n return volumeLoadObject.promise\n .then((volume: IImageVolume) => {\n if (!this._volumeCache.get(volumeId)) {\n // If the image has been purged before being loaded, we stop here.\n console.warn(\n 'The image was purged from the cache before it completed loading.'\n );\n return;\n }\n\n if (volume.sizeInBytes === undefined) {\n throw new Error(\n 'putVolumeLoadObject: volume.sizeInBytes must not be undefined'\n );\n }\n if (volume.sizeInBytes.toFixed === undefined) {\n throw new Error(\n 'putVolumeLoadObject: volume.sizeInBytes is not a number'\n );\n }\n\n // this.isCacheable is called at the volume loader, before requesting\n // the images of the volume\n\n this.decacheIfNecessaryUntilBytesAvailable(\n volume.sizeInBytes,\n // @ts-ignore: // todo ImageVolume does not have imageIds\n volume.imageIds\n );\n\n // cachedVolume.loaded = true\n cachedVolume.volume = volume;\n cachedVolume.sizeInBytes = volume.sizeInBytes;\n this._incrementVolumeCacheSize(cachedVolume.sizeInBytes);\n\n const eventDetails: EventTypes.VolumeCacheVolumeAddedEventDetail = {\n volume: cachedVolume,\n };\n\n triggerEvent(\n eventTarget,\n Events.VOLUME_CACHE_VOLUME_ADDED,\n eventDetails\n );\n })\n .catch((error) => {\n this._volumeCache.delete(volumeId);\n throw error;\n });\n }\n\n /**\n * Returns the object that is loading a given volumeId\n *\n * @param volumeId - Volume ID\n * @returns IVolumeLoadObject\n */\n public getVolumeLoadObject = (volumeId: string): IVolumeLoadObject => {\n if (volumeId === undefined) {\n throw new Error('getVolumeLoadObject: volumeId must not be undefined');\n }\n const cachedVolume = this._volumeCache.get(volumeId);\n\n if (cachedVolume === undefined) {\n return;\n }\n\n // Bump time stamp for cached volume (not used for anything for now)\n cachedVolume.timeStamp = Date.now();\n\n return cachedVolume.volumeLoadObject;\n };\n\n /**\n * Returns the volume associated with the volumeId\n *\n * @param volumeId - Volume ID\n * @returns Volume\n */\n public getVolume = (volumeId: string): IImageVolume => {\n if (volumeId === undefined) {\n throw new Error('getVolume: volumeId must not be undefined');\n }\n const cachedVolume = this._volumeCache.get(volumeId);\n\n if (cachedVolume === undefined) {\n return;\n }\n\n // Bump time stamp for cached volume (not used for anything for now)\n cachedVolume.timeStamp = Date.now();\n\n return cachedVolume.volume;\n };\n\n /**\n * Removes the image loader associated with a given Id from the cache\n *\n * It increases the cache size after removing the image.\n *\n * @fires Events.IMAGE_CACHE_IMAGE_REMOVED\n *\n * @param imageId - Image ID\n */\n public removeImageLoadObject = (imageId: string): void => {\n if (imageId === undefined) {\n throw new Error('removeImageLoadObject: imageId must not be undefined');\n }\n const cachedImage = this._imageCache.get(imageId);\n\n if (cachedImage === undefined) {\n throw new Error(\n 'removeImageLoadObject: imageId was not present in imageCache'\n );\n }\n\n this._incrementImageCacheSize(-cachedImage.sizeInBytes);\n\n const eventDetails = {\n imageId,\n };\n\n triggerEvent(eventTarget, Events.IMAGE_CACHE_IMAGE_REMOVED, eventDetails);\n this._decacheImage(imageId);\n };\n\n /**\n * Removes the volume loader associated with a given Id from the cache\n *\n * It increases the cache size after removing the image.\n *\n * @fires Events.VOLUME_CACHE_VOLUME_REMOVED\n *\n * @param imageId - ImageId\n */\n public removeVolumeLoadObject = (volumeId: string): void => {\n if (volumeId === undefined) {\n throw new Error('removeVolumeLoadObject: volumeId must not be undefined');\n }\n const cachedVolume = this._volumeCache.get(volumeId);\n\n if (cachedVolume === undefined) {\n throw new Error(\n 'removeVolumeLoadObject: volumeId was not present in volumeCache'\n );\n }\n\n this._incrementVolumeCacheSize(-cachedVolume.sizeInBytes);\n\n const eventDetails = {\n volume: cachedVolume,\n volumeId,\n };\n\n triggerEvent(eventTarget, Events.VOLUME_CACHE_VOLUME_REMOVED, eventDetails);\n this._decacheVolume(volumeId);\n };\n\n /**\n * Increases the image cache size with the provided increment\n *\n * @param increment - bytes length\n */\n private _incrementImageCacheSize = (increment: number) => {\n this._imageCacheSize += increment;\n };\n\n /**\n * Increases the cache size with the provided increment\n *\n * @param increment - bytes length\n */\n private _incrementVolumeCacheSize = (increment: number) => {\n this._volumeCacheSize += increment;\n };\n}\n\n/**\n * This module deals with Caching of images and volumes\n * The cache has two main components: a volatile portion for images and a\n * non-volatile portion for volumes. Individual 2D images are volatile and\n * will be replaced by new images hitting the cache. When you allocate volumes,\n * these are non-volatile and reserve a block of memory from the cache.\n * Volumes must be released manually.\n * We will have a shared block of memory allocated for the entire cache, e.g. 1GB\n * which will be shared for images and volumes.\n *\n * **When a new image is added:**\n * We check if there is enough unallocated + volatile space for the single image\n *\n * if so\n * - We allocate the image in image cache, and if necessary oldest images\n * are decached to match the maximumCacheSize criteria\n * - If a volume contains that imageId, copy it over using TypedArray's set method.\n * If no volumes contain the imageId, the image is fetched by image loaders\n *\n * If not (cache is mostly/completely full with volumes)\n * - throw that the cache does not have enough working space to allocate the image\n *\n *\n * **When a new volume is added:**\n * Check if there is enough unallocated + volatile space to allocate the volume:\n *\n * If so:\n * - Decache oldest images which won't be included in this volume until\n * we have enough free space for the volume\n * - If not enough space from previous space, decache images that will be included\n * in the volume until we have enough free space (These will need to be re-fetched,\n * but we must do this not to straddle over the given memory limit, even for a\n * short time, as this may crash the app)\n * - At this point, if any of the frames (indexed by imageId) are present in the volatile\n * image cache, copy these over to the volume now\n *\n * If not (cache is mostly/completely full with volumes),\n * - throw that the cache does not have enough working space to allocate the volume.\n *\n */\nconst cache = new Cache();\nexport default cache;\nexport { Cache }; // for documentation\n","// prettier-ignore\n// @ts-nocheck\n/**\n * Generates a unique id that has limited chance of collision\n *\n * @see {@link https://stackoverflow.com/a/2117523/1867984|StackOverflow: Source}\n * @returns a v4 compliant GUID\n */\nexport default function uuidv4(): string {\n return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>\n (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)\n );\n}\n","import '@kitware/vtk.js/Rendering/Profiles/Volume';\n\nimport vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData';\nimport type { vtkImageData as vtkImageDataType } from '@kitware/vtk.js/Common/DataModel/ImageData';\nimport vtkDataArray from '@kitware/vtk.js/Common/Core/DataArray';\nimport cloneDeep from 'lodash.clonedeep';\n\nimport { ImageVolume } from './cache/classes/ImageVolume';\nimport type * as Types from './types';\nimport cache from './cache/cache';\nimport Events from './enums/Events';\nimport eventTarget from './eventTarget';\nimport triggerEvent from './utilities/triggerEvent';\nimport { uuidv4 } from './utilities';\nimport { Point3, Metadata, EventTypes, Mat3 } from './types';\n\ninterface VolumeLoaderOptions {\n imageIds: Array<string>;\n}\n\ninterface DerivedVolumeOptions {\n volumeId: string;\n targetBuffer?: {\n type: 'Float32Array' | 'Uint8Array';\n sharedArrayBuffer?: boolean;\n };\n}\ninterface LocalVolumeOptions {\n scalarData: Float32Array | Uint8Array;\n metadata: Metadata;\n dimensions: Point3;\n spacing: Point3;\n origin: Point3;\n direction: Mat3;\n}\n\nfunction createInternalVTKRepresentation({\n dimensions,\n metadata,\n spacing,\n direction,\n origin,\n scalarData,\n}): vtkImageDataType {\n const { PhotometricInterpretation } = metadata;\n\n let numComponents = 1;\n if (PhotometricInterpretation === 'RGB') {\n numComponents = 3;\n }\n\n const scalarArray = vtkDataArray.newInstance({\n name: 'Pixels',\n numberOfComponents: numComponents,\n values: scalarData,\n });\n\n const imageData = vtkImageData.newInstance();\n\n imageData.setDimensions(dimensions);\n imageData.setSpacing(spacing);\n imageData.setDirection(direction);\n imageData.setOrigin(origin);\n imageData.getPointData().setScalars(scalarArray);\n\n return imageData;\n}\n\n/**\n * This module deals with VolumeLoaders and loading volumes\n */\n\nconst volumeLoaders = {};\n\nlet unknownVolumeLoader;\n\n/**\n * Load a volume using a registered Cornerstone Volume Loader.\n *\n * The volume loader that is used will be\n * determined by the volume loader scheme matching against the volumeId.\n *\n * @param volumeId - A Cornerstone Volume Object's volumeId\n * @param options - Options to be passed to the Volume Loader. Options\n * contain the ImageIds that is passed to the loader\n *\n * @returns An Object which can be used to act after a volume is loaded or loading fails\n *\n */\nfunction loadVolumeFromVolumeLoader(\n volumeId: string,\n options: VolumeLoaderOptions\n): Types.IVolumeLoadObject {\n const colonIndex = volumeId.indexOf(':');\n const scheme = volumeId.substring(0, colonIndex);\n const loader = volumeLoaders[scheme];\n\n if (loader === undefined || loader === null) {\n if (unknownVolumeLoader !== undefined) {\n return unknownVolumeLoader(volumeId, options);\n }\n\n throw new Error(\n 'loadVolumeFromVolumeLoader: no volume loader for volumeId'\n );\n }\n\n const volumeLoadObject = loader(volumeId, options);\n\n // Broadcast a volume loaded event once the image is loaded\n volumeLoadObject.promise.then(\n function (volume) {\n triggerEvent(eventTarget, Events.VOLUME_LOADED, { volume });\n },\n function (error) {\n const errorObject: EventTypes.VolumeLoadedFailedEventDetail = {\n volumeId,\n error,\n };\n\n triggerEvent(eventTarget, Events.VOLUME_LOADED_FAILED, errorObject);\n }\n );\n\n return volumeLoadObject;\n}\n\n/**\n * Loads a volume given a volumeId and optional priority and returns a promise which will resolve to\n * the loaded image object or fail if an error occurred. The loaded image is not stored in the cache.\n *\n * @param volumeId - A Cornerstone Image Object's volumeId\n * @param options - Options to be passed to the Volume Loader\n *\n * @returns An Object which can be used to act after an image is loaded or loading fails\n */\nexport function loadVolume(\n volumeId: string,\n options: VolumeLoaderOptions = { imageIds: [] }\n): Promise<Types.IImageVolume> {\n if (volumeId === undefined) {\n throw new Error('loadVolume: parameter volumeId must not be undefined');\n }\n\n let volumeLoadObject = cache.getVolumeLoadObject(volumeId);\n\n if (volumeLoadObject !== undefined) {\n return volumeLoadObject.promise;\n }\n\n volumeLoadObject = loadVolumeFromVolumeLoader(volumeId, options);\n\n return volumeLoadObject.promise.then((volume: Types.IImageVolume) => {\n volume.imageData = createInternalVTKRepresentation(volume);\n return volume;\n });\n}\n\n/**\n * Loads an image given an volumeId and optional priority and returns a promise which will resolve to\n * the loaded image object or fail if an error occurred. The image is stored in the cache.\n *\n * @param volumeId - A Cornerstone Image Object's volumeId\n * @param options - Options to be passed to the Volume Loader\n *\n * @returns Volume Loader Object\n */\nexport async function createAndCacheVolume(\n volumeId: string,\n options: VolumeLoaderOptions\n): Promise<Record<string, any>> {\n if (volumeId === undefined) {\n throw new Error(\n 'createAndCacheVolume: parameter volumeId must not be undefined'\n );\n }\n\n let volumeLoadObject = cache.getVolumeLoadObject(volumeId);\n\n if (volumeLoadObject !== undefined) {\n return volumeLoadObject.promise;\n }\n\n volumeLoadObject = loadVolumeFromVolumeLoader(volumeId, options);\n\n volumeLoadObject.promise.then((volume: Types.IImageVolume) => {\n volume.imageData = createInternalVTKRepresentation(volume);\n });\n\n cache.putVolumeLoadObject(volumeId, volumeLoadObject).catch((err) => {\n throw err;\n });\n\n return volumeLoadObject.promise;\n}\n\n/**\n * Based on a referencedVolumeId, it will build and cache a new volume. If\n * no scalarData is specified in the options, an empty derived volume will be\n * created that matches the image metadata of the referenceVolume. If scalarData\n * is given, it will be used to generate the intensity values for the derivedVolume.\n * Finally, it will save the volume in the cache.\n * @param referencedVolumeId - the volumeId from which the new volume will get its metadata\n * @param options - DerivedVolumeOptions {uid: derivedVolumeUID, targetBuffer: { type: FLOAT32Array | Uint8Array}, scalarData: if provided}\n *\n * @returns ImageVolume\n */\nexport async function createAndCacheDerivedVolume(\n referencedVolumeId: string,\n options: DerivedVolumeOptions\n): Promise<ImageVolume> {\n const referencedVolume = cache.getVolume(referencedVolumeId);\n\n if (!referencedVolume) {\n throw new Error(\n `Cannot created derived volume: Referenced volume with id ${referencedVolumeId} does not exist.`\n );\n }\n\n let { volumeId } = options;\n const { targetBuffer } = options;\n\n if (volumeId === undefined) {\n volumeId = uuidv4();\n }\n\n const { metadata, dimensions, spacing, origin, direction, scalarData } =\n referencedVolume;\n const scalarLength = scalarData.length;\n\n let numBytes, TypedArray;\n\n // If target buffer is provided\n if (targetBuffer) {\n if (targetBuffer.type === 'Float32Array') {\n numBytes = scalarLength * 4;\n TypedArray = Float32Array;\n } else if (targetBuffer.type === 'Uint8Array') {\n numBytes = scalarLength;\n TypedArray = Uint8Array;\n } else {\n throw new Error('TargetBuffer should be Float32Array or Uint8Array');\n }\n } else {\n // Use float32 if no targetBuffer is provided\n numBytes = scalarLength * 4;\n TypedArray = Float32Array;\n }\n\n // check if there is enough space in unallocated + image Cache\n const isCacheable = cache.isCacheable(numBytes);\n if (!isCacheable) {\n throw new Error(Events.CACHE_SIZE_EXCEEDED);\n }\n\n let volumeScalarData;\n if (targetBuffer?.sharedArrayBuffer) {\n const buffer = new SharedArrayBuffer(numBytes);\n volumeScalarData = new TypedArray(buffer);\n } else {\n volumeScalarData = new TypedArray(scalarLength);\n }\n\n // Todo: handle more than one component for segmentation (RGB)\n const scalarArray = vtkDataArray.newInstance({\n name: 'Pixels',\n numberOfComponents: 1,\n values: volumeScalarData,\n });\n\n const derivedImageData = vtkImageData.newInstance();\n\n derivedImageData.setDimensions(dimensions);\n derivedImageData.setSpacing(spacing);\n derivedImageData.setDirection(direction);\n derivedImageData.setOrigin(origin);\n derivedImageData.getPointData().setScalars(scalarArray);\n\n const derivedVolume = new ImageVolume({\n volumeId,\n metadata: cloneDeep(metadata),\n dimensions: [dimensions[0], dimensions[1], dimensions[2]],\n spacing,\n origin,\n direction,\n imageData: derivedImageData,\n scalarData: volumeScalarData,\n sizeInBytes: numBytes,\n referencedVolumeId,\n });\n\n const volumeLoadObject = {\n promise: Promise.resolve(derivedVolume),\n };\n\n await cache.putVolumeLoadObject(volumeId, volumeLoadObject);\n\n return derivedVolume;\n}\n\n/**\n * Creates and cache a volume based on a set of provided properties including\n * dimensions, spacing, origin, direction, metadata, scalarData. It should be noted that\n * scalarData should be provided for this function to work. If a volume with the same\n * Id exists in the cache it returns it immediately.\n * @param options - { scalarData, metadata, dimensions, spacing, origin, direction }\n * @param volumeId - Id of the generated volume\n *\n * @returns ImageVolume\n */\nexport function createLocalVolume(\n options: LocalVolumeOptions,\n volumeId: string,\n preventCache = false\n): ImageVolume {\n const { scalarData, metadata, dimensions, spacing, origin, direction } =\n options;\n\n if (\n !scalarData ||\n !(scalarData instanceof Uint8Array || scalarData instanceof Float32Array)\n ) {\n throw new Error(\n 'To use createLocalVolume you should pass scalarData of type Uint8Array or Float32Array'\n );\n }\n\n // Todo: handle default values for spacing, origin, direction if not provided\n if (volumeId === undefined) {\n volumeId = uuidv4();\n }\n\n const cachedVolume = cache.getVolume(volumeId);\n\n if (cachedVolume) {\n return cachedVolume as ImageVolume;\n }\n\n const scalarLength = dimensions[0] * dimensions[1] * dimensions[2];\n\n const numBytes = scalarData ? scalarData.buffer.byteLength : scalarLength * 4;\n\n // check if there is enough space in unallocated + image Cache\n const isCacheable = cache.isCacheable(numBytes);\n if (!isCacheable) {\n throw new Error(Events.CACHE_SIZE_EXCEEDED);\n }\n\n const scalarArray = vtkDataArray.newInstance({\n name: 'Pixels',\n numberOfComponents: 1,\n values: scalarData,\n });\n\n const imageData = vtkImageData.newInstance();\n\n imageData.setDimensions(dimensions);\n imageData.setSpacing(spacing);\n imageData.setDirection(direction);\n imageData.setOrigin(origin);\n imageData.getPointData().setScalars(scalarArray);\n\n const derivedVolume = new ImageVolume({\n volumeId,\n metadata: cloneDeep(metadata),\n dimensions: [dimensions[0], dimensions[1], dimensions[2]],\n spacing,\n origin,\n direction,\n imageData: imageData,\n scalarData,\n sizeInBytes: numBytes,\n });\n\n if (preventCache) {\n return derivedVolume;\n }\n\n const volumeLoadObject = {\n promise: Promise.resolve(derivedVolume),\n };\n cache.putVolumeLoadObject(volumeId, volumeLoadObject);\n\n return derivedVolume;\n}\n\n/**\n * Registers an volumeLoader plugin with cornerstone for the specified scheme\n *\n * @param scheme - The scheme to use for this volume loader (e.g. 'dicomweb', 'wadouri', 'http')\n * @param volumeLoader - A Cornerstone Volume Loader function\n */\nexport function registerVolumeLoader(\n scheme: string,\n volumeLoader: Types.VolumeLoaderFn\n): void {\n volumeLoaders[scheme] = volumeLoader;\n}\n\n/**\n * Registers a new unknownVolumeLoader and returns the previous one\n *\n * @param volumeLoader - A Cornerstone Volume Loader\n *\n * @returns The previous Unknown Volume Loader\n */\nexport function registerUnknownVolumeLoader(\n volumeLoader: Types.VolumeLoaderFn\n): Types.VolumeLoaderFn | undefined {\n const oldVolumeLoader = unknownVolumeLoader;\n\n unknownVolumeLoader = volumeLoader;\n\n return oldVolumeLoader;\n}\n","import macro from '@kitware/vtk.js/macros';\nimport vtkVolumeMapper from '@kitware/vtk.js/Rendering/Core/VolumeMapper';\n\n/**\n * vtkSharedVolumeMapper - A derived class of the core vtkVolumeMapper class\n * the scalar texture in as an argument. This is so we can share the same texture\n * memory across different mappers/actors, so we don't duplicate memory usage.\n *\n *\n *\n * @param {*} publicAPI The public API to extend\n * @param {*} model The private model to extend.\n * @hidden\n */\nfunction vtkSharedVolumeMapper(publicAPI, model) {\n model.classHierarchy.push('vtkSharedVolumeMapper');\n\n const superDelete = publicAPI.delete;\n publicAPI.delete = () => {\n model.scalarTexture = null;\n superDelete();\n };\n}\n\n// ----------------------------------------------------------------------------\n// Object factory\n// ----------------------------------------------------------------------------\n\n// ----------------------------------------------------------------------------\n\nconst DEFAULT_VALUES = {\n scalarTexture: null,\n};\n\nexport function extend(publicAPI, model, initialValues = {}) {\n Object.assign(model, DEFAULT_VALUES, initialValues);\n\n vtkVolumeMapper.extend(publicAPI, model, initialValues);\n\n macro.setGet(publicAPI, model, ['scalarTexture']);\n\n // Object methods\n vtkSharedVolumeMapper(publicAPI, model);\n}\n\n// ----------------------------------------------------------------------------\n\nexport const newInstance = macro.newInstance(extend, 'vtkSharedVolumeMapper');\n\n// ----------------------------------------------------------------------------\n\nexport default { newInstance, extend };\n","import { vtkSharedVolumeMapper } from '../vtkClasses';\n\n/**\n * Given an imageData and a vtkOpenGLTexture, it creates a \"shared\" vtk volume mapper\n * from which various volume actors can be created.\n *\n * @param imageData - the vtkImageData object that contains the data to\n * render.\n * @param vtkOpenGLTexture - The vtkOpenGLTexture that will be used to render\n * the volume.\n * @returns The volume mapper.\n */\nexport default function createVolumeMapper(\n imageData: any,\n vtkOpenGLTexture: any\n): any {\n const volumeMapper = vtkSharedVolumeMapper.newInstance();\n\n volumeMapper.setInputData(imageData);\n\n const spacing = imageData.getSpacing();\n // Set the sample distance to half the mean length of one side. This is where the divide by 6 comes from.\n // https://github.com/Kitware/VTK/blob/6b559c65bb90614fb02eb6d1b9e3f0fca3fe4b0b/Rendering/VolumeOpenGL2/vtkSmartVolumeMapper.cxx#L344\n const sampleDistance = (spacing[0] + spacing[1] + spacing[2]) / 6;\n\n // This is to allow for good pixel level image quality.\n volumeMapper.setMaximumSamplesPerRay(4000);\n\n volumeMapper.setSampleDistance(sampleDistance);\n\n volumeMapper.setScalarTexture(vtkOpenGLTexture);\n\n return volumeMapper;\n}\n","import RequestType from '../enums/RequestType';\nimport { IImage } from '../types';\nimport { uuidv4 } from '../utilities';\n\ntype AdditionalDetails = {\n imageId?: string;\n volumeId?: string;\n};\n\ntype RequestDetailsInterface = {\n requestFn: () => Promise<IImage | void>;\n type: RequestType;\n additionalDetails: AdditionalDetails;\n};\n\ntype RequestPool = {\n [name in RequestType]: { [key: number]: RequestDetailsInterface[] };\n};\n\n/**\n * RequestPool manager class is a base class that manages the request pools.\n * It is used imageRetrievalPoolManager, and imageLoadPoolManager to retrieve and load images.\n * Previously requestPoolManager was used to manage the retrieval and loading and decoding\n * of the images in a way that new requests were sent after the image was both loaded and decoded\n * which was not performant since it was waiting for the image to be loaded and decoded before\n * sending the next request which is a network request and can be done in parallel.\n * Now, we use separate imageRetrievalPoolManager and imageLoadPoolManager\n * to improve performance and both are extending the RequestPoolManager class which\n * is a basic queueing pool.\n *\n * A new requestPool can be created by instantiating a new RequestPoolManager class.\n *\n * ```javascript\n * const requestPoolManager = new RequestPoolManager()\n * ```\n *\n * ## ImageLoadPoolManager\n *\n * You can use the imageLoadPoolManager to load images, by providing a `requestFn`\n * that returns a promise for the image. You can provide a `type` to specify the type of\n * request (interaction, thumbnail, prefetch), and you can provide additional details\n * that will be passed to the requestFn. Below is an example of a requestFn that loads\n * an image from an imageId:\n *\n * ```javascript\n *\n * const priority = -5\n * const requestType = RequestType.Interaction\n * const additionalDetails = { imageId }\n * const options = {\n * targetBuffer: {\n * type: 'Float32Array',\n * offset: null,\n * length: null,\n * },\n * preScale: {\n * enabled: true,\n * },\n * }\n *\n * imageLoadPoolManager.addRequest(\n * loadAndCacheImage(imageId, options).then(() => { // set on viewport}),\n * requestType,\n * additionalDetails,\n * priority\n * )\n * ```\n * ### ImageRetrievalPoolManager\n * You don't need to directly use the imageRetrievalPoolManager to load images\n * since the imageLoadPoolManager will automatically use it for retrieval. However,\n * maximum number of concurrent requests can be set by calling `setMaxConcurrentRequests`.\n */\nclass RequestPoolManager {\n private id: string;\n private awake: boolean;\n private requestPool: RequestPool;\n private numRequests = {\n interaction: 0,\n thumbnail: 0,\n prefetch: 0,\n };\n /* maximum number of requests of each type. */\n public maxNumRequests: {\n interaction: number;\n thumbnail: number;\n prefetch: number;\n };\n /* A public property that is used to set the delay between requests. */\n public grabDelay: number;\n private timeoutHandle: number;\n\n /**\n * By default a request pool containing three priority groups, one for each\n * of the request types, is created. Maximum number of requests of each type\n * is set to 6.\n */\n constructor(id?: string) {\n this.id = id ? id : uuidv4();\n\n this.requestPool = {\n interaction: { 0: [] },\n thumbnail: { 0: [] },\n prefetch: { 0: [] },\n };\n\n this.grabDelay = 5;\n this.awake = false;\n\n this.numRequests = {\n interaction: 0,\n thumbnail: 0,\n prefetch: 0,\n };\n\n this.maxNumRequests = {\n interaction: 6,\n thumbnail: 6,\n prefetch: 5,\n };\n }\n\n /**\n * This function sets the maximum number of requests for a given request type.\n * @param type - The type of request you want to set the max number\n * of requests for it can be either of interaction, prefetch, or thumbnail.\n * @param maxNumRequests - The maximum number of requests that can be\n * made at a time.\n */\n public setMaxSimultaneousRequests(\n type: RequestType,\n maxNumRequests: number\n ): void {\n this.maxNumRequests[type] = maxNumRequests;\n }\n\n /**\n * It returns the maximum number of requests of a given type that can be made\n * @param type - The type of request.\n * @returns The maximum number of requests of a given type.\n */\n public getMaxSimultaneousRequests(type: RequestType): number {\n return this.maxNumRequests[type];\n }\n\n /**\n * Stops further fetching of the requests, all the ongoing requests will still\n * be retrieved\n */\n public destroy(): void {\n if (this.timeoutHandle) {\n window.clearTimeout(this.timeoutHandle);\n }\n }\n\n /**\n * Adds the requests to the pool of requests.\n *\n * @param requestFn - A function that returns a promise which resolves in the image\n * @param type - Priority category, it can be either of interaction, prefetch,\n * or thumbnail.\n * @param additionalDetails - Additional details that requests can contain.\n * For instance the volumeId for the volume requests\n * @param priority - Priority number for each category of requests. Its default\n * value is priority 0. The lower the priority number, the higher the priority number\n *\n */\n public addRequest(\n requestFn: () => Promise<IImage | void>,\n type: RequestType,\n additionalDetails: Record<string, unknown>,\n priority = 0\n ): void {\n // Describe the request\n const requestDetails: RequestDetailsInterface = {\n requestFn,\n type,\n additionalDetails,\n };\n\n // Check if the priority group exists on the request type\n if (this.requestPool[type][priority] === undefined) {\n this.requestPool[type][priority] = [];\n }\n\n // Adding the request to the correct priority group of the request type\n this.requestPool[type][priority].push(requestDetails);\n\n // Wake up\n if (!this.awake) {\n this.awake = true;\n this.startGrabbing();\n } else if (type === RequestType.Interaction) {\n // Todo: this is a hack for interaction right now, we should separate\n // the grabbing from the adding requests\n this.startGrabbing();\n }\n }\n\n /**\n * Filter the requestPoolManager's pool of request based on the result of\n * provided filter function. The provided filter function needs to return false or true\n *\n * @param filterFunction - The filter function for filtering of the requests to keep\n */\n public filterRequests(\n filterFunction: (requestDetails: RequestDetailsInterface) => boolean\n ): void {\n Object.keys(this.requestPool).forEach((type: string) => {\n const requestType = this.requestPool[type];\n Object.keys(requestType).forEach((priority) => {\n requestType[priority] = requestType[priority].filter(\n (requestDetails: RequestDetailsInterface) => {\n return filterFunction(requestDetails);\n }\n );\n });\n });\n }\n\n /**\n * Clears the requests specific to the provided type. For instance, the\n * pool of requests of type 'interaction' can be cleared via this function.\n *\n *\n * @param type - category of the request (either interaction, prefetch or thumbnail)\n */\n public clearRequestStack(type: string): void {\n if (!this.requestPool[type]) {\n throw new Error(`No category for the type ${type} found`);\n }\n this.requestPool[type] = { 0: [] };\n }\n\n private sendRequests(type) {\n const requestsToSend = this.maxNumRequests[type] - this.numRequests[type];\n\n for (let i = 0; i < requestsToSend; i++) {\n const requestDetails = this.getNextRequest(type);\n if (requestDetails === null) {\n return false;\n } else if (requestDetails) {\n this.numRequests[type]++;\n this.awake = true;\n\n requestDetails.requestFn().finally(() => {\n this.numRequests[type]--;\n this.startAgain();\n });\n }\n }\n\n return true;\n }\n\n private getNextRequest(type): RequestDetailsInterface | null {\n const interactionPriorities = this.getSortedPriorityGroups(type);\n for (const priority of interactionPriorities) {\n if (this.requestPool[type][priority].length) {\n return this.requestPool[type][priority].shift();\n }\n }\n\n return null;\n }\n\n protected startGrabbing(): void {\n const hasRemainingInteractionRequests = this.sendRequests(\n RequestType.Interaction\n );\n const hasRemainingThumbnailRequests = this.sendRequests(\n RequestType.Thumbnail\n );\n const hasRemainingPrefetchRequests = this.sendRequests(\n RequestType.Prefetch\n );\n\n if (\n !hasRemainingInteractionRequests &&\n !hasRemainingThumbnailRequests &&\n !hasRemainingPrefetchRequests\n ) {\n this.awake = false;\n }\n }\n\n protected startAgain(): void {\n if (!this.awake) {\n return;\n }\n\n if (this.grabDelay !== undefined) {\n this.timeoutHandle = window.setTimeout(() => {\n this.startGrabbing();\n }, this.grabDelay);\n } else {\n this.startGrabbing();\n }\n }\n\n protected getSortedPriorityGroups(type: string): Array<number> {\n const priorities = Object.keys(this.requestPool[type])\n .map(Number)\n .filter((priority) => this.requestPool[type][priority].length)\n .sort();\n return priorities;\n }\n\n /**\n * Returns the request pool containing different categories, their priority and\n * the added request details.\n *\n * @returns the request pool which contains different categories, their priority and\n * the added request details\n */\n getRequestPool(): RequestPool {\n return this.requestPool;\n }\n}\n\nconst requestPoolManager = new RequestPoolManager();\n\nexport { RequestPoolManager };\nexport default requestPoolManager;\n","import { RequestPoolManager } from './requestPoolManager';\nimport RequestType from '../enums/RequestType';\n\n/**\n * You can use the imageLoadPoolManager to load images, by providing a `requestFn`\n * that returns a promise for the image. You can provide a `type` to specify the type of\n * request (interaction, thumbnail, prefetch), and you can provide additional details\n * that will be passed to the requestFn. Below is an example of a requestFn that loads\n * an image from an imageId:\n *\n * ```javascript\n *\n * const priority = -5\n * const requestType = RequestType.Interaction\n * const additionalDetails = { imageId }\n * const options = {\n * targetBuffer: {\n * type: 'Float32Array',\n * offset: null,\n * length: null,\n * },\n * preScale: {\n * enabled: true,\n * },\n * }\n *\n * imageLoadPoolManager.addRequest(\n * loadAndCacheImage(imageId, options).then(() => { // set on viewport}),\n * requestType,\n * additionalDetails,\n * priority\n * )\n * ```\n */\nconst imageLoadPoolManager = new RequestPoolManager('imageLoadPool');\n\nimageLoadPoolManager.grabDelay = 0;\n\nimageLoadPoolManager.setMaxSimultaneousRequests(RequestType.Interaction, 1000);\nimageLoadPoolManager.setMaxSimultaneousRequests(RequestType.Thumbnail, 1000);\nimageLoadPoolManager.setMaxSimultaneousRequests(RequestType.Prefetch, 1000);\n\nexport default imageLoadPoolManager;\n","import cache from './cache/cache';\nimport Events from './enums/Events';\nimport eventTarget from './eventTarget';\nimport { triggerEvent } from './utilities';\nimport { IImage, ImageLoaderFn, IImageLoadObject, EventTypes } from './types';\nimport imageLoadPoolManager from './requestPool/imageLoadPoolManager';\n\nexport interface ImageLoaderOptions {\n priority: number;\n requestType: string;\n additionalDetails?: Record<string, unknown>;\n}\n/**\n * This module deals with ImageLoaders, loading images and caching images\n */\nconst imageLoaders = {};\nlet unknownImageLoader;\n\n/**\n * Loads an image using a registered Cornerstone Image Loader.\n *\n * The image loader that is used will be\n * determined by the image loader scheme matching against the imageId.\n *\n * @param imageId - A Cornerstone Image Object's imageId\n * @param Options - to be passed to the Image Loader\n *\n * @returns - An Object which can be used to act after an image is loaded or loading fails\n */\nfunction loadImageFromImageLoader(\n imageId: string,\n options: ImageLoaderOptions\n): IImageLoadObject {\n // Extract the image loader scheme: wadors:https://image1 => wadors\n const colonIndex = imageId.indexOf(':');\n const scheme = imageId.substring(0, colonIndex);\n const loader = imageLoaders[scheme];\n if (loader === undefined || loader === null) {\n if (unknownImageLoader !== undefined) {\n return unknownImageLoader(imageId);\n }\n throw new Error('loadImageFromImageLoader: no image loader for imageId');\n }\n // Load using the registered loader\n const imageLoadObject = loader(imageId, options);\n // Broadcast an image loaded event once the image is loaded\n imageLoadObject.promise.then(\n function (image) {\n triggerEvent(eventTarget, Events.IMAGE_LOADED, { image });\n },\n function (error) {\n const errorObject: EventTypes.ImageLoadedFailedEventDetail = {\n imageId,\n error,\n };\n triggerEvent(eventTarget, Events.IMAGE_LOAD_FAILED, errorObject);\n }\n );\n return imageLoadObject;\n}\n\n/**\n * Gets the imageLoadObject by 1) Looking in to the cache to see if the\n * imageLoadObject has already been cached, 2) Checks inside the volume cache\n * to see if there is a volume that contains the same imageURI for the requested\n * imageID 3) Checks inside the imageCache for similar imageURI that might have\n * been stored as a result of decaching a volume 4) Finally if none were found\n * it request it from the registered imageLoaders.\n *\n * @param imageId - A Cornerstone Image Object's imageId\n * @param options - Options to be passed to the Image Loader\n *\n * @returns An Object which can be used to act after an image is loaded or loading fails\n */\nfunction loadImageFromCacheOrVolume(\n imageId: string,\n options: ImageLoaderOptions\n): IImageLoadObject {\n // 1. Check inside the image cache for imageId\n let imageLoadObject = cache.getImageLoadObject(imageId);\n if (imageLoadObject !== undefined) {\n return imageLoadObject;\n }\n // 2. Check if there exists a volume in the cache containing the imageId,\n // we copy the pixelData over.\n const cachedVolumeInfo = cache.getVolumeContainingImageId(imageId);\n if (cachedVolumeInfo && cachedVolumeInfo.volume.loadStatus.loaded) {\n // 2.1 Convert the volume at the specific slice to a cornerstoneImage object.\n // this will copy the pixel data over.\n const { volume, imageIdIndex } = cachedVolumeInfo;\n imageLoadObject = volume.convertToCornerstoneImage(imageId, imageIdIndex);\n return imageLoadObject;\n }\n // 3. If no volume found, we search inside the imageCache for the imageId\n // that has the same URI which had been cached if the volume was converted\n // to an image\n const cachedImage = cache.getCachedImageBasedOnImageURI(imageId);\n if (cachedImage) {\n imageLoadObject = cachedImage.imageLoadObject;\n return imageLoadObject;\n }\n // 4. if not in image cache nor inside the volume cache, we request the\n // image loaders to load it\n imageLoadObject = loadImageFromImageLoader(imageId, options);\n\n return imageLoadObject;\n}\n\n/**\n * Loads an image given an imageId and optional priority and returns a promise\n * which will resolve to the loaded image object or fail if an error occurred.\n * The loaded image is not stored in the cache.\n *\n *\n * @param imageId - A Cornerstone Image Object's imageId\n * @param options - Options to be passed to the Image Loader\n *\n * @returns An Object which can be used to act after an image is loaded or loading fails\n */\nexport function loadImage(\n imageId: string,\n options: ImageLoaderOptions = { priority: 0, requestType: 'prefetch' }\n): Promise<IImage> {\n if (imageId === undefined) {\n throw new Error('loadImage: parameter imageId must not be undefined');\n }\n\n return loadImageFromCacheOrVolume(imageId, options).promise;\n}\n\n/**\n * Loads an image given an imageId and optional priority and returns a promise\n * which will resolve to the loaded image object or fail if an error occurred.\n * The image is stored in the cache.\n *\n * @param imageId - A Cornerstone Image Object's imageId\n * @param options - Options to be passed to the Image Loader\n *\n * @returns Image Loader Object\n */\nexport function loadAndCacheImage(\n imageId: string,\n options: ImageLoaderOptions = { priority: 0, requestType: 'prefetch' }\n): Promise<IImage> {\n if (imageId === undefined) {\n throw new Error(\n 'loadAndCacheImage: parameter imageId must not be undefined'\n );\n }\n const imageLoadObject = loadImageFromCacheOrVolume(imageId, options);\n\n // if not inside cache, store it\n if (!cache.getImageLoadObject(imageId)) {\n cache.putImageLoadObject(imageId, imageLoadObject).catch((err) => {\n console.warn(err);\n });\n }\n\n return imageLoadObject.promise;\n}\n\n/**\n * Load and cache a list of imageIds\n *\n * @param imageIds - list of imageIds\n * @param options - options for loader\n *\n */\nexport function loadAndCacheImages(\n imageIds: Array<string>,\n options: ImageLoaderOptions = { priority: 0, requestType: 'prefetch' }\n): Promise<IImage>[] {\n if (!imageIds || imageIds.length === 0) {\n throw new Error(\n 'loadAndCacheImages: parameter imageIds must be list of image Ids'\n );\n }\n\n const allPromises = imageIds.map((imageId) => {\n return loadAndCacheImage(imageId, options);\n });\n\n return allPromises;\n}\n\n/**\n * Removes the imageId from the request pool manager and executes the `cancel`\n * function if it exists.\n *\n * @param imageId - A Cornerstone Image Object's imageId\n *\n */\nexport function cancelLoadImage(imageId: string): void {\n const filterFunction = ({ additionalDetails }) => {\n if (additionalDetails.imageId) {\n return additionalDetails.imageId !== imageId;\n }\n\n // for volumes\n return true;\n };\n\n // Instruct the request pool manager to filter queued\n // requests to ensure requests we no longer need are\n // no longer sent.\n imageLoadPoolManager.filterRequests(filterFunction);\n\n // TODO: Cancel decoding and retrieval as well (somehow?)\n\n // cancel image loading if in progress\n const imageLoadObject = cache.getImageLoadObject(imageId);\n\n if (imageLoadObject) {\n imageLoadObject.cancelFn();\n }\n}\n\n/**\n * Removes the imageIds from the request pool manager and calls the `cancel`\n * function if it exists.\n *\n * @param imageIds - Array of Cornerstone Image Object's imageIds\n *\n */\nexport function cancelLoadImages(imageIds: Array<string>): void {\n imageIds.forEach((imageId) => cancelLoadImage(imageId));\n}\n\n/**\n * Removes all the ongoing image loads by calling the `cancel` method on each\n * imageLoadObject. If no `cancel` method is available, it will be ignored.\n *\n */\nexport function cancelLoadAll(): void {\n const requestPool = imageLoadPoolManager.getRequestPool();\n\n Object.keys(requestPool).forEach((type: string) => {\n const requests = requestPool[type];\n\n Object.keys(requests).forEach((priority) => {\n const requestDetails = requests[priority].pop();\n const { imageId, volumeId } = requestDetails.additionalDetails;\n\n let loadObject;\n\n if (imageId) {\n loadObject = cache.getImageLoadObject(imageId);\n } else if (volumeId) {\n loadObject = cache.getVolumeLoadObject(volumeId);\n }\n if (loadObject) {\n loadObject.cancel();\n }\n });\n // resetting the pool types to be empty\n imageLoadPoolManager.clearRequestStack(type);\n\n // TODO: Clear retrieval and decoding queues as well\n });\n}\n\n/**\n * Registers an imageLoader plugin with cornerstone for the specified scheme\n *\n * @param scheme - The scheme to use for this image loader (e.g. 'dicomweb', 'wadouri', 'http')\n * @param imageLoader - A Cornerstone Image Loader function\n */\nexport function registerImageLoader(\n scheme: string,\n imageLoader: ImageLoaderFn\n): void {\n imageLoaders[scheme] = imageLoader;\n}\n/**\n * Registers a new unknownImageLoader and returns the previous one\n *\n * @param imageLoader - A Cornerstone Image Loader\n *\n * @returns The previous Unknown Image Loader\n */\nexport function registerUnknownImageLoader(\n imageLoader: ImageLoaderFn\n): ImageLoaderFn {\n const oldImageLoader = unknownImageLoader;\n unknownImageLoader = imageLoader;\n return oldImageLoader;\n}\n/**\n * Removes all registered and unknown image loaders. This should be called\n * when the application is unmounted to prevent memory leaks.\n *\n */\nexport function unregisterAllImageLoaders(): void {\n Object.keys(imageLoaders).forEach(\n (imageLoader) => delete imageLoaders[imageLoader]\n );\n unknownImageLoader = undefined;\n}\n","// This module defines a way to access various metadata about an imageId. This layer of abstraction exists\n// So metadata can be provided in different ways (e.g. by parsing DICOM P10 or by a WADO-RS document)\n\nconst providers = [];\n\n/**\n * Adds a metadata provider with the specified priority\n * @param provider - Metadata provider function\n * @param priority - 0 is default/normal, > 0 is high, < 0 is low\n *\n * @category MetaData\n */\nexport function addProvider(\n provider: (type: string, query: any) => any,\n priority = 0\n): void {\n let i;\n\n // Find the right spot to insert this provider based on priority\n for (i = 0; i < providers.length; i++) {\n if (providers[i].priority <= priority) {\n break;\n }\n }\n\n // Insert the decode task at position i\n providers.splice(i, 0, {\n priority,\n provider,\n });\n}\n\n/**\n * Removes the specified provider\n *\n * @param provider - Metadata provider function\n *\n * @category MetaData\n */\nexport function removeProvider(\n provider: (type: string, query: any) => { any }\n): void {\n for (let i = 0; i < providers.length; i++) {\n if (providers[i].provider === provider) {\n providers.splice(i, 1);\n\n break;\n }\n }\n}\n\n/**\n * Removes all providers\n *\n * @category MetaData\n */\nexport function removeAllProviders(): void {\n while (providers.length > 0) {\n providers.pop();\n }\n}\n\n/**\n * Gets metadata from the registered metadata providers. Will call each one from highest priority to lowest\n * until one responds\n *\n * @param type - The type of metadata requested from the metadata store\n * @param query - The query for the metadata store, often imageId\n *\n * @returns The metadata retrieved from the metadata store\n * @category MetaData\n */\nfunction getMetaData(type: string, query: string): any {\n // Invoke each provider in priority order until one returns something\n for (let i = 0; i < providers.length; i++) {\n const result = providers[i].provider(type, query);\n\n if (result !== undefined) {\n return result;\n }\n }\n}\n\nexport { getMetaData as get };\n","/**\n * Given a low and high window level, return the window width and window center\n * @param low - The low window level.\n * @param high - The high window level.\n * @returns a JavaScript object with two properties: windowWidth and windowCenter.\n */\nfunction toWindowLevel(\n low: number,\n high: number\n): {\n windowWidth: number;\n windowCenter: number;\n} {\n const windowWidth = Math.abs(low - high);\n const windowCenter = low + windowWidth / 2;\n\n return { windowWidth, windowCenter };\n}\n\n/**\n * Given a window width and center, return the lower and upper bounds of the window\n * @param windowWidth - the width of the window in HU\n * @param windowCenter - The center of the window.\n * @returns a JavaScript object with two properties: lower and upper.\n */\nfunction toLowHighRange(\n windowWidth: number,\n windowCenter: number\n): {\n lower: number;\n upper: number;\n} {\n const lower = windowCenter - windowWidth / 2.0;\n const upper = windowCenter + windowWidth / 2.0;\n\n return { lower, upper };\n}\n\nexport { toWindowLevel, toLowHighRange };\n","/**\n * Calculate the minimum and maximum values in an Array\n *\n * @param storedPixelData - The pixel data to calculate the min and max values for\n * @returns an object with two properties: min and max\n */\nexport default function getMinMax(storedPixelData: number[]): {\n min: number;\n max: number;\n} {\n // we always calculate the min max values since they are not always\n // present in DICOM and we don't want to trust them anyway as cornerstone\n // depends on us providing reliable values for these\n let min = storedPixelData[0];\n\n let max = storedPixelData[0];\n\n let storedPixel;\n const numPixels = storedPixelData.length;\n\n for (let index = 1; index < numPixels; index++) {\n storedPixel = storedPixelData[index];\n min = Math.min(min, storedPixel);\n max = Math.max(max, storedPixel);\n }\n\n return {\n min,\n max,\n };\n}\n","import {\n VolumeActor,\n IImageVolume,\n VOIRange,\n ScalingParameters,\n} from '../../types';\nimport { loadAndCacheImage } from '../../imageLoader';\nimport * as metaData from '../../metaData';\nimport { getMinMax, windowLevel } from '../../utilities';\nimport { RequestType } from '../../enums';\n\nconst PRIORITY = 0;\nconst REQUEST_TYPE = RequestType.Prefetch;\n\n/**\n * It sets the default window level of an image volume based on the VOI.\n * It first look for the VOI in the metadata and if it is not found, it\n * loads the middle slice image (middle imageId) and based on its min\n * and max pixel values, it calculates the VOI.\n * Finally it sets the VOI on the volumeActor transferFunction\n * @param volumeActor - The volume actor\n * @param imageVolume - The image volume that we want to set the VOI for.\n */\nasync function setDefaultVolumeVOI(\n volumeActor: VolumeActor,\n imageVolume: IImageVolume\n): Promise<void> {\n let voi = getVOIFromMetadata(imageVolume);\n\n if (!voi) {\n voi = await getVOIFromMinMax(imageVolume);\n }\n\n if (!voi || voi.lower === undefined || voi.upper === undefined) {\n throw new Error(\n 'Could not get VOI from metadata, nor from the min max of the image middle slice'\n );\n }\n\n voi = handlePreScaledVolume(imageVolume, voi);\n const { lower, upper } = voi;\n\n volumeActor\n .getProperty()\n .getRGBTransferFunction(0)\n .setMappingRange(lower, upper);\n}\n\nfunction handlePreScaledVolume(imageVolume: IImageVolume, voi: VOIRange) {\n const imageIds = imageVolume.imageIds;\n const imageIdIndex = Math.floor(imageIds.length / 2);\n const imageId = imageIds[imageIdIndex];\n\n const generalSeriesModule =\n metaData.get('generalSeriesModule', imageId) || {};\n\n /**\n * If the volume is prescaled and the modality is PT Sometimes you get super high\n * values at the peak and it skews the min/max so nothing useful is displayed\n * Therefore, we follow the majority of other viewers and we set the min/max\n * for the scaled PT to be 0, 5\n */\n if (generalSeriesModule.modality === 'PT' && imageVolume.isPrescaled) {\n return {\n lower: 0,\n upper: 5,\n };\n }\n\n return voi;\n}\n\n/**\n * Get the VOI from the metadata of the middle slice of the image volume. It checks\n * the metadata for the VOI and if it is not found, it returns null\n *\n * @param imageVolume - The image volume that we want to get the VOI from.\n * @returns VOIRange with lower and upper values\n */\nfunction getVOIFromMetadata(imageVolume: IImageVolume): VOIRange {\n const { imageIds } = imageVolume;\n\n const imageIdIndex = Math.floor(imageIds.length / 2);\n const imageId = imageIds[imageIdIndex];\n\n const voiLutModule = metaData.get('voiLutModule', imageId);\n\n if (voiLutModule && voiLutModule.windowWidth && voiLutModule.windowCenter) {\n const { windowWidth, windowCenter } = voiLutModule;\n\n const voi = {\n windowWidth: Array.isArray(windowWidth) ? windowWidth[0] : windowWidth,\n windowCenter: Array.isArray(windowCenter)\n ? windowCenter[0]\n : windowCenter,\n };\n\n const { lower, upper } = windowLevel.toLowHighRange(\n Number(voi.windowWidth),\n Number(voi.windowCenter)\n );\n\n return {\n lower,\n upper,\n };\n }\n}\n\n/**\n * It loads the middle slice image (middle imageId) and based on its min\n * and max pixel values, it calculates the VOI.\n *\n * @param imageVolume - The image volume that we want to get the VOI from.\n * @returns The VOIRange with lower and upper values\n */\nasync function getVOIFromMinMax(imageVolume: IImageVolume): Promise<VOIRange> {\n const { scalarData, imageIds } = imageVolume;\n\n // Get the middle image from the list of imageIds\n const imageIdIndex = Math.floor(imageIds.length / 2);\n const imageId = imageVolume.imageIds[imageIdIndex];\n const generalSeriesModule =\n metaData.get('generalSeriesModule', imageId) || {};\n const { modality } = generalSeriesModule;\n const modalityLutModule = metaData.get('modalityLutModule', imageId) || {};\n\n const numImages = imageIds.length;\n const bytesPerImage = scalarData.byteLength / numImages;\n const voxelsPerImage = scalarData.length / numImages;\n const bytePerPixel = scalarData.BYTES_PER_ELEMENT;\n\n let type;\n\n if (scalarData instanceof Uint8Array) {\n type = 'Uint8Array';\n } else if (scalarData instanceof Float32Array) {\n type = 'Float32Array';\n } else {\n throw new Error('Unsupported array type');\n }\n\n const scalingParameters: ScalingParameters = {\n rescaleSlope: modalityLutModule.rescaleSlope,\n rescaleIntercept: modalityLutModule.rescaleIntercept,\n modality,\n };\n\n let scalingParametersToUse;\n if (modality === 'PT') {\n const suvFactor = metaData.get('scalingModule', imageId);\n\n if (suvFactor) {\n scalingParametersToUse = {\n ...scalingParameters,\n suvbw: suvFactor.suvbw,\n };\n }\n }\n\n const byteOffset = imageIdIndex * bytesPerImage;\n\n const options = {\n targetBuffer: {\n arrayBuffer: scalarData.buffer,\n offset: byteOffset,\n length: voxelsPerImage,\n type,\n },\n priority: PRIORITY,\n requestType: REQUEST_TYPE,\n preScale: {\n enabled: true,\n scalingParameters: scalingParametersToUse,\n },\n };\n\n // Loading the middle slice image for a volume has two scenarios, the first one is that\n // uses the same volumeLoader which might not resolve to an image (since for performance\n // reasons volumes' pixelData is set via offset and length on the volume arrayBuffer\n // when each slice is loaded). The second scenario is that the image might not reach\n // to the volumeLoader, and an already cached image (with Image object) is used\n // instead. For the first scenario, we use the arrayBuffer of the volume to get the correct\n // slice for the imageScalarData, and for the second scenario we use the getPixelData\n // on the Cornerstone IImage object to get the pixel data.\n const image = await loadAndCacheImage(imageId, options);\n\n let imageScalarData;\n if (!image) {\n imageScalarData = _getImageScalarDataFromImageVolume(\n imageVolume,\n byteOffset,\n bytePerPixel,\n voxelsPerImage\n );\n } else {\n imageScalarData = image.getPixelData();\n }\n\n // Get the min and max pixel values of the middle slice\n const { min, max } = getMinMax(imageScalarData);\n\n return {\n lower: min,\n upper: max,\n };\n}\n\nfunction _getImageScalarDataFromImageVolume(\n imageVolume,\n byteOffset,\n bytePerPixel,\n voxelsPerImage\n) {\n const { scalarData } = imageVolume;\n const { volumeBuffer } = scalarData;\n if (scalarData.BYTES_PER_ELEMENT !== bytePerPixel) {\n byteOffset *= scalarData.BYTES_PER_ELEMENT / bytePerPixel;\n }\n\n const TypedArray = scalarData.constructor;\n const imageScalarData = new TypedArray(voxelsPerImage);\n\n const volumeBufferView = new TypedArray(\n volumeBuffer,\n byteOffset,\n voxelsPerImage\n );\n\n imageScalarData.set(volumeBufferView);\n\n return imageScalarData;\n}\n\nexport default setDefaultVolumeVOI;\n","import vtkVolume from '@kitware/vtk.js/Rendering/Core/Volume';\n\nimport { VolumeActor } from './../../types/IActor';\nimport { VoiModifiedEventDetail } from './../../types/EventTypes';\nimport { loadVolume } from '../../volumeLoader';\nimport createVolumeMapper from './createVolumeMapper';\nimport BlendModes from '../../enums/BlendModes';\nimport { triggerEvent } from '../../utilities';\nimport { Events } from '../../enums';\nimport setDefaultVolumeVOI from './setDefaultVolumeVOI';\n\ninterface createVolumeActorInterface {\n volumeId: string;\n callback?: ({\n volumeActor,\n volumeId,\n }: {\n volumeActor: VolumeActor;\n volumeId: string;\n }) => void;\n blendMode?: BlendModes;\n}\n\n/**\n * Given a volumeId, it creates a vtk volume actor and returns it. If\n * callback is provided, it will be called with the volume actor and the\n * volumeId. If blendMode is provided, it will be set on the volume actor.\n *\n * @param props - createVolumeActorInterface\n * @returns A promise that resolves to a VolumeActor.\n */\nasync function createVolumeActor(\n props: createVolumeActorInterface,\n element: HTMLDivElement,\n viewportId: string,\n suppressEvents = false\n): Promise<VolumeActor> {\n const { volumeId, callback, blendMode } = props;\n\n const imageVolume = await loadVolume(volumeId);\n\n if (!imageVolume) {\n throw new Error(\n `imageVolume with id: ${imageVolume.volumeId} does not exist`\n );\n }\n\n const { imageData, vtkOpenGLTexture } = imageVolume;\n\n const volumeMapper = createVolumeMapper(imageData, vtkOpenGLTexture);\n\n if (blendMode) {\n volumeMapper.setBlendMode(blendMode);\n }\n\n const volumeActor = vtkVolume.newInstance();\n volumeActor.setMapper(volumeMapper);\n\n // If the volume is composed of imageIds, we can apply a default VOI based\n // on either the metadata or the min/max of the middle slice. Example of other\n // types of volumes which might not be composed of imageIds would be e.g., nrrd, nifti\n // format volumes\n if (imageVolume.imageIds) {\n await setDefaultVolumeVOI(volumeActor, imageVolume);\n }\n\n if (callback) {\n callback({ volumeActor, volumeId });\n }\n\n if (!suppressEvents) {\n triggerVOIModified(element, viewportId, volumeActor, volumeId);\n }\n\n return volumeActor;\n}\n\nfunction triggerVOIModified(\n element: HTMLDivElement,\n viewportId: string,\n volumeActor: VolumeActor,\n volumeId: string\n) {\n const voiRange = volumeActor\n .getProperty()\n .getRGBTransferFunction(0)\n // @ts-ignore: vtk d ts problem\n .getRange();\n\n const voiModifiedEventDetail: VoiModifiedEventDetail = {\n viewportId,\n range: {\n lower: voiRange[0],\n upper: voiRange[1],\n },\n volumeId,\n };\n\n triggerEvent(element, Events.VOI_MODIFIED, voiModifiedEventDetail);\n}\n\nexport default createVolumeActor;\n","const VIEWPORT_ELEMENT = 'viewport-element';\nconst CANVAS_CSS_CLASS = 'cornerstone-canvas';\n\n/**\n * Create a canvas and append it to the element\n *\n * @param element - An HTML Element\n * @returns canvas - A Canvas DOM element\n */\nfunction createCanvas(element: Element | HTMLDivElement): HTMLCanvasElement {\n const canvas = document.createElement('canvas');\n\n canvas.style.position = 'absolute';\n canvas.style.width = '100%';\n canvas.style.height = '100%';\n canvas.classList.add(CANVAS_CSS_CLASS);\n element.appendChild(canvas);\n\n return canvas;\n}\n\n/**\n * Creates an internal div that will contain canvas and SVG layer as children\n * @param element - An HTML Element\n * @returns div Cornerstone internal div that will include the canvas and SVG\n * as its children\n */\nexport function createViewportElement(element: HTMLDivElement): HTMLDivElement {\n const div = document.createElement('div');\n div.style.position = 'relative';\n div.style.width = '100%';\n div.style.height = '100%';\n div.classList.add(VIEWPORT_ELEMENT);\n element.appendChild(div);\n\n return div;\n}\n\n/**\n * Create a canvas or returns the one that already exists for a given element.\n * It first checks if the element has a canvas, if not it creates one and returns it.\n *\n * @param element - An HTML Element\n * @returns canvas a Canvas DOM element\n */\nexport default function getOrCreateCanvas(\n element: HTMLDivElement\n): HTMLCanvasElement {\n const canvasSelector = `canvas.${CANVAS_CSS_CLASS}`;\n const viewportElement = `div.${VIEWPORT_ELEMENT}`;\n\n // Internal div with `relative` positioning to enable absolute positioning\n // of the canvas and svg layer.\n const internalDiv =\n element.querySelector(viewportElement) || createViewportElement(element);\n\n return internalDiv.querySelector(canvasSelector) || createCanvas(internalDiv);\n}\n","export default function _arrayLikeToArray(arr, len) {\n if (len == null || len > arr.length) len = arr.length;\n\n for (var i = 0, arr2 = new Array(len); i < len; i++) {\n arr2[i] = arr[i];\n }\n\n return arr2;\n}","import arrayLikeToArray from \"./arrayLikeToArray.js\";\nexport default function _unsupportedIterableToArray(o, minLen) {\n if (!o) return;\n if (typeof o === \"string\") return arrayLikeToArray(o, minLen);\n var n = Object.prototype.toString.call(o).slice(8, -1);\n if (n === \"Object\" && o.constructor) n = o.constructor.name;\n if (n === \"Map\" || n === \"Set\") return Array.from(o);\n if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return arrayLikeToArray(o, minLen);\n}","import arrayWithoutHoles from \"./arrayWithoutHoles.js\";\nimport iterableToArray from \"./iterableToArray.js\";\nimport unsupportedIterableToArray from \"./unsupportedIterableToArray.js\";\nimport nonIterableSpread from \"./nonIterableSpread.js\";\nexport default function _toConsumableArray(arr) {\n return arrayWithoutHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableSpread();\n}","import arrayLikeToArray from \"./arrayLikeToArray.js\";\nexport default function _arrayWithoutHoles(arr) {\n if (Array.isArray(arr)) return arrayLikeToArray(arr);\n}","export default function _iterableToArray(iter) {\n if (typeof Symbol !== \"undefined\" && iter[Symbol.iterator] != null || iter[\"@@iterator\"] != null) return Array.from(iter);\n}","export default function _nonIterableSpread() {\n throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}","import type { IRenderingEngine } from '../types';\n\nconst cache = {};\n\nconst renderingEngineCache = {\n /**\n * Returns the `RenderingEngine` instance with the given `id`.\n *\n * @param id - The `id` of the `RenderingEngine` instance to fetch.\n * @returns The `RenderingEngine` instance.\n */\n get: (id: string): IRenderingEngine => {\n return cache[id];\n },\n /**\n * Adds the `RenderingEngine` instance to the cache.\n *\n * @param re - The `RenderingEngine` to add.\n */\n set: (re: IRenderingEngine): void => {\n const renderingEngineId = re.id;\n\n cache[renderingEngineId] = re;\n },\n /**\n * Deletes the `RenderingEngine` instance from the cache.\n *\n * @param id - The `id` of the `RenderingEngine` instance to delete.\n * @returns True if the delete was successful.\n */\n delete: (id: string) => {\n return delete cache[id];\n },\n\n getAll: (): Array<IRenderingEngine> => {\n const renderingEngineIds = Object.keys(cache);\n const renderingEngines = renderingEngineIds.map((id) => cache[id]);\n\n return renderingEngines;\n },\n};\n\nexport default renderingEngineCache;\n","import { mat3, mat4, vec3 } from 'gl-matrix';\nimport macro from '@kitware/vtk.js/macros';\nimport vtkOpenGLVolumeMapper from '@kitware/vtk.js/Rendering/OpenGL/VolumeMapper';\nimport { Filter } from '@kitware/vtk.js/Rendering/OpenGL/Texture/Constants';\nimport { VtkDataTypes } from '@kitware/vtk.js/Common/Core/DataArray/Constants';\nimport vtkDataArray from '@kitware/vtk.js/Common/Core/DataArray';\nimport { Representation } from '@kitware/vtk.js/Rendering/Core/Property/Constants';\n\nconst { vtkWarningMacro } = macro;\n/**\n * vtkStreamingOpenGLVolumeMapper - A dervied class of the core vtkOpenGLVolumeMapper class.\n * This class replaces the buildBufferObjects function so that we progressively upload our textures\n * into GPU memory using the new methods on vtkStreamingOpenGLTexture.\n *\n *\n * @param {*} publicAPI The public API to extend\n * @param {*} model The private model to extend.\n */\nfunction vtkStreamingOpenGLVolumeMapper(publicAPI, model) {\n model.classHierarchy.push('vtkStreamingOpenGLVolumeMapper');\n\n /**\n * buildBufferObjects - A fork of vtkOpenGLVolumeMapper's buildBufferObjects method.\n * This fork performs most of the same actions, but builds the textures progressively using\n * vtkStreamingOpenGLTexture's methods, and also prevents recomputation of the texture for each\n * vtkStreamingOpenGLVolumeMapper using the texture.\n *\n *\n * @param {*} ren The renderer.\n * @param {*} actor The actor to build the buffer objects for.\n */\n publicAPI.buildBufferObjects = (ren, actor) => {\n const image = model.currentInput;\n if (!image) {\n return;\n }\n\n const scalars = image.getPointData() && image.getPointData().getScalars();\n if (!scalars) {\n return;\n }\n\n const vprop = actor.getProperty();\n\n if (!model.jitterTexture.getHandle()) {\n const oTable = new Uint8Array(32 * 32);\n for (let i = 0; i < 32 * 32; ++i) {\n oTable[i] = 255.0 * Math.random();\n }\n model.jitterTexture.setMinificationFilter(Filter.LINEAR);\n model.jitterTexture.setMagnificationFilter(Filter.LINEAR);\n model.jitterTexture.create2DFromRaw(\n 32,\n 32,\n 1,\n VtkDataTypes.UNSIGNED_CHAR,\n oTable\n );\n }\n\n const numComp = scalars.getNumberOfComponents();\n const iComps = vprop.getIndependentComponents();\n const numIComps = iComps ? numComp : 1;\n\n // rebuild opacity tfun?\n let toString = `${vprop.getMTime()}`;\n if (model.opacityTextureString !== toString) {\n const oWidth = 1024;\n const oSize = oWidth * 2 * numIComps;\n const ofTable = new Float32Array(oSize);\n const tmpTable = new Float32Array(oWidth);\n\n for (let c = 0; c < numIComps; ++c) {\n const ofun = vprop.getScalarOpacity(c);\n const opacityFactor =\n model.renderable.getSampleDistance() /\n vprop.getScalarOpacityUnitDistance(c);\n\n const oRange = ofun.getRange();\n ofun.getTable(oRange[0], oRange[1], oWidth, tmpTable, 1);\n // adjust for sample distance etc\n for (let i = 0; i < oWidth; ++i) {\n ofTable[c * oWidth * 2 + i] =\n 1.0 - (1.0 - tmpTable[i]) ** opacityFactor;\n ofTable[c * oWidth * 2 + i + oWidth] = ofTable[c * oWidth * 2 + i];\n }\n }\n\n model.opacityTexture.releaseGraphicsResources(model._openGLRenderWindow);\n model.opacityTexture.setMinificationFilter(Filter.LINEAR);\n model.opacityTexture.setMagnificationFilter(Filter.LINEAR);\n\n // use float texture where possible because we really need the resolution\n // for this table. Errors in low values of opacity accumulate to\n // visible artifacts. High values of opacity quickly terminate without\n // artifacts.\n if (\n model._openGLRenderWindow.getWebgl2() ||\n (model.context.getExtension('OES_texture_float') &&\n model.context.getExtension('OES_texture_float_linear'))\n ) {\n model.opacityTexture.create2DFromRaw(\n oWidth,\n 2 * numIComps,\n 1,\n VtkDataTypes.FLOAT,\n ofTable\n );\n } else {\n const oTable = new Uint8Array(oSize);\n for (let i = 0; i < oSize; ++i) {\n oTable[i] = 255.0 * ofTable[i];\n }\n model.opacityTexture.create2DFromRaw(\n oWidth,\n 2 * numIComps,\n 1,\n VtkDataTypes.UNSIGNED_CHAR,\n oTable\n );\n }\n model.opacityTextureString = toString;\n }\n\n // rebuild color tfun?\n toString = `${vprop.getMTime()}`;\n\n if (model.colorTextureString !== toString) {\n const cWidth = 1024;\n const cSize = cWidth * 2 * numIComps * 3;\n const cTable = new Uint8Array(cSize);\n const tmpTable = new Float32Array(cWidth * 3);\n\n for (let c = 0; c < numIComps; ++c) {\n const cfun = vprop.getRGBTransferFunction(c);\n const cRange = cfun.getRange();\n cfun.getTable(cRange[0], cRange[1], cWidth, tmpTable, 1);\n for (let i = 0; i < cWidth * 3; ++i) {\n cTable[c * cWidth * 6 + i] = 255.0 * tmpTable[i];\n cTable[c * cWidth * 6 + i + cWidth * 3] = 255.0 * tmpTable[i];\n }\n }\n\n model.colorTexture.releaseGraphicsResources(model._openGLRenderWindow);\n model.colorTexture.setMinificationFilter(Filter.LINEAR);\n model.colorTexture.setMagnificationFilter(Filter.LINEAR);\n\n model.colorTexture.create2DFromRaw(\n cWidth,\n 2 * numIComps,\n 3,\n VtkDataTypes.UNSIGNED_CHAR,\n cTable\n );\n model.colorTextureString = toString;\n }\n\n // rebuild the scalarTexture if the data has changed\n toString = `${image.getMTime()}`;\n\n if (model.scalarTextureString !== toString) {\n // Build the textures\n const dims = image.getDimensions();\n\n const previousTextureParameters =\n model.scalarTexture.getTextureParameters();\n\n const dataType = image.getPointData().getScalars().getDataType();\n const data = image.getPointData().getScalars().getData();\n\n let shouldReset = true;\n\n if (\n previousTextureParameters.dataType &&\n previousTextureParameters.dataType === dataType\n ) {\n const previousTextureSize =\n previousTextureParameters.width *\n previousTextureParameters.height *\n previousTextureParameters.depth *\n previousTextureParameters.numComps;\n if (data.length === previousTextureSize) {\n shouldReset = false;\n }\n }\n\n if (shouldReset) {\n model.scalarTexture.releaseGraphicsResources(model._openGLRenderWindow);\n model.scalarTexture.resetFormatAndType();\n\n model.scalarTexture.create3DFilterableFromRaw(\n dims[0],\n dims[1],\n dims[2],\n numComp,\n scalars.getDataType(),\n scalars.getData(),\n model.renderable.getPreferSizeOverAccuracy()\n );\n } else {\n model.scalarTexture.deactivate();\n model.scalarTexture.update3DFromRaw(data);\n }\n\n model.scalarTextureString = toString;\n }\n\n if (!model.tris.getCABO().getElementCount()) {\n // build the CABO\n const ptsArray = new Float32Array(12);\n for (let i = 0; i < 4; i++) {\n ptsArray[i * 3] = (i % 2) * 2 - 1.0;\n ptsArray[i * 3 + 1] = i > 1 ? 1.0 : -1.0;\n ptsArray[i * 3 + 2] = -1.0;\n }\n\n const cellArray = new Uint16Array(8);\n cellArray[0] = 3;\n cellArray[1] = 0;\n cellArray[2] = 1;\n cellArray[3] = 3;\n cellArray[4] = 3;\n cellArray[5] = 0;\n cellArray[6] = 3;\n cellArray[7] = 2;\n\n const points = vtkDataArray.newInstance({\n numberOfComponents: 3,\n values: ptsArray,\n });\n points.setName('points');\n const cells = vtkDataArray.newInstance({\n numberOfComponents: 1,\n values: cellArray,\n });\n model.tris.getCABO().createVBO(cells, 'polys', Representation.SURFACE, {\n points,\n cellOffset: 0,\n });\n }\n\n model.VBOBuildTime.modified();\n };\n\n publicAPI.setCameraShaderParameters = (cellBO, ren, actor) => {\n const program = cellBO.getProgram();\n const cam = model.openGLCamera.getRenderable();\n const crange = cam.getClippingRange();\n // NOTE: the actual slab thickness clipping is done with clipping planes,\n // but here we still need to set the cam uniform to the clipping range.\n\n program.setUniformf('camThick', crange[1] - crange[0]);\n program.setUniformf('camNear', crange[0]);\n program.setUniformf('camFar', crange[1]);\n\n // // [WMVP]C == {world, model, view, projection} coordinates\n // // E.g., WCPC == world to projection coordinate transformation\n cam.setIsPerformingCoordinateTransformation(true);\n const keyMats = model.openGLCamera.getKeyMatrices(ren);\n cam.setIsPerformingCoordinateTransformation(false);\n const actMats = model.openGLVolume.getKeyMatrices();\n mat4.multiply(model.modelToView, keyMats.wcvc, actMats.mcwc);\n\n const bounds = model.currentInput.getBounds();\n const spc = model.currentInput.getSpacing();\n const dims = model.currentInput.getDimensions();\n\n // compute the viewport bounds of the volume\n // we will only render those fragments.\n const pos = new Float64Array(3);\n const dir = new Float64Array(3);\n let dcxmin = 1.0;\n let dcxmax = -1.0;\n let dcymin = 1.0;\n let dcymax = -1.0;\n\n for (let i = 0; i < 8; ++i) {\n vec3.set(\n pos,\n bounds[i % 2],\n bounds[2 + (Math.floor(i / 2) % 2)],\n bounds[4 + Math.floor(i / 4)]\n );\n vec3.transformMat4(pos, pos, model.modelToView);\n if (!cam.getParallelProjection()) {\n vec3.normalize(dir, pos);\n\n // now find the projection of this point onto a\n // nearZ distance plane. Since the camera is at 0,0,0\n // in VC the ray is just t*pos and\n // t is -nearZ/dir.z\n // intersection becomes pos.x/pos.z\n const t = -crange[0] / pos[2];\n vec3.scale(pos, dir, t);\n }\n // now convert to DC\n vec3.transformMat4(pos, pos, keyMats.vcpc);\n\n dcxmin = Math.min(pos[0], dcxmin);\n dcxmax = Math.max(pos[0], dcxmax);\n dcymin = Math.min(pos[1], dcymin);\n dcymax = Math.max(pos[1], dcymax);\n }\n\n program.setUniformf('dcxmin', dcxmin);\n program.setUniformf('dcxmax', dcxmax);\n program.setUniformf('dcymin', dcymin);\n program.setUniformf('dcymax', dcymax);\n\n if (program.isUniformUsed('cameraParallel')) {\n program.setUniformi('cameraParallel', cam.getParallelProjection());\n }\n\n const ext = model.currentInput.getSpatialExtent();\n const vsize = new Float64Array(3);\n vec3.set(\n vsize,\n (ext[1] - ext[0]) * spc[0],\n (ext[3] - ext[2]) * spc[1],\n (ext[5] - ext[4]) * spc[2]\n );\n program.setUniform3f('vSpacing', spc[0], spc[1], spc[2]);\n\n vec3.set(pos, ext[0], ext[2], ext[4]);\n\n model.currentInput.indexToWorldVec3(pos, pos);\n\n vec3.transformMat4(pos, pos, model.modelToView);\n\n program.setUniform3f('vOriginVC', pos[0], pos[1], pos[2]);\n\n // apply the image directions\n const i2wmat4 = model.currentInput.getIndexToWorld();\n mat4.multiply(model.idxToView, model.modelToView, i2wmat4);\n\n mat3.multiply(\n model.idxNormalMatrix,\n keyMats.normalMatrix,\n actMats.normalMatrix\n );\n mat3.multiply(\n model.idxNormalMatrix,\n model.idxNormalMatrix,\n model.currentInput.getDirection()\n );\n\n const maxSamples =\n vec3.length(vsize) / model.renderable.getSampleDistance();\n if (maxSamples > model.renderable.getMaximumSamplesPerRay()) {\n vtkWarningMacro(`The number of steps required ${Math.ceil(\n maxSamples\n )} is larger than the\n specified maximum number of steps ${model.renderable.getMaximumSamplesPerRay()}.\n Please either change the\n volumeMapper sampleDistance or its maximum number of samples.`);\n }\n\n const vctoijk = new Float64Array(3);\n\n vec3.set(vctoijk, 1.0, 1.0, 1.0);\n vec3.divide(vctoijk, vctoijk, vsize);\n program.setUniform3f('vVCToIJK', vctoijk[0], vctoijk[1], vctoijk[2]);\n program.setUniform3i('volumeDimensions', dims[0], dims[1], dims[2]);\n\n if (!model._openGLRenderWindow.getWebgl2()) {\n const volInfo = model.scalarTexture.getVolumeInfo();\n program.setUniformf('texWidth', model.scalarTexture.getWidth());\n program.setUniformf('texHeight', model.scalarTexture.getHeight());\n program.setUniformi('xreps', volInfo.xreps);\n program.setUniformi('xstride', volInfo.xstride);\n program.setUniformi('ystride', volInfo.ystride);\n }\n\n // map normals through normal matrix\n // then use a point on the plane to compute the distance\n const normal = new Float64Array(3);\n const pos2 = new Float64Array(3);\n for (let i = 0; i < 6; ++i) {\n switch (i) {\n case 1:\n vec3.set(normal, -1.0, 0.0, 0.0);\n vec3.set(pos2, ext[0], ext[2], ext[4]);\n break;\n case 2:\n vec3.set(normal, 0.0, 1.0, 0.0);\n vec3.set(pos2, ext[1], ext[3], ext[5]);\n break;\n case 3:\n vec3.set(normal, 0.0, -1.0, 0.0);\n vec3.set(pos2, ext[0], ext[2], ext[4]);\n break;\n case 4:\n vec3.set(normal, 0.0, 0.0, 1.0);\n vec3.set(pos2, ext[1], ext[3], ext[5]);\n break;\n case 5:\n vec3.set(normal, 0.0, 0.0, -1.0);\n vec3.set(pos2, ext[0], ext[2], ext[4]);\n break;\n case 0:\n default:\n vec3.set(normal, 1.0, 0.0, 0.0);\n vec3.set(pos2, ext[1], ext[3], ext[5]);\n break;\n }\n vec3.transformMat3(normal, normal, model.idxNormalMatrix);\n vec3.transformMat4(pos2, pos2, model.idxToView);\n const dist = -1.0 * vec3.dot(pos2, normal);\n\n // we have the plane in view coordinates\n // specify the planes in view coordinates\n program.setUniform3f(`vPlaneNormal${i}`, normal[0], normal[1], normal[2]);\n program.setUniformf(`vPlaneDistance${i}`, dist);\n\n if (actor.getProperty().getUseLabelOutline()) {\n const image = model.currentInput;\n const worldToIndex = image.getWorldToIndex();\n\n program.setUniformMatrix('vWCtoIDX', worldToIndex);\n\n // Get the projection coordinate to world coordinate transformation matrix.\n mat4.invert(model.projectionToWorld, keyMats.wcpc);\n program.setUniformMatrix('PCWCMatrix', model.projectionToWorld);\n\n const size = publicAPI.getRenderTargetSize();\n const offset = publicAPI.getRenderTargetOffset();\n\n program.setUniformf('vpWidth', size[0]);\n program.setUniformf('vpHeight', size[1]);\n\n // TODO: You need to use the fix/labelMapOutline branch or these\n // won't be consumed by the shader\n program.setUniformf('vpOffsetX', offset[0] / size[0]);\n program.setUniformf('vpOffsetY', offset[1] / size[1]);\n }\n }\n\n mat4.invert(model.projectionToView, keyMats.vcpc);\n model.projectionToView[10] = model.projectionToView[14];\n program.setUniformMatrix('PCVCMatrix', model.projectionToView);\n\n // handle lighting values\n switch (model.lastLightComplexity) {\n default:\n case 0: // no lighting, tcolor is fine as is\n break;\n\n case 1: // headlight\n case 2: // light kit\n case 3: {\n // positional not implemented fallback to directional\n // mat3.transpose(keyMats.normalMatrix, keyMats.normalMatrix);\n let lightNum = 0;\n const lightColor = [];\n ren.getLights().forEach((light) => {\n const status = light.getSwitch();\n if (status > 0) {\n const dColor = light.getColor();\n const intensity = light.getIntensity();\n lightColor[0] = dColor[0] * intensity;\n lightColor[1] = dColor[1] * intensity;\n lightColor[2] = dColor[2] * intensity;\n program.setUniform3fArray(`lightColor${lightNum}`, lightColor);\n const ldir = light.getDirection();\n vec3.set(normal, ldir[0], ldir[1], ldir[2]);\n vec3.transformMat3(normal, normal, keyMats.normalMatrix);\n program.setUniform3f(\n `lightDirectionVC${lightNum}`,\n normal[0],\n normal[1],\n normal[2]\n );\n // camera DOP is 0,0,-1.0 in VC\n const halfAngle = [\n -0.5 * normal[0],\n -0.5 * normal[1],\n -0.5 * (normal[2] - 1.0),\n ];\n program.setUniform3fArray(`lightHalfAngleVC${lightNum}`, halfAngle);\n lightNum++;\n }\n });\n // mat3.transpose(keyMats.normalMatrix, keyMats.normalMatrix);\n }\n }\n };\n\n // publicAPI.getRenderTargetSize = () => {\n // // https://github.com/Kitware/vtk-js/blob/master/Sources/Rendering/OpenGL/VolumeMapper/index.js#L952\n // if (model.lastXYF > 1.43) {\n // const sz = model.framebuffer.getSize()\n // return [model.fvp[0] * sz[0], model.fvp[1] * sz[1]]\n // }\n\n // // This seems wrong, it assumes the renderWindow only has one renderer\n // // but I don't know if this stuff is correct...\n\n // const { usize, vsize } = model.openGLRenderer.getTiledSizeAndOrigin()\n\n // return [usize, vsize]\n // }\n\n // publicAPI.getRenderTargetSize = () => {\n // if (model._useSmallViewport) {\n // return [model._smallViewportWidth, model._smallViewportHeight]\n // }\n\n // return model._openGLRenderWindow.getFramebufferSize()\n // }\n publicAPI.getRenderTargetSize = () => {\n if (model._useSmallViewport) {\n return [model._smallViewportWidth, model._smallViewportHeight];\n }\n\n const { usize, vsize } = model.openGLRenderer.getTiledSizeAndOrigin();\n\n return [usize, vsize];\n };\n\n publicAPI.getRenderTargetOffset = () => {\n const { lowerLeftU, lowerLeftV } =\n model.openGLRenderer.getTiledSizeAndOrigin();\n\n return [lowerLeftU, lowerLeftV];\n };\n}\n\n// ----------------------------------------------------------------------------\n// Object factory\n// ----------------------------------------------------------------------------\n\n// ----------------------------------------------------------------------------\n\nconst DEFAULT_VALUES = {};\n\nexport function extend(publicAPI, model, initialValues = {}) {\n Object.assign(model, DEFAULT_VALUES, initialValues);\n\n vtkOpenGLVolumeMapper.extend(publicAPI, model, initialValues);\n\n model.scalarTexture = initialValues.scalarTexture;\n model.previousState = {};\n\n // Object methods\n vtkStreamingOpenGLVolumeMapper(publicAPI, model);\n}\n\n// ----------------------------------------------------------------------------\n\nexport const newInstance = macro.newInstance(\n extend,\n 'vtkStreamingOpenGLVolumeMapper'\n);\n\n// ----------------------------------------------------------------------------\n\nexport default { newInstance, extend };\n","import macro from '@kitware/vtk.js/macros';\n// import vtkGenericWidgetRepresentation from '@kitware/vtk.js/Rendering/SceneGraph/GenericWidgetRepresentation'\nimport vtkOpenGLActor from '@kitware/vtk.js/Rendering/OpenGL/Actor';\nimport vtkOpenGLActor2D from '@kitware/vtk.js/Rendering/OpenGL/Actor2D';\nimport vtkOpenGLCamera from '@kitware/vtk.js/Rendering/OpenGL/Camera';\nimport vtkOpenGLGlyph3DMapper from '@kitware/vtk.js/Rendering/OpenGL/Glyph3DMapper';\nimport vtkOpenGLImageMapper from '@kitware/vtk.js/Rendering/OpenGL/ImageMapper';\nimport vtkOpenGLImageSlice from '@kitware/vtk.js/Rendering/OpenGL/ImageSlice';\nimport vtkOpenGLPixelSpaceCallbackMapper from '@kitware/vtk.js/Rendering/OpenGL/PixelSpaceCallbackMapper';\nimport vtkOpenGLPolyDataMapper from '@kitware/vtk.js/Rendering/OpenGL/PolyDataMapper';\nimport vtkOpenGLRenderer from '@kitware/vtk.js/Rendering/OpenGL/Renderer';\nimport vtkOpenGLSkybox from '@kitware/vtk.js/Rendering/OpenGL/Skybox';\nimport vtkOpenGLSphereMapper from '@kitware/vtk.js/Rendering/OpenGL/SphereMapper';\nimport vtkOpenGLStickMapper from '@kitware/vtk.js/Rendering/OpenGL/StickMapper';\nimport vtkOpenGLTexture from '@kitware/vtk.js/Rendering/OpenGL/Texture';\nimport vtkOpenGLVolume from '@kitware/vtk.js/Rendering/OpenGL/Volume';\nimport vtkOpenGLVolumeMapper from '@kitware/vtk.js/Rendering/OpenGL/VolumeMapper';\nimport vtkViewNodeFactory from '@kitware/vtk.js/Rendering/SceneGraph/ViewNodeFactory';\nimport vtkStreamingOpenGLVolumeMapper from './vtkStreamingOpenGLVolumeMapper';\n\n/**\n * vtkStreamingOpenGLViewNodeFactory - A fork of the vtkOpenGLViewNodeFactory,\n * so that we can inject our custom derived \"Streaming\" classes.\n *\n * @param {*} publicAPI The public API to extend\n * @param {*} model The private model to extend.\n */\nfunction vtkStreamingOpenGLViewNodeFactory(publicAPI, model) {\n // Set our className\n model.classHierarchy.push('vtkStreamingOpenGLViewNodeFactory');\n\n /**\n * createNode - fork of createNode from vtkOpenGLViewNodeFactory.\n * This fork is required to inject the properties from model.getModelInitialValues.\n *\n * @param {object} dataObject An instance of a vtk.js class.\n */\n publicAPI.createNode = (dataObject) => {\n if (dataObject.isDeleted()) {\n return null;\n }\n\n let cpt = 0;\n let className = dataObject.getClassName(cpt++);\n let isObject = false;\n const keys = Object.keys(model.overrides);\n while (className && !isObject) {\n if (keys.indexOf(className) !== -1) {\n isObject = true;\n } else {\n className = dataObject.getClassName(cpt++);\n }\n }\n\n if (!isObject) {\n return null;\n }\n\n const initialValues = model.getModelInitialValues(dataObject);\n\n const vn = model.overrides[className](initialValues);\n vn.setMyFactory(publicAPI);\n return vn;\n };\n\n /**\n * getModelInitialValues - This function allows us to pass textures down from our\n * vtkSharedVolumeMapper to new instances of vtkStreamingOpenGLVolumeMapper.\n * The prevents us from sharing memory.\n *\n * TODO: It would be beneficial to push similar, but generalized, functionality\n * back to vtk.js in the future.\n *\n * @param {object} dataObject An instance of a vtk.js class.\n */\n model.getModelInitialValues = (dataObject) => {\n const initialValues = {};\n\n const className = dataObject.getClassName();\n\n if (className === 'vtkSharedVolumeMapper') {\n initialValues.scalarTexture = dataObject.getScalarTexture();\n }\n\n return initialValues;\n };\n}\n\n// ----------------------------------------------------------------------------\n// Object factory\n// ----------------------------------------------------------------------------\n\nconst DEFAULT_VALUES = {};\n\n// ----------------------------------------------------------------------------\n\nexport function extend(publicAPI, model, initialValues = {}) {\n Object.assign(model, DEFAULT_VALUES, initialValues);\n\n // Inheritance\n vtkViewNodeFactory.extend(publicAPI, model, initialValues);\n\n // Object methods\n vtkStreamingOpenGLViewNodeFactory(publicAPI, model);\n\n // Initialization\n publicAPI.registerOverride('vtkActor', vtkOpenGLActor.newInstance);\n publicAPI.registerOverride('vtkActor2D', vtkOpenGLActor2D.newInstance);\n publicAPI.registerOverride('vtkCamera', vtkOpenGLCamera.newInstance);\n publicAPI.registerOverride(\n 'vtkGlyph3DMapper',\n vtkOpenGLGlyph3DMapper.newInstance\n );\n publicAPI.registerOverride(\n 'vtkImageMapper',\n vtkOpenGLImageMapper.newInstance\n );\n publicAPI.registerOverride('vtkImageSlice', vtkOpenGLImageSlice.newInstance);\n publicAPI.registerOverride('vtkMapper', vtkOpenGLPolyDataMapper.newInstance);\n publicAPI.registerOverride(\n 'vtkPixelSpaceCallbackMapper',\n vtkOpenGLPixelSpaceCallbackMapper.newInstance\n );\n publicAPI.registerOverride('vtkRenderer', vtkOpenGLRenderer.newInstance);\n publicAPI.registerOverride('vtkSkybox', vtkOpenGLSkybox.newInstance);\n publicAPI.registerOverride(\n 'vtkSphereMapper',\n vtkOpenGLSphereMapper.newInstance\n );\n publicAPI.registerOverride(\n 'vtkStickMapper',\n vtkOpenGLStickMapper.newInstance\n );\n publicAPI.registerOverride('vtkTexture', vtkOpenGLTexture.newInstance);\n publicAPI.registerOverride('vtkVolume', vtkOpenGLVolume.newInstance);\n publicAPI.registerOverride(\n 'vtkVolumeMapper',\n vtkOpenGLVolumeMapper.newInstance\n );\n publicAPI.registerOverride(\n 'vtkSharedVolumeMapper',\n vtkStreamingOpenGLVolumeMapper.newInstance\n );\n // publicAPI.registerOverride(\n // 'vtkWidgetRepresentation',\n // vtkGenericWidgetRepresentation.newInstance\n // )\n}\n\n// ----------------------------------------------------------------------------\n\nexport const newInstance = macro.newInstance(\n extend,\n 'vtkStreamingOpenGLViewNodeFactory'\n);\n\n// ----------------------------------------------------------------------------\n\nexport default { newInstance, extend };\n","import macro from '@kitware/vtk.js/macros';\nimport vtkOpenGLRenderWindow from '@kitware/vtk.js/Rendering/OpenGL/RenderWindow';\nimport vtkStreamingOpenGLViewNodeFactory from './vtkStreamingOpenGLViewNodeFactory';\n\n/**\n * vtkStreamingOpenGLRenderWindow - A dervied class of the core vtkOpenGLRenderWindow class.\n * The main purpose for this class extension is to add in our own node factory, so we can use\n * our extended \"streaming\" classes for progressive texture loading.\n *\n *\n * @param {*} publicAPI The public API to extend\n * @param {*} model The private model to extend.\n */\nfunction vtkStreamingOpenGLRenderWindow(publicAPI, model) {\n model.classHierarchy.push('vtkStreamingOpenGLRenderWindow');\n}\n\n// ----------------------------------------------------------------------------\n// Object factory\n// ----------------------------------------------------------------------------\n\n// ----------------------------------------------------------------------------\n\nexport function extend(publicAPI, model, initialValues = {}) {\n Object.assign(model, initialValues);\n\n vtkOpenGLRenderWindow.extend(publicAPI, model, initialValues);\n\n model.myFactory = vtkStreamingOpenGLViewNodeFactory.newInstance();\n /* eslint-disable no-use-before-define */\n model.myFactory.registerOverride('vtkRenderWindow', newInstance);\n /* eslint-enable no-use-before-define */\n\n // Object methods\n vtkStreamingOpenGLRenderWindow(publicAPI, model);\n}\n\n// ----------------------------------------------------------------------------\n\nexport const newInstance = macro.newInstance(\n extend,\n 'vtkStreamingOpenGLRenderWindow'\n);\n\n// ----------------------------------------------------------------------------\n\nexport default { newInstance, extend };\n","import macro from '@kitware/vtk.js/macros';\nimport vtkStreamingOpenGLRenderWindow from './vtkStreamingOpenGLRenderWindow';\nimport vtkRenderer from '@kitware/vtk.js/Rendering/Core/Renderer';\nimport vtkRenderWindow from '@kitware/vtk.js/Rendering/Core/RenderWindow';\nimport vtkRenderWindowInteractor from '@kitware/vtk.js/Rendering/Core/RenderWindowInteractor';\n\n// Load basic classes for vtk() factory\nimport '@kitware/vtk.js/Common/Core/Points';\nimport '@kitware/vtk.js/Common/Core/DataArray';\nimport '@kitware/vtk.js/Common/DataModel/PolyData';\nimport '@kitware/vtk.js/Rendering/Core/Actor';\nimport '@kitware/vtk.js/Rendering/Core/Mapper';\n\n/**\n * vtkOffscreenMultiRenderWindow - A class to deal with offscreen rendering with multiple renderers.\n *\n * This class is based on the vtkGenericRenderWindow with two key differences:\n * - the vtkGenericRenderWindow had a renderer at the top level, with helpers to get it from the renderWindow.\n * although you could add more renderers, this gave special status to the first viewport. Which was confusing.\n * - When checking the size of the container element we no longer check the client size, as the canvas is offscreen.\n * - We aren't using interactor styles, so don't set one up.\n *\n * Additionally this class has some new helpers to easily add/associate renderers to different viewportIds.\n *\n *\n * @param {*} publicAPI The public API to extend\n * @param {*} model The private model to extend.\n */\nfunction vtkOffscreenMultiRenderWindow(publicAPI, model) {\n // Capture resize trigger method to remove from publicAPI\n const invokeResize = publicAPI.invokeResize;\n delete publicAPI.invokeResize;\n\n // VTK renderWindow. No renderers set by default\n model.renderWindow = vtkRenderWindow.newInstance();\n model.rendererMap = {};\n\n // OpenGLRenderWindow\n model.openGLRenderWindow = vtkStreamingOpenGLRenderWindow.newInstance();\n model.renderWindow.addView(model.openGLRenderWindow);\n\n // Interactor\n model.interactor = vtkRenderWindowInteractor.newInstance();\n model.interactor.setView(model.openGLRenderWindow);\n model.interactor.initialize();\n\n publicAPI.addRenderer = ({ viewport, id, background }) => {\n const renderer = vtkRenderer.newInstance({\n viewport,\n background: background || model.background,\n });\n\n model.renderWindow.addRenderer(renderer);\n model.rendererMap[id] = renderer;\n };\n\n publicAPI.destroy = () => {\n const rwi = model.renderWindow.getInteractor();\n rwi.delete();\n };\n\n publicAPI.removeRenderer = (id) => {\n const renderer = publicAPI.getRenderer(id);\n model.renderWindow.removeRenderer(renderer);\n renderer.delete();\n delete model.rendererMap[id];\n };\n\n publicAPI.getRenderer = (id) => {\n return model.rendererMap[id];\n };\n\n publicAPI.getRenderers = () => {\n const { rendererMap } = model;\n\n const renderers = Object.keys(rendererMap).map((id) => {\n return { id, renderer: rendererMap[id] };\n });\n\n return renderers;\n };\n\n // Handle window resize\n publicAPI.resize = () => {\n if (model.container) {\n // Don't use getBoundingClientRect() as in vtkGenericRenderWindow as is an offscreen canvas.\n const { width, height } = model.container;\n\n // Note: we do not scale by devicePixelRatio here because it has already\n // been done when adding the offscreenCanvas viewport representations\n model.openGLRenderWindow.setSize(Math.floor(width), Math.floor(height));\n invokeResize();\n model.renderWindow.render();\n }\n };\n\n // Handle DOM container relocation\n publicAPI.setContainer = (el) => {\n // Switch container\n model.container = el;\n model.openGLRenderWindow.setContainer(model.container);\n };\n\n // Properly release GL context\n publicAPI.delete = macro.chain(\n publicAPI.setContainer,\n publicAPI.destroy,\n model.openGLRenderWindow.delete,\n publicAPI.delete\n );\n\n publicAPI.resize();\n}\n\n// ----------------------------------------------------------------------------\n// Object factory\n// ----------------------------------------------------------------------------\n\nconst DEFAULT_VALUES = {\n background: [0.0, 0.0, 0.0],\n container: null,\n};\n\n// ----------------------------------------------------------------------------\n\nexport function extend(publicAPI, model, initialValues = {}) {\n Object.assign(model, DEFAULT_VALUES, initialValues);\n\n // Object methods\n macro.obj(publicAPI, model);\n macro.get(publicAPI, model, [\n 'renderWindow',\n 'openGLRenderWindow',\n 'interactor',\n 'container',\n ]);\n macro.event(publicAPI, model, 'resize');\n\n // Object specific methods\n vtkOffscreenMultiRenderWindow(publicAPI, model);\n}\n\n// ----------------------------------------------------------------------------\n\nexport const newInstance = macro.newInstance(extend);\n\n// ----------------------------------------------------------------------------\n\nexport default { newInstance, extend };\n","export default function _assertThisInitialized(self) {\n if (self === void 0) {\n throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");\n }\n\n return self;\n}","export default function _getPrototypeOf(o) {\n _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {\n return o.__proto__ || Object.getPrototypeOf(o);\n };\n return _getPrototypeOf(o);\n}","import getPrototypeOf from \"./getPrototypeOf.js\";\nexport default function _superPropBase(object, property) {\n while (!Object.prototype.hasOwnProperty.call(object, property)) {\n object = getPrototypeOf(object);\n if (object === null) break;\n }\n\n return object;\n}","import superPropBase from \"./superPropBase.js\";\nexport default function _get() {\n if (typeof Reflect !== \"undefined\" && Reflect.get) {\n _get = Reflect.get.bind();\n } else {\n _get = function _get(target, property, receiver) {\n var base = superPropBase(target, property);\n if (!base) return;\n var desc = Object.getOwnPropertyDescriptor(base, property);\n\n if (desc.get) {\n return desc.get.call(arguments.length < 3 ? target : receiver);\n }\n\n return desc.value;\n };\n }\n\n return _get.apply(this, arguments);\n}","export default function _setPrototypeOf(o, p) {\n _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {\n o.__proto__ = p;\n return o;\n };\n return _setPrototypeOf(o, p);\n}","import setPrototypeOf from \"./setPrototypeOf.js\";\nexport default function _inherits(subClass, superClass) {\n if (typeof superClass !== \"function\" && superClass !== null) {\n throw new TypeError(\"Super expression must either be null or a function\");\n }\n\n subClass.prototype = Object.create(superClass && superClass.prototype, {\n constructor: {\n value: subClass,\n writable: true,\n configurable: true\n }\n });\n Object.defineProperty(subClass, \"prototype\", {\n writable: false\n });\n if (superClass) setPrototypeOf(subClass, superClass);\n}","import _typeof from \"./typeof.js\";\nimport assertThisInitialized from \"./assertThisInitialized.js\";\nexport default function _possibleConstructorReturn(self, call) {\n if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) {\n return call;\n } else if (call !== void 0) {\n throw new TypeError(\"Derived constructors may only return object or undefined\");\n }\n\n return assertThisInitialized(self);\n}","import cache, { Cache } from './cache';\nimport ImageVolume from './classes/ImageVolume';\n\nexport { ImageVolume, Cache };\nexport default cache;\n","import type Point3 from '../types/Point3';\n\n/**\n * Given an imageData object and a point in physical space, return the index of the\n * voxel that contains the point. TODO: this should be pushed to vtk upstream.\n * @param imageData - The image data object.\n * @param physicalPoint - The point in physical space that you want to transform to\n * index space.\n * @returns An array of integers.\n */\nexport default function transformWorldToIndex(imageData, worldPos: Point3) {\n const continuousIndex = imageData.worldToIndex(worldPos);\n const index = continuousIndex.map(Math.round);\n\n return index;\n}\n","import arrayWithHoles from \"./arrayWithHoles.js\";\nimport iterableToArrayLimit from \"./iterableToArrayLimit.js\";\nimport unsupportedIterableToArray from \"./unsupportedIterableToArray.js\";\nimport nonIterableRest from \"./nonIterableRest.js\";\nexport default function _slicedToArray(arr, i) {\n return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || unsupportedIterableToArray(arr, i) || nonIterableRest();\n}","export default function _arrayWithHoles(arr) {\n if (Array.isArray(arr)) return arr;\n}","export default function _iterableToArrayLimit(arr, i) {\n var _i = arr == null ? null : typeof Symbol !== \"undefined\" && arr[Symbol.iterator] || arr[\"@@iterator\"];\n\n if (_i == null) return;\n var _arr = [];\n var _n = true;\n var _d = false;\n\n var _s, _e;\n\n try {\n for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {\n _arr.push(_s.value);\n\n if (i && _arr.length === i) break;\n }\n } catch (err) {\n _d = true;\n _e = err;\n } finally {\n try {\n if (!_n && _i[\"return\"] != null) _i[\"return\"]();\n } finally {\n if (_d) throw _e;\n }\n }\n\n return _arr;\n}","export default function _nonIterableRest() {\n throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}","import type vtkActor from '@kitware/vtk.js/Rendering/Core/Actor';\nimport type vtkImageSlice from '@kitware/vtk.js/Rendering/Core/ImageSlice';\nimport type vtkVolume from '@kitware/vtk.js/Rendering/Core/Volume';\n\n/**\n * Checks if a vtk Actor is an image actor (vtkVolume or vtkImageSlice) otherwise returns false.\n *\n * @param actor - actor\n * @returns A boolean value.\n */\nexport default function isImageActor(\n actor: vtkActor | vtkVolume | vtkImageSlice\n): boolean {\n if (actor.isA('vtkVolume')) {\n return true;\n }\n\n if (actor.isA('vtkImageSlice')) {\n return true;\n }\n\n return false;\n}\n","import { Point3, Plane } from '../types';\nimport { vec3, mat3 } from 'gl-matrix';\n\n/**\n * It calculates the intersection of a line and a plane.\n * Plane equation is Ax+By+Cz=D\n * @param p0 - [x,y,z] of the first point of the line\n * @param p1 - [x,y,z] of the second point of the line\n * @param plane - [A, B, C, D] Plane parameter: Ax+By+Cz=D\n * @returns - [X,Y,Z] coordinates of the intersection\n */\nfunction linePlaneIntersection(p0: Point3, p1: Point3, plane: Plane): Point3 {\n const [x0, y0, z0] = p0;\n const [x1, y1, z1] = p1;\n const [A, B, C, D] = plane;\n const a = x1 - x0;\n const b = y1 - y0;\n const c = z1 - z0;\n const t = (-1 * (A * x0 + B * y0 + C * z0 - D)) / (A * a + B * b + C * c);\n const X = a * t + x0;\n const Y = b * t + y0;\n const Z = c * t + z0;\n\n return [X, Y, Z];\n}\n\n/**\n * It returns the plane equation defined by a point and a normal vector.\n * @param normal - normal vector\n * @param point - a point on the plane\n * @returns - [A, B,C, D] of plane equation A*X + B*Y + C*Z = D\n */\nfunction planeEquation(normal: Point3, point: Point3 | vec3): Plane {\n const [A, B, C] = normal;\n const D = A * point[0] + B * point[1] + C * point[2];\n return [A, B, C, D];\n}\n\n/**\n * Computes the intersection of three planes in 3D space with equations:\n * A1*X + B1*Y + C1*Z = D1\n * A2*X + B2*Y + C2*Z = D2\n * A3*X + B3*Y + C3*Z = D3\n * @returns - [x, y, z] the intersection in the world coordinate\n */\nfunction threePlaneIntersection(\n firstPlane: Plane,\n secondPlane: Plane,\n thirdPlane: Plane\n): Point3 {\n const [A1, B1, C1, D1] = firstPlane;\n const [A2, B2, C2, D2] = secondPlane;\n const [A3, B3, C3, D3] = thirdPlane;\n const m0 = mat3.fromValues(A1, A2, A3, B1, B2, B3, C1, C2, C3);\n const m1 = mat3.fromValues(D1, D2, D3, B1, B2, B3, C1, C2, C3);\n const m2 = mat3.fromValues(A1, A2, A3, D1, D2, D3, C1, C2, C3);\n const m3 = mat3.fromValues(A1, A2, A3, B1, B2, B3, D1, D2, D3);\n\n // TODO: handle no intersection scenario\n const x = mat3.determinant(m1) / mat3.determinant(m0);\n const y = mat3.determinant(m2) / mat3.determinant(m0);\n const z = mat3.determinant(m3) / mat3.determinant(m0);\n return [x, y, z];\n}\n\n/**\n * Computes the distance of a point in 3D space to a plane\n * @param plane - [A, B, C, D] of plane equation A*X + B*Y + C*Z = D\n * @param point - [A, B, C] the plane in World coordinate\n * @param signed - if true, the distance is signed\n * @returns - the distance of the point to the plane\n * */\nfunction planeDistanceToPoint(\n plane: Plane,\n point: Point3,\n signed = false\n): number {\n const [A, B, C, D] = plane;\n const [x, y, z] = point;\n const numerator = A * x + B * y + C * z - D;\n const distance = Math.abs(numerator) / Math.sqrt(A * A + B * B + C * C);\n const sign = signed ? Math.sign(numerator) : 1;\n return sign * distance;\n}\n\nexport {\n linePlaneIntersection,\n planeEquation,\n threePlaneIntersection,\n planeDistanceToPoint,\n};\n","/**\n * A function that checks if there is a value in the array that is NaN.\n * or if the input is a number it just checks if it is NaN.\n * @param input - The input to check if it is NaN.\n * @returns - True if the input is NaN, false otherwise.\n */\nexport default function hasNaNValues(input: number[] | number): boolean {\n if (Array.isArray(input)) {\n return input.some((value) => Number.isNaN(value));\n }\n return Number.isNaN(input);\n}\n","import type { vtkCamera } from '@kitware/vtk.js/Rendering/Core/Camera';\nimport vtkMatrixBuilder from '@kitware/vtk.js/Common/Core/MatrixBuilder';\nimport vtkMath from '@kitware/vtk.js/Common/Core/Math';\nimport vtkPlane from '@kitware/vtk.js/Common/DataModel/Plane';\n\nimport { vec2, vec3, mat4 } from 'gl-matrix';\nimport _cloneDeep from 'lodash.clonedeep';\n\nimport Events from '../enums/Events';\nimport ViewportType from '../enums/ViewportType';\nimport renderingEngineCache from './renderingEngineCache';\nimport { triggerEvent, planar, isImageActor } from '../utilities';\nimport hasNaNValues from '../utilities/hasNaNValues';\nimport { RENDERING_DEFAULTS } from '../constants';\nimport type {\n ICamera,\n ActorEntry,\n IRenderingEngine,\n ViewportInputOptions,\n Point2,\n Point3,\n FlipDirection,\n EventTypes,\n} from '../types';\nimport type { ViewportInput, IViewport } from '../types/IViewport';\nimport type { vtkSlabCamera } from './vtkClasses/vtkSlabCamera';\n\n/**\n * An object representing a single viewport, which is a camera\n * looking into a viewport, and an associated target output `HTMLDivElement`.\n * Viewport is a base class that can be extended to create a specific\n * viewport type. Both VolumeViewport and StackViewport are subclasses\n * of Viewport. Common logic for all viewports is contained in Viewport class\n * which is camera properties/methods, vtk.js actors, and other common\n * logic.\n */\nclass Viewport implements IViewport {\n /** unique identifier for the viewport */\n readonly id: string;\n /** HTML element in DOM that is used for rendering the viewport */\n readonly element: HTMLDivElement;\n /** an internal canvas that is created on the provided HTML element */\n readonly canvas: HTMLCanvasElement;\n /** RenderingEngine id that the viewport belongs to */\n readonly renderingEngineId: string;\n /** Type of viewport */\n readonly type: ViewportType;\n protected flipHorizontal = false;\n protected flipVertical = false;\n protected rotation = 0;\n public isDisabled: boolean;\n\n /** sx of viewport on the offscreen canvas */\n sx: number;\n /** sy of viewport on the offscreen canvas */\n sy: number;\n /** sWidth of viewport on the offscreen canvas */\n sWidth: number;\n /** sHeight of viewport on the offscreen canvas */\n sHeight: number;\n /** a Map containing the actor uid and actors */\n _actors: Map<string, any>;\n /** Default options for the viewport which includes orientation, viewPlaneNormal and backgroundColor */\n readonly defaultOptions: any;\n /** options for the viewport which includes orientation axis and backgroundColor */\n options: ViewportInputOptions;\n private _suppressCameraModifiedEvents = false;\n /** A flag representing if viewport methods should fire events or not */\n readonly suppressEvents: boolean;\n protected hasPixelSpacing = true;\n /** The camera that is initially defined on the reset for\n * the relative pan/zoom\n */\n protected initialCamera: ICamera;\n\n constructor(props: ViewportInput) {\n this.id = props.id;\n this.renderingEngineId = props.renderingEngineId;\n this.type = props.type;\n this.element = props.element;\n this.canvas = props.canvas;\n this.sx = props.sx;\n this.sy = props.sy;\n this.sWidth = props.sWidth;\n this.sHeight = props.sHeight;\n this._actors = new Map();\n // Set data attributes for render events\n this.element.setAttribute('data-viewport-uid', this.id);\n this.element.setAttribute(\n 'data-rendering-engine-uid',\n this.renderingEngineId\n );\n\n this.defaultOptions = _cloneDeep(props.defaultOptions);\n this.suppressEvents = props.defaultOptions.suppressEvents\n ? props.defaultOptions.suppressEvents\n : false;\n this.options = _cloneDeep(props.defaultOptions);\n this.isDisabled = false;\n }\n\n getFrameOfReferenceUID: () => string;\n canvasToWorld: (canvasPos: Point2) => Point3;\n worldToCanvas: (worldPos: Point3) => Point2;\n customRenderViewportToCanvas: () => unknown;\n resize: () => void;\n getProperties: () => void;\n\n static get useCustomRenderingPipeline(): boolean {\n return false;\n }\n\n /**\n * Returns the rendering engine driving the `Viewport`.\n *\n * @returns The RenderingEngine instance.\n */\n public getRenderingEngine(): IRenderingEngine {\n return renderingEngineCache.get(this.renderingEngineId);\n }\n\n /**\n * Returns the `vtkRenderer` responsible for rendering the `Viewport`.\n *\n * @returns The `vtkRenderer` for the `Viewport`.\n */\n public getRenderer() {\n const renderingEngine = this.getRenderingEngine();\n\n if (!renderingEngine || renderingEngine.hasBeenDestroyed) {\n throw new Error('Rendering engine has been destroyed');\n }\n\n return renderingEngine.offscreenMultiRenderWindow.getRenderer(this.id);\n }\n\n /**\n * Renders the `Viewport` using the `RenderingEngine`.\n */\n public render(): void {\n const renderingEngine = this.getRenderingEngine();\n\n renderingEngine.renderViewport(this.id);\n }\n\n /**\n * Sets new options and (TODO) applies them.\n *\n * @param options - The viewport options to set.\n * @param immediate - If `true`, renders the viewport after the options are set.\n */\n public setOptions(options: ViewportInputOptions, immediate = false): void {\n this.options = <ViewportInputOptions>_cloneDeep(options);\n\n // TODO When this is needed we need to move the camera position.\n // We can steal some logic from the tools we build to do this.\n\n if (immediate) {\n this.render();\n }\n }\n\n /**\n * Resets the options the `Viewport`'s `defaultOptions`\n *\n * @param immediate - If `true`, renders the viewport after the options are reset.\n */\n public reset(immediate = false) {\n this.options = _cloneDeep(this.defaultOptions);\n\n // TODO When this is needed we need to move the camera position.\n // We can steal some logic from the tools we build to do this.\n\n if (immediate) {\n this.render();\n }\n }\n\n /**\n * Flip the viewport on horizontal or vertical axis, this method\n * works with vtk-js backed rendering pipeline.\n *\n * @param flipOptions - Flip options specifying the axis of flip\n * @param flipOptions.flipHorizontal - Flip the viewport on horizontal axis\n * @param flipOptions.flipVertical - Flip the viewport on vertical axis\n */\n protected flip({ flipHorizontal, flipVertical }: FlipDirection): void {\n const imageData = this.getDefaultImageData();\n\n if (!imageData) {\n return;\n }\n\n const camera = this.getCamera();\n const { viewPlaneNormal, viewUp, focalPoint, position } = camera;\n\n const viewRight = vec3.cross(vec3.create(), viewPlaneNormal, viewUp);\n let viewUpToSet = vec3.copy(vec3.create(), viewUp);\n const viewPlaneNormalToSet = vec3.negate(vec3.create(), viewPlaneNormal);\n\n // for both flip horizontal and vertical we need to move the camera to the\n // other side of the image\n const distance = vec3.distance(position, focalPoint);\n\n // If the pan has been applied, we need to be able\n // apply the pan back\n const dimensions = imageData.getDimensions();\n const middleIJK = dimensions.map((d) => Math.floor(d / 2));\n\n const idx = [middleIJK[0], middleIJK[1], middleIJK[2]];\n const centeredFocalPoint = imageData.indexToWorld(idx, vec3.create());\n\n const resetFocalPoint = this._getFocalPointForResetCamera(\n centeredFocalPoint as Point3,\n camera,\n { resetPan: true, resetToCenter: false }\n );\n\n const panDir = vec3.subtract(vec3.create(), focalPoint, resetFocalPoint);\n const panValue = vec3.length(panDir);\n\n const getPanDir = (mirrorVec) => {\n const panDirMirror = vec3.scale(\n vec3.create(),\n mirrorVec,\n 2 * vec3.dot(panDir, mirrorVec)\n );\n vec3.subtract(panDirMirror, panDirMirror, panDir);\n vec3.normalize(panDirMirror, panDirMirror);\n\n return panDirMirror;\n };\n\n // Flipping horizontal mean that the camera should move\n // to the other side of the image but looking at the\n // same direction and same focal point\n if (flipHorizontal) {\n // we need to apply the pan value to the new focal point but in the direction\n // that is mirrored on the viewUp for the flip horizontal and\n // viewRight for the flip vertical\n\n // mirror the pan direction based on the viewUp\n const panDirMirror = getPanDir(viewUpToSet);\n\n // move focal point from the resetFocalPoint to the newFocalPoint\n // based on the panDirMirror and panValue\n const newFocalPoint = vec3.scaleAndAdd(\n vec3.create(),\n resetFocalPoint,\n panDirMirror,\n panValue\n );\n\n // move the camera position also the same way as the focal point\n const newPosition = vec3.scaleAndAdd(\n vec3.create(),\n newFocalPoint,\n viewPlaneNormalToSet,\n distance\n );\n\n this.setCamera({\n viewPlaneNormal: viewPlaneNormalToSet as Point3,\n position: newPosition as Point3,\n focalPoint: newFocalPoint as Point3,\n });\n\n this.flipHorizontal = !this.flipHorizontal;\n }\n\n // Flipping vertical mean that the camera should negate the view up\n // and also move to the other side of the image but looking at the\n if (flipVertical) {\n viewUpToSet = vec3.negate(viewUpToSet, viewUp);\n\n // we need to apply the pan value to the new focal point but in the direction\n const panDirMirror = getPanDir(viewRight);\n\n const newFocalPoint = vec3.scaleAndAdd(\n vec3.create(),\n resetFocalPoint,\n panDirMirror,\n panValue\n );\n\n const newPosition = vec3.scaleAndAdd(\n vec3.create(),\n newFocalPoint,\n viewPlaneNormalToSet,\n distance\n );\n\n this.setCamera({\n focalPoint: newFocalPoint as Point3,\n viewPlaneNormal: viewPlaneNormalToSet as Point3,\n viewUp: viewUpToSet as Point3,\n position: newPosition as Point3,\n });\n\n this.flipVertical = !this.flipVertical;\n }\n\n this.render();\n }\n\n private getDefaultImageData(): any {\n const actorEntry = this.getDefaultActor();\n\n if (actorEntry && isImageActor(actorEntry.actor)) {\n return actorEntry.actor.getMapper().getInputData();\n }\n }\n\n /**\n * Get the default actor\n * @returns An actor entry.\n */\n public getDefaultActor(): ActorEntry {\n return this.getActors()[0];\n }\n\n /**\n * Get all the actors in the viewport\n * @returns An array of ActorEntry objects.\n */\n public getActors(): Array<ActorEntry> {\n return Array.from(this._actors.values());\n }\n\n /**\n * Get an actor by its UID\n * @param actorUID - The unique ID of the actor.\n * @returns An ActorEntry object.\n */\n public getActor(actorUID: string): ActorEntry {\n return this._actors.get(actorUID);\n }\n\n /**\n * Get an actor UID by its index\n * @param index - array index.\n * @returns actorUID\n */\n public getActorUIDByIndex(index: number): string {\n const actor = this.getActors()[index];\n if (actor) {\n return actor.uid;\n }\n }\n\n /**\n * Get an actor by its index\n * @param index - array index.\n * @returns actorUID\n */\n public getActorByIndex(index: number): ActorEntry {\n return this.getActors()[index];\n }\n\n /**\n * It removes all actors from the viewport and then adds the actors from the array.\n * @param actors - An array of ActorEntry objects.\n */\n public setActors(actors: Array<ActorEntry>): void {\n this.removeAllActors();\n const resetCameraPanAndZoom = true;\n // when we set the actor we need to reset the camera to initialize the\n // camera focal point with the bounds of the actors.\n this.addActors(actors, resetCameraPanAndZoom);\n }\n\n /**\n * Remove the actor from the viewport\n * @param actorUID - The unique identifier for the actor.\n */\n public removeActor(actorUID: string): void {\n const actorEntry = this.getActor(actorUID);\n if (!actorEntry) {\n console.warn(`Actor ${actorUID} does not exist for this viewport`);\n return;\n }\n const renderer = this.getRenderer();\n renderer.removeViewProp(actorEntry.actor); // removeActor not implemented in vtk?\n this._actors.delete(actorUID);\n }\n\n /**\n * Remove the actors with the given UIDs from the viewport\n * @param actorUIDs - An array of actor UIDs to remove.\n */\n public removeActors(actorUIDs: Array<string>): void {\n actorUIDs.forEach((actorUID) => {\n this.removeActor(actorUID);\n });\n }\n\n /**\n * Add a list of actors (actor entries) to the viewport\n * @param resetCameraPanAndZoom - force reset pan and zoom of the camera,\n * default value is false.\n * @param actors - An array of ActorEntry objects.\n */\n public addActors(\n actors: Array<ActorEntry>,\n resetCameraPanAndZoom = false\n ): void {\n const renderingEngine = this.getRenderingEngine();\n if (!renderingEngine || renderingEngine.hasBeenDestroyed) {\n console.warn(\n 'Viewport::addActors::Rendering engine has not been initialized or has been destroyed'\n );\n return;\n }\n\n actors.forEach((actor) => this.addActor(actor));\n\n // set the clipping planes for the actors\n this.resetCamera(resetCameraPanAndZoom, resetCameraPanAndZoom);\n }\n\n /**\n * Add an actor to the viewport including its id, its actor and slabThickness\n * if defined\n * @param actorEntry - ActorEntry\n * @param actorEntry.uid - The unique identifier for the actor.\n * @param actorEntry.actor - The volume actor.\n * @param actorEntry.slabThickness - The slab thickness.\n */\n public addActor(actorEntry: ActorEntry): void {\n const { uid: actorUID, actor } = actorEntry;\n const renderingEngine = this.getRenderingEngine();\n\n if (!renderingEngine || renderingEngine.hasBeenDestroyed) {\n console.warn(\n `Cannot add actor UID of ${actorUID} Rendering Engine has been destroyed`\n );\n return;\n }\n\n if (!actorUID || !actor) {\n throw new Error('Actors should have uid and vtk Actor properties');\n }\n\n if (this.getActor(actorUID)) {\n console.warn(`Actor ${actorUID} already exists for this viewport`);\n return;\n }\n\n const renderer = this.getRenderer();\n renderer.addActor(actor);\n this._actors.set(actorUID, Object.assign({}, actorEntry));\n }\n\n /**\n * Remove all actors from the renderer\n */\n public removeAllActors(): void {\n this.getRenderer().removeAllViewProps();\n this._actors = new Map();\n return;\n }\n\n /**\n * Reset the camera to the default viewport camera without firing events\n */\n protected resetCameraNoEvent(): void {\n this._suppressCameraModifiedEvents = true;\n this.resetCamera();\n this._suppressCameraModifiedEvents = false;\n }\n\n /**\n * Sets the camera to the default viewport camera without firing events\n * @param camera - The camera to use for the viewport.\n */\n protected setCameraNoEvent(camera: ICamera): void {\n this._suppressCameraModifiedEvents = true;\n this.setCamera(camera);\n this._suppressCameraModifiedEvents = false;\n }\n\n /**\n * Calculates the intersections between the volume's boundaries and the viewplane.\n * 1) Determine the viewplane using the camera's ViewplaneNormal and focalPoint.\n * 2) Using volumeBounds, calculate the line equation for the 3D volume's 12 edges.\n * 3) Intersect each edge to the viewPlane and see whether the intersection point is inside the volume bounds.\n * 4) Return list of intersection points\n * It should be noted that intersection points may range from 3 to 6 points.\n * Orthogonal views have four points of intersection.\n *\n * @param imageData - vtkImageData\n * @param focalPoint - camera focal point\n * @param normal - view plane normal\n * @returns intersections list\n */\n private _getViewImageDataIntersections(imageData, focalPoint, normal) {\n // Viewplane equation: Ax+By+Cz=D\n const A = normal[0];\n const B = normal[1];\n const C = normal[2];\n const D = A * focalPoint[0] + B * focalPoint[1] + C * focalPoint[2];\n\n // Computing the edges of the 3D cube\n const bounds = imageData.getBounds();\n const edges = this._getEdges(bounds);\n\n const intersections = [];\n\n for (const edge of edges) {\n // start point: [x0, y0, z0], end point: [x1, y1, z1]\n const [[x0, y0, z0], [x1, y1, z1]] = edge;\n // Check if the edge is parallel to plane\n if (A * (x1 - x0) + B * (y1 - y0) + C * (z1 - z0) === 0) {\n continue;\n }\n const intersectionPoint = planar.linePlaneIntersection(\n [x0, y0, z0],\n [x1, y1, z1],\n [A, B, C, D]\n );\n\n if (this._isInBounds(intersectionPoint, bounds)) {\n intersections.push(intersectionPoint);\n }\n }\n\n return intersections;\n }\n\n /**\n * Resets the camera based on the rendering volume(s) bounds. If\n * resetPan and resetZoom are true it places the focal point at the center of\n * the volume (or slice); otherwise, only the camera zoom and camera Pan or Zoom\n * is reset for the current view.\n * @param resetPan - If true, the camera focal point is reset to the center of the volume (slice)\n * @param resetZoom - If true, the camera zoom is reset to the default zoom\n * @param storeAsInitialCamera - If true, reset camera is stored as the initial camera (to allow differences to\n * be detected for pan/zoom values)\n * @returns boolean\n */\n protected resetCamera(\n resetPan = true,\n resetZoom = true,\n resetToCenter = true,\n storeAsInitialCamera = true\n ): boolean {\n const renderer = this.getRenderer();\n\n // fix the flip right away, since we rely on the viewPlaneNormal and\n // viewUp for later. Basically, we need to flip back if flipHorizontal\n // is true or flipVertical is true\n this.setCamera({\n flipHorizontal: false,\n flipVertical: false,\n });\n\n const previousCamera = _cloneDeep(this.getCamera());\n\n const bounds = renderer.computeVisiblePropBounds();\n const focalPoint = <Point3>[0, 0, 0];\n const imageData = this.getDefaultImageData();\n\n // Todo: remove this, this is just for tests passing\n if (imageData) {\n const spc = imageData.getSpacing();\n\n bounds[0] = bounds[0] + spc[0] / 2;\n bounds[1] = bounds[1] - spc[0] / 2;\n bounds[2] = bounds[2] + spc[1] / 2;\n bounds[3] = bounds[3] - spc[1] / 2;\n bounds[4] = bounds[4] + spc[2] / 2;\n bounds[5] = bounds[5] - spc[2] / 2;\n }\n\n const activeCamera = this.getVtkActiveCamera();\n const viewPlaneNormal = <Point3>activeCamera.getViewPlaneNormal();\n const viewUp = <Point3>activeCamera.getViewUp();\n\n // Reset the perspective zoom factors, otherwise subsequent zooms will cause\n // the view angle to become very small and cause bad depth sorting.\n // todo: parallel projection only\n\n focalPoint[0] = (bounds[0] + bounds[1]) / 2.0;\n focalPoint[1] = (bounds[2] + bounds[3]) / 2.0;\n focalPoint[2] = (bounds[4] + bounds[5]) / 2.0;\n\n if (imageData) {\n const dimensions = imageData.getDimensions();\n const middleIJK = dimensions.map((d) => Math.floor(d / 2));\n\n const idx = [middleIJK[0], middleIJK[1], middleIJK[2]];\n imageData.indexToWorld(idx, focalPoint);\n }\n\n const { widthWorld, heightWorld } =\n this._getWorldDistanceViewUpAndViewRight(bounds, viewUp, viewPlaneNormal);\n\n const canvasSize = [this.sWidth, this.sHeight];\n\n const boundsAspectRatio = widthWorld / heightWorld;\n const canvasAspectRatio = canvasSize[0] / canvasSize[1];\n\n let radius;\n\n if (boundsAspectRatio < canvasAspectRatio) {\n // can fit full height, so use it.\n radius = heightWorld / 2;\n } else {\n const scaleFactor = boundsAspectRatio / canvasAspectRatio;\n\n radius = (heightWorld * scaleFactor) / 2;\n }\n\n //const angle = vtkMath.radiansFromDegrees(activeCamera.getViewAngle())\n const parallelScale = 1.1 * radius;\n\n let w1 = bounds[1] - bounds[0];\n let w2 = bounds[3] - bounds[2];\n let w3 = bounds[5] - bounds[4];\n w1 *= w1;\n w2 *= w2;\n w3 *= w3;\n radius = w1 + w2 + w3;\n\n // If we have just a single point, pick a radius of 1.0\n radius = radius === 0 ? 1.0 : radius;\n\n // compute the radius of the enclosing sphere\n radius = Math.sqrt(radius) * 0.5;\n\n const distance = 1.1 * radius;\n\n const viewUpToSet: Point3 =\n Math.abs(vtkMath.dot(viewUp, viewPlaneNormal)) > 0.999\n ? [-viewUp[2], viewUp[0], viewUp[1]]\n : viewUp;\n\n const focalPointToSet = this._getFocalPointForResetCamera(\n focalPoint,\n previousCamera,\n { resetPan, resetToCenter }\n );\n\n const positionToSet: Point3 = [\n focalPointToSet[0] + distance * viewPlaneNormal[0],\n focalPointToSet[1] + distance * viewPlaneNormal[1],\n focalPointToSet[2] + distance * viewPlaneNormal[2],\n ];\n\n renderer.resetCameraClippingRange(bounds);\n\n const clippingRangeToUse: Point2 = [\n -RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE,\n RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE,\n ];\n\n activeCamera.setPhysicalScale(radius);\n activeCamera.setPhysicalTranslation(\n -focalPointToSet[0],\n -focalPointToSet[1],\n -focalPointToSet[2]\n );\n\n this.setCamera({\n parallelScale: resetZoom ? parallelScale : previousCamera.parallelScale,\n focalPoint: focalPointToSet,\n position: positionToSet,\n viewAngle: 90,\n viewUp: viewUpToSet,\n clippingRange: clippingRangeToUse,\n });\n\n const modifiedCamera = _cloneDeep(this.getCamera());\n\n if (storeAsInitialCamera) {\n this.setInitialCamera(modifiedCamera);\n }\n\n const RESET_CAMERA_EVENT = {\n type: 'ResetCameraEvent',\n renderer,\n };\n\n // Here to let parallel/distributed compositing intercept\n // and do the right thing.\n renderer.invokeEvent(RESET_CAMERA_EVENT);\n\n this.triggerCameraModifiedEventIfNecessary(previousCamera, modifiedCamera);\n\n return true;\n }\n\n /**\n * Sets the provided camera as the initial camera.\n * This allows computing differences applied later as compared to the initial\n * position, for things like zoom and pan.\n * @param camera - to store as the initial value.\n */\n protected setInitialCamera(camera: ICamera): void {\n this.initialCamera = camera;\n }\n\n /**\n * Helper function to return the current canvas pan value.\n *\n * @returns a Point2 containing the current pan values\n * on the canvas,\n * computed from the current camera, where the initial pan\n * value is [0,0].\n */\n public getPan(): Point2 {\n const activeCamera = this.getVtkActiveCamera();\n const focalPoint = activeCamera.getFocalPoint() as Point3;\n\n const zero3 = this.canvasToWorld([0, 0]);\n const initialCanvasFocal = this.worldToCanvas(\n <Point3>vec3.subtract(vec3.create(), this.initialCamera.focalPoint, zero3)\n );\n const currentCanvasFocal = this.worldToCanvas(\n <Point3>vec3.subtract(vec3.create(), focalPoint, zero3)\n );\n const result = <Point2>(\n vec2.subtract(vec2.create(), initialCanvasFocal, currentCanvasFocal)\n );\n return result;\n }\n\n /**\n * Sets the canvas pan value relative to the initial view position of 0,0\n * Modifies the camera to perform the pan.\n */\n public setPan(pan: Point2, storeAsInitialCamera = false): void {\n const previousCamera = this.getCamera();\n const { focalPoint, position } = previousCamera;\n const zero3 = this.canvasToWorld([0, 0]);\n const delta2 = vec2.subtract(vec2.create(), pan, this.getPan());\n if (\n Math.abs(delta2[0]) < 1 &&\n Math.abs(delta2[1]) < 1 &&\n !storeAsInitialCamera\n ) {\n return;\n }\n const delta = vec3.subtract(\n vec3.create(),\n this.canvasToWorld(<Point2>delta2),\n zero3\n );\n const newFocal = vec3.subtract(vec3.create(), focalPoint, delta);\n const newPosition = vec3.subtract(vec3.create(), position, delta);\n this.setCamera(\n {\n ...previousCamera,\n focalPoint: newFocal as Point3,\n position: newPosition as Point3,\n },\n storeAsInitialCamera\n );\n }\n\n /**\n * Returns a current zoom level relative to the initial parallel scale\n * originally applied to the image. That is, on initial display,\n * the zoom level is 1. Computed as a function of the camera.\n */\n public getZoom(): number {\n const activeCamera = this.getVtkActiveCamera();\n const { parallelScale: initialParallelScale } = this.initialCamera;\n return initialParallelScale / activeCamera.getParallelScale();\n }\n\n /** Zooms the image using parallel scale by updating the camera value.\n * @param value - The relative parallel scale to apply. It is relative\n * to the initial offsets value.\n * @param storeAsInitialCamera - can be set to true to reset the camera\n * after applying this zoom as the initial camera. A subsequent getZoom\n * call will return \"1\", but the zoom will have been applied.\n */\n public setZoom(value: number, storeAsInitialCamera = false): void {\n const camera = this.getCamera();\n const { parallelScale: initialParallelScale } = this.initialCamera;\n const parallelScale = initialParallelScale / value;\n if (camera.parallelScale === parallelScale && !storeAsInitialCamera) {\n return;\n }\n this.setCamera(\n {\n ...camera,\n parallelScale,\n },\n storeAsInitialCamera\n );\n }\n\n /**\n * Because the focalPoint is always in the centre of the viewport,\n * we must do planar computations if the frame (image \"slice\") is to be preserved.\n * 1. Calculate the intersection of the view plane with the imageData\n * which results in points of intersection (minimum of 3, maximum of 6)\n * 2. Calculate average of the intersection points to get newFocalPoint\n * 3. Set the new focalPoint\n * @param imageData - imageData\n * @returns focalPoint\n */\n private _getFocalPointForViewPlaneReset(imageData) {\n // Todo: move some where else\n const { focalPoint, viewPlaneNormal: normal } = this.getCamera();\n const intersections = this._getViewImageDataIntersections(\n imageData,\n focalPoint,\n normal\n );\n\n let x = 0;\n let y = 0;\n let z = 0;\n\n intersections.forEach(([point_x, point_y, point_z]) => {\n x += point_x;\n y += point_y;\n z += point_z;\n });\n\n const newFocalPoint = <Point3>[\n x / intersections.length,\n y / intersections.length,\n z / intersections.length,\n ];\n // Set the focal point on the average of the intersection points\n return newFocalPoint;\n }\n\n /**\n * Gets the target output canvas for the `Viewport`.\n *\n * @returns an HTMLCanvasElement.\n */\n public getCanvas(): HTMLCanvasElement {\n return <HTMLCanvasElement>this.canvas;\n }\n /**\n * Gets the active vtkCamera for the viewport.\n *\n * @returns vtk driven camera\n */\n protected getVtkActiveCamera(): vtkCamera | vtkSlabCamera {\n const renderer = this.getRenderer();\n\n return renderer.getActiveCamera();\n }\n\n /**\n * Get the camera's current state\n * @returns The camera object.\n */\n public getCamera(): ICamera {\n const vtkCamera = this.getVtkActiveCamera();\n\n return {\n viewUp: <Point3>vtkCamera.getViewUp(),\n viewPlaneNormal: <Point3>vtkCamera.getViewPlaneNormal(),\n position: <Point3>vtkCamera.getPosition(),\n focalPoint: <Point3>vtkCamera.getFocalPoint(),\n parallelProjection: vtkCamera.getParallelProjection(),\n parallelScale: vtkCamera.getParallelScale(),\n viewAngle: vtkCamera.getViewAngle(),\n flipHorizontal: this.flipHorizontal,\n flipVertical: this.flipVertical,\n };\n }\n\n /**\n * Set the camera parameters\n * @param cameraInterface - ICamera\n * @param storeAsInitialCamera - to set the provided camera as the initial one,\n * used to compute differences for things like pan and zoom.\n */\n public setCamera(\n cameraInterface: ICamera,\n storeAsInitialCamera = false\n ): void {\n const vtkCamera = this.getVtkActiveCamera();\n const previousCamera = _cloneDeep(this.getCamera());\n const updatedCamera = Object.assign({}, previousCamera, cameraInterface);\n const {\n viewUp,\n viewPlaneNormal,\n position,\n focalPoint,\n parallelScale,\n viewAngle,\n flipHorizontal,\n flipVertical,\n clippingRange,\n } = cameraInterface;\n\n // Note: Flip camera should be two separate calls since\n // for flip, we need to flip the viewportNormal, and if\n // flipHorizontal, and flipVertical are both true, that would\n // the logic would be incorrect. So instead, we handle flip Horizontal\n // and flipVertical separately.\n if (flipHorizontal !== undefined) {\n // flip if not flipped but requested to flip OR if flipped but requested to\n // not flip\n const flipH =\n (flipHorizontal && !this.flipHorizontal) ||\n (!flipHorizontal && this.flipHorizontal);\n\n if (flipH) {\n this.flip({ flipHorizontal: flipH });\n }\n }\n\n if (flipVertical !== undefined) {\n const flipV =\n (flipVertical && !this.flipVertical) ||\n (!flipVertical && this.flipVertical);\n\n if (flipV) {\n this.flip({ flipVertical: flipV });\n }\n }\n\n if (viewUp !== undefined) {\n vtkCamera.setViewUp(viewUp);\n }\n\n if (viewPlaneNormal !== undefined) {\n vtkCamera.setDirectionOfProjection(\n -viewPlaneNormal[0],\n -viewPlaneNormal[1],\n -viewPlaneNormal[2]\n );\n }\n\n if (position !== undefined) {\n vtkCamera.setPosition(...position);\n }\n\n if (focalPoint !== undefined) {\n vtkCamera.setFocalPoint(...focalPoint);\n }\n\n if (parallelScale !== undefined) {\n vtkCamera.setParallelScale(parallelScale);\n }\n\n if (viewAngle !== undefined) {\n vtkCamera.setViewAngle(viewAngle);\n }\n\n if (clippingRange !== undefined) {\n vtkCamera.setClippingRange(clippingRange);\n }\n\n // update clippingPlanes if volume viewports\n const actorEntry = this.getDefaultActor();\n if (actorEntry?.actor?.isA('vtkVolume')) {\n this.updateClippingPlanesForActors(updatedCamera);\n }\n\n if (actorEntry?.actor?.isA('vtkImageSlice')) {\n const renderer = this.getRenderer();\n renderer.resetCameraClippingRange();\n }\n\n if (storeAsInitialCamera) {\n this.setInitialCamera(updatedCamera);\n }\n\n this.triggerCameraModifiedEventIfNecessary(\n previousCamera,\n this.getCamera()\n );\n }\n\n /**\n * Trigger camera modified event\n * @param cameraInterface - ICamera\n * @param cameraInterface - ICamera\n */\n public triggerCameraModifiedEventIfNecessary(\n previousCamera: ICamera,\n updatedCamera: ICamera\n ): void {\n if (!this._suppressCameraModifiedEvents && !this.suppressEvents) {\n const eventDetail: EventTypes.CameraModifiedEventDetail = {\n previousCamera,\n camera: updatedCamera,\n element: this.element,\n viewportId: this.id,\n renderingEngineId: this.renderingEngineId,\n rotation: this.rotation,\n };\n\n triggerEvent(this.element, Events.CAMERA_MODIFIED, eventDetail);\n }\n }\n\n /**\n * Updates the actors clipping planes orientation from the camera properties\n * @param updatedCamera - ICamera\n */\n protected updateClippingPlanesForActors(updatedCamera: ICamera): void {\n const actorEntries = this.getActors();\n actorEntries.forEach((actorEntry) => {\n // we assume that the first two clipping plane of the mapper are always\n // the 'camera' clipping. Update clipping planes only if the actor is\n // a vtkVolume\n if (!actorEntry.actor || !isImageActor(actorEntry.actor)) {\n return;\n }\n\n const mapper = actorEntry.actor.getMapper();\n const vtkPlanes = mapper.getClippingPlanes();\n\n let slabThickness = RENDERING_DEFAULTS.MINIMUM_SLAB_THICKNESS;\n if (actorEntry.slabThickness) {\n slabThickness = actorEntry.slabThickness;\n }\n\n const { viewPlaneNormal, focalPoint } = updatedCamera;\n\n this.setOrientationOfClippingPlanes(\n vtkPlanes,\n slabThickness,\n viewPlaneNormal,\n focalPoint\n );\n });\n }\n\n public setOrientationOfClippingPlanes(\n vtkPlanes: Array<vtkPlane>,\n slabThickness: number,\n viewPlaneNormal: Point3,\n focalPoint: Point3\n ): void {\n if (vtkPlanes.length < 2) {\n return;\n }\n\n const scaledDistance = <Point3>[\n viewPlaneNormal[0],\n viewPlaneNormal[1],\n viewPlaneNormal[2],\n ];\n vtkMath.multiplyScalar(scaledDistance, slabThickness);\n\n vtkPlanes[0].setNormal(viewPlaneNormal);\n const newOrigin1 = <Point3>[0, 0, 0];\n vtkMath.subtract(focalPoint, scaledDistance, newOrigin1);\n vtkPlanes[0].setOrigin(newOrigin1);\n\n vtkPlanes[1].setNormal(\n -viewPlaneNormal[0],\n -viewPlaneNormal[1],\n -viewPlaneNormal[2]\n );\n const newOrigin2 = <Point3>[0, 0, 0];\n vtkMath.add(focalPoint, scaledDistance, newOrigin2);\n vtkPlanes[1].setOrigin(newOrigin2);\n }\n\n private _getWorldDistanceViewUpAndViewRight(bounds, viewUp, viewPlaneNormal) {\n const viewUpCorners = this._getCorners(bounds);\n const viewRightCorners = this._getCorners(bounds);\n\n const viewRight = vec3.cross(vec3.create(), viewUp, viewPlaneNormal);\n\n let transform = vtkMatrixBuilder\n .buildFromDegree()\n .identity()\n .rotateFromDirections(viewUp, [1, 0, 0]);\n\n viewUpCorners.forEach((pt) => transform.apply(pt));\n\n // range is now maximum X distance\n let minY = Infinity;\n let maxY = -Infinity;\n for (let i = 0; i < 8; i++) {\n const y = viewUpCorners[i][0];\n if (y > maxY) {\n maxY = y;\n }\n if (y < minY) {\n minY = y;\n }\n }\n\n transform = vtkMatrixBuilder\n .buildFromDegree()\n .identity()\n .rotateFromDirections(\n [viewRight[0], viewRight[1], viewRight[2]],\n [1, 0, 0]\n );\n\n viewRightCorners.forEach((pt) => transform.apply(pt));\n\n // range is now maximum Y distance\n let minX = Infinity;\n let maxX = -Infinity;\n for (let i = 0; i < 8; i++) {\n const x = viewRightCorners[i][0];\n if (x > maxX) {\n maxX = x;\n }\n if (x < minX) {\n minX = x;\n }\n }\n\n return { widthWorld: maxX - minX, heightWorld: maxY - minY };\n }\n\n _getCorners(bounds: Array<number>): Array<number>[] {\n return [\n [bounds[0], bounds[2], bounds[4]],\n [bounds[0], bounds[2], bounds[5]],\n [bounds[0], bounds[3], bounds[4]],\n [bounds[0], bounds[3], bounds[5]],\n [bounds[1], bounds[2], bounds[4]],\n [bounds[1], bounds[2], bounds[5]],\n [bounds[1], bounds[3], bounds[4]],\n [bounds[1], bounds[3], bounds[5]],\n ];\n }\n\n _getFocalPointForResetCamera(\n centeredFocalPoint: Point3,\n previousCamera: ICamera,\n { resetPan = true, resetToCenter = true }\n ): Point3 {\n if (resetToCenter && resetPan) {\n return centeredFocalPoint;\n }\n\n if (resetToCenter && !resetPan) {\n return hasNaNValues(previousCamera.focalPoint)\n ? centeredFocalPoint\n : previousCamera.focalPoint;\n }\n\n if (!resetToCenter && resetPan) {\n // this is an interesting case that means the reset camera should not\n // change the slice (default behavior is to go to the center of the\n // image), and rather just reset the pan on the slice that is currently\n // being viewed\n const oldCamera = previousCamera;\n const oldFocalPoint = oldCamera.focalPoint;\n const oldViewPlaneNormal = oldCamera.viewPlaneNormal;\n\n const vectorFromOldFocalPointToCenteredFocalPoint = vec3.subtract(\n vec3.create(),\n centeredFocalPoint,\n oldFocalPoint\n );\n\n const distanceFromOldFocalPointToCenteredFocalPoint = vec3.dot(\n vectorFromOldFocalPointToCenteredFocalPoint,\n oldViewPlaneNormal\n );\n\n const newFocalPoint = vec3.scaleAndAdd(\n vec3.create(),\n centeredFocalPoint,\n oldViewPlaneNormal,\n -1 * distanceFromOldFocalPointToCenteredFocalPoint\n );\n\n return [newFocalPoint[0], newFocalPoint[1], newFocalPoint[2]];\n }\n\n if (!resetPan && !resetToCenter) {\n // this means the reset camera should not change the slice and should not\n // touch the pan either.\n return hasNaNValues(previousCamera.focalPoint)\n ? centeredFocalPoint\n : previousCamera.focalPoint;\n }\n }\n\n /**\n * Determines whether or not the 3D point position is inside the boundaries of the 3D imageData.\n * @param point - 3D coordinate\n * @param bounds - Bounds of the image\n * @returns boolean\n */\n _isInBounds(point: Point3, bounds: number[]): boolean {\n const [xMin, xMax, yMin, yMax, zMin, zMax] = bounds;\n const [x, y, z] = point;\n if (x < xMin || x > xMax || y < yMin || y > yMax || z < zMin || z > zMax) {\n return false;\n }\n return true;\n }\n\n /**\n * Returns a list of edges for the imageData bounds, which are\n * the cube edges in the case of volumeViewport edges.\n * p1: front, bottom, left\n * p2: front, top, left\n * p3: back, bottom, left\n * p4: back, top, left\n * p5: front, bottom, right\n * p6: front, top, right\n * p7: back, bottom, right\n * p8: back, top, right\n * @param bounds - Bounds of the renderer\n * @returns Edges of the containing bounds\n */\n _getEdges(bounds: Array<number>): Array<[number[], number[]]> {\n const [p1, p2, p3, p4, p5, p6, p7, p8] = this._getCorners(bounds);\n return [\n [p1, p2],\n [p1, p5],\n [p1, p3],\n [p2, p4],\n [p2, p6],\n [p3, p4],\n [p3, p7],\n [p4, p8],\n [p5, p7],\n [p5, p6],\n [p6, p8],\n [p7, p8],\n ];\n }\n}\n\nexport default Viewport;\n","import { Point3 } from '../types';\n\n/**\n * Converts `vtkVolumeActor` bounds to corners in world space.\n *\n * @param volumeActor - The `vtkVolumeActor`.\n *\n * @returns An array of the corners of the `volumeActor` in world space.\n */\nexport default function getVolumeActorCorners(volumeActor): Array<Point3> {\n const imageData = volumeActor.getMapper().getInputData();\n const bounds = imageData.extentToBounds(imageData.getExtent());\n\n return [\n [bounds[0], bounds[2], bounds[4]],\n [bounds[0], bounds[2], bounds[5]],\n [bounds[0], bounds[3], bounds[4]],\n [bounds[0], bounds[3], bounds[5]],\n [bounds[1], bounds[2], bounds[4]],\n [bounds[1], bounds[2], bounds[5]],\n [bounds[1], bounds[3], bounds[4]],\n [bounds[1], bounds[3], bounds[5]],\n ];\n}\n","import vtkMatrixBuilder from '@kitware/vtk.js/Common/Core/MatrixBuilder';\nimport getVolumeActorCorners from './getVolumeActorCorners';\nimport type { VolumeActor, Point3, ActorSliceRange } from '../types';\n\n/**\n * Given a `vtkVolumeActor`, and a normal direction,\n * calculate the range of slices in the focal normal direction that encapsulate\n * the volume. Also project the `focalPoint` onto this range.\n *\n * @param volumeActor - The `vtkVolumeActor`.\n * @param viewPlaneNormal - The normal to the camera view.\n * @param focalPoint - The focal point of the camera.\n *\n * @returns an object containing the `min`, `max` and `current`\n * positions in the normal direction.\n */\nexport default function getSliceRange(\n volumeActor: VolumeActor,\n viewPlaneNormal: Point3,\n focalPoint: Point3\n): ActorSliceRange {\n const corners = getVolumeActorCorners(volumeActor);\n\n // Get rotation matrix from normal to +X (since bounds is aligned to XYZ)\n const transform = vtkMatrixBuilder\n .buildFromDegree()\n .identity()\n .rotateFromDirections(viewPlaneNormal, [1, 0, 0]);\n\n corners.forEach((pt) => transform.apply(pt));\n\n const transformedFocalPoint = [...focalPoint];\n\n transform.apply(transformedFocalPoint);\n\n const currentSlice = transformedFocalPoint[0];\n\n // range is now maximum X distance\n let minX = Infinity;\n let maxX = -Infinity;\n for (let i = 0; i < 8; i++) {\n const x = corners[i][0];\n if (x > maxX) {\n maxX = x;\n }\n if (x < minX) {\n minX = x;\n }\n }\n\n return {\n min: minX,\n max: maxX,\n current: currentSlice,\n actor: volumeActor,\n viewPlaneNormal,\n focalPoint,\n };\n}\n","import { vec3 } from 'gl-matrix';\nimport { IImageVolume, Point3 } from '../types';\n\n/**\n * Given an `imageVolume` and a normal direction (`viewPlaneNormal`), calculates\n * the spacing between voxels in the normal direction. If (`viewPlaneNormal`) is\n * parallel to one of the directions you will obtain the spacing in that direction.\n * Otherwise each of the `imageVolume`'s directions are projected onto the volume,\n * so that you obtain a spacing of the order of \"seeing a new set of voxels if the camera where to dolly\".\n *\n * @param imageVolume - The image volume to calculate the spacing in the normal direction.\n * @param viewPlaneNormal - The normal direction of the view plane.\n * @returns\n */\nexport default function getSpacingInNormalDirection(\n imageVolume: IImageVolume,\n viewPlaneNormal: Point3\n): number {\n const { direction, spacing } = imageVolume;\n\n // Calculate size of spacing vector in normal direction\n const iVector = direction.slice(0, 3) as Point3;\n const jVector = direction.slice(3, 6) as Point3;\n const kVector = direction.slice(6, 9) as Point3;\n\n const dotProducts = [\n vec3.dot(iVector, <vec3>viewPlaneNormal),\n vec3.dot(jVector, <vec3>viewPlaneNormal),\n vec3.dot(kVector, <vec3>viewPlaneNormal),\n ];\n\n const projectedSpacing = vec3.create();\n\n vec3.set(\n projectedSpacing,\n dotProducts[0] * spacing[0],\n dotProducts[1] * spacing[1],\n dotProducts[2] * spacing[2]\n );\n\n const spacingInNormalDirection = vec3.length(projectedSpacing);\n\n return spacingInNormalDirection;\n}\n","import cache from '../cache/cache';\n// import type { VolumeViewport } from '../RenderingEngine'\nimport { ICamera, IImageVolume, IVolumeViewport } from '../types';\nimport getSpacingInNormalDirection from './getSpacingInNormalDirection';\n\n/**\n * Given a volume viewport and camera, find the target volume.\n * The imageVolume is retrieved from cache for the specified targetVolumeId or\n * in case it is not provided, it chooses the volumeId on the viewport (there\n * might be more than one in case of fusion) that has the finest resolution in the\n * direction of view (normal).\n *\n * @param viewport - volume viewport\n * @param camera - current camera\n * @param targetVolumeId - If a target volumeId is given that volume\n * is forced to be used.\n *\n * @returns An object containing the imageVolume and spacingInNormalDirection.\n *\n */\nexport default function getTargetVolumeAndSpacingInNormalDir(\n viewport: IVolumeViewport,\n camera: ICamera,\n targetVolumeId?: string\n): {\n imageVolume: IImageVolume;\n spacingInNormalDirection: number;\n} {\n const { viewPlaneNormal } = camera;\n const volumeActors = viewport.getActors();\n\n if (!volumeActors || !volumeActors.length) {\n return { spacingInNormalDirection: null, imageVolume: null };\n }\n const numVolumeActors = volumeActors.length;\n\n const imageVolumes = volumeActors.map((va) => {\n // prefer the referenceUID if it is set, since it can be a derived actor\n // and the uid does not necessarily match the volumeId\n const uid = va.referenceId ?? va.uid;\n return cache.getVolume(uid);\n });\n\n // If a volumeId is defined, set that volume as the target\n if (targetVolumeId) {\n const imageVolume = imageVolumes.find(\n (iv) => iv.volumeId === targetVolumeId\n );\n\n const spacingInNormalDirection = getSpacingInNormalDirection(\n imageVolume,\n viewPlaneNormal\n );\n\n return { imageVolume, spacingInNormalDirection };\n }\n\n // Fetch volume actor with finest resolution in direction of projection.\n const smallest = {\n spacingInNormalDirection: Infinity,\n imageVolume: null,\n };\n\n for (let i = 0; i < numVolumeActors; i++) {\n const imageVolume = imageVolumes[i];\n\n const spacingInNormalDirection = getSpacingInNormalDirection(\n imageVolume,\n viewPlaneNormal\n );\n\n if (spacingInNormalDirection < smallest.spacingInNormalDirection) {\n smallest.spacingInNormalDirection = spacingInNormalDirection;\n smallest.imageVolume = imageVolume;\n }\n }\n\n return smallest;\n}\n","import { ImageSliceData, IVolumeViewport, VolumeActor } from '../types';\nimport getSliceRange from './getSliceRange';\nimport getTargetVolumeAndSpacingInNormalDir from './getTargetVolumeAndSpacingInNormalDir';\n\n/**\n * It calculates the number of slices and the current slice index for a given\n * Volume viewport\n * @param viewport - volume viewport\n * @returns An object with two properties: numberOfSlices and imageIndex.\n */\nfunction getImageSliceDataForVolumeViewport(\n viewport: IVolumeViewport\n): ImageSliceData {\n const camera = viewport.getCamera();\n\n const { spacingInNormalDirection, imageVolume } =\n getTargetVolumeAndSpacingInNormalDir(viewport, camera);\n\n if (!imageVolume) {\n return;\n }\n\n const { viewPlaneNormal, focalPoint } = camera;\n\n const actorEntry = viewport\n .getActors()\n .find(\n (a) =>\n a.referenceId === imageVolume.volumeId || a.uid === imageVolume.volumeId\n );\n\n if (!actorEntry) {\n console.warn('No actor found for with actorUID of', imageVolume.volumeId);\n }\n\n const volumeActor = actorEntry.actor as VolumeActor;\n const sliceRange = getSliceRange(volumeActor, viewPlaneNormal, focalPoint);\n\n const { min, max, current } = sliceRange;\n\n // calculate number of steps from min to max with current normal spacing in direction\n const numberOfSlices = Math.round((max - min) / spacingInNormalDirection) + 1;\n\n // calculate the imageIndex based on min, max, current\n let imageIndex = ((current - min) / (max - min)) * numberOfSlices;\n imageIndex = Math.floor(imageIndex);\n\n // Clamp imageIndex\n if (imageIndex > numberOfSlices - 1) {\n imageIndex = numberOfSlices - 1;\n } else if (imageIndex < 0) {\n imageIndex = 0;\n }\n\n return {\n numberOfSlices,\n imageIndex,\n };\n}\n\nexport default getImageSliceDataForVolumeViewport;\n","import renderingEngineCache from './renderingEngineCache';\nimport type { IRenderingEngine } from '../types';\n\n/**\n * Method to retrieve a RenderingEngine by its unique identifier.\n *\n * @example\n * How to get a RenderingEngine that was created earlier:\n * ```javascript\n * import { RenderingEngine, getRenderingEngine } from 'vtkjs-viewport';\n *\n * const renderingEngine = new RenderingEngine('my-engine');\n *\n * // getting reference to rendering engine later...\n * const renderingEngine = getRenderingEngine('my-engine');\n * ```\n *\n * @param id - The identifier that was used to create the RenderingEngine\n * @returns the matching RenderingEngine, or `undefined` if there is no match\n * @public\n */\nexport function getRenderingEngine(id: string): IRenderingEngine | undefined {\n return renderingEngineCache.get(id);\n}\n\n/**\n * Get all the rendering engines that are currently registered\n * @returns An array of rendering engines.\n */\nexport function getRenderingEngines(): IRenderingEngine[] | undefined {\n return renderingEngineCache.getAll();\n}\n\nexport default getRenderingEngine;\n","import {\n getImageSliceDataForVolumeViewport,\n triggerEvent,\n} from '../../utilities';\nimport { EventTypes } from '../../types';\nimport { Events } from '../../enums';\nimport { getRenderingEngine } from '../getRenderingEngine';\nimport BaseVolumeViewport from '../BaseVolumeViewport';\n\n// Keeping track of previous imageIndex for each viewportId\ntype VolumeImageState = Record<string, number>;\n\nconst state: VolumeImageState = {};\n\nexport function resetVolumeNewImageState(viewportId: string): void {\n if (state[viewportId] !== undefined) {\n delete state[viewportId];\n }\n}\n\n/**\n * It captures the camera modified event and with the camera focal point and viewPlaneNomad\n * it calculates the image index in the view direction. Finally it triggers\n * a VOLUME_NEW_IMAGE event with the image index.\n *\n * @internal\n *\n * @param cameraEvent - The camera modified event\n * @param viewportImageData - The image data of the viewport\n */\nfunction volumeNewImageEventDispatcher(\n cameraEvent: EventTypes.CameraModifiedEvent\n): void {\n const { renderingEngineId, viewportId } = cameraEvent.detail;\n const renderingEngine = getRenderingEngine(renderingEngineId);\n const viewport = renderingEngine.getViewport(viewportId);\n\n if (!(viewport instanceof BaseVolumeViewport)) {\n throw new Error(\n `volumeNewImageEventDispatcher: viewport is not a BaseVolumeViewport`\n );\n }\n\n if (state[viewport.id] === undefined) {\n state[viewport.id] = 0;\n }\n\n const { numberOfSlices, imageIndex } =\n getImageSliceDataForVolumeViewport(viewport);\n\n if (state[viewport.id] === imageIndex) {\n return;\n }\n\n state[viewport.id] = imageIndex;\n\n const eventDetail: EventTypes.VolumeNewImageEventDetail = {\n imageIndex,\n viewportId,\n renderingEngineId,\n numberOfSlices,\n };\n\n triggerEvent(viewport.element, Events.VOLUME_NEW_IMAGE, eventDetail);\n}\n\nexport default volumeNewImageEventDispatcher;\n","import macro from '@kitware/vtk.js/macros';\nimport vtkCamera from '@kitware/vtk.js/Rendering/Core/Camera';\nimport { vec3, mat4 } from 'gl-matrix';\nimport vtkMath from '@kitware/vtk.js/Common/Core/Math';\n\n/**\n * vtkSlabCamera - A derived class of the core vtkCamera class\n *\n * This customization is necesssary because when we do coordinate transformations\n * we need to set the cRange between [d, d + 0.1],\n * where d is distance between the camera position and the focal point.\n * While when we render we set to the clippingRange [0.01, d * 2],\n * where d is the calculated from the bounds of all the actors.\n *\n * @param {*} publicAPI The public API to extend\n * @param {*} model The private model to extend.\n */\nfunction vtkSlabCamera(publicAPI, model) {\n model.classHierarchy.push('vtkSlabCamera');\n\n // Set up private variables and methods\n const tmpMatrix = mat4.identity(new Float64Array(16));\n const tmpvec1 = new Float64Array(3);\n\n /**\n * getProjectionMatrix - A fork of vtkCamera's getProjectionMatrix method.\n * This fork performs most of the same actions, but define crange around\n * model.distance when doing coordinate transformations.\n */\n publicAPI.getProjectionMatrix = (aspect, nearz, farz) => {\n const result = mat4.create();\n\n if (model.projectionMatrix) {\n const scale = 1 / model.physicalScale;\n vec3.set(tmpvec1, scale, scale, scale);\n\n mat4.copy(result, model.projectionMatrix);\n mat4.scale(result, result, tmpvec1);\n mat4.transpose(result, result);\n return result;\n }\n\n mat4.identity(tmpMatrix);\n\n let cRange0 = model.clippingRange[0];\n let cRange1 = model.clippingRange[1];\n if (model.isPerformingCoordinateTransformation) {\n /**\n * NOTE: this is necessary because we want the coordinate transformation\n * respect to the view plane (plane orthogonal to the camera and passing to\n * the focal point).\n *\n * When vtk.js computes the coordinate transformations, it simply uses the\n * camera matrix (no ray casting).\n *\n * However for the volume viewport the clipping range is set to be\n * (-RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE, RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE).\n * The clipping range is used in the camera method getProjectionMatrix().\n * The projection matrix is used then for viewToWorld/worldToView methods of\n * the renderer. This means that vkt.js will not return the coordinates of\n * the point on the view plane (i.e. the depth coordinate will corresponded\n * to the focal point).\n *\n * Therefore the clipping range has to be set to (distance, distance + 0.01),\n * where now distance is the distance between the camera position and focal\n * point. This is done internally, in our camera customization when the flag\n * isPerformingCoordinateTransformation is set to true.\n */\n cRange0 = model.distance;\n cRange1 = model.distance + 0.1;\n }\n\n const cWidth = cRange1 - cRange0;\n const cRange = [\n cRange0 + ((nearz + 1) * cWidth) / 2.0,\n cRange0 + ((farz + 1) * cWidth) / 2.0,\n ];\n\n if (model.parallelProjection) {\n // set up a rectangular parallelipiped\n const width = model.parallelScale * aspect;\n const height = model.parallelScale;\n\n const xmin = (model.windowCenter[0] - 1.0) * width;\n const xmax = (model.windowCenter[0] + 1.0) * width;\n const ymin = (model.windowCenter[1] - 1.0) * height;\n const ymax = (model.windowCenter[1] + 1.0) * height;\n\n mat4.ortho(tmpMatrix, xmin, xmax, ymin, ymax, cRange[0], cRange[1]);\n mat4.transpose(tmpMatrix, tmpMatrix);\n } else if (model.useOffAxisProjection) {\n throw new Error('Off-Axis projection is not supported at this time');\n } else {\n const tmp = Math.tan(vtkMath.radiansFromDegrees(model.viewAngle) / 2.0);\n let width;\n let height;\n if (model.useHorizontalViewAngle === true) {\n width = cRange0 * tmp;\n height = (cRange0 * tmp) / aspect;\n } else {\n width = cRange0 * tmp * aspect;\n height = cRange0 * tmp;\n }\n\n const xmin = (model.windowCenter[0] - 1.0) * width;\n const xmax = (model.windowCenter[0] + 1.0) * width;\n const ymin = (model.windowCenter[1] - 1.0) * height;\n const ymax = (model.windowCenter[1] + 1.0) * height;\n const znear = cRange[0];\n const zfar = cRange[1];\n\n tmpMatrix[0] = (2.0 * znear) / (xmax - xmin);\n tmpMatrix[5] = (2.0 * znear) / (ymax - ymin);\n tmpMatrix[2] = (xmin + xmax) / (xmax - xmin);\n tmpMatrix[6] = (ymin + ymax) / (ymax - ymin);\n tmpMatrix[10] = -(znear + zfar) / (zfar - znear);\n tmpMatrix[14] = -1.0;\n tmpMatrix[11] = (-2.0 * znear * zfar) / (zfar - znear);\n tmpMatrix[15] = 0.0;\n }\n\n mat4.copy(result, tmpMatrix);\n\n return result;\n };\n}\n\n// ----------------------------------------------------------------------------\n// Object factory\n// ----------------------------------------------------------------------------\n\n// ----------------------------------------------------------------------------\n\nconst DEFAULT_VALUES = {\n isPerformingCoordinateTransformation: false,\n};\n\nexport function extend(publicAPI, model, initialValues = {}) {\n Object.assign(model, DEFAULT_VALUES, initialValues);\n\n vtkCamera.extend(publicAPI, model, initialValues);\n\n macro.setGet(publicAPI, model, ['isPerformingCoordinateTransformation']);\n\n // Object methods\n vtkSlabCamera(publicAPI, model);\n}\n\n// ----------------------------------------------------------------------------\n\nexport const newInstance = macro.newInstance(extend, 'vtkSlabCamera');\n\n// ----------------------------------------------------------------------------\n\nexport default { newInstance, extend };\n","function e(e,t,r,n){return new(r||(r=Promise))((function(o,a){function i(e){try{d(n.next(e))}catch(e){a(e)}}function c(e){try{d(n.throw(e))}catch(e){a(e)}}function d(e){var t;e.done?o(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(i,c)}d((n=n.apply(e,t||[])).next())}))}const t=[\"geforce 320m\",\"geforce 8600\",\"geforce 8600m gt\",\"geforce 8800 gs\",\"geforce 8800 gt\",\"geforce 9400\",\"geforce 9400m g\",\"geforce 9400m\",\"geforce 9600m gt\",\"geforce 9600m\",\"geforce fx go5200\",\"geforce gt 120\",\"geforce gt 130\",\"geforce gt 330m\",\"geforce gtx 285\",\"google swiftshader\",\"intel g41\",\"intel g45\",\"intel gma 4500mhd\",\"intel gma x3100\",\"intel hd 3000\",\"intel q45\",\"legacy\",\"mali-2\",\"mali-3\",\"mali-4\",\"quadro fx 1500\",\"quadro fx 4\",\"quadro fx 5\",\"radeon hd 2400\",\"radeon hd 2600\",\"radeon hd 4670\",\"radeon hd 4850\",\"radeon hd 4870\",\"radeon hd 5670\",\"radeon hd 5750\",\"radeon hd 6290\",\"radeon hd 6300\",\"radeon hd 6310\",\"radeon hd 6320\",\"radeon hd 6490m\",\"radeon hd 6630m\",\"radeon hd 6750m\",\"radeon hd 6770m\",\"radeon hd 6970m\",\"sgx 543\",\"sgx543\"];function r(e){return e=e.toLowerCase().replace(/^angle ?\\((.+)\\)*$/,\"$1\").replace(/\\s(\\d{1,2}gb|direct3d.+$)|\\(r\\)| \\([^)]+\\)$/g,\"\").replace(/(?:vulkan|opengl) \\d+\\.\\d+(?:\\.\\d+)?(?: \\((.*)\\))?/,\"$1\")}const n=\"undefined\"==typeof window,o=(()=>{if(n)return;const{userAgent:e,platform:t,maxTouchPoints:r}=window.navigator,o=/(iphone|ipod|ipad)/i.test(e),a=\"iPad\"===t||\"MacIntel\"===t&&r>0&&!window.MSStream;return{isIpad:a,isMobile:/android/i.test(e)||o||a,isSafari12:/Version\\/12.+Safari/.test(e)}})();function a(e,t,r){if(!r)return[t];const n=function(e){const t=\"\\n precision highp float;\\n attribute vec3 aPosition;\\n varying float vvv;\\n void main() {\\n vvv = 0.31622776601683794;\\n gl_Position = vec4(aPosition, 1.0);\\n }\\n \",r=\"\\n precision highp float;\\n varying float vvv;\\n void main() {\\n vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * vvv;\\n enc = fract(enc);\\n enc -= enc.yzww * vec4(1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0, 0.0);\\n gl_FragColor = enc;\\n }\\n \",n=e.createShader(35633),o=e.createShader(35632),a=e.createProgram();if(!(o&&n&&a))return;e.shaderSource(n,t),e.shaderSource(o,r),e.compileShader(n),e.compileShader(o),e.attachShader(a,n),e.attachShader(a,o),e.linkProgram(a),e.detachShader(a,n),e.detachShader(a,o),e.deleteShader(n),e.deleteShader(o),e.useProgram(a);const i=e.createBuffer();e.bindBuffer(34962,i),e.bufferData(34962,new Float32Array([-1,-1,0,3,-1,0,-1,3,0]),35044);const c=e.getAttribLocation(a,\"aPosition\");e.vertexAttribPointer(c,3,5126,!1,0,0),e.enableVertexAttribArray(c),e.clearColor(1,1,1,1),e.clear(16384),e.viewport(0,0,1,1),e.drawArrays(4,0,3);const d=new Uint8Array(4);return e.readPixels(0,0,1,1,6408,5121,d),e.deleteProgram(a),e.deleteBuffer(i),d.join(\"\")}(e),a=\"801621810\",i=\"8016218135\",c=\"80162181161\",d=(null==o?void 0:o.isIpad)?[[\"a7\",c,12],[\"a8\",i,15],[\"a8x\",i,15],[\"a9\",i,15],[\"a9x\",i,15],[\"a10\",i,15],[\"a10x\",i,15],[\"a12\",a,15],[\"a12x\",a,15],[\"a12z\",a,15],[\"a14\",a,15],[\"m1\",a,15]]:[[\"a7\",c,12],[\"a8\",i,12],[\"a9\",i,15],[\"a10\",i,15],[\"a11\",a,15],[\"a12\",a,15],[\"a13\",a,15],[\"a14\",a,15]];let l;\"80162181255\"===n?l=d.filter((([,,e])=>e>=14)):(l=d.filter((([,e])=>e===n)),l.length||(l=d));return l.map((([e])=>`apple ${e} gpu`))}const i=[],c=[];function d(e,t){if(e===t)return 0;const r=e;e.length>t.length&&(e=t,t=r);let n=e.length,o=t.length;for(;n>0&&e.charCodeAt(~-n)===t.charCodeAt(~-o);)n--,o--;let a,d=0;for(;d<n&&e.charCodeAt(d)===t.charCodeAt(d);)d++;if(n-=d,o-=d,0===n)return o;let l,s,f=0,u=0,h=0;for(;u<n;)c[u]=e.charCodeAt(d+u),i[u]=++u;for(;h<o;)for(a=t.charCodeAt(d+h),l=h++,f=h,u=0;u<n;u++)s=a===c[u]?l:l+1,l=i[u],f=i[u]=l>f?s>f?f+1:s:s>l?l+1:s;return f}function l(e){return null!=e}class s extends Error{constructor(e){super(e),Object.setPrototypeOf(this,new.target.prototype)}}const f=({mobileTiers:i=[0,15,30,60],desktopTiers:c=[0,15,30,60],override:f={},glContext:u,failIfMajorPerformanceCaveat:h=!1,benchmarksURL:g=\"https://unpkg.com/detect-gpu@4.0.45/dist/benchmarks\"}={})=>e(void 0,void 0,void 0,(function*(){const p={};if(n)return{tier:0,type:\"SSR\"};const{isIpad:m=!!(null==o?void 0:o.isIpad),isMobile:v=!!(null==o?void 0:o.isMobile),screenSize:w=window.screen,loadBenchmarks:x=(t=>e(void 0,void 0,void 0,(function*(){const e=yield fetch(`${g}/${t}`).then((e=>e.json()));if(parseInt(e.shift().split(\".\")[0],10)<4)throw new s(\"Detect GPU benchmark data is out of date. Please update to version 4x\");return e})))}=f;let{renderer:A}=f;const P=(e,t,r,n,o)=>({device:o,fps:n,gpu:r,isMobile:v,tier:e,type:t});let b,S=\"\";if(A)A=r(A),b=[A];else{const e=u||function(e,t=!1){const r={alpha:!1,antialias:!1,depth:!1,failIfMajorPerformanceCaveat:t,powerPreference:\"high-performance\",stencil:!1};e&&delete r.powerPreference;const n=window.document.createElement(\"canvas\"),o=n.getContext(\"webgl\",r)||n.getContext(\"experimental-webgl\",r);return null!=o?o:void 0}(null==o?void 0:o.isSafari12,h);if(!e)return P(0,\"WEBGL_UNSUPPORTED\");const t=e.getExtension(\"WEBGL_debug_renderer_info\");if(t&&(A=e.getParameter(t.UNMASKED_RENDERER_WEBGL)),!A)return P(1,\"FALLBACK\");S=A,A=r(A),b=function(e,t,r){return\"apple gpu\"===t?a(e,t,r):[t]}(e,A,v)}const y=(yield Promise.all(b.map((function(t){var r;return e(this,void 0,void 0,(function*(){const e=(e=>{const t=v?[\"adreno\",\"apple\",\"mali-t\",\"mali\",\"nvidia\",\"powervr\"]:[\"intel\",\"apple\",\"amd\",\"radeon\",\"nvidia\",\"geforce\"];for(const r of t)if(e.includes(r))return r})(t);if(!e)return;const n=`${v?\"m\":\"d\"}-${e}${m?\"-ipad\":\"\"}.json`,o=p[n]=null!==(r=p[n])&&void 0!==r?r:x(n);let a;try{a=yield o}catch(e){if(e instanceof s)throw e;return}const i=function(e){var t;const r=(e=e.replace(/\\([^)]+\\)/,\"\")).match(/\\d+/)||e.match(/(\\W|^)([A-Za-z]{1,3})(\\W|$)/g);return null!==(t=null==r?void 0:r.join(\"\").replace(/\\W|amd/g,\"\"))&&void 0!==t?t:\"\"}(t);let c=a.filter((([,e])=>e===i));c.length||(c=a.filter((([e])=>e.includes(t))));const l=c.length;if(0===l)return;let f,[u,,,h]=l>1?c.map((e=>[e,d(t,e[0])])).sort((([,e],[,t])=>e-t))[0][0]:c[0],g=Number.MAX_VALUE;const{devicePixelRatio:A}=window,P=w.width*A*w.height*A;for(const e of h){const[t,r]=e,n=t*r,o=Math.abs(P-n);o<g&&(g=o,f=e)}if(!f)return;const[,,b,S]=f;return[g,b,u,S]}))})))).filter(l).sort((([e=Number.MAX_VALUE,t],[r=Number.MAX_VALUE,n])=>e===r?t-n:e-r));if(!y.length){const e=t.find((e=>A.includes(e)));return e?P(0,\"BLOCKLISTED\",e):P(1,\"FALLBACK\",`${A} (${S})`)}const[,C,E,L]=y[0];if(-1===C)return P(0,\"BLOCKLISTED\",E,C,L);const M=v?i:c;let $=0;for(let e=0;e<M.length;e++)C>=M[e]&&($=e);return P($,\"BENCHMARK\",E,C,L)}));export{f as getGPUTier};\n//# sourceMappingURL=detect-gpu.esm.js.map\n","import { getGPUTier } from 'detect-gpu';\n\nlet csRenderInitialized = false;\nlet useCPURendering = false;\n\n// https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/By_example/Detect_WebGL\nfunction hasActiveWebGLContext() {\n // Create canvas element. The canvas is not added to the\n // document itself, so it is never displayed in the\n // browser window.\n const canvas = document.createElement('canvas');\n // Get WebGLRenderingContext from canvas element.\n const gl =\n canvas.getContext('webgl') || canvas.getContext('experimental-webgl');\n\n // Report the result.\n if (gl && gl instanceof WebGLRenderingContext) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Initialize the cornerstone-core. If the browser has a webgl context and\n * the detected gpu (by detect-gpu library) indicates the GPU is not low end we\n * will use webgl GPU rendering. Otherwise we will use cpu rendering.\n *\n * @param defaultConfiguration - A configuration object\n * @returns A promise that resolves to true cornerstone has been initialized successfully.\n * @category Initialization\n */\nasync function init(defaultConfiguration = {}): Promise<boolean> {\n if (csRenderInitialized) {\n return csRenderInitialized;\n }\n\n // detectGPU\n const hasWebGLContext = hasActiveWebGLContext();\n if (!hasWebGLContext) {\n useCPURendering = true;\n console.log('CornerstoneRender: GPU not detected, using CPU rendering');\n } else {\n const gpuTier = await getGPUTier();\n console.log(\n 'CornerstoneRender: Using detect-gpu to get the GPU benchmark:',\n gpuTier\n );\n if (gpuTier.tier < 1) {\n console.log(\n 'CornerstoneRender: GPU is not powerful enough, using CPU rendering'\n );\n useCPURendering = true;\n } else {\n console.log('CornerstoneRender: using GPU rendering');\n }\n }\n csRenderInitialized = true;\n return csRenderInitialized;\n}\n\n/**\n * It sets the useCPURenderingOnlyForDebugOrTests variable to the status value.\n * This only should be used for debugging or tests. DO NOT USE IT IF YOU ARE NOT\n * SURE WHAT YOU ARE DOING.\n * @param status - boolean\n * @category Initialization\n *\n */\nfunction setUseCPURendering(status: boolean): void {\n useCPURendering = status;\n csRenderInitialized = true;\n}\n\n/**\n * Resets the cornerstone-core init state if it has been manually\n * initialized to force use the cpu rendering (e.g., for tests)\n * @category Initialization\n *\n */\nfunction resetUseCPURendering() {\n useCPURendering = !hasActiveWebGLContext();\n}\n\n/**\n * Returns whether or not we are using CPU rendering.\n * @returns true if we are using CPU rendering.\n * @category Initialization\n *\n */\nfunction getShouldUseCPURendering(): boolean {\n return useCPURendering;\n}\n\n/**\n *\n * Returns whether or not cornerstone-core has been initialized.\n * @returns true if the cornerstone render has been initialized.\n * @category Initialization\n *\n */\nfunction isCornerstoneInitialized(): boolean {\n return csRenderInitialized;\n}\n\nexport {\n init,\n getShouldUseCPURendering,\n isCornerstoneInitialized,\n setUseCPURendering,\n resetUseCPURendering,\n};\n","import vtkVolume from '@kitware/vtk.js/Rendering/Core/Volume';\n\nimport cache from '../cache';\nimport ViewportType from '../enums/ViewportType';\nimport Viewport from './Viewport';\nimport { createVolumeActor } from './helpers';\nimport volumeNewImageEventDispatcher, {\n resetVolumeNewImageState,\n} from './helpers/volumeNewImageEventDispatcher';\nimport { loadVolume } from '../volumeLoader';\nimport vtkSlabCamera from './vtkClasses/vtkSlabCamera';\nimport { getShouldUseCPURendering } from '../init';\nimport type {\n Point2,\n Point3,\n IImageData,\n IVolumeInput,\n ActorEntry,\n FlipDirection,\n VolumeViewportProperties,\n} from '../types';\nimport type { ViewportInput } from '../types/IViewport';\nimport type IVolumeViewport from '../types/IVolumeViewport';\nimport { Events, BlendModes, OrientationAxis } from '../enums';\nimport eventTarget from '../eventTarget';\nimport { imageIdToURI, triggerEvent } from '../utilities';\nimport type { vtkSlabCamera as vtkSlabCameraType } from './vtkClasses/vtkSlabCamera';\nimport { VoiModifiedEventDetail } from '../types/EventTypes';\n\n/**\n * Abstract base class for volume viewports. VolumeViewports are used to render\n * 3D volumes from which various orientations can be viewed. Since VolumeViewports\n * use SharedVolumeMappers behind the scene, memory footprint of visualizations\n * of the same volume in different orientations is very small.\n *\n * For setting volumes on viewports you need to use {@link addVolumesToViewports}\n * which will add volumes to the specified viewports.\n */\nabstract class BaseVolumeViewport extends Viewport implements IVolumeViewport {\n useCPURendering = false;\n private _FrameOfReferenceUID: string;\n\n constructor(props: ViewportInput) {\n super(props);\n\n this.useCPURendering = getShouldUseCPURendering();\n\n if (this.useCPURendering) {\n throw new Error(\n 'VolumeViewports cannot be used whilst CPU Fallback Rendering is enabled.'\n );\n }\n\n const renderer = this.getRenderer();\n\n const camera = vtkSlabCamera.newInstance();\n renderer.setActiveCamera(camera);\n\n switch (this.type) {\n case ViewportType.ORTHOGRAPHIC:\n camera.setParallelProjection(true);\n break;\n case ViewportType.VOLUME_3D:\n camera.setParallelProjection(true);\n break;\n case ViewportType.PERSPECTIVE:\n camera.setParallelProjection(false);\n break;\n default:\n throw new Error(`Unrecognized viewport type: ${this.type}`);\n }\n\n this.initializeVolumeNewImageEventDispatcher();\n }\n\n static get useCustomRenderingPipeline(): boolean {\n return false;\n }\n\n private initializeVolumeNewImageEventDispatcher(): void {\n const volumeNewImageHandlerBound = volumeNewImageHandler.bind(this);\n const volumeNewImageCleanUpBound = volumeNewImageCleanUp.bind(this);\n\n function volumeNewImageHandler(cameraEvent) {\n const { viewportId } = cameraEvent.detail;\n\n if (viewportId !== this.id || this.isDisabled) {\n return;\n }\n\n const viewportImageData = this.getImageData();\n\n if (!viewportImageData) {\n return;\n }\n\n volumeNewImageEventDispatcher(cameraEvent);\n }\n\n function volumeNewImageCleanUp(evt) {\n const { viewportId } = evt.detail;\n\n if (viewportId !== this.id) {\n return;\n }\n\n this.element.removeEventListener(\n Events.CAMERA_MODIFIED,\n volumeNewImageHandlerBound\n );\n\n eventTarget.removeEventListener(\n Events.ELEMENT_DISABLED,\n volumeNewImageCleanUpBound\n );\n\n resetVolumeNewImageState(viewportId);\n }\n\n this.element.removeEventListener(\n Events.CAMERA_MODIFIED,\n volumeNewImageHandlerBound\n );\n this.element.addEventListener(\n Events.CAMERA_MODIFIED,\n volumeNewImageHandlerBound\n );\n\n eventTarget.addEventListener(\n Events.ELEMENT_DISABLED,\n volumeNewImageCleanUpBound\n );\n }\n\n /**\n * Sets the properties for the volume viewport on the volume\n * (if fusion, it sets it for the first volume in the fusion)\n *\n * @param voiRange - Sets the lower and upper voi\n * @param volumeId - The volume id to set the properties for (if undefined, the first volume)\n * @param suppressEvents - If true, the viewport will not emit events\n */\n public setProperties(\n { voiRange }: VolumeViewportProperties = {},\n volumeId?: string,\n suppressEvents = false\n ): void {\n if (volumeId !== undefined && !this.getActor(volumeId)) {\n return;\n }\n\n const actorEntries = this.getActors();\n\n if (!actorEntries.length) {\n return;\n }\n\n let volumeActor;\n\n if (volumeId) {\n const actorEntry = actorEntries.find((entry: ActorEntry) => {\n return entry.uid === volumeId;\n });\n\n volumeActor = actorEntry?.actor as vtkVolume;\n }\n\n // // set it for the first volume (if there are more than one - fusion)\n if (!volumeActor) {\n volumeActor = actorEntries[0].actor as vtkVolume;\n volumeId = actorEntries[0].uid;\n }\n\n if (!voiRange) {\n return;\n }\n\n // Todo: later when we have more properties, refactor the setVoiRange code below\n const { lower, upper } = voiRange;\n volumeActor.getProperty().getRGBTransferFunction(0).setRange(lower, upper);\n\n if (!suppressEvents) {\n const eventDetail: VoiModifiedEventDetail = {\n viewportId: this.id,\n range: voiRange,\n volumeId: volumeId,\n };\n\n triggerEvent(this.element, Events.VOI_MODIFIED, eventDetail);\n }\n }\n\n /**\n * Creates volume actors for all volumes defined in the `volumeInputArray`.\n * For each entry, if a `callback` is supplied, it will be called with the new volume actor as input.\n * For each entry, if a `blendMode` and/or `slabThickness` is defined, this will be set on the actor's\n * `VolumeMapper`.\n *\n * @param volumeInputArray - The array of `VolumeInput`s which define the volumes to add.\n * @param immediate - Whether the `Viewport` should be rendered as soon as volumes are added.\n */\n public async setVolumes(\n volumeInputArray: Array<IVolumeInput>,\n immediate = false,\n suppressEvents = false\n ): Promise<void> {\n const firstImageVolume = cache.getVolume(volumeInputArray[0].volumeId);\n\n if (!firstImageVolume) {\n throw new Error(\n `imageVolume with id: ${firstImageVolume.volumeId} does not exist`\n );\n }\n\n const FrameOfReferenceUID = firstImageVolume.metadata.FrameOfReferenceUID;\n\n await this._isValidVolumeInputArray(volumeInputArray, FrameOfReferenceUID);\n\n this._FrameOfReferenceUID = FrameOfReferenceUID;\n\n const volumeActors = [];\n\n // One actor per volume\n for (let i = 0; i < volumeInputArray.length; i++) {\n const { volumeId, actorUID, slabThickness } = volumeInputArray[i];\n\n const actor = await createVolumeActor(\n volumeInputArray[i],\n this.element,\n this.id,\n suppressEvents\n );\n\n // We cannot use only volumeId since then we cannot have for instance more\n // than one representation of the same volume (since actors would have the\n // same name, and we don't allow that) AND We cannot use only any uid, since\n // we rely on the volume in the cache for mapper. So we prefer actorUID if\n // it is defined, otherwise we use volumeId for the actor name.\n const uid = actorUID || volumeId;\n volumeActors.push({\n uid,\n actor,\n slabThickness,\n referenceId: volumeId,\n });\n }\n\n this._setVolumeActors(volumeActors);\n\n triggerEvent(this.element, Events.VOLUME_VIEWPORT_NEW_VOLUME, {\n viewportId: this.id,\n volumeActors,\n });\n\n if (immediate) {\n this.render();\n }\n }\n\n /**\n * Creates and adds volume actors for all volumes defined in the `volumeInputArray`.\n * For each entry, if a `callback` is supplied, it will be called with the new volume actor as input.\n *\n * @param volumeInputArray - The array of `VolumeInput`s which define the volumes to add.\n * @param immediate - Whether the `Viewport` should be rendered as soon as volumes are added.\n */\n public async addVolumes(\n volumeInputArray: Array<IVolumeInput>,\n immediate = false,\n suppressEvents = false\n ): Promise<void> {\n const firstImageVolume = cache.getVolume(volumeInputArray[0].volumeId);\n\n if (!firstImageVolume) {\n throw new Error(\n `imageVolume with id: ${firstImageVolume.volumeId} does not exist`\n );\n }\n\n const volumeActors = [];\n\n await this._isValidVolumeInputArray(\n volumeInputArray,\n this._FrameOfReferenceUID\n );\n\n // One actor per volume\n for (let i = 0; i < volumeInputArray.length; i++) {\n const { volumeId, visibility, actorUID, slabThickness } =\n volumeInputArray[i];\n\n const actor = await createVolumeActor(\n volumeInputArray[i],\n this.element,\n this.id,\n suppressEvents\n );\n\n if (visibility === false) {\n actor.setVisibility(false);\n }\n\n // We cannot use only volumeId since then we cannot have for instance more\n // than one representation of the same volume (since actors would have the\n // same name, and we don't allow that) AND We cannot use only any uid, since\n // we rely on the volume in the cache for mapper. So we prefer actorUID if\n // it is defined, otherwise we use volumeId for the actor name.\n const uid = actorUID || volumeId;\n volumeActors.push({\n uid,\n actor,\n slabThickness,\n // although the actor UID is defined, we need to use the volumeId for the\n // referenceId, since the actor UID is used to reference the actor in the\n // viewport, however, the actor is created from its volumeId\n // and if later we need to grab the referenced volume from cache,\n // we can use the referenceId to get the volume from the cache\n referenceId: volumeId,\n });\n }\n\n this.addActors(volumeActors);\n\n if (immediate) {\n // render\n this.render();\n }\n }\n\n /**\n * It removes the volume actor from the Viewport. If the volume actor is not in\n * the viewport, it does nothing.\n * @param actorUIDs - Array of actor UIDs to remove. In case of simple volume it will\n * be the volume Id, but in case of Segmentation it will be `{volumeId}-{representationType}`\n * since the same volume can be rendered in multiple representations.\n * @param immediate - If true, the Viewport will be rendered immediately\n */\n public removeVolumeActors(actorUIDs: Array<string>, immediate = false): void {\n // Todo: This is actually removeActors\n this.removeActors(actorUIDs);\n\n if (immediate) {\n this.render();\n }\n }\n\n /**\n * It sets the orientation for the camera, the orientation can be one of the\n * following: axial, sagittal, coronal, default. Use the Enums.OrientationAxis\n * to set the orientation. The \"default\" orientation is the orientation that\n * the volume was acquired in (scan axis)\n *\n * @param orientation - The orientation to set the camera to.\n * @param immediate - Whether the `Viewport` should be rendered as soon as the camera is set.\n */\n public setOrientation(orientation: OrientationAxis, immediate = true): void {\n console.warn('Method \"setOrientation\" needs implementation');\n }\n\n private async _isValidVolumeInputArray(\n volumeInputArray: Array<IVolumeInput>,\n FrameOfReferenceUID: string\n ): Promise<boolean> {\n const numVolumes = volumeInputArray.length;\n\n // Check all other volumes exist and have the same FrameOfReference\n for (let i = 1; i < numVolumes; i++) {\n const volumeInput = volumeInputArray[i];\n\n const imageVolume = await loadVolume(volumeInput.volumeId);\n\n if (!imageVolume) {\n throw new Error(\n `imageVolume with id: ${imageVolume.volumeId} does not exist`\n );\n }\n\n if (FrameOfReferenceUID !== imageVolume.metadata.FrameOfReferenceUID) {\n throw new Error(\n `Volumes being added to viewport ${this.id} do not share the same FrameOfReferenceUID. This is not yet supported`\n );\n }\n }\n\n return true;\n }\n\n /**\n * gets the visible bounds of the viewport in the world coordinate system\n */\n public getBounds(): number[] {\n const renderer = this.getRenderer();\n const bounds = renderer.computeVisiblePropBounds();\n return bounds;\n }\n\n /**\n * Flip the viewport along the desired axis\n * @param flipDirection - FlipDirection\n */\n public flip(flipDirection: FlipDirection): void {\n super.flip(flipDirection);\n }\n\n public getFrameOfReferenceUID = (): string => {\n return this._FrameOfReferenceUID;\n };\n\n /**\n * Checks if the viewport has a volume actor with the given volumeId\n * @param volumeId - the volumeId to look for\n * @returns Boolean indicating if the volume is present in the viewport\n */\n public hasVolumeId(volumeId: string): boolean {\n // Note: this assumes that the uid of the volume is the same as the volumeId\n // which is not guaranteed to be the case for SEG.\n const actorEntries = this.getActors();\n return actorEntries.some((actorEntry) => {\n return actorEntry.uid === volumeId;\n });\n }\n\n /**\n * Returns the image and its properties that is being shown inside the\n * stack viewport. It returns, the image dimensions, image direction,\n * image scalar data, vtkImageData object, metadata, and scaling (e.g., PET suvbw)\n * Note: since the volume viewport supports fusion, to get the\n * image data for a specific volume, use the optional volumeId\n * argument.\n *\n * @param volumeId - The volumeId of the volume to get the image for.\n * @returns IImageData: {dimensions, direction, scalarData, vtkImageData, metadata, scaling}\n */\n public getImageData(volumeId?: string): IImageData | undefined {\n const defaultActor = this.getDefaultActor();\n if (!defaultActor) {\n return;\n }\n\n const { uid: defaultActorUID } = defaultActor;\n volumeId = volumeId ?? defaultActorUID;\n\n const { actor } = this.getActor(volumeId);\n\n if (!actor.isA('vtkVolume')) {\n return;\n }\n\n const volume = cache.getVolume(volumeId);\n\n const vtkImageData = actor.getMapper().getInputData();\n return {\n dimensions: vtkImageData.getDimensions(),\n spacing: vtkImageData.getSpacing(),\n origin: vtkImageData.getOrigin(),\n direction: vtkImageData.getDirection(),\n scalarData: vtkImageData.getPointData().getScalars().getData(),\n imageData: actor.getMapper().getInputData(),\n metadata: {\n Modality: volume?.metadata?.Modality,\n },\n scaling: volume?.scaling,\n hasPixelSpacing: true,\n };\n }\n\n /**\n * Attaches the volume actors to the viewport.\n *\n * @param volumeActorEntries - The volume actors to add the viewport.\n *\n */\n private _setVolumeActors(volumeActorEntries: Array<ActorEntry>): void {\n this.setActors(volumeActorEntries);\n }\n\n /**\n * canvasToWorld Returns the world coordinates of the given `canvasPos`\n * projected onto the plane defined by the `Viewport`'s `vtkCamera`'s focal point\n * and the direction of projection.\n *\n * @param canvasPos - The position in canvas coordinates.\n * @returns The corresponding world coordinates.\n * @public\n */\n public canvasToWorld = (canvasPos: Point2): Point3 => {\n const vtkCamera = this.getVtkActiveCamera() as vtkSlabCameraType;\n\n /**\n * NOTE: this is necessary because we want the coordinate transformation\n * respect to the view plane (plane orthogonal to the camera and passing to\n * the focal point).\n *\n * When vtk.js computes the coordinate transformations, it simply uses the\n * camera matrix (no ray casting).\n *\n * However for the volume viewport the clipping range is set to be\n * (-RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE, RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE).\n * The clipping range is used in the camera method getProjectionMatrix().\n * The projection matrix is used then for viewToWorld/worldToView methods of\n * the renderer. This means that vkt.js will not return the coordinates of\n * the point on the view plane (i.e. the depth coordinate will correspond\n * to the focal point).\n *\n * Therefore the clipping range has to be set to (distance, distance + 0.01),\n * where now distance is the distance between the camera position and focal\n * point. This is done internally, in our camera customization when the flag\n * isPerformingCoordinateTransformation is set to true.\n */\n\n vtkCamera.setIsPerformingCoordinateTransformation(true);\n\n const renderer = this.getRenderer();\n const offscreenMultiRenderWindow =\n this.getRenderingEngine().offscreenMultiRenderWindow;\n const openGLRenderWindow =\n offscreenMultiRenderWindow.getOpenGLRenderWindow();\n const size = openGLRenderWindow.getSize();\n const devicePixelRatio = window.devicePixelRatio || 1;\n const canvasPosWithDPR = [\n canvasPos[0] * devicePixelRatio,\n canvasPos[1] * devicePixelRatio,\n ];\n const displayCoord = [\n canvasPosWithDPR[0] + this.sx,\n canvasPosWithDPR[1] + this.sy,\n ];\n\n // The y axis display coordinates are inverted with respect to canvas coords\n displayCoord[1] = size[1] - displayCoord[1];\n\n const worldCoord = openGLRenderWindow.displayToWorld(\n displayCoord[0],\n displayCoord[1],\n 0,\n renderer\n );\n\n vtkCamera.setIsPerformingCoordinateTransformation(false);\n\n return [worldCoord[0], worldCoord[1], worldCoord[2]];\n };\n\n /**\n * Returns the canvas coordinates of the given `worldPos`\n * projected onto the `Viewport`'s `canvas`.\n *\n * @param worldPos - The position in world coordinates.\n * @returns The corresponding canvas coordinates.\n * @public\n */\n public worldToCanvas = (worldPos: Point3): Point2 => {\n const vtkCamera = this.getVtkActiveCamera() as vtkSlabCameraType;\n\n /**\n * NOTE: this is necessary because we want the coordinate trasformation\n * respect to the view plane (plane orthogonal to the camera and passing to\n * the focal point).\n *\n * When vtk.js computes the coordinate transformations, it simply uses the\n * camera matrix (no ray casting).\n *\n * However for the volume viewport the clipping range is set to be\n * (-RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE, RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE).\n * The clipping range is used in the camera method getProjectionMatrix().\n * The projection matrix is used then for viewToWorld/worldToView methods of\n * the renderer. This means that vkt.js will not return the coordinates of\n * the point on the view plane (i.e. the depth coordinate will corresponded\n * to the focal point).\n *\n * Therefore the clipping range has to be set to (distance, distance + 0.01),\n * where now distance is the distance between the camera position and focal\n * point. This is done internally, in our camera customization when the flag\n * isPerformingCoordinateTransformation is set to true.\n */\n\n vtkCamera.setIsPerformingCoordinateTransformation(true);\n\n const renderer = this.getRenderer();\n const offscreenMultiRenderWindow =\n this.getRenderingEngine().offscreenMultiRenderWindow;\n const openGLRenderWindow =\n offscreenMultiRenderWindow.getOpenGLRenderWindow();\n const size = openGLRenderWindow.getSize();\n const displayCoord = openGLRenderWindow.worldToDisplay(\n ...worldPos,\n renderer\n );\n\n // The y axis display coordinates are inverted with respect to canvas coords\n displayCoord[1] = size[1] - displayCoord[1];\n\n const canvasCoord = <Point2>[\n displayCoord[0] - this.sx,\n displayCoord[1] - this.sy,\n ];\n\n const devicePixelRatio = window.devicePixelRatio || 1;\n const canvasCoordWithDPR = <Point2>[\n canvasCoord[0] / devicePixelRatio,\n canvasCoord[1] / devicePixelRatio,\n ];\n\n vtkCamera.setIsPerformingCoordinateTransformation(false);\n\n return canvasCoordWithDPR;\n };\n\n /*\n * Checking if the imageURI is in the volumes that are being\n * rendered by the viewport. imageURI is the imageId without the schema\n * for instance for the imageId of wadors:http://..., the http://... is the imageURI.\n * Why we don't check the imageId is because the same image can be shown in\n * another viewport (StackViewport) with a different schema\n *\n * @param imageURI - The imageURI to check\n * @returns True if the imageURI is in the volumes that are being rendered by the viewport\n */\n public hasImageURI = (imageURI: string): boolean => {\n const volumeActors = this.getActors().filter(({ actor }) =>\n actor.isA('vtkVolume')\n );\n\n return volumeActors.some(({ uid }) => {\n const volume = cache.getVolume(uid);\n\n if (!volume || !volume.imageIds) {\n return false;\n }\n\n const volumeImageURIs = volume.imageIds.map(imageIdToURI);\n\n return volumeImageURIs.includes(imageURI);\n });\n };\n\n /**\n * Reset the camera for the volume viewport\n */\n resetCamera(\n resetPan?: boolean,\n resetZoom?: boolean,\n resetToCenter?: boolean\n ): boolean {\n return super.resetCamera(resetPan, resetZoom, resetToCenter);\n }\n\n getCurrentImageIdIndex = (): number => {\n throw new Error('Method not implemented.');\n };\n\n getCurrentImageId = (): string => {\n throw new Error('Method not implemented.');\n };\n\n getIntensityFromWorld(point: Point3): number {\n throw new Error('Method not implemented.');\n }\n\n setBlendMode(\n blendMode: BlendModes,\n filterActorUIDs?: string[],\n immediate?: boolean\n ): void {\n throw new Error('Method not implemented.');\n }\n\n setSlabThickness(slabThickness: number, filterActorUIDs?: string[]): void {\n throw new Error('Method not implemented.');\n }\n\n getSlabThickness(): number {\n throw new Error('Method not implemented.');\n }\n}\n\nexport default BaseVolumeViewport;\n","import { vec3 } from 'gl-matrix';\nimport vtkPlane from '@kitware/vtk.js/Common/DataModel/Plane';\n\nimport cache from '../cache';\nimport transformWorldToIndex from '../utilities/transformWorldToIndex';\nimport type {\n Point3,\n IVolumeInput,\n ActorEntry,\n IImageVolume,\n OrientationVectors,\n} from '../types';\nimport type { ViewportInput } from '../types/IViewport';\nimport { RENDERING_DEFAULTS, MPR_CAMERA_VALUES, EPSILON } from '../constants';\nimport { BlendModes, OrientationAxis } from '../enums';\nimport BaseVolumeViewport from './BaseVolumeViewport';\n\n/**\n * An object representing a VolumeViewport. VolumeViewports are used to render\n * 3D volumes from which various orientations can be viewed. Since VolumeViewports\n * use SharedVolumeMappers behind the scene, memory footprint of visualizations\n * of the same volume in different orientations is very small.\n *\n * For setting volumes on viewports you need to use {@link addVolumesToViewports}\n * which will add volumes to the specified viewports.\n */\nclass VolumeViewport extends BaseVolumeViewport {\n private _useAcquisitionPlaneForViewPlane = false;\n constructor(props: ViewportInput) {\n super(props);\n\n const { orientation } = this.options;\n\n // if the camera is set to be acquisition axis then we need to skip\n // it for now until the volume is set\n if (orientation && orientation !== OrientationAxis.ACQUISITION) {\n const { viewPlaneNormal, viewUp } =\n this._getOrientationVectors(orientation);\n const camera = this.getVtkActiveCamera();\n camera.setDirectionOfProjection(\n -viewPlaneNormal[0],\n -viewPlaneNormal[1],\n -viewPlaneNormal[2]\n );\n camera.setViewUpFrom(viewUp);\n\n this.resetCamera();\n return;\n }\n\n this._useAcquisitionPlaneForViewPlane = true;\n }\n\n /**\n * Creates volume actors for all volumes defined in the `volumeInputArray`.\n * For each entry, if a `callback` is supplied, it will be called with the new volume actor as input.\n * For each entry, if a `blendMode` and/or `slabThickness` is defined, this will be set on the actor's\n * `VolumeMapper`.\n *\n * @param volumeInputArray - The array of `VolumeInput`s which define the volumes to add.\n * @param immediate - Whether the `Viewport` should be rendered as soon as volumes are added.\n */\n public async setVolumes(\n volumeInputArray: Array<IVolumeInput>,\n immediate = false,\n suppressEvents = false\n ): Promise<void> {\n const firstImageVolume = cache.getVolume(volumeInputArray[0].volumeId);\n\n if (!firstImageVolume) {\n throw new Error(\n `imageVolume with id: ${firstImageVolume.volumeId} does not exist`\n );\n }\n\n if (this._useAcquisitionPlaneForViewPlane) {\n this._setViewPlaneToAcquisitionPlane(firstImageVolume);\n this._useAcquisitionPlaneForViewPlane = false;\n }\n\n return super.setVolumes(volumeInputArray, immediate, suppressEvents);\n }\n\n /**\n * Creates and adds volume actors for all volumes defined in the `volumeInputArray`.\n * For each entry, if a `callback` is supplied, it will be called with the new volume actor as input.\n *\n * @param volumeInputArray - The array of `VolumeInput`s which define the volumes to add.\n * @param immediate - Whether the `Viewport` should be rendered as soon as volumes are added.\n */\n public async addVolumes(\n volumeInputArray: Array<IVolumeInput>,\n immediate = false,\n suppressEvents = false\n ): Promise<void> {\n const firstImageVolume = cache.getVolume(volumeInputArray[0].volumeId);\n\n if (!firstImageVolume) {\n throw new Error(\n `imageVolume with id: ${firstImageVolume.volumeId} does not exist`\n );\n }\n\n if (this._useAcquisitionPlaneForViewPlane) {\n this._setViewPlaneToAcquisitionPlane(firstImageVolume);\n this._useAcquisitionPlaneForViewPlane = false;\n }\n\n return super.addVolumes(volumeInputArray, immediate, suppressEvents);\n }\n\n /**\n * It sets the orientation for the camera, the orientation can be one of the\n * following: axial, sagittal, coronal, default. Use the Enums.OrientationAxis\n * to set the orientation. The \"default\" orientation is the orientation that\n * the volume was acquired in (scan axis)\n *\n * @param orientation - The orientation to set the camera to.\n * @param immediate - Whether the `Viewport` should be rendered as soon as the camera is set.\n */\n public setOrientation(orientation: OrientationAxis, immediate = true): void {\n let viewPlaneNormal, viewUp;\n\n if (MPR_CAMERA_VALUES[orientation]) {\n ({ viewPlaneNormal, viewUp } = MPR_CAMERA_VALUES[orientation]);\n } else if (orientation === 'acquisition') {\n ({ viewPlaneNormal, viewUp } = this._getAcquisitionPlaneOrientation());\n } else {\n throw new Error(\n `Invalid orientation: ${orientation}. Use Enums.OrientationAxis instead.`\n );\n }\n\n this.setCamera({\n viewPlaneNormal,\n viewUp,\n });\n\n this.resetCamera();\n\n if (immediate) {\n this.render();\n }\n }\n\n private _getOrientationVectors(\n orientation: OrientationAxis | OrientationVectors\n ): OrientationVectors {\n if (typeof orientation === 'object') {\n if (orientation.viewPlaneNormal && orientation.viewUp) {\n return orientation;\n } else {\n throw new Error(\n 'Invalid orientation object. It must contain viewPlaneNormal and viewUp'\n );\n }\n } else if (\n typeof orientation === 'string' &&\n MPR_CAMERA_VALUES[orientation]\n ) {\n return MPR_CAMERA_VALUES[orientation];\n } else {\n throw new Error(\n `Invalid orientation: ${orientation}. Valid orientations are: ${Object.keys(\n MPR_CAMERA_VALUES\n ).join(', ')}`\n );\n }\n }\n\n private _getAcquisitionPlaneOrientation(): OrientationVectors {\n const actorEntry = this.getDefaultActor();\n\n if (!actorEntry) {\n return;\n }\n\n // Todo: fix this after we add the volumeId reference to actorEntry later\n // in the segmentation refactor\n const volumeId = actorEntry.uid;\n\n const imageVolume = cache.getVolume(volumeId);\n\n if (!imageVolume) {\n throw new Error(\n `imageVolume with id: ${volumeId} does not exist in cache`\n );\n }\n\n const { direction } = imageVolume;\n const viewPlaneNormal = direction.slice(6, 9).map((x) => -x) as Point3;\n const viewUp = (direction.slice(3, 6) as Point3).map((x) => -x) as Point3;\n\n return {\n viewPlaneNormal,\n viewUp,\n };\n }\n\n private _setViewPlaneToAcquisitionPlane(imageVolume: IImageVolume): void {\n let viewPlaneNormal, viewUp;\n\n if (imageVolume) {\n const { direction } = imageVolume;\n viewPlaneNormal = direction.slice(6, 9).map((x) => -x) as Point3;\n viewUp = (direction.slice(3, 6) as Point3).map((x) => -x) as Point3;\n } else {\n ({ viewPlaneNormal, viewUp } = this._getAcquisitionPlaneOrientation());\n }\n\n this.setCamera({\n viewPlaneNormal,\n viewUp,\n });\n\n this.resetCamera();\n }\n\n /**\n * Given a point in world coordinates, return the intensity at that point\n * @param point - The point in world coordinates to get the intensity\n * from.\n * @returns The intensity value of the voxel at the given point.\n */\n public getIntensityFromWorld(point: Point3): number {\n const { actor, uid } = this.getDefaultActor();\n if (!actor.isA('vtkVolume')) {\n return;\n }\n\n const imageData = actor.getMapper().getInputData();\n\n const volume = cache.getVolume(uid);\n const { dimensions } = volume;\n\n const index = transformWorldToIndex(imageData, point);\n\n const voxelIndex =\n index[2] * dimensions[0] * dimensions[1] +\n index[1] * dimensions[0] +\n index[0];\n\n return volume.scalarData[voxelIndex];\n }\n\n public setBlendMode(\n blendMode: BlendModes,\n filterActorUIDs = [],\n immediate = false\n ): void {\n let actorEntries = this.getActors();\n\n if (filterActorUIDs && filterActorUIDs.length > 0) {\n actorEntries = actorEntries.filter((actorEntry: ActorEntry) => {\n return filterActorUIDs.includes(actorEntry.uid);\n });\n }\n\n actorEntries.forEach((actorEntry) => {\n const { actor } = actorEntry;\n\n const mapper = actor.getMapper();\n // @ts-ignore vtk incorrect typing\n mapper.setBlendMode(blendMode);\n });\n\n if (immediate) {\n this.render();\n }\n }\n\n /**\n * Reset the camera for the volume viewport\n */\n public resetCamera(\n resetPan = true,\n resetZoom = true,\n resetToCenter = true\n ): boolean {\n super.resetCamera(resetPan, resetZoom, resetToCenter);\n const activeCamera = this.getVtkActiveCamera();\n // Set large numbers to ensure everything is always rendered\n if (activeCamera.getParallelProjection()) {\n activeCamera.setClippingRange(\n -RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE,\n RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE\n );\n } else {\n activeCamera.setClippingRange(\n RENDERING_DEFAULTS.MINIMUM_SLAB_THICKNESS,\n RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE\n );\n }\n\n const viewPlaneNormal = <Point3>activeCamera.getViewPlaneNormal();\n const focalPoint = <Point3>activeCamera.getFocalPoint();\n\n const actorEntries = this.getActors();\n actorEntries.forEach((actorEntry) => {\n // we assume that the first two clipping plane of the mapper are always\n // the 'camera' clipping. Add clipping planes only if the actor is\n // a vtkVolume\n if (!actorEntry.actor || !actorEntry.actor.isA('vtkVolume')) {\n return;\n }\n const mapper = actorEntry.actor.getMapper();\n const vtkPlanes = mapper.getClippingPlanes();\n if (vtkPlanes.length === 0) {\n const clipPlane1 = vtkPlane.newInstance();\n const clipPlane2 = vtkPlane.newInstance();\n const newVtkPlanes = [clipPlane1, clipPlane2];\n\n let slabThickness = RENDERING_DEFAULTS.MINIMUM_SLAB_THICKNESS;\n if (actorEntry.slabThickness) {\n slabThickness = actorEntry.slabThickness;\n }\n\n this.setOrientationOfClippingPlanes(\n newVtkPlanes,\n slabThickness,\n viewPlaneNormal,\n focalPoint\n );\n\n mapper.addClippingPlane(clipPlane1);\n mapper.addClippingPlane(clipPlane2);\n }\n });\n\n return true;\n }\n\n /**\n * It sets the slabThickness of the actors of the viewport. If filterActorUIDs are\n * provided, only the actors with the given UIDs will be affected. If no\n * filterActorUIDs are provided, all actors will be affected.\n *\n * @param slabThickness - The slab thickness to set.\n * @param blendMode - The blend mode to use when rendering the actors.\n * @param filterActorUIDs - Optional argument to filter the actors to apply\n * the slab thickness to (if not provided, all actors will be affected).\n */\n public setSlabThickness(slabThickness: number, filterActorUIDs = []): void {\n let actorEntries = this.getActors();\n\n if (filterActorUIDs && filterActorUIDs.length > 0) {\n actorEntries = actorEntries.filter((actorEntry) => {\n return filterActorUIDs.includes(actorEntry.uid);\n });\n }\n\n actorEntries.forEach((actorEntry) => {\n const { actor } = actorEntry;\n\n if (actor.isA('vtkVolume')) {\n actorEntry.slabThickness = slabThickness;\n }\n });\n\n const currentCamera = this.getCamera();\n this.updateClippingPlanesForActors(currentCamera);\n this.triggerCameraModifiedEventIfNecessary(currentCamera, currentCamera);\n }\n\n /**\n * Gets the largest slab thickness from all actors in the viewport.\n *\n * @returns slabThickness - The slab thickness.\n */\n public getSlabThickness(): number {\n const actors = this.getActors();\n let slabThickness = RENDERING_DEFAULTS.MINIMUM_SLAB_THICKNESS;\n actors.forEach((actor) => {\n if (actor.slabThickness > slabThickness) {\n slabThickness = actor.slabThickness;\n }\n });\n\n return slabThickness;\n }\n\n /**\n * Uses viewport camera and volume actor to decide if the viewport\n * is looking at the volume in the direction of acquisition (imageIds).\n * If so, it uses the origin and focalPoint to calculate the slice index.\n * Todo: This only works if the imageIds are properly sorted\n *\n * @returns The slice index\n */\n public getCurrentImageIdIndex = (): number | undefined => {\n return this._getImageIdIndex();\n };\n\n /**\n * Uses viewport camera and volume actor to decide if the viewport\n * is looking at the volume in the direction of acquisition (imageIds).\n * If so, it uses the origin and focalPoint to find which imageId is\n * currently being viewed.\n *\n * @returns ImageId\n */\n public getCurrentImageId = (): string | undefined => {\n const index = this._getImageIdIndex();\n\n if (isNaN(index)) {\n return;\n }\n\n const { uid, actor } = this.getDefaultActor();\n if (!actor.isA('vtkVolume')) {\n return;\n }\n\n const volume = cache.getVolume(uid);\n\n if (!volume) {\n return;\n }\n\n const imageIds = volume.imageIds;\n\n return imageIds[index];\n };\n\n private _getImageIdIndex = () => {\n const { viewPlaneNormal, focalPoint } = this.getCamera();\n\n // Todo: handle scenario of fusion of multiple volumes\n // we cannot only check number of actors, because we might have\n // segmentations ...\n const { direction, origin, spacing } = this.getImageData();\n\n // get the last 3 components of the direction - axis normal\n const dir = direction.slice(direction.length - 3);\n\n const dot = Math.abs(\n dir[0] * viewPlaneNormal[0] +\n dir[1] * viewPlaneNormal[1] +\n dir[2] * viewPlaneNormal[2]\n );\n\n // if dot is not 1 or -1 return null since it means\n // viewport is not looking at the image acquisition plane\n if (dot - 1 > EPSILON) {\n return;\n }\n\n // how many steps are from the origin to the focal point in the\n // normal direction\n const spacingInNormal = spacing[2];\n const sub = vec3.create();\n vec3.sub(sub, focalPoint, origin);\n const distance = vec3.dot(sub, viewPlaneNormal);\n\n // divide by the spacing in the normal direction to get the\n // number of steps, and subtract 1 to get the index\n return Math.round(Math.abs(distance) / spacingInNormal);\n };\n}\n\nexport default VolumeViewport;\n","/**\n * A utility that can be used to invert (in place) an RgbTransferFunction.\n *\n * @example\n * Grabbing a reference to the RGB Transfer function from the viewport:\n * ```\n * const rgbTransferFunction = viewport\n * .getActor()\n * .getProperty()\n * .getRGBTransferFunction(0);\n *\n * rgbTransferFunction.setRange(0, 5);\n *\n * invertRgbTransferFunction(rgbTransferFunction);\n * ```\n *\n * @see {@link https://kitware.github.io/vtk-js/api/Rendering_Core_ColorTransferFunction.html|VTK.js: ColorTransferFunction}\n * @param rgbTransferFunction\n */\nexport default function invertRgbTransferFunction(\n rgbTransferFunction: any\n): void {\n const size = rgbTransferFunction.getSize();\n\n for (let index = 0; index < size; index++) {\n const nodeValue1 = [];\n\n rgbTransferFunction.getNodeValue(index, nodeValue1);\n\n nodeValue1[1] = 1 - nodeValue1[1];\n nodeValue1[2] = 1 - nodeValue1[2];\n nodeValue1[3] = 1 - nodeValue1[3];\n\n rgbTransferFunction.setNodeValue(index, nodeValue1);\n }\n}\n","/**\n * returns equal if the two arrays are identical within the\n * given tolerance.\n *\n * @param v1 - The first array of values\n * @param v2 - The second array of values.\n * @param tolerance - The acceptable tolerance, the default is 0.00001\n *\n * @returns True if the two values are within the tolerance levels.\n */\nexport default function isEqual(\n v1: number[] | Float32Array,\n v2: number[] | Float32Array,\n tolerance = 1e-5\n): boolean {\n if (v1.length !== v2.length) {\n return false;\n }\n\n for (let i = 0; i < v1.length; i++) {\n if (Math.abs(v1[i] - v2[i]) > tolerance) {\n return false;\n }\n }\n\n return true;\n}\n","/**\n * Use the performance.now() method if possible, and if not, use Date.now()\n *\n * @return {number} Time elapsed since the time origin\n * @memberof Polyfills\n */\nexport default function (): number {\n if (window.performance) {\n return performance.now();\n }\n\n return Date.now();\n}\n","/* eslint no-bitwise: 0 */\n\n/**\n * Volume of Interest Lookup Table Function\n *\n * @typedef {Function} VOILUTFunction\n *\n * @param {Number} modalityLutValue\n * @returns {Number} transformed value\n * @memberof Objects\n */\n\n/**\n * @module: VOILUT\n */\n\n/**\n *\n * @param {Number} windowWidth Window Width\n * @param {Number} windowCenter Window Center\n * @returns {VOILUTFunction} VOI LUT mapping function\n * @memberof VOILUT\n */\nfunction generateLinearVOILUT(windowWidth: number, windowCenter: number) {\n return function (modalityLutValue) {\n return ((modalityLutValue - windowCenter) / windowWidth + 0.5) * 255.0;\n };\n}\n\n/**\n * Generate a non-linear volume of interest lookup table\n *\n * @param {LUT} voiLUT Volume of Interest Lookup Table Object\n *\n * @returns {VOILUTFunction} VOI LUT mapping function\n * @memberof VOILUT\n */\nfunction generateNonLinearVOILUT(voiLUT) {\n // We don't trust the voiLUT.numBitsPerEntry, mainly thanks to Agfa!\n const bitsPerEntry = Math.max(...voiLUT.lut).toString(2).length;\n const shift = bitsPerEntry - 8;\n const minValue = voiLUT.lut[0] >> shift;\n const maxValue = voiLUT.lut[voiLUT.lut.length - 1] >> shift;\n const maxValueMapped = voiLUT.firstValueMapped + voiLUT.lut.length - 1;\n\n return function (modalityLutValue) {\n if (modalityLutValue < voiLUT.firstValueMapped) {\n return minValue;\n } else if (modalityLutValue >= maxValueMapped) {\n return maxValue;\n }\n\n return voiLUT.lut[modalityLutValue - voiLUT.firstValueMapped] >> shift;\n };\n}\n\n/**\n * Retrieve a VOI LUT mapping function given the current windowing settings\n * and the VOI LUT for the image\n *\n * @param {Number} windowWidth Window Width\n * @param {Number} windowCenter Window Center\n * @param {LUT} [voiLUT] Volume of Interest Lookup Table Object\n *\n * @return {VOILUTFunction} VOI LUT mapping function\n * @memberof VOILUT\n */\nexport default function (windowWidth: number, windowCenter: number, voiLUT) {\n if (voiLUT) {\n return generateNonLinearVOILUT(voiLUT);\n }\n\n return generateLinearVOILUT(windowWidth, windowCenter);\n}\n","import {\n CPUFallbackTransform,\n Point2,\n TransformMatrix2D,\n} from '../../../../types';\n\n// By Simon Sarris\n// Www.simonsarris.com\n// Sarris@acm.org\n//\n// Free to use and distribute at will\n// So long as you are nice to people, etc\n\n// Simple class for keeping track of the current transformation matrix\n\n// For instance:\n// Var t = new Transform();\n// T.rotate(5);\n// Var m = t.m;\n// Ctx.setTransform(m[0], m[1], m[2], m[3], m[4], m[5]);\n\n// Is equivalent to:\n// Ctx.rotate(5);\n\n// But now you can retrieve it :)\n\n// Remember that this does not account for any CSS transforms applied to the canvas\nexport class Transform implements CPUFallbackTransform {\n private m: TransformMatrix2D;\n\n constructor() {\n this.reset();\n }\n\n getMatrix(): TransformMatrix2D {\n return this.m;\n }\n\n reset(): void {\n this.m = [1, 0, 0, 1, 0, 0];\n }\n\n clone(): CPUFallbackTransform {\n const transform = new Transform();\n\n transform.m[0] = this.m[0];\n transform.m[1] = this.m[1];\n transform.m[2] = this.m[2];\n transform.m[3] = this.m[3];\n transform.m[4] = this.m[4];\n transform.m[5] = this.m[5];\n\n return transform;\n }\n\n multiply(matrix: TransformMatrix2D): void {\n const m11 = this.m[0] * matrix[0] + this.m[2] * matrix[1];\n const m12 = this.m[1] * matrix[0] + this.m[3] * matrix[1];\n\n const m21 = this.m[0] * matrix[2] + this.m[2] * matrix[3];\n const m22 = this.m[1] * matrix[2] + this.m[3] * matrix[3];\n\n const dx = this.m[0] * matrix[4] + this.m[2] * matrix[5] + this.m[4];\n const dy = this.m[1] * matrix[4] + this.m[3] * matrix[5] + this.m[5];\n\n this.m[0] = m11;\n this.m[1] = m12;\n this.m[2] = m21;\n this.m[3] = m22;\n this.m[4] = dx;\n this.m[5] = dy;\n }\n\n invert(): void {\n const d = 1 / (this.m[0] * this.m[3] - this.m[1] * this.m[2]);\n const m0 = this.m[3] * d;\n const m1 = -this.m[1] * d;\n const m2 = -this.m[2] * d;\n const m3 = this.m[0] * d;\n const m4 = d * (this.m[2] * this.m[5] - this.m[3] * this.m[4]);\n const m5 = d * (this.m[1] * this.m[4] - this.m[0] * this.m[5]);\n\n this.m[0] = m0;\n this.m[1] = m1;\n this.m[2] = m2;\n this.m[3] = m3;\n this.m[4] = m4;\n this.m[5] = m5;\n }\n\n rotate(rad: number): void {\n const c = Math.cos(rad);\n const s = Math.sin(rad);\n const m11 = this.m[0] * c + this.m[2] * s;\n const m12 = this.m[1] * c + this.m[3] * s;\n const m21 = this.m[0] * -s + this.m[2] * c;\n const m22 = this.m[1] * -s + this.m[3] * c;\n\n this.m[0] = m11;\n this.m[1] = m12;\n this.m[2] = m21;\n this.m[3] = m22;\n }\n\n translate(x: number, y: number): void {\n this.m[4] += this.m[0] * x + this.m[2] * y;\n this.m[5] += this.m[1] * x + this.m[3] * y;\n }\n\n scale(sx: number, sy: number) {\n this.m[0] *= sx;\n this.m[1] *= sx;\n this.m[2] *= sy;\n this.m[3] *= sy;\n }\n\n transformPoint(point: Point2): Point2 {\n const x = point[0];\n const y = point[1];\n\n return [\n x * this.m[0] + y * this.m[2] + this.m[4],\n x * this.m[1] + y * this.m[3] + this.m[5],\n ];\n }\n}\n","import { Transform } from './transform';\nimport {\n CPUFallbackEnabledElement,\n CPUFallbackTransform,\n} from '../../../../types';\n\n/**\n * Calculate the transform for a Cornerstone enabled element\n *\n * @param enabledElement - The Cornerstone Enabled Element\n * @param scale - The viewport scale\n * @returns The current transform\n */\nexport default function (\n enabledElement: CPUFallbackEnabledElement,\n scale?: number\n): CPUFallbackTransform {\n const transform = new Transform();\n\n if (!enabledElement.viewport.displayedArea) {\n return transform;\n }\n\n // Move to center of canvas\n transform.translate(\n enabledElement.canvas.width / 2,\n enabledElement.canvas.height / 2\n );\n\n // Apply the rotation before scaling for non square pixels\n const angle = enabledElement.viewport.rotation;\n\n if (angle !== 0) {\n transform.rotate((angle * Math.PI) / 180);\n }\n\n // Apply the scale\n let widthScale = enabledElement.viewport.scale;\n let heightScale = enabledElement.viewport.scale;\n\n const width =\n enabledElement.viewport.displayedArea.brhc.x -\n (enabledElement.viewport.displayedArea.tlhc.x - 1);\n const height =\n enabledElement.viewport.displayedArea.brhc.y -\n (enabledElement.viewport.displayedArea.tlhc.y - 1);\n\n if (enabledElement.viewport.displayedArea.presentationSizeMode === 'NONE') {\n if (\n enabledElement.image.rowPixelSpacing <\n enabledElement.image.columnPixelSpacing\n ) {\n widthScale *=\n enabledElement.image.columnPixelSpacing /\n enabledElement.image.rowPixelSpacing;\n } else if (\n enabledElement.image.columnPixelSpacing <\n enabledElement.image.rowPixelSpacing\n ) {\n heightScale *=\n enabledElement.image.rowPixelSpacing /\n enabledElement.image.columnPixelSpacing;\n }\n } else {\n // These should be good for \"TRUE SIZE\" and \"MAGNIFY\"\n widthScale = enabledElement.viewport.displayedArea.columnPixelSpacing;\n heightScale = enabledElement.viewport.displayedArea.rowPixelSpacing;\n\n if (\n enabledElement.viewport.displayedArea.presentationSizeMode ===\n 'SCALE TO FIT'\n ) {\n // Fit TRUE IMAGE image (width/height) to window\n const verticalScale =\n enabledElement.canvas.height / (height * heightScale);\n const horizontalScale =\n enabledElement.canvas.width / (width * widthScale);\n\n // Apply new scale\n widthScale = heightScale = Math.min(horizontalScale, verticalScale);\n\n if (\n enabledElement.viewport.displayedArea.rowPixelSpacing <\n enabledElement.viewport.displayedArea.columnPixelSpacing\n ) {\n widthScale *=\n enabledElement.viewport.displayedArea.columnPixelSpacing /\n enabledElement.viewport.displayedArea.rowPixelSpacing;\n } else if (\n enabledElement.viewport.displayedArea.columnPixelSpacing <\n enabledElement.viewport.displayedArea.rowPixelSpacing\n ) {\n heightScale *=\n enabledElement.viewport.displayedArea.rowPixelSpacing /\n enabledElement.viewport.displayedArea.columnPixelSpacing;\n }\n }\n }\n\n transform.scale(widthScale, heightScale);\n\n // Unrotate to so we can translate unrotated\n if (angle !== 0) {\n transform.rotate((-angle * Math.PI) / 180);\n }\n\n // Apply the pan offset\n transform.translate(\n enabledElement.viewport.translation.x,\n enabledElement.viewport.translation.y\n );\n\n // Rotate again so we can apply general scale\n if (angle !== 0) {\n transform.rotate((angle * Math.PI) / 180);\n }\n\n if (scale !== undefined) {\n // Apply the font scale\n transform.scale(scale, scale);\n }\n\n // Apply Flip if required\n if (enabledElement.viewport.hflip) {\n transform.scale(-1, 1);\n }\n\n if (enabledElement.viewport.vflip) {\n transform.scale(1, -1);\n }\n\n // Move back from center of image\n transform.translate(-width / 2, -height / 2);\n\n return transform;\n}\n","import calculateTransform from './calculateTransform';\nimport { CPUFallbackEnabledElement } from '../../../../types';\n\n/**\n * Sets the canvas context transformation matrix to the pixel coordinate system. This allows\n * geometry to be driven using the canvas context using coordinates in the pixel coordinate system\n * @param {EnabledElement} enabledElement The\n * @param {CanvasRenderingContext2D} context The CanvasRenderingContext2D for the enabledElement's Canvas\n * @param {Number} [scale] Optional scale to apply\n * @returns {void}\n */\nexport default function (\n enabledElement: CPUFallbackEnabledElement,\n context: CanvasRenderingContext2D,\n scale?: number\n): void {\n if (enabledElement === undefined) {\n throw new Error(\n 'setToPixelCoordinateSystem: parameter enabledElement must not be undefined'\n );\n }\n if (context === undefined) {\n throw new Error(\n 'setToPixelCoordinateSystem: parameter context must not be undefined'\n );\n }\n\n const transform = calculateTransform(enabledElement, scale);\n const m = transform.getMatrix();\n\n context.setTransform(m[0], m[1], m[2], m[3], m[4], m[5]);\n}\n","import { CPUFallbackEnabledElement, IImage } from '../../../../types';\n\n/**\n * Determine whether or not an Enabled Element needs to be re-rendered.\n *\n * If the imageId has changed, or if any of the last rendered viewport\n * parameters have changed, this function will return true.\n *\n * @param enabledElement - An Enabled Element\n * @param image - An Image\n * @returns Whether - or not the Enabled Element needs to re-render its image\n */\nexport default function doesImageNeedToBeRendered(\n enabledElement: CPUFallbackEnabledElement,\n image: IImage\n): boolean {\n const lastRenderedImageId = enabledElement.renderingTools.lastRenderedImageId;\n const lastRenderedViewport =\n enabledElement.renderingTools.lastRenderedViewport;\n\n return (\n image.imageId !== lastRenderedImageId ||\n !lastRenderedViewport ||\n lastRenderedViewport.windowCenter !==\n enabledElement.viewport.voi.windowCenter ||\n lastRenderedViewport.windowWidth !==\n enabledElement.viewport.voi.windowWidth ||\n lastRenderedViewport.invert !== enabledElement.viewport.invert ||\n lastRenderedViewport.rotation !== enabledElement.viewport.rotation ||\n lastRenderedViewport.hflip !== enabledElement.viewport.hflip ||\n lastRenderedViewport.vflip !== enabledElement.viewport.vflip ||\n lastRenderedViewport.modalityLUT !== enabledElement.viewport.modalityLUT ||\n lastRenderedViewport.voiLUT !== enabledElement.viewport.voiLUT ||\n lastRenderedViewport.colormap !== enabledElement.viewport.colormap\n );\n}\n","import { CPUFallbackEnabledElement, IImage } from '../../../../types';\n\n/**\n * Sets size and clears canvas\n *\n * @param {Object} enabledElement Cornerstone Enabled Element\n * @param {Object} image Image to be rendered\n * @returns {void}\n * @memberof rendering\n */\nexport default function (\n enabledElement: CPUFallbackEnabledElement,\n image: IImage\n): void {\n const renderCanvas = enabledElement.renderingTools.renderCanvas;\n\n // Resize the canvas\n renderCanvas.width = image.width;\n renderCanvas.height = image.height;\n\n const canvasContext = renderCanvas.getContext('2d');\n\n // NOTE - we need to fill the render canvas with white pixels since we\n // control the luminance using the alpha channel to improve rendering performance.\n canvasContext.fillStyle = 'white';\n canvasContext.fillRect(0, 0, renderCanvas.width, renderCanvas.height);\n\n const renderCanvasData = canvasContext.getImageData(\n 0,\n 0,\n image.width,\n image.height\n );\n\n enabledElement.renderingTools.renderCanvasContext = canvasContext;\n enabledElement.renderingTools.renderCanvasData = renderCanvasData;\n}\n","import {\n CPUFallbackEnabledElement,\n CPUFallbackRenderingTools,\n} from '../../../../types';\n\n/**\n * Saves the parameters of the last render into renderingTools, used later to decide if data can be reused.\n *\n * @param {Object} enabledElement Cornerstone EnabledElement\n * @returns {Object} enabledElement.renderingTools\n * @memberof rendering\n */\n\nexport default function (\n enabledElement: CPUFallbackEnabledElement\n): CPUFallbackRenderingTools {\n const imageId = enabledElement.image.imageId;\n const viewport = enabledElement.viewport;\n const isColor = enabledElement.image.color;\n\n enabledElement.renderingTools.lastRenderedImageId = imageId;\n enabledElement.renderingTools.lastRenderedIsColor = isColor;\n enabledElement.renderingTools.lastRenderedViewport = {\n windowCenter: viewport.voi.windowCenter,\n windowWidth: viewport.voi.windowWidth,\n invert: viewport.invert,\n rotation: viewport.rotation,\n hflip: viewport.hflip,\n vflip: viewport.vflip,\n modalityLUT: viewport.modalityLUT,\n voiLUT: viewport.voiLUT,\n colormap: viewport.colormap,\n };\n\n return enabledElement.renderingTools;\n}\n","import now from './now';\nimport generateColorLUT from './generateColorLUT';\nimport storedColorPixelDataToCanvasImageData from './storedColorPixelDataToCanvasImageData';\nimport storedRGBAPixelDataToCanvasImageData from './storedRGBAPixelDataToCanvasImageData';\nimport setToPixelCoordinateSystem from './setToPixelCoordinateSystem';\nimport doesImageNeedToBeRendered from './doesImageNeedToBeRendered';\nimport initializeRenderCanvas from './initializeRenderCanvas';\nimport saveLastRendered from './saveLastRendered';\nimport {\n IImage,\n CPUFallbackViewport,\n CPUFallbackEnabledElement,\n} from '../../../../types';\n\n/**\n * Generates an appropriate Look Up Table to render the given image with the given window width and level (specified in the viewport)\n * Uses an internal cache for performance\n *\n * @param {Object} image The image to be rendered\n * @param {Object} viewport The viewport values used for rendering\n * @returns {Uint8ClampedArray} Look Up Table array.\n * @memberof rendering\n */\nfunction getLut(image: IImage, viewport: CPUFallbackViewport) {\n // If we have a cached lut and it has the right values, return it immediately\n if (\n image.cachedLut !== undefined &&\n image.cachedLut.windowCenter === viewport.voi.windowCenter &&\n image.cachedLut.windowWidth === viewport.voi.windowWidth &&\n image.cachedLut.invert === viewport.invert\n ) {\n return image.cachedLut.lutArray;\n }\n\n // Lut is invalid or not present, regenerate it and cache it\n generateColorLUT(\n image,\n viewport.voi.windowWidth,\n viewport.voi.windowCenter,\n viewport.invert\n );\n image.cachedLut.windowWidth = viewport.voi.windowWidth;\n image.cachedLut.windowCenter = viewport.voi.windowCenter;\n image.cachedLut.invert = viewport.invert;\n\n return image.cachedLut.lutArray;\n}\n\n/**\n * Returns an appropriate canvas to render the Image. If the canvas available in the cache is appropriate\n * it is returned, otherwise adjustments are made. It also sets the color transfer functions.\n *\n * @param enabledElement - The cornerstone enabled element\n * @param image - The image to be rendered\n * @param invalidated - Is pixel data valid\n * @returns An appropriate canvas for rendering the image\n * @memberof rendering\n */\nfunction getRenderCanvas(\n enabledElement: CPUFallbackEnabledElement,\n image: IImage,\n invalidated: boolean\n): HTMLCanvasElement {\n const canvasWasColor =\n enabledElement.renderingTools.lastRenderedIsColor === true;\n\n if (!enabledElement.renderingTools.renderCanvas || !canvasWasColor) {\n enabledElement.renderingTools.renderCanvas =\n document.createElement('canvas');\n }\n\n const renderCanvas = enabledElement.renderingTools.renderCanvas;\n\n // The ww/wc is identity and not inverted - get a canvas with the image rendered into it for\n // Fast drawing\n if (\n enabledElement.viewport.voi.windowWidth === 255 &&\n enabledElement.viewport.voi.windowCenter === 128 &&\n enabledElement.viewport.invert === false &&\n image.getCanvas &&\n image.getCanvas()\n ) {\n return image.getCanvas();\n }\n\n // Apply the lut to the stored pixel data onto the render canvas\n if (\n doesImageNeedToBeRendered(enabledElement, image) === false &&\n invalidated !== true\n ) {\n return renderCanvas;\n }\n\n // If our render canvas does not match the size of this image reset it\n // NOTE: This might be inefficient if we are updating multiple images of different\n // Sizes frequently.\n if (\n renderCanvas.width !== image.width ||\n renderCanvas.height !== image.height\n ) {\n initializeRenderCanvas(enabledElement, image);\n }\n\n // Get the lut to use\n let start = now();\n const colorLUT = getLut(image, enabledElement.viewport);\n\n image.stats = image.stats || {};\n image.stats.lastLutGenerateTime = now() - start;\n\n const renderCanvasData = enabledElement.renderingTools.renderCanvasData;\n const renderCanvasContext = enabledElement.renderingTools.renderCanvasContext;\n\n // The color image voi/invert has been modified - apply the lut to the underlying\n // Pixel data and put it into the renderCanvas\n if (image.rgba) {\n storedRGBAPixelDataToCanvasImageData(\n image,\n colorLUT,\n renderCanvasData.data\n );\n } else {\n storedColorPixelDataToCanvasImageData(\n image,\n colorLUT,\n renderCanvasData.data\n );\n }\n\n start = now();\n renderCanvasContext.putImageData(renderCanvasData, 0, 0);\n image.stats.lastPutImageDataTime = now() - start;\n\n return renderCanvas;\n}\n\n/**\n * API function to render a color image to an enabled element\n *\n * @param {EnabledElement} enabledElement The Cornerstone Enabled Element to redraw\n * @param {Boolean} invalidated - true if pixel data has been invalidated and cached rendering should not be used\n * @returns {void}\n * @memberof rendering\n */\nexport function renderColorImage(\n enabledElement: CPUFallbackEnabledElement,\n invalidated: boolean\n): void {\n if (enabledElement === undefined) {\n throw new Error(\n 'renderColorImage: enabledElement parameter must not be undefined'\n );\n }\n\n const image = enabledElement.image;\n\n if (image === undefined) {\n throw new Error(\n 'renderColorImage: image must be loaded before it can be drawn'\n );\n }\n\n // Get the canvas context and reset the transform\n const context = enabledElement.canvas.getContext('2d');\n\n context.setTransform(1, 0, 0, 1, 0, 0);\n\n // Clear the canvas\n context.fillStyle = 'black';\n context.fillRect(\n 0,\n 0,\n enabledElement.canvas.width,\n enabledElement.canvas.height\n );\n\n // Turn off image smooth/interpolation if pixelReplication is set in the viewport\n context.imageSmoothingEnabled = !enabledElement.viewport.pixelReplication;\n\n // Save the canvas context state and apply the viewport properties\n setToPixelCoordinateSystem(enabledElement, context);\n\n const renderCanvas = getRenderCanvas(enabledElement, image, invalidated);\n\n const sx = enabledElement.viewport.displayedArea.tlhc.x - 1;\n const sy = enabledElement.viewport.displayedArea.tlhc.y - 1;\n const width = enabledElement.viewport.displayedArea.brhc.x - sx;\n const height = enabledElement.viewport.displayedArea.brhc.y - sy;\n\n context.drawImage(renderCanvas, sx, sy, width, height, 0, 0, width, height);\n\n enabledElement.renderingTools = saveLastRendered(enabledElement);\n}\n","import getVOILUT from './getVOILut';\nimport { IImage, CPUFallbackLUT } from '../../../../types';\n\n/**\n * Creates a LUT used while rendering to convert stored pixel values to\n * display pixels\n *\n * @param image - A Cornerstone Image Object\n * @param windowWidth - The Window Width\n * @param windowCenter - The Window Center\n * @param invert - A boolean describing whether or not the image has been inverted\n * @param voiLUT- A Volume of Interest Lookup Table\n *\n * @returns A lookup table to apply to the image\n */\nexport default function (\n image: IImage,\n windowWidth: number | number[],\n windowCenter: number | number[],\n invert: boolean,\n voiLUT?: CPUFallbackLUT\n) {\n const maxPixelValue = image.maxPixelValue;\n const minPixelValue = image.minPixelValue;\n const offset = Math.min(minPixelValue, 0);\n\n if (image.cachedLut === undefined) {\n const length = maxPixelValue - offset + 1;\n\n image.cachedLut = {};\n image.cachedLut.lutArray = new Uint8ClampedArray(length);\n }\n\n const lut = image.cachedLut.lutArray;\n const vlutfn = getVOILUT(\n Array.isArray(windowWidth) ? windowWidth[0] : windowWidth,\n Array.isArray(windowCenter) ? windowCenter[0] : windowCenter,\n voiLUT\n );\n\n if (invert === true) {\n for (\n let storedValue = minPixelValue;\n storedValue <= maxPixelValue;\n storedValue++\n ) {\n lut[storedValue + -offset] = 255 - vlutfn(storedValue);\n }\n } else {\n for (\n let storedValue = minPixelValue;\n storedValue <= maxPixelValue;\n storedValue++\n ) {\n lut[storedValue + -offset] = vlutfn(storedValue);\n }\n }\n\n return lut;\n}\n","import now from './now';\nimport { IImage } from '../../../../types';\n\n/**\n * Converts stored RGBA color pixel values to display pixel values using a LUT.\n *\n * @param {Image} image A Cornerstone Image Object\n * @param {Array} lut Lookup table array\n * @param {Uint8ClampedArray} canvasImageDataData canvasImageData.data buffer filled with white pixels\n *\n * @returns {void}\n * @memberof Internal\n */\nexport default function (\n image: IImage,\n lut: Uint8ClampedArray,\n canvasImageDataData: Uint8ClampedArray\n): void {\n let start = now();\n const pixelData = image.getPixelData();\n\n image.stats.lastGetPixelDataTime = now() - start;\n\n const minPixelValue = image.minPixelValue;\n let canvasImageDataIndex = 0;\n let storedPixelDataIndex = 0;\n const numPixels = pixelData.length;\n\n // NOTE: As of Nov 2014, most javascript engines have lower performance when indexing negative indexes.\n // We have a special code path for this case that improves performance. Thanks to @jpambrun for this enhancement\n start = now();\n if (minPixelValue < 0) {\n while (storedPixelDataIndex < numPixels) {\n canvasImageDataData[canvasImageDataIndex++] =\n lut[pixelData[storedPixelDataIndex++] + -minPixelValue]; // Red\n canvasImageDataData[canvasImageDataIndex++] =\n lut[pixelData[storedPixelDataIndex++] + -minPixelValue]; // Green\n canvasImageDataData[canvasImageDataIndex++] =\n lut[pixelData[storedPixelDataIndex++] + -minPixelValue]; // Blue\n canvasImageDataData[canvasImageDataIndex++] =\n pixelData[storedPixelDataIndex++];\n }\n } else {\n while (storedPixelDataIndex < numPixels) {\n canvasImageDataData[canvasImageDataIndex++] =\n lut[pixelData[storedPixelDataIndex++]]; // Red\n canvasImageDataData[canvasImageDataIndex++] =\n lut[pixelData[storedPixelDataIndex++]]; // Green\n canvasImageDataData[canvasImageDataIndex++] =\n lut[pixelData[storedPixelDataIndex++]]; // Blue\n canvasImageDataData[canvasImageDataIndex++] =\n pixelData[storedPixelDataIndex++];\n }\n }\n image.stats.lastStoredPixelDataToCanvasImageDataTime = now() - start;\n}\n","import now from './now';\nimport { IImage } from '../../../../types';\n\n/**\n * Converts stored color pixel values to display pixel values using a LUT.\n *\n * Note: Skips alpha value for any input image pixel data.\n *\n * @param {Image} image A Cornerstone Image Object\n * @param {Array} lut Lookup table array\n * @param {Uint8ClampedArray} canvasImageDataData canvasImageData.data buffer filled with white pixels\n *\n * @returns {void}\n * @memberof Internal\n */\nexport default function (\n image: IImage,\n lut: Uint8ClampedArray,\n canvasImageDataData: Uint8ClampedArray\n): void {\n let start = now();\n const pixelData = image.getPixelData();\n\n image.stats.lastGetPixelDataTime = now() - start;\n\n const minPixelValue = image.minPixelValue;\n let canvasImageDataIndex = 0;\n let storedPixelDataIndex = 0;\n const numPixels = pixelData.length;\n\n // NOTE: As of Nov 2014, most javascript engines have lower performance when indexing negative indexes.\n // We have a special code path for this case that improves performance. Thanks to @jpambrun for this enhancement\n start = now();\n if (minPixelValue < 0) {\n while (storedPixelDataIndex < numPixels) {\n canvasImageDataData[canvasImageDataIndex++] =\n lut[pixelData[storedPixelDataIndex++] + -minPixelValue]; // Red\n canvasImageDataData[canvasImageDataIndex++] =\n lut[pixelData[storedPixelDataIndex++] + -minPixelValue]; // Green\n canvasImageDataData[canvasImageDataIndex] =\n lut[pixelData[storedPixelDataIndex] + -minPixelValue]; // Blue\n storedPixelDataIndex += 2;\n canvasImageDataIndex += 2;\n }\n } else {\n while (storedPixelDataIndex < numPixels) {\n canvasImageDataData[canvasImageDataIndex++] =\n lut[pixelData[storedPixelDataIndex++]]; // Red\n canvasImageDataData[canvasImageDataIndex++] =\n lut[pixelData[storedPixelDataIndex++]]; // Green\n canvasImageDataData[canvasImageDataIndex] =\n lut[pixelData[storedPixelDataIndex]]; // Blue\n storedPixelDataIndex += 2;\n canvasImageDataIndex += 2;\n }\n }\n image.stats.lastStoredPixelDataToCanvasImageDataTime = now() - start;\n}\n","import now from './now';\nimport { IImage } from '../../../../types';\n\n/**\n * This function transforms stored pixel values into a canvas image data buffer\n * by using a LUT. This is the most performance sensitive code in cornerstone and\n * we use a special trick to make this go as fast as possible. Specifically we\n * use the alpha channel only to control the luminance rather than the red, green and\n * blue channels which makes it over 3x faster. The canvasImageDataData buffer needs\n * to be previously filled with white pixels.\n *\n * NOTE: Attribution would be appreciated if you use this technique!\n *\n * @param {Image} image A Cornerstone Image Object\n * @param {Array} lut Lookup table array\n * @param {Uint8ClampedArray} canvasImageDataData canvasImageData.data buffer filled with white pixels\n *\n * @returns {void}\n * @memberof Internal\n */\nexport default function (\n image: IImage,\n lut: Uint8ClampedArray,\n canvasImageDataData: Uint8ClampedArray\n): void {\n let start = now();\n const pixelData = image.getPixelData();\n\n image.stats.lastGetPixelDataTime = now() - start;\n\n const numPixels = pixelData.length;\n const minPixelValue = image.minPixelValue;\n let canvasImageDataIndex = 3;\n let storedPixelDataIndex = 0;\n\n // NOTE: As of Nov 2014, most javascript engines have lower performance when indexing negative indexes.\n // We have a special code path for this case that improves performance. Thanks to @jpambrun for this enhancement\n\n // Added two paths (Int16Array, Uint16Array) to avoid polymorphic deoptimization in chrome.\n start = now();\n if (pixelData instanceof Int16Array) {\n if (minPixelValue < 0) {\n while (storedPixelDataIndex < numPixels) {\n canvasImageDataData[canvasImageDataIndex] =\n lut[pixelData[storedPixelDataIndex++] + -minPixelValue]; // Alpha\n canvasImageDataIndex += 4;\n }\n } else {\n while (storedPixelDataIndex < numPixels) {\n canvasImageDataData[canvasImageDataIndex] =\n lut[pixelData[storedPixelDataIndex++]]; // Alpha\n canvasImageDataIndex += 4;\n }\n }\n } else if (pixelData instanceof Uint16Array) {\n while (storedPixelDataIndex < numPixels) {\n canvasImageDataData[canvasImageDataIndex] =\n lut[pixelData[storedPixelDataIndex++]]; // Alpha\n canvasImageDataIndex += 4;\n }\n } else if (minPixelValue < 0) {\n while (storedPixelDataIndex < numPixels) {\n canvasImageDataData[canvasImageDataIndex] =\n lut[pixelData[storedPixelDataIndex++] + -minPixelValue]; // Alpha\n canvasImageDataIndex += 4;\n }\n } else {\n while (storedPixelDataIndex < numPixels) {\n canvasImageDataData[canvasImageDataIndex] =\n lut[pixelData[storedPixelDataIndex++]]; // Alpha\n canvasImageDataIndex += 4;\n }\n }\n\n image.stats.lastStoredPixelDataToCanvasImageDataTime = now() - start;\n}\n","import now from './now';\nimport { IImage } from '../../../../types';\n\n/**\n * This function transforms stored pixel values into a canvas image data buffer\n * by using a LUT. This is the most performance sensitive code in cornerstone and\n * we use a special trick to make this go as fast as possible. Specifically we\n * use the alpha channel only to control the luminance rather than the red, green and\n * blue channels which makes it over 3x faster. The canvasImageDataData buffer needs\n * to be previously filled with white pixels.\n *\n * NOTE: Attribution would be appreciated if you use this technique!\n *\n * @param {Image} image A Cornerstone Image Object\n * @param {Array} lut Lookup table array\n * @param {Uint8ClampedArray} canvasImageDataData canvasImageData.data buffer filled with white pixels\n *\n * @returns {void}\n * @memberof Internal\n */\nexport default function (\n image: IImage,\n lutFunction: (value: number) => number,\n canvasImageDataData: Uint8ClampedArray\n): void {\n let start = now();\n const pixelData = image.getPixelData();\n\n image.stats.lastGetPixelDataTime = now() - start;\n\n const numPixels = pixelData.length;\n // const minPixelValue = image.minPixelValue;\n let canvasImageDataIndex = 3;\n let storedPixelDataIndex = 0;\n\n // NOTE: As of Nov 2014, most javascript engines have lower performance when indexing negative indexes.\n // We have a special code path for this case that improves performance. Thanks to @jpambrun for this enhancement\n\n // Added two paths (Int16Array, Uint16Array) to avoid polymorphic deoptimization in chrome.\n start = now();\n\n while (storedPixelDataIndex < numPixels) {\n canvasImageDataData[canvasImageDataIndex] = lutFunction(\n pixelData[storedPixelDataIndex++]\n ); // Alpha\n canvasImageDataIndex += 4;\n }\n\n image.stats.lastStoredPixelDataToCanvasImageDataTime = now() - start;\n}\n","import now from './now';\nimport { IImage } from '../../../../types';\n\n/**\n * This function transforms stored pixel values into a canvas image data buffer\n * by using a LUT.\n *\n * @param {Image} image A Cornerstone Image Object\n * @param {Array} lut Lookup table array\n * @param {Uint8ClampedArray} canvasImageDataData canvasImageData.data buffer filled with white pixels\n *\n * @returns {void}\n * @memberof Internal\n */\nexport default function (\n image: IImage,\n lut: Uint8ClampedArray,\n canvasImageDataData: Uint8ClampedArray\n): void {\n let start = now();\n const pixelData = image.getPixelData();\n\n image.stats.lastGetPixelDataTime = now() - start;\n\n const numPixels = pixelData.length;\n const minPixelValue = image.minPixelValue;\n let canvasImageDataIndex = 0;\n let storedPixelDataIndex = 0;\n let pixelValue;\n\n // NOTE: As of Nov 2014, most javascript engines have lower performance when indexing negative indexes.\n // We have a special code path for this case that improves performance. Thanks to @jpambrun for this enhancement\n\n // Added two paths (Int16Array, Uint16Array) to avoid polymorphic deoptimization in chrome.\n start = now();\n if (pixelData instanceof Int16Array) {\n if (minPixelValue < 0) {\n while (storedPixelDataIndex < numPixels) {\n pixelValue = lut[pixelData[storedPixelDataIndex++] + -minPixelValue];\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = 255; // Alpha\n }\n } else {\n while (storedPixelDataIndex < numPixels) {\n pixelValue = lut[pixelData[storedPixelDataIndex++]];\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = 255; // Alpha\n }\n }\n } else if (pixelData instanceof Uint16Array) {\n while (storedPixelDataIndex < numPixels) {\n pixelValue = lut[pixelData[storedPixelDataIndex++]];\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = 255; // Alpha\n }\n } else if (minPixelValue < 0) {\n while (storedPixelDataIndex < numPixels) {\n pixelValue = lut[pixelData[storedPixelDataIndex++] + -minPixelValue];\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = 255; // Alpha\n }\n } else {\n while (storedPixelDataIndex < numPixels) {\n pixelValue = lut[pixelData[storedPixelDataIndex++]];\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = 255; // Alpha\n }\n }\n\n image.stats.lastStoredPixelDataToCanvasImageDataTime = now() - start;\n}\n","/**\n * Check if two lookup tables match\n *\n * @param {LUT} a A lookup table function\n * @param {LUT} b Another lookup table function\n * @return {boolean} Whether or not they match\n * @memberof rendering\n */\nexport default function (a: any, b: any) {\n // If undefined, they are equal\n if (!a && !b) {\n return true;\n }\n // If one is undefined, not equal\n if (!a || !b) {\n return false;\n }\n\n // Check the unique ids\n return a.id === b.id;\n}\n","import computeAutoVoi from './computeAutoVoi';\nimport lutMatches from './lutMatches';\nimport generateLut from './generateLut';\nimport { IImage, CPUFallbackViewport } from '../../../../types';\n\n/**\n * Retrieve or generate a LUT Array for an Image and Viewport\n *\n * @param {Image} image An Image Object\n * @param {Viewport} viewport An Viewport Object\n * @param {Boolean} invalidated Whether or not the LUT data has been invalidated\n * (e.g. by a change to the windowWidth, windowCenter, or invert viewport parameters).\n * @return {Uint8ClampedArray} LUT Array\n * @memberof rendering\n */\nexport default function (\n image: IImage,\n viewport: CPUFallbackViewport,\n invalidated: boolean\n): Uint8ClampedArray {\n // If we have a cached lut and it has the right values, return it immediately\n if (\n image.cachedLut !== undefined &&\n image.cachedLut.windowCenter === viewport.voi.windowCenter &&\n image.cachedLut.windowWidth === viewport.voi.windowWidth &&\n lutMatches(image.cachedLut.modalityLUT, viewport.modalityLUT) &&\n lutMatches(image.cachedLut.voiLUT, viewport.voiLUT) &&\n image.cachedLut.invert === viewport.invert &&\n invalidated !== true\n ) {\n return image.cachedLut.lutArray;\n }\n\n computeAutoVoi(viewport, image);\n\n // Lut is invalid or not present, regenerate it and cache it\n generateLut(\n image,\n viewport.voi.windowWidth,\n viewport.voi.windowCenter,\n viewport.invert,\n viewport.modalityLUT,\n viewport.voiLUT\n );\n\n image.cachedLut.windowWidth = viewport.voi.windowWidth;\n image.cachedLut.windowCenter = viewport.voi.windowCenter;\n image.cachedLut.invert = viewport.invert;\n image.cachedLut.voiLUT = viewport.voiLUT;\n image.cachedLut.modalityLUT = viewport.modalityLUT;\n\n return image.cachedLut.lutArray;\n}\n","import type { IImage, CPUFallbackViewport } from '../../../../types';\n\n/**\n * Computes the VOI to display all the pixels if no VOI LUT data (Window Width/Window Center or voiLUT) exists on the viewport object.\n *\n * @param viewport - Object containing the viewport properties\n * @param image - An Image loaded by a Cornerstone Image Loader\n */\nexport default function computeAutoVoi(\n viewport: CPUFallbackViewport,\n image: IImage\n): void {\n if (hasVoi(viewport)) {\n return;\n }\n\n const maxVoi = image.maxPixelValue * image.slope + image.intercept;\n const minVoi = image.minPixelValue * image.slope + image.intercept;\n const ww = maxVoi - minVoi;\n const wc = (maxVoi + minVoi) / 2;\n\n if (viewport.voi === undefined) {\n viewport.voi = {\n windowWidth: ww,\n windowCenter: wc,\n };\n } else {\n viewport.voi.windowWidth = ww;\n viewport.voi.windowCenter = wc;\n }\n}\n\n/**\n * Check if viewport has voi LUT data\n * @param viewport - The viewport to check for voi LUT data\n * @returns true viewport has LUT data (Window Width/Window Center or voiLUT). Otherwise, false.\n */\nfunction hasVoi(viewport: CPUFallbackViewport): boolean {\n const hasLut =\n viewport.voiLUT && viewport.voiLUT.lut && viewport.voiLUT.lut.length > 0;\n\n return (\n hasLut ||\n (viewport.voi.windowWidth !== undefined &&\n viewport.voi.windowCenter !== undefined)\n );\n}\n","import getModalityLut from './getModalityLut';\nimport getVOILUT from './getVOILut';\nimport { IImage, CPUFallbackLUT } from '../../../../types';\n\n/**\n * Creates a LUT used while rendering to convert stored pixel values to\n * display pixels\n *\n * @param image - A Cornerstone Image Object\n * @param windowWidth - The Window Width\n * @param windowCenter - The Window Center\n * @param invert - A boolean describing whether or not the image has been inverted\n * @param modalityLUT - A modality Lookup Table\n * @param voiLUT - A Volume of Interest Lookup Table\n *\n * @returns A lookup table to apply to the image\n */\nexport default function (\n image: IImage,\n windowWidth: number,\n windowCenter: number,\n invert: boolean,\n modalityLUT: CPUFallbackLUT,\n voiLUT: CPUFallbackLUT\n): Uint8ClampedArray {\n const maxPixelValue = image.maxPixelValue;\n const minPixelValue = image.minPixelValue;\n const offset = Math.min(minPixelValue, 0);\n\n if (image.cachedLut === undefined) {\n const length = maxPixelValue - offset + 1;\n\n image.cachedLut = {};\n image.cachedLut.lutArray = new Uint8ClampedArray(length);\n }\n\n const lut = image.cachedLut.lutArray;\n\n const mlutfn = getModalityLut(image.slope, image.intercept, modalityLUT);\n const vlutfn = getVOILUT(windowWidth, windowCenter, voiLUT);\n\n if (image.isPreScaled) {\n // if the image is already preScaled, it means that the slop and the intercept\n // are applied and there is no need for a modalityLut\n if (invert === true) {\n for (\n let storedValue = minPixelValue;\n storedValue <= maxPixelValue;\n storedValue++\n ) {\n lut[storedValue + -offset] = 255 - vlutfn(storedValue);\n }\n } else {\n for (\n let storedValue = minPixelValue;\n storedValue <= maxPixelValue;\n storedValue++\n ) {\n lut[storedValue + -offset] = vlutfn(storedValue);\n }\n }\n } else {\n if (invert === true) {\n for (\n let storedValue = minPixelValue;\n storedValue <= maxPixelValue;\n storedValue++\n ) {\n lut[storedValue + -offset] = 255 - vlutfn(mlutfn(storedValue));\n }\n } else {\n for (\n let storedValue = minPixelValue;\n storedValue <= maxPixelValue;\n storedValue++\n ) {\n lut[storedValue + -offset] = vlutfn(mlutfn(storedValue));\n }\n }\n }\n\n return lut;\n}\n","/**\n * Generates a linear modality transformation function\n *\n * See DICOM PS3.3 C.11.1 Modality LUT Module\n *\n * http://dicom.nema.org/medical/Dicom/current/output/chtml/part03/sect_C.11.html\n *\n * @param {Number} slope m in the equation specified by Rescale Intercept (0028,1052).\n * @param {Number} intercept The value b in relationship between stored values (SV) and the output units specified in Rescale Type (0028,1054).\n\n Output units = m*SV + b.\n * @return {function(*): *} A linear modality LUT function. Given a stored pixel it returns the modality pixel value\n * @memberof Internal\n */\nfunction generateLinearModalityLUT(slope, intercept) {\n return (storedPixelValue) => storedPixelValue * slope + intercept;\n}\n\nfunction generateNonLinearModalityLUT(modalityLUT) {\n const minValue = modalityLUT.lut[0];\n const maxValue = modalityLUT.lut[modalityLUT.lut.length - 1];\n const maxValueMapped = modalityLUT.firstValueMapped + modalityLUT.lut.length;\n\n return (storedPixelValue) => {\n if (storedPixelValue < modalityLUT.firstValueMapped) {\n return minValue;\n } else if (storedPixelValue >= maxValueMapped) {\n return maxValue;\n }\n\n return modalityLUT.lut[storedPixelValue];\n };\n}\n\n/**\n * Get the appropriate Modality LUT for the current situation.\n *\n * @param {Number} [slope] m in the equation specified by Rescale Intercept (0028,1052).\n * @param {Number} [intercept] The value b in relationship between stored values (SV) and the output units specified in Rescale Type (0028,1054).\n * @param {Function} [modalityLUT] A modality LUT function. Given a stored pixel it returns the modality pixel value.\n *\n * @return {function(*): *} A modality LUT function. Given a stored pixel it returns the modality pixel value.\n * @memberof Internal\n */\nexport default function (\n slope: number,\n intercept: number,\n modalityLUT: unknown\n) {\n if (modalityLUT) {\n return generateNonLinearModalityLUT(modalityLUT);\n }\n\n return generateLinearModalityLUT(slope, intercept);\n}\n","import storedPixelDataToCanvasImageData from './storedPixelDataToCanvasImageData';\nimport storedPixelDataToCanvasImageDataPET from './storedPixelDataToCanvasImageDataPET';\nimport storedPixelDataToCanvasImageDataRGBA from './storedPixelDataToCanvasImageDataRGBA';\nimport setToPixelCoordinateSystem from './setToPixelCoordinateSystem';\nimport now from './now';\nimport getLut from './getLut';\nimport doesImageNeedToBeRendered from './doesImageNeedToBeRendered';\nimport initializeRenderCanvas from './initializeRenderCanvas';\nimport saveLastRendered from './saveLastRendered';\nimport { IImage, CPUFallbackEnabledElement } from '../../../../types';\n\n/**\n * Returns an appropriate canvas to render the Image. If the canvas available in the cache is appropriate\n * it is returned, otherwise adjustments are made. It also sets the color transfer functions.\n *\n * @param {Object} enabledElement The cornerstone enabled element\n * @param {Object} image The image to be rendered\n * @param {Boolean} invalidated Is pixel data valid\n * @param {Boolean} [useAlphaChannel = true] Will an alpha channel be used\n * @returns {HTMLCanvasElement} An appropriate canvas for rendering the image\n * @memberof rendering\n */\nfunction getRenderCanvas(\n enabledElement: CPUFallbackEnabledElement,\n image: IImage,\n invalidated: boolean,\n useAlphaChannel = true\n): HTMLCanvasElement {\n const canvasWasColor =\n enabledElement.renderingTools.lastRenderedIsColor === true;\n\n if (!enabledElement.renderingTools.renderCanvas || canvasWasColor) {\n enabledElement.renderingTools.renderCanvas =\n document.createElement('canvas');\n initializeRenderCanvas(enabledElement, image);\n }\n\n const renderCanvas = enabledElement.renderingTools.renderCanvas;\n\n if (\n doesImageNeedToBeRendered(enabledElement, image) === false &&\n invalidated !== true\n ) {\n return renderCanvas;\n }\n\n // If our render canvas does not match the size of this image reset it\n // NOTE: This might be inefficient if we are updating multiple images of different\n // Sizes frequently.\n if (\n renderCanvas.width !== image.width ||\n renderCanvas.height !== image.height\n ) {\n initializeRenderCanvas(enabledElement, image);\n }\n\n image.stats = image.stats || {};\n\n const renderCanvasData = enabledElement.renderingTools.renderCanvasData;\n const renderCanvasContext = enabledElement.renderingTools.renderCanvasContext;\n\n let start = now();\n image.stats.lastLutGenerateTime = now() - start;\n\n const { viewport } = enabledElement;\n\n // If modality is 'PT' and the image is scaled then the results are floating points,\n // and we cannot create a lut for it (cannot have float indices). Therefore,\n // we use a mapping function to get the voiLUT from the values by applying\n // the windowLevel and windowWidth.\n if (viewport.modality === 'PT' && image.isPreScaled) {\n const { windowWidth, windowCenter } = viewport.voi;\n const minimum = windowCenter - windowWidth / 2;\n const maximum = windowCenter + windowWidth / 2;\n const range = maximum - minimum;\n const collectedMultiplierTerms = 255.0 / range;\n\n let petVOILutFunction;\n\n if (viewport.invert) {\n petVOILutFunction = (value) =>\n 255 - (value - minimum) * collectedMultiplierTerms;\n } else {\n // Note, don't need to math.floor, that is dealt with by setting the value in the Uint8Array.\n petVOILutFunction = (value) =>\n (value - minimum) * collectedMultiplierTerms;\n }\n\n storedPixelDataToCanvasImageDataPET(\n image,\n petVOILutFunction,\n renderCanvasData.data\n );\n } else {\n // Get the lut to use\n const lut = getLut(image, viewport, invalidated);\n\n if (useAlphaChannel) {\n storedPixelDataToCanvasImageData(image, lut, renderCanvasData.data);\n } else {\n storedPixelDataToCanvasImageDataRGBA(image, lut, renderCanvasData.data);\n }\n }\n\n start = now();\n renderCanvasContext.putImageData(renderCanvasData, 0, 0);\n image.stats.lastPutImageDataTime = now() - start;\n\n return renderCanvas;\n}\n\n/**\n * API function to draw a grayscale image to a given enabledElement\n *\n * @param {EnabledElement} enabledElement The Cornerstone Enabled Element to redraw\n * @param {Boolean} invalidated - true if pixel data has been invalidated and cached rendering should not be used\n * @returns {void}\n * @memberof rendering\n */\nexport function renderGrayscaleImage(\n enabledElement: CPUFallbackEnabledElement,\n invalidated: boolean\n): void {\n if (enabledElement === undefined) {\n throw new Error(\n 'drawImage: enabledElement parameter must not be undefined'\n );\n }\n\n const image = enabledElement.image;\n\n if (image === undefined) {\n throw new Error('drawImage: image must be loaded before it can be drawn');\n }\n\n // Get the canvas context and reset the transform\n const context = enabledElement.canvas.getContext('2d');\n\n context.setTransform(1, 0, 0, 1, 0, 0);\n\n // Clear the canvas\n context.fillStyle = 'black';\n context.fillRect(\n 0,\n 0,\n enabledElement.canvas.width,\n enabledElement.canvas.height\n );\n\n // Turn off image smooth/interpolation if pixelReplication is set in the viewport\n context.imageSmoothingEnabled = !enabledElement.viewport.pixelReplication;\n\n // Save the canvas context state and apply the viewport properties\n setToPixelCoordinateSystem(enabledElement, context);\n\n const renderCanvas = getRenderCanvas(enabledElement, image, invalidated);\n\n const sx = enabledElement.viewport.displayedArea.tlhc.x - 1;\n const sy = enabledElement.viewport.displayedArea.tlhc.y - 1;\n const width = enabledElement.viewport.displayedArea.brhc.x - sx;\n const height = enabledElement.viewport.displayedArea.brhc.y - sy;\n\n context.drawImage(renderCanvas, sx, sy, width, height, 0, 0, width, height);\n\n enabledElement.renderingTools = saveLastRendered(enabledElement);\n}\n","import { Point2, Point4, CPUFallbackLookupTable } from '../../../../types';\n\n// This code was created based on vtkLookupTable\n// http://www.vtk.org/doc/release/5.0/html/a01697.html\n// https://github.com/Kitware/VTK/blob/master/Common/Core/vtkLookupTable.cxx\nconst BELOW_RANGE_COLOR_INDEX = 0;\nconst ABOVE_RANGE_COLOR_INDEX = 1;\nconst NAN_COLOR_INDEX = 2;\n\n/**\n * Converts an HSV (Hue, Saturation, Value) color to RGB (Red, Green, Blue) color value\n * @param {Number} hue A number representing the hue color value\n * @param {any} sat A number representing the saturation color value\n * @param {any} val A number representing the value color value\n * @returns {Numberp[]} An RGB color array\n */\nfunction HSVToRGB(hue, sat, val) {\n if (hue > 1) {\n throw new Error('HSVToRGB expects hue < 1');\n }\n\n const rgb = [];\n\n if (sat === 0) {\n rgb[0] = val;\n rgb[1] = val;\n rgb[2] = val;\n\n return rgb;\n }\n\n const hueCase = Math.floor(hue * 6);\n const frac = 6 * hue - hueCase;\n const lx = val * (1 - sat);\n const ly = val * (1 - sat * frac);\n const lz = val * (1 - sat * (1 - frac));\n\n switch (hueCase) {\n /* 0<hue<1/6 */\n case 0:\n case 6:\n rgb[0] = val;\n rgb[1] = lz;\n rgb[2] = lx;\n break;\n\n /* 1/6<hue<2/6 */\n case 1:\n rgb[0] = ly;\n rgb[1] = val;\n rgb[2] = lx;\n break;\n\n /* 2/6<hue<3/6 */\n case 2:\n rgb[0] = lx;\n rgb[1] = val;\n rgb[2] = lz;\n break;\n\n /* 3/6<hue/4/6 */\n case 3:\n rgb[0] = lx;\n rgb[1] = ly;\n rgb[2] = val;\n break;\n\n /* 4/6<hue<5/6 */\n case 4:\n rgb[0] = lz;\n rgb[1] = lx;\n rgb[2] = val;\n break;\n\n /* 5/6<hue<1 */\n case 5:\n rgb[0] = val;\n rgb[1] = lx;\n rgb[2] = ly;\n break;\n }\n\n return rgb;\n}\n\n/**\n * Maps a value to an index in the table\n * @param {Number} v A double value which table index will be returned.\n * @param {any} p An object that contains the Table \"Range\", the table \"MaxIndex\",\n * A \"Shift\" from first value in the table and the table \"Scale\" value\n * @returns {Number} The mapped index in the table\n * @memberof Colors\n */\nfunction linearIndexLookupMain(v, p) {\n let dIndex;\n\n // NOTE: Added Math.floor since values were not integers? Check VTK source\n if (v < p.Range[0]) {\n dIndex = p.MaxIndex + BELOW_RANGE_COLOR_INDEX + 1.5;\n } else if (v > p.Range[1]) {\n dIndex = p.MaxIndex + ABOVE_RANGE_COLOR_INDEX + 1.5;\n } else {\n dIndex = (v + p.Shift) * p.Scale;\n }\n\n return Math.floor(dIndex);\n}\n\n/**\n * Maps scalar values into colors via a lookup table\n * LookupTable is an object that is used by mapper objects to map scalar values into rgba (red-green-blue-alpha transparency) color specification,\n * or rgba into scalar values. The color table can be created by direct insertion of color values, or by specifying hue, saturation, value, and alpha range and generating a table\n */\nclass LookupTable implements CPUFallbackLookupTable {\n NumberOfColors: number;\n Ramp: string;\n TableRange: Point2;\n HueRange: Point2;\n SaturationRange: Point2;\n ValueRange: Point2;\n AlphaRange: Point2;\n NaNColor: Point4;\n BelowRangeColor: Point4;\n UseBelowRangeColor: boolean;\n AboveRangeColor: Point4;\n UseAboveRangeColor: boolean;\n InputRange: Point2;\n Table: Point4[];\n\n /**\n * Creates a default linear LookupTable object with 256 colors.\n */\n constructor() {\n this.NumberOfColors = 256;\n this.Ramp = 'linear';\n this.TableRange = [0, 255];\n this.HueRange = [0, 0.66667];\n this.SaturationRange = [1, 1];\n this.ValueRange = [1, 1];\n this.AlphaRange = [1, 1];\n this.NaNColor = [128, 0, 0, 255];\n this.BelowRangeColor = [0, 0, 0, 255];\n this.UseBelowRangeColor = true;\n this.AboveRangeColor = [255, 255, 255, 255];\n this.UseAboveRangeColor = true;\n this.InputRange = [0, 255];\n this.Table = [];\n }\n\n /**\n * Specify the number of values (i.e., colors) in the lookup table.\n * @param {Number} number The number of colors in he LookupTable\n * @returns {void}\n * @memberof Colors\n */\n public setNumberOfTableValues(number) {\n this.NumberOfColors = number;\n }\n\n /**\n * Set the shape of the table ramp to either 'linear', 'scurve' or 'sqrt'\n * @param {String} ramp A string value representing the shape of the table. Allowed values are 'linear', 'scurve' or 'sqrt'\n * @returns {void}\n * @memberof Colors\n */\n public setRamp(ramp) {\n this.Ramp = ramp;\n }\n\n /**\n * Sets the minimum/maximum scalar values for scalar mapping.\n * Scalar values less than minimum range value are clamped to minimum range value.\n * Scalar values greater than maximum range value are clamped to maximum range value.\n * @param {Number} start A double representing the minimum scaler value of the LookupTable\n * @param {any} end A double representing the maximum scaler value of the LookupTable\n * @returns {void}\n * @memberof Colors\n */\n public setTableRange(start, end) {\n this.TableRange[0] = start;\n this.TableRange[1] = end;\n }\n\n /**\n * Set the range in hue (using automatic generation). Hue ranges between [0,1].\n * @param {Number} start A double representing the minimum hue value in a range. Min. is 0\n * @param {Number} end A double representing the maximum hue value in a range. Max. is 1\n * @returns {void}\n * @memberof Colors\n */\n public setHueRange(start, end) {\n this.HueRange[0] = start;\n this.HueRange[1] = end;\n }\n\n /**\n * Set the range in saturation (using automatic generation). Saturation ranges between [0,1].\n * @param {Number} start A double representing the minimum Saturation value in a range. Min. is 0\n * @param {Number} end A double representing the maximum Saturation value in a range. Max. is 1\n * @returns {void}\n * @memberof Colors\n */\n public setSaturationRange(start, end) {\n this.SaturationRange[0] = start;\n this.SaturationRange[1] = end;\n }\n\n /**\n * Set the range in value (using automatic generation). Value ranges between [0,1].\n * @param {Numeber } start A double representing the minimum value in a range. Min. is 0\n * @param {Numeber} end A double representing the maximum value in a range. Max. is 1\n * @returns {void}\n * @memberof Colors\n */\n public setValueRange(start, end) {\n // Set the range in value (using automatic generation). Value ranges between [0,1].\n this.ValueRange[0] = start;\n this.ValueRange[1] = end;\n }\n\n /**\n * (Not Used) Sets the range of scalars which will be mapped.\n * @param {Number} start the minimum scalar value in the range\n * @param {Number} end the maximum scalar value in the range\n * @returns {void}\n * @memberof Colors\n */\n public setRange(start, end) {\n this.InputRange[0] = start;\n this.InputRange[1] = end;\n }\n\n /**\n * Set the range in alpha (using automatic generation). Alpha ranges from [0,1].\n * @param {Number} start A double representing the minimum alpha value\n * @param {Number} end A double representing the maximum alpha value\n * @returns {void}\n * @memberof Colors\n */\n public setAlphaRange(start, end) {\n // Set the range in alpha (using automatic generation). Alpha ranges from [0,1].\n this.AlphaRange[0] = start;\n this.AlphaRange[1] = end;\n }\n\n /**\n * Map one value through the lookup table and return the color as an\n * RGBA array of doubles between 0 and 1.\n * @param {Number} scalar A double scalar value which will be mapped to a color in the LookupTable\n * @returns {Number[]} An RGBA array of doubles between 0 and 1\n * @memberof Colors\n */\n public getColor(scalar) {\n return this.mapValue(scalar);\n }\n\n /**\n * Generate lookup table from hue, saturation, value, alpha min/max values. Table is built from linear ramp of each value.\n * @param {Boolean} force true to force the build of the LookupTable. Otherwie, false. This is useful if a lookup table has been defined manually\n * (using SetTableValue) and then an application decides to rebuild the lookup table using the implicit process.\n * @returns {void}\n * @memberof Colors\n */\n public build(force) {\n if (this.Table.length > 1 && !force) {\n return;\n }\n\n // Clear the table\n this.Table = [];\n\n const maxIndex = this.NumberOfColors - 1;\n\n let hinc, sinc, vinc, ainc;\n\n if (maxIndex) {\n hinc = (this.HueRange[1] - this.HueRange[0]) / maxIndex;\n sinc = (this.SaturationRange[1] - this.SaturationRange[0]) / maxIndex;\n vinc = (this.ValueRange[1] - this.ValueRange[0]) / maxIndex;\n ainc = (this.AlphaRange[1] - this.AlphaRange[0]) / maxIndex;\n } else {\n hinc = sinc = vinc = ainc = 0.0;\n }\n\n for (let i = 0; i <= maxIndex; i++) {\n const hue = this.HueRange[0] + i * hinc;\n const sat = this.SaturationRange[0] + i * sinc;\n const val = this.ValueRange[0] + i * vinc;\n const alpha = this.AlphaRange[0] + i * ainc;\n\n const rgb = HSVToRGB(hue, sat, val);\n const c_rgba: Point4 = [0, 0, 0, 0];\n\n switch (this.Ramp) {\n case 'scurve':\n c_rgba[0] = Math.floor(\n 127.5 * (1.0 + Math.cos((1.0 - rgb[0]) * Math.PI))\n );\n c_rgba[1] = Math.floor(\n 127.5 * (1.0 + Math.cos((1.0 - rgb[1]) * Math.PI))\n );\n c_rgba[2] = Math.floor(\n 127.5 * (1.0 + Math.cos((1.0 - rgb[2]) * Math.PI))\n );\n c_rgba[3] = Math.floor(alpha * 255);\n break;\n case 'linear':\n c_rgba[0] = Math.floor(rgb[0] * 255 + 0.5);\n c_rgba[1] = Math.floor(rgb[1] * 255 + 0.5);\n c_rgba[2] = Math.floor(rgb[2] * 255 + 0.5);\n c_rgba[3] = Math.floor(alpha * 255 + 0.5);\n break;\n case 'sqrt':\n c_rgba[0] = Math.floor(Math.sqrt(rgb[0]) * 255 + 0.5);\n c_rgba[1] = Math.floor(Math.sqrt(rgb[1]) * 255 + 0.5);\n c_rgba[2] = Math.floor(Math.sqrt(rgb[2]) * 255 + 0.5);\n c_rgba[3] = Math.floor(Math.sqrt(alpha) * 255 + 0.5);\n break;\n default:\n throw new Error(`Invalid Ramp value (${this.Ramp})`);\n }\n\n this.Table.push(c_rgba);\n }\n\n this.buildSpecialColors();\n }\n\n /**\n * Ensures the out-of-range colors (Below range and Above range) are set correctly.\n * @returns {void}\n * @memberof Colors\n */\n private buildSpecialColors() {\n const numberOfColors = this.NumberOfColors;\n const belowRangeColorIndex = numberOfColors + BELOW_RANGE_COLOR_INDEX;\n const aboveRangeColorIndex = numberOfColors + ABOVE_RANGE_COLOR_INDEX;\n const nanColorIndex = numberOfColors + NAN_COLOR_INDEX;\n\n // Below range color\n if (this.UseBelowRangeColor || numberOfColors === 0) {\n this.Table[belowRangeColorIndex] = this.BelowRangeColor;\n } else {\n // Duplicate the first color in the table.\n this.Table[belowRangeColorIndex] = this.Table[0];\n }\n\n // Above range color\n if (this.UseAboveRangeColor || numberOfColors === 0) {\n this.Table[aboveRangeColorIndex] = this.AboveRangeColor;\n } else {\n // Duplicate the last color in the table.\n this.Table[aboveRangeColorIndex] = this.Table[numberOfColors - 1];\n }\n\n // Always use NanColor\n this.Table[nanColorIndex] = this.NaNColor;\n }\n\n /**\n * Similar to GetColor - Map one value through the lookup table and return the color as an\n * RGBA array of doubles between 0 and 1.\n * @param {Numeber} v A double scalar value which will be mapped to a color in the LookupTable\n * @returns {Number[]} An RGBA array of doubles between 0 and 1\n * @memberof Colors\n */\n private mapValue(v) {\n const index = this.getIndex(v);\n\n if (index < 0) {\n return this.NaNColor;\n } else if (index === 0) {\n if (this.UseBelowRangeColor && v < this.TableRange[0]) {\n return this.BelowRangeColor;\n }\n } else if (index === this.NumberOfColors - 1) {\n if (this.UseAboveRangeColor && v > this.TableRange[1]) {\n return this.AboveRangeColor;\n }\n }\n\n return this.Table[index];\n }\n\n /**\n * Return the table index associated with a particular value.\n * @param {Number} v A double value which table index will be returned.\n * @returns {Number} The index in the LookupTable\n * @memberof Colors\n */\n private getIndex(v) {\n const p = {\n Range: [],\n MaxIndex: this.NumberOfColors - 1,\n Shift: -this.TableRange[0],\n Scale: 1,\n };\n\n if (this.TableRange[1] <= this.TableRange[0]) {\n p.Scale = Number.MAX_VALUE;\n } else {\n p.Scale = p.MaxIndex / (this.TableRange[1] - this.TableRange[0]);\n }\n\n p.Range[0] = this.TableRange[0];\n p.Range[1] = this.TableRange[1];\n\n // First, check whether we have a number...\n if (isNaN(v)) {\n // For backwards compatibility\n return -1;\n }\n\n // Map to an index:\n let index = linearIndexLookupMain(v, p);\n\n // For backwards compatibility, if the index indicates an\n // Out-of-range value, truncate to index range for in-range colors.\n if (index === this.NumberOfColors + BELOW_RANGE_COLOR_INDEX) {\n index = 0;\n } else if (index === this.NumberOfColors + ABOVE_RANGE_COLOR_INDEX) {\n index = this.NumberOfColors - 1;\n }\n\n return index;\n }\n\n /**\n * Directly load color into lookup table. Use [0,1] double values for color component specification.\n * Make sure that you've either used the Build() method or used SetNumberOfTableValues() prior to using this method.\n * @param {Number} index The index in the LookupTable of where to insert the color value\n * @param {Number[]} rgba An array of [0,1] double values for an RGBA color component\n * @returns {void}\n * @memberof Colors\n */\n public setTableValue(index, rgba) {\n // Check if it index, red, green, blue and alpha were passed as parameter\n if (arguments.length === 5) {\n rgba = Array.prototype.slice.call(arguments, 1);\n }\n\n // Check the index to make sure it is valid\n if (index < 0) {\n throw new Error(\n `Can't set the table value for negative index (${index})`\n );\n }\n\n if (index >= this.NumberOfColors) {\n new Error(\n `Index ${index} is greater than the number of colors ${this.NumberOfColors}`\n );\n }\n\n this.Table[index] = rgba;\n\n if (index === 0 || index === this.NumberOfColors - 1) {\n // This is needed due to the way the special colors are stored in\n // The internal table. If Above/BelowRangeColors are not used and\n // The min/max colors are changed in the table with this member\n // Function, then the colors used for values outside the range may\n // Be incorrect. Calling this here ensures the out-of-range colors\n // Are set correctly.\n this.buildSpecialColors();\n }\n }\n}\n\nexport default LookupTable;\n","import LookupTable from './lookupTable';\nimport CPU_COLORMAPS from '../../../../constants/cpuColormaps';\nimport {\n CPUFallbackColormap,\n CPUFallbackColormapData,\n Point4,\n} from '../../../../types';\n\nconst COLOR_TRANSPARENT: Point4 = [0, 0, 0, 0];\n\n/**\n * Generate linearly spaced vectors\n * http://cens.ioc.ee/local/man/matlab/techdoc/ref/linspace.html\n * @param {Number} a A number representing the first vector\n * @param {Number} b A number representing the second vector\n * @param {Number} n The number of linear spaced vectors to generate\n * @returns {Array} An array of points representing linear spaced vectors.\n * @memberof Colors\n */\nfunction linspace(a: number, b: number, n: number): number[] {\n n = n === null ? 100 : n;\n\n const increment = (b - a) / (n - 1);\n const vector = [];\n\n while (n-- > 0) {\n vector.push(a);\n a += increment;\n }\n\n // Make sure the last item will always be \"b\" because most of the\n // Time we'll get numbers like 1.0000000000000002 instead of 1.\n vector[vector.length - 1] = b;\n\n return vector;\n}\n\n/**\n * Returns the \"rank/index\" of the element in a sorted array if found or the highest index if not. Uses (binary search)\n * @param {Array} array A sorted array to search in\n * @param {any} elem the element in the array to search for\n * @returns {number} The rank/index of the element in the given array\n * @memberof Colors\n */\nfunction getRank(array, elem) {\n let left = 0;\n let right = array.length - 1;\n\n while (left <= right) {\n const mid = left + Math.floor((right - left) / 2);\n const midElem = array[mid];\n\n if (midElem === elem) {\n return mid;\n } else if (elem < midElem) {\n right = mid - 1;\n } else {\n left = mid + 1;\n }\n }\n\n return left;\n}\n\n/**\n * Find the indices into a sorted array a such that, if the corresponding elements\n * In v were inserted before the indices, the order of a would be preserved.\n * http://lagrange.univ-lyon1.fr/docs/numpy/1.11.0/reference/generated/numpy.searchsorted.html\n * @param {Array} inputArray The array where the values will be inserted\n * @param {Array} values An array of the values to be inserted into the inputArray\n * @returns {Array} The indices where elements should be inserted to maintain order.\n * @memberof Colors\n */\nfunction searchSorted(inputArray, values) {\n let i;\n const indexes = [];\n const len = values.length;\n\n inputArray.sort(function (a, b) {\n return a - b;\n });\n\n for (i = 0; i < len; i++) {\n indexes[i] = getRank(inputArray, values[i]);\n }\n\n return indexes;\n}\n\n/**\n * Creates an *N* -element 1-d lookup table\n * @param {Number} N The number of elements in the result lookup table\n * @param {Array} data represented by a list of x,y0,y1 mapping correspondences. Each element in this\n * List represents how a value between 0 and 1 (inclusive) represented by x is mapped to\n * A corresponding value between 0 and 1 (inclusive). The two values of y are to allow for\n * Discontinuous mapping functions (say as might be found in a sawtooth) where y0 represents\n * The value of y for values of x <= to that given, and y1 is the value to be used for x >\n * Than that given). The list must start with x=0, end with x=1, and all values of x must be\n * In increasing order. Values between the given mapping points are determined by simple linear\n * Interpolation.\n * @param {any} gamma value denotes a \"gamma curve\" value which adjusts the brightness\n * at the bottom and top of the map.\n * @returns {any[]} an array \"result\" where result[x*(N-1)] gives the closest value for\n * Values of x between 0 and 1.\n * @memberof Colors\n */\nfunction makeMappingArray(N, data, gamma) {\n let i;\n const x = [];\n const y0 = [];\n const y1 = [];\n const lut = [];\n\n gamma = gamma === null ? 1 : gamma;\n\n for (i = 0; i < data.length; i++) {\n const element = data[i];\n\n x.push((N - 1) * element[0]);\n y0.push(element[1]);\n y1.push(element[1]);\n }\n\n const xLinSpace = linspace(0, 1, N);\n\n for (i = 0; i < N; i++) {\n xLinSpace[i] = (N - 1) * Math.pow(xLinSpace[i], gamma);\n }\n\n const xLinSpaceIndexes = searchSorted(x, xLinSpace);\n\n for (i = 1; i < N - 1; i++) {\n const index = xLinSpaceIndexes[i];\n const colorPercent =\n (xLinSpace[i] - x[index - 1]) / (x[index] - x[index - 1]);\n const colorDelta = y0[index] - y1[index - 1];\n\n lut[i] = colorPercent * colorDelta + y1[index - 1];\n }\n\n lut[0] = y1[0];\n lut[N - 1] = y0[data.length - 1];\n\n return lut;\n}\n\n/**\n * Creates a Colormap based on lookup tables using linear segments.\n * @param {{red:Array, green:Array, blue:Array}} segmentedData An object with a red, green and blue entries.\n * Each entry should be a list of x, y0, y1 tuples, forming rows in a table.\n * @param {Number} N The number of elements in the result Colormap\n * @param {any} gamma value denotes a \"gamma curve\" value which adjusts the brightness\n * at the bottom and top of the Colormap.\n * @returns {Array} The created Colormap object\n * @description The lookup table is generated using linear interpolation for each\n * Primary color, with the 0-1 domain divided into any number of\n * Segments.\n * https://github.com/stefanv/matplotlib/blob/3f1a23755e86fef97d51e30e106195f34425c9e3/lib/matplotlib/colors.py#L663\n * @memberof Colors\n */\nfunction createLinearSegmentedColormap(segmentedData, N, gamma) {\n let i;\n const lut = [];\n\n N = N === null ? 256 : N;\n gamma = gamma === null ? 1 : gamma;\n\n const redLut = makeMappingArray(N, segmentedData.red, gamma);\n const greenLut = makeMappingArray(N, segmentedData.green, gamma);\n const blueLut = makeMappingArray(N, segmentedData.blue, gamma);\n\n for (i = 0; i < N; i++) {\n const red = Math.round(redLut[i] * 255);\n const green = Math.round(greenLut[i] * 255);\n const blue = Math.round(blueLut[i] * 255);\n const rgba = [red, green, blue, 255];\n\n lut.push(rgba);\n }\n\n return lut;\n}\n\n/**\n * Return all available colormaps (id and name)\n * @returns {Array<{id,key}>} An array of colormaps with an object containing the \"id\" and display \"name\"\n * @memberof Colors\n */\nexport function getColormapsList() {\n const colormaps = [];\n const keys = Object.keys(CPU_COLORMAPS);\n\n keys.forEach(function (key) {\n if (CPU_COLORMAPS.hasOwnProperty(key)) {\n const colormap = CPU_COLORMAPS[key];\n\n colormaps.push({\n id: key,\n name: colormap.name,\n });\n }\n });\n\n colormaps.sort(function (a, b) {\n const aName = a.name.toLowerCase();\n const bName = b.name.toLowerCase();\n\n if (aName === bName) {\n return 0;\n }\n\n return aName < bName ? -1 : 1;\n });\n\n return colormaps;\n}\n\n/**\n * Return a colorMap object with the provided id and colormapData\n * if the Id matches existent colorMap objects (check colormapsData) the colormapData is ignored.\n * if the colormapData is not empty, the colorMap will be added to the colormapsData list. Otherwise, an empty colorMap object is returned.\n * @param {string} id The ID of the colormap\n * @param {Object} colormapData - An object that can contain a name, numColors, gama, segmentedData and/or colors\n * @returns {*} The Colormap Object\n * @memberof Colors\n */\nexport function getColormap(\n id: string,\n colormapData?: CPUFallbackColormapData\n): CPUFallbackColormap {\n let colormap = CPU_COLORMAPS[id];\n\n if (!colormap) {\n colormap = CPU_COLORMAPS[id] = colormapData || {\n name: '',\n colors: [],\n };\n }\n\n if (!colormap.colors && colormap.segmentedData) {\n colormap.colors = createLinearSegmentedColormap(\n colormap.segmentedData,\n colormap.numColors,\n colormap.gamma\n );\n }\n\n const cpuFallbackColormap: CPUFallbackColormap = {\n getId() {\n return id;\n },\n\n getColorSchemeName() {\n return colormap.name;\n },\n\n setColorSchemeName(name) {\n colormap.name = name;\n },\n\n getNumberOfColors() {\n return colormap.colors.length;\n },\n\n setNumberOfColors(numColors) {\n while (colormap.colors.length < numColors) {\n colormap.colors.push(COLOR_TRANSPARENT);\n }\n\n colormap.colors.length = numColors;\n },\n\n getColor(index) {\n if (this.isValidIndex(index)) {\n return colormap.colors[index];\n }\n\n return COLOR_TRANSPARENT;\n },\n\n getColorRepeating(index) {\n const numColors = colormap.colors.length;\n\n index = numColors ? index % numColors : 0;\n\n return this.getColor(index);\n },\n\n setColor(index, rgba) {\n if (this.isValidIndex(index)) {\n colormap.colors[index] = rgba;\n }\n },\n\n addColor(rgba) {\n colormap.colors.push(rgba);\n },\n\n insertColor(index, rgba) {\n if (this.isValidIndex(index)) {\n colormap.colors.splice(index, 1, rgba);\n }\n },\n\n removeColor(index) {\n if (this.isValidIndex(index)) {\n colormap.colors.splice(index, 1);\n }\n },\n\n clearColors() {\n colormap.colors = [];\n },\n\n buildLookupTable(lut) {\n if (!lut) {\n return;\n }\n\n const numColors = colormap.colors.length;\n\n lut.setNumberOfTableValues(numColors);\n\n for (let i = 0; i < numColors; i++) {\n lut.setTableValue(i, colormap.colors[i]);\n }\n },\n\n createLookupTable() {\n const lut = new LookupTable();\n\n this.buildLookupTable(lut);\n\n return lut;\n },\n\n isValidIndex(index) {\n return index >= 0 && index < colormap.colors.length;\n },\n };\n\n return cpuFallbackColormap;\n}\n","import setToPixelCoordinateSystem from './setToPixelCoordinateSystem';\nimport now from './now';\nimport initializeRenderCanvas from './initializeRenderCanvas';\nimport getLut from './getLut';\nimport saveLastRendered from './saveLastRendered';\nimport doesImageNeedToBeRendered from './doesImageNeedToBeRendered';\nimport storedPixelDataToCanvasImageDataPseudocolorLUT from './storedPixelDataToCanvasImageDataPseudocolorLUT';\nimport storedPixelDataToCanvasImageDataPseudocolorLUTPET from './storedPixelDataToCanvasImageDataPseudocolorLUTPET';\nimport * as colors from '../colors/index';\nimport type { IImage, CPUFallbackEnabledElement } from '../../../../types';\n\nfunction clamp(value: number, min: number, max: number) {\n return Math.max(min, Math.min(max, value));\n}\n\n/**\n * Returns an appropriate canvas to render the Image. If the canvas available in the cache is appropriate\n * it is returned, otherwise adjustments are made. It also sets the color transfer functions.\n *\n * @param {Object} enabledElement The cornerstone enabled element\n * @param {Object} image The image to be rendered\n * @param {Boolean} invalidated Is pixel data valid\n * @returns {HTMLCanvasElement} An appropriate canvas for rendering the image\n * @memberof rendering\n */\nfunction getRenderCanvas(\n enabledElement: CPUFallbackEnabledElement,\n image: IImage,\n invalidated: boolean\n): HTMLCanvasElement {\n if (!enabledElement.renderingTools.renderCanvas) {\n enabledElement.renderingTools.renderCanvas =\n document.createElement('canvas');\n }\n\n const renderCanvas = enabledElement.renderingTools.renderCanvas;\n\n let colormap =\n enabledElement.viewport.colormap || enabledElement.options.colormap;\n\n if (enabledElement.options && enabledElement.options.colormap) {\n console.warn(\n 'enabledElement.options.colormap is deprecated. Use enabledElement.viewport.colormap instead'\n );\n }\n if (colormap && typeof colormap === 'string') {\n colormap = colors.getColormap(colormap);\n }\n\n if (!colormap) {\n throw new Error('renderPseudoColorImage: colormap not found.');\n }\n\n const colormapId = colormap.getId();\n\n if (\n doesImageNeedToBeRendered(enabledElement, image) === false &&\n invalidated !== true &&\n enabledElement.renderingTools.colormapId === colormapId\n ) {\n return renderCanvas;\n }\n\n // If our render canvas does not match the size of this image reset it\n // NOTE: This might be inefficient if we are updating multiple images of different\n // Sizes frequently.\n if (\n renderCanvas.width !== image.width ||\n renderCanvas.height !== image.height\n ) {\n initializeRenderCanvas(enabledElement, image);\n }\n\n // Get the lut to use\n let start = now();\n\n if (\n !enabledElement.renderingTools.colorLUT ||\n invalidated ||\n enabledElement.renderingTools.colormapId !== colormapId\n ) {\n colormap.setNumberOfColors(256);\n enabledElement.renderingTools.colorLUT = colormap.createLookupTable();\n enabledElement.renderingTools.colormapId = colormapId;\n }\n\n const renderCanvasData = enabledElement.renderingTools.renderCanvasData;\n const renderCanvasContext = enabledElement.renderingTools.renderCanvasContext;\n const { viewport } = enabledElement;\n const colorLUT = enabledElement.renderingTools.colorLUT;\n\n if (viewport.modality === 'PT') {\n const { windowWidth, windowCenter } = viewport.voi;\n const minimum = windowCenter - windowWidth / 2;\n const maximum = windowCenter + windowWidth / 2;\n const range = maximum - minimum;\n const collectedMultiplierTerms = 255.0 / range;\n\n let petVOILutFunction;\n\n if (viewport.invert) {\n petVOILutFunction = (value) => {\n return clamp(\n Math.floor(255 - (value - minimum) * collectedMultiplierTerms),\n 0,\n 255\n );\n };\n } else {\n petVOILutFunction = (value) => {\n return clamp(\n Math.floor((value - minimum) * collectedMultiplierTerms),\n 0,\n 255\n );\n };\n }\n\n storedPixelDataToCanvasImageDataPseudocolorLUTPET(\n image,\n petVOILutFunction,\n colorLUT,\n renderCanvasData.data\n );\n } else {\n const lut = getLut(image, enabledElement.viewport, invalidated);\n\n image.stats = image.stats || {};\n image.stats.lastLutGenerateTime = now() - start;\n\n storedPixelDataToCanvasImageDataPseudocolorLUT(\n image,\n lut,\n colorLUT,\n renderCanvasData.data\n );\n }\n\n start = now();\n renderCanvasContext.putImageData(renderCanvasData, 0, 0);\n image.stats.lastPutImageDataTime = now() - start;\n\n return renderCanvas;\n}\n\n/**\n * API function to draw a pseudo-color image to a given enabledElement\n *\n * @param {EnabledElement} enabledElement The Cornerstone Enabled Element to redraw\n * @param {Boolean} invalidated - true if pixel data has been invalidated and cached rendering should not be used\n * @returns {void}\n * @memberof rendering\n */\nexport function renderPseudoColorImage(\n enabledElement: CPUFallbackEnabledElement,\n invalidated: boolean\n): void {\n if (enabledElement === undefined) {\n throw new Error(\n 'drawImage: enabledElement parameter must not be undefined'\n );\n }\n\n const image = enabledElement.image;\n\n if (image === undefined) {\n throw new Error('drawImage: image must be loaded before it can be drawn');\n }\n\n // Get the canvas context and reset the transform\n const context = enabledElement.canvas.getContext('2d');\n\n context.setTransform(1, 0, 0, 1, 0, 0);\n\n // Clear the canvas\n context.fillStyle = 'black';\n context.fillRect(\n 0,\n 0,\n enabledElement.canvas.width,\n enabledElement.canvas.height\n );\n\n // Turn off image smooth/interpolation if pixelReplication is set in the viewport\n context.imageSmoothingEnabled = !enabledElement.viewport.pixelReplication;\n\n // Save the canvas context state and apply the viewport properties\n setToPixelCoordinateSystem(enabledElement, context);\n\n // If no options are set we will retrieve the renderCanvas through the\n // Normal Canvas rendering path\n // TODO: Add WebGL support for pseudocolor pipeline\n const renderCanvas = getRenderCanvas(enabledElement, image, invalidated);\n\n const sx = enabledElement.viewport.displayedArea.tlhc.x - 1;\n const sy = enabledElement.viewport.displayedArea.tlhc.y - 1;\n const width = enabledElement.viewport.displayedArea.brhc.x - sx;\n const height = enabledElement.viewport.displayedArea.brhc.y - sy;\n\n context.drawImage(renderCanvas, sx, sy, width, height, 0, 0, width, height);\n\n enabledElement.renderingTools = saveLastRendered(enabledElement);\n}\n","import * as colors from '../colors/index';\nimport now from './now';\nimport type { IImage, CPUFallbackLookupTable } from '../../../../types';\n\n/**\n *\n * @param {Image} image A Cornerstone Image Object\n * @param {Array} grayscaleLut Lookup table array\n * @param {LookupTable|Array} colorLUT Lookup table array\n * @param {Uint8ClampedArray} canvasImageDataData canvasImageData.data buffer filled with white pixels\n *\n * @returns {void}\n * @memberof Internal\n */\nfunction storedPixelDataToCanvasImageDataPseudocolorLUTPET(\n image: IImage,\n lutFunction: (value: number) => number,\n colorLUT: CPUFallbackLookupTable,\n canvasImageDataData: Uint8ClampedArray\n): void {\n let start = now();\n const pixelData = image.getPixelData();\n\n image.stats.lastGetPixelDataTime = now() - start;\n\n const numPixels = pixelData.length;\n const minPixelValue = image.minPixelValue;\n let canvasImageDataIndex = 0;\n let storedPixelDataIndex = 0;\n let grayscale;\n let rgba;\n let clut;\n\n start = now();\n\n if (colorLUT instanceof colors.LookupTable) {\n clut = colorLUT.Table;\n } else {\n clut = colorLUT;\n }\n\n if (minPixelValue < 0) {\n while (storedPixelDataIndex < numPixels) {\n grayscale = lutFunction(\n pixelData[storedPixelDataIndex++] + -minPixelValue\n );\n\n rgba = clut[grayscale];\n canvasImageDataData[canvasImageDataIndex++] = rgba[0];\n canvasImageDataData[canvasImageDataIndex++] = rgba[1];\n canvasImageDataData[canvasImageDataIndex++] = rgba[2];\n canvasImageDataData[canvasImageDataIndex++] = rgba[3];\n }\n } else {\n while (storedPixelDataIndex < numPixels) {\n grayscale = lutFunction(pixelData[storedPixelDataIndex++]);\n rgba = clut[grayscale];\n canvasImageDataData[canvasImageDataIndex++] = rgba[0];\n canvasImageDataData[canvasImageDataIndex++] = rgba[1];\n canvasImageDataData[canvasImageDataIndex++] = rgba[2];\n canvasImageDataData[canvasImageDataIndex++] = rgba[3];\n }\n }\n\n image.stats.lastStoredPixelDataToCanvasImageDataTime = now() - start;\n}\n\nexport default storedPixelDataToCanvasImageDataPseudocolorLUTPET;\n","import * as colors from '../colors/index';\nimport now from './now';\nimport type { IImage, CPUFallbackLookupTable } from '../../../../types';\n\n/**\n *\n * @param {Image} image A Cornerstone Image Object\n * @param {Array} grayscaleLut Lookup table array\n * @param {LookupTable|Array} colorLUT Lookup table array\n * @param {Uint8ClampedArray} canvasImageDataData canvasImageData.data buffer filled with white pixels\n *\n * @returns {void}\n * @memberof Internal\n */\nfunction storedPixelDataToCanvasImageDataPseudocolorLUT(\n image: IImage,\n grayscaleLut: Uint8ClampedArray,\n colorLUT: CPUFallbackLookupTable,\n canvasImageDataData: Uint8ClampedArray\n): void {\n let start = now();\n const pixelData = image.getPixelData();\n\n image.stats.lastGetPixelDataTime = now() - start;\n\n const numPixels = pixelData.length;\n const minPixelValue = image.minPixelValue;\n let canvasImageDataIndex = 0;\n let storedPixelDataIndex = 0;\n let grayscale;\n let rgba;\n let clut;\n\n start = now();\n\n if (colorLUT instanceof colors.LookupTable) {\n clut = colorLUT.Table;\n } else {\n clut = colorLUT;\n }\n\n if (minPixelValue < 0) {\n while (storedPixelDataIndex < numPixels) {\n grayscale =\n grayscaleLut[pixelData[storedPixelDataIndex++] + -minPixelValue];\n rgba = clut[grayscale];\n canvasImageDataData[canvasImageDataIndex++] = rgba[0];\n canvasImageDataData[canvasImageDataIndex++] = rgba[1];\n canvasImageDataData[canvasImageDataIndex++] = rgba[2];\n canvasImageDataData[canvasImageDataIndex++] = rgba[3];\n }\n } else {\n while (storedPixelDataIndex < numPixels) {\n grayscale = grayscaleLut[pixelData[storedPixelDataIndex++]];\n rgba = clut[grayscale];\n canvasImageDataData[canvasImageDataIndex++] = rgba[0];\n canvasImageDataData[canvasImageDataIndex++] = rgba[1];\n canvasImageDataData[canvasImageDataIndex++] = rgba[2];\n canvasImageDataData[canvasImageDataIndex++] = rgba[3];\n }\n }\n\n image.stats.lastStoredPixelDataToCanvasImageDataTime = now() - start;\n}\n\nexport default storedPixelDataToCanvasImageDataPseudocolorLUT;\n","import now from './rendering/now';\nimport { renderColorImage } from './rendering/renderColorImage';\nimport { renderGrayscaleImage } from './rendering/renderGrayscaleImage';\nimport { renderPseudoColorImage } from './rendering/renderPseudoColorImage';\nimport { CPUFallbackEnabledElement } from '../../../types';\n\n/**\n * Draw an image to a given enabled element synchronously\n *\n * @param enabledElement - An enabled element to draw into\n * @param invalidated - true if pixel data has been invalidated and cached rendering should not be used\n */\nexport default function (\n enabledElement: CPUFallbackEnabledElement,\n invalidated: boolean\n): void {\n const image = enabledElement.image;\n\n // Check if enabledElement can be redrawn\n if (!enabledElement.canvas || !enabledElement.image) {\n return;\n }\n\n // Start measuring the time needed to draw the image.\n const start = now();\n\n image.stats = {\n lastGetPixelDataTime: -1.0,\n lastStoredPixelDataToCanvasImageDataTime: -1.0,\n lastPutImageDataTime: -1.0,\n lastRenderTime: -1.0,\n lastLutGenerateTime: -1.0,\n };\n\n if (image) {\n let render = image.render;\n\n if (!render) {\n if (enabledElement.viewport.colormap) {\n render = renderPseudoColorImage;\n } else if (image.color) {\n render = renderColorImage;\n } else {\n render = renderGrayscaleImage;\n }\n }\n\n render(enabledElement, invalidated);\n }\n\n // Calculate how long it took to draw the image/layers\n const renderTimeInMs = now() - start;\n\n image.stats.lastRenderTime = renderTimeInMs;\n\n enabledElement.invalid = false;\n enabledElement.needsRedraw = false;\n}\n","import calculateTransform from './calculateTransform';\nimport {\n CPUFallbackEnabledElement,\n CPUFallbackTransform,\n} from '../../../../types';\n\nexport default function (\n enabledElement: CPUFallbackEnabledElement\n): CPUFallbackTransform {\n // Todo: for some reason using the cached transfer after the first call\n // does not give correct transform.\n // if (enabledElement.transform) {\n // return enabledElement.transform;\n // }\n\n return calculateTransform(enabledElement);\n}\n","import getTransform from './getTransform';\n\nimport { Point2, CPUFallbackEnabledElement } from '../../../../types';\n\n/**\n * Converts a point in the canvas coordinate system to the pixel coordinate system\n * system. This can be used to reset tools' image coordinates after modifications\n * have been made in canvas space (e.g. moving a tool by a few cm, independent of\n * image resolution).\n *\n * @param element - The Cornerstone element within which the input point lies\n * @param pt - The input point in the canvas coordinate system\n *\n * @returns The transformed point in the pixel coordinate system\n */\nexport default function (\n enabledElement: CPUFallbackEnabledElement,\n pt: Point2\n): Point2 {\n const transform = getTransform(enabledElement);\n\n transform.invert();\n\n return transform.transformPoint(pt);\n}\n","import getTransform from './getTransform';\nimport { CPUFallbackEnabledElement, Point2 } from '../../../../types';\n\n/**\n * Converts a point in the pixel coordinate system to the canvas coordinate system\n * system. This can be used to render using canvas context without having the weird\n * side effects that come from scaling and non square pixels\n *\n * @param {HTMLDivElement} element An HTML Element enabled for Cornerstone\n * @param {{x: Number, y: Number}} pt The transformed point in the pixel coordinate system\n *\n * @returns {{x: Number, y: Number}} The input point in the canvas coordinate system\n * @memberof PixelCoordinateSystem\n */\nexport default function (\n enabledElement: CPUFallbackEnabledElement,\n pt: Point2\n): Point2 {\n const transform = getTransform(enabledElement);\n\n return transform.transformPoint(pt);\n}\n","import { CPUFallbackViewport } from '../../../../types';\n\nconst state = {\n viewport: {},\n};\n\n/**\n * Sets new default values for `getDefaultViewport`\n *\n * @param {Object} viewport - Object that sets new default values for getDefaultViewport\n * @returns {undefined}\n */\nexport default function (viewport: CPUFallbackViewport): void {\n state.viewport = viewport || {};\n}\n\nexport { state };\n","/**\n * Check if the supplied parameter is undefined and throws and error\n * @param {any} checkParam the parameter to validate for undefined\n * @param {any} errorMsg the error message to be thrown\n * @returns {void}\n * @memberof internal\n */\nexport function validateParameterUndefined(\n checkParam: any | undefined,\n errorMsg: string\n): void {\n if (checkParam === undefined) {\n throw new Error(errorMsg);\n }\n}\n\n/**\n * Check if the supplied parameter is undefined or null and throws and error\n * @param {any} checkParam the parameter to validate for undefined\n * @param {any} errorMsg the error message to be thrown\n * @returns {void}\n * @memberof internal\n */\nexport function validateParameterUndefinedOrNull(\n checkParam: any | null | undefined,\n errorMsg: string\n): void {\n if (checkParam === undefined || checkParam === null) {\n throw new Error(errorMsg);\n }\n}\n","import { validateParameterUndefinedOrNull } from './validator';\nimport { IImage } from '../../../../types';\n\n/**\n * Check if the angle is rotated\n * @param {Number} rotation the rotation angle\n * @returns {Boolean} true if the angle is rotated; Otherwise, false.\n * @memberof Internal\n */\nfunction isRotated(rotation?: number | null): boolean {\n return !(\n rotation === null ||\n rotation === undefined ||\n rotation === 0 ||\n rotation === 180\n );\n}\n\n/**\n * Retrieves the current image dimensions given an enabled element\n *\n * @param {any} image The Cornerstone image.\n * @param {Number} rotation Optional. The rotation angle of the image.\n * @return {{width:Number, height:Number}} The Image dimensions\n * @memberof Internal\n */\nexport default function (\n image: IImage,\n rotation = null\n): { height: number; width: number } {\n validateParameterUndefinedOrNull(\n image,\n 'getImageSize: parameter image must not be undefined'\n );\n validateParameterUndefinedOrNull(\n image.width,\n 'getImageSize: parameter image must have width'\n );\n validateParameterUndefinedOrNull(\n image.height,\n 'getImageSize: parameter image must have height'\n );\n\n if (isRotated(rotation)) {\n return {\n height: image.width,\n width: image.height,\n };\n }\n\n return {\n width: image.width,\n height: image.height,\n };\n}\n","import { validateParameterUndefinedOrNull } from './validator';\nimport getImageSize from './getImageSize';\nimport { IImage } from '../../../../types';\n\n/**\n * Calculates the horizontal, vertical and minimum scale factor for an image\n @param canvas - The window size where the image is displayed. This can be any HTML element or structure with a width, height fields (e.g. canvas).\n * @param image - The cornerstone image object\n * @param rotation - The rotation angle of the image.\n * @returns The calculated horizontal, vertical and minimum scale factor\n */\nexport default function (\n canvas: HTMLCanvasElement,\n image: IImage,\n rotation: number | null = null\n): {\n verticalScale: number;\n horizontalScale: number;\n scaleFactor: number;\n} {\n validateParameterUndefinedOrNull(\n canvas,\n 'getImageScale: parameter canvas must not be undefined'\n );\n validateParameterUndefinedOrNull(\n image,\n 'getImageScale: parameter image must not be undefined'\n );\n\n const imageSize = getImageSize(image, rotation);\n const rowPixelSpacing = image.rowPixelSpacing || 1;\n const columnPixelSpacing = image.columnPixelSpacing || 1;\n let verticalRatio = 1;\n let horizontalRatio = 1;\n\n if (rowPixelSpacing < columnPixelSpacing) {\n horizontalRatio = columnPixelSpacing / rowPixelSpacing;\n } else {\n // even if they are equal we want to calculate this ratio (the ration might be 0.5)\n verticalRatio = rowPixelSpacing / columnPixelSpacing;\n }\n\n const verticalScale = canvas.height / imageSize.height / verticalRatio;\n const horizontalScale = canvas.width / imageSize.width / horizontalRatio;\n\n // Fit image to window\n return {\n verticalScale,\n horizontalScale,\n scaleFactor: Math.min(horizontalScale, verticalScale),\n };\n}\n","import createViewport from './createViewport';\nimport getImageFitScale from './getImageFitScale';\nimport {\n IImage,\n CPUFallbackColormap,\n CPUFallbackViewport,\n} from '../../../../types';\n\n/**\n * Creates a new viewport object containing default values for the image and canvas\n *\n * @param canvas - A Canvas DOM element\n * @param image - A Cornerstone Image Object\n * @returns viewport - object\n */\nexport default function (\n canvas: HTMLCanvasElement,\n image: IImage,\n modality?: string,\n colormap?: CPUFallbackColormap\n): CPUFallbackViewport {\n if (canvas === undefined) {\n throw new Error(\n 'getDefaultViewport: parameter canvas must not be undefined'\n );\n }\n\n if (image === undefined) {\n return createViewport();\n }\n\n // Fit image to window\n const scale = getImageFitScale(canvas, image, 0).scaleFactor;\n\n let voi;\n\n if (modality === 'PT' && image.isPreScaled) {\n voi = {\n windowWidth: 5,\n windowCenter: 2.5,\n };\n } else if (\n image.windowWidth !== undefined &&\n image.windowCenter !== undefined\n ) {\n voi = {\n windowWidth: Array.isArray(image.windowWidth)\n ? image.windowWidth[0]\n : image.windowWidth,\n windowCenter: Array.isArray(image.windowCenter)\n ? image.windowCenter[0]\n : image.windowCenter,\n };\n }\n\n return {\n scale,\n translation: {\n x: 0,\n y: 0,\n },\n voi,\n invert: image.invert,\n pixelReplication: false,\n rotation: 0,\n hflip: false,\n vflip: false,\n modalityLUT: image.modalityLUT,\n modality,\n voiLUT: image.voiLUT,\n colormap: colormap !== undefined ? colormap : image.colormap,\n displayedArea: {\n tlhc: {\n x: 1,\n y: 1,\n },\n brhc: {\n x: image.columns,\n y: image.rows,\n },\n rowPixelSpacing:\n image.rowPixelSpacing === undefined ? 1 : image.rowPixelSpacing,\n columnPixelSpacing:\n image.columnPixelSpacing === undefined ? 1 : image.columnPixelSpacing,\n presentationSizeMode: 'NONE',\n },\n };\n}\n","import { state } from './setDefaultViewport';\nimport {\n CPUFallbackViewportDisplayedArea,\n CPUFallbackViewport,\n} from '../../../../types';\n\n// eslint-disable-next-line valid-jsdoc\n/**\n * Creates the default displayed area.\n * C.10.4 Displayed Area Module: This Module describes Attributes required to define a Specified Displayed Area space.\n *\n * @returns {tlhc: {x,y}, brhc: {x, y},rowPixelSpacing: Number, columnPixelSpacing: Number, presentationSizeMode: Number} displayedArea object\n * @memberof Internal\n */\nfunction createDefaultDisplayedArea(): CPUFallbackViewportDisplayedArea {\n return {\n // Top Left Hand Corner\n tlhc: {\n x: 1,\n y: 1,\n },\n // Bottom Right Hand Corner\n brhc: {\n x: 1,\n y: 1,\n },\n rowPixelSpacing: 1,\n columnPixelSpacing: 1,\n presentationSizeMode: 'NONE',\n };\n}\n\n/**\n * Creates a new viewport object containing default values\n *\n * @returns {Viewport} viewport object\n * @memberof Internal\n */\nexport default function createViewport(): CPUFallbackViewport {\n const displayedArea = createDefaultDisplayedArea();\n const initialDefaultViewport = {\n scale: 1,\n translation: {\n x: 0,\n y: 0,\n },\n voi: {\n windowWidth: undefined,\n windowCenter: undefined,\n },\n invert: false,\n pixelReplication: false,\n rotation: 0,\n hflip: false,\n vflip: false,\n modalityLUT: undefined,\n voiLUT: undefined,\n colormap: undefined,\n labelmap: false,\n displayedArea,\n };\n\n return Object.assign({}, initialDefaultViewport, state.viewport);\n}\n","import getImageFitScale from './getImageFitScale';\nimport { CPUFallbackEnabledElement } from '../../../../types';\n\n/**\n * Adjusts an image's scale and translation so the image is centered and all pixels\n * in the image are viewable.\n *\n * @param element - The Cornerstone element to update\n */\nexport default function (enabledElement: CPUFallbackEnabledElement): void {\n const { image } = enabledElement;\n\n // The new scale is the minimum of the horizontal and vertical scale values\n enabledElement.viewport.scale = getImageFitScale(\n enabledElement.canvas,\n image,\n enabledElement.viewport.rotation\n ).scaleFactor;\n\n enabledElement.viewport.translation.x = 0;\n enabledElement.viewport.translation.y = 0;\n}\n","import fitToWindow from './fitToWindow';\nimport getImageSize from './getImageSize';\nimport { CPUFallbackEnabledElement } from '../../../../types';\n\n/**\n * This module is responsible for enabling an element to display images with cornerstone\n *\n * @param {HTMLDivElement} element The DOM element enabled for Cornerstone\n * @param {HTMLDivElement} canvas The Canvas DOM element within the DOM element enabled for Cornerstone\n * @returns {void}\n */\nfunction setCanvasSize(enabledElement: CPUFallbackEnabledElement) {\n const { canvas } = enabledElement;\n const { clientWidth, clientHeight } = canvas;\n\n // Set the canvas to be same resolution as the client.\n if (canvas.width !== clientWidth || canvas.height !== clientHeight) {\n canvas.width = clientWidth;\n canvas.height = clientHeight;\n }\n}\n\n/**\n * Checks if the image of a given enabled element fitted the window\n * before the resize\n *\n * @param {EnabledElement} enabledElement The Cornerstone Enabled Element\n * @param {number} oldCanvasWidth The width of the canvas before the resize\n * @param {number} oldCanvasHeight The height of the canvas before the resize\n * @return {Boolean} true if it fitted the windows, false otherwise\n */\nfunction wasFitToWindow(\n enabledElement: CPUFallbackEnabledElement,\n oldCanvasWidth: number,\n oldCanvasHeight: number\n): boolean {\n const scale = enabledElement.viewport.scale;\n const imageSize = getImageSize(\n enabledElement.image,\n enabledElement.viewport.rotation\n );\n const imageWidth = Math.round(imageSize.width * scale);\n const imageHeight = Math.round(imageSize.height * scale);\n const x = enabledElement.viewport.translation.x;\n const y = enabledElement.viewport.translation.y;\n\n return (\n (imageWidth === oldCanvasWidth && imageHeight <= oldCanvasHeight) ||\n (imageWidth <= oldCanvasWidth &&\n imageHeight === oldCanvasHeight &&\n x === 0 &&\n y === 0)\n );\n}\n\n/**\n * Rescale the image relative to the changed size of the canvas\n *\n * @param {EnabledElement} enabledElement The Cornerstone Enabled Element\n * @param {number} oldCanvasWidth The width of the canvas before the resize\n * @param {number} oldCanvasHeight The height of the canvas before the resize\n * @return {void}\n */\nfunction relativeRescale(\n enabledElement: CPUFallbackEnabledElement,\n oldCanvasWidth: number,\n oldCanvasHeight: number\n): void {\n const scale = enabledElement.viewport.scale;\n const canvasWidth = enabledElement.canvas.width;\n const canvasHeight = enabledElement.canvas.height;\n const relWidthChange = canvasWidth / oldCanvasWidth;\n const relHeightChange = canvasHeight / oldCanvasHeight;\n const relChange = Math.sqrt(relWidthChange * relHeightChange);\n\n enabledElement.viewport.scale = relChange * scale;\n}\n\n/**\n * Resizes an enabled element and optionally fits the image to window\n *\n * @param {HTMLDivElement} element The DOM element enabled for Cornerstone\n * @param {Boolean} forceFitToWindow true to to force a refit, false to rescale accordingly\n * @returns {void}\n */\nexport default function (\n enabledElement: CPUFallbackEnabledElement,\n forceFitToWindow = false\n): void {\n const oldCanvasWidth = enabledElement.canvas.width;\n const oldCanvasHeight = enabledElement.canvas.height;\n\n setCanvasSize(enabledElement);\n\n if (enabledElement.image === undefined) {\n return;\n }\n\n if (\n forceFitToWindow ||\n wasFitToWindow(enabledElement, oldCanvasWidth, oldCanvasHeight)\n ) {\n // Fit the image to the window again if it fitted before the resize\n fitToWindow(enabledElement);\n } else {\n // Adapt the scale of a zoomed or panned image relative to the size change\n relativeRescale(enabledElement, oldCanvasWidth, oldCanvasHeight);\n }\n}\n","import vtkDataArray from '@kitware/vtk.js/Common/Core/DataArray';\nimport vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData';\nimport type { vtkImageData as vtkImageDataType } from '@kitware/vtk.js/Common/DataModel/ImageData';\nimport _cloneDeep from 'lodash.clonedeep';\nimport vtkCamera from '@kitware/vtk.js/Rendering/Core/Camera';\nimport { vec2, vec3, mat4 } from 'gl-matrix';\nimport vtkImageMapper from '@kitware/vtk.js/Rendering/Core/ImageMapper';\nimport vtkImageSlice from '@kitware/vtk.js/Rendering/Core/ImageSlice';\nimport vtkColorTransferFunction from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction';\nimport * as metaData from '../metaData';\nimport Viewport from './Viewport';\nimport eventTarget from '../eventTarget';\nimport Events from '../enums/Events';\nimport {\n triggerEvent,\n isEqual,\n invertRgbTransferFunction,\n windowLevel as windowLevelUtil,\n imageIdToURI,\n isImageActor,\n} from '../utilities';\nimport {\n Point2,\n Point3,\n VOIRange,\n ICamera,\n IImage,\n IImageData,\n CPUIImageData,\n PTScaling,\n Scaling,\n StackViewportProperties,\n FlipDirection,\n ActorEntry,\n CPUFallbackEnabledElement,\n CPUFallbackColormapData,\n EventTypes,\n IStackViewport,\n VolumeActor,\n Mat3,\n} from '../types';\nimport { ViewportInput } from '../types/IViewport';\nimport drawImageSync from './helpers/cpuFallback/drawImageSync';\nimport { getColormap } from './helpers/cpuFallback/colors/index';\n\nimport { loadAndCacheImage } from '../imageLoader';\nimport imageLoadPoolManager from '../requestPool/imageLoadPoolManager';\nimport InterpolationType from '../enums/InterpolationType';\nimport canvasToPixel from './helpers/cpuFallback/rendering/canvasToPixel';\nimport pixelToCanvas from './helpers/cpuFallback/rendering/pixelToCanvas';\nimport getDefaultViewport from './helpers/cpuFallback/rendering/getDefaultViewport';\nimport calculateTransform from './helpers/cpuFallback/rendering/calculateTransform';\nimport resize from './helpers/cpuFallback/rendering/resize';\n\nimport resetCamera from './helpers/cpuFallback/rendering/resetCamera';\nimport { Transform } from './helpers/cpuFallback/rendering/transform';\nimport { getShouldUseCPURendering } from '../init';\nimport RequestType from '../enums/RequestType';\nimport {\n StackViewportNewStackEventDetail,\n StackViewportScrollEventDetail,\n VoiModifiedEventDetail,\n} from '../types/EventTypes';\nimport cache from '../cache';\nimport correctShift from './helpers/cpuFallback/rendering/correctShift';\nimport { ImageActor } from '../types/IActor';\nimport isRgbaSourceRgbDest from './helpers/isRgbaSourceRgbDest';\n\nconst EPSILON = 1; // Slice Thickness\n\ninterface ImagePixelModule {\n bitsAllocated: number;\n bitsStored: number;\n samplesPerPixel: number;\n highBit: number;\n photometricInterpretation: string;\n pixelRepresentation: string;\n windowWidth: number;\n windowCenter: number;\n modality: string;\n}\n\ninterface ImageDataMetaData {\n bitsAllocated: number;\n numComps: number;\n origin: Point3;\n direction: Mat3;\n dimensions: Point3;\n spacing: Point3;\n numVoxels: number;\n imagePlaneModule: unknown;\n imagePixelModule: ImagePixelModule;\n}\n\ninterface ImagePlaneModule {\n columnCosines?: Point3;\n columnPixelSpacing?: number;\n imageOrientationPatient?: Float32Array;\n imagePositionPatient?: Point3;\n pixelSpacing?: Point2;\n rowCosines?: Point3;\n rowPixelSpacing?: number;\n sliceLocation?: number;\n sliceThickness?: number;\n frameOfReferenceUID: string;\n columns: number;\n rows: number;\n}\n\n// TODO This needs to be exposed as its published to consumers.\ntype CalibrationEvent = {\n rowScale: number;\n columnScale: number;\n};\n\n/**\n * An object representing a single stack viewport, which is a camera\n * looking into an internal viewport, and an associated target output `canvas`.\n *\n * StackViewports can be rendered using both GPU and a fallback CPU is the GPU\n * is not available (or low performance). Read more about StackViewports in\n * the documentation section of this website.\n */\nclass StackViewport extends Viewport implements IStackViewport {\n private imageIds: Array<string>;\n // current imageIdIndex that is rendered in the viewport\n private currentImageIdIndex: number;\n // the imageIdIndex that is targeted to be loaded with scrolling but has not initiated loading yet\n private targetImageIdIndex: number;\n // setTimeout if the image is debounced to be loaded\n private debouncedTimeout: number;\n\n // Viewport Properties\n private voiRange: VOIRange;\n private initialVOIRange: VOIRange;\n private invert = false;\n private interpolationType: InterpolationType;\n\n // Helpers\n private _imageData: vtkImageDataType;\n private cameraFocalPointOnRender: Point3; // we use focalPoint since flip manipulates the position and makes it useless to track\n private stackInvalidated = false; // if true -> new actor is forced to be created for the stack\n private voiApplied = false;\n private rotationCache = 0;\n private _publishCalibratedEvent = false;\n private _calibrationEvent: CalibrationEvent;\n private _cpuFallbackEnabledElement?: CPUFallbackEnabledElement;\n // CPU fallback\n private useCPURendering: boolean;\n private cpuImagePixelData: number[];\n private cpuRenderingInvalidated: boolean;\n private csImage: IImage;\n\n // TODO: These should not be here and will be nuked\n public modality: string; // this is needed for tools\n public scaling: Scaling;\n\n /**\n * Constructor for the StackViewport class\n * @param props - ViewportInput\n */\n constructor(props: ViewportInput) {\n super(props);\n this.scaling = {};\n this.modality = null;\n this.useCPURendering = getShouldUseCPURendering();\n\n if (this.useCPURendering) {\n this._cpuFallbackEnabledElement = {\n canvas: this.canvas,\n renderingTools: {},\n transform: new Transform(),\n viewport: {},\n };\n } else {\n const renderer = this.getRenderer();\n const camera = vtkCamera.newInstance();\n renderer.setActiveCamera(camera);\n\n const viewPlaneNormal = <Point3>[0, 0, -1];\n const viewUp = <Point3>[0, -1, 0];\n\n camera.setDirectionOfProjection(\n -viewPlaneNormal[0],\n -viewPlaneNormal[1],\n -viewPlaneNormal[2]\n );\n camera.setViewUp(...viewUp);\n camera.setParallelProjection(true);\n camera.setThicknessFromFocalPoint(0.1);\n // @ts-ignore: vtkjs incorrect typing\n camera.setFreezeFocalPoint(true);\n }\n\n this.imageIds = [];\n this.currentImageIdIndex = 0;\n this.targetImageIdIndex = 0;\n this.cameraFocalPointOnRender = [0, 0, 0];\n this.resetCamera();\n\n this.initializeElementDisabledHandler();\n }\n\n static get useCustomRenderingPipeline(): boolean {\n return getShouldUseCPURendering();\n }\n\n private initializeElementDisabledHandler() {\n eventTarget.addEventListener(\n Events.ELEMENT_DISABLED,\n function elementDisabledHandler() {\n clearTimeout(this.debouncedTimeout);\n\n eventTarget.removeEventListener(\n Events.ELEMENT_DISABLED,\n elementDisabledHandler\n );\n }\n );\n }\n\n /**\n * Resizes the viewport - only used in CPU fallback for StackViewport. The\n * GPU resizing happens inside the RenderingEngine.\n */\n public resize = (): void => {\n // GPU viewport resize is handled inside the RenderingEngine\n if (this.useCPURendering) {\n this._resizeCPU();\n }\n };\n\n /**\n * Returns the image and its properties that is being shown inside the\n * stack viewport. It returns, the image dimensions, image direction,\n * image scalar data, vtkImageData object, metadata, and scaling (e.g., PET suvbw)\n *\n * @returns IImageData: dimensions, direction, scalarData, vtkImageData, metadata, scaling\n */\n public getImageData(): IImageData | CPUIImageData {\n if (this.useCPURendering) {\n return this.getImageDataCPU();\n } else {\n return this.getImageDataGPU();\n }\n }\n\n private _resizeCPU = (): void => {\n if (this._cpuFallbackEnabledElement.viewport) {\n resize(this._cpuFallbackEnabledElement);\n }\n };\n\n private getImageDataGPU(): IImageData | undefined {\n const defaultActor = this.getDefaultActor();\n\n if (!defaultActor) {\n return;\n }\n\n const { actor } = defaultActor;\n if (!isImageActor(actor)) {\n return;\n }\n\n const vtkImageData = actor.getMapper().getInputData();\n return {\n dimensions: vtkImageData.getDimensions(),\n spacing: vtkImageData.getSpacing(),\n origin: vtkImageData.getOrigin(),\n direction: vtkImageData.getDirection(),\n scalarData: vtkImageData.getPointData().getScalars().getData(),\n imageData: actor.getMapper().getInputData(),\n metadata: { Modality: this.modality },\n scaling: this.scaling,\n hasPixelSpacing: this.hasPixelSpacing,\n preScale: {\n ...this.csImage.preScale,\n },\n };\n }\n\n private getImageDataCPU(): CPUIImageData | undefined {\n const { metadata } = this._cpuFallbackEnabledElement;\n\n const spacing = metadata.spacing;\n\n return {\n dimensions: metadata.dimensions,\n spacing,\n origin: metadata.origin,\n direction: metadata.direction,\n metadata: { Modality: this.modality },\n scaling: this.scaling,\n imageData: {\n getDirection: () => metadata.direction,\n getDimensions: () => metadata.dimensions,\n getScalarData: () => this.cpuImagePixelData,\n getSpacing: () => spacing,\n worldToIndex: (point: Point3) => {\n const canvasPoint = this.worldToCanvasCPU(point);\n const pixelCoord = canvasToPixel(\n this._cpuFallbackEnabledElement,\n canvasPoint\n );\n return [pixelCoord[0], pixelCoord[1], 0];\n },\n indexToWorld: (point: Point3) => {\n const canvasPoint = pixelToCanvas(this._cpuFallbackEnabledElement, [\n point[0],\n point[1],\n ]);\n return this.canvasToWorldCPU(canvasPoint);\n },\n },\n scalarData: this.cpuImagePixelData,\n hasPixelSpacing: this.hasPixelSpacing,\n preScale: {\n ...this.csImage.preScale,\n },\n };\n }\n\n /**\n * Returns the frame of reference UID, if the image doesn't have imagePlaneModule\n * metadata, it returns undefined, otherwise, frameOfReferenceUID is returned.\n * @returns frameOfReferenceUID : string representing frame of reference id\n */\n public getFrameOfReferenceUID = (): string | undefined => {\n // Get the current image that is displayed in the viewport\n const imageId = this.getCurrentImageId();\n\n if (!imageId) {\n return;\n }\n\n // Use the metadata provider to grab its imagePlaneModule metadata\n const imagePlaneModule = metaData.get('imagePlaneModule', imageId);\n\n // If nothing exists, return undefined\n if (!imagePlaneModule) {\n return;\n }\n\n // Otherwise, provide the FrameOfReferenceUID so we can map\n // annotations made on VolumeViewports back to StackViewports\n // and vice versa\n return imagePlaneModule.frameOfReferenceUID;\n };\n\n /**\n * Creates imageMapper based on the provided vtkImageData and also creates\n * the imageSliceActor and connects it to the imageMapper.\n * For color stack images, it sets the independent components to be false which\n * is required in vtk.\n *\n * @param imageData - vtkImageData for the viewport\n * @returns actor vtkActor\n */\n\n private createActorMapper = (imageData) => {\n const mapper = vtkImageMapper.newInstance();\n mapper.setInputData(imageData);\n\n const actor = vtkImageSlice.newInstance();\n\n // @ts-ignore: vtkjs incorrect typing\n actor.setMapper(mapper);\n\n if (imageData.getPointData().getNumberOfComponents() > 1) {\n // @ts-ignore: vtkjs incorrect typing\n actor.getProperty().setIndependentComponents(false);\n }\n\n return actor;\n };\n\n /**\n * Retrieves the metadata from the metadata provider, and optionally adds the\n * scaling to the viewport if modality is PET and scaling metadata is provided.\n *\n * @param imageId - a string representing the imageId for the image\n * @returns imagePlaneModule and imagePixelModule containing the metadata for the image\n */\n private buildMetadata(imageId: string) {\n const {\n pixelRepresentation,\n bitsAllocated,\n bitsStored,\n highBit,\n photometricInterpretation,\n samplesPerPixel,\n } = metaData.get('imagePixelModule', imageId);\n\n const voiLutModule = metaData.get('voiLutModule', imageId);\n\n let windowWidth, windowCenter;\n if (voiLutModule) {\n ({ windowWidth, windowCenter } = voiLutModule);\n\n if (Array.isArray(windowWidth)) {\n windowWidth = windowWidth[0];\n }\n\n if (Array.isArray(windowCenter)) {\n windowCenter = windowCenter[0];\n }\n }\n\n const { modality } = metaData.get('generalSeriesModule', imageId);\n const imageIdScalingFactor = metaData.get('scalingModule', imageId);\n\n if (modality === 'PT' && imageIdScalingFactor) {\n this._addScalingToViewport(imageIdScalingFactor);\n }\n\n // todo: some tools rely on the modality\n this.modality = modality;\n\n let imagePlaneModule = this._getImagePlaneModule(imageId);\n\n // Todo: for now, it gives error for getImageData\n if (!this.useCPURendering) {\n imagePlaneModule = this.calibrateIfNecessary(imageId, imagePlaneModule);\n }\n\n return {\n imagePlaneModule,\n imagePixelModule: {\n bitsAllocated,\n bitsStored,\n samplesPerPixel,\n highBit,\n photometricInterpretation,\n pixelRepresentation,\n windowWidth,\n windowCenter,\n modality,\n },\n };\n }\n\n /**\n * Checks the metadataProviders to see if a calibratedPixelSpacing is\n * given. If so, checks the actor to see if it needs to be modified, and\n * set the flags for imageCalibration if a new actor needs to be created\n *\n * @param imageId - imageId\n * @param imagePlaneModule - imagePlaneModule\n * @returns modified imagePlaneModule with the calibrated spacings\n */\n private calibrateIfNecessary(imageId, imagePlaneModule) {\n const calibratedPixelSpacing = metaData.get(\n 'calibratedPixelSpacing',\n imageId\n );\n\n if (!calibratedPixelSpacing) {\n return imagePlaneModule;\n }\n\n const [calibratedRowSpacing, calibratedColumnSpacing] =\n calibratedPixelSpacing;\n\n // Todo: This is necessary in general, but breaks an edge case when an image\n // is calibrated to some other spacing, and it gets calibrated BACK to the\n // original spacing.\n if (\n imagePlaneModule.rowPixelSpacing === calibratedRowSpacing &&\n imagePlaneModule.columnPixelSpacing === calibratedColumnSpacing\n ) {\n return imagePlaneModule;\n }\n\n // Check if there is already an actor\n const imageDataMetadata = this.getImageData();\n\n // If no actor (first load) and calibration matches the dicom header\n if (\n !imageDataMetadata &&\n imagePlaneModule.rowPixelSpacing === calibratedRowSpacing &&\n imagePlaneModule.columnPixelSpacing === calibratedColumnSpacing\n ) {\n return imagePlaneModule;\n }\n\n // If no actor (first load) and calibration doesn't match headers\n // -> needs calibration\n if (\n !imageDataMetadata &&\n (imagePlaneModule.rowPixelSpacing !== calibratedRowSpacing ||\n imagePlaneModule.columnPixelSpacing !== calibratedColumnSpacing)\n ) {\n this._publishCalibratedEvent = true;\n\n this._calibrationEvent = <CalibrationEvent>{\n rowScale: calibratedRowSpacing / imagePlaneModule.rowPixelSpacing,\n columnScale:\n calibratedColumnSpacing / imagePlaneModule.columnPixelSpacing,\n };\n\n // modify imagePlaneModule for actor to use calibrated spacing\n imagePlaneModule.rowPixelSpacing = calibratedRowSpacing;\n imagePlaneModule.columnPixelSpacing = calibratedColumnSpacing;\n return imagePlaneModule;\n }\n\n // If there is already an actor, check if calibration is needed for the current actor\n const { imageData } = imageDataMetadata;\n const [columnPixelSpacing, rowPixelSpacing] = imageData.getSpacing();\n\n imagePlaneModule.rowPixelSpacing = calibratedRowSpacing;\n imagePlaneModule.columnPixelSpacing = calibratedColumnSpacing;\n\n // If current actor spacing matches the calibrated spacing\n if (\n rowPixelSpacing === calibratedRowSpacing &&\n columnPixelSpacing === calibratedPixelSpacing\n ) {\n // No calibration is required\n return imagePlaneModule;\n }\n\n // Calibration is required\n this._publishCalibratedEvent = true;\n\n this._calibrationEvent = <CalibrationEvent>{\n rowScale: calibratedRowSpacing / rowPixelSpacing,\n columnScale: calibratedColumnSpacing / columnPixelSpacing,\n };\n\n return imagePlaneModule;\n }\n\n /**\n * Sets the properties for the viewport on the default actor. Properties include\n * setting the VOI, inverting the colors and setting the interpolation type, rotation\n * @param voiRange - Sets the lower and upper voi\n * @param invert - Inverts the colors\n * @param interpolationType - Changes the interpolation type (1:linear, 0: nearest)\n * @param rotation - image rotation in degrees\n */\n public setProperties(\n {\n voiRange,\n invert,\n interpolationType,\n rotation,\n }: StackViewportProperties = {},\n suppressEvents = false\n ): void {\n // if voi is not applied for the first time, run the setVOI function\n // which will apply the default voi\n if (typeof voiRange !== 'undefined' || !this.voiApplied) {\n this.setVOI(voiRange, suppressEvents);\n }\n\n if (typeof invert !== 'undefined') {\n this.setInvertColor(invert);\n }\n\n if (typeof interpolationType !== 'undefined') {\n this.setInterpolationType(interpolationType);\n }\n\n if (typeof rotation !== 'undefined') {\n if (this.rotationCache !== rotation) {\n this.setRotation(this.rotationCache, rotation);\n }\n }\n }\n\n /**\n * Retrieve the viewport properties\n * @returns viewport properties including voi, invert, interpolation type, rotation, flip\n */\n public getProperties = (): StackViewportProperties => {\n return {\n voiRange: this.voiRange,\n rotation: this.rotationCache,\n interpolationType: this.interpolationType,\n invert: this.invert,\n };\n };\n\n /**\n * Reset the viewport properties to the default values\n */\n public resetProperties(): void {\n this.cpuRenderingInvalidated = true;\n\n this.fillWithBackgroundColor();\n\n if (this.useCPURendering) {\n this._cpuFallbackEnabledElement.renderingTools = {};\n }\n\n this._resetProperties();\n\n this.render();\n }\n\n /**\n * If the user has selected CPU rendering, return the CPU camera, otherwise\n * return the default camera\n * @returns The camera object.\n */\n public getCamera(): ICamera {\n if (this.useCPURendering) {\n return this.getCameraCPU();\n } else {\n return super.getCamera();\n }\n }\n\n /**\n * Set the camera based on the provided camera object.\n * @param cameraInterface - The camera interface that will be used to\n * render the scene.\n */\n public setCamera(\n cameraInterface: ICamera,\n storeAsInitialCamera = false\n ): void {\n if (this.useCPURendering) {\n this.setCameraCPU(cameraInterface);\n } else {\n super.setCamera(cameraInterface, storeAsInitialCamera);\n }\n }\n\n private _resetProperties() {\n // to force the default voi to be applied on the next render\n this.voiApplied = false;\n\n this.setProperties({\n voiRange: this.initialVOIRange,\n rotation: 0,\n interpolationType: InterpolationType.LINEAR,\n invert: false,\n });\n }\n\n private _setPropertiesFromCache(): void {\n const suppressEvents = true;\n this.setProperties(\n {\n voiRange: this.voiRange,\n rotation: this.rotation,\n interpolationType: this.interpolationType,\n invert: this.invert,\n },\n suppressEvents\n );\n }\n\n private getCameraCPU(): Partial<ICamera> {\n const { metadata, viewport } = this._cpuFallbackEnabledElement;\n const { direction } = metadata;\n\n // focalPoint and position of CPU camera is just a placeholder since\n // tools need focalPoint to be defined\n const viewPlaneNormal = direction.slice(6, 9).map((x) => -x) as Point3;\n let viewUp = direction.slice(3, 6).map((x) => -x) as Point3;\n\n // If camera is rotated, we need the correct rotated viewUp along the\n // viewPlaneNormal vector\n if (this.rotation) {\n const rotationMatrix = mat4.fromRotation(\n mat4.create(),\n (this.rotation * Math.PI) / 180,\n viewPlaneNormal\n );\n viewUp = vec3.transformMat4(\n vec3.create(),\n viewUp,\n rotationMatrix\n ) as Point3;\n }\n\n const canvasCenter: Point2 = [\n this.element.clientWidth / 2,\n this.element.clientHeight / 2,\n ];\n\n // Focal point is the center of the canvas in world coordinate by construction\n const canvasCenterWorld = this.canvasToWorld(canvasCenter);\n\n // parallel scale is half of the viewport height in the world units (mm)\n\n const topLeftWorld = this.canvasToWorld([0, 0]);\n const bottomLeftWorld = this.canvasToWorld([0, this.element.clientHeight]);\n\n const parallelScale = vec3.distance(topLeftWorld, bottomLeftWorld) / 2;\n\n return {\n parallelProjection: true,\n focalPoint: canvasCenterWorld,\n position: [0, 0, 0],\n parallelScale,\n scale: viewport.scale,\n viewPlaneNormal: [\n viewPlaneNormal[0],\n viewPlaneNormal[1],\n viewPlaneNormal[2],\n ],\n viewUp: [viewUp[0], viewUp[1], viewUp[2]],\n flipHorizontal: this.flipHorizontal,\n flipVertical: this.flipVertical,\n };\n }\n\n private setCameraCPU(cameraInterface: ICamera): void {\n const { viewport, image } = this._cpuFallbackEnabledElement;\n const previousCamera = this.getCameraCPU();\n\n const { focalPoint, parallelScale, scale, flipHorizontal, flipVertical } =\n cameraInterface;\n\n const { clientHeight } = this.element;\n\n if (focalPoint) {\n const focalPointCanvas = this.worldToCanvasCPU(focalPoint);\n const focalPointPixel = canvasToPixel(\n this._cpuFallbackEnabledElement,\n focalPointCanvas\n );\n\n const prevFocalPointCanvas = this.worldToCanvasCPU(\n previousCamera.focalPoint\n );\n const prevFocalPointPixel = canvasToPixel(\n this._cpuFallbackEnabledElement,\n prevFocalPointCanvas\n );\n\n const deltaPixel = vec2.create();\n vec2.subtract(\n deltaPixel,\n vec2.fromValues(focalPointPixel[0], focalPointPixel[1]),\n vec2.fromValues(prevFocalPointPixel[0], prevFocalPointPixel[1])\n );\n\n const shift = correctShift(\n { x: deltaPixel[0], y: deltaPixel[1] },\n viewport\n );\n\n viewport.translation.x -= shift.x;\n viewport.translation.y -= shift.y;\n }\n\n if (parallelScale) {\n // We need to convert he parallelScale which has a physical meaning to\n // camera scale factor (since CPU works with scale). Since parallelScale represents\n // half of the height of the viewport in the world unit (mm), we can use that\n // to compute the scale factor which is the ratio of the viewport height in pixels\n // to the current rendered image height.\n const { rowPixelSpacing } = image;\n const scale = (clientHeight * rowPixelSpacing * 0.5) / parallelScale;\n\n viewport.scale = scale;\n viewport.parallelScale = parallelScale;\n }\n\n if (scale) {\n const { rowPixelSpacing } = image;\n viewport.scale = scale;\n viewport.parallelScale = (clientHeight * rowPixelSpacing * 0.5) / scale;\n }\n\n if (flipHorizontal !== undefined || flipVertical !== undefined) {\n this.setFlipCPU({ flipHorizontal, flipVertical });\n }\n\n // re-calculate the transforms\n this._cpuFallbackEnabledElement.transform = calculateTransform(\n this._cpuFallbackEnabledElement\n );\n\n const eventDetail: EventTypes.CameraModifiedEventDetail = {\n previousCamera,\n camera: this.getCamera(),\n element: this.element,\n viewportId: this.id,\n renderingEngineId: this.renderingEngineId,\n rotation: this.rotation,\n };\n\n triggerEvent(this.element, Events.CAMERA_MODIFIED, eventDetail);\n }\n\n private setFlipCPU({ flipHorizontal, flipVertical }: FlipDirection): void {\n const { viewport } = this._cpuFallbackEnabledElement;\n\n if (flipHorizontal !== undefined) {\n viewport.hflip = flipHorizontal;\n this.flipHorizontal = viewport.hflip;\n }\n\n if (flipVertical !== undefined) {\n viewport.vflip = flipVertical;\n this.flipVertical = viewport.vflip;\n }\n }\n\n private setVOI(voiRange: VOIRange, suppressEvents?: boolean): void {\n if (this.useCPURendering) {\n this.setVOICPU(voiRange, suppressEvents);\n return;\n }\n\n this.setVOIGPU(voiRange, suppressEvents);\n }\n\n private setRotation(rotationCache: number, rotation: number): void {\n const previousCamera = this.getCamera();\n\n if (this.useCPURendering) {\n this.setRotationCPU(rotationCache, rotation);\n } else {\n this.setRotationGPU(rotationCache, rotation);\n }\n\n // New camera after rotation\n const camera = this.getCamera();\n\n const eventDetail: EventTypes.CameraModifiedEventDetail = {\n previousCamera,\n camera,\n element: this.element,\n viewportId: this.id,\n renderingEngineId: this.renderingEngineId,\n rotation: this.rotation,\n };\n\n triggerEvent(this.element, Events.CAMERA_MODIFIED, eventDetail);\n }\n\n private setInterpolationType(interpolationType: InterpolationType): void {\n if (this.useCPURendering) {\n this.setInterpolationTypeCPU(interpolationType);\n return;\n }\n\n this.setInterpolationTypeGPU(interpolationType);\n }\n\n private setInvertColor(invert: boolean): void {\n if (this.useCPURendering) {\n this.setInvertColorCPU(invert);\n return;\n }\n\n this.setInvertColorGPU(invert);\n }\n\n private setRotationCPU(rotationCache: number, rotation: number): void {\n const { viewport } = this._cpuFallbackEnabledElement;\n\n viewport.rotation = rotation;\n this.rotationCache = rotation;\n this.rotation = rotation;\n }\n\n private setRotationGPU(rotationCache: number, rotation: number): void {\n // Moving back to zero rotation, for new scrolled slice rotation is 0 after camera reset\n this.getVtkActiveCamera().roll(rotationCache);\n\n // rotating camera to the new value\n this.getVtkActiveCamera().roll(-rotation);\n this.rotationCache = rotation;\n this.rotation = rotation;\n }\n\n private setInterpolationTypeGPU(interpolationType: InterpolationType): void {\n const defaultActor = this.getDefaultActor();\n\n if (!defaultActor) {\n return;\n }\n\n const { actor } = defaultActor;\n if (!isImageActor(actor)) {\n return;\n }\n const volumeProperty = actor.getProperty();\n\n // @ts-ignore\n volumeProperty.setInterpolationType(interpolationType);\n this.interpolationType = interpolationType;\n }\n\n private setInterpolationTypeCPU(interpolationType: InterpolationType): void {\n const { viewport } = this._cpuFallbackEnabledElement;\n\n if (interpolationType === InterpolationType.LINEAR) {\n viewport.pixelReplication = false;\n } else {\n viewport.pixelReplication = true;\n }\n\n this.interpolationType = interpolationType;\n }\n\n private setInvertColorCPU(invert: boolean): void {\n const { viewport } = this._cpuFallbackEnabledElement;\n\n if (!viewport) {\n return;\n }\n\n viewport.invert = invert;\n this.invert = invert;\n }\n\n private setInvertColorGPU(invert: boolean): void {\n const defaultActor = this.getDefaultActor();\n\n if (!defaultActor) {\n return;\n }\n\n const { actor } = defaultActor;\n if (!isImageActor(actor)) {\n return;\n }\n\n // Duplicated logic to make sure typescript stops complaining\n // about vtkActor not having the correct property\n if (actor.isA('vtkVolume')) {\n const volumeActor = actor as VolumeActor;\n const tfunc = volumeActor.getProperty().getRGBTransferFunction(0);\n\n if ((!this.invert && invert) || (this.invert && !invert)) {\n invertRgbTransferFunction(tfunc);\n }\n this.invert = invert;\n } else if (actor.isA('vtkImageSlice')) {\n const imageSliceActor = actor as vtkImageSlice;\n const tfunc = imageSliceActor.getProperty().getRGBTransferFunction(0);\n\n if ((!this.invert && invert) || (this.invert && !invert)) {\n invertRgbTransferFunction(tfunc);\n }\n this.invert = invert;\n }\n }\n\n private setVOICPU(voiRange: VOIRange, suppressEvents?: boolean): void {\n const { viewport, image } = this._cpuFallbackEnabledElement;\n\n if (!viewport || !image) {\n return;\n }\n\n if (typeof voiRange === 'undefined') {\n const { windowWidth: ww, windowCenter: wc } = image;\n\n const wwToUse = Array.isArray(ww) ? ww[0] : ww;\n const wcToUse = Array.isArray(wc) ? wc[0] : wc;\n viewport.voi = {\n windowWidth: wwToUse,\n windowCenter: wcToUse,\n };\n\n const { lower, upper } = windowLevelUtil.toLowHighRange(wwToUse, wcToUse);\n voiRange = { lower, upper };\n } else {\n const { lower, upper } = voiRange;\n const { windowCenter, windowWidth } = windowLevelUtil.toWindowLevel(\n lower,\n upper\n );\n\n if (!viewport.voi) {\n viewport.voi = {\n windowWidth: 0,\n windowCenter: 0,\n };\n }\n\n viewport.voi.windowWidth = windowWidth;\n viewport.voi.windowCenter = windowCenter;\n }\n\n this.voiApplied = true;\n this.voiRange = voiRange;\n const eventDetail: VoiModifiedEventDetail = {\n viewportId: this.id,\n range: voiRange,\n };\n\n if (!suppressEvents) {\n triggerEvent(this.element, Events.VOI_MODIFIED, eventDetail);\n }\n }\n\n private setVOIGPU(voiRange: VOIRange, suppressEvents?: boolean): void {\n const defaultActor = this.getDefaultActor();\n if (!defaultActor) {\n return;\n }\n\n const { actor } = defaultActor;\n\n if (!isImageActor(actor)) {\n return;\n }\n\n const imageActor = actor as ImageActor;\n\n let voiRangeToUse = voiRange;\n if (typeof voiRangeToUse === 'undefined') {\n const imageData = imageActor.getMapper().getInputData();\n const range = imageData.getPointData().getScalars().getRange();\n voiRangeToUse = { lower: range[0], upper: range[1] };\n }\n\n const { windowWidth, windowCenter } = windowLevelUtil.toWindowLevel(\n voiRangeToUse.lower,\n voiRangeToUse.upper\n );\n\n imageActor.getProperty().setColorWindow(windowWidth);\n imageActor.getProperty().setColorLevel(windowCenter);\n\n this.voiApplied = true;\n this.voiRange = voiRangeToUse;\n\n if (!suppressEvents) {\n const eventDetail: VoiModifiedEventDetail = {\n viewportId: this.id,\n range: voiRangeToUse,\n };\n\n triggerEvent(this.element, Events.VOI_MODIFIED, eventDetail);\n }\n }\n\n /**\n * Adds scaling parameters to the viewport to be used along all slices\n *\n * @param imageIdScalingFactor - suvbw, suvlbm, suvbsa\n */\n private _addScalingToViewport(imageIdScalingFactor) {\n if (!this.scaling.PET) {\n // These ratios are constant across all frames, so only need one.\n const { suvbw, suvlbm, suvbsa } = imageIdScalingFactor;\n\n const petScaling = <PTScaling>{};\n\n if (suvlbm) {\n petScaling.suvbwToSuvlbm = suvlbm / suvbw;\n }\n\n if (suvbsa) {\n petScaling.suvbwToSuvbsa = suvbsa / suvbw;\n }\n\n this.scaling.PET = petScaling;\n }\n }\n\n /**\n * Calculates number of components based on the dicom metadata\n *\n * @param photometricInterpretation - string dicom tag\n * @returns number representing number of components\n */\n private _getNumCompsFromPhotometricInterpretation(\n photometricInterpretation: string\n ): number {\n // TODO: this function will need to have more logic later\n // see http://dicom.nema.org/medical/Dicom/current/output/chtml/part03/sect_C.7.6.3.html#sect_C.7.6.3.1.2\n let numberOfComponents = 1;\n if (\n photometricInterpretation === 'RGB' ||\n photometricInterpretation.indexOf('YBR') !== -1 ||\n photometricInterpretation === 'PALETTE COLOR'\n ) {\n numberOfComponents = 3;\n }\n\n return numberOfComponents;\n }\n\n /**\n * Calculates image metadata based on the image object. It calculates normal\n * axis for the images, and output image metadata\n *\n * @param image - stack image containing cornerstone image\n * @returns image metadata: bitsAllocated, number of components, origin,\n * direction, dimensions, spacing, number of voxels.\n */\n private _getImageDataMetadata(image: IImage): ImageDataMetaData {\n // TODO: Creating a single image should probably not require a metadata provider.\n // We should define the minimum we need to display an image and it should live on\n // the Image object itself. Additional stuff (e.g. pixel spacing, direction, origin, etc)\n // should be optional and used if provided through a metadata provider.\n\n const { imagePlaneModule, imagePixelModule } = this.buildMetadata(\n image.imageId\n );\n\n let rowCosines, columnCosines;\n\n rowCosines = <Point3>imagePlaneModule.rowCosines;\n columnCosines = <Point3>imagePlaneModule.columnCosines;\n\n // if null or undefined\n if (rowCosines == null || columnCosines == null) {\n rowCosines = <Point3>[1, 0, 0];\n columnCosines = <Point3>[0, 1, 0];\n }\n\n const rowCosineVec = vec3.fromValues(\n rowCosines[0],\n rowCosines[1],\n rowCosines[2]\n );\n const colCosineVec = vec3.fromValues(\n columnCosines[0],\n columnCosines[1],\n columnCosines[2]\n );\n const scanAxisNormal = vec3.create();\n vec3.cross(scanAxisNormal, rowCosineVec, colCosineVec);\n\n let origin = imagePlaneModule.imagePositionPatient;\n // if null or undefined\n if (origin == null) {\n origin = [0, 0, 0];\n }\n\n const xSpacing =\n imagePlaneModule.columnPixelSpacing || image.columnPixelSpacing;\n const ySpacing = imagePlaneModule.rowPixelSpacing || image.rowPixelSpacing;\n const xVoxels = image.columns;\n const yVoxels = image.rows;\n\n // Note: For rendering purposes, we use the EPSILON as the z spacing.\n // This is purely for internal implementation logic since we are still\n // technically rendering 3D objects with vtk.js, but the abstracted intention\n // of the stack viewport is to render 2D images\n const zSpacing = EPSILON;\n const zVoxels = 1;\n\n const numComps =\n image.numComps ||\n this._getNumCompsFromPhotometricInterpretation(\n imagePixelModule.photometricInterpretation\n );\n\n return {\n bitsAllocated: imagePixelModule.bitsAllocated,\n numComps,\n origin,\n direction: [...rowCosineVec, ...colCosineVec, ...scanAxisNormal] as Mat3,\n dimensions: [xVoxels, yVoxels, zVoxels],\n spacing: [xSpacing, ySpacing, zSpacing],\n numVoxels: xVoxels * yVoxels * zVoxels,\n imagePlaneModule,\n imagePixelModule,\n };\n }\n\n /**\n * Converts the image direction to camera viewUp and viewplaneNormal\n *\n * @param imageDataDirection - vtkImageData direction\n * @returns viewplane normal and viewUp of the camera\n */\n private _getCameraOrientation(imageDataDirection: Mat3): {\n viewPlaneNormal: Point3;\n viewUp: Point3;\n } {\n const viewPlaneNormal = imageDataDirection.slice(6, 9).map((x) => -x);\n\n const viewUp = imageDataDirection.slice(3, 6).map((x) => -x);\n return {\n viewPlaneNormal: [\n viewPlaneNormal[0],\n viewPlaneNormal[1],\n viewPlaneNormal[2],\n ],\n viewUp: [viewUp[0], viewUp[1], viewUp[2]],\n };\n }\n\n /**\n * Creates vtkImagedata based on the image object, it creates\n * and empty scalar data for the image based on the metadata\n * tags (e.g., bitsAllocated)\n *\n * @param image - cornerstone Image object\n */\n private _createVTKImageData({\n origin,\n direction,\n dimensions,\n spacing,\n bitsAllocated,\n numComps,\n numVoxels,\n }): void {\n let pixelArray;\n switch (bitsAllocated) {\n case 8:\n pixelArray = new Uint8Array(numVoxels * numComps);\n break;\n\n case 16:\n pixelArray = new Float32Array(numVoxels * numComps);\n\n break;\n case 24:\n pixelArray = new Uint8Array(numVoxels * 3 * numComps);\n\n break;\n default:\n console.log('bit allocation not implemented');\n }\n\n const scalarArray = vtkDataArray.newInstance({\n name: 'Pixels',\n numberOfComponents: numComps,\n values: pixelArray,\n });\n\n this._imageData = vtkImageData.newInstance();\n\n this._imageData.setDimensions(dimensions);\n this._imageData.setSpacing(spacing);\n this._imageData.setDirection(direction);\n this._imageData.setOrigin(origin);\n this._imageData.getPointData().setScalars(scalarArray);\n }\n\n /**\n * Sets the imageIds to be visualized inside the stack viewport. It accepts\n * list of imageIds, the index of the first imageId to be viewed. It is a\n * asynchronous function that returns a promise resolving to imageId being\n * displayed in the stack viewport.\n *\n *\n * @param imageIds - list of strings, that represents list of image Ids\n * @param currentImageIdIndex - number representing the index of the initial image to be displayed\n */\n public async setStack(\n imageIds: Array<string>,\n currentImageIdIndex = 0\n ): Promise<string> {\n this.imageIds = imageIds;\n this.currentImageIdIndex = currentImageIdIndex;\n this.targetImageIdIndex = currentImageIdIndex;\n this.stackInvalidated = true;\n this.rotationCache = 0;\n this.flipVertical = false;\n this.flipHorizontal = false;\n this.voiApplied = false;\n\n this._resetProperties();\n\n this.fillWithBackgroundColor();\n\n if (this.useCPURendering) {\n this._cpuFallbackEnabledElement.renderingTools = {};\n delete this._cpuFallbackEnabledElement.viewport.colormap;\n }\n\n const imageId = await this._setImageIdIndex(currentImageIdIndex);\n\n const eventDetail: StackViewportNewStackEventDetail = {\n imageIds,\n viewportId: this.id,\n element: this.element,\n currentImageIdIndex: currentImageIdIndex,\n };\n\n triggerEvent(eventTarget, Events.STACK_VIEWPORT_NEW_STACK, eventDetail);\n\n return imageId;\n }\n\n /**\n * It checks if the new image object matches the dimensions, spacing,\n * and direction of the previously displayed image in the viewport or not.\n * It returns a boolean\n *\n * @param image - Cornerstone Image object\n * @param imageData - vtkImageData\n * @returns boolean\n */\n private _checkVTKImageDataMatchesCornerstoneImage(\n image: IImage,\n imageData: vtkImageDataType\n ): boolean {\n if (!imageData) {\n return false;\n }\n\n const [xSpacing, ySpacing] = imageData.getSpacing();\n const [xVoxels, yVoxels] = imageData.getDimensions();\n const imagePlaneModule = this._getImagePlaneModule(image.imageId);\n const direction = imageData.getDirection();\n const rowCosines = direction.slice(0, 3);\n const columnCosines = direction.slice(3, 6);\n\n // using spacing, size, and direction only for now\n return (\n (xSpacing === image.rowPixelSpacing ||\n (image.rowPixelSpacing === null && xSpacing === 1.0)) &&\n (ySpacing === image.columnPixelSpacing ||\n (image.columnPixelSpacing === null && ySpacing === 1.0)) &&\n xVoxels === image.columns &&\n yVoxels === image.rows &&\n isEqual(imagePlaneModule.rowCosines, <Point3>rowCosines) &&\n isEqual(imagePlaneModule.columnCosines, <Point3>columnCosines)\n );\n }\n\n /**\n * It Updates the vtkImageData of the viewport with the new pixel data\n * from the provided image object.\n *\n * @param image - Cornerstone Image object\n */\n private _updateVTKImageDataFromCornerstoneImage(image: IImage): void {\n const imagePlaneModule = this._getImagePlaneModule(image.imageId);\n let origin = imagePlaneModule.imagePositionPatient;\n\n if (origin == null) {\n origin = [0, 0, 0];\n }\n\n this._imageData.setOrigin(origin);\n\n // 1. Update the pixel data in the vtkImageData object with the pixelData\n // from the loaded Cornerstone image\n const pixelData = image.getPixelData();\n const scalars = this._imageData.getPointData().getScalars();\n const scalarData = scalars.getData() as Uint8Array | Float32Array;\n\n if (image.rgba || isRgbaSourceRgbDest(pixelData, scalarData)) {\n if (!image.rgba) {\n console.warn('rgba not specified but data looks rgba ish', image);\n }\n // if image is already cached with rgba for any reason (cpu fallback),\n // we need to convert it to rgb for the pixel data set\n // RGB case\n const numPixels = pixelData.length / 4;\n\n let rgbIndex = 0;\n let index = 0;\n\n for (let i = 0; i < numPixels; i++) {\n scalarData[index++] = pixelData[rgbIndex++]; // red\n scalarData[index++] = pixelData[rgbIndex++]; // green\n scalarData[index++] = pixelData[rgbIndex++]; // blue\n rgbIndex++; // skip alpha\n }\n } else {\n scalarData.set(pixelData);\n }\n\n // Trigger modified on the VTK Object so the texture is updated\n // TODO: evaluate directly changing things with texSubImage3D later\n this._imageData.modified();\n }\n\n /**\n * It uses imageLoadPoolManager to add request for the imageId. It loadsAndCache\n * the image and triggers the STACK_NEW_IMAGE when the request successfully retrieves\n * the image. Next, the volume actor gets updated with the new new retrieved image.\n *\n * @param imageId - string representing the imageId\n * @param imageIdIndex - index of the imageId in the imageId list\n */\n private async _loadAndDisplayImage(\n imageId: string,\n imageIdIndex: number\n ): Promise<string> {\n if (this.useCPURendering) {\n await this._loadAndDisplayImageCPU(imageId, imageIdIndex);\n } else {\n await this._loadAndDisplayImageGPU(imageId, imageIdIndex);\n }\n\n return imageId;\n }\n\n private _loadAndDisplayImageCPU(\n imageId: string,\n imageIdIndex: number\n ): Promise<string> {\n return new Promise((resolve, reject) => {\n // 1. Load the image using the Image Loader\n function successCallback(\n image: IImage,\n imageIdIndex: number,\n imageId: string\n ) {\n // Perform this check after the image has finished loading\n // in case the user has already scrolled away to another image.\n // In that case, do not render this image.\n if (this.currentImageIdIndex !== imageIdIndex) {\n return;\n }\n\n this.csImage = image;\n\n const eventDetail: EventTypes.StackNewImageEventDetail = {\n image,\n imageId,\n imageIdIndex,\n viewportId: this.id,\n renderingEngineId: this.renderingEngineId,\n };\n\n triggerEvent(this.element, Events.STACK_NEW_IMAGE, eventDetail);\n\n const metadata = this._getImageDataMetadata(image) as ImageDataMetaData;\n\n image.isPreScaled = image.preScale?.scaled;\n\n const viewport = getDefaultViewport(\n this.canvas,\n image,\n this.modality,\n this._cpuFallbackEnabledElement.viewport.colormap\n );\n\n this._cpuFallbackEnabledElement.image = image;\n this._cpuFallbackEnabledElement.metadata = {\n ...metadata,\n };\n this.cpuImagePixelData = image.getPixelData();\n\n const viewportSettingToUse = Object.assign(\n {},\n viewport,\n this._cpuFallbackEnabledElement.viewport\n );\n\n // Important: this.stackInvalidated is different than cpuRenderingInvalidated. The\n // former is being used to maintain the previous state of the viewport\n // in the same stack, the latter is used to trigger drawImageSync\n this._cpuFallbackEnabledElement.viewport = this.stackInvalidated\n ? viewport\n : viewportSettingToUse;\n\n // used the previous state of the viewport, then stackInvalidated is set to false\n this.stackInvalidated = false;\n\n // new viewport is set to the current viewport, then cpuRenderingInvalidated is set to true\n this.cpuRenderingInvalidated = true;\n\n this._cpuFallbackEnabledElement.transform = calculateTransform(\n this._cpuFallbackEnabledElement\n );\n\n // Todo: trigger an event to allow applications to hook into END of loading state\n // Currently we use loadHandlerManagers for this\n\n // Trigger the image to be drawn on the next animation frame\n this.render();\n\n // Update the viewport's currentImageIdIndex to reflect the newly\n // rendered image\n this.currentImageIdIndex = imageIdIndex;\n resolve(imageId);\n }\n\n function errorCallback(\n error: Error,\n imageIdIndex: number,\n imageId: string\n ) {\n const eventDetail = {\n error,\n imageIdIndex,\n imageId,\n };\n\n if (!this.suppressEvents) {\n triggerEvent(eventTarget, Events.IMAGE_LOAD_ERROR, eventDetail);\n }\n\n reject(error);\n }\n\n function sendRequest(imageId, imageIdIndex, options) {\n return loadAndCacheImage(imageId, options).then(\n (image) => {\n successCallback.call(this, image, imageIdIndex, imageId);\n },\n (error) => {\n errorCallback.call(this, error, imageIdIndex, imageId);\n }\n );\n }\n\n // Todo: Note that eventually all viewport data is converted into Float32Array,\n // we use it here for the purpose of scaling for now.\n const type = 'Float32Array';\n\n const priority = -5;\n const requestType = RequestType.Interaction;\n const additionalDetails = { imageId };\n const options = {\n targetBuffer: {\n type,\n offset: null,\n length: null,\n },\n preScale: {\n enabled: true,\n },\n useRGBA: false,\n };\n\n imageLoadPoolManager.addRequest(\n sendRequest.bind(this, imageId, imageIdIndex, options),\n requestType,\n additionalDetails,\n priority\n );\n });\n }\n\n private _loadAndDisplayImageGPU(imageId: string, imageIdIndex: number) {\n return new Promise((resolve, reject) => {\n // 1. Load the image using the Image Loader\n function successCallback(image, imageIdIndex, imageId) {\n // Todo: trigger an event to allow applications to hook into END of loading state\n // Currently we use loadHandlerManagers for this\n // Perform this check after the image has finished loading\n // in case the user has already scrolled away to another image.\n // In that case, do not render this image.\n if (this.currentImageIdIndex !== imageIdIndex) {\n return;\n }\n\n // cornerstone image\n this.csImage = image;\n\n const eventDetail: EventTypes.StackNewImageEventDetail = {\n image,\n imageId,\n imageIdIndex,\n viewportId: this.id,\n renderingEngineId: this.renderingEngineId,\n };\n\n triggerEvent(this.element, Events.STACK_NEW_IMAGE, eventDetail);\n this._updateActorToDisplayImageId(image);\n\n // Trigger the image to be drawn on the next animation frame\n this.render();\n\n // Update the viewport's currentImageIdIndex to reflect the newly\n // rendered image\n this.currentImageIdIndex = imageIdIndex;\n resolve(imageId);\n }\n\n function errorCallback(error, imageIdIndex, imageId) {\n const eventDetail = {\n error,\n imageIdIndex,\n imageId,\n };\n\n triggerEvent(eventTarget, Events.IMAGE_LOAD_ERROR, eventDetail);\n reject(error);\n }\n\n function sendRequest(imageId, imageIdIndex, options) {\n return loadAndCacheImage(imageId, options).then(\n (image) => {\n successCallback.call(this, image, imageIdIndex, imageId);\n },\n (error) => {\n errorCallback.call(this, error, imageIdIndex, imageId);\n }\n );\n }\n\n // Todo: Note that eventually all viewport data is converted into Float32Array,\n // we use it here for the purpose of scaling for now.\n const type = 'Float32Array';\n\n const priority = -5;\n const requestType = RequestType.Interaction;\n const additionalDetails = { imageId };\n\n const options = {\n targetBuffer: {\n type,\n offset: null,\n length: null,\n },\n preScale: {\n enabled: true,\n },\n useRGBA: false,\n };\n\n const eventDetail: EventTypes.PreStackNewImageEventDetail = {\n imageId,\n imageIdIndex,\n viewportId: this.id,\n renderingEngineId: this.renderingEngineId,\n };\n triggerEvent(this.element, Events.PRE_STACK_NEW_IMAGE, eventDetail);\n\n imageLoadPoolManager.addRequest(\n sendRequest.bind(this, imageId, imageIdIndex, options),\n requestType,\n additionalDetails,\n priority\n );\n });\n }\n\n /**\n * It updates the volume actor with the retrieved cornerstone image.\n * It first checks if the new image has the same dimensions, spacings, and\n * dimensions of the previous one: 1) If yes, it updates the pixel data 2) if not,\n * it creates a whole new volume actor for the image.\n * Note: Camera gets reset for both situations. Therefore, each image renders at\n * its exact 3D location in the space, and both image and camera moves while scrolling.\n *\n * @param image - Cornerstone image\n * @returns\n */\n private _updateActorToDisplayImageId(image) {\n // This function should do the following:\n // - Get the existing actor's vtkImageData that is being used to render the current image and check if we can reuse the vtkImageData that is in place (i.e. do the image dimensions and data type match?)\n // - If we can reuse it, replace the scalar data under the hood\n // - If we cannot reuse it, create a new actor, remove the old one, and reset the camera\n\n // 2. Check if we can reuse the existing vtkImageData object, if one is present.\n const sameImageData = this._checkVTKImageDataMatchesCornerstoneImage(\n image,\n this._imageData\n );\n\n const activeCamera = this.getRenderer().getActiveCamera();\n\n // Cache camera props so we can trigger one camera changed event after\n // The full transition.\n const previousCameraProps = _cloneDeep(this.getCamera());\n if (sameImageData && !this.stackInvalidated) {\n // 3a. If we can reuse it, replace the scalar data under the hood\n this._updateVTKImageDataFromCornerstoneImage(image);\n\n // Since the 3D location of the imageData is changing as we scroll, we need\n // to modify the camera position to render this properly. However, resetting\n // causes problem related to zoom and pan tools: upon rendering of a new slice\n // the pan and zoom will get reset. To solve this, 1) we store the camera\n // properties related to pan and zoom 2) reset the camera to correctly place\n // it in the space 3) restore the pan, zoom props.\n const cameraProps = this.getCamera();\n\n const panCache = vec3.subtract(\n vec3.create(),\n this.cameraFocalPointOnRender,\n cameraProps.focalPoint\n );\n\n // store rotation cache since reset camera will reset it\n const rotationCache = this.rotationCache;\n\n // Reset the camera to point to the new slice location, reset camera doesn't\n // modify the direction of projection and viewUp\n this.resetCameraNoEvent();\n\n // restore the rotation cache for the new slice\n this.setRotation(rotationCache, rotationCache);\n\n // set the flip back to the previous value since the restore camera props\n // rely on the correct flip value\n this.setCameraNoEvent({\n flipHorizontal: previousCameraProps.flipHorizontal,\n flipVertical: previousCameraProps.flipVertical,\n });\n\n const { focalPoint } = this.getCamera();\n this.cameraFocalPointOnRender = focalPoint;\n\n // This is necessary to initialize the clipping range and it is not related\n // to our custom slabThickness.\n // @ts-ignore: vtkjs incorrect typing\n activeCamera.setFreezeFocalPoint(true);\n\n // We shouldn't restore the focalPoint, position and parallelScale after reset\n // if it is the first render or we have completely re-created the vtkImageData\n this._restoreCameraProps(\n cameraProps,\n previousCameraProps,\n panCache as Point3\n );\n\n // Restore rotation for the new slice of the image\n this.rotationCache = 0;\n this._setPropertiesFromCache();\n\n return;\n }\n\n const {\n origin,\n direction,\n dimensions,\n spacing,\n bitsAllocated,\n numComps,\n numVoxels,\n imagePixelModule,\n } = this._getImageDataMetadata(image);\n\n // 3b. If we cannot reuse the vtkImageData object (either the first render\n // or the size has changed), create a new one\n this._createVTKImageData({\n origin,\n direction,\n dimensions,\n spacing,\n bitsAllocated,\n numComps,\n numVoxels,\n });\n\n // Set the scalar data of the vtkImageData object from the Cornerstone\n // Image's pixel data\n this._updateVTKImageDataFromCornerstoneImage(image);\n\n // Create a VTK Image Slice actor to display the vtkImageData object\n const actor = this.createActorMapper(this._imageData);\n const actors = [];\n actors.push({ uid: this.id, actor });\n this.setActors(actors);\n // Adjusting the camera based on slice axis. this is required if stack\n // contains various image orientations (axial ct, sagittal xray)\n const { viewPlaneNormal, viewUp } = this._getCameraOrientation(direction);\n\n this.setCameraNoEvent({ viewUp, viewPlaneNormal });\n\n // Reset the camera to point to the new slice location, reset camera doesn't\n // modify the direction of projection and viewUp\n this.resetCameraNoEvent();\n\n this.triggerCameraEvent(this.getCamera(), previousCameraProps);\n\n // This is necessary to initialize the clipping range and it is not related\n // to our custom slabThickness.\n // @ts-ignore: vtkjs incorrect typing\n activeCamera.setFreezeFocalPoint(true);\n\n // set voi for the first time\n const { windowCenter, windowWidth } = imagePixelModule;\n let voiRange =\n typeof windowCenter === 'number' && typeof windowWidth === 'number'\n ? windowLevelUtil.toLowHighRange(windowWidth, windowCenter)\n : undefined;\n\n // check if the image is already prescaled\n const isPreScaled =\n this.csImage.isPreScaled || this.csImage.preScale?.scaled;\n\n if (imagePixelModule.modality === 'PT' && isPreScaled) {\n voiRange = { lower: 0, upper: 5 };\n }\n\n this.initialVOIRange = voiRange;\n\n if (this.voiApplied && typeof voiRange === 'undefined') {\n // There are some cases when different frames within the same multi-frame\n // file are not hitting the actor cache because above\n // this.__checkVTKImageDataMatchesCornerstoneImage() call results in\n // \"false\".\n // In that case we want to keep the applied VOI range.\n voiRange = this.voiRange;\n }\n this.setProperties({ voiRange });\n\n // At the moment it appears that vtkImageSlice actors do not automatically\n // have an RGB Transfer Function created, so we need to create one.\n // Note: the 1024 here is what VTK would normally do to resample a color transfer function\n // before it is put into the GPU. Setting it with a length of 1024 allows us to\n // avoid that resampling step.\n const cfun = vtkColorTransferFunction.newInstance();\n let lower = 0;\n let upper = 1024;\n if (\n voiRange &&\n voiRange.lower !== undefined &&\n voiRange.upper !== undefined\n ) {\n lower = voiRange.lower;\n upper = voiRange.upper;\n }\n cfun.addRGBPoint(lower, 0.0, 0.0, 0.0);\n cfun.addRGBPoint(upper, 1.0, 1.0, 1.0);\n actor.getProperty().setRGBTransferFunction(0, cfun);\n\n // Saving position of camera on render, to cache the panning\n const { focalPoint } = this.getCamera();\n this.cameraFocalPointOnRender = focalPoint;\n this.stackInvalidated = false;\n\n if (this._publishCalibratedEvent) {\n this.triggerCalibrationEvent();\n }\n }\n\n /**\n * Loads the image based on the provided imageIdIndex\n * @param imageIdIndex - number represents imageId index\n */\n private async _setImageIdIndex(imageIdIndex: number): Promise<string> {\n if (imageIdIndex >= this.imageIds.length) {\n throw new Error(\n `ImageIdIndex provided ${imageIdIndex} is invalid, the stack only has ${this.imageIds.length} elements`\n );\n }\n\n // Update the state of the viewport to the new imageIdIndex;\n this.currentImageIdIndex = imageIdIndex;\n this.hasPixelSpacing = true;\n\n // Todo: trigger an event to allow applications to hook into START of loading state\n // Currently we use loadHandlerManagers for this\n const imageId = await this._loadAndDisplayImage(\n this.imageIds[imageIdIndex],\n imageIdIndex\n );\n\n return imageId;\n }\n\n /**\n * Centers Pan and resets the zoom for stack viewport.\n */\n public resetCamera(resetPan = true, resetZoom = true): boolean {\n if (this.useCPURendering) {\n this.resetCameraCPU(resetPan, resetZoom);\n } else {\n this.resetCameraGPU(resetPan, resetZoom);\n }\n\n this.rotation = 0;\n this.rotationCache = 0;\n return true;\n }\n\n private resetCameraCPU(resetPan, resetZoom) {\n const { image } = this._cpuFallbackEnabledElement;\n\n if (!image) {\n return;\n }\n\n resetCamera(this._cpuFallbackEnabledElement, resetPan, resetZoom);\n\n const { scale } = this._cpuFallbackEnabledElement.viewport;\n\n // canvas center is the focal point\n const { clientWidth, clientHeight } = this.element;\n const center: Point2 = [clientWidth / 2, clientHeight / 2];\n\n const centerWorld = this.canvasToWorldCPU(center);\n\n this.setCameraCPU({\n focalPoint: centerWorld,\n scale,\n });\n }\n\n private resetCameraGPU(resetPan, resetZoom): boolean {\n // Todo: we need to make the rotation a camera properties so that\n // we can reset it there, right now it is not possible to reset the rotation\n // without this\n this.getVtkActiveCamera().roll(this.rotationCache);\n\n // For stack Viewport we since we have only one slice\n // it should be enough to reset the camera to the center of the image\n const resetToCenter = true;\n return super.resetCamera(resetPan, resetZoom, resetToCenter);\n }\n\n /**\n * It scrolls the stack of imageIds by the delta amount provided. If the debounce\n * flag is set, it will only scroll the stack if the delta is greater than the\n * debounceThreshold which is 40 milliseconds by default.\n * @param delta - number of indices to scroll, it can be positive or negative\n * @param debounce - whether to debounce the scroll event\n * @param loop - whether to loop the stack\n */\n public scroll(delta: number, debounce = true, loop = false): void {\n const imageIds = this.imageIds;\n\n const currentTargetImageIdIndex = this.targetImageIdIndex;\n const numberOfFrames = imageIds.length;\n\n let newTargetImageIdIndex = currentTargetImageIdIndex + delta;\n newTargetImageIdIndex = Math.max(0, newTargetImageIdIndex);\n\n if (loop) {\n newTargetImageIdIndex = newTargetImageIdIndex % numberOfFrames;\n } else {\n newTargetImageIdIndex = Math.min(\n numberOfFrames - 1,\n newTargetImageIdIndex\n );\n }\n\n this.targetImageIdIndex = newTargetImageIdIndex;\n\n const targetImageId = imageIds[newTargetImageIdIndex];\n\n const imageAlreadyLoaded = cache.isImageIdCached(targetImageId);\n\n // If image is already cached we want to scroll right away; however, if it is\n // not cached, we can debounce the scroll event to avoid firing multiple scroll\n // events for the images that might happen to be passing by (as a result of infinite\n // scrolling).\n if (imageAlreadyLoaded || !debounce) {\n this.setImageIdIndex(newTargetImageIdIndex);\n } else {\n clearTimeout(this.debouncedTimeout);\n this.debouncedTimeout = window.setTimeout(() => {\n this.setImageIdIndex(newTargetImageIdIndex);\n }, 40);\n }\n\n const eventData: StackViewportScrollEventDetail = {\n newImageIdIndex: newTargetImageIdIndex,\n imageId: targetImageId,\n direction: delta,\n };\n\n if (newTargetImageIdIndex !== currentTargetImageIdIndex) {\n triggerEvent(this.element, Events.STACK_VIEWPORT_SCROLL, eventData);\n }\n }\n\n /**\n * Loads the image based on the provided imageIdIndex. It is an Async function which\n * returns a promise that resolves to the imageId.\n *\n * @param imageIdIndex - number represents imageId index in the list of\n * provided imageIds in setStack\n */\n public async setImageIdIndex(imageIdIndex: number): Promise<string> {\n // If we are already on this imageId index, stop here\n if (this.currentImageIdIndex === imageIdIndex) {\n return this.getCurrentImageId();\n }\n\n // Otherwise, get the imageId and attempt to display it\n const imageId = this._setImageIdIndex(imageIdIndex);\n\n return imageId;\n }\n\n /**\n * Calibrates the image with new metadata that has been added for imageId. To calibrate\n * a viewport, you should add your calibration data manually to\n * calibratedPixelSpacingMetadataProvider and call viewport.calibrateSpacing\n * for it get applied.\n *\n * @param imageId - imageId to be calibrated\n */\n public calibrateSpacing(imageId: string): void {\n const imageIdIndex = this.getImageIds().indexOf(imageId);\n this.stackInvalidated = true;\n this._loadAndDisplayImage(imageId, imageIdIndex);\n }\n\n /**\n * Restores the camera props such zooming and panning after an image is\n * changed, if needed (after scroll)\n *\n * @param parallelScale - camera parallel scale\n */\n private _restoreCameraProps(\n { parallelScale: prevScale }: ICamera,\n previousCamera: ICamera,\n panCache: Point3\n ): void {\n const renderer = this.getRenderer();\n\n // get the focalPoint and position after the reset\n const { position, focalPoint } = this.getCamera();\n\n const newPosition = vec3.subtract(vec3.create(), position, panCache);\n const newFocal = vec3.subtract(vec3.create(), focalPoint, panCache);\n\n // Restoring previous state x,y and scale, keeping the new z\n // we need to break the flip operations since they also work on the\n // camera position and focal point\n this.setCameraNoEvent({\n parallelScale: prevScale,\n position: newPosition as Point3,\n focalPoint: newFocal as Point3,\n });\n\n const camera = this.getCamera();\n\n this.triggerCameraEvent(camera, previousCamera);\n\n // Invoking render\n const RESET_CAMERA_EVENT = {\n type: 'ResetCameraEvent',\n renderer,\n };\n\n renderer.invokeEvent(RESET_CAMERA_EVENT);\n }\n\n private triggerCameraEvent(camera: ICamera, previousCamera: ICamera) {\n // Finally emit event for the full camera change cause during load image.\n const eventDetail: EventTypes.CameraModifiedEventDetail = {\n previousCamera,\n camera,\n element: this.element,\n viewportId: this.id,\n renderingEngineId: this.renderingEngineId,\n };\n\n if (!this.suppressEvents) {\n // For crosshairs to adapt to new viewport size\n triggerEvent(this.element, Events.CAMERA_MODIFIED, eventDetail);\n }\n }\n\n private triggerCalibrationEvent() {\n // Update the indexToWorld and WorldToIndex for viewport\n const { imageData } = this.getImageData();\n // Finally emit event for the full camera change cause during load image.\n const eventDetail: EventTypes.ImageSpacingCalibratedEventDetail = {\n element: this.element,\n viewportId: this.id,\n renderingEngineId: this.renderingEngineId,\n imageId: this.getCurrentImageId(),\n // Todo: why do we need to pass imageData? isn't' indexToWorld and worldToIndex enough?\n imageData: imageData as vtkImageData,\n worldToIndex: imageData.getWorldToIndex() as mat4,\n ...this._calibrationEvent,\n };\n\n if (!this.suppressEvents) {\n // Let the tools know the image spacing has been calibrated\n triggerEvent(this.element, Events.IMAGE_SPACING_CALIBRATED, eventDetail);\n }\n\n this._publishCalibratedEvent = false;\n }\n\n /**\n * canvasToWorld Returns the world coordinates of the given `canvasPos`\n * projected onto the plane defined by the `Viewport`'s camera.\n *\n * @param canvasPos - The position in canvas coordinates.\n * @returns The corresponding world coordinates.\n * @public\n */\n public canvasToWorld = (canvasPos: Point2): Point3 => {\n if (this.useCPURendering) {\n return this.canvasToWorldCPU(canvasPos);\n }\n\n return this.canvasToWorldGPU(canvasPos);\n };\n\n /**\n * Returns the canvas coordinates of the given `worldPos`\n * projected onto the `Viewport`'s `canvas`.\n *\n * @param worldPos - The position in world coordinates.\n * @returns The corresponding canvas coordinates.\n * @public\n */\n public worldToCanvas = (worldPos: Point3): Point2 => {\n if (this.useCPURendering) {\n return this.worldToCanvasCPU(worldPos);\n }\n\n return this.worldToCanvasGPU(worldPos);\n };\n\n private canvasToWorldCPU = (canvasPos: Point2): Point3 => {\n if (!this._cpuFallbackEnabledElement.image) {\n return;\n }\n // compute the pixel coordinate in the image\n const [px, py] = canvasToPixel(this._cpuFallbackEnabledElement, canvasPos);\n\n // convert pixel coordinate to world coordinate\n const { origin, spacing, direction } = this.getImageData();\n\n const worldPos = vec3.fromValues(0, 0, 0);\n\n // Calculate size of spacing vector in normal direction\n const iVector = direction.slice(0, 3) as Point3;\n const jVector = direction.slice(3, 6) as Point3;\n\n // Calculate the world coordinate of the pixel\n vec3.scaleAndAdd(worldPos, origin, iVector, px * spacing[0]);\n vec3.scaleAndAdd(worldPos, worldPos, jVector, py * spacing[1]);\n\n return worldPos as Point3;\n };\n\n private worldToCanvasCPU = (worldPos: Point3): Point2 => {\n // world to pixel\n const { spacing, direction, origin } = this.getImageData();\n\n const iVector = direction.slice(0, 3) as Point3;\n const jVector = direction.slice(3, 6) as Point3;\n\n const diff = vec3.subtract(vec3.create(), worldPos, origin);\n\n const worldPoint: Point2 = [\n vec3.dot(diff, iVector) / spacing[0],\n vec3.dot(diff, jVector) / spacing[1],\n ];\n\n // pixel to canvas\n const canvasPoint = pixelToCanvas(\n this._cpuFallbackEnabledElement,\n worldPoint\n );\n return canvasPoint;\n };\n\n private canvasToWorldGPU = (canvasPos: Point2): Point3 => {\n const renderer = this.getRenderer();\n\n // Temporary setting the clipping range to the distance and distance + 0.1\n // in order to calculate the transformations correctly.\n // This is similar to the vtkSlabCamera isPerformingCoordinateTransformations\n // You can read more about it here there.\n const vtkCamera = this.getVtkActiveCamera();\n const crange = vtkCamera.getClippingRange();\n const distance = vtkCamera.getDistance();\n\n vtkCamera.setClippingRange(distance, distance + 0.1);\n\n const offscreenMultiRenderWindow =\n this.getRenderingEngine().offscreenMultiRenderWindow;\n const openGLRenderWindow =\n offscreenMultiRenderWindow.getOpenGLRenderWindow();\n const size = openGLRenderWindow.getSize();\n\n const devicePixelRatio = window.devicePixelRatio || 1;\n const canvasPosWithDPR = [\n canvasPos[0] * devicePixelRatio,\n canvasPos[1] * devicePixelRatio,\n ];\n const displayCoord = [\n canvasPosWithDPR[0] + this.sx,\n canvasPosWithDPR[1] + this.sy,\n ];\n\n // The y axis display coordinates are inverted with respect to canvas coords\n displayCoord[1] = size[1] - displayCoord[1];\n\n const worldCoord = openGLRenderWindow.displayToWorld(\n displayCoord[0],\n displayCoord[1],\n 0,\n renderer\n );\n\n // set clipping range back to original to be able\n vtkCamera.setClippingRange(crange[0], crange[1]);\n\n return [worldCoord[0], worldCoord[1], worldCoord[2]];\n };\n\n private worldToCanvasGPU = (worldPos: Point3) => {\n const renderer = this.getRenderer();\n\n // Temporary setting the clipping range to the distance and distance + 0.1\n // in order to calculate the transformations correctly.\n // This is similar to the vtkSlabCamera isPerformingCoordinateTransformations\n // You can read more about it here there.\n const vtkCamera = this.getVtkActiveCamera();\n const crange = vtkCamera.getClippingRange();\n const distance = vtkCamera.getDistance();\n\n vtkCamera.setClippingRange(distance, distance + 0.1);\n\n const offscreenMultiRenderWindow =\n this.getRenderingEngine().offscreenMultiRenderWindow;\n const openGLRenderWindow =\n offscreenMultiRenderWindow.getOpenGLRenderWindow();\n const size = openGLRenderWindow.getSize();\n const displayCoord = openGLRenderWindow.worldToDisplay(\n ...worldPos,\n renderer\n );\n\n // The y axis display coordinates are inverted with respect to canvas coords\n displayCoord[1] = size[1] - displayCoord[1];\n\n const canvasCoord = <Point2>[\n displayCoord[0] - this.sx,\n displayCoord[1] - this.sy,\n ];\n\n // set clipping range back to original to be able\n vtkCamera.setClippingRange(crange[0], crange[1]);\n\n const devicePixelRatio = window.devicePixelRatio || 1;\n const canvasCoordWithDPR = <Point2>[\n canvasCoord[0] / devicePixelRatio,\n canvasCoord[1] / devicePixelRatio,\n ];\n\n return canvasCoordWithDPR;\n };\n\n /**\n * Returns the index of the imageId being renderer\n *\n * @returns currently shown imageId index\n */\n public getCurrentImageIdIndex = (): number => {\n return this.currentImageIdIndex;\n };\n\n /**\n *\n * Returns the imageIdIndex that is targeted to be loaded, in case of debounced\n * loading (with scroll), the targetImageIdIndex is the latest imageId\n * index that is requested to be loaded but debounced.\n */\n public getTargetImageIdIndex = (): number => {\n return this.targetImageIdIndex;\n };\n\n /**\n * Returns the list of image Ids for the current viewport\n * @returns list of strings for image Ids\n */\n public getImageIds = (): Array<string> => {\n return this.imageIds;\n };\n\n /**\n * Returns the currently rendered imageId\n * @returns string for imageId\n */\n public getCurrentImageId = (): string => {\n return this.imageIds[this.currentImageIdIndex];\n };\n\n /**\n * Returns true if the viewport contains the given imageId\n * @param imageId - imageId\n * @returns boolean if imageId is in viewport\n */\n public hasImageId = (imageId: string): boolean => {\n return this.imageIds.includes(imageId);\n };\n\n /**\n * Returns true if the viewport contains the given imageURI (no data loader scheme)\n * @param imageURI - imageURI\n * @returns boolean if imageURI is in viewport\n */\n public hasImageURI = (imageURI: string): boolean => {\n const imageIds = this.imageIds;\n for (let i = 0; i < imageIds.length; i++) {\n if (imageIdToURI(imageIds[i]) === imageURI) return true;\n }\n\n return false;\n };\n\n /**\n * If the renderer is CPU based, throw an error. Otherwise, returns the `vtkRenderer` responsible for rendering the `Viewport`.\n *\n * @returns The `vtkRenderer` for the `Viewport`.\n */\n public getRenderer() {\n if (this.useCPURendering) {\n throw this.getCPUFallbackError('getRenderer');\n }\n\n return super.getRenderer();\n }\n\n /**\n * If the renderer is CPU based, throw an error. Otherwise, return the default\n * actor which is the first actor in the renderer.\n * @returns An actor entry.\n */\n public getDefaultActor(): ActorEntry {\n if (this.useCPURendering) {\n throw this.getCPUFallbackError('getDefaultActor');\n }\n\n return super.getDefaultActor();\n }\n\n /**\n * If the renderer is CPU based, throw an error. Otherwise, return the actors in the viewport\n * @returns An array of ActorEntry objects.\n */\n public getActors(): Array<ActorEntry> {\n if (this.useCPURendering) {\n throw this.getCPUFallbackError('getActors');\n }\n\n return super.getActors();\n }\n\n /**\n * If the renderer is CPU based, throw an error. Otherwise, it returns the actor entry for the given actor UID.\n * @param actorUID - The unique ID of the actor you want to get.\n * @returns An ActorEntry object.\n */\n public getActor(actorUID: string): ActorEntry {\n if (this.useCPURendering) {\n throw this.getCPUFallbackError('getActor');\n }\n\n return super.getActor(actorUID);\n }\n\n /**\n * If the renderer is CPU-based, throw an error; otherwise, set the\n * actors in the viewport.\n * @param actors - An array of ActorEntry objects.\n */\n public setActors(actors: Array<ActorEntry>): void {\n if (this.useCPURendering) {\n throw this.getCPUFallbackError('setActors');\n }\n\n return super.setActors(actors);\n }\n\n /**\n * If the renderer is CPU based, throw an error. Otherwise, add a list of actors to the viewport\n * @param actors - An array of ActorEntry objects.\n */\n public addActors(actors: Array<ActorEntry>): void {\n if (this.useCPURendering) {\n throw this.getCPUFallbackError('addActors');\n }\n\n return super.addActors(actors);\n }\n\n /**\n * If the renderer is CPU based, throw an error. Otherwise, add the\n * actor to the viewport\n * @param actorEntry - The ActorEntry object that was created by the\n * user.\n */\n public addActor(actorEntry: ActorEntry): void {\n if (this.useCPURendering) {\n throw this.getCPUFallbackError('addActor');\n }\n\n return super.addActor(actorEntry);\n }\n\n /**\n * It throws an error if the renderer is CPU based. Otherwise, it removes the actors from the viewport.\n */\n public removeAllActors(): void {\n if (this.useCPURendering) {\n throw this.getCPUFallbackError('removeAllActors');\n }\n\n return super.removeAllActors();\n }\n\n private getCPUFallbackError(method: string): Error {\n return new Error(\n `method ${method} cannot be used during CPU Fallback mode`\n );\n }\n\n private fillWithBackgroundColor() {\n const renderingEngine = this.getRenderingEngine();\n\n if (renderingEngine) {\n renderingEngine.fillCanvasWithBackgroundColor(\n this.canvas,\n this.options.background\n );\n }\n }\n\n public customRenderViewportToCanvas = () => {\n if (!this.useCPURendering) {\n throw new Error(\n 'Custom cpu rendering pipeline should only be hit in CPU rendering mode'\n );\n }\n\n if (this._cpuFallbackEnabledElement.image) {\n drawImageSync(\n this._cpuFallbackEnabledElement,\n this.cpuRenderingInvalidated\n );\n // reset flags\n this.cpuRenderingInvalidated = false;\n } else {\n this.fillWithBackgroundColor();\n }\n\n return {\n canvas: this.canvas,\n element: this.element,\n viewportId: this.id,\n renderingEngineId: this.renderingEngineId,\n };\n };\n\n /**\n * Sets the colormap for the current viewport.\n * @param colormap - The colormap data to use.\n */\n public setColormap(colormap: CPUFallbackColormapData): void {\n if (this.useCPURendering) {\n this.setColormapCPU(colormap);\n } else {\n this.setColormapGPU(colormap);\n }\n }\n\n /**\n * It sets the colormap to the default colormap.\n */\n public unsetColormap(): void {\n if (this.useCPURendering) {\n this.unsetColormapCPU();\n } else {\n this.unsetColormapGPU();\n }\n }\n\n private unsetColormapCPU() {\n delete this._cpuFallbackEnabledElement.viewport.colormap;\n this._cpuFallbackEnabledElement.renderingTools = {};\n\n this.cpuRenderingInvalidated = true;\n\n this.fillWithBackgroundColor();\n\n this.render();\n }\n\n private setColormapCPU(colormapData: CPUFallbackColormapData) {\n const colormap = getColormap(colormapData.name, colormapData);\n\n this._cpuFallbackEnabledElement.viewport.colormap = colormap;\n this._cpuFallbackEnabledElement.renderingTools = {};\n\n this.fillWithBackgroundColor();\n this.cpuRenderingInvalidated = true;\n\n this.render();\n }\n\n private setColormapGPU(colormap: CPUFallbackColormapData) {\n // TODO -> vtk has full colormaps which are piecewise and frankly better?\n // Do we really want a pre defined 256 color map just for the sake of harmonization?\n throw new Error('setColorMapGPU not implemented.');\n }\n\n private unsetColormapGPU() {\n // TODO -> vtk has full colormaps which are piecewise and frankly better?\n // Do we really want a pre defined 256 color map just for the sake of harmonization?\n throw new Error('unsetColormapGPU not implemented.');\n }\n\n // create default values for imagePlaneModule if values are undefined\n private _getImagePlaneModule(imageId: string): ImagePlaneModule {\n const imagePlaneModule = metaData.get('imagePlaneModule', imageId);\n\n const newImagePlaneModule: ImagePlaneModule = {\n ...imagePlaneModule,\n };\n\n if (!newImagePlaneModule.columnPixelSpacing) {\n newImagePlaneModule.columnPixelSpacing = 1;\n this.hasPixelSpacing = false;\n }\n\n if (!newImagePlaneModule.rowPixelSpacing) {\n newImagePlaneModule.rowPixelSpacing = 1;\n this.hasPixelSpacing = false;\n }\n\n if (!newImagePlaneModule.columnCosines) {\n newImagePlaneModule.columnCosines = [0, 1, 0];\n }\n\n if (!newImagePlaneModule.rowCosines) {\n newImagePlaneModule.rowCosines = [1, 0, 0];\n }\n\n if (!newImagePlaneModule.imagePositionPatient) {\n newImagePlaneModule.imagePositionPatient = [0, 0, 0];\n }\n\n if (!newImagePlaneModule.imageOrientationPatient) {\n newImagePlaneModule.imageOrientationPatient = new Float32Array([\n 1, 0, 0, 0, 1, 0,\n ]);\n }\n\n return newImagePlaneModule;\n }\n}\n\nexport default StackViewport;\n","import { CPUFallbackViewport, Point2 } from '../../../../types';\n\ntype Shift = {\n x: number;\n y: number;\n};\n/**\n * Corrects the shift by accounting for viewport rotation and flips.\n *\n * @param shift - The shift to correct.\n * @param viewportOrientation - Object containing information on the viewport orientation.\n */\nexport default function (\n shift: Shift,\n viewportOrientation: CPUFallbackViewport\n): Shift {\n const { hflip, vflip, rotation } = viewportOrientation;\n\n // Apply Flips\n shift.x *= hflip ? -1 : 1;\n shift.y *= vflip ? -1 : 1;\n\n // Apply rotations\n if (rotation !== 0) {\n const angle = (rotation * Math.PI) / 180;\n\n const cosA = Math.cos(angle);\n const sinA = Math.sin(angle);\n\n const newX = shift.x * cosA - shift.y * sinA;\n const newY = shift.x * sinA + shift.y * cosA;\n\n shift.x = newX;\n shift.y = newY;\n }\n\n return shift;\n}\n","export default (src, dest) => src.length * 3 === dest.byteLength * 4;\n","import getImageFitScale from './getImageFitScale';\nimport { CPUFallbackEnabledElement } from '../../../../types';\n\n/**\n * Resets the camera to the default position. which would be the center of the image.\n * with no translation, no flipping, no zoom and proper scale.\n */\nexport default function (\n enabledElement: CPUFallbackEnabledElement,\n resetPan = true,\n resetZoom = true\n): void {\n const { canvas, image, viewport } = enabledElement;\n const scale = getImageFitScale(canvas, image, 0).scaleFactor;\n\n viewport.vflip = false;\n viewport.hflip = false;\n\n if (resetPan) {\n viewport.translation.x = 0;\n viewport.translation.y = 0;\n }\n\n if (resetZoom) {\n viewport.displayedArea.tlhc.x = 1;\n viewport.displayedArea.tlhc.y = 1;\n viewport.displayedArea.brhc.x = image.columns;\n viewport.displayedArea.brhc.y = image.rows;\n\n viewport.scale = scale;\n }\n}\n","import BaseVolumeViewport from './BaseVolumeViewport';\nimport { RENDERING_DEFAULTS } from '../constants';\n\n/**\n * An object representing a 3-dimensional volume viewport. VolumeViewport3Ds are used to render\n * 3D volumes in their entirety, and not just load a single slice at a time.\n *\n * For setting volumes on viewports you need to use {@link addVolumesToViewports}\n * which will add volumes to the specified viewports.\n */\nclass VolumeViewport3D extends BaseVolumeViewport {\n public resetCamera(\n resetPan = true,\n resetZoom = true,\n resetToCenter = true\n ): boolean {\n super.resetCamera(resetPan, resetZoom, resetToCenter);\n const activeCamera = this.getVtkActiveCamera();\n // Set large numbers to ensure everything is always rendered\n if (activeCamera.getParallelProjection()) {\n activeCamera.setClippingRange(\n -RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE,\n RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE\n );\n } else {\n activeCamera.setClippingRange(\n RENDERING_DEFAULTS.MINIMUM_SLAB_THICKNESS,\n RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE\n );\n }\n\n return;\n }\n}\n\nexport default VolumeViewport3D;\n","// TODO -> Eventually we'll need to register to this list\nimport StackViewport from '../StackViewport';\nimport VolumeViewport from '../VolumeViewport';\nimport ViewportType from '../../enums/ViewportType';\nimport VolumeViewport3D from '../VolumeViewport3D';\n\nconst viewportTypeToViewportClass = {\n [ViewportType.ORTHOGRAPHIC]: VolumeViewport,\n [ViewportType.PERSPECTIVE]: VolumeViewport,\n [ViewportType.STACK]: StackViewport,\n [ViewportType.VOLUME_3D]: VolumeViewport3D,\n};\n\nexport default viewportTypeToViewportClass;\n","import viewportTypeToViewportClass from './viewportTypeToViewportClass';\n\nexport default function viewportTypeUsesCustomRenderingPipeline(\n viewportType: string\n) {\n return viewportTypeToViewportClass[viewportType].useCustomRenderingPipeline;\n}\n","import Events from '../enums/Events';\nimport renderingEngineCache from './renderingEngineCache';\nimport eventTarget from '../eventTarget';\nimport { triggerEvent, uuidv4 } from '../utilities';\nimport { vtkOffscreenMultiRenderWindow } from './vtkClasses';\nimport ViewportType from '../enums/ViewportType';\nimport VolumeViewport from './VolumeViewport';\nimport BaseVolumeViewport from './BaseVolumeViewport';\nimport StackViewport from './StackViewport';\nimport viewportTypeUsesCustomRenderingPipeline from './helpers/viewportTypeUsesCustomRenderingPipeline';\nimport getOrCreateCanvas from './helpers/getOrCreateCanvas';\nimport { getShouldUseCPURendering, isCornerstoneInitialized } from '../init';\nimport type IStackViewport from '../types/IStackViewport';\nimport type IRenderingEngine from '../types/IRenderingEngine';\nimport type IVolumeViewport from '../types/IVolumeViewport';\nimport type * as EventTypes from '../types/EventTypes';\nimport type {\n ViewportInput,\n PublicViewportInput,\n InternalViewportInput,\n NormalizedViewportInput,\n} from '../types/IViewport';\nimport { OrientationAxis } from '../enums';\nimport VolumeViewport3D from './VolumeViewport3D';\n\ntype ViewportDisplayCoords = {\n sxStartDisplayCoords: number;\n syStartDisplayCoords: number;\n sxEndDisplayCoords: number;\n syEndDisplayCoords: number;\n sx: number;\n sy: number;\n sWidth: number;\n sHeight: number;\n};\n\n/**\n * A RenderingEngine takes care of the full pipeline of creating viewports and rendering\n * them on a large offscreen canvas and transmitting this data back to the screen. This allows us\n * to leverage the power of vtk.js whilst only using one WebGL context for the processing, and allowing\n * us to share texture memory across on-screen viewports that show the same data.\n *\n * Instantiating a rendering engine:\n * ```js\n * const renderingEngine = new RenderingEngine('pet-ct-rendering-engine');\n * ```\n *\n * There are various ways you can trigger a render on viewports. The simplest is to call `render()`\n * on the rendering engine; however, it will trigger a render on all viewports. A more efficient\n * way to do this is to call `renderViewports([viewportId])` on the rendering engine to\n * trigger a render on a specific viewport(s). Each viewport also has a `.render` method which can be used to trigger a render on that\n * viewport.\n *\n * Rendering engine uses `detect-gpu` external library to detect if GPU is available and\n * it has minimum requirement to be able to render a volume with vtk.js. If GPU is not available\n * RenderingEngine will throw an error if you try to render a volume; however, for StackViewports\n * it is capable of falling back to CPU rendering for Stack images.\n *\n * By default RenderingEngine will use vtk.js enabled pipeline for rendering viewports,\n * however, if a custom rendering pipeline is specified by a custom viewport, it will be used instead.\n * We use this custom pipeline to render a StackViewport on CPU using Cornerstone-legacy cpu rendering pipeline.\n *\n * @public\n */\nclass RenderingEngine implements IRenderingEngine {\n /** Unique identifier for renderingEngine */\n readonly id: string;\n /** A flag which tells if the renderingEngine has been destroyed */\n public hasBeenDestroyed: boolean;\n public offscreenMultiRenderWindow: any;\n readonly offScreenCanvasContainer: any; // WebGL\n private _viewports: Map<string, IStackViewport | IVolumeViewport>;\n private _needsRender: Set<string> = new Set();\n private _animationFrameSet = false;\n private _animationFrameHandle: number | null = null;\n private useCPURendering: boolean;\n\n /**\n * @param uid - Unique identifier for RenderingEngine\n */\n constructor(id?: string) {\n this.id = id ? id : uuidv4();\n this.useCPURendering = getShouldUseCPURendering();\n\n renderingEngineCache.set(this);\n\n if (!isCornerstoneInitialized()) {\n throw new Error(\n '@cornerstonejs/core is not initialized, run init() first'\n );\n }\n\n if (!this.useCPURendering) {\n this.offscreenMultiRenderWindow =\n vtkOffscreenMultiRenderWindow.newInstance();\n this.offScreenCanvasContainer = document.createElement('div');\n this.offscreenMultiRenderWindow.setContainer(\n this.offScreenCanvasContainer\n );\n }\n\n this._viewports = new Map();\n this.hasBeenDestroyed = false;\n }\n\n /**\n * Enables the requested viewport and add it to the viewports. It will\n * properly create the Stack viewport or Volume viewport:\n *\n * 1) Checks if the viewport is defined already, if yes, remove it first\n * 2) Checks if the viewport is using a custom rendering pipeline, if no,\n * it calculates a new offscreen canvas with the new requested viewport\n * 3) Adds the viewport\n *\n *\n * ```typescript\n * renderingEngine.enableElement({\n * viewportId: viewportId,\n * type: ViewportType.ORTHOGRAPHIC,\n * element,\n * defaultOptions: {\n * orientation: Enums.OrientationAxis.AXIAL,\n * background: [1, 0, 1],\n * },\n * })\n * ```\n *\n * @fires Events.ELEMENT_ENABLED\n *\n * @param viewportInputEntry - viewport specifications\n */\n public enableElement(viewportInputEntry: PublicViewportInput): void {\n const viewportInput = this._normalizeViewportInputEntry(viewportInputEntry);\n\n this._throwIfDestroyed();\n const { element, viewportId } = viewportInput;\n\n // Throw error if no canvas\n if (!element) {\n throw new Error('No element provided');\n }\n\n // 1. Get the viewport from the list of available viewports.\n const viewport = this.getViewport(viewportId);\n\n // 1.a) If there is a found viewport, we remove the viewport and create a new viewport\n if (viewport) {\n this.disableElement(viewportId);\n // todo: if only removing the viewport, make sure resize also happens\n // this._removeViewport(viewportId)\n }\n\n // 2.a) See if viewport uses a custom rendering pipeline.\n const { type } = viewportInput;\n\n const viewportUsesCustomRenderingPipeline =\n viewportTypeUsesCustomRenderingPipeline(type);\n\n // 2.b) Retrieving the list of viewports for calculation of the new size for\n // offScreen canvas.\n\n // If the viewport being added uses a custom pipeline, or we aren't using\n // GPU rendering, we don't need to resize the offscreen canvas.\n if (!this.useCPURendering && !viewportUsesCustomRenderingPipeline) {\n this.enableVTKjsDrivenViewport(viewportInput);\n } else {\n // 3 Add the requested viewport to rendering Engine\n this.addCustomViewport(viewportInput);\n }\n\n // 5. Set the background color for the canvas\n const canvas = getOrCreateCanvas(element);\n const { background } = viewportInput.defaultOptions;\n this.fillCanvasWithBackgroundColor(canvas, background);\n }\n\n /**\n * Disables the requested viewportId from the rendering engine:\n *\n * 1) It removes the viewport from the the list of viewports\n * 2) remove the renderer from the offScreen render window if using vtk.js driven\n * rendering pipeline\n * 3) resetting the viewport to remove the canvas attributes and canvas data\n * 4) resize the offScreen appropriately (if using vtk.js driven rendering pipeline)\n *\n * @fires Events.ELEMENT_ENABLED\n *\n * @param viewportId - viewport Id\n *\n */\n public disableElement(viewportId: string): void {\n this._throwIfDestroyed();\n // 1. Getting the viewport to remove it\n const viewport = this.getViewport(viewportId);\n\n // 2 To throw if there is no viewport stored in rendering engine\n if (!viewport) {\n console.warn(`viewport ${viewportId} does not exist`);\n return;\n }\n\n // 3. Reset the viewport to remove attributes, and reset the canvas\n this._resetViewport(viewport);\n\n // 4. Remove the related renderer from the offScreenMultiRenderWindow\n if (\n !viewportTypeUsesCustomRenderingPipeline(viewport.type) &&\n !this.useCPURendering\n ) {\n this.offscreenMultiRenderWindow.removeRenderer(viewportId);\n }\n\n // 5. Remove the requested viewport from the rendering engine\n this._removeViewport(viewportId);\n viewport.isDisabled = true;\n\n // 6. Avoid rendering for the disabled viewport\n this._needsRender.delete(viewportId);\n\n // 7. Clear RAF if no viewport is left\n const viewports = this.getViewports();\n if (!viewports.length) {\n this._clearAnimationFrame();\n }\n\n // 8. Resize the offScreen canvas to accommodate for the new size (after removal)\n // Note: Resize should not reset pan and zoom when disabling an element.\n // This is because we are only resizing the offscreen canvas to deal with the element\n // which was removed, and do not wish to alter the current state of any other currently enabled element\n const immediate = true;\n const keepCamera = true;\n this.resize(immediate, keepCamera);\n }\n\n /**\n * It takes an array of viewport input objects including element, viewportId, type\n * and defaultOptions. It will add the viewport to the rendering engine and enables them.\n *\n *\n * ```typescript\n *renderingEngine.setViewports([\n * {\n * viewportId: axialViewportId,\n * type: ViewportType.ORTHOGRAPHIC,\n * element: document.getElementById('axialDiv'),\n * defaultOptions: {\n * orientation: Enums.OrientationAxis.AXIAL,\n * },\n * },\n * {\n * viewportId: sagittalViewportId,\n * type: ViewportType.ORTHOGRAPHIC,\n * element: document.getElementById('sagittalDiv'),\n * defaultOptions: {\n * orientation: Enums.OrientationAxis.SAGITTAL,\n * },\n * },\n * {\n * viewportId: customOrientationViewportId,\n * type: ViewportType.ORTHOGRAPHIC,\n * element: document.getElementById('customOrientationDiv'),\n * defaultOptions: {\n * orientation: { viewPlaneNormal: [0, 0, 1], viewUp: [0, 1, 0] },\n * },\n * },\n * ])\n * ```\n *\n * @fires Events.ELEMENT_ENABLED\n *\n * @param viewportInputEntries - Array<PublicViewportInput>\n */\n\n public setViewports(\n publicViewportInputEntries: Array<PublicViewportInput>\n ): void {\n const viewportInputEntries = this._normalizeViewportInputEntries(\n publicViewportInputEntries\n );\n this._throwIfDestroyed();\n this._reset();\n\n // 1. Split viewports based on whether they use vtk.js or a custom pipeline.\n\n const vtkDrivenViewportInputEntries: NormalizedViewportInput[] = [];\n const customRenderingViewportInputEntries: NormalizedViewportInput[] = [];\n\n viewportInputEntries.forEach((vpie) => {\n if (\n !this.useCPURendering &&\n !viewportTypeUsesCustomRenderingPipeline(vpie.type)\n ) {\n vtkDrivenViewportInputEntries.push(vpie);\n } else {\n customRenderingViewportInputEntries.push(vpie);\n }\n });\n\n this.setVtkjsDrivenViewports(vtkDrivenViewportInputEntries);\n this.setCustomViewports(customRenderingViewportInputEntries);\n }\n\n /**\n * Resizes the offscreen viewport and recalculates translations to on screen canvases.\n * It is up to the parent app to call the resize of the on-screen canvas changes.\n * This is left as an app level concern as one might want to debounce the changes, or the like.\n *\n * @param immediate - Whether all of the viewports should be rendered immediately.\n * @param keepCamera - Whether to keep the camera for other viewports while resizing the offscreen canvas\n */\n public resize(immediate = true, keepCamera = true): void {\n this._throwIfDestroyed();\n // 1. Get the viewports' canvases\n const viewports = this._getViewportsAsArray();\n\n const vtkDrivenViewports = [];\n const customRenderingViewports = [];\n\n viewports.forEach((vpie) => {\n if (!viewportTypeUsesCustomRenderingPipeline(vpie.type)) {\n vtkDrivenViewports.push(vpie);\n } else {\n customRenderingViewports.push(vpie);\n }\n });\n\n this._resizeVTKViewports(vtkDrivenViewports, keepCamera, immediate);\n\n this._resizeUsingCustomResizeHandler(\n customRenderingViewports,\n keepCamera,\n immediate\n );\n }\n\n /**\n * Returns the viewport by Id\n *\n * @returns viewport\n */\n public getViewport(viewportId: string): IStackViewport | IVolumeViewport {\n return this._viewports.get(viewportId);\n }\n\n /**\n * getViewports Returns an array of all `Viewport`s on the `RenderingEngine` instance.\n *\n * @returns Array of viewports\n */\n public getViewports(): Array<IStackViewport | IVolumeViewport> {\n this._throwIfDestroyed();\n\n return this._getViewportsAsArray();\n }\n\n /**\n * Filters all the available viewports and return the stack viewports\n * @returns stack viewports registered on the rendering Engine\n */\n public getStackViewports(): Array<IStackViewport> {\n this._throwIfDestroyed();\n\n const viewports = this.getViewports();\n\n const isStackViewport = (\n viewport: IStackViewport | IVolumeViewport\n ): viewport is StackViewport => {\n return viewport instanceof StackViewport;\n };\n\n return viewports.filter(isStackViewport);\n }\n\n /**\n * Return all the viewports that are volume viewports\n * @returns An array of VolumeViewport objects.\n */\n public getVolumeViewports(): Array<IVolumeViewport> {\n this._throwIfDestroyed();\n\n const viewports = this.getViewports();\n\n const isVolumeViewport = (\n viewport: IStackViewport | IVolumeViewport\n ): viewport is BaseVolumeViewport => {\n return viewport instanceof BaseVolumeViewport;\n };\n\n return viewports.filter(isVolumeViewport);\n }\n\n /**\n * Renders all viewports on the next animation frame.\n *\n * @fires Events.IMAGE_RENDERED\n */\n public render(): void {\n const viewports = this.getViewports();\n const viewportIds = viewports.map((vp) => vp.id);\n\n this._setViewportsToBeRenderedNextFrame(viewportIds);\n }\n\n /**\n * Renders any viewports viewing the given Frame Of Reference.\n *\n * @param FrameOfReferenceUID - The unique identifier of the\n * Frame Of Reference.\n */\n public renderFrameOfReference = (FrameOfReferenceUID: string): void => {\n const viewports = this._getViewportsAsArray();\n const viewportIdsWithSameFrameOfReferenceUID = viewports.map((vp) => {\n if (vp.getFrameOfReferenceUID() === FrameOfReferenceUID) {\n return vp.id;\n }\n });\n\n return this.renderViewports(viewportIdsWithSameFrameOfReferenceUID);\n };\n\n /**\n * Renders the provided Viewport IDs.\n *\n */\n public renderViewports(viewportIds: Array<string>): void {\n this._setViewportsToBeRenderedNextFrame(viewportIds);\n }\n\n /**\n * Renders only a specific `Viewport` on the next animation frame.\n *\n * @param viewportId - The Id of the viewport.\n */\n public renderViewport(viewportId: string): void {\n this._setViewportsToBeRenderedNextFrame([viewportId]);\n }\n\n /**\n * destroy the rendering engine. It will remove all the viewports and,\n * if the rendering engine is using the GPU, it will also destroy the GPU\n * resources.\n */\n public destroy(): void {\n if (this.hasBeenDestroyed) {\n return;\n }\n\n // remove vtk rendered first before resetting the viewport\n if (!this.useCPURendering) {\n const viewports = this._getViewportsAsArray();\n viewports.forEach((vp) => {\n this.offscreenMultiRenderWindow.removeRenderer(vp.id);\n });\n\n // Free up WebGL resources\n this.offscreenMultiRenderWindow.delete();\n\n // Make sure all references go stale and are garbage collected.\n delete this.offscreenMultiRenderWindow;\n }\n\n this._reset();\n renderingEngineCache.delete(this.id);\n\n this.hasBeenDestroyed = true;\n }\n\n /**\n * Fill the canvas with the background color\n * @param canvas - The canvas element to draw on.\n * @param backgroundColor - An array of three numbers between 0 and 1 that\n * specify the red, green, and blue values of the background color.\n */\n public fillCanvasWithBackgroundColor(\n canvas: HTMLCanvasElement,\n backgroundColor: [number, number, number]\n ): void {\n const ctx = canvas.getContext('2d');\n\n // Default to black if no background color is set\n let fillStyle;\n if (backgroundColor) {\n const rgb = backgroundColor.map((f) => Math.floor(255 * f));\n fillStyle = `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`;\n } else {\n fillStyle = 'black';\n }\n\n // We draw over the previous stack with the background color while we\n // wait for the next stack to load\n ctx.fillStyle = fillStyle;\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n }\n\n private _normalizeViewportInputEntry(\n viewportInputEntry: PublicViewportInput\n ) {\n const { type, defaultOptions } = viewportInputEntry;\n let options = defaultOptions;\n\n if (!options || Object.keys(options).length === 0) {\n options = {\n background: [0, 0, 0],\n orientation: null,\n };\n\n if (type === ViewportType.ORTHOGRAPHIC) {\n options = {\n ...options,\n orientation: OrientationAxis.AXIAL,\n };\n }\n }\n\n return {\n ...viewportInputEntry,\n defaultOptions: options,\n };\n }\n\n private _normalizeViewportInputEntries(\n viewportInputEntries: Array<PublicViewportInput>\n ): Array<NormalizedViewportInput> {\n const normalizedViewportInputs = [];\n\n viewportInputEntries.forEach((viewportInput) => {\n normalizedViewportInputs.push(\n this._normalizeViewportInputEntry(viewportInput)\n );\n });\n\n return normalizedViewportInputs;\n }\n\n private _resizeUsingCustomResizeHandler(\n customRenderingViewports: StackViewport[],\n keepCamera = true,\n immediate = true\n ) {\n // 1. If viewport has a custom resize method, call it here.\n customRenderingViewports.forEach((vp) => {\n if (typeof vp.resize === 'function') vp.resize();\n });\n\n // 3. Reset viewport cameras\n customRenderingViewports.forEach((vp) => {\n const prevCamera = vp.getCamera();\n vp.resetCamera();\n\n if (keepCamera) {\n vp.setCamera(prevCamera);\n }\n });\n\n // 2. If render is immediate: Render all\n if (immediate === true) {\n this.render();\n }\n }\n\n private _resizeVTKViewports(\n vtkDrivenViewports: Array<IStackViewport | IVolumeViewport>,\n keepCamera = true,\n immediate = true\n ) {\n const canvasesDrivenByVtkJs = vtkDrivenViewports.map((vp) => vp.canvas);\n\n if (canvasesDrivenByVtkJs.length) {\n // 1. Recalculate and resize the offscreen canvas size\n const { offScreenCanvasWidth, offScreenCanvasHeight } =\n this._resizeOffScreenCanvas(canvasesDrivenByVtkJs);\n\n // 2. Recalculate the viewports location on the off screen canvas\n this._resize(\n vtkDrivenViewports,\n offScreenCanvasWidth,\n offScreenCanvasHeight\n );\n }\n\n // 3. Reset viewport cameras\n vtkDrivenViewports.forEach((vp: IStackViewport | IVolumeViewport) => {\n const canvas = getOrCreateCanvas(vp.element);\n const rect = canvas.getBoundingClientRect();\n const devicePixelRatio = window.devicePixelRatio || 1;\n canvas.width = rect.width * devicePixelRatio;\n canvas.height = rect.height * devicePixelRatio;\n\n const prevCamera = vp.getCamera();\n vp.resetCamera();\n\n if (keepCamera) {\n vp.setCamera(prevCamera);\n }\n });\n\n // 4. If render is immediate: Render all\n if (immediate === true) {\n this.render();\n }\n }\n\n /**\n * Enables a viewport to be driven by the offscreen vtk.js rendering engine.\n *\n * @param viewportInputEntry - Information object used to\n * construct and enable the viewport.\n */\n private enableVTKjsDrivenViewport(\n viewportInputEntry: NormalizedViewportInput\n ) {\n const viewports = this._getViewportsAsArray();\n const viewportsDrivenByVtkJs = viewports.filter(\n (vp) => viewportTypeUsesCustomRenderingPipeline(vp.type) === false\n );\n\n const canvasesDrivenByVtkJs = viewportsDrivenByVtkJs.map((vp) => vp.canvas);\n\n const canvas = getOrCreateCanvas(viewportInputEntry.element);\n canvasesDrivenByVtkJs.push(canvas);\n\n const devicePixelRatio = window.devicePixelRatio || 1;\n\n const rect = canvas.getBoundingClientRect();\n canvas.width = rect.width * devicePixelRatio;\n canvas.height = rect.height * devicePixelRatio;\n\n // 2.c Calculating the new size for offScreen Canvas\n const { offScreenCanvasWidth, offScreenCanvasHeight } =\n this._resizeOffScreenCanvas(canvasesDrivenByVtkJs);\n\n // 2.d Re-position previous viewports on the offScreen Canvas based on the new\n // offScreen canvas size\n const xOffset = this._resize(\n viewportsDrivenByVtkJs,\n offScreenCanvasWidth,\n offScreenCanvasHeight\n );\n\n const internalViewportEntry = { ...viewportInputEntry, canvas };\n\n // 3 Add the requested viewport to rendering Engine\n this.addVtkjsDrivenViewport(internalViewportEntry, {\n offScreenCanvasWidth,\n offScreenCanvasHeight,\n xOffset,\n });\n }\n\n /**\n * Disables the requested viewportId from the rendering engine:\n * 1) It removes the viewport from the the list of viewports\n * 2) remove the renderer from the offScreen render window\n * 3) resetting the viewport to remove the canvas attributes and canvas data\n * 4) resize the offScreen appropriately\n *\n * @param viewportId - viewport Id\n *\n */\n private _removeViewport(viewportId: string): void {\n // 1. Get the viewport\n const viewport = this.getViewport(viewportId);\n if (!viewport) {\n console.warn(`viewport ${viewportId} does not exist`);\n return;\n }\n\n // 2. Delete the viewports from the the viewports\n this._viewports.delete(viewportId);\n }\n\n /**\n * Adds a viewport driven by vtk.js to the `RenderingEngine`.\n *\n * @param viewportInputEntry - Information object used to construct and enable the viewport.\n * @param options - Options object used to configure the viewport.\n * @param options.offScreenCanvasWidth - The width of the offscreen canvas.\n * @param options.offScreenCanvasHeight - The height of the offscreen canvas.\n * @param options.xOffset - The x offset of the viewport on the offscreen canvas.\n */\n private addVtkjsDrivenViewport(\n viewportInputEntry: InternalViewportInput,\n offscreenCanvasProperties?: {\n offScreenCanvasWidth: number;\n offScreenCanvasHeight: number;\n xOffset: number;\n }\n ): void {\n const { element, canvas, viewportId, type, defaultOptions } =\n viewportInputEntry;\n\n // Make the element not focusable, we use this for modifier keys to work\n element.tabIndex = -1;\n\n const { offScreenCanvasWidth, offScreenCanvasHeight, xOffset } =\n offscreenCanvasProperties;\n\n // 1. Calculate the size of location of the viewport on the offScreen canvas\n const {\n sxStartDisplayCoords,\n syStartDisplayCoords,\n sxEndDisplayCoords,\n syEndDisplayCoords,\n sx,\n sy,\n sWidth,\n sHeight,\n } = this._getViewportCoordsOnOffScreenCanvas(\n viewportInputEntry,\n offScreenCanvasWidth,\n offScreenCanvasHeight,\n xOffset\n );\n\n // 2. Add a renderer to the offScreenMultiRenderWindow\n this.offscreenMultiRenderWindow.addRenderer({\n viewport: [\n sxStartDisplayCoords,\n syStartDisplayCoords,\n sxEndDisplayCoords,\n syEndDisplayCoords,\n ],\n id: viewportId,\n background: defaultOptions.background\n ? defaultOptions.background\n : [0, 0, 0],\n });\n\n // 3. ViewportInput to be passed to a stack/volume viewport\n const viewportInput = <ViewportInput>{\n id: viewportId,\n element, // div\n renderingEngineId: this.id,\n type,\n canvas,\n sx,\n sy,\n sWidth,\n sHeight,\n defaultOptions: defaultOptions || {},\n };\n\n // 4. Create a proper viewport based on the type of the viewport\n let viewport;\n if (type === ViewportType.STACK) {\n // 4.a Create stack viewport\n viewport = new StackViewport(viewportInput);\n } else if (\n type === ViewportType.ORTHOGRAPHIC ||\n type === ViewportType.PERSPECTIVE\n ) {\n // 4.b Create a volume viewport\n viewport = new VolumeViewport(viewportInput);\n } else if (type === ViewportType.VOLUME_3D) {\n viewport = new VolumeViewport3D(viewportInput);\n } else {\n throw new Error(`Viewport Type ${type} is not supported`);\n }\n\n // 5. Storing the viewports\n this._viewports.set(viewportId, viewport);\n\n const eventDetail: EventTypes.ElementEnabledEventDetail = {\n element,\n viewportId,\n renderingEngineId: this.id,\n };\n\n if (!viewport.suppressEvents) {\n triggerEvent(eventTarget, Events.ELEMENT_ENABLED, eventDetail);\n }\n }\n\n /**\n * Adds a viewport using a custom rendering pipeline to the `RenderingEngine`.\n *\n * @param viewportInputEntry - Information object used to\n * construct and enable the viewport.\n */\n private addCustomViewport(viewportInputEntry: PublicViewportInput): void {\n const { element, viewportId, type, defaultOptions } = viewportInputEntry;\n\n // Make the element not focusable, we use this for modifier keys to work\n element.tabIndex = -1;\n\n const canvas = getOrCreateCanvas(element);\n\n // Add a viewport with no offset\n const { clientWidth, clientHeight } = canvas;\n\n // Set the canvas to be same resolution as the client.\n // Note: This ignores devicePixelRatio for now. We may want to change it in the\n // future but it has no benefit for the Cornerstone CPU rendering pathway at the\n // moment anyway.\n if (canvas.width !== clientWidth || canvas.height !== clientHeight) {\n canvas.width = clientWidth;\n canvas.height = clientHeight;\n }\n\n const viewportInput = <ViewportInput>{\n id: viewportId,\n renderingEngineId: this.id,\n element, // div\n type,\n canvas,\n sx: 0, // No offset, uses own renderer\n sy: 0,\n sWidth: clientWidth,\n sHeight: clientHeight,\n defaultOptions: defaultOptions || {},\n };\n\n // 4. Create a proper viewport based on the type of the viewport\n\n if (type !== ViewportType.STACK) {\n // In the future these will need to be pluggable, but we aren't there yet\n // and these are just Stacks for now.\n throw new Error('Support for fully custom viewports not yet implemented');\n }\n\n // 4.a Create stack viewport\n const viewport = new StackViewport(viewportInput);\n\n // 5. Storing the viewports\n this._viewports.set(viewportId, viewport);\n\n const eventDetail: EventTypes.ElementEnabledEventDetail = {\n element,\n viewportId,\n renderingEngineId: this.id,\n };\n\n triggerEvent(eventTarget, Events.ELEMENT_ENABLED, eventDetail);\n }\n\n /**\n * Sets multiple viewports using custom rendering\n * pipelines to the `RenderingEngine`.\n *\n * @param viewportInputEntries - An array of information\n * objects used to construct and enable the viewports.\n */\n private setCustomViewports(viewportInputEntries: PublicViewportInput[]) {\n viewportInputEntries.forEach((vpie) => this.addCustomViewport(vpie));\n }\n\n /**\n * Sets multiple vtk.js driven viewports to\n * the `RenderingEngine`.\n *\n * @param viewportInputEntries - An array of information\n * objects used to construct and enable the viewports.\n */\n private setVtkjsDrivenViewports(\n viewportInputEntries: NormalizedViewportInput[]\n ) {\n // Deal with vtkjs driven viewports\n if (viewportInputEntries.length) {\n // 1. Getting all the canvases from viewports calculation of the new offScreen size\n const vtkDrivenCanvases = viewportInputEntries.map((vp) =>\n getOrCreateCanvas(vp.element)\n );\n\n // Ensure the canvas size includes any scaling due to device pixel ratio\n vtkDrivenCanvases.forEach((canvas) => {\n const devicePixelRatio = window.devicePixelRatio || 1;\n\n const rect = canvas.getBoundingClientRect();\n canvas.width = rect.width * devicePixelRatio;\n canvas.height = rect.height * devicePixelRatio;\n });\n\n // 2. Set canvas size based on height and sum of widths\n const { offScreenCanvasWidth, offScreenCanvasHeight } =\n this._resizeOffScreenCanvas(vtkDrivenCanvases);\n\n /*\n TODO: Commenting this out until we can mock the Canvas usage in the tests (or use jsdom?)\n if (!offScreenCanvasWidth || !offScreenCanvasHeight) {\n throw new Error('Invalid offscreen canvas width or height')\n }*/\n\n // 3. Adding the viewports based on the viewportInputEntry definition to the\n // rendering engine.\n let xOffset = 0;\n for (let i = 0; i < viewportInputEntries.length; i++) {\n const vtkDrivenViewportInputEntry = viewportInputEntries[i];\n const canvas = vtkDrivenCanvases[i];\n const internalViewportEntry = {\n ...vtkDrivenViewportInputEntry,\n canvas,\n };\n\n this.addVtkjsDrivenViewport(internalViewportEntry, {\n offScreenCanvasWidth,\n offScreenCanvasHeight,\n xOffset,\n });\n\n // Incrementing the xOffset which provides the horizontal location of each\n // viewport on the offScreen canvas\n xOffset += canvas.width;\n }\n }\n }\n\n /**\n * Resizes the offscreen canvas based on the provided vtk.js driven canvases.\n *\n * @param canvases - An array of HTML Canvas\n */\n private _resizeOffScreenCanvas(\n canvasesDrivenByVtkJs: Array<HTMLCanvasElement>\n ): { offScreenCanvasWidth: number; offScreenCanvasHeight: number } {\n const { offScreenCanvasContainer, offscreenMultiRenderWindow } = this;\n\n const devicePixelRatio = window.devicePixelRatio || 1;\n\n // 1. Calculated the height of the offScreen canvas to be the maximum height\n // between canvases\n const offScreenCanvasHeight = Math.max(\n ...canvasesDrivenByVtkJs.map(\n (canvas) => canvas.clientHeight * devicePixelRatio\n )\n );\n\n // 2. Calculating the width of the offScreen canvas to be the sum of all\n let offScreenCanvasWidth = 0;\n\n canvasesDrivenByVtkJs.forEach((canvas) => {\n offScreenCanvasWidth += canvas.clientWidth * devicePixelRatio;\n });\n\n offScreenCanvasContainer.width = offScreenCanvasWidth;\n offScreenCanvasContainer.height = offScreenCanvasHeight;\n\n // 3. Resize command\n offscreenMultiRenderWindow.resize();\n\n return { offScreenCanvasWidth, offScreenCanvasHeight };\n }\n\n /**\n * Recalculates and updates the viewports location on the offScreen canvas upon its resize\n *\n * @param viewports - An array of viewports\n * @param offScreenCanvasWidth - new offScreen canvas width\n * @param offScreenCanvasHeight - new offScreen canvas height\n *\n * @returns _xOffset the final offset which will be used for the next viewport\n */\n private _resize(\n viewportsDrivenByVtkJs: Array<IStackViewport | IVolumeViewport>,\n offScreenCanvasWidth: number,\n offScreenCanvasHeight: number\n ): number {\n // Redefine viewport properties\n let _xOffset = 0;\n\n const devicePixelRatio = window.devicePixelRatio || 1;\n\n for (let i = 0; i < viewportsDrivenByVtkJs.length; i++) {\n const viewport = viewportsDrivenByVtkJs[i];\n const {\n sxStartDisplayCoords,\n syStartDisplayCoords,\n sxEndDisplayCoords,\n syEndDisplayCoords,\n sx,\n sy,\n sWidth,\n sHeight,\n } = this._getViewportCoordsOnOffScreenCanvas(\n viewport,\n offScreenCanvasWidth,\n offScreenCanvasHeight,\n _xOffset\n );\n\n _xOffset += viewport.canvas.clientWidth * devicePixelRatio;\n\n viewport.sx = sx;\n viewport.sy = sy;\n viewport.sWidth = sWidth;\n viewport.sHeight = sHeight;\n\n // Updating the renderer for the viewport\n const renderer = this.offscreenMultiRenderWindow.getRenderer(viewport.id);\n renderer.setViewport([\n sxStartDisplayCoords,\n syStartDisplayCoords,\n sxEndDisplayCoords,\n syEndDisplayCoords,\n ]);\n }\n\n // Returns the final xOffset\n return _xOffset;\n }\n\n /**\n * Calculates the location of the provided viewport on the offScreenCanvas\n *\n * @param viewports - An array of viewports\n * @param offScreenCanvasWidth - new offScreen canvas width\n * @param offScreenCanvasHeight - new offScreen canvas height\n * @param _xOffset - xOffSet to draw\n */\n private _getViewportCoordsOnOffScreenCanvas(\n viewport: InternalViewportInput | IStackViewport | IVolumeViewport,\n offScreenCanvasWidth: number,\n offScreenCanvasHeight: number,\n _xOffset: number\n ): ViewportDisplayCoords {\n const { canvas } = viewport;\n const { clientWidth, clientHeight } = canvas;\n const devicePixelRatio = window.devicePixelRatio || 1;\n const height = clientHeight * devicePixelRatio;\n const width = clientWidth * devicePixelRatio;\n\n // Update the canvas drawImage offsets.\n const sx = _xOffset;\n const sy = 0;\n const sWidth = width;\n const sHeight = height;\n\n const sxStartDisplayCoords = sx / offScreenCanvasWidth;\n\n // Need to offset y if it not max height\n const syStartDisplayCoords =\n sy + (offScreenCanvasHeight - height) / offScreenCanvasHeight;\n\n const sWidthDisplayCoords = sWidth / offScreenCanvasWidth;\n const sHeightDisplayCoords = sHeight / offScreenCanvasHeight;\n\n return {\n sxStartDisplayCoords,\n syStartDisplayCoords,\n sxEndDisplayCoords: sxStartDisplayCoords + sWidthDisplayCoords,\n syEndDisplayCoords: syStartDisplayCoords + sHeightDisplayCoords,\n sx,\n sy,\n sWidth,\n sHeight,\n };\n }\n\n /**\n * @method _getViewportsAsArray Returns an array of all viewports\n *\n * @returns {Array} Array of viewports.\n */\n private _getViewportsAsArray() {\n return Array.from(this._viewports.values());\n }\n\n private _setViewportsToBeRenderedNextFrame(viewportIds: string[]) {\n // Add the viewports to the set of flagged viewports\n viewportIds.forEach((viewportId) => {\n this._needsRender.add(viewportId);\n });\n\n // Render any flagged viewports\n this._render();\n }\n\n /**\n * Sets up animation frame if necessary\n */\n private _render() {\n // If we have viewports that need rendering and we have not already\n // set the RAF callback to run on the next frame.\n if (this._needsRender.size > 0 && this._animationFrameSet === false) {\n this._animationFrameHandle = window.requestAnimationFrame(\n this._renderFlaggedViewports\n );\n\n // Set the flag that we have already set up the next RAF call.\n this._animationFrameSet = true;\n }\n }\n\n /**\n * Renders all viewports.\n */\n private _renderFlaggedViewports = () => {\n this._throwIfDestroyed();\n\n if (!this.useCPURendering) {\n this.performVtkDrawCall();\n }\n\n const viewports = this._getViewportsAsArray();\n const eventDetailArray = [];\n\n for (let i = 0; i < viewports.length; i++) {\n const viewport = viewports[i];\n if (this._needsRender.has(viewport.id)) {\n const eventDetail =\n this.renderViewportUsingCustomOrVtkPipeline(viewport);\n eventDetailArray.push(eventDetail);\n\n // This viewport has been rendered, we can remove it from the set\n this._needsRender.delete(viewport.id);\n\n // If there is nothing left that is flagged for rendering, stop the loop\n if (this._needsRender.size === 0) {\n break;\n }\n }\n }\n\n // allow RAF to be called again\n this._animationFrameSet = false;\n this._animationFrameHandle = null;\n\n eventDetailArray.forEach((eventDetail) => {\n triggerEvent(eventDetail.element, Events.IMAGE_RENDERED, eventDetail);\n });\n };\n\n /**\n * Performs the single `vtk.js` draw call which is used to render the offscreen\n * canvas for vtk.js. This is a bulk rendering step for all Volume and Stack\n * viewports when GPU rendering is available.\n */\n private performVtkDrawCall() {\n // Render all viewports under vtk.js' control.\n const { offscreenMultiRenderWindow } = this;\n const renderWindow = offscreenMultiRenderWindow.getRenderWindow();\n\n const renderers = offscreenMultiRenderWindow.getRenderers();\n\n if (!renderers.length) {\n return;\n }\n\n for (let i = 0; i < renderers.length; i++) {\n const { renderer, id } = renderers[i];\n\n // Requesting viewports that need rendering to be rendered only\n if (this._needsRender.has(id)) {\n renderer.setDraw(true);\n } else {\n renderer.setDraw(false);\n }\n }\n\n renderWindow.render();\n\n // After redraw we set all renderers to not render until necessary\n for (let i = 0; i < renderers.length; i++) {\n renderers[i].renderer.setDraw(false);\n }\n }\n\n /**\n * Renders the given viewport\n * using its proffered method.\n *\n * @param viewport - The viewport to render\n */\n private renderViewportUsingCustomOrVtkPipeline(\n viewport: IStackViewport | IVolumeViewport\n ): EventTypes.ImageRenderedEventDetail[] {\n let eventDetail;\n\n if (viewportTypeUsesCustomRenderingPipeline(viewport.type) === true) {\n eventDetail =\n viewport.customRenderViewportToCanvas() as EventTypes.ImageRenderedEventDetail;\n } else {\n if (this.useCPURendering) {\n throw new Error(\n 'GPU not available, and using a viewport with no custom render pipeline.'\n );\n }\n\n const { offscreenMultiRenderWindow } = this;\n const openGLRenderWindow =\n offscreenMultiRenderWindow.getOpenGLRenderWindow();\n const context = openGLRenderWindow.get3DContext();\n const offScreenCanvas = context.canvas;\n\n eventDetail = this._renderViewportFromVtkCanvasToOnscreenCanvas(\n viewport,\n offScreenCanvas\n );\n }\n\n return eventDetail;\n }\n\n /**\n * Renders a particular `Viewport`'s on screen canvas.\n * @param viewport - The `Viewport` to render.\n * @param offScreenCanvas - The offscreen canvas to render from.\n */\n private _renderViewportFromVtkCanvasToOnscreenCanvas(\n viewport: IStackViewport | IVolumeViewport,\n offScreenCanvas\n ): EventTypes.ImageRenderedEventDetail {\n const {\n element,\n canvas,\n sx,\n sy,\n sWidth,\n sHeight,\n id: viewportId,\n renderingEngineId,\n suppressEvents,\n } = viewport;\n\n const { width: dWidth, height: dHeight } = canvas;\n\n const onScreenContext = canvas.getContext('2d');\n\n onScreenContext.drawImage(\n offScreenCanvas,\n sx,\n sy,\n sWidth,\n sHeight,\n 0, //dx\n 0, // dy\n dWidth,\n dHeight\n );\n\n return {\n element,\n suppressEvents,\n viewportId,\n renderingEngineId,\n };\n }\n\n /**\n * Reset the viewport by removing the data attributes\n * and clearing the context of draw. It also emits an element disabled event\n *\n * @param viewport - The `Viewport` to render.\n */\n private _resetViewport(viewport: IStackViewport | IVolumeViewport) {\n const renderingEngineId = this.id;\n\n const { element, canvas, id: viewportId } = viewport;\n\n const eventDetail: EventTypes.ElementDisabledEventDetail = {\n element,\n viewportId,\n renderingEngineId,\n };\n\n // Trigger first before removing the data attributes, as we need the enabled\n // element to remove tools associated with the viewport\n triggerEvent(eventTarget, Events.ELEMENT_DISABLED, eventDetail);\n\n element.removeAttribute('data-viewport-uid');\n element.removeAttribute('data-rendering-engine-uid');\n\n // clear drawing\n const context = canvas.getContext('2d');\n context.clearRect(0, 0, canvas.width, canvas.height);\n }\n\n private _clearAnimationFrame() {\n window.cancelAnimationFrame(this._animationFrameHandle);\n\n this._needsRender.clear();\n this._animationFrameSet = false;\n this._animationFrameHandle = null;\n }\n\n /**\n * Resets the `RenderingEngine`\n */\n private _reset() {\n const viewports = this._getViewportsAsArray();\n\n viewports.forEach((viewport) => {\n this._resetViewport(viewport);\n });\n\n this._clearAnimationFrame();\n\n this._viewports = new Map();\n }\n\n /**\n * Throws an error if trying to interact with the `RenderingEngine`\n * instance after its `destroy` method has been called.\n */\n private _throwIfDestroyed() {\n if (this.hasBeenDestroyed) {\n throw new Error(\n 'this.destroy() has been manually called to free up memory, can not longer use this instance. Instead make a new one.'\n );\n }\n }\n\n // debugging utils for offScreen canvas\n _downloadOffScreenCanvas() {\n const dataURL = this._debugRender();\n _TEMPDownloadURI(dataURL);\n }\n\n // debugging utils for offScreen canvas\n _debugRender(): void {\n const { offscreenMultiRenderWindow } = this;\n const renderWindow = offscreenMultiRenderWindow.getRenderWindow();\n\n const renderers = offscreenMultiRenderWindow.getRenderers();\n\n for (let i = 0; i < renderers.length; i++) {\n renderers[i].renderer.setDraw(true);\n }\n\n renderWindow.render();\n const openGLRenderWindow =\n offscreenMultiRenderWindow.getOpenGLRenderWindow();\n const context = openGLRenderWindow.get3DContext();\n\n const offScreenCanvas = context.canvas;\n const dataURL = offScreenCanvas.toDataURL();\n\n this._getViewportsAsArray().forEach((viewport) => {\n const { sx, sy, sWidth, sHeight } = viewport;\n\n const canvas = <HTMLCanvasElement>viewport.canvas;\n const { width: dWidth, height: dHeight } = canvas;\n\n const onScreenContext = canvas.getContext('2d');\n\n //sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight\n onScreenContext.drawImage(\n offScreenCanvas,\n sx,\n sy,\n sWidth,\n sHeight,\n 0, //dx\n 0, // dy\n dWidth,\n dHeight\n );\n });\n\n return dataURL;\n }\n}\n\nexport default RenderingEngine;\n\n// debugging utils for offScreen canvas\nfunction _TEMPDownloadURI(uri) {\n const link = document.createElement('a');\n\n link.download = 'viewport.png';\n link.href = uri;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n}\n","import RenderingEngine from './RenderingEngine';\nimport getRenderingEngine from './getRenderingEngine';\nimport VolumeViewport from './VolumeViewport';\nimport StackViewport from './StackViewport';\nimport VolumeViewport3D from './VolumeViewport3D';\nimport {\n createVolumeActor,\n createVolumeMapper,\n getOrCreateCanvas,\n} from './helpers';\n\nexport {\n getRenderingEngine,\n RenderingEngine,\n VolumeViewport,\n VolumeViewport3D,\n createVolumeActor,\n createVolumeMapper,\n getOrCreateCanvas,\n StackViewport,\n};\n\nexport default RenderingEngine;\n","import { RequestPoolManager } from './requestPoolManager';\nimport RequestType from '../enums/RequestType';\n\n/**\n * ImageRetrievalPoolManager\n * You don't need to directly use the imageRetrievalPoolManager to load images\n * since the imageLoadPoolManager will automatically use it for retrieval. However,\n * maximum number of concurrent requests can be set by calling `setMaxConcurrentRequests`.\n *\n * Retrieval (usually) === XHR requests\n */\nconst imageRetrievalPoolManager = new RequestPoolManager('imageRetrievalPool');\n\nimageRetrievalPoolManager.setMaxSimultaneousRequests(\n RequestType.Interaction,\n 200\n);\nimageRetrievalPoolManager.setMaxSimultaneousRequests(\n RequestType.Thumbnail,\n 200\n);\nimageRetrievalPoolManager.setMaxSimultaneousRequests(RequestType.Prefetch, 200);\nimageRetrievalPoolManager.grabDelay = 0;\n\nexport default imageRetrievalPoolManager;\n","import getRenderingEngine, {\n getRenderingEngines,\n} from './RenderingEngine/getRenderingEngine';\nimport { IEnabledElement } from './types';\n\n/**\n * A convenience method to find an EnabledElement given a reference to its\n * associated element. Commonly used in code that's handling a custom\n * event emitted by this library.\n *\n * @example\n * Using the renderingEngine to find the enabled element:\n * ```javascript\n * const element = getRenderingEngine(renderingEngineId)\n * .getViewport(viewportId)\n * .element\n *\n * const enabledElement = getEnabledElement(element)\n * ```\n *\n * @example\n * Using a cornerstone event's \"element\"\n * ```javascript\n * // Our \"cornerstone events\" contain the source element, which is\n * // raised on the viewport's div element\n * const { element } = evt.detail\n * const enabledElement = getEnabledElement(element)\n * ```\n *\n * @param element - a reference to an EnabledElement/Viewport's div element\n * @returns the associated EnabledElement, or undefined if no matching EnabledElement\n * can be found\n */\nexport default function getEnabledElement(\n element: HTMLDivElement | undefined\n): IEnabledElement | undefined {\n if (!element) {\n return;\n }\n\n const { viewportUid, renderingEngineUid } = element.dataset;\n\n return getEnabledElementByIds(viewportUid, renderingEngineUid);\n}\n\n/**\n * Similar to {@link getEnabledElement}, but takes the IDs of the\n * renderingEngine and viewport as parameters to return the associated\n * EnabledElement.\n *\n * @param viewportId - The Id of the viewport\n * @param renderingEngineId - The Id of the rendering engine.\n * @returns The enabled element which is an object that contains the viewport, rendering\n * engine, viewport Id, rendering engine Id, and the Frame of Reference UID.\n */\nexport function getEnabledElementByIds(\n viewportId: string,\n renderingEngineId: string\n): IEnabledElement {\n if (!renderingEngineId || !viewportId) {\n return;\n }\n\n const renderingEngine = getRenderingEngine(renderingEngineId);\n\n if (!renderingEngine || renderingEngine.hasBeenDestroyed) {\n return;\n }\n\n const viewport = renderingEngine.getViewport(viewportId);\n\n if (!viewport) {\n return;\n }\n\n const FrameOfReferenceUID = viewport.getFrameOfReferenceUID();\n\n return {\n viewport,\n renderingEngine,\n viewportId,\n renderingEngineId,\n FrameOfReferenceUID,\n };\n}\n\n/**\n * Get all the enabled elements from all the rendering engines\n * @returns An array of enabled elements.\n */\nexport function getEnabledElements(): IEnabledElement[] {\n const enabledElements = [];\n\n const renderingEngines = getRenderingEngines();\n\n renderingEngines.forEach((renderingEngine) => {\n const viewports = renderingEngine.getViewports();\n\n viewports.forEach(({ element }) => {\n enabledElements.push(getEnabledElement(element));\n });\n });\n\n return enabledElements;\n}\n","/*\n * Constants\n */\n\nconst DEFAULT_SETTINGS = Symbol('DefaultSettings');\nconst RUNTIME_SETTINGS = Symbol('RuntimeSettings');\nconst OBJECT_SETTINGS_MAP = Symbol('ObjectSettingsMap');\nconst DICTIONARY = Symbol('Dictionary');\n\n/**\n * Settings\n */\nexport default class Settings {\n constructor(base?: Settings) {\n const dictionary = Object.create(\n base instanceof Settings && DICTIONARY in base ? base[DICTIONARY] : null\n );\n Object.seal(\n Object.defineProperty(this, DICTIONARY, {\n value: dictionary,\n })\n );\n }\n\n set(key: string, value: unknown): boolean {\n return set(this[DICTIONARY], key, value, null);\n }\n\n get(key: string): unknown {\n return get(this[DICTIONARY], key);\n }\n\n /**\n * Unset a specific key or a set of keys within a namespace when the key ends with a dot (ASCII #46).\n * If the key is \".\", all keys will be removed and this command works as a reset.\n * @param key - name The key to be unset or a namespace.\n * @returns boolean\n */\n unset(key: string): boolean {\n return unset(this[DICTIONARY], key + '');\n }\n\n forEach(callback: (key: string, value: unknown) => void): void {\n iterate(this[DICTIONARY], callback);\n }\n\n extend(): Settings {\n return new Settings(this);\n }\n\n /**\n * Recursively import all properties from the given plain JavaScript object.\n * This method has the opposite effect of the `dump` method.\n * @param root - The root object whose properties will\n * be imported.\n */\n import(root: Record<string, unknown>): void {\n if (isPlainObject(root)) {\n Object.keys(root).forEach((key) => {\n set(this[DICTIONARY], key, root[key], null);\n });\n }\n }\n\n /**\n * Build a JSON representation of the current internal state of this settings\n * object. The returned object can be safely passed to `JSON.stringify`\n * function.\n * @returns The JSON representation of the current\n * state of this settings instance\n */\n dump(): Record<string, unknown> {\n const context = {};\n iterate(this[DICTIONARY], (key, value) => {\n if (typeof value !== 'undefined') {\n deepSet(context, key, value);\n }\n });\n return context;\n }\n\n static assert(subject: Settings): Settings {\n return subject instanceof Settings\n ? subject\n : Settings.getRuntimeSettings();\n }\n\n static getDefaultSettings(subfield = null): Settings | any {\n let defaultSettings = Settings[DEFAULT_SETTINGS];\n if (!(defaultSettings instanceof Settings)) {\n defaultSettings = new Settings();\n Settings[DEFAULT_SETTINGS] = defaultSettings;\n }\n\n // Given subfield of 'segmentation' it will return all settings\n // that starts with segmentation.*\n if (subfield) {\n const settingObj = {};\n defaultSettings.forEach((name: string) => {\n if (name.startsWith(subfield)) {\n const setting = name.split(`${subfield}.`)[1];\n settingObj[setting] = defaultSettings.get(name);\n }\n });\n return settingObj;\n }\n\n return defaultSettings;\n }\n\n static getRuntimeSettings(): Settings {\n let runtimeSettings = Settings[RUNTIME_SETTINGS];\n if (!(runtimeSettings instanceof Settings)) {\n runtimeSettings = new Settings(Settings.getDefaultSettings());\n Settings[RUNTIME_SETTINGS] = runtimeSettings;\n }\n return runtimeSettings;\n }\n\n static getObjectSettings(subject: unknown, from?: unknown): Settings {\n let settings = null;\n if (subject instanceof Settings) {\n settings = subject;\n } else if (typeof subject === 'object' && subject !== null) {\n let objectSettingsMap = Settings[OBJECT_SETTINGS_MAP];\n if (!(objectSettingsMap instanceof WeakMap)) {\n objectSettingsMap = new WeakMap();\n Settings[OBJECT_SETTINGS_MAP] = objectSettingsMap;\n }\n settings = objectSettingsMap.get(subject);\n if (!(settings instanceof Settings)) {\n settings = new Settings(\n Settings.assert(Settings.getObjectSettings(from))\n );\n objectSettingsMap.set(subject, settings);\n }\n }\n return settings;\n }\n\n static extendRuntimeSettings(): Settings {\n return Settings.getRuntimeSettings().extend();\n }\n}\n\n/*\n * Local Helpers\n */\n\nfunction unset(dictionary: Record<string, unknown>, name: string): boolean {\n if (name.endsWith('.')) {\n let deleteCount = 0;\n const namespace = name;\n const base = namespace.slice(0, -1);\n const deleteAll = base.length === 0;\n for (const key in dictionary) {\n if (\n Object.prototype.hasOwnProperty.call(dictionary, key) &&\n (deleteAll || key.startsWith(namespace) || key === base)\n ) {\n delete dictionary[key];\n ++deleteCount;\n }\n }\n return deleteCount > 0;\n }\n return delete dictionary[name];\n}\n\nfunction iterate(\n dictionary: Record<string, unknown>,\n callback: (key: string, value: unknown) => void\n): void {\n for (const key in dictionary) {\n callback(key, dictionary[key]);\n }\n}\n\nfunction setAll(\n dictionary: Record<string, unknown>,\n prefix: string,\n record: Record<string, unknown>,\n references: WeakSet<Record<string, unknown>>\n): boolean {\n let failCount: number;\n if (references.has(record)) {\n return set(dictionary, prefix, null, references);\n }\n references.add(record);\n failCount = 0;\n for (const field in record) {\n if (Object.prototype.hasOwnProperty.call(record, field)) {\n const key = field.length === 0 ? prefix : `${prefix}.${field}`;\n if (!set(dictionary, key, record[field], references)) {\n ++failCount;\n }\n }\n }\n references.delete(record);\n return failCount === 0;\n}\n\n/**\n * Set the key-value pair on a given dictionary. If the given value is a\n * plain javascript object, every property of that object will also be set.\n * @param dictionary {Record<string, unknown>} The target dictionary\n * @param key {string} The given key\n * @param value {unknown} The given value\n * @param references {WeakSet<Record<string, unknown>>} references is a WeakSet\n * instance used to keep track of which objects have already been iterated\n * through preventing thus possible stack overflows caused by cyclic references\n * @returns {boolean} Returns true if every given key-value pair has been\n * successfully set\n */\nfunction set(\n dictionary: Record<string, unknown>,\n key: string,\n value: unknown,\n references: WeakSet<Record<string, unknown>>\n): boolean {\n if (isValidKey(key)) {\n if (isPlainObject(value)) {\n return setAll(\n dictionary,\n key,\n value as Record<string, unknown>,\n references instanceof WeakSet ? references : new WeakSet()\n );\n }\n dictionary[key] = value;\n return true;\n }\n return false;\n}\n\nfunction get(dictionary: Record<string, unknown>, key: string): unknown {\n return dictionary[key];\n}\n\n/**\n * Make sure the -provided key correctly formatted.\n * e.g.:\n * \"my.cool.property\" (valid)\n * \"my.cool.property.\" (invalid)\n * \".my.cool.property\" (invalid)\n * \"my.cool..property\" (invalid)\n * @param key {string} The property name to be used as key within the internal\n * dictionary\n * @returns {boolean} True on success, false otherwise\n */\nfunction isValidKey(key: string): boolean {\n let last: number, current: number, previous: number;\n if (typeof key !== 'string' || (last = key.length - 1) < 0) return false;\n previous = -1;\n while ((current = key.indexOf('.', previous + 1)) >= 0) {\n if (current - previous < 2 || current === last) return false;\n previous = current;\n }\n return true;\n}\n\nfunction isPlainObject(subject: unknown) {\n if (typeof subject === 'object' && subject !== null) {\n const prototype = Object.getPrototypeOf(subject);\n if (prototype === Object.prototype || prototype === null) {\n return true;\n }\n }\n return false;\n}\n\nfunction deepSet(context, key, value) {\n const separator = key.indexOf('.');\n if (separator >= 0) {\n const subKey = key.slice(0, separator);\n let subContext = context[subKey];\n if (typeof subContext !== 'object' || subContext === null) {\n const subContextValue = subContext;\n subContext = {};\n if (typeof subContextValue !== 'undefined') {\n subContext[''] = subContextValue;\n }\n context[subKey] = subContext;\n }\n deepSet(subContext, key.slice(separator + 1, key.length), value);\n } else {\n context[key] = value;\n }\n}\n\n/**\n * Initial Settings for the repository\n */\nSettings.getDefaultSettings().set('useCursors', true);\n","/**\n * A utility that can be used to scale (in place) an RgbTransferFunction. We\n * often use this to scale the transfer function based on a PET calculation.\n *\n * @example\n * Grabbing a reference to the RGB Transfer function from the viewport:\n * ```\n * const rgbTransferFunction = viewport\n * .getActor()\n * .getProperty()\n * .getRGBTransferFunction(0);\n *\n * scaleRgbTransferFunction(rgbTransferFunction, 2);\n * ```\n *\n * @see {@link https://kitware.github.io/vtk-js/api/Rendering_Core_ColorTransferFunction.html|VTK.js: ColorTransferFunction}\n * @param rgbTransferFunction\n * @param scalingFactor\n */\nexport default function scaleRGBTransferFunction(\n rgbTransferFunction: any,\n scalingFactor: number\n): void {\n const size = rgbTransferFunction.getSize();\n\n for (let index = 0; index < size; index++) {\n const nodeValue1 = [];\n\n rgbTransferFunction.getNodeValue(index, nodeValue1);\n\n nodeValue1[1] = nodeValue1[1] * scalingFactor;\n nodeValue1[2] = nodeValue1[2] * scalingFactor;\n nodeValue1[3] = nodeValue1[3] * scalingFactor;\n\n rgbTransferFunction.setNodeValue(index, nodeValue1);\n }\n}\n","const LAST_RUNTIME_ID = Symbol('LastRuntimeId');\nconst GLOBAL_CONTEXT = {};\nconst DEFAULT_MAX = 0xffffffff; // Max 32-bit integer\nconst DEFAULT_SEPARATOR = '-';\n\n/**\n * Generate a unique numeric ID string valid during a single runtime session;\n *\n * @param context - An optional object to be used as context.\n * Defaults to a global context;\n * @param separator - The component separator. Defaults to \"-\";\n * @param max - The maximum component value. Defaults to 4294967295;\n * @returns The string representation of the the unique ID;\n */\nexport default function getRuntimeId(\n context?: unknown,\n separator?: string,\n max?: number\n): string {\n return getNextRuntimeId(\n // @ts-ignore\n context !== null && typeof context === 'object' ? context : GLOBAL_CONTEXT,\n LAST_RUNTIME_ID,\n (typeof max === 'number' && max > 0 ? max : DEFAULT_MAX) >>> 0\n ).join(typeof separator === 'string' ? separator : DEFAULT_SEPARATOR);\n}\n\n/*\n * Helpers\n */\n\nfunction getNextRuntimeId(\n context: Record<symbol, Array<number>>,\n symbol: symbol,\n max: number\n): Array<number> {\n let idComponents = context[symbol];\n if (!(idComponents instanceof Array)) {\n idComponents = [0];\n Object.defineProperty(context, symbol, { value: idComponents });\n }\n for (let carry = true, i = 0; carry && i < idComponents.length; ++i) {\n let n = idComponents[i] | 0;\n if (n < max) {\n carry = false;\n n = n + 1;\n } else {\n n = 0;\n if (i + 1 === idComponents.length) idComponents.push(0);\n }\n idComponents[i] = n;\n }\n return idComponents;\n}\n","import imageIdToURI from './imageIdToURI';\n\nconst state = {}; // Calibrated pixel spacing per imageId\n\n/**\n * Simple metadataProvider object to store metadata for calibrated spacings.\n * This can be added via cornerstone.metaData.addProvider(...) in order to store\n * and return calibrated pixel spacings when metaData type is \"calibratedPixelSpacing\".\n */\nconst metadataProvider = {\n /**\n * Adds metadata for an imageId.\n * @param imageId - the imageId for the metadata to store\n * @param payload - the payload composed of new calibrated pixel spacings\n */\n add: (imageId: string, payload: [number, number]): void => {\n const imageURI = imageIdToURI(imageId);\n if (!state[imageURI]) {\n state[imageURI] = {};\n }\n state[imageURI] = payload;\n },\n\n /**\n * Returns the metadata for an imageId if it exists.\n * @param type - the type of metadata to enquire about\n * @param imageId - the imageId to enquire about\n * @returns the calibrated pixel spacings for the imageId if it exists, otherwise undefined\n */\n get: (type: string, imageId: string): [number, number] => {\n if (type === 'calibratedPixelSpacing') {\n const imageURI = imageIdToURI(imageId);\n return state[imageURI];\n }\n },\n};\n\nexport default metadataProvider;\n","import type Point3 from '../types/Point3';\n\n/**\n * returns equal if the two vec3s are opposite within the\n * given tolerance in each dimension.\n *\n * @param v1 - The first 3 vector\n * @param v2 - The second 3 vector.\n * @param tolerance - The acceptable tolerance.\n *\n * @returns True if the two values are within the tolerance levels.\n */\nexport default function isOpposite(\n v1: Point3,\n v2: Point3,\n tolerance = 1e-5\n): boolean {\n return (\n Math.abs(v1[0] + v2[0]) < tolerance &&\n Math.abs(v1[1] + v2[1]) < tolerance &&\n Math.abs(v1[2] + v2[2]) < tolerance\n );\n}\n","import global from '../global';\n/**\n * A helper function that creates a new Float32Array that utilized a shared\n * array buffer. This allows the array to be updated simultaneously in\n * workers or the main thread. Depending on the system (the CPU, the OS, the Browser)\n * it can take a while until the change is propagated to all contexts.\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer|MDN: SharedArrayBuffer}\n * @remarks\n * We use SharedArrayBuffers in our ImageCache class. It's what allows us to\n * stream data to build a volume. It's important to note that SharedArrayBuffer\n * does not work out of the box for all web browsers. In some, it is disabled\n * behind a flag; in others, it has been removed entirely.\n *\n * @example\n * Creating an array for a Volume with known dimensions:\n * ```\n * const dimensions = [512, 512, 25];\n * const scalarData = createUint8SharedArray(dimensions[0] * dimensions[1] * dimensions[2]);\n * ```\n *\n * @param length - frame size * number of frames\n * @returns a Uint8Array with an underlying SharedArrayBuffer\n * @public\n */\nfunction createUint8SharedArray(length: number): Uint8Array {\n if (!window.crossOriginIsolated) {\n throw new Error(\n 'Your page is NOT cross-origin isolated, see https://developer.mozilla.org/en-US/docs/Web/API/crossOriginIsolated'\n );\n }\n if (window.SharedArrayBuffer === undefined) {\n throw new Error(\n 'SharedArrayBuffer is NOT supported in your browser see https://developer.chrome.com/blog/enabling-shared-array-buffer/'\n );\n }\n\n const sharedArrayBuffer = new SharedArrayBuffer(length);\n\n return new Uint8Array(sharedArrayBuffer);\n}\n\nexport default createUint8SharedArray;\n","import global from '../global';\n\n/**\n * A helper function that creates a new Float32Array that utilized a shared\n * array buffer. This allows the array to be updated simultaneously in\n * workers or the main thread. Depending on the system (the CPU, the OS, the Browser)\n * it can take a while until the change is propagated to all contexts.\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer|MDN: SharedArrayBuffer}\n * @remarks\n * We use SharedArrayBuffers in our ImageCache class. It's what allows us to\n * stream data to build a volume. It's important to note that SharedArrayBuffer\n * does not work out of the box for all web browsers. In some, it is disabled\n * behind a flag; in others, it has been removed entirely.\n *\n * @example\n * Creating an array for a Volume with known dimensions:\n * ```\n * const dimensions = [512, 512, 25];\n * const scalarData = createFloat32SharedArray(dimensions[0] * dimensions[1] * dimensions[2]);\n * ```\n *\n * @param length - frame size * number of frames\n * @returns a Float32Array with an underlying SharedArrayBuffer\n * @public\n */\nfunction createFloat32SharedArray(length: number): Float32Array {\n if (!window.crossOriginIsolated) {\n throw new Error(\n 'Your page is NOT cross-origin isolated, see https://developer.mozilla.org/en-US/docs/Web/API/crossOriginIsolated'\n );\n }\n if (window.SharedArrayBuffer === undefined) {\n throw new Error(\n 'SharedArrayBuffer is NOT supported in your browser see https://developer.chrome.com/blog/enabling-shared-array-buffer/'\n );\n }\n\n const sharedArrayBuffer = new SharedArrayBuffer(length * 4);\n\n return new Float32Array(sharedArrayBuffer);\n}\n\nexport default createFloat32SharedArray;\n","import { vec3 } from 'gl-matrix';\nimport * as metaData from '../metaData';\nimport type { IImageVolume, Point3 } from '../types';\n\nimport getSpacingInNormalDirection from './getSpacingInNormalDirection';\n\n/**\n * Given an image, a point in space and the viewPlaneNormal it returns the\n * closest imageId of the image volume that is within half voxel spacing\n * of the point in space.\n * @param imageVolume - The image volume\n * @param worldPos - The position in the world coordinate system (from mouse click)\n * @param viewPlaneNormal - The normal vector of the viewport\n * @param viewUp - The viewUp vector of the camera.\n *\n * @returns The imageId for the tool.\n */\nexport default function getClosestImageId(\n imageVolume: IImageVolume,\n worldPos: Point3,\n viewPlaneNormal: Point3,\n viewUp: Point3\n): string {\n if (!imageVolume) {\n return;\n }\n\n const { direction, imageIds } = imageVolume;\n\n if (!imageIds || !imageIds.length) {\n return;\n }\n\n // 1. Get ScanAxis vector\n const kVector = direction.slice(6, 9);\n\n // 2. Check if scanAxis is not parallel to camera viewPlaneNormal\n const dotProducts = vec3.dot(kVector as Point3, <vec3>viewPlaneNormal);\n\n // 2.a if imagePlane is not parallel to the camera: tool is not drawn on an\n // imaging plane, return\n if (Math.abs(dotProducts) < 0.99) {\n return;\n }\n\n // 3. Calculate Spacing the in the normal direction, this will get used to\n // check whether we are withing a slice\n const spacingInNormalDirection = getSpacingInNormalDirection(\n imageVolume,\n viewPlaneNormal\n );\n\n const halfSpacingInNormalDirection = spacingInNormalDirection / 2;\n\n // 4. Iterate over all imageIds and check if the tool point (worldPos) is\n // withing one of the slices defined by an imageId\n let imageIdForTool;\n for (let i = 0; i < imageIds.length; i++) {\n const imageId = imageIds[i];\n\n // 4.a Get metadata for the imageId\n const { imagePositionPatient } = metaData.get('imagePlaneModule', imageId);\n\n // 4.b Calculate the direction vector from annotation. point to the first voxel\n // of this image defined by imageId\n const dir = vec3.create();\n vec3.sub(dir, worldPos, imagePositionPatient);\n\n // 4.c Calculate the distance between the vector above and the viewplaneNormal\n // i.e., projected distance\n const dot = vec3.dot(dir, viewPlaneNormal);\n\n // 4.d If the distance is withing range, return the imageId\n if (Math.abs(dot) < halfSpacingInNormalDirection) {\n imageIdForTool = imageId;\n }\n }\n\n return imageIdForTool;\n}\n","import { Point3 } from '../types';\n\n/**\n * Returns true if the specified index is within the given dimensions.\n *\n * @param index - The index to check.\n * @param dimensions - The dimensions to check against.\n *\n * @returns True if the index is in-bounds.\n */\nexport default function indexWithinDimensions(\n index: Point3,\n dimensions: Point3\n): boolean {\n if (\n index[0] < 0 ||\n index[0] >= dimensions[0] ||\n index[1] < 0 ||\n index[1] >= dimensions[1] ||\n index[2] < 0 ||\n index[2] >= dimensions[2]\n ) {\n return false;\n }\n\n return true;\n}\n","import { IVolumeViewport } from '../types';\nimport {\n getRenderingEngines,\n getRenderingEngine,\n} from '../RenderingEngine/getRenderingEngine';\n\n/**\n * Returns the viewports containing the same volume actors (all actors) the same\n * as the target viewport. If renderingEngineId is provided, it will only return\n * viewports that are associated with the renderingEngineId; otherwise, it will\n * return search in all rendering engines.\n *\n * This method is useful for finding viewports that are associated with the same\n * volume (e.g., for tools that share state between viewports).\n *\n * @param viewport - target viewport\n * @returns array of viewports that have the same volume actor as the target viewport\n */\nfunction getVolumeViewportsContainingSameVolumes(\n targetViewport: IVolumeViewport,\n renderingEngineId?: string\n): Array<IVolumeViewport> {\n // If rendering engine is not provided, use all rendering engines\n let renderingEngines;\n if (renderingEngineId) {\n renderingEngines = [getRenderingEngine(renderingEngineId)];\n } else {\n renderingEngines = getRenderingEngines();\n }\n\n const sameVolumesViewports = [];\n\n renderingEngines.forEach((renderingEngine) => {\n const targetActors = targetViewport.getActors();\n const viewports = renderingEngine.getVolumeViewports();\n\n for (const vp of viewports) {\n const vpActors = vp.getActors();\n\n if (vpActors.length !== targetActors.length) {\n continue;\n }\n\n // every targetActors should be in the vpActors\n const sameVolumes = targetActors.every(({ uid }) =>\n vpActors.find((vpActor) => uid === vpActor.uid)\n );\n\n if (sameVolumes) {\n sameVolumesViewports.push(vp);\n }\n }\n });\n\n return sameVolumesViewports;\n}\n\nexport default getVolumeViewportsContainingSameVolumes;\n","import { IVolumeViewport } from '../types';\nimport {\n getRenderingEngines,\n getRenderingEngine,\n} from '../RenderingEngine/getRenderingEngine';\n\n/**\n * Similar to {@link getVolumeViewportsContainingSameVolumes}, but uses the volumeId\n * to filter viewports that contain the same volume.\n *\n * @returns VolumeViewport viewports array\n */\nfunction getViewportsWithVolumeId(\n volumeId: string,\n renderingEngineId?: string\n): Array<IVolumeViewport> {\n // If rendering engine is not provided, use all rendering engines\n let renderingEngines;\n if (renderingEngineId) {\n renderingEngines = [getRenderingEngine(renderingEngineId)];\n } else {\n renderingEngines = getRenderingEngines();\n }\n\n const targetViewports = [];\n\n renderingEngines.forEach((renderingEngine) => {\n const viewports = renderingEngine.getVolumeViewports();\n const filteredViewports = viewports.filter((vp) =>\n vp.hasVolumeId(volumeId)\n );\n targetViewports.push(...filteredViewports);\n });\n\n return targetViewports;\n}\n\nexport default getViewportsWithVolumeId;\n","import { IImage, CPUFallbackEnabledElement } from '../types';\n\nimport getDefaultViewport from '../RenderingEngine/helpers/cpuFallback/rendering/getDefaultViewport';\nimport calculateTransform from '../RenderingEngine/helpers/cpuFallback/rendering/calculateTransform';\nimport drawImageSync from '../RenderingEngine/helpers/cpuFallback/drawImageSync';\n\n/**\n * Renders a cornerstone image object to a canvas.\n * Note: this does not load the image but only takes care of the rendering pipeline\n *\n * @param image - Cornerstone image object\n * @param canvas - Canvas element to render to\n */\nexport default function renderToCanvas(\n canvas: HTMLCanvasElement,\n image: IImage,\n modality?: string\n): void {\n const viewport = getDefaultViewport(canvas, image, modality);\n\n const enabledElement: CPUFallbackEnabledElement = {\n canvas,\n viewport,\n image,\n renderingTools: {},\n };\n\n enabledElement.transform = calculateTransform(enabledElement);\n\n const invalidated = true;\n drawImageSync(enabledElement, invalidated);\n}\n","import { IImage } from '../types';\n\nimport { loadAndCacheImage } from '../imageLoader';\nimport * as metaData from '../metaData';\nimport { RequestType } from '../enums';\nimport imageLoadPoolManager from '../requestPool/imageLoadPoolManager';\nimport renderToCanvas from './renderToCanvas';\n\n/**\n * Loads and renders an imageId to a Canvas. It will use the CPU rendering pipeline\n * for image.\n *\n * @example\n * ```\n * const canvas = document.getElementById('myCanvas')\n * const imageId = 'myImageId'\n *\n * loadImageToCanvas(canvas, imageId)\n * ```\n * @param imageId - The imageId to render\n * @param canvas - Canvas element to render to\n * @param requestType - The type of request (default to interaction), can be 'interaction' or 'prefetch' or 'thumbnail'\n * the order of loading for the pool manager is interaction, thumbnail, prefetch\n * @param priority - The priority of the request within the request type (lower is higher priority)\n * @returns - A promise that resolves when the image has been rendered with the imageId\n */\nexport default function loadImageToCanvas(\n canvas: HTMLCanvasElement,\n imageId: string,\n requestType = RequestType.Thumbnail,\n priority = -5\n): Promise<string> {\n return new Promise((resolve, reject) => {\n function successCallback(image: IImage, imageId: string) {\n const { modality } = metaData.get('generalSeriesModule', imageId) || {};\n\n image.isPreScaled = image.isPreScaled || image.preScale?.scaled;\n renderToCanvas(canvas, image, modality);\n resolve(imageId);\n }\n\n function errorCallback(error: Error, imageId: string) {\n console.error(error, imageId);\n reject(error);\n }\n\n function sendRequest(imageId, imageIdIndex, options) {\n return loadAndCacheImage(imageId, options).then(\n (image) => {\n successCallback.call(this, image, imageId);\n },\n (error) => {\n errorCallback.call(this, error, imageId);\n }\n );\n }\n\n // IMPORTANT: Request type should be passed if not the 'interaction'\n // highest priority will be used for the request type in the imageRetrievalPool\n const options = {\n targetBuffer: {\n type: 'Float32Array',\n offset: null,\n length: null,\n },\n preScale: {\n enabled: true,\n },\n requestType,\n };\n\n imageLoadPoolManager.addRequest(\n sendRequest.bind(null, imageId, null, options),\n requestType,\n { imageId },\n priority\n );\n });\n}\n","import { vec3 } from 'gl-matrix';\nimport { metaData } from '..';\nimport { Point2, Point3 } from '../types';\n\n/**\n * Given the imageId, and 3d coordinates on the world space, it returns the continuos\n * image coordinates (IJ) on the image space. The image space is\n * defined with [0,0] being on the top left corner of the top left pixel,\n * the [1,1] being on the bottom right corner of the top left pixel.\n * @param imageId - The image id\n * @param worldCoords - The 3d coordinates on the world.\n * @returns The 2d coordinates on the image.\n *\n */\nfunction worldToImageCoords(\n imageId: string,\n worldCoords: Point3\n): Point2 | undefined {\n const imagePlaneModule = metaData.get('imagePlaneModule', imageId);\n\n if (!imagePlaneModule) {\n throw new Error(`No imagePlaneModule found for imageId: ${imageId}`);\n }\n\n // For the image coordinates we need to calculate the transformation matrix\n // from the world coordinates to the image coordinates.\n\n const {\n columnCosines,\n columnPixelSpacing,\n rowCosines,\n rowPixelSpacing,\n imagePositionPatient: origin,\n rows,\n columns,\n } = imagePlaneModule;\n\n // The origin is the image position patient, but since image coordinates start\n // from [0,0] for the top left hand of the first pixel, and the origin is at the\n // center of the first pixel, we need to account for this.\n const newOrigin = vec3.create();\n\n vec3.scaleAndAdd(newOrigin, origin, columnCosines, -columnPixelSpacing / 2);\n vec3.scaleAndAdd(newOrigin, newOrigin, rowCosines, -rowPixelSpacing / 2);\n\n // Get the subtraction vector from the origin to the world coordinates\n const sub = vec3.create();\n vec3.sub(sub, worldCoords, newOrigin);\n\n // Projected distance of the sub vector onto the rowCosines\n const rowDistance = vec3.dot(sub, rowCosines);\n\n // Projected distance of the sub vector onto the columnCosines\n const columnDistance = vec3.dot(sub, columnCosines);\n\n const imageCoords = [\n rowDistance / rowPixelSpacing,\n columnDistance / columnPixelSpacing,\n ];\n\n return imageCoords as Point2;\n}\n\nexport default worldToImageCoords;\n","import { vec3 } from 'gl-matrix';\nimport { metaData } from '..';\nimport { Point2, Point3 } from '../types';\n\n/**\n * Given the imageId and a 2d coordinates on the image space with [0,0] being the top left corner\n * of the top left pixel, and options which includes the imageId, it returns the\n * 3d coordinates on the world space.\n * @param imageId - The image id\n * @param imageCoords - The 2d coordinates on the image\n * @returns The 3d coordinates on the world.\n *\n */\nexport default function imageToWorldCoords(\n imageId: string,\n imageCoords: Point2\n): Point3 | undefined {\n const imagePlaneModule = metaData.get('imagePlaneModule', imageId);\n\n if (!imagePlaneModule) {\n throw new Error(`No imagePlaneModule found for imageId: ${imageId}`);\n }\n\n const {\n columnCosines,\n columnPixelSpacing,\n rowCosines,\n rowPixelSpacing,\n imagePositionPatient: origin,\n } = imagePlaneModule;\n\n // calculate the image coordinates in the world space\n const imageCoordsInWorld = vec3.create();\n\n // move from origin in the direction of the row cosines with the amount of\n // row pixel spacing times the first element of the image coordinates vector\n vec3.scaleAndAdd(\n imageCoordsInWorld,\n origin,\n rowCosines,\n // to accommodate the [0,0] being on the top left corner of the top left pixel\n // but the origin is at the center of the top left pixel\n rowPixelSpacing * (imageCoords[0] - 0.5)\n );\n\n vec3.scaleAndAdd(\n imageCoordsInWorld,\n imageCoordsInWorld,\n columnCosines,\n columnPixelSpacing * (imageCoords[1] - 0.5)\n );\n\n return Array.from(imageCoordsInWorld) as Point3;\n}\n","import { vec3 } from 'gl-matrix';\nimport { ActorSliceRange, Point3 } from '../types';\n\n/**\n * Given a number of frames, `deltaFrames`,\n * move the `focalPoint` and camera `position` so that it moves forward/backwards\n * `deltaFrames` in the camera's normal direction, and snaps to the nearest frame.\n *\n * @param focalPoint - The focal point to move.\n * @param position - The camera position to move.\n * @param sliceRange - The scroll range used to find the current\n * position in the stack, as well as prevent scrolling past the extent of the volume.\n * @param viewPlaneNormal - The normal direction of the camera.\n * @param spacingInNormalDirection - The spacing of frames the normal direction of the camera.\n * @param deltaFrames - The number of frames to jump.\n *\n * @returns The `newFocalPoint` and `newPosition` of the camera.\n */\nexport default function snapFocalPointToSlice(\n focalPoint: Point3,\n position: Point3,\n sliceRange: ActorSliceRange,\n viewPlaneNormal: Point3,\n spacingInNormalDirection: number,\n deltaFrames: number\n): { newFocalPoint: Point3; newPosition: Point3 } {\n const { min, max, current } = sliceRange;\n\n // Get the current offset off the camera position so we can add it on at the end.\n const posDiffFromFocalPoint = vec3.create();\n\n vec3.sub(posDiffFromFocalPoint, <vec3>position, <vec3>focalPoint);\n\n // Now we can see how many steps there are in this direction\n const steps = Math.round((max - min) / spacingInNormalDirection);\n\n // Find out current frameIndex\n const fraction = (current - min) / (max - min);\n const floatingStepNumber = fraction * steps;\n let frameIndex = Math.round(floatingStepNumber);\n\n // Dolly the focal point back to min slice focal point.\n let newFocalPoint = <Point3>[\n focalPoint[0] -\n viewPlaneNormal[0] * floatingStepNumber * spacingInNormalDirection,\n focalPoint[1] -\n viewPlaneNormal[1] * floatingStepNumber * spacingInNormalDirection,\n focalPoint[2] -\n viewPlaneNormal[2] * floatingStepNumber * spacingInNormalDirection,\n ];\n\n // Increment the slice number by deltaFrames.\n frameIndex += deltaFrames;\n\n // Clamp sliceNumber to volume.\n if (frameIndex > steps) {\n frameIndex = steps;\n } else if (frameIndex < 0) {\n frameIndex = 0;\n }\n\n // Dolly the focal towards to the correct frame focal point.\n const newSlicePosFromMin = frameIndex * spacingInNormalDirection;\n\n newFocalPoint = <Point3>[\n newFocalPoint[0] + viewPlaneNormal[0] * newSlicePosFromMin,\n newFocalPoint[1] + viewPlaneNormal[1] * newSlicePosFromMin,\n newFocalPoint[2] + viewPlaneNormal[2] * newSlicePosFromMin,\n ];\n\n const newPosition = <Point3>[\n newFocalPoint[0] + posDiffFromFocalPoint[0],\n newFocalPoint[1] + posDiffFromFocalPoint[1],\n newFocalPoint[2] + posDiffFromFocalPoint[2],\n ];\n\n return { newFocalPoint, newPosition };\n}\n","import { getRenderingEngine } from '../RenderingEngine';\nimport { getRenderingEngines } from '../RenderingEngine/getRenderingEngine';\nimport { IStackViewport, IVolumeViewport } from '../types';\n\ntype Viewport = IStackViewport | IVolumeViewport;\n\n/**\n * Get the viewport that is rendering the image with the given imageURI (imageId without\n * the loader schema), this can be a stackViewport or a volumeViewport.\n *\n * @param renderingEngine - The rendering engine that is rendering the viewports\n * @param imageURI - The imageURI of the image that is requested\n * @returns A Viewport\n */\nexport default function getViewportsWithImageURI(\n imageURI: string,\n renderingEngineId?: string\n): Array<Viewport> {\n // If rendering engine is not provided, use all rendering engines\n let renderingEngines;\n if (renderingEngineId) {\n renderingEngines = [getRenderingEngine(renderingEngineId)];\n } else {\n renderingEngines = getRenderingEngines();\n }\n\n const viewports = [];\n renderingEngines.forEach((renderingEngine) => {\n const stackViewports = renderingEngine.getStackViewports();\n\n const filteredStackViewports = stackViewports.filter((viewport) =>\n viewport.hasImageURI(imageURI)\n );\n\n // If no stack viewport found but a volumeViewport is rendering the same data\n const volumeViewports = renderingEngine.getVolumeViewports();\n\n const filteredVolumeViewports = volumeViewports.filter((viewport) =>\n viewport.hasImageURI(imageURI)\n );\n\n viewports.push(...filteredStackViewports, ...filteredVolumeViewports);\n });\n\n return viewports;\n}\n","import { vec3 } from 'gl-matrix';\nimport { planar } from '.';\nimport { metaData } from '..';\nimport { IStackViewport, Point3 } from '../types';\n\n/**\n * Given a point in 3D space and a viewport it returns the index of the closest imageId, it assumes that stack images are sorted according to their sliceLocation\n * @param point - [A, B, C] coordinates of the point in 3D space\n * @param viewport - The StackViewport to search for the closest imageId\n *\n * @returns The imageId index of the closest imageId or null if no imageId is found\n */\nexport default function getClosestStackImageIndexForPoint(\n point: Point3,\n viewport: IStackViewport\n): number | null {\n const minimalDistance = calculateMinimalDistanceForStackViewport(\n point,\n viewport\n );\n return minimalDistance ? minimalDistance.index : null;\n}\n\n//assumes that imageIds are sorted by slice location\nexport function calculateMinimalDistanceForStackViewport(\n point: Point3,\n viewport: IStackViewport\n): { distance: number; index: number } | null {\n const imageIds = viewport.getImageIds();\n const currentImageIdIndex = viewport.getCurrentImageIdIndex();\n\n if (imageIds.length === 0) return null;\n\n const getDistance = (imageId: string): null | number => {\n const planeMetadata = getPlaneMetadata(imageId);\n if (!planeMetadata) return null;\n const plane = planar.planeEquation(\n planeMetadata.planeNormal,\n planeMetadata.imagePositionPatient\n );\n const distance = planar.planeDistanceToPoint(plane, point);\n return distance;\n };\n\n const closestStack = {\n distance: getDistance(imageIds[currentImageIdIndex]) ?? Infinity,\n index: currentImageIdIndex,\n };\n\n //check higher indices\n const higherImageIds = imageIds.slice(currentImageIdIndex + 1);\n\n for (let i = 0; i < higherImageIds.length; i++) {\n const id = higherImageIds[i];\n const distance = getDistance(id);\n if (distance === null) continue;\n if (distance <= closestStack.distance) {\n closestStack.distance = distance;\n closestStack.index = i + currentImageIdIndex + 1;\n } else break;\n }\n //check lower indices\n const lowerImageIds = imageIds.slice(0, currentImageIdIndex);\n for (let i = lowerImageIds.length - 1; i >= 0; i--) {\n const id = lowerImageIds[i];\n const distance = getDistance(id);\n if (distance === null || distance === closestStack.distance) continue;\n if (distance < closestStack.distance) {\n closestStack.distance = distance;\n closestStack.index = i;\n } else break;\n }\n return closestStack.distance === Infinity ? null : closestStack;\n}\n\nfunction getPlaneMetadata(imageId: string): null | {\n rowCosines: Point3;\n columnCosines: Point3;\n imagePositionPatient: Point3;\n planeNormal: Point3;\n} {\n const targetImagePlane = metaData.get('imagePlaneModule', imageId);\n\n if (\n !targetImagePlane ||\n !(\n targetImagePlane.rowCosines instanceof Array &&\n targetImagePlane.rowCosines.length === 3\n ) ||\n !(\n targetImagePlane.columnCosines instanceof Array &&\n targetImagePlane.columnCosines.length === 3\n ) ||\n !(\n targetImagePlane.imagePositionPatient instanceof Array &&\n targetImagePlane.imagePositionPatient.length === 3\n )\n ) {\n return null;\n }\n const {\n rowCosines,\n columnCosines,\n imagePositionPatient,\n }: {\n rowCosines: Point3;\n columnCosines: Point3;\n imagePositionPatient: Point3;\n } = targetImagePlane;\n\n const rowVec = vec3.set(vec3.create(), ...rowCosines);\n const colVec = vec3.set(vec3.create(), ...columnCosines);\n const planeNormal = vec3.cross(vec3.create(), rowVec, colVec) as Point3;\n\n return { rowCosines, columnCosines, imagePositionPatient, planeNormal };\n}\n","import { mat4 } from 'gl-matrix';\nimport { addProvider } from '../metaData';\n\nconst state = {};\n\n/**\n * Simple metadataProvider object to store metadata for spatial registration module.\n */\nconst spatialRegistrationMetadataProvider = {\n /* Adding a new entry to the state object. */\n add: (query: string[], payload: mat4): void => {\n const [viewportId1, viewportId2] = query;\n const entryId = `${viewportId1}_${viewportId2}`;\n\n if (!state[entryId]) {\n state[entryId] = {};\n }\n\n state[entryId] = payload;\n },\n\n get: (type: string, query: string[]): mat4 => {\n if (type !== 'spatialRegistrationModule') {\n return;\n }\n\n const [viewportId1, viewportId2] = query;\n\n // check both ways\n const entryId = `${viewportId1}_${viewportId2}`;\n\n if (state[entryId]) {\n return state[entryId];\n }\n\n const entryIdReverse = `${viewportId2}_${viewportId1}`;\n\n if (state[entryIdReverse]) {\n return mat4.invert(mat4.create(), state[entryIdReverse]);\n }\n },\n};\n\naddProvider(\n spatialRegistrationMetadataProvider.get.bind(\n spatialRegistrationMetadataProvider\n )\n);\n\nexport default spatialRegistrationMetadataProvider;\n","import { vec3, mat4 } from 'gl-matrix';\nimport { IStackViewport } from '../types';\nimport { StackViewport } from '../RenderingEngine';\nimport spatialRegistrationMetadataProvider from './spatialRegistrationMetadataProvider';\nimport { metaData } from '..';\nimport isEqual from './isEqual';\n\n/**\n * It calculates the registration matrix between two viewports (currently only\n * translation is supported)\n * If the viewports are in the same frame of reference, it will return early,\n * but otherwise it will use the current image's metadata to calculate the\n * translation between the two viewports and adds it to the spatialRegistrationModule\n * metadata provider\n *\n *\n * @param viewport1 - The first stack viewport\n * @param viewport2 - The second stack viewport\n */\nfunction calculateViewportsSpatialRegistration(\n viewport1: IStackViewport,\n viewport2: IStackViewport\n): void {\n if (\n !(viewport1 instanceof StackViewport) ||\n !(viewport2 instanceof StackViewport)\n ) {\n throw new Error(\n 'calculateViewportsSpatialRegistration: Both viewports must be StackViewports, volume viewports are not supported yet'\n );\n }\n\n const isSameFrameOfReference =\n viewport1.getFrameOfReferenceUID() === viewport2.getFrameOfReferenceUID();\n\n if (isSameFrameOfReference) {\n return;\n }\n\n const imageId1 = viewport1.getCurrentImageId();\n const imageId2 = viewport2.getCurrentImageId();\n\n const imagePlaneModule1 = metaData.get('imagePlaneModule', imageId1);\n const imagePlaneModule2 = metaData.get('imagePlaneModule', imageId2);\n\n const isSameImagePlane =\n imagePlaneModule1 &&\n imagePlaneModule2 &&\n isEqual(\n imagePlaneModule1.imageOrientationPatient,\n imagePlaneModule2.imageOrientationPatient\n );\n\n if (!isSameImagePlane) {\n throw new Error(\n 'Viewport spatial registration only supported for same orientation (hence translation only) for now'\n );\n }\n\n const imagePositionPatient1 = imagePlaneModule1.imagePositionPatient;\n const imagePositionPatient2 = imagePlaneModule2.imagePositionPatient;\n\n const translation = vec3.subtract(\n vec3.create(),\n imagePositionPatient1,\n imagePositionPatient2\n );\n\n const mat = mat4.fromTranslation(mat4.create(), translation);\n\n spatialRegistrationMetadataProvider.add([viewport1.id, viewport2.id], mat);\n}\n\nexport default calculateViewportsSpatialRegistration;\n","import {\n IImageData,\n IStackViewport,\n IVolumeViewport,\n Point2,\n Point3,\n} from '../types';\n\n/**\n * Given a viewport, return the corners of the image in the viewport in world coordinates.\n * Note that this is different than the corners of the canvas in world coordinates since\n * an image can be zoomed out and the canvas can be larger than the image; hence, the\n * corners of the canvas in world coordinates will be outside the image.\n *\n * @param viewport - The viewport to get the corners of.\n * @returns The corners of the image in the viewport in world coordinates.\n */\nexport default function getViewportImageCornersInWorld(\n viewport: IStackViewport | IVolumeViewport\n): Point3[] {\n const { imageData, dimensions } = viewport.getImageData() as IImageData;\n const { canvas } = viewport;\n\n const topLeftCanvas: Point2 = [0, 0];\n const topRightCanvas: Point2 = [canvas.width, 0];\n const bottomRightCanvas: Point2 = [canvas.width, canvas.height];\n const bottomLeftCanvas: Point2 = [0, canvas.height];\n\n const topLeftWorld = viewport.canvasToWorld(topLeftCanvas);\n const topRightWorld = viewport.canvasToWorld(topRightCanvas);\n const bottomRightWorld = viewport.canvasToWorld(bottomRightCanvas);\n const bottomLeftWorld = viewport.canvasToWorld(bottomLeftCanvas);\n\n const topLeftImage = imageData.worldToIndex(topLeftWorld);\n const topRightImage = imageData.worldToIndex(topRightWorld);\n const bottomRightImage = imageData.worldToIndex(bottomRightWorld);\n const bottomLeftImage = imageData.worldToIndex(bottomLeftWorld);\n\n return _getStackViewportImageCorners({\n dimensions,\n imageData,\n topLeftImage,\n topRightImage,\n bottomRightImage,\n bottomLeftImage,\n topLeftWorld,\n topRightWorld,\n bottomRightWorld,\n bottomLeftWorld,\n });\n}\n\nfunction _getStackViewportImageCorners({\n dimensions,\n imageData,\n topLeftImage,\n topRightImage,\n bottomRightImage,\n bottomLeftImage,\n topLeftWorld,\n topRightWorld,\n bottomRightWorld,\n bottomLeftWorld,\n}) {\n const topLeftImageWorld = _isInBounds(topLeftImage, dimensions)\n ? topLeftWorld\n : (imageData.indexToWorld([0, 0, 0]) as Point3);\n\n const topRightImageWorld = _isInBounds(topRightImage, dimensions)\n ? topRightWorld\n : (imageData.indexToWorld([dimensions[0] - 1, 0, 0]) as Point3);\n\n const bottomRightImageWorld = _isInBounds(bottomRightImage, dimensions)\n ? bottomRightWorld\n : (imageData.indexToWorld([\n dimensions[0] - 1,\n dimensions[1] - 1,\n 0,\n ]) as Point3);\n\n const bottomLeftImageWorld = _isInBounds(bottomLeftImage, dimensions)\n ? bottomLeftWorld\n : (imageData.indexToWorld([0, dimensions[1] - 1, 0]) as Point3);\n\n return [\n topLeftImageWorld,\n topRightImageWorld,\n bottomLeftImageWorld,\n bottomRightImageWorld,\n ];\n}\n\nfunction _isInBounds(imageCoord, dimensions) {\n return (\n imageCoord[0] > 0 ||\n imageCoord[0] < dimensions[0] - 1 ||\n imageCoord[1] > 0 ||\n imageCoord[1] < dimensions[1] - 1 ||\n imageCoord[2] > 0 ||\n imageCoord[2] < dimensions[2] - 1\n );\n}\n","import vtkColorTransferFunction from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction';\nimport vtkPiecewiseFunction from '@kitware/vtk.js/Common/DataModel/PiecewiseFunction';\nimport { ViewportPreset } from '../types';\nimport { VolumeActor } from '../types/IActor';\n\n/**\n * Applies a preset to a volume actor.\n *\n * @param actor - The volume actor to apply the preset to.\n * @param preset - The preset to apply.\n */\nexport default function applyPreset(actor: VolumeActor, preset: ViewportPreset) {\n // Create color transfer function\n const colorTransferArray = preset.colorTransfer\n .split(' ')\n .splice(1)\n .map(parseFloat);\n\n const { shiftRange } = getShiftRange(colorTransferArray);\n const min = shiftRange[0];\n const width = shiftRange[1] - shiftRange[0];\n const cfun = vtkColorTransferFunction.newInstance();\n const normColorTransferValuePoints = [];\n for (let i = 0; i < colorTransferArray.length; i += 4) {\n let value = colorTransferArray[i];\n const r = colorTransferArray[i + 1];\n const g = colorTransferArray[i + 2];\n const b = colorTransferArray[i + 3];\n\n value = (value - min) / width;\n normColorTransferValuePoints.push([value, r, g, b]);\n }\n\n applyPointsToRGBFunction(normColorTransferValuePoints, shiftRange, cfun);\n\n actor.getProperty().setRGBTransferFunction(0, cfun);\n\n // Create scalar opacity function\n const scalarOpacityArray = preset.scalarOpacity\n .split(' ')\n .splice(1)\n .map(parseFloat);\n\n const ofun = vtkPiecewiseFunction.newInstance();\n const normPoints = [];\n for (let i = 0; i < scalarOpacityArray.length; i += 2) {\n let value = scalarOpacityArray[i];\n const opacity = scalarOpacityArray[i + 1];\n\n value = (value - min) / width;\n\n normPoints.push([value, opacity]);\n }\n\n applyPointsToPiecewiseFunction(normPoints, shiftRange, ofun);\n\n actor.getProperty().setScalarOpacity(0, ofun);\n\n const [\n gradientMinValue,\n gradientMinOpacity,\n gradientMaxValue,\n gradientMaxOpacity,\n ] = preset.gradientOpacity.split(' ').splice(1).map(parseFloat);\n\n actor.getProperty().setUseGradientOpacity(0, true);\n actor.getProperty().setGradientOpacityMinimumValue(0, gradientMinValue);\n actor.getProperty().setGradientOpacityMinimumOpacity(0, gradientMinOpacity);\n actor.getProperty().setGradientOpacityMaximumValue(0, gradientMaxValue);\n actor.getProperty().setGradientOpacityMaximumOpacity(0, gradientMaxOpacity);\n\n if (preset.interpolation === '1') {\n actor.getProperty().setInterpolationTypeToFastLinear();\n //actor.getProperty().setInterpolationTypeToLinear()\n }\n\n const ambient = parseFloat(preset.ambient);\n const diffuse = parseFloat(preset.diffuse);\n const specular = parseFloat(preset.specular);\n const specularPower = parseFloat(preset.specularPower);\n\n actor.getProperty().setAmbient(ambient);\n actor.getProperty().setDiffuse(diffuse);\n actor.getProperty().setSpecular(specular);\n actor.getProperty().setSpecularPower(specularPower);\n}\n\nfunction getShiftRange(colorTransferArray) {\n // Credit to paraview-glance\n // https://github.com/Kitware/paraview-glance/blob/3fec8eeff31e9c19ad5b6bff8e7159bd745e2ba9/src/components/controls/ColorBy/script.js#L133\n\n // shift range is original rgb/opacity range centered around 0\n let min = Infinity;\n let max = -Infinity;\n for (let i = 0; i < colorTransferArray.length; i += 4) {\n min = Math.min(min, colorTransferArray[i]);\n max = Math.max(max, colorTransferArray[i]);\n }\n\n const center = (max - min) / 2;\n\n return {\n shiftRange: [-center, center],\n min,\n max,\n };\n}\n\nfunction applyPointsToRGBFunction(points, range, cfun) {\n const width = range[1] - range[0];\n const rescaled = points.map(([x, r, g, b]) => [\n x * width + range[0],\n r,\n g,\n b,\n ]);\n\n cfun.removeAllPoints();\n rescaled.forEach(([x, r, g, b]) => cfun.addRGBPoint(x, r, g, b));\n\n return rescaled;\n}\n\nfunction applyPointsToPiecewiseFunction(points, range, pwf) {\n const width = range[1] - range[0];\n const rescaled = points.map(([x, y]) => [x * width + range[0], y]);\n\n pwf.removeAllPoints();\n rescaled.forEach(([x, y]) => pwf.addPoint(x, y));\n\n return rescaled;\n}\n","import BaseVolumeViewport from '../BaseVolumeViewport';\nimport type {\n IVolumeInput,\n IRenderingEngine,\n IVolumeViewport,\n} from '../../types';\n\n/**\n * Similar to {@link addVolumesToViewports} it adds volumes to viewports; however,\n * this method will Set the volumes on the viewports which means that the previous\n * volumes will be removed.\n *\n * @param renderingEngine - The rendering engine to use to get viewports from\n * @param volumeInputs - Array of volume inputs including volumeId. Other properties\n * such as visibility, callback, blendMode, slabThickness are optional\n * @param viewportIds - Array of viewport IDs to add the volume to\n * @param immediateRender - If true, the volumes will be rendered immediately\n * @returns A promise that resolves when all volumes have been added\n */\nasync function setVolumesForViewports(\n renderingEngine: IRenderingEngine,\n volumeInputs: Array<IVolumeInput>,\n viewportIds: Array<string>,\n immediateRender = false,\n suppressEvents = false\n): Promise<void> {\n // Check if all viewports are volumeViewports\n viewportIds.forEach((viewportId) => {\n const viewport = renderingEngine.getViewport(viewportId);\n\n if (!viewport) {\n throw new Error(`Viewport with Id ${viewportId} does not exist`);\n }\n\n // if not instance of BaseVolumeViewport, throw\n if (!(viewport instanceof BaseVolumeViewport)) {\n throw new Error('setVolumesForViewports only supports VolumeViewport and VolumeViewport3D');\n }\n });\n\n const setVolumePromises = viewportIds.map(async (viewportId) => {\n const viewport = renderingEngine.getViewport(viewportId) as IVolumeViewport;\n\n await viewport.setVolumes(volumeInputs, immediateRender, suppressEvents);\n });\n\n await Promise.all(setVolumePromises);\n\n return;\n}\n\nexport default setVolumesForViewports;\n","import { VolumeViewport } from '../';\nimport BaseVolumeViewport from '../BaseVolumeViewport';\nimport type { IVolumeInput, IRenderingEngine } from '../../types';\n\n/**\n * For each provided viewport it adds a volume to the viewport using the\n * provided renderingEngine\n *\n *\n * @param renderingEngine - The rendering engine to use to get viewports from\n * @param volumeInputs - Array of volume inputs including volumeId. Other properties\n * such as visibility, callback, blendMode, slabThickness are optional\n * @param viewportIds - Array of viewport IDs to add the volume to\n * @param immediateRender - If true, the volumes will be rendered immediately\n * @returns A promise that resolves when all volumes have been added\n */\nasync function addVolumesToViewports(\n renderingEngine: IRenderingEngine,\n volumeInputs: Array<IVolumeInput>,\n viewportIds: Array<string>,\n immediateRender = false,\n suppressEvents = false\n): Promise<void> {\n // Check if all viewports are volumeViewports\n for (const viewportId of viewportIds) {\n const viewport = renderingEngine.getViewport(viewportId);\n\n if (!viewport) {\n throw new Error(`Viewport with Id ${viewportId} does not exist`);\n }\n\n // if not instance of BaseVolumeViewport, throw\n if (!(viewport instanceof BaseVolumeViewport)) {\n console.warn(\n `Viewport with Id ${viewportId} is not a BaseVolumeViewport. Cannot add volume to this viewport.`\n );\n\n return;\n }\n }\n\n const addVolumePromises = viewportIds.map(async (viewportId) => {\n const viewport = renderingEngine.getViewport(viewportId) as VolumeViewport;\n\n await viewport.addVolumes(volumeInputs, immediateRender, suppressEvents);\n });\n\n await Promise.all(addVolumePromises);\n return;\n}\n\nexport default addVolumesToViewports;\n"],"names":["root","factory","exports","module","require","define","amd","self","__WEBPACK_EXTERNAL_MODULE__468__","__WEBPACK_EXTERNAL_MODULE__197__","__WEBPACK_EXTERNAL_MODULE__821__","__WEBPACK_EXTERNAL_MODULE__976__","__WEBPACK_EXTERNAL_MODULE__807__","__WEBPACK_EXTERNAL_MODULE__847__","__WEBPACK_EXTERNAL_MODULE__739__","__WEBPACK_EXTERNAL_MODULE__215__","__WEBPACK_EXTERNAL_MODULE__283__","__WEBPACK_EXTERNAL_MODULE__785__","__WEBPACK_EXTERNAL_MODULE__953__","__WEBPACK_EXTERNAL_MODULE__9__","__WEBPACK_EXTERNAL_MODULE__864__","__WEBPACK_EXTERNAL_MODULE__896__","__WEBPACK_EXTERNAL_MODULE__861__","__WEBPACK_EXTERNAL_MODULE__795__","__WEBPACK_EXTERNAL_MODULE__281__","__WEBPACK_EXTERNAL_MODULE__329__","__WEBPACK_EXTERNAL_MODULE__673__","__WEBPACK_EXTERNAL_MODULE__348__","__WEBPACK_EXTERNAL_MODULE__70__","__WEBPACK_EXTERNAL_MODULE__474__","__WEBPACK_EXTERNAL_MODULE__610__","__WEBPACK_EXTERNAL_MODULE__21__","__WEBPACK_EXTERNAL_MODULE__643__","__WEBPACK_EXTERNAL_MODULE__128__","__WEBPACK_EXTERNAL_MODULE__664__","__WEBPACK_EXTERNAL_MODULE__973__","__WEBPACK_EXTERNAL_MODULE__394__","__WEBPACK_EXTERNAL_MODULE__582__","__WEBPACK_EXTERNAL_MODULE__482__","__WEBPACK_EXTERNAL_MODULE__343__","__WEBPACK_EXTERNAL_MODULE__363__","__WEBPACK_EXTERNAL_MODULE__982__","__WEBPACK_EXTERNAL_MODULE__130__","__WEBPACK_EXTERNAL_MODULE__298__","__WEBPACK_EXTERNAL_MODULE__398__","__WEBPACK_EXTERNAL_MODULE__388__","__WEBPACK_EXTERNAL_MODULE__120__","__WEBPACK_EXTERNAL_MODULE__395__","__WEBPACK_EXTERNAL_MODULE__948__","__WEBPACK_EXTERNAL_MODULE__478__","__WEBPACK_EXTERNAL_MODULE__441__","_typeof","_regeneratorRuntime","__esModule","Op","Object","prototype","hasOwn","hasOwnProperty","$Symbol","Symbol","iteratorSymbol","iterator","asyncIteratorSymbol","asyncIterator","toStringTagSymbol","toStringTag","obj","key","value","defineProperty","enumerable","configurable","writable","err","wrap","innerFn","outerFn","tryLocsList","protoGenerator","Generator","generator","create","context","Context","_invoke","state","method","arg","Error","undefined","done","delegate","delegateResult","maybeInvokeDelegate","ContinueSentinel","sent","_sent","dispatchException","abrupt","record","tryCatch","type","fn","call","GeneratorFunction","GeneratorFunctionPrototype","IteratorPrototype","this","getProto","getPrototypeOf","NativeIteratorPrototype","values","Gp","defineIteratorMethods","forEach","AsyncIterator","PromiseImpl","invoke","resolve","reject","result","__await","then","unwrapped","error","previousPromise","callInvokeWithMethodAndArg","TypeError","info","resultName","next","nextLoc","pushTryEntry","locs","entry","tryLoc","catchLoc","finallyLoc","afterLoc","tryEntries","push","resetTryEntry","completion","reset","iterable","iteratorMethod","isNaN","length","i","doneResult","displayName","isGeneratorFunction","genFun","ctor","constructor","name","mark","setPrototypeOf","__proto__","awrap","async","Promise","iter","keys","object","reverse","pop","skipTempReset","prev","charAt","slice","stop","rootRecord","rval","exception","handle","loc","caught","hasCatch","hasFinally","finallyEntry","complete","finish","thrown","delegateYield","runtime","regeneratorRuntime","accidentalStrictMode","globalThis","Function","HASH_UNDEFINED","MAX_SAFE_INTEGER","argsTag","boolTag","dateTag","funcTag","genTag","mapTag","numberTag","objectTag","promiseTag","regexpTag","setTag","stringTag","symbolTag","weakMapTag","arrayBufferTag","dataViewTag","float32Tag","float64Tag","int8Tag","int16Tag","int32Tag","uint8Tag","uint8ClampedTag","uint16Tag","uint32Tag","reFlags","reIsHostCtor","reIsUint","cloneableTags","freeGlobal","g","freeSelf","freeExports","nodeType","freeModule","moduleExports","addMapEntry","map","pair","set","addSetEntry","add","arrayReduce","array","iteratee","accumulator","initAccum","index","isHostObject","toString","e","mapToArray","Array","size","overArg","func","transform","setToArray","uid","arrayProto","funcProto","objectProto","coreJsData","maskSrcKey","exec","IE_PROTO","funcToString","objectToString","reIsNative","RegExp","replace","Buffer","Uint8Array","getPrototype","objectCreate","propertyIsEnumerable","splice","nativeGetSymbols","getOwnPropertySymbols","nativeIsBuffer","isBuffer","nativeKeys","DataView","getNative","Map","Set","WeakMap","nativeCreate","dataViewCtorString","toSource","mapCtorString","promiseCtorString","setCtorString","weakMapCtorString","symbolProto","symbolValueOf","valueOf","Hash","entries","clear","ListCache","MapCache","Stack","__data__","assignValue","objValue","eq","assocIndexOf","baseClone","isDeep","isFull","customizer","stack","isObject","isArr","isArray","input","initCloneArray","source","copyArray","tag","getTag","isFunc","buffer","copy","cloneBuffer","isPrototype","proto","initCloneObject","copyObject","getSymbols","copySymbols","baseAssign","cloneFunc","symbol","Ctor","cloneArrayBuffer","dataView","byteOffset","byteLength","cloneDataView","typedArray","cloneTypedArray","cloneMap","regexp","lastIndex","cloneRegExp","cloneSet","initCloneByTag","stacked","get","props","keysFunc","symbolsFunc","offset","arrayPush","baseGetAllKeys","getAllKeys","arrayEach","subValue","arrayBuffer","newValue","getMapData","data","getValue","isFunction","test","baseIsNative","has","cache","pairs","LARGE_ARRAY_SIZE","isIndex","other","ArrayBuffer","ctorString","isArrayLike","isLength","inherited","isObjectLike","isArrayLikeObject","isArguments","n","baseTimes","String","skipIndexes","arrayLikeKeys","baseKeys","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","id","loaded","__webpack_modules__","getter","d","a","definition","o","window","prop","r","nmd","paths","children","Events","RequestType","ViewportType","InterpolationType","BlendModes","BlendMode","vtkConstants","COMPOSITE_BLEND","MAXIMUM_INTENSITY_BLEND","MINIMUM_INTENSITY_BLEND","AVERAGE_INTENSITY_BLEND","OrientationAxis","hotIron","numOfColors","colors","pet","numColors","hotMetalBlue","pet20Step","gray","gamma","segmentedData","red","green","blue","jet","hsv","hot","cool","spring","summer","autumn","winter","bone","copper","spectral","coolwarm","blues","RENDERING_DEFAULTS","MINIMUM_SLAB_THICKNESS","MAXIMUM_RAY_DISTANCE","freeze","deepFreeze","getOwnPropertyNames","axial","viewPlaneNormal","viewUp","sagittal","coronal","gradientOpacity","specularPower","scalarOpacity","specular","shade","ambient","colorTransfer","diffuse","interpolation","asyncGeneratorStep","gen","_next","_throw","_asyncToGenerator","args","arguments","apply","_defineProperties","target","descriptor","_createClass","Constructor","protoProps","staticProps","_classCallCheck","instance","_defineProperty","vtkStreamingOpenGLTexture","publicAPI","model","classHierarchy","superCreate3DFilterableFromRaw","create3DFilterableFromRaw","width","height","depth","numComps","dataType","inputDataType","inputNumComps","update3DFromRaw","updatedFrames","bytesPerVoxel","TypedArrayConstructor","_openGLRenderWindow","activateTexture","createTexture","bind","Int16Array","Float32Array","fillSubImage3D","generateMipmap","deactivate","frameIndex","zOffset","components","rowLength","gl","MAX_TEXTURE_SIZE","getParameter","blockHeight","Math","floor","multiRowBlockLength","min","multiRowBlockLengthInBytes","normalBlocks","lastBlockHeight","multiRowLastBlockLength","block","yOffset","texSubImage3D","format","openGLDataType","getTextureParameters","setUpdatedFrame","DEFAULT_VALUES","extend","initialValues","assign","vtkOpenGLTexture","newInstance","macro","ImageVolume","volumeId","metadata","dimensions","spacing","origin","direction","imageData","scalarData","sizeInBytes","numVoxels","scaling","referencedVolumeId","CornerstoneEventTarget","listeners","callback","indexOf","stackLength","event","defaultPrevented","triggerEvent","el","eventTarget","detail","CustomEvent","cancelable","dispatchEvent","imageIdToURI","imageId","colonIndex","substring","Cache","newMaxCacheSize","errorMessage","_maxCacheSize","getBytesAvailable","_imageCacheSize","_volumeCacheSize","imageLoadObject","_imageCache","cancelFn","decache","delete","cachedVolume","_volumeCache","volumeLoadObject","volume","cancelLoading","imageIterator","removeImageLoadObject","purgeVolumeCache","volumeIterator","removeVolumeLoadObject","timeStamp","Date","now","cachedImage","_incrementImageCacheSize","eventDetails","_decacheImage","_incrementVolumeCacheSize","_decacheVolume","increment","getMaxCacheSize","getCacheSize","numBytes","volumeImageIds","bytesAvailable","cachedImages","from","sort","b","cachedImageIds","im","imageIdsToPurge","filter","includes","promise","sharedCacheKey","image","toFixed","isCacheable","decacheIfNecessaryUntilBytesAvailable","console","warn","catch","volumeIds","imageIdToUse","imageIds","imageIdIndex","imageURIToUse","foundImageId","find","uuidv4","c","crypto","getRandomValues","createInternalVTKRepresentation","numComponents","PhotometricInterpretation","scalarArray","vtkDataArray","numberOfComponents","vtkImageData","setDimensions","setSpacing","setDirection","setOrigin","getPointData","setScalars","unknownVolumeLoader","volumeLoaders","loadVolumeFromVolumeLoader","options","scheme","loader","errorObject","loadVolume","createAndCacheVolume","createAndCacheDerivedVolume","referencedVolume","targetBuffer","scalarLength","TypedArray","sharedArrayBuffer","SharedArrayBuffer","volumeScalarData","derivedImageData","derivedVolume","cloneDeep","createLocalVolume","preventCache","registerVolumeLoader","volumeLoader","registerUnknownVolumeLoader","oldVolumeLoader","vtkSharedVolumeMapper","superDelete","scalarTexture","vtkVolumeMapper","createVolumeMapper","volumeMapper","setInputData","getSpacing","sampleDistance","setMaximumSamplesPerRay","setSampleDistance","setScalarTexture","RequestPoolManager","interaction","thumbnail","prefetch","requestPool","grabDelay","awake","numRequests","maxNumRequests","timeoutHandle","clearTimeout","requestFn","additionalDetails","priority","requestDetails","startGrabbing","filterFunction","requestType","requestsToSend","getNextRequest","finally","startAgain","getSortedPriorityGroups","shift","hasRemainingInteractionRequests","sendRequests","hasRemainingThumbnailRequests","hasRemainingPrefetchRequests","setTimeout","Number","imageLoadPoolManager","setMaxSimultaneousRequests","unknownImageLoader","imageLoaders","loadImageFromCacheOrVolume","cachedVolumeInfo","loadStatus","convertToCornerstoneImage","loadImageFromImageLoader","loadImage","loadAndCacheImage","loadAndCacheImages","allPromises","cancelLoadImage","cancelLoadImages","cancelLoadAll","requests","loadObject","cancel","registerImageLoader","imageLoader","registerUnknownImageLoader","oldImageLoader","unregisterAllImageLoaders","providers","addProvider","provider","removeProvider","removeAllProviders","getMetaData","query","toWindowLevel","low","high","windowWidth","abs","windowCenter","toLowHighRange","lower","upper","getMinMax","storedPixelData","storedPixel","max","numPixels","REQUEST_TYPE","volumeActor","imageVolume","voi","getVOIFromMetadata","getVOIFromMinMax","handlePreScaledVolume","getProperty","getRGBTransferFunction","setMappingRange","metaData","modality","isPrescaled","voiLutModule","windowLevel","generalSeriesModule","modalityLutModule","numImages","bytesPerImage","voxelsPerImage","bytePerPixel","BYTES_PER_ELEMENT","scalingParameters","rescaleSlope","rescaleIntercept","suvFactor","scalingParametersToUse","suvbw","preScale","enabled","imageScalarData","getPixelData","_getImageScalarDataFromImageVolume","volumeBuffer","volumeBufferView","setDefaultVolumeVOI","element","viewportId","suppressEvents","blendMode","setBlendMode","vtkVolume","setMapper","triggerVOIModified","voiRange","getRange","voiModifiedEventDetail","range","createVolumeActor","VIEWPORT_ELEMENT","CANVAS_CSS_CLASS","getOrCreateCanvas","canvasSelector","viewportElement","internalDiv","querySelector","div","document","createElement","style","position","classList","appendChild","createViewportElement","canvas","createCanvas","arr","len","arr2","minLen","_toConsumableArray","re","renderingEngineId","vtkWarningMacro","vtkStreamingOpenGLVolumeMapper","buildBufferObjects","ren","actor","currentInput","scalars","getScalars","vprop","jitterTexture","getHandle","oTable","random","setMinificationFilter","Filter","setMagnificationFilter","create2DFromRaw","VtkDataTypes","numComp","getNumberOfComponents","numIComps","getIndependentComponents","getMTime","opacityTextureString","oWidth","oSize","ofTable","tmpTable","ofun","getScalarOpacity","opacityFactor","renderable","getSampleDistance","getScalarOpacityUnitDistance","oRange","getTable","opacityTexture","releaseGraphicsResources","getWebgl2","getExtension","colorTextureString","cWidth","cTable","cfun","cRange","colorTexture","scalarTextureString","dims","getDimensions","previousTextureParameters","getDataType","getData","shouldReset","previousTextureSize","resetFormatAndType","getPreferSizeOverAccuracy","tris","getCABO","getElementCount","ptsArray","cellArray","Uint16Array","points","setName","cells","createVBO","Representation","cellOffset","VBOBuildTime","modified","setCameraShaderParameters","cellBO","program","getProgram","cam","openGLCamera","getRenderable","crange","getClippingRange","setUniformf","setIsPerformingCoordinateTransformation","keyMats","getKeyMatrices","actMats","openGLVolume","mat4","modelToView","wcvc","mcwc","bounds","getBounds","spc","pos","Float64Array","dir","dcxmin","dcxmax","dcymin","dcymax","vec3","getParallelProjection","t","vcpc","isUniformUsed","setUniformi","ext","getSpatialExtent","vsize","setUniform3f","indexToWorldVec3","i2wmat4","getIndexToWorld","idxToView","mat3","idxNormalMatrix","normalMatrix","getDirection","maxSamples","getMaximumSamplesPerRay","ceil","vctoijk","setUniform3i","volInfo","getVolumeInfo","getWidth","getHeight","xreps","xstride","ystride","normal","pos2","dist","getUseLabelOutline","worldToIndex","getWorldToIndex","setUniformMatrix","projectionToWorld","wcpc","getRenderTargetSize","getRenderTargetOffset","projectionToView","lastLightComplexity","lightNum","lightColor","getLights","light","getSwitch","dColor","getColor","intensity","getIntensity","setUniform3fArray","ldir","halfAngle","_useSmallViewport","_smallViewportWidth","_smallViewportHeight","openGLRenderer","getTiledSizeAndOrigin","usize","lowerLeftU","lowerLeftV","vtkOpenGLVolumeMapper","previousState","vtkStreamingOpenGLViewNodeFactory","createNode","dataObject","isDeleted","cpt","className","getClassName","overrides","getModelInitialValues","vn","setMyFactory","getScalarTexture","vtkViewNodeFactory","registerOverride","vtkOpenGLActor","vtkOpenGLActor2D","vtkOpenGLCamera","vtkOpenGLGlyph3DMapper","vtkOpenGLImageMapper","vtkOpenGLImageSlice","vtkOpenGLPolyDataMapper","vtkOpenGLPixelSpaceCallbackMapper","vtkOpenGLRenderer","vtkOpenGLSkybox","vtkOpenGLSphereMapper","vtkOpenGLStickMapper","vtkOpenGLVolume","vtkStreamingOpenGLRenderWindow","vtkOpenGLRenderWindow","myFactory","vtkOffscreenMultiRenderWindow","invokeResize","renderWindow","vtkRenderWindow","rendererMap","openGLRenderWindow","addView","interactor","vtkRenderWindowInteractor","setView","initialize","addRenderer","viewport","background","renderer","vtkRenderer","destroy","getInteractor","removeRenderer","getRenderer","getRenderers","resize","container","setSize","render","setContainer","_assertThisInitialized","ReferenceError","_getPrototypeOf","_superPropBase","property","_get","Reflect","receiver","base","desc","getOwnPropertyDescriptor","_setPrototypeOf","p","_inherits","subClass","superClass","_possibleConstructorReturn","transformWorldToIndex","worldPos","round","_slicedToArray","_i","_s","_e","_arr","_n","_d","isImageActor","isA","linePlaneIntersection","p0","p1","plane","x0","y0","z0","x1","y1","z1","A","B","C","planeEquation","point","threePlaneIntersection","firstPlane","secondPlane","thirdPlane","A1","B1","C1","D1","A2","B2","C2","D2","A3","B3","C3","D3","m0","m1","m2","m3","planeDistanceToPoint","signed","D","x","y","z","numerator","distance","sqrt","sign","hasNaNValues","some","Viewport","sx","sy","sWidth","sHeight","_actors","setAttribute","defaultOptions","_cloneDeep","isDisabled","renderingEngineCache","renderingEngine","getRenderingEngine","hasBeenDestroyed","offscreenMultiRenderWindow","renderViewport","immediate","flipHorizontal","flipVertical","getDefaultImageData","camera","getCamera","focalPoint","viewRight","viewUpToSet","viewPlaneNormalToSet","middleIJK","idx","centeredFocalPoint","indexToWorld","resetFocalPoint","_getFocalPointForResetCamera","resetPan","resetToCenter","panDir","panValue","getPanDir","mirrorVec","panDirMirror","newFocalPoint","newPosition","setCamera","actorEntry","getDefaultActor","getMapper","getInputData","getActors","actorUID","actors","removeAllActors","addActors","getActor","removeViewProp","actorUIDs","removeActor","resetCameraPanAndZoom","addActor","resetCamera","removeAllViewProps","_suppressCameraModifiedEvents","intersections","_getEdges","intersectionPoint","planar","_isInBounds","resetZoom","storeAsInitialCamera","previousCamera","computeVisiblePropBounds","activeCamera","getVtkActiveCamera","getViewPlaneNormal","getViewUp","radius","_getWorldDistanceViewUpAndViewRight","widthWorld","heightWorld","canvasSize","boundsAspectRatio","canvasAspectRatio","scaleFactor","parallelScale","w1","w2","w3","vtkMath","focalPointToSet","positionToSet","resetCameraClippingRange","clippingRangeToUse","setPhysicalScale","setPhysicalTranslation","viewAngle","clippingRange","modifiedCamera","setInitialCamera","RESET_CAMERA_EVENT","invokeEvent","triggerCameraModifiedEventIfNecessary","initialCamera","getFocalPoint","zero3","canvasToWorld","initialCanvasFocal","worldToCanvas","currentCanvasFocal","vec2","pan","delta2","getPan","delta","newFocal","getParallelScale","initialParallelScale","_getViewImageDataIntersections","point_x","point_y","point_z","getActiveCamera","vtkCamera","getPosition","parallelProjection","getViewAngle","cameraInterface","updatedCamera","flipH","flip","flipV","setViewUp","setDirectionOfProjection","setPosition","setFocalPoint","setParallelScale","setViewAngle","setClippingRange","updateClippingPlanesForActors","eventDetail","rotation","vtkPlanes","getClippingPlanes","slabThickness","setOrientationOfClippingPlanes","scaledDistance","setNormal","newOrigin1","newOrigin2","viewUpCorners","_getCorners","viewRightCorners","vtkMatrixBuilder","identity","rotateFromDirections","pt","minY","Infinity","maxY","minX","maxX","oldCamera","oldFocalPoint","oldViewPlaneNormal","vectorFromOldFocalPointToCenteredFocalPoint","distanceFromOldFocalPointToCenteredFocalPoint","xMin","xMax","yMin","yMax","zMin","zMax","p2","p3","p4","p5","p6","p7","p8","getVolumeActorCorners","extentToBounds","getExtent","getSliceRange","corners","transformedFocalPoint","currentSlice","current","getSpacingInNormalDirection","iVector","jVector","kVector","dotProducts","projectedSpacing","getTargetVolumeAndSpacingInNormalDir","targetVolumeId","volumeActors","spacingInNormalDirection","numVolumeActors","imageVolumes","va","referenceId","iv","smallest","sliceRange","numberOfSlices","imageIndex","getRenderingEngines","vtkSlabCamera","tmpMatrix","tmpvec1","getProjectionMatrix","aspect","nearz","farz","projectionMatrix","scale","physicalScale","cRange0","cRange1","isPerformingCoordinateTransformation","xmin","xmax","ymin","ymax","useOffAxisProjection","tmp","tan","useHorizontalViewAngle","znear","zfar","throw","toLowerCase","userAgent","platform","maxTouchPoints","navigator","MSStream","isIpad","isMobile","isSafari12","charCodeAt","l","s","f","u","h","super","mobileTiers","desktopTiers","override","glContext","failIfMajorPerformanceCaveat","benchmarksURL","tier","m","v","screenSize","w","screen","loadBenchmarks","fetch","json","parseInt","split","P","device","fps","gpu","S","alpha","antialias","powerPreference","stencil","getContext","UNMASKED_RENDERER_WEBGL","createShader","createProgram","shaderSource","compileShader","attachShader","linkProgram","detachShader","deleteShader","useProgram","createBuffer","bindBuffer","bufferData","getAttribLocation","vertexAttribPointer","enableVertexAttribArray","clearColor","drawArrays","readPixels","deleteProgram","deleteBuffer","join","all","match","MAX_VALUE","devicePixelRatio","E","L","M","$","csRenderInitialized","useCPURendering","hasActiveWebGLContext","WebGLRenderingContext","init","log","getGPUTier","gpuTier","setUseCPURendering","status","resetUseCPURendering","getShouldUseCPURendering","isCornerstoneInitialized","BaseVolumeViewport","_FrameOfReferenceUID","canvasPos","getOpenGLRenderWindow","getSize","canvasPosWithDPR","displayCoord","worldCoord","displayToWorld","worldToDisplay","canvasCoord","canvasCoordWithDPR","imageURI","setActiveCamera","setParallelProjection","initializeVolumeNewImageEventDispatcher","volumeNewImageHandlerBound","cameraEvent","getImageData","getViewport","getImageSliceDataForVolumeViewport","volumeNewImageEventDispatcher","volumeNewImageCleanUpBound","evt","removeEventListener","resetVolumeNewImageState","addEventListener","actorEntries","setRange","volumeInputArray","firstImageVolume","FrameOfReferenceUID","_isValidVolumeInputArray","_setVolumeActors","visibility","setVisibility","removeActors","orientation","numVolumes","volumeInput","flipDirection","defaultActor","defaultActorUID","getOrigin","Modality","hasPixelSpacing","volumeActorEntries","setActors","filterActorUIDs","VolumeViewport","_getImageIdIndex","EPSILON","spacingInNormal","sub","_getOrientationVectors","setViewUpFrom","_useAcquisitionPlaneForViewPlane","_setViewPlaneToAcquisitionPlane","MPR_CAMERA_VALUES","_getAcquisitionPlaneOrientation","voxelIndex","mapper","clipPlane1","vtkPlane","clipPlane2","newVtkPlanes","addClippingPlane","currentCamera","invertRgbTransferFunction","rgbTransferFunction","nodeValue1","getNodeValue","setNodeValue","isEqual","v1","v2","tolerance","performance","voiLUT","lut","minValue","maxValue","maxValueMapped","firstValueMapped","modalityLutValue","generateNonLinearVOILUT","generateLinearVOILUT","Transform","matrix","m11","m12","m21","m22","dx","dy","m4","m5","rad","cos","sin","enabledElement","displayedArea","translate","angle","rotate","PI","widthScale","heightScale","brhc","tlhc","presentationSizeMode","rowPixelSpacing","columnPixelSpacing","verticalScale","horizontalScale","translation","hflip","vflip","calculateTransform","getMatrix","setTransform","doesImageNeedToBeRendered","lastRenderedImageId","renderingTools","lastRenderedViewport","invert","modalityLUT","colormap","renderCanvas","canvasContext","fillStyle","fillRect","renderCanvasData","renderCanvasContext","isColor","color","lastRenderedIsColor","getRenderCanvas","invalidated","canvasWasColor","getCanvas","initializeRenderCanvas","start","colorLUT","cachedLut","maxPixelValue","minPixelValue","lutArray","Uint8ClampedArray","vlutfn","getVOILUT","generateColorLUT","storedValue","getLut","stats","lastLutGenerateTime","rgba","canvasImageDataData","pixelData","lastGetPixelDataTime","canvasImageDataIndex","storedPixelDataIndex","lastStoredPixelDataToCanvasImageDataTime","storedRGBAPixelDataToCanvasImageData","storedColorPixelDataToCanvasImageData","putImageData","lastPutImageDataTime","renderColorImage","imageSmoothingEnabled","pixelReplication","setToPixelCoordinateSystem","drawImage","saveLastRendered","lutFunction","pixelValue","lutMatches","hasVoi","maxVoi","slope","intercept","minVoi","ww","wc","computeAutoVoi","mlutfn","storedPixelValue","generateNonLinearModalityLUT","generateLinearModalityLUT","getModalityLut","isPreScaled","generateLut","renderGrayscaleImage","useAlphaChannel","minimum","collectedMultiplierTerms","storedPixelDataToCanvasImageDataPET","storedPixelDataToCanvasImageData","storedPixelDataToCanvasImageDataRGBA","HSVToRGB","hue","sat","val","rgb","hueCase","frac","lx","ly","lz","LookupTable","NumberOfColors","Ramp","TableRange","HueRange","SaturationRange","ValueRange","AlphaRange","NaNColor","BelowRangeColor","UseBelowRangeColor","AboveRangeColor","UseAboveRangeColor","InputRange","Table","number","ramp","end","scalar","mapValue","force","hinc","sinc","vinc","ainc","maxIndex","c_rgba","buildSpecialColors","numberOfColors","belowRangeColorIndex","aboveRangeColorIndex","nanColorIndex","getIndex","Range","MaxIndex","Shift","Scale","dIndex","linearIndexLookupMain","COLOR_TRANSPARENT","getRank","elem","left","right","mid","midElem","makeMappingArray","N","xLinSpace","vector","linspace","pow","xLinSpaceIndexes","inputArray","indexes","searchSorted","colorPercent","colorDelta","getColormap","colormapData","CPU_COLORMAPS","redLut","greenLut","blueLut","createLinearSegmentedColormap","cpuFallbackColormap","getId","getColorSchemeName","setColorSchemeName","getNumberOfColors","setNumberOfColors","isValidIndex","getColorRepeating","setColor","addColor","insertColor","removeColor","clearColors","buildLookupTable","setNumberOfTableValues","setTableValue","createLookupTable","clamp","renderPseudoColorImage","colormapId","clut","storedPixelDataToCanvasImageDataPseudocolorLUTPET","grayscaleLut","storedPixelDataToCanvasImageDataPseudocolorLUT","lastRenderTime","renderTimeInMs","invalid","needsRedraw","getTransform","transformPoint","validateParameterUndefinedOrNull","checkParam","errorMsg","isRotated","imageSize","getImageSize","verticalRatio","horizontalRatio","initialDefaultViewport","labelmap","getImageFitScale","columns","rows","setCanvasSize","clientWidth","clientHeight","wasFitToWindow","oldCanvasWidth","oldCanvasHeight","imageWidth","imageHeight","relativeRescale","relWidthChange","relHeightChange","relChange","StackViewport","_resizeCPU","_cpuFallbackEnabledElement","forceFitToWindow","fitToWindow","getCurrentImageId","imagePlaneModule","frameOfReferenceUID","vtkImageMapper","vtkImageSlice","setIndependentComponents","rotationCache","interpolationType","canvasToWorldCPU","canvasToWorldGPU","worldToCanvasCPU","worldToCanvasGPU","canvasToPixel","px","py","diff","worldPoint","pixelToCanvas","getDistance","currentImageIdIndex","targetImageIdIndex","drawImageSync","cpuRenderingInvalidated","fillWithBackgroundColor","setThicknessFromFocalPoint","setFreezeFocalPoint","cameraFocalPointOnRender","initializeElementDisabledHandler","elementDisabledHandler","debouncedTimeout","getImageDataCPU","getImageDataGPU","csImage","getScalarData","cpuImagePixelData","canvasPoint","pixelCoord","pixelRepresentation","bitsAllocated","bitsStored","highBit","photometricInterpretation","samplesPerPixel","imageIdScalingFactor","_addScalingToViewport","_getImagePlaneModule","calibrateIfNecessary","imagePixelModule","calibratedPixelSpacing","calibratedRowSpacing","calibratedColumnSpacing","imageDataMetadata","_publishCalibratedEvent","_calibrationEvent","rowScale","columnScale","voiApplied","setVOI","setInvertColor","setInterpolationType","setRotation","_resetProperties","getCameraCPU","setCameraCPU","setProperties","initialVOIRange","rotationMatrix","canvasCenter","canvasCenterWorld","topLeftWorld","bottomLeftWorld","focalPointCanvas","focalPointPixel","prevFocalPointCanvas","prevFocalPointPixel","deltaPixel","viewportOrientation","cosA","sinA","newX","newY","correctShift","setFlipCPU","setVOICPU","setVOIGPU","setRotationCPU","setRotationGPU","setInterpolationTypeCPU","setInterpolationTypeGPU","setInvertColorCPU","setInvertColorGPU","roll","tfunc","wwToUse","wcToUse","windowLevelUtil","imageActor","voiRangeToUse","setColorWindow","setColorLevel","PET","suvlbm","suvbsa","petScaling","suvbwToSuvlbm","suvbwToSuvbsa","rowCosines","columnCosines","buildMetadata","rowCosineVec","colCosineVec","scanAxisNormal","imagePositionPatient","xSpacing","ySpacing","xVoxels","yVoxels","_getNumCompsFromPhotometricInterpretation","imageDataDirection","pixelArray","_imageData","stackInvalidated","_setImageIdIndex","dest","rgbIndex","_loadAndDisplayImageCPU","_loadAndDisplayImageGPU","successCallback","_getImageDataMetadata","scaled","getDefaultViewport","viewportSettingToUse","errorCallback","useRGBA","_updateActorToDisplayImageId","sameImageData","_checkVTKImageDataMatchesCornerstoneImage","previousCameraProps","_updateVTKImageDataFromCornerstoneImage","cameraProps","panCache","resetCameraNoEvent","setCameraNoEvent","_restoreCameraProps","_setPropertiesFromCache","_createVTKImageData","createActorMapper","_getCameraOrientation","triggerCameraEvent","vtkColorTransferFunction","addRGBPoint","setRGBTransferFunction","triggerCalibrationEvent","_loadAndDisplayImage","resetCameraCPU","resetCameraGPU","center","centerWorld","debounce","loop","currentTargetImageIdIndex","numberOfFrames","newTargetImageIdIndex","targetImageId","imageAlreadyLoaded","setImageIdIndex","eventData","newImageIdIndex","getImageIds","prevScale","getCPUFallbackError","fillCanvasWithBackgroundColor","setColormapCPU","setColormapGPU","unsetColormapCPU","unsetColormapGPU","newImagePlaneModule","imageOrientationPatient","VolumeViewport3D","viewportTypeUsesCustomRenderingPipeline","viewportType","viewportTypeToViewportClass","useCustomRenderingPipeline","RenderingEngine","viewportIdsWithSameFrameOfReferenceUID","_getViewportsAsArray","vp","getFrameOfReferenceUID","renderViewports","_throwIfDestroyed","performVtkDrawCall","viewports","eventDetailArray","_needsRender","renderViewportUsingCustomOrVtkPipeline","_animationFrameSet","_animationFrameHandle","offScreenCanvasContainer","_viewports","viewportInputEntry","viewportInput","_normalizeViewportInputEntry","disableElement","viewportUsesCustomRenderingPipeline","addCustomViewport","enableVTKjsDrivenViewport","_resetViewport","_removeViewport","getViewports","_clearAnimationFrame","publicViewportInputEntries","viewportInputEntries","_normalizeViewportInputEntries","_reset","vtkDrivenViewportInputEntries","customRenderingViewportInputEntries","vpie","setVtkjsDrivenViewports","setCustomViewports","keepCamera","vtkDrivenViewports","customRenderingViewports","_resizeVTKViewports","_resizeUsingCustomResizeHandler","viewportIds","_setViewportsToBeRenderedNextFrame","backgroundColor","ctx","normalizedViewportInputs","prevCamera","canvasesDrivenByVtkJs","_resizeOffScreenCanvas","offScreenCanvasWidth","offScreenCanvasHeight","_resize","rect","getBoundingClientRect","viewportsDrivenByVtkJs","xOffset","internalViewportEntry","addVtkjsDrivenViewport","offscreenCanvasProperties","tabIndex","_getViewportCoordsOnOffScreenCanvas","sxStartDisplayCoords","syStartDisplayCoords","sxEndDisplayCoords","syEndDisplayCoords","vtkDrivenCanvases","vtkDrivenViewportInputEntry","_xOffset","setViewport","_render","requestAnimationFrame","_renderFlaggedViewports","getRenderWindow","renderers","setDraw","customRenderViewportToCanvas","offScreenCanvas","get3DContext","_renderViewportFromVtkCanvasToOnscreenCanvas","dWidth","dHeight","removeAttribute","clearRect","cancelAnimationFrame","uri","link","_debugRender","download","href","body","click","removeChild","dataURL","toDataURL","imageRetrievalPoolManager","getEnabledElement","dataset","getEnabledElementByIds","viewportUid","renderingEngineUid","getEnabledElements","enabledElements","DEFAULT_SETTINGS","RUNTIME_SETTINGS","OBJECT_SETTINGS_MAP","DICTIONARY","Settings","dictionary","seal","endsWith","deleteCount","namespace","deleteAll","startsWith","unset","iterate","isPlainObject","deepSet","subject","getRuntimeSettings","subfield","defaultSettings","settingObj","setting","runtimeSettings","getDefaultSettings","settings","objectSettingsMap","assert","getObjectSettings","references","last","previous","isValidKey","prefix","failCount","field","setAll","WeakSet","separator","subKey","subContext","subContextValue","scaleRGBTransferFunction","scalingFactor","LAST_RUNTIME_ID","GLOBAL_CONTEXT","getRuntimeId","idComponents","carry","getNextRuntimeId","payload","isOpposite","crossOriginIsolated","getClosestImageId","imageIdForTool","halfSpacingInNormalDirection","dot","indexWithinDimensions","targetViewport","renderingEngines","sameVolumesViewports","targetActors","getVolumeViewports","vpActors","every","vpActor","targetViewports","filteredViewports","hasVolumeId","renderToCanvas","loadImageToCanvas","worldCoords","newOrigin","imageToWorldCoords","imageCoords","imageCoordsInWorld","snapFocalPointToSlice","deltaFrames","posDiffFromFocalPoint","steps","floatingStepNumber","newSlicePosFromMin","getViewportsWithImageURI","filteredStackViewports","getStackViewports","hasImageURI","filteredVolumeViewports","getClosestStackImageIndexForPoint","minimalDistance","getCurrentImageIdIndex","planeMetadata","targetImagePlane","rowVec","colVec","planeNormal","getPlaneMetadata","closestStack","higherImageIds","lowerImageIds","calculateMinimalDistanceForStackViewport","spatialRegistrationMetadataProvider","viewportId1","viewportId2","entryId","entryIdReverse","viewport1","viewport2","imageId1","imageId2","imagePlaneModule1","imagePlaneModule2","imagePositionPatient1","imagePositionPatient2","mat","getViewportImageCornersInWorld","topRightCanvas","bottomRightCanvas","bottomLeftCanvas","topRightWorld","bottomRightWorld","topLeftImage","topRightImage","bottomRightImage","bottomLeftImage","topLeftImageWorld","topRightImageWorld","bottomRightImageWorld","_getStackViewportImageCorners","imageCoord","applyPreset","preset","colorTransferArray","parseFloat","shiftRange","getShiftRange","normColorTransferValuePoints","rescaled","removeAllPoints","applyPointsToRGBFunction","scalarOpacityArray","vtkPiecewiseFunction","normPoints","opacity","pwf","addPoint","applyPointsToPiecewiseFunction","setScalarOpacity","gradientMinValue","gradientMinOpacity","gradientMaxValue","gradientMaxOpacity","setUseGradientOpacity","setGradientOpacityMinimumValue","setGradientOpacityMinimumOpacity","setGradientOpacityMaximumValue","setGradientOpacityMaximumOpacity","setInterpolationTypeToFastLinear","setAmbient","setDiffuse","setSpecular","setSpecularPower","volumeInputs","immediateRender","setVolumePromises","setVolumes","setVolumesForViewports","addVolumePromises","addVolumes","addVolumesToViewports"],"sourceRoot":""}
1
+ {"version":3,"file":"index.js","mappings":"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I,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,OAGpBC,IAAK,CACHlQ,KAAM,MACNmQ,UAAW,IACXF,OAAQ,CACN,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,GAAI,EAAG,KACX,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,IAAK,GAAI,KACb,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,OAGpBG,aAAc,CACZpQ,KAAM,iBACNmQ,UAAW,IACXF,OAAQ,CACN,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,OAGpBI,UAAW,CACTrQ,KAAM,cACNmQ,UAAW,IACXF,OAAQ,CACN,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CA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QAAS,MACTC,cAAe,KAEjB,CACE5S,KAAM,WACNoS,gBAAiB,iBACjBC,cAAe,IACfC,cAAe,6CACfC,SAAU,IACVC,MAAO,IACPC,QAAS,MACTC,cACE,2FACFC,QAAS,IACTC,cAAe,KAEjB,CACE5S,KAAM,aACNoS,gBAAiB,cACjBC,cAAe,KACfC,cACE,sFACFC,SAAU,MACVC,MAAO,IACPC,QAAS,MACTC,cACE,+JACFC,QAAS,MACTC,cAAe,KAEjB,CACE5S,KAAM,cACNoS,gBAAiB,cACjBC,cAAe,KACfC,cACE,qFACFC,SAAU,MACVC,MAAO,IACPC,QAAS,MACTC,cACE,qJACFC,QAAS,MACTC,cAAe,KAEjB,CACE5S,KAAM,cACNoS,gBAAiB,cACjBC,cAAe,KACfC,cACE,0GACFC,SAAU,MACVC,MAAO,IACPC,QAAS,MACTC,cACE,2IACFC,QAAS,MACTC,cAAe,KAEjB,CACE5S,KAAM,6BACNoS,gBAAiB,cACjBC,cAAe,KACfC,cACE,oEACFC,SAAU,MACVC,MAAO,IACPC,QAAS,MACTC,cACE,yIACFC,QAAS,MACTC,cAAe,KAEjB,CACE5S,KAAM,mBACNoS,gBAAiB,cACjBC,cAAe,IACfC,cACE,qEACFC,SAAU,IACVC,MAAO,IACPC,QAAS,MACTC,cACE,0IACFC,QAAS,IACTC,cAAe,KAEjB,CACE5S,KAAM,uBACNoS,gBAAiB,cACjBC,cAAe,IACfC,cACE,+EACFC,SAAU,IACVC,MAAO,IACPC,QAAS,MACTC,cACE,4HACFC,QAAS,IACTC,cAAe,KAEjB,CACE5S,KAAM,yBACNoS,gBAAiB,cACjBC,cAAe,IACfC,cACE,sGACFC,SAAU,IACVC,MAAO,IACPC,QAAS,MACTC,cACE,iKACFC,QAAS,IACTC,cAAe,KAEjB,CACE5S,KAAM,yBACNoS,gBAAiB,cACjBC,cAAe,KACfC,cACE,mGACFC,SAAU,MACVC,MAAO,IACPC,QAAS,MACTC,cACE,yKACFC,QAAS,MACTC,cAAe,KAEjB,CACE5S,KAAM,yBACNoS,gBAAiB,cACjBC,cAAe,IACfC,cAAe,yCACfC,SAAU,IAC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","sources":["webpack://cornerstone3D/webpack/universalModuleDefinition","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/regeneratorRuntime.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/typeof.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/regenerator/index.js","webpack://cornerstone3D/../../node_modules/lodash.clonedeep/index.js","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Common/Core/DataArray\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Common/Core/DataArray/Constants\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Common/Core/Math\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Common/Core/MatrixBuilder\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Common/Core/Points\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Common/DataModel/ImageData\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Common/DataModel/PiecewiseFunction\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Common/DataModel/Plane\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Common/DataModel/PolyData\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/Actor\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/Camera\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/ColorTransferFunction\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/ImageMapper\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/ImageSlice\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/Mapper\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/Property/Constants\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/RenderWindow\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/RenderWindowInteractor\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/Renderer\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/Volume\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/VolumeMapper\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/VolumeMapper/Constants\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/Actor\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/Actor2D\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/Camera\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/Glyph3DMapper\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/ImageMapper\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/ImageSlice\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/PixelSpaceCallbackMapper\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/PolyDataMapper\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/RenderWindow\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/Renderer\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/Skybox\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/SphereMapper\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/StickMapper\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/Texture\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/Texture/Constants\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/Volume\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/VolumeMapper\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Profiles/Volume\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/SceneGraph/ViewNodeFactory\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/macros\"","webpack://cornerstone3D/external umd {\"root\":\"window\",\"commonjs\":\"gl-matrix\",\"commonjs2\":\"gl-matrix\",\"amd\":\"gl-matrix\"}","webpack://cornerstone3D/webpack/bootstrap","webpack://cornerstone3D/webpack/runtime/compat get default export","webpack://cornerstone3D/webpack/runtime/define property getters","webpack://cornerstone3D/webpack/runtime/global","webpack://cornerstone3D/webpack/runtime/hasOwnProperty shorthand","webpack://cornerstone3D/webpack/runtime/make namespace object","webpack://cornerstone3D/webpack/runtime/node module decorator","webpack://cornerstone3D/./src/enums/Events.ts","webpack://cornerstone3D/./src/enums/RequestType.ts","webpack://cornerstone3D/./src/enums/ViewportType.ts","webpack://cornerstone3D/./src/enums/InterpolationType.ts","webpack://cornerstone3D/./src/enums/BlendModes.ts","webpack://cornerstone3D/./src/enums/OrientationAxis.ts","webpack://cornerstone3D/./src/constants/cpuColormaps.ts","webpack://cornerstone3D/./src/constants/rendering.ts","webpack://cornerstone3D/./src/constants/epsilon.ts","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/typeof.js","webpack://cornerstone3D/./src/utilities/deepFreeze.ts","webpack://cornerstone3D/./src/constants/mprCameraValues.ts","webpack://cornerstone3D/./src/constants/viewportPresets.ts","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/createClass.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/classCallCheck.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/defineProperty.js","webpack://cornerstone3D/./src/RenderingEngine/vtkClasses/vtkStreamingOpenGLTexture.js","webpack://cornerstone3D/./src/cache/classes/ImageVolume.ts","webpack://cornerstone3D/./src/eventTarget.ts","webpack://cornerstone3D/./src/utilities/triggerEvent.ts","webpack://cornerstone3D/./src/utilities/imageIdToURI.ts","webpack://cornerstone3D/./src/cache/cache.ts","webpack://cornerstone3D/./src/utilities/uuidv4.ts","webpack://cornerstone3D/./src/volumeLoader.ts","webpack://cornerstone3D/./src/RenderingEngine/vtkClasses/vtkSharedVolumeMapper.js","webpack://cornerstone3D/./src/RenderingEngine/helpers/createVolumeMapper.ts","webpack://cornerstone3D/./src/requestPool/requestPoolManager.ts","webpack://cornerstone3D/./src/requestPool/imageLoadPoolManager.ts","webpack://cornerstone3D/./src/imageLoader.ts","webpack://cornerstone3D/./src/metaData.ts","webpack://cornerstone3D/./src/utilities/windowLevel.ts","webpack://cornerstone3D/./src/utilities/getMinMax.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/setDefaultVolumeVOI.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/createVolumeActor.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/getOrCreateCanvas.ts","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/arrayLikeToArray.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/unsupportedIterableToArray.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/toConsumableArray.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/arrayWithoutHoles.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/iterableToArray.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/nonIterableSpread.js","webpack://cornerstone3D/./src/RenderingEngine/renderingEngineCache.ts","webpack://cornerstone3D/./src/RenderingEngine/vtkClasses/vtkStreamingOpenGLVolumeMapper.js","webpack://cornerstone3D/./src/RenderingEngine/vtkClasses/vtkStreamingOpenGLViewNodeFactory.js","webpack://cornerstone3D/./src/RenderingEngine/vtkClasses/vtkStreamingOpenGLRenderWindow.js","webpack://cornerstone3D/./src/RenderingEngine/vtkClasses/vtkOffscreenMultiRenderWindow.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/superPropBase.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/get.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/inherits.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/possibleConstructorReturn.js","webpack://cornerstone3D/./src/cache/index.ts","webpack://cornerstone3D/./src/utilities/transformWorldToIndex.ts","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/slicedToArray.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/arrayWithHoles.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/iterableToArrayLimit.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/nonIterableRest.js","webpack://cornerstone3D/./src/utilities/isImageActor.ts","webpack://cornerstone3D/./src/utilities/planar.ts","webpack://cornerstone3D/./src/utilities/hasNaNValues.ts","webpack://cornerstone3D/./src/RenderingEngine/Viewport.ts","webpack://cornerstone3D/./src/utilities/getVolumeActorCorners.ts","webpack://cornerstone3D/./src/utilities/getSliceRange.ts","webpack://cornerstone3D/./src/utilities/getSpacingInNormalDirection.ts","webpack://cornerstone3D/./src/utilities/getTargetVolumeAndSpacingInNormalDir.ts","webpack://cornerstone3D/./src/utilities/getImageSliceDataForVolumeViewport.ts","webpack://cornerstone3D/./src/RenderingEngine/getRenderingEngine.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/volumeNewImageEventDispatcher.ts","webpack://cornerstone3D/./src/RenderingEngine/vtkClasses/vtkSlabCamera.js","webpack://cornerstone3D/../../node_modules/detect-gpu/dist/detect-gpu.esm.js","webpack://cornerstone3D/./src/init.ts","webpack://cornerstone3D/./src/RenderingEngine/BaseVolumeViewport.ts","webpack://cornerstone3D/./src/RenderingEngine/VolumeViewport.ts","webpack://cornerstone3D/./src/utilities/invertRgbTransferFunction.ts","webpack://cornerstone3D/./src/utilities/isEqual.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/now.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/getVOILut.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/transform.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/calculateTransform.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/setToPixelCoordinateSystem.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/doesImageNeedToBeRendered.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/initializeRenderCanvas.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/saveLastRendered.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/renderColorImage.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/generateColorLUT.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/storedRGBAPixelDataToCanvasImageData.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/storedColorPixelDataToCanvasImageData.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageData.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPET.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataRGBA.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/lutMatches.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/getLut.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/computeAutoVoi.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/generateLut.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/getModalityLut.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/renderGrayscaleImage.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/colors/lookupTable.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/colors/colormap.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/renderPseudoColorImage.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPseudocolorLUTPET.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPseudocolorLUT.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/drawImageSync.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/getTransform.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/canvasToPixel.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/pixelToCanvas.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/setDefaultViewport.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/validator.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/getImageSize.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/getImageFitScale.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/getDefaultViewport.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/createViewport.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/fitToWindow.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/resize.ts","webpack://cornerstone3D/./src/RenderingEngine/StackViewport.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/correctShift.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/isRgbaSourceRgbDest.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/resetCamera.ts","webpack://cornerstone3D/./src/RenderingEngine/VolumeViewport3D.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/viewportTypeToViewportClass.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/viewportTypeUsesCustomRenderingPipeline.ts","webpack://cornerstone3D/./src/RenderingEngine/RenderingEngine.ts","webpack://cornerstone3D/./src/RenderingEngine/index.ts","webpack://cornerstone3D/./src/requestPool/imageRetrievalPoolManager.ts","webpack://cornerstone3D/./src/getEnabledElement.ts","webpack://cornerstone3D/./src/Settings.ts","webpack://cornerstone3D/./src/utilities/scaleRgbTransferFunction.ts","webpack://cornerstone3D/./src/utilities/getRuntimeId.ts","webpack://cornerstone3D/./src/utilities/calibratedPixelSpacingMetadataProvider.ts","webpack://cornerstone3D/./src/utilities/isOpposite.ts","webpack://cornerstone3D/./src/utilities/createUint8SharedArray.ts","webpack://cornerstone3D/./src/utilities/createFloat32SharedArray.ts","webpack://cornerstone3D/./src/utilities/getClosestImageId.ts","webpack://cornerstone3D/./src/utilities/indexWithinDimensions.ts","webpack://cornerstone3D/./src/utilities/getVolumeViewportsContainingSameVolumes.ts","webpack://cornerstone3D/./src/utilities/getViewportsWithVolumeId.ts","webpack://cornerstone3D/./src/utilities/renderToCanvas.ts","webpack://cornerstone3D/./src/utilities/loadImageToCanvas.ts","webpack://cornerstone3D/./src/utilities/worldToImageCoords.ts","webpack://cornerstone3D/./src/utilities/imageToWorldCoords.ts","webpack://cornerstone3D/./src/utilities/snapFocalPointToSlice.ts","webpack://cornerstone3D/./src/utilities/getViewportsWithImageURI.ts","webpack://cornerstone3D/./src/utilities/getClosestStackImageIndexForPoint.ts","webpack://cornerstone3D/./src/utilities/spatialRegistrationMetadataProvider.ts","webpack://cornerstone3D/./src/utilities/calculateViewportsSpatialRegistration.ts","webpack://cornerstone3D/./src/utilities/getViewportImageCornersInWorld.ts","webpack://cornerstone3D/./src/utilities/applyPreset.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/setVolumesForViewports.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/addVolumesToViewports.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"@kitware/vtk.js/Rendering/Core/VolumeMapper/Constants\"), require(\"@kitware/vtk.js/macros\"), require(\"@kitware/vtk.js/Rendering/Core/Camera\"), require(\"gl-matrix\"), require(\"@kitware/vtk.js/Common/Core/Math\"), require(\"@kitware/vtk.js/Common/Core/MatrixBuilder\"), require(\"@kitware/vtk.js/Rendering/Core/Volume\"), require(\"@kitware/vtk.js/Rendering/Profiles/Volume\"), require(\"@kitware/vtk.js/Common/DataModel/ImageData\"), require(\"@kitware/vtk.js/Common/Core/DataArray\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Texture\"), require(\"@kitware/vtk.js/Rendering/Core/VolumeMapper\"), require(\"@kitware/vtk.js/Common/DataModel/Plane\"), require(\"@kitware/vtk.js/Rendering/Core/ImageMapper\"), require(\"@kitware/vtk.js/Rendering/Core/ImageSlice\"), require(\"@kitware/vtk.js/Rendering/Core/ColorTransferFunction\"), require(\"@kitware/vtk.js/Rendering/Core/Renderer\"), require(\"@kitware/vtk.js/Rendering/Core/RenderWindow\"), require(\"@kitware/vtk.js/Rendering/Core/RenderWindowInteractor\"), require(\"@kitware/vtk.js/Common/Core/Points\"), require(\"@kitware/vtk.js/Common/DataModel/PolyData\"), require(\"@kitware/vtk.js/Rendering/Core/Actor\"), require(\"@kitware/vtk.js/Rendering/Core/Mapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/RenderWindow\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Actor\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Actor2D\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Camera\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Glyph3DMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/ImageMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/ImageSlice\"), require(\"@kitware/vtk.js/Rendering/OpenGL/PixelSpaceCallbackMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/PolyDataMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Renderer\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Skybox\"), require(\"@kitware/vtk.js/Rendering/OpenGL/SphereMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/StickMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Volume\"), require(\"@kitware/vtk.js/Rendering/OpenGL/VolumeMapper\"), require(\"@kitware/vtk.js/Rendering/SceneGraph/ViewNodeFactory\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Texture/Constants\"), require(\"@kitware/vtk.js/Common/Core/DataArray/Constants\"), require(\"@kitware/vtk.js/Rendering/Core/Property/Constants\"), require(\"@kitware/vtk.js/Common/DataModel/PiecewiseFunction\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"@kitware/vtk.js/Rendering/Core/VolumeMapper/Constants\", \"@kitware/vtk.js/macros\", \"@kitware/vtk.js/Rendering/Core/Camera\", \"gl-matrix\", \"@kitware/vtk.js/Common/Core/Math\", \"@kitware/vtk.js/Common/Core/MatrixBuilder\", \"@kitware/vtk.js/Rendering/Core/Volume\", \"@kitware/vtk.js/Rendering/Profiles/Volume\", \"@kitware/vtk.js/Common/DataModel/ImageData\", \"@kitware/vtk.js/Common/Core/DataArray\", \"@kitware/vtk.js/Rendering/OpenGL/Texture\", \"@kitware/vtk.js/Rendering/Core/VolumeMapper\", \"@kitware/vtk.js/Common/DataModel/Plane\", \"@kitware/vtk.js/Rendering/Core/ImageMapper\", \"@kitware/vtk.js/Rendering/Core/ImageSlice\", \"@kitware/vtk.js/Rendering/Core/ColorTransferFunction\", \"@kitware/vtk.js/Rendering/Core/Renderer\", \"@kitware/vtk.js/Rendering/Core/RenderWindow\", \"@kitware/vtk.js/Rendering/Core/RenderWindowInteractor\", \"@kitware/vtk.js/Common/Core/Points\", \"@kitware/vtk.js/Common/DataModel/PolyData\", \"@kitware/vtk.js/Rendering/Core/Actor\", \"@kitware/vtk.js/Rendering/Core/Mapper\", \"@kitware/vtk.js/Rendering/OpenGL/RenderWindow\", \"@kitware/vtk.js/Rendering/OpenGL/Actor\", \"@kitware/vtk.js/Rendering/OpenGL/Actor2D\", \"@kitware/vtk.js/Rendering/OpenGL/Camera\", \"@kitware/vtk.js/Rendering/OpenGL/Glyph3DMapper\", \"@kitware/vtk.js/Rendering/OpenGL/ImageMapper\", \"@kitware/vtk.js/Rendering/OpenGL/ImageSlice\", \"@kitware/vtk.js/Rendering/OpenGL/PixelSpaceCallbackMapper\", \"@kitware/vtk.js/Rendering/OpenGL/PolyDataMapper\", \"@kitware/vtk.js/Rendering/OpenGL/Renderer\", \"@kitware/vtk.js/Rendering/OpenGL/Skybox\", \"@kitware/vtk.js/Rendering/OpenGL/SphereMapper\", \"@kitware/vtk.js/Rendering/OpenGL/StickMapper\", \"@kitware/vtk.js/Rendering/OpenGL/Volume\", \"@kitware/vtk.js/Rendering/OpenGL/VolumeMapper\", \"@kitware/vtk.js/Rendering/SceneGraph/ViewNodeFactory\", \"@kitware/vtk.js/Rendering/OpenGL/Texture/Constants\", \"@kitware/vtk.js/Common/Core/DataArray/Constants\", \"@kitware/vtk.js/Rendering/Core/Property/Constants\", \"@kitware/vtk.js/Common/DataModel/PiecewiseFunction\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"cornerstone3D\"] = factory(require(\"@kitware/vtk.js/Rendering/Core/VolumeMapper/Constants\"), require(\"@kitware/vtk.js/macros\"), require(\"@kitware/vtk.js/Rendering/Core/Camera\"), require(\"gl-matrix\"), require(\"@kitware/vtk.js/Common/Core/Math\"), require(\"@kitware/vtk.js/Common/Core/MatrixBuilder\"), require(\"@kitware/vtk.js/Rendering/Core/Volume\"), require(\"@kitware/vtk.js/Rendering/Profiles/Volume\"), require(\"@kitware/vtk.js/Common/DataModel/ImageData\"), require(\"@kitware/vtk.js/Common/Core/DataArray\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Texture\"), require(\"@kitware/vtk.js/Rendering/Core/VolumeMapper\"), require(\"@kitware/vtk.js/Common/DataModel/Plane\"), require(\"@kitware/vtk.js/Rendering/Core/ImageMapper\"), require(\"@kitware/vtk.js/Rendering/Core/ImageSlice\"), require(\"@kitware/vtk.js/Rendering/Core/ColorTransferFunction\"), require(\"@kitware/vtk.js/Rendering/Core/Renderer\"), require(\"@kitware/vtk.js/Rendering/Core/RenderWindow\"), require(\"@kitware/vtk.js/Rendering/Core/RenderWindowInteractor\"), require(\"@kitware/vtk.js/Common/Core/Points\"), require(\"@kitware/vtk.js/Common/DataModel/PolyData\"), require(\"@kitware/vtk.js/Rendering/Core/Actor\"), require(\"@kitware/vtk.js/Rendering/Core/Mapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/RenderWindow\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Actor\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Actor2D\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Camera\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Glyph3DMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/ImageMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/ImageSlice\"), require(\"@kitware/vtk.js/Rendering/OpenGL/PixelSpaceCallbackMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/PolyDataMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Renderer\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Skybox\"), require(\"@kitware/vtk.js/Rendering/OpenGL/SphereMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/StickMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Volume\"), require(\"@kitware/vtk.js/Rendering/OpenGL/VolumeMapper\"), require(\"@kitware/vtk.js/Rendering/SceneGraph/ViewNodeFactory\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Texture/Constants\"), require(\"@kitware/vtk.js/Common/Core/DataArray/Constants\"), require(\"@kitware/vtk.js/Rendering/Core/Property/Constants\"), require(\"@kitware/vtk.js/Common/DataModel/PiecewiseFunction\"));\n\telse\n\t\troot[\"cornerstone3D\"] = factory(root[\"@kitware/vtk.js/Rendering/Core/VolumeMapper/Constants\"], root[\"@kitware/vtk.js/macros\"], root[\"@kitware/vtk.js/Rendering/Core/Camera\"], root[\"window\"], root[\"@kitware/vtk.js/Common/Core/Math\"], root[\"@kitware/vtk.js/Common/Core/MatrixBuilder\"], root[\"@kitware/vtk.js/Rendering/Core/Volume\"], root[\"@kitware/vtk.js/Rendering/Profiles/Volume\"], root[\"@kitware/vtk.js/Common/DataModel/ImageData\"], root[\"@kitware/vtk.js/Common/Core/DataArray\"], root[\"@kitware/vtk.js/Rendering/OpenGL/Texture\"], root[\"@kitware/vtk.js/Rendering/Core/VolumeMapper\"], root[\"@kitware/vtk.js/Common/DataModel/Plane\"], root[\"@kitware/vtk.js/Rendering/Core/ImageMapper\"], root[\"@kitware/vtk.js/Rendering/Core/ImageSlice\"], root[\"@kitware/vtk.js/Rendering/Core/ColorTransferFunction\"], root[\"@kitware/vtk.js/Rendering/Core/Renderer\"], root[\"@kitware/vtk.js/Rendering/Core/RenderWindow\"], root[\"@kitware/vtk.js/Rendering/Core/RenderWindowInteractor\"], root[\"@kitware/vtk.js/Common/Core/Points\"], root[\"@kitware/vtk.js/Common/DataModel/PolyData\"], root[\"@kitware/vtk.js/Rendering/Core/Actor\"], root[\"@kitware/vtk.js/Rendering/Core/Mapper\"], root[\"@kitware/vtk.js/Rendering/OpenGL/RenderWindow\"], root[\"@kitware/vtk.js/Rendering/OpenGL/Actor\"], root[\"@kitware/vtk.js/Rendering/OpenGL/Actor2D\"], root[\"@kitware/vtk.js/Rendering/OpenGL/Camera\"], root[\"@kitware/vtk.js/Rendering/OpenGL/Glyph3DMapper\"], root[\"@kitware/vtk.js/Rendering/OpenGL/ImageMapper\"], root[\"@kitware/vtk.js/Rendering/OpenGL/ImageSlice\"], root[\"@kitware/vtk.js/Rendering/OpenGL/PixelSpaceCallbackMapper\"], root[\"@kitware/vtk.js/Rendering/OpenGL/PolyDataMapper\"], root[\"@kitware/vtk.js/Rendering/OpenGL/Renderer\"], root[\"@kitware/vtk.js/Rendering/OpenGL/Skybox\"], root[\"@kitware/vtk.js/Rendering/OpenGL/SphereMapper\"], root[\"@kitware/vtk.js/Rendering/OpenGL/StickMapper\"], root[\"@kitware/vtk.js/Rendering/OpenGL/Volume\"], root[\"@kitware/vtk.js/Rendering/OpenGL/VolumeMapper\"], root[\"@kitware/vtk.js/Rendering/SceneGraph/ViewNodeFactory\"], root[\"@kitware/vtk.js/Rendering/OpenGL/Texture/Constants\"], root[\"@kitware/vtk.js/Common/Core/DataArray/Constants\"], root[\"@kitware/vtk.js/Rendering/Core/Property/Constants\"], root[\"@kitware/vtk.js/Common/DataModel/PiecewiseFunction\"]);\n})(self, function(__WEBPACK_EXTERNAL_MODULE__468__, __WEBPACK_EXTERNAL_MODULE__197__, __WEBPACK_EXTERNAL_MODULE__821__, __WEBPACK_EXTERNAL_MODULE__976__, __WEBPACK_EXTERNAL_MODULE__807__, __WEBPACK_EXTERNAL_MODULE__847__, __WEBPACK_EXTERNAL_MODULE__739__, __WEBPACK_EXTERNAL_MODULE__215__, __WEBPACK_EXTERNAL_MODULE__283__, __WEBPACK_EXTERNAL_MODULE__785__, __WEBPACK_EXTERNAL_MODULE__953__, __WEBPACK_EXTERNAL_MODULE__9__, __WEBPACK_EXTERNAL_MODULE__864__, __WEBPACK_EXTERNAL_MODULE__896__, __WEBPACK_EXTERNAL_MODULE__861__, __WEBPACK_EXTERNAL_MODULE__795__, __WEBPACK_EXTERNAL_MODULE__281__, __WEBPACK_EXTERNAL_MODULE__329__, __WEBPACK_EXTERNAL_MODULE__673__, __WEBPACK_EXTERNAL_MODULE__348__, __WEBPACK_EXTERNAL_MODULE__70__, __WEBPACK_EXTERNAL_MODULE__474__, __WEBPACK_EXTERNAL_MODULE__610__, __WEBPACK_EXTERNAL_MODULE__21__, __WEBPACK_EXTERNAL_MODULE__643__, __WEBPACK_EXTERNAL_MODULE__128__, __WEBPACK_EXTERNAL_MODULE__664__, __WEBPACK_EXTERNAL_MODULE__973__, __WEBPACK_EXTERNAL_MODULE__394__, __WEBPACK_EXTERNAL_MODULE__582__, __WEBPACK_EXTERNAL_MODULE__482__, __WEBPACK_EXTERNAL_MODULE__343__, __WEBPACK_EXTERNAL_MODULE__363__, __WEBPACK_EXTERNAL_MODULE__982__, __WEBPACK_EXTERNAL_MODULE__130__, __WEBPACK_EXTERNAL_MODULE__298__, __WEBPACK_EXTERNAL_MODULE__398__, __WEBPACK_EXTERNAL_MODULE__388__, __WEBPACK_EXTERNAL_MODULE__120__, __WEBPACK_EXTERNAL_MODULE__395__, __WEBPACK_EXTERNAL_MODULE__948__, __WEBPACK_EXTERNAL_MODULE__478__, __WEBPACK_EXTERNAL_MODULE__441__) {\nreturn ","var _typeof = require(\"./typeof.js\")[\"default\"];\n\nfunction _regeneratorRuntime() {\n \"use strict\";\n /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */\n\n module.exports = _regeneratorRuntime = function _regeneratorRuntime() {\n return exports;\n }, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;\n var exports = {},\n Op = Object.prototype,\n hasOwn = Op.hasOwnProperty,\n $Symbol = \"function\" == typeof Symbol ? Symbol : {},\n iteratorSymbol = $Symbol.iterator || \"@@iterator\",\n asyncIteratorSymbol = $Symbol.asyncIterator || \"@@asyncIterator\",\n toStringTagSymbol = $Symbol.toStringTag || \"@@toStringTag\";\n\n function define(obj, key, value) {\n return Object.defineProperty(obj, key, {\n value: value,\n enumerable: !0,\n configurable: !0,\n writable: !0\n }), obj[key];\n }\n\n try {\n define({}, \"\");\n } catch (err) {\n define = function define(obj, key, value) {\n return obj[key] = value;\n };\n }\n\n function wrap(innerFn, outerFn, self, tryLocsList) {\n var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator,\n generator = Object.create(protoGenerator.prototype),\n context = new Context(tryLocsList || []);\n return generator._invoke = function (innerFn, self, context) {\n var state = \"suspendedStart\";\n return function (method, arg) {\n if (\"executing\" === state) throw new Error(\"Generator is already running\");\n\n if (\"completed\" === state) {\n if (\"throw\" === method) throw arg;\n return doneResult();\n }\n\n for (context.method = method, context.arg = arg;;) {\n var delegate = context.delegate;\n\n if (delegate) {\n var delegateResult = maybeInvokeDelegate(delegate, context);\n\n if (delegateResult) {\n if (delegateResult === ContinueSentinel) continue;\n return delegateResult;\n }\n }\n\n if (\"next\" === context.method) context.sent = context._sent = context.arg;else if (\"throw\" === context.method) {\n if (\"suspendedStart\" === state) throw state = \"completed\", context.arg;\n context.dispatchException(context.arg);\n } else \"return\" === context.method && context.abrupt(\"return\", context.arg);\n state = \"executing\";\n var record = tryCatch(innerFn, self, context);\n\n if (\"normal\" === record.type) {\n if (state = context.done ? \"completed\" : \"suspendedYield\", record.arg === ContinueSentinel) continue;\n return {\n value: record.arg,\n done: context.done\n };\n }\n\n \"throw\" === record.type && (state = \"completed\", context.method = \"throw\", context.arg = record.arg);\n }\n };\n }(innerFn, self, context), generator;\n }\n\n function tryCatch(fn, obj, arg) {\n try {\n return {\n type: \"normal\",\n arg: fn.call(obj, arg)\n };\n } catch (err) {\n return {\n type: \"throw\",\n arg: err\n };\n }\n }\n\n exports.wrap = wrap;\n var ContinueSentinel = {};\n\n function Generator() {}\n\n function GeneratorFunction() {}\n\n function GeneratorFunctionPrototype() {}\n\n var IteratorPrototype = {};\n define(IteratorPrototype, iteratorSymbol, function () {\n return this;\n });\n var getProto = Object.getPrototypeOf,\n NativeIteratorPrototype = getProto && getProto(getProto(values([])));\n NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype);\n var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype);\n\n function defineIteratorMethods(prototype) {\n [\"next\", \"throw\", \"return\"].forEach(function (method) {\n define(prototype, method, function (arg) {\n return this._invoke(method, arg);\n });\n });\n }\n\n function AsyncIterator(generator, PromiseImpl) {\n function invoke(method, arg, resolve, reject) {\n var record = tryCatch(generator[method], generator, arg);\n\n if (\"throw\" !== record.type) {\n var result = record.arg,\n value = result.value;\n return value && \"object\" == _typeof(value) && hasOwn.call(value, \"__await\") ? PromiseImpl.resolve(value.__await).then(function (value) {\n invoke(\"next\", value, resolve, reject);\n }, function (err) {\n invoke(\"throw\", err, resolve, reject);\n }) : PromiseImpl.resolve(value).then(function (unwrapped) {\n result.value = unwrapped, resolve(result);\n }, function (error) {\n return invoke(\"throw\", error, resolve, reject);\n });\n }\n\n reject(record.arg);\n }\n\n var previousPromise;\n\n this._invoke = function (method, arg) {\n function callInvokeWithMethodAndArg() {\n return new PromiseImpl(function (resolve, reject) {\n invoke(method, arg, resolve, reject);\n });\n }\n\n return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg();\n };\n }\n\n function maybeInvokeDelegate(delegate, context) {\n var method = delegate.iterator[context.method];\n\n if (undefined === method) {\n if (context.delegate = null, \"throw\" === context.method) {\n if (delegate.iterator[\"return\"] && (context.method = \"return\", context.arg = undefined, maybeInvokeDelegate(delegate, context), \"throw\" === context.method)) return ContinueSentinel;\n context.method = \"throw\", context.arg = new TypeError(\"The iterator does not provide a 'throw' method\");\n }\n\n return ContinueSentinel;\n }\n\n var record = tryCatch(method, delegate.iterator, context.arg);\n if (\"throw\" === record.type) return context.method = \"throw\", context.arg = record.arg, context.delegate = null, ContinueSentinel;\n var info = record.arg;\n return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, \"return\" !== context.method && (context.method = \"next\", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = \"throw\", context.arg = new TypeError(\"iterator result is not an object\"), context.delegate = null, ContinueSentinel);\n }\n\n function pushTryEntry(locs) {\n var entry = {\n tryLoc: locs[0]\n };\n 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry);\n }\n\n function resetTryEntry(entry) {\n var record = entry.completion || {};\n record.type = \"normal\", delete record.arg, entry.completion = record;\n }\n\n function Context(tryLocsList) {\n this.tryEntries = [{\n tryLoc: \"root\"\n }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0);\n }\n\n function values(iterable) {\n if (iterable) {\n var iteratorMethod = iterable[iteratorSymbol];\n if (iteratorMethod) return iteratorMethod.call(iterable);\n if (\"function\" == typeof iterable.next) return iterable;\n\n if (!isNaN(iterable.length)) {\n var i = -1,\n next = function next() {\n for (; ++i < iterable.length;) {\n if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next;\n }\n\n return next.value = undefined, next.done = !0, next;\n };\n\n return next.next = next;\n }\n }\n\n return {\n next: doneResult\n };\n }\n\n function doneResult() {\n return {\n value: undefined,\n done: !0\n };\n }\n\n return GeneratorFunction.prototype = GeneratorFunctionPrototype, define(Gp, \"constructor\", GeneratorFunctionPrototype), define(GeneratorFunctionPrototype, \"constructor\", GeneratorFunction), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, \"GeneratorFunction\"), exports.isGeneratorFunction = function (genFun) {\n var ctor = \"function\" == typeof genFun && genFun.constructor;\n return !!ctor && (ctor === GeneratorFunction || \"GeneratorFunction\" === (ctor.displayName || ctor.name));\n }, exports.mark = function (genFun) {\n return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, \"GeneratorFunction\")), genFun.prototype = Object.create(Gp), genFun;\n }, exports.awrap = function (arg) {\n return {\n __await: arg\n };\n }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () {\n return this;\n }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) {\n void 0 === PromiseImpl && (PromiseImpl = Promise);\n var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl);\n return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) {\n return result.done ? result.value : iter.next();\n });\n }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, \"Generator\"), define(Gp, iteratorSymbol, function () {\n return this;\n }), define(Gp, \"toString\", function () {\n return \"[object Generator]\";\n }), exports.keys = function (object) {\n var keys = [];\n\n for (var key in object) {\n keys.push(key);\n }\n\n return keys.reverse(), function next() {\n for (; keys.length;) {\n var key = keys.pop();\n if (key in object) return next.value = key, next.done = !1, next;\n }\n\n return next.done = !0, next;\n };\n }, exports.values = values, Context.prototype = {\n constructor: Context,\n reset: function reset(skipTempReset) {\n if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = \"next\", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) {\n \"t\" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined);\n }\n },\n stop: function stop() {\n this.done = !0;\n var rootRecord = this.tryEntries[0].completion;\n if (\"throw\" === rootRecord.type) throw rootRecord.arg;\n return this.rval;\n },\n dispatchException: function dispatchException(exception) {\n if (this.done) throw exception;\n var context = this;\n\n function handle(loc, caught) {\n return record.type = \"throw\", record.arg = exception, context.next = loc, caught && (context.method = \"next\", context.arg = undefined), !!caught;\n }\n\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i],\n record = entry.completion;\n if (\"root\" === entry.tryLoc) return handle(\"end\");\n\n if (entry.tryLoc <= this.prev) {\n var hasCatch = hasOwn.call(entry, \"catchLoc\"),\n hasFinally = hasOwn.call(entry, \"finallyLoc\");\n\n if (hasCatch && hasFinally) {\n if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0);\n if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc);\n } else if (hasCatch) {\n if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0);\n } else {\n if (!hasFinally) throw new Error(\"try statement without catch or finally\");\n if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc);\n }\n }\n }\n },\n abrupt: function abrupt(type, arg) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n\n if (entry.tryLoc <= this.prev && hasOwn.call(entry, \"finallyLoc\") && this.prev < entry.finallyLoc) {\n var finallyEntry = entry;\n break;\n }\n }\n\n finallyEntry && (\"break\" === type || \"continue\" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null);\n var record = finallyEntry ? finallyEntry.completion : {};\n return record.type = type, record.arg = arg, finallyEntry ? (this.method = \"next\", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record);\n },\n complete: function complete(record, afterLoc) {\n if (\"throw\" === record.type) throw record.arg;\n return \"break\" === record.type || \"continue\" === record.type ? this.next = record.arg : \"return\" === record.type ? (this.rval = this.arg = record.arg, this.method = \"return\", this.next = \"end\") : \"normal\" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel;\n },\n finish: function finish(finallyLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel;\n }\n },\n \"catch\": function _catch(tryLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n\n if (entry.tryLoc === tryLoc) {\n var record = entry.completion;\n\n if (\"throw\" === record.type) {\n var thrown = record.arg;\n resetTryEntry(entry);\n }\n\n return thrown;\n }\n }\n\n throw new Error(\"illegal catch attempt\");\n },\n delegateYield: function delegateYield(iterable, resultName, nextLoc) {\n return this.delegate = {\n iterator: values(iterable),\n resultName: resultName,\n nextLoc: nextLoc\n }, \"next\" === this.method && (this.arg = undefined), ContinueSentinel;\n }\n }, exports;\n}\n\nmodule.exports = _regeneratorRuntime, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;","function _typeof(obj) {\n \"@babel/helpers - typeof\";\n\n return (module.exports = _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (obj) {\n return typeof obj;\n } : function (obj) {\n return obj && \"function\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n }, module.exports.__esModule = true, module.exports[\"default\"] = module.exports), _typeof(obj);\n}\n\nmodule.exports = _typeof, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;","// TODO(Babel 8): Remove this file.\n\nvar runtime = require(\"../helpers/regeneratorRuntime\")();\nmodule.exports = runtime;\n\n// Copied from https://github.com/facebook/regenerator/blob/main/packages/runtime/runtime.js#L736=\ntry {\n regeneratorRuntime = runtime;\n} catch (accidentalStrictMode) {\n if (typeof globalThis === \"object\") {\n globalThis.regeneratorRuntime = runtime;\n } else {\n Function(\"r\", \"regeneratorRuntime = r\")(runtime);\n }\n}\n","/**\n * lodash (Custom Build) <https://lodash.com/>\n * Build: `lodash modularize exports=\"npm\" -o ./`\n * Copyright jQuery Foundation and other contributors <https://jquery.org/>\n * Released under MIT license <https://lodash.com/license>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n\n/** Used as the size to enable large array optimizations. */\nvar LARGE_ARRAY_SIZE = 200;\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n objectTag = '[object Object]',\n promiseTag = '[object Promise]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]',\n weakMapTag = '[object WeakMap]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n/**\n * Used to match `RegExp`\n * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n */\nvar reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g;\n\n/** Used to match `RegExp` flags from their coerced string values. */\nvar reFlags = /\\w*$/;\n\n/** Used to detect host constructors (Safari). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/** Used to identify `toStringTag` values supported by `_.clone`. */\nvar cloneableTags = {};\ncloneableTags[argsTag] = cloneableTags[arrayTag] =\ncloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =\ncloneableTags[boolTag] = cloneableTags[dateTag] =\ncloneableTags[float32Tag] = cloneableTags[float64Tag] =\ncloneableTags[int8Tag] = cloneableTags[int16Tag] =\ncloneableTags[int32Tag] = cloneableTags[mapTag] =\ncloneableTags[numberTag] = cloneableTags[objectTag] =\ncloneableTags[regexpTag] = cloneableTags[setTag] =\ncloneableTags[stringTag] = cloneableTags[symbolTag] =\ncloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =\ncloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;\ncloneableTags[errorTag] = cloneableTags[funcTag] =\ncloneableTags[weakMapTag] = false;\n\n/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/**\n * Adds the key-value `pair` to `map`.\n *\n * @private\n * @param {Object} map The map to modify.\n * @param {Array} pair The key-value pair to add.\n * @returns {Object} Returns `map`.\n */\nfunction addMapEntry(map, pair) {\n // Don't return `map.set` because it's not chainable in IE 11.\n map.set(pair[0], pair[1]);\n return map;\n}\n\n/**\n * Adds `value` to `set`.\n *\n * @private\n * @param {Object} set The set to modify.\n * @param {*} value The value to add.\n * @returns {Object} Returns `set`.\n */\nfunction addSetEntry(set, value) {\n // Don't return `set.add` because it's not chainable in IE 11.\n set.add(value);\n return set;\n}\n\n/**\n * A specialized version of `_.forEach` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns `array`.\n */\nfunction arrayEach(array, iteratee) {\n var index = -1,\n length = array ? array.length : 0;\n\n while (++index < length) {\n if (iteratee(array[index], index, array) === false) {\n break;\n }\n }\n return array;\n}\n\n/**\n * Appends the elements of `values` to `array`.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to append.\n * @returns {Array} Returns `array`.\n */\nfunction arrayPush(array, values) {\n var index = -1,\n length = values.length,\n offset = array.length;\n\n while (++index < length) {\n array[offset + index] = values[index];\n }\n return array;\n}\n\n/**\n * A specialized version of `_.reduce` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {*} [accumulator] The initial value.\n * @param {boolean} [initAccum] Specify using the first element of `array` as\n * the initial value.\n * @returns {*} Returns the accumulated value.\n */\nfunction arrayReduce(array, iteratee, accumulator, initAccum) {\n var index = -1,\n length = array ? array.length : 0;\n\n if (initAccum && length) {\n accumulator = array[++index];\n }\n while (++index < length) {\n accumulator = iteratee(accumulator, array[index], index, array);\n }\n return accumulator;\n}\n\n/**\n * The base implementation of `_.times` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\nfunction baseTimes(n, iteratee) {\n var index = -1,\n result = Array(n);\n\n while (++index < n) {\n result[index] = iteratee(index);\n }\n return result;\n}\n\n/**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction getValue(object, key) {\n return object == null ? undefined : object[key];\n}\n\n/**\n * Checks if `value` is a host object in IE < 9.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a host object, else `false`.\n */\nfunction isHostObject(value) {\n // Many host objects are `Object` objects that can coerce to strings\n // despite having improperly defined `toString` methods.\n var result = false;\n if (value != null && typeof value.toString != 'function') {\n try {\n result = !!(value + '');\n } catch (e) {}\n }\n return result;\n}\n\n/**\n * Converts `map` to its key-value pairs.\n *\n * @private\n * @param {Object} map The map to convert.\n * @returns {Array} Returns the key-value pairs.\n */\nfunction mapToArray(map) {\n var index = -1,\n result = Array(map.size);\n\n map.forEach(function(value, key) {\n result[++index] = [key, value];\n });\n return result;\n}\n\n/**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\nfunction overArg(func, transform) {\n return function(arg) {\n return func(transform(arg));\n };\n}\n\n/**\n * Converts `set` to an array of its values.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the values.\n */\nfunction setToArray(set) {\n var index = -1,\n result = Array(set.size);\n\n set.forEach(function(value) {\n result[++index] = value;\n });\n return result;\n}\n\n/** Used for built-in method references. */\nvar arrayProto = Array.prototype,\n funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to detect overreaching core-js shims. */\nvar coreJsData = root['__core-js_shared__'];\n\n/** Used to detect methods masquerading as native. */\nvar maskSrcKey = (function() {\n var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n return uid ? ('Symbol(src)_1.' + uid) : '';\n}());\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/** Built-in value references. */\nvar Buffer = moduleExports ? root.Buffer : undefined,\n Symbol = root.Symbol,\n Uint8Array = root.Uint8Array,\n getPrototype = overArg(Object.getPrototypeOf, Object),\n objectCreate = Object.create,\n propertyIsEnumerable = objectProto.propertyIsEnumerable,\n splice = arrayProto.splice;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeGetSymbols = Object.getOwnPropertySymbols,\n nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,\n nativeKeys = overArg(Object.keys, Object);\n\n/* Built-in method references that are verified to be native. */\nvar DataView = getNative(root, 'DataView'),\n Map = getNative(root, 'Map'),\n Promise = getNative(root, 'Promise'),\n Set = getNative(root, 'Set'),\n WeakMap = getNative(root, 'WeakMap'),\n nativeCreate = getNative(Object, 'create');\n\n/** Used to detect maps, sets, and weakmaps. */\nvar dataViewCtorString = toSource(DataView),\n mapCtorString = toSource(Map),\n promiseCtorString = toSource(Promise),\n setCtorString = toSource(Set),\n weakMapCtorString = toSource(WeakMap);\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;\n\n/**\n * Creates a hash object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Hash(entries) {\n var index = -1,\n length = entries ? entries.length : 0;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n/**\n * Removes all key-value entries from the hash.\n *\n * @private\n * @name clear\n * @memberOf Hash\n */\nfunction hashClear() {\n this.__data__ = nativeCreate ? nativeCreate(null) : {};\n}\n\n/**\n * Removes `key` and its value from the hash.\n *\n * @private\n * @name delete\n * @memberOf Hash\n * @param {Object} hash The hash to modify.\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction hashDelete(key) {\n return this.has(key) && delete this.__data__[key];\n}\n\n/**\n * Gets the hash value for `key`.\n *\n * @private\n * @name get\n * @memberOf Hash\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction hashGet(key) {\n var data = this.__data__;\n if (nativeCreate) {\n var result = data[key];\n return result === HASH_UNDEFINED ? undefined : result;\n }\n return hasOwnProperty.call(data, key) ? data[key] : undefined;\n}\n\n/**\n * Checks if a hash value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Hash\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction hashHas(key) {\n var data = this.__data__;\n return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key);\n}\n\n/**\n * Sets the hash `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Hash\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the hash instance.\n */\nfunction hashSet(key, value) {\n var data = this.__data__;\n data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;\n return this;\n}\n\n// Add methods to `Hash`.\nHash.prototype.clear = hashClear;\nHash.prototype['delete'] = hashDelete;\nHash.prototype.get = hashGet;\nHash.prototype.has = hashHas;\nHash.prototype.set = hashSet;\n\n/**\n * Creates an list cache object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction ListCache(entries) {\n var index = -1,\n length = entries ? entries.length : 0;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n/**\n * Removes all key-value entries from the list cache.\n *\n * @private\n * @name clear\n * @memberOf ListCache\n */\nfunction listCacheClear() {\n this.__data__ = [];\n}\n\n/**\n * Removes `key` and its value from the list cache.\n *\n * @private\n * @name delete\n * @memberOf ListCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction listCacheDelete(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n return false;\n }\n var lastIndex = data.length - 1;\n if (index == lastIndex) {\n data.pop();\n } else {\n splice.call(data, index, 1);\n }\n return true;\n}\n\n/**\n * Gets the list cache value for `key`.\n *\n * @private\n * @name get\n * @memberOf ListCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction listCacheGet(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n return index < 0 ? undefined : data[index][1];\n}\n\n/**\n * Checks if a list cache value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf ListCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction listCacheHas(key) {\n return assocIndexOf(this.__data__, key) > -1;\n}\n\n/**\n * Sets the list cache `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf ListCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the list cache instance.\n */\nfunction listCacheSet(key, value) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n data.push([key, value]);\n } else {\n data[index][1] = value;\n }\n return this;\n}\n\n// Add methods to `ListCache`.\nListCache.prototype.clear = listCacheClear;\nListCache.prototype['delete'] = listCacheDelete;\nListCache.prototype.get = listCacheGet;\nListCache.prototype.has = listCacheHas;\nListCache.prototype.set = listCacheSet;\n\n/**\n * Creates a map cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction MapCache(entries) {\n var index = -1,\n length = entries ? entries.length : 0;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n/**\n * Removes all key-value entries from the map.\n *\n * @private\n * @name clear\n * @memberOf MapCache\n */\nfunction mapCacheClear() {\n this.__data__ = {\n 'hash': new Hash,\n 'map': new (Map || ListCache),\n 'string': new Hash\n };\n}\n\n/**\n * Removes `key` and its value from the map.\n *\n * @private\n * @name delete\n * @memberOf MapCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction mapCacheDelete(key) {\n return getMapData(this, key)['delete'](key);\n}\n\n/**\n * Gets the map value for `key`.\n *\n * @private\n * @name get\n * @memberOf MapCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction mapCacheGet(key) {\n return getMapData(this, key).get(key);\n}\n\n/**\n * Checks if a map value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf MapCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction mapCacheHas(key) {\n return getMapData(this, key).has(key);\n}\n\n/**\n * Sets the map `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf MapCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the map cache instance.\n */\nfunction mapCacheSet(key, value) {\n getMapData(this, key).set(key, value);\n return this;\n}\n\n// Add methods to `MapCache`.\nMapCache.prototype.clear = mapCacheClear;\nMapCache.prototype['delete'] = mapCacheDelete;\nMapCache.prototype.get = mapCacheGet;\nMapCache.prototype.has = mapCacheHas;\nMapCache.prototype.set = mapCacheSet;\n\n/**\n * Creates a stack cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Stack(entries) {\n this.__data__ = new ListCache(entries);\n}\n\n/**\n * Removes all key-value entries from the stack.\n *\n * @private\n * @name clear\n * @memberOf Stack\n */\nfunction stackClear() {\n this.__data__ = new ListCache;\n}\n\n/**\n * Removes `key` and its value from the stack.\n *\n * @private\n * @name delete\n * @memberOf Stack\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction stackDelete(key) {\n return this.__data__['delete'](key);\n}\n\n/**\n * Gets the stack value for `key`.\n *\n * @private\n * @name get\n * @memberOf Stack\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction stackGet(key) {\n return this.__data__.get(key);\n}\n\n/**\n * Checks if a stack value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Stack\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction stackHas(key) {\n return this.__data__.has(key);\n}\n\n/**\n * Sets the stack `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Stack\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the stack cache instance.\n */\nfunction stackSet(key, value) {\n var cache = this.__data__;\n if (cache instanceof ListCache) {\n var pairs = cache.__data__;\n if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {\n pairs.push([key, value]);\n return this;\n }\n cache = this.__data__ = new MapCache(pairs);\n }\n cache.set(key, value);\n return this;\n}\n\n// Add methods to `Stack`.\nStack.prototype.clear = stackClear;\nStack.prototype['delete'] = stackDelete;\nStack.prototype.get = stackGet;\nStack.prototype.has = stackHas;\nStack.prototype.set = stackSet;\n\n/**\n * Creates an array of the enumerable property names of the array-like `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @param {boolean} inherited Specify returning inherited property names.\n * @returns {Array} Returns the array of property names.\n */\nfunction arrayLikeKeys(value, inherited) {\n // Safari 8.1 makes `arguments.callee` enumerable in strict mode.\n // Safari 9 makes `arguments.length` enumerable in strict mode.\n var result = (isArray(value) || isArguments(value))\n ? baseTimes(value.length, String)\n : [];\n\n var length = result.length,\n skipIndexes = !!length;\n\n for (var key in value) {\n if ((inherited || hasOwnProperty.call(value, key)) &&\n !(skipIndexes && (key == 'length' || isIndex(key, length)))) {\n result.push(key);\n }\n }\n return result;\n}\n\n/**\n * Assigns `value` to `key` of `object` if the existing value is not equivalent\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction assignValue(object, key, value) {\n var objValue = object[key];\n if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||\n (value === undefined && !(key in object))) {\n object[key] = value;\n }\n}\n\n/**\n * Gets the index at which the `key` is found in `array` of key-value pairs.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} key The key to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction assocIndexOf(array, key) {\n var length = array.length;\n while (length--) {\n if (eq(array[length][0], key)) {\n return length;\n }\n }\n return -1;\n}\n\n/**\n * The base implementation of `_.assign` without support for multiple sources\n * or `customizer` functions.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @returns {Object} Returns `object`.\n */\nfunction baseAssign(object, source) {\n return object && copyObject(source, keys(source), object);\n}\n\n/**\n * The base implementation of `_.clone` and `_.cloneDeep` which tracks\n * traversed objects.\n *\n * @private\n * @param {*} value The value to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @param {boolean} [isFull] Specify a clone including symbols.\n * @param {Function} [customizer] The function to customize cloning.\n * @param {string} [key] The key of `value`.\n * @param {Object} [object] The parent object of `value`.\n * @param {Object} [stack] Tracks traversed objects and their clone counterparts.\n * @returns {*} Returns the cloned value.\n */\nfunction baseClone(value, isDeep, isFull, customizer, key, object, stack) {\n var result;\n if (customizer) {\n result = object ? customizer(value, key, object, stack) : customizer(value);\n }\n if (result !== undefined) {\n return result;\n }\n if (!isObject(value)) {\n return value;\n }\n var isArr = isArray(value);\n if (isArr) {\n result = initCloneArray(value);\n if (!isDeep) {\n return copyArray(value, result);\n }\n } else {\n var tag = getTag(value),\n isFunc = tag == funcTag || tag == genTag;\n\n if (isBuffer(value)) {\n return cloneBuffer(value, isDeep);\n }\n if (tag == objectTag || tag == argsTag || (isFunc && !object)) {\n if (isHostObject(value)) {\n return object ? value : {};\n }\n result = initCloneObject(isFunc ? {} : value);\n if (!isDeep) {\n return copySymbols(value, baseAssign(result, value));\n }\n } else {\n if (!cloneableTags[tag]) {\n return object ? value : {};\n }\n result = initCloneByTag(value, tag, baseClone, isDeep);\n }\n }\n // Check for circular references and return its corresponding clone.\n stack || (stack = new Stack);\n var stacked = stack.get(value);\n if (stacked) {\n return stacked;\n }\n stack.set(value, result);\n\n if (!isArr) {\n var props = isFull ? getAllKeys(value) : keys(value);\n }\n arrayEach(props || value, function(subValue, key) {\n if (props) {\n key = subValue;\n subValue = value[key];\n }\n // Recursively populate clone (susceptible to call stack limits).\n assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack));\n });\n return result;\n}\n\n/**\n * The base implementation of `_.create` without support for assigning\n * properties to the created object.\n *\n * @private\n * @param {Object} prototype The object to inherit from.\n * @returns {Object} Returns the new object.\n */\nfunction baseCreate(proto) {\n return isObject(proto) ? objectCreate(proto) : {};\n}\n\n/**\n * The base implementation of `getAllKeys` and `getAllKeysIn` which uses\n * `keysFunc` and `symbolsFunc` to get the enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @param {Function} symbolsFunc The function to get the symbols of `object`.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction baseGetAllKeys(object, keysFunc, symbolsFunc) {\n var result = keysFunc(object);\n return isArray(object) ? result : arrayPush(result, symbolsFunc(object));\n}\n\n/**\n * The base implementation of `getTag`.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction baseGetTag(value) {\n return objectToString.call(value);\n}\n\n/**\n * The base implementation of `_.isNative` without bad shim checks.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function,\n * else `false`.\n */\nfunction baseIsNative(value) {\n if (!isObject(value) || isMasked(value)) {\n return false;\n }\n var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor;\n return pattern.test(toSource(value));\n}\n\n/**\n * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeys(object) {\n if (!isPrototype(object)) {\n return nativeKeys(object);\n }\n var result = [];\n for (var key in Object(object)) {\n if (hasOwnProperty.call(object, key) && key != 'constructor') {\n result.push(key);\n }\n }\n return result;\n}\n\n/**\n * Creates a clone of `buffer`.\n *\n * @private\n * @param {Buffer} buffer The buffer to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Buffer} Returns the cloned buffer.\n */\nfunction cloneBuffer(buffer, isDeep) {\n if (isDeep) {\n return buffer.slice();\n }\n var result = new buffer.constructor(buffer.length);\n buffer.copy(result);\n return result;\n}\n\n/**\n * Creates a clone of `arrayBuffer`.\n *\n * @private\n * @param {ArrayBuffer} arrayBuffer The array buffer to clone.\n * @returns {ArrayBuffer} Returns the cloned array buffer.\n */\nfunction cloneArrayBuffer(arrayBuffer) {\n var result = new arrayBuffer.constructor(arrayBuffer.byteLength);\n new Uint8Array(result).set(new Uint8Array(arrayBuffer));\n return result;\n}\n\n/**\n * Creates a clone of `dataView`.\n *\n * @private\n * @param {Object} dataView The data view to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned data view.\n */\nfunction cloneDataView(dataView, isDeep) {\n var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;\n return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);\n}\n\n/**\n * Creates a clone of `map`.\n *\n * @private\n * @param {Object} map The map to clone.\n * @param {Function} cloneFunc The function to clone values.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned map.\n */\nfunction cloneMap(map, isDeep, cloneFunc) {\n var array = isDeep ? cloneFunc(mapToArray(map), true) : mapToArray(map);\n return arrayReduce(array, addMapEntry, new map.constructor);\n}\n\n/**\n * Creates a clone of `regexp`.\n *\n * @private\n * @param {Object} regexp The regexp to clone.\n * @returns {Object} Returns the cloned regexp.\n */\nfunction cloneRegExp(regexp) {\n var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));\n result.lastIndex = regexp.lastIndex;\n return result;\n}\n\n/**\n * Creates a clone of `set`.\n *\n * @private\n * @param {Object} set The set to clone.\n * @param {Function} cloneFunc The function to clone values.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned set.\n */\nfunction cloneSet(set, isDeep, cloneFunc) {\n var array = isDeep ? cloneFunc(setToArray(set), true) : setToArray(set);\n return arrayReduce(array, addSetEntry, new set.constructor);\n}\n\n/**\n * Creates a clone of the `symbol` object.\n *\n * @private\n * @param {Object} symbol The symbol object to clone.\n * @returns {Object} Returns the cloned symbol object.\n */\nfunction cloneSymbol(symbol) {\n return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};\n}\n\n/**\n * Creates a clone of `typedArray`.\n *\n * @private\n * @param {Object} typedArray The typed array to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned typed array.\n */\nfunction cloneTypedArray(typedArray, isDeep) {\n var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;\n return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);\n}\n\n/**\n * Copies the values of `source` to `array`.\n *\n * @private\n * @param {Array} source The array to copy values from.\n * @param {Array} [array=[]] The array to copy values to.\n * @returns {Array} Returns `array`.\n */\nfunction copyArray(source, array) {\n var index = -1,\n length = source.length;\n\n array || (array = Array(length));\n while (++index < length) {\n array[index] = source[index];\n }\n return array;\n}\n\n/**\n * Copies properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy properties from.\n * @param {Array} props The property identifiers to copy.\n * @param {Object} [object={}] The object to copy properties to.\n * @param {Function} [customizer] The function to customize copied values.\n * @returns {Object} Returns `object`.\n */\nfunction copyObject(source, props, object, customizer) {\n object || (object = {});\n\n var index = -1,\n length = props.length;\n\n while (++index < length) {\n var key = props[index];\n\n var newValue = customizer\n ? customizer(object[key], source[key], key, object, source)\n : undefined;\n\n assignValue(object, key, newValue === undefined ? source[key] : newValue);\n }\n return object;\n}\n\n/**\n * Copies own symbol properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy symbols from.\n * @param {Object} [object={}] The object to copy symbols to.\n * @returns {Object} Returns `object`.\n */\nfunction copySymbols(source, object) {\n return copyObject(source, getSymbols(source), object);\n}\n\n/**\n * Creates an array of own enumerable property names and symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction getAllKeys(object) {\n return baseGetAllKeys(object, keys, getSymbols);\n}\n\n/**\n * Gets the data for `map`.\n *\n * @private\n * @param {Object} map The map to query.\n * @param {string} key The reference key.\n * @returns {*} Returns the map data.\n */\nfunction getMapData(map, key) {\n var data = map.__data__;\n return isKeyable(key)\n ? data[typeof key == 'string' ? 'string' : 'hash']\n : data.map;\n}\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n var value = getValue(object, key);\n return baseIsNative(value) ? value : undefined;\n}\n\n/**\n * Creates an array of the own enumerable symbol properties of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\nvar getSymbols = nativeGetSymbols ? overArg(nativeGetSymbols, Object) : stubArray;\n\n/**\n * Gets the `toStringTag` of `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nvar getTag = baseGetTag;\n\n// Fallback for data views, maps, sets, and weak maps in IE 11,\n// for data views in Edge < 14, and promises in Node.js.\nif ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||\n (Map && getTag(new Map) != mapTag) ||\n (Promise && getTag(Promise.resolve()) != promiseTag) ||\n (Set && getTag(new Set) != setTag) ||\n (WeakMap && getTag(new WeakMap) != weakMapTag)) {\n getTag = function(value) {\n var result = objectToString.call(value),\n Ctor = result == objectTag ? value.constructor : undefined,\n ctorString = Ctor ? toSource(Ctor) : undefined;\n\n if (ctorString) {\n switch (ctorString) {\n case dataViewCtorString: return dataViewTag;\n case mapCtorString: return mapTag;\n case promiseCtorString: return promiseTag;\n case setCtorString: return setTag;\n case weakMapCtorString: return weakMapTag;\n }\n }\n return result;\n };\n}\n\n/**\n * Initializes an array clone.\n *\n * @private\n * @param {Array} array The array to clone.\n * @returns {Array} Returns the initialized clone.\n */\nfunction initCloneArray(array) {\n var length = array.length,\n result = array.constructor(length);\n\n // Add properties assigned by `RegExp#exec`.\n if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {\n result.index = array.index;\n result.input = array.input;\n }\n return result;\n}\n\n/**\n * Initializes an object clone.\n *\n * @private\n * @param {Object} object The object to clone.\n * @returns {Object} Returns the initialized clone.\n */\nfunction initCloneObject(object) {\n return (typeof object.constructor == 'function' && !isPrototype(object))\n ? baseCreate(getPrototype(object))\n : {};\n}\n\n/**\n * Initializes an object clone based on its `toStringTag`.\n *\n * **Note:** This function only supports cloning values with tags of\n * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n *\n * @private\n * @param {Object} object The object to clone.\n * @param {string} tag The `toStringTag` of the object to clone.\n * @param {Function} cloneFunc The function to clone values.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the initialized clone.\n */\nfunction initCloneByTag(object, tag, cloneFunc, isDeep) {\n var Ctor = object.constructor;\n switch (tag) {\n case arrayBufferTag:\n return cloneArrayBuffer(object);\n\n case boolTag:\n case dateTag:\n return new Ctor(+object);\n\n case dataViewTag:\n return cloneDataView(object, isDeep);\n\n case float32Tag: case float64Tag:\n case int8Tag: case int16Tag: case int32Tag:\n case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:\n return cloneTypedArray(object, isDeep);\n\n case mapTag:\n return cloneMap(object, isDeep, cloneFunc);\n\n case numberTag:\n case stringTag:\n return new Ctor(object);\n\n case regexpTag:\n return cloneRegExp(object);\n\n case setTag:\n return cloneSet(object, isDeep, cloneFunc);\n\n case symbolTag:\n return cloneSymbol(object);\n }\n}\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n length = length == null ? MAX_SAFE_INTEGER : length;\n return !!length &&\n (typeof value == 'number' || reIsUint.test(value)) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\n/**\n * Checks if `value` is suitable for use as unique object key.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n */\nfunction isKeyable(value) {\n var type = typeof value;\n return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n ? (value !== '__proto__')\n : (value === null);\n}\n\n/**\n * Checks if `func` has its source masked.\n *\n * @private\n * @param {Function} func The function to check.\n * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n */\nfunction isMasked(func) {\n return !!maskSrcKey && (maskSrcKey in func);\n}\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n}\n\n/**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to process.\n * @returns {string} Returns the source code.\n */\nfunction toSource(func) {\n if (func != null) {\n try {\n return funcToString.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n}\n\n/**\n * This method is like `_.clone` except that it recursively clones `value`.\n *\n * @static\n * @memberOf _\n * @since 1.0.0\n * @category Lang\n * @param {*} value The value to recursively clone.\n * @returns {*} Returns the deep cloned value.\n * @see _.clone\n * @example\n *\n * var objects = [{ 'a': 1 }, { 'b': 2 }];\n *\n * var deep = _.cloneDeep(objects);\n * console.log(deep[0] === objects[0]);\n * // => false\n */\nfunction cloneDeep(value) {\n return baseClone(value, true, true);\n}\n\n/**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n return value === other || (value !== value && other !== other);\n}\n\n/**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n * else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\nfunction isArguments(value) {\n // Safari 8.1 makes `arguments.callee` enumerable in strict mode.\n return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&\n (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);\n}\n\n/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n return value != null && isLength(value.length) && !isFunction(value);\n}\n\n/**\n * This method is like `_.isArrayLike` except that it also checks if `value`\n * is an object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array-like object,\n * else `false`.\n * @example\n *\n * _.isArrayLikeObject([1, 2, 3]);\n * // => true\n *\n * _.isArrayLikeObject(document.body.children);\n * // => true\n *\n * _.isArrayLikeObject('abc');\n * // => false\n *\n * _.isArrayLikeObject(_.noop);\n * // => false\n */\nfunction isArrayLikeObject(value) {\n return isObjectLike(value) && isArrayLike(value);\n}\n\n/**\n * Checks if `value` is a buffer.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.\n * @example\n *\n * _.isBuffer(new Buffer(2));\n * // => true\n *\n * _.isBuffer(new Uint8Array(2));\n * // => false\n */\nvar isBuffer = nativeIsBuffer || stubFalse;\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 8-9 which returns 'object' for typed array and other constructors.\n var tag = isObject(value) ? objectToString.call(value) : '';\n return tag == funcTag || tag == genTag;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return !!value && typeof value == 'object';\n}\n\n/**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\nfunction keys(object) {\n return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);\n}\n\n/**\n * This method returns a new empty array.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {Array} Returns the new empty array.\n * @example\n *\n * var arrays = _.times(2, _.stubArray);\n *\n * console.log(arrays);\n * // => [[], []]\n *\n * console.log(arrays[0] === arrays[1]);\n * // => false\n */\nfunction stubArray() {\n return [];\n}\n\n/**\n * This method returns `false`.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {boolean} Returns `false`.\n * @example\n *\n * _.times(2, _.stubFalse);\n * // => [false, false]\n */\nfunction stubFalse() {\n return false;\n}\n\nmodule.exports = cloneDeep;\n","module.exports = __WEBPACK_EXTERNAL_MODULE__785__;","module.exports = __WEBPACK_EXTERNAL_MODULE__948__;","module.exports = __WEBPACK_EXTERNAL_MODULE__807__;","module.exports = __WEBPACK_EXTERNAL_MODULE__847__;","module.exports = __WEBPACK_EXTERNAL_MODULE__348__;","module.exports = __WEBPACK_EXTERNAL_MODULE__283__;","module.exports = __WEBPACK_EXTERNAL_MODULE__441__;","module.exports = __WEBPACK_EXTERNAL_MODULE__864__;","module.exports = __WEBPACK_EXTERNAL_MODULE__70__;","module.exports = __WEBPACK_EXTERNAL_MODULE__474__;","module.exports = __WEBPACK_EXTERNAL_MODULE__821__;","module.exports = __WEBPACK_EXTERNAL_MODULE__795__;","module.exports = __WEBPACK_EXTERNAL_MODULE__896__;","module.exports = __WEBPACK_EXTERNAL_MODULE__861__;","module.exports = __WEBPACK_EXTERNAL_MODULE__610__;","module.exports = __WEBPACK_EXTERNAL_MODULE__478__;","module.exports = __WEBPACK_EXTERNAL_MODULE__329__;","module.exports = __WEBPACK_EXTERNAL_MODULE__673__;","module.exports = __WEBPACK_EXTERNAL_MODULE__281__;","module.exports = __WEBPACK_EXTERNAL_MODULE__739__;","module.exports = __WEBPACK_EXTERNAL_MODULE__9__;","module.exports = __WEBPACK_EXTERNAL_MODULE__468__;","module.exports = __WEBPACK_EXTERNAL_MODULE__643__;","module.exports = __WEBPACK_EXTERNAL_MODULE__128__;","module.exports = __WEBPACK_EXTERNAL_MODULE__664__;","module.exports = __WEBPACK_EXTERNAL_MODULE__973__;","module.exports = __WEBPACK_EXTERNAL_MODULE__394__;","module.exports = __WEBPACK_EXTERNAL_MODULE__582__;","module.exports = __WEBPACK_EXTERNAL_MODULE__482__;","module.exports = __WEBPACK_EXTERNAL_MODULE__343__;","module.exports = __WEBPACK_EXTERNAL_MODULE__21__;","module.exports = __WEBPACK_EXTERNAL_MODULE__363__;","module.exports = __WEBPACK_EXTERNAL_MODULE__982__;","module.exports = __WEBPACK_EXTERNAL_MODULE__130__;","module.exports = __WEBPACK_EXTERNAL_MODULE__298__;","module.exports = __WEBPACK_EXTERNAL_MODULE__953__;","module.exports = __WEBPACK_EXTERNAL_MODULE__395__;","module.exports = __WEBPACK_EXTERNAL_MODULE__398__;","module.exports = __WEBPACK_EXTERNAL_MODULE__388__;","module.exports = __WEBPACK_EXTERNAL_MODULE__215__;","module.exports = __WEBPACK_EXTERNAL_MODULE__120__;","module.exports = __WEBPACK_EXTERNAL_MODULE__197__;","module.exports = __WEBPACK_EXTERNAL_MODULE__976__;","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\tid: moduleId,\n\t\tloaded: false,\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Flag the module as loaded\n\tmodule.loaded = true;\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = function(module) {\n\tvar getter = module && module.__esModule ?\n\t\tfunction() { return module['default']; } :\n\t\tfunction() { return module; };\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","// define __esModule on exports\n__webpack_require__.r = function(exports) {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","__webpack_require__.nmd = function(module) {\n\tmodule.paths = [];\n\tif (!module.children) module.children = [];\n\treturn module;\n};","/**\n * Cornerstone Core events\n */\nenum Events {\n /**\n * ERROR CODES\n */\n\n /**\n * Error that is thrown when the ImageCache exceeds its max cache size.\n * This can happen for both volumes and stack images.\n */\n CACHE_SIZE_EXCEEDED = 'CACHE_SIZE_EXCEEDED',\n /**\n * Happens if an image (either a single image in stack viewport) or a slice\n * of a volume fails to load by the image/volume loaders.\n */\n IMAGE_LOAD_ERROR = 'IMAGE_LOAD_ERROR',\n\n /**\n * Triggers on the HTML element when the viewport camera changes.\n *\n * Make use of {@link EventTypes.CameraModifiedEvent | CameraModified Event Type } for typing your event listeners for CAMERA_MODIFIED event,\n * and see what event detail is included in {@link EventTypes.CameraModifiedEventDetail | CameraModified Event Detail }\n */\n CAMERA_MODIFIED = 'CORNERSTONE_CAMERA_MODIFIED',\n /**\n * Triggers on the HTML element when the viewport camera resets\n *\n * Make use of {@link EventTypes.CameraResetEvent | CameraReset Event Type } for typing your event listeners for CAMERA_RESET event,\n * and see what event detail is included in {@link EventTypes.CameraResetEventDetail | CameraReset Event Detail }\n */\n CAMERA_RESET = 'CORNERSTONE_CAMERA_RESET',\n /**\n * Triggers on the HTML element when viewport modifies its VOI\n *\n * Make use of {@link EventTypes.VoiModifiedEvent | VoiModified Event Type } for typing your event listeners for VOI_MODIFIED event,\n * and see what event detail is included in {@link EventTypes.VoiModifiedEventDetail | VoiModified Event Detail }\n */\n VOI_MODIFIED = 'CORNERSTONE_VOI_MODIFIED',\n /**\n * Triggers on the eventTarget when the element is disabled\n *\n * Make use of {@link EventTypes.ElementDisabledEvent | ElementDisabled Event Type } for typing your event listeners for ELEMENT_DISABLED event,\n * and see what event detail is included in {@link EventTypes.ElementDisabledEventDetail | ElementDisabled Event Detail }\n */\n ELEMENT_DISABLED = 'CORNERSTONE_ELEMENT_DISABLED',\n /**\n * Triggers on the eventTarget when the element is enabled\n *\n * Make use of {@link EventTypes.ElementEnabledEvent | ElementEnabled Event Type } for typing your event listeners for ELEMENT_ENABLED event,\n * and see what event detail is included in {@link EventTypes.ElementEnabledEventDetail | ElementEnabled Event Detail }\n */\n ELEMENT_ENABLED = 'CORNERSTONE_ELEMENT_ENABLED',\n /**\n * Triggers on the element when the image in the element has been rendered\n *\n * Make use of {@link EventTypes.ImageRenderedEvent | ImageRendered Event Type } for typing your event listeners for IMAGE_RENDERED event,\n * and see what event detail is included in {@link EventTypes.ImageRenderedEventDetail | ImageRendered Event Detail }\n */\n IMAGE_RENDERED = 'CORNERSTONE_IMAGE_RENDERED',\n /**\n * Triggers on the eventTarget when the image volume data is modified. This happens\n * in the streamingImageLoader when each frame is loaded and inserted into a volume.\n *\n *\n * Make use of {@link EventTypes.ImageVolumeModifiedEvent | ImageVolumeModified Event Type } for typing your event listeners for IMAGE_VOLUME_MODIFIED event,\n * and see what event detail is included in {@link EventTypes.ImageVolumeModifiedEventDetail | ImageVolumeModified Event Detail }\n */\n IMAGE_VOLUME_MODIFIED = 'CORNERSTONE_IMAGE_VOLUME_MODIFIED',\n /**\n * Triggers on the eventTarget when the image has successfully loaded by imageLoaders\n *\n * Make use of {@link EventTypes.ImageLoadedEvent | ImageLoaded Event Type } for typing your event listeners for IMAGE_LOADED event,\n * and see what event detail is included in {@link EventTypes.ImageLoadedEventDetail | ImageLoaded Event Detail }\n */\n IMAGE_LOADED = 'CORNERSTONE_IMAGE_LOADED',\n /**\n * Triggers on the eventTarget when the image has failed loading by imageLoaders\n *\n * Make use of {@link EventTypes.ImageLoadedFailedEvent | ImageLoadedFailed Event Type } for typing your event listeners for IMAGE_LOADED_FAILED event,\n * and see what event detail is included in {@link EventTypes.ImageLoadedFailedEventDetail | ImageLoadedFailed Event Detail }\n */\n IMAGE_LOAD_FAILED = 'CORNERSTONE_IMAGE_LOAD_FAILED',\n /**\n * Triggers on element when a new voluem is set on the volume viewport\n */\n VOLUME_VIEWPORT_NEW_VOLUME = 'CORNERSTONE_VOLUME_VIEWPORT_NEW_VOLUME',\n\n /**\n * Triggers on the eventTarget when the volume has successfully loaded by volumeLoaders\n *\n * Make use of {@link EventTypes.VolumeLoadedEvent | VolumeLoaded Event Type } for typing your event listeners for VOLUME_LOADED event,\n * and see what event detail is included in {@link EventTypes.VolumeLoadedEventDetail | VolumeLoaded Event Detail }\n */\n VOLUME_LOADED = 'CORNERSTONE_VOLUME_LOADED',\n /**\n * Triggers on the eventTarget when the image has failed loading by volumeLoaders\n *\n * Make use of {@link EventTypes.VolumeLoadedFailedEvent | VolumeLoadedFailed Event Type } for typing your event listeners for VOLUME_LOADED_FAILED event,\n * and see what event detail is included in {@link EventTypes.VolumeLoadedFailedEventDetail | VolumeLoadedFailed Event Detail }\n */\n VOLUME_LOADED_FAILED = 'CORNERSTONE_VOLUME_LOADED_FAILED',\n /**\n * Triggers on the eventTarget when an image is added to the image cache\n *\n * Make use of {@link EventTypes.ImageCacheImageAddedEvent | ImageCacheAdded Event Type } for typing your event listeners for IMAGE_CACHE_ADDED event,\n * and see what event detail is included in {@link EventTypes.ImageCacheImageAddedEventDetail | ImageCacheAdded Event Detail }\n */\n IMAGE_CACHE_IMAGE_ADDED = 'CORNERSTONE_IMAGE_CACHE_IMAGE_ADDED',\n /**\n * Triggers on the eventTarget when an image is removed from the image cache\n *\n * Make use of {@link EventTypes.ImageCacheImageRemovedEvent | ImageCacheRemoved Event Type } for typing your event listeners for IMAGE_CACHE_REMOVED event,\n * and see what event detail is included in {@link EventTypes.ImageCacheImageRemovedEventDetail | ImageCacheRemoved Event Detail }\n */\n IMAGE_CACHE_IMAGE_REMOVED = 'CORNERSTONE_IMAGE_CACHE_IMAGE_REMOVED',\n /**\n * Triggers on the eventTarget when a volume is added to the volume cache\n *\n * Make use of {@link EventTypes.VolumeCacheVolumeAddedEvent | VolumeCacheAdded Event Type } for typing your event listeners for VOLUME_CACHE_ADDED event,\n * and see what event detail is included in {@link EventTypes.VolumeCacheVolumeAddedEventDetail | VolumeCacheAdded Event Detail }\n */\n VOLUME_CACHE_VOLUME_ADDED = 'CORNERSTONE_VOLUME_CACHE_VOLUME_ADDED',\n /**\n * Triggers on the eventTarget when a volume is removed from the volume cache\n *\n * Make use of {@link EventTypes.VolumeCacheVolumeRemovedEvent | VolumeCacheRemoved Event Type } for typing your event listeners for VOLUME_CACHE_REMOVED event,\n * and see what event detail is included in {@link EventTypes.VolumeCacheVolumeRemovedEventDetail | VolumeCacheRemoved Event Detail }\n */\n VOLUME_CACHE_VOLUME_REMOVED = 'CORNERSTONE_VOLUME_CACHE_VOLUME_REMOVED',\n /**\n * Triggers on the element when a new image is set on the stackViewport\n *\n * Make use of {@link EventTypes.StackNewImageEvent | StackNewImage Event Type } for typing your event listeners for STACK_NEW_IMAGE event,\n * and see what event detail is included in {@link EventTypes.StackNewImageEventDetail | StackNewImage Event Detail }\n */\n STACK_NEW_IMAGE = 'CORNERSTONE_STACK_NEW_IMAGE',\n\n /**\n * Triggers on the element when a new image is set on the volumeViewport, this can be due to scrolling or other\n * tools that change the camera position or focal point.\n *\n * Make use of {@link EventTypes.VolumeNewImageEvent | VolumeNewImage Event Type } for typing your event listeners for VOLUME_NEW_IMAGE event,\n * and see what event detail is included in {@link EventTypes.VolumeNewImageEventDetail | VolumeNewImage Event Detail }\n */\n VOLUME_NEW_IMAGE = 'CORNERSTONE_VOLUME_NEW_IMAGE',\n\n /**\n * Triggers on the element when a new image is about to be set on the stackViewport, pre display\n *\n * Make use of {@link EventTypes.PreStackNewImageEvent | PreStackNewImage Event Type } for typing your event listeners for PRE_STACK_NEW_IMAGE event,\n * and see what event detail is included in {@link EventTypes.PreStackNewImageEventDetail | PreStackNewImage Event Detail }\n */\n PRE_STACK_NEW_IMAGE = 'CORNERSTONE_PRE_STACK_NEW_IMAGE',\n /**\n * Triggers on the element when the viewport's image has calibrated its pixel spacings\n *\n * Make use of {@link EventTypes.ImageSpacingCalibratedEvent | ImageSpacingCalibrated Event Type } for typing your event listeners for IMAGE_SPACING_CALIBRATED event,\n * and see what event detail is included in {@link EventTypes.ImageSpacingCalibratedEventDetail | ImageSpacingCalibrated Event Detail }\n */\n IMAGE_SPACING_CALIBRATED = 'CORNERSTONE_IMAGE_SPACING_CALIBRATED',\n /**\n * Triggers on the eventTarget when there is a progress in the image load process. Note: this event\n * is being used in the Cornerstone-WADO-Image-Loader repository. See {@link https://github.com/cornerstonejs/cornerstoneWADOImageLoader/blob/master/src/imageLoader/internal/xhrRequest.js | here}\n *\n * Make use of {@link EventTypes.ImageLoadProgress | ImageLoadProgress Event Type } for typing your event listeners for IMAGE_LOAD_PROGRESS event,\n * and see what event detail is included in {@link EventTypes.ImageLoadProgressEventDetail | ImageLoadProgress Event Detail }\n */\n IMAGE_LOAD_PROGRESS = 'CORNERSTONE_IMAGE_LOAD_PROGRESS',\n\n /**\n * Triggers on the event target when a new stack is set on its stack viewport.\n * Make use of {@link EventTypes.StackViewportNewStack | StackViewportNewStack Event Type } for typing your event listeners for STACK_VIEWPORT_NEW_STACK event,\n * and see what event detail is included in {@link EventTypes.StackViewportNewStackEventDetail | StackViewportNewStack Event Detail }\n */\n STACK_VIEWPORT_NEW_STACK = 'CORNERSTONE_STACK_VIEWPORT_NEW_STACK',\n\n /**\n * Triggers on the element when the underlying StackViewport is scrolled.\n * Make use of {@link EventTypes.StackViewportScroll | StackViewportScroll Event Type } for typing your event listeners for STACK_VIEWPORT_SCROLL event,\n * and see what event detail is included in {@link EventTypes.StackViewportScrollEventDetail | StackViewportScroll Event Detail }\n */\n STACK_VIEWPORT_SCROLL = 'CORNERSTONE_STACK_VIEWPORT_SCROLL',\n\n // IMAGE_CACHE_FULL = 'CORNERSTONE_IMAGE_CACHE_FULL',\n // PRE_RENDER = 'CORNERSTONE_PRE_RENDER',\n // ELEMENT_RESIZED = 'CORNERSTONE_ELEMENT_RESIZED',\n}\n\nexport default Events;\n","/**\n * Request types for requesting images from the imageLoadPoolManager\n */\nenum RequestType {\n /** Highest priority for loading*/\n Interaction = 'interaction',\n /** Second highest priority for loading*/\n Thumbnail = 'thumbnail',\n /** Lowest priority for loading*/\n Prefetch = 'prefetch',\n}\n\nexport default RequestType;\n","/**\n * ViewportType enum for cornerstone-render which defines the type of viewport.\n * It can be either STACK, PERSPECTIVE, ORTHOGRAPHIC.\n */\nenum ViewportType {\n /**\n * - Suitable for rendering a stack of images, that might or might not belong to the same image.\n * - Stack can include 2D images of different shapes, size and direction\n */\n STACK = 'stack',\n /**\n * - Suitable for rendering a volumetric data which is considered as one 3D image.\n * - Having a VolumeViewport enables Multi-planar reformation or reconstruction (MPR) by design, in which you can visualize the volume from various different orientations without addition of performance costs.\n */\n ORTHOGRAPHIC = 'orthographic',\n /** Perspective Viewport: Not Implemented yet */\n PERSPECTIVE = 'perspective',\n VOLUME_3D = 'volume3d',\n}\n\nexport default ViewportType;\n","/**\n * Interpolation types for image rendering\n */\nenum InterpolationType {\n /** nearest neighbor interpolation */\n NEAREST,\n /** linear interpolation - Default */\n LINEAR,\n /** */\n FAST_LINEAR,\n}\n\nexport default InterpolationType;\n","import vtkConstants from '@kitware/vtk.js/Rendering/Core/VolumeMapper/Constants';\n\nconst { BlendMode } = vtkConstants;\n\n/**\n * Enums for blendModes for viewport images based on vtk.js\n *\n * It should be noted that if crosshairs are enabled and can modify the slab thickness,\n * then it will not show any difference unless MAXIMUM_INTENSITY_BLEND is set on the viewport\n * as the blend.\n */\nenum BlendModes {\n /** composite blending - suitable for compositing multiple images */\n COMPOSITE = BlendMode.COMPOSITE_BLEND,\n /** maximum intensity projection */\n MAXIMUM_INTENSITY_BLEND = BlendMode.MAXIMUM_INTENSITY_BLEND,\n /** minimum intensity projection */\n MINIMUM_INTENSITY_BLEND = BlendMode.MINIMUM_INTENSITY_BLEND,\n /** average intensity projection */\n AVERAGE_INTENSITY_BLEND = BlendMode.AVERAGE_INTENSITY_BLEND,\n}\n\nexport default BlendModes;\n","enum OrientationAxis {\n AXIAL = 'axial',\n CORONAL = 'coronal',\n SAGITTAL = 'sagittal',\n ACQUISITION = 'acquisition',\n}\n\nexport default OrientationAxis;\n","import { CPUFallbackColormapsData } from '../types';\n\n// Colormaps\n//\n// Hot Iron, PET, Hot Metal Blue and PET 20 Step are color palettes\n// Defined by the DICOM standard\n// http://dicom.nema.org/dicom/2013/output/chtml/part06/chapter_B.html\n//\n// All Linear Segmented Colormaps were copied from matplotlib\n// https://github.com/stefanv/matplotlib/blob/master/lib/matplotlib/_cm.py\n\nconst colormapsData: CPUFallbackColormapsData = {\n hotIron: {\n name: 'Hot Iron',\n numOfColors: 256,\n colors: [\n [0, 0, 0, 255],\n [2, 0, 0, 255],\n [4, 0, 0, 255],\n [6, 0, 0, 255],\n [8, 0, 0, 255],\n [10, 0, 0, 255],\n [12, 0, 0, 255],\n [14, 0, 0, 255],\n [16, 0, 0, 255],\n [18, 0, 0, 255],\n [20, 0, 0, 255],\n [22, 0, 0, 255],\n [24, 0, 0, 255],\n [26, 0, 0, 255],\n [28, 0, 0, 255],\n [30, 0, 0, 255],\n [32, 0, 0, 255],\n [34, 0, 0, 255],\n [36, 0, 0, 255],\n [38, 0, 0, 255],\n [40, 0, 0, 255],\n [42, 0, 0, 255],\n [44, 0, 0, 255],\n [46, 0, 0, 255],\n [48, 0, 0, 255],\n [50, 0, 0, 255],\n [52, 0, 0, 255],\n [54, 0, 0, 255],\n [56, 0, 0, 255],\n [58, 0, 0, 255],\n [60, 0, 0, 255],\n [62, 0, 0, 255],\n [64, 0, 0, 255],\n [66, 0, 0, 255],\n [68, 0, 0, 255],\n [70, 0, 0, 255],\n [72, 0, 0, 255],\n [74, 0, 0, 255],\n [76, 0, 0, 255],\n [78, 0, 0, 255],\n [80, 0, 0, 255],\n [82, 0, 0, 255],\n [84, 0, 0, 255],\n [86, 0, 0, 255],\n [88, 0, 0, 255],\n [90, 0, 0, 255],\n [92, 0, 0, 255],\n [94, 0, 0, 255],\n [96, 0, 0, 255],\n [98, 0, 0, 255],\n [100, 0, 0, 255],\n [102, 0, 0, 255],\n [104, 0, 0, 255],\n [106, 0, 0, 255],\n [108, 0, 0, 255],\n [110, 0, 0, 255],\n [112, 0, 0, 255],\n [114, 0, 0, 255],\n [116, 0, 0, 255],\n [118, 0, 0, 255],\n [120, 0, 0, 255],\n [122, 0, 0, 255],\n [124, 0, 0, 255],\n [126, 0, 0, 255],\n [128, 0, 0, 255],\n [130, 0, 0, 255],\n [132, 0, 0, 255],\n [134, 0, 0, 255],\n [136, 0, 0, 255],\n [138, 0, 0, 255],\n [140, 0, 0, 255],\n [142, 0, 0, 255],\n [144, 0, 0, 255],\n [146, 0, 0, 255],\n [148, 0, 0, 255],\n [150, 0, 0, 255],\n [152, 0, 0, 255],\n [154, 0, 0, 255],\n [156, 0, 0, 255],\n [158, 0, 0, 255],\n [160, 0, 0, 255],\n [162, 0, 0, 255],\n [164, 0, 0, 255],\n [166, 0, 0, 255],\n [168, 0, 0, 255],\n [170, 0, 0, 255],\n [172, 0, 0, 255],\n [174, 0, 0, 255],\n [176, 0, 0, 255],\n [178, 0, 0, 255],\n [180, 0, 0, 255],\n [182, 0, 0, 255],\n [184, 0, 0, 255],\n [186, 0, 0, 255],\n [188, 0, 0, 255],\n [190, 0, 0, 255],\n [192, 0, 0, 255],\n [194, 0, 0, 255],\n [196, 0, 0, 255],\n [198, 0, 0, 255],\n [200, 0, 0, 255],\n [202, 0, 0, 255],\n [204, 0, 0, 255],\n [206, 0, 0, 255],\n [208, 0, 0, 255],\n [210, 0, 0, 255],\n [212, 0, 0, 255],\n [214, 0, 0, 255],\n [216, 0, 0, 255],\n [218, 0, 0, 255],\n [220, 0, 0, 255],\n [222, 0, 0, 255],\n [224, 0, 0, 255],\n [226, 0, 0, 255],\n [228, 0, 0, 255],\n [230, 0, 0, 255],\n [232, 0, 0, 255],\n [234, 0, 0, 255],\n [236, 0, 0, 255],\n [238, 0, 0, 255],\n [240, 0, 0, 255],\n [242, 0, 0, 255],\n [244, 0, 0, 255],\n [246, 0, 0, 255],\n [248, 0, 0, 255],\n [250, 0, 0, 255],\n [252, 0, 0, 255],\n [254, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 2, 0, 255],\n [255, 4, 0, 255],\n [255, 6, 0, 255],\n [255, 8, 0, 255],\n [255, 10, 0, 255],\n [255, 12, 0, 255],\n [255, 14, 0, 255],\n [255, 16, 0, 255],\n [255, 18, 0, 255],\n [255, 20, 0, 255],\n [255, 22, 0, 255],\n [255, 24, 0, 255],\n [255, 26, 0, 255],\n [255, 28, 0, 255],\n [255, 30, 0, 255],\n [255, 32, 0, 255],\n [255, 34, 0, 255],\n [255, 36, 0, 255],\n [255, 38, 0, 255],\n [255, 40, 0, 255],\n [255, 42, 0, 255],\n [255, 44, 0, 255],\n [255, 46, 0, 255],\n [255, 48, 0, 255],\n [255, 50, 0, 255],\n [255, 52, 0, 255],\n [255, 54, 0, 255],\n [255, 56, 0, 255],\n [255, 58, 0, 255],\n [255, 60, 0, 255],\n [255, 62, 0, 255],\n [255, 64, 0, 255],\n [255, 66, 0, 255],\n [255, 68, 0, 255],\n [255, 70, 0, 255],\n [255, 72, 0, 255],\n [255, 74, 0, 255],\n [255, 76, 0, 255],\n [255, 78, 0, 255],\n [255, 80, 0, 255],\n [255, 82, 0, 255],\n [255, 84, 0, 255],\n [255, 86, 0, 255],\n [255, 88, 0, 255],\n [255, 90, 0, 255],\n [255, 92, 0, 255],\n [255, 94, 0, 255],\n [255, 96, 0, 255],\n [255, 98, 0, 255],\n [255, 100, 0, 255],\n [255, 102, 0, 255],\n [255, 104, 0, 255],\n [255, 106, 0, 255],\n [255, 108, 0, 255],\n [255, 110, 0, 255],\n [255, 112, 0, 255],\n [255, 114, 0, 255],\n [255, 116, 0, 255],\n [255, 118, 0, 255],\n [255, 120, 0, 255],\n [255, 122, 0, 255],\n [255, 124, 0, 255],\n [255, 126, 0, 255],\n [255, 128, 4, 255],\n [255, 130, 8, 255],\n [255, 132, 12, 255],\n [255, 134, 16, 255],\n [255, 136, 20, 255],\n [255, 138, 24, 255],\n [255, 140, 28, 255],\n [255, 142, 32, 255],\n [255, 144, 36, 255],\n [255, 146, 40, 255],\n [255, 148, 44, 255],\n [255, 150, 48, 255],\n [255, 152, 52, 255],\n [255, 154, 56, 255],\n [255, 156, 60, 255],\n [255, 158, 64, 255],\n [255, 160, 68, 255],\n [255, 162, 72, 255],\n [255, 164, 76, 255],\n [255, 166, 80, 255],\n [255, 168, 84, 255],\n [255, 170, 88, 255],\n [255, 172, 92, 255],\n [255, 174, 96, 255],\n [255, 176, 100, 255],\n [255, 178, 104, 255],\n [255, 180, 108, 255],\n [255, 182, 112, 255],\n [255, 184, 116, 255],\n [255, 186, 120, 255],\n [255, 188, 124, 255],\n [255, 190, 128, 255],\n [255, 192, 132, 255],\n [255, 194, 136, 255],\n [255, 196, 140, 255],\n [255, 198, 144, 255],\n [255, 200, 148, 255],\n [255, 202, 152, 255],\n [255, 204, 156, 255],\n [255, 206, 160, 255],\n [255, 208, 164, 255],\n [255, 210, 168, 255],\n [255, 212, 172, 255],\n [255, 214, 176, 255],\n [255, 216, 180, 255],\n [255, 218, 184, 255],\n [255, 220, 188, 255],\n [255, 222, 192, 255],\n [255, 224, 196, 255],\n [255, 226, 200, 255],\n [255, 228, 204, 255],\n [255, 230, 208, 255],\n [255, 232, 212, 255],\n [255, 234, 216, 255],\n [255, 236, 220, 255],\n [255, 238, 224, 255],\n [255, 240, 228, 255],\n [255, 242, 232, 255],\n [255, 244, 236, 255],\n [255, 246, 240, 255],\n [255, 248, 244, 255],\n [255, 250, 248, 255],\n [255, 252, 252, 255],\n [255, 255, 255, 255],\n ],\n },\n pet: {\n name: 'PET',\n numColors: 256,\n colors: [\n [0, 0, 0, 255],\n [0, 2, 1, 255],\n [0, 4, 3, 255],\n [0, 6, 5, 255],\n [0, 8, 7, 255],\n [0, 10, 9, 255],\n [0, 12, 11, 255],\n [0, 14, 13, 255],\n [0, 16, 15, 255],\n [0, 18, 17, 255],\n [0, 20, 19, 255],\n [0, 22, 21, 255],\n [0, 24, 23, 255],\n [0, 26, 25, 255],\n [0, 28, 27, 255],\n [0, 30, 29, 255],\n [0, 32, 31, 255],\n [0, 34, 33, 255],\n [0, 36, 35, 255],\n [0, 38, 37, 255],\n [0, 40, 39, 255],\n [0, 42, 41, 255],\n [0, 44, 43, 255],\n [0, 46, 45, 255],\n [0, 48, 47, 255],\n [0, 50, 49, 255],\n [0, 52, 51, 255],\n [0, 54, 53, 255],\n [0, 56, 55, 255],\n [0, 58, 57, 255],\n [0, 60, 59, 255],\n [0, 62, 61, 255],\n [0, 65, 63, 255],\n [0, 67, 65, 255],\n [0, 69, 67, 255],\n [0, 71, 69, 255],\n [0, 73, 71, 255],\n [0, 75, 73, 255],\n [0, 77, 75, 255],\n [0, 79, 77, 255],\n [0, 81, 79, 255],\n [0, 83, 81, 255],\n [0, 85, 83, 255],\n [0, 87, 85, 255],\n [0, 89, 87, 255],\n [0, 91, 89, 255],\n [0, 93, 91, 255],\n [0, 95, 93, 255],\n [0, 97, 95, 255],\n [0, 99, 97, 255],\n [0, 101, 99, 255],\n [0, 103, 101, 255],\n [0, 105, 103, 255],\n [0, 107, 105, 255],\n [0, 109, 107, 255],\n [0, 111, 109, 255],\n [0, 113, 111, 255],\n [0, 115, 113, 255],\n [0, 117, 115, 255],\n [0, 119, 117, 255],\n [0, 121, 119, 255],\n [0, 123, 121, 255],\n [0, 125, 123, 255],\n [0, 128, 125, 255],\n [1, 126, 127, 255],\n [3, 124, 129, 255],\n [5, 122, 131, 255],\n [7, 120, 133, 255],\n [9, 118, 135, 255],\n [11, 116, 137, 255],\n [13, 114, 139, 255],\n [15, 112, 141, 255],\n [17, 110, 143, 255],\n [19, 108, 145, 255],\n [21, 106, 147, 255],\n [23, 104, 149, 255],\n [25, 102, 151, 255],\n [27, 100, 153, 255],\n [29, 98, 155, 255],\n [31, 96, 157, 255],\n [33, 94, 159, 255],\n [35, 92, 161, 255],\n [37, 90, 163, 255],\n [39, 88, 165, 255],\n [41, 86, 167, 255],\n [43, 84, 169, 255],\n [45, 82, 171, 255],\n [47, 80, 173, 255],\n [49, 78, 175, 255],\n [51, 76, 177, 255],\n [53, 74, 179, 255],\n [55, 72, 181, 255],\n [57, 70, 183, 255],\n [59, 68, 185, 255],\n [61, 66, 187, 255],\n [63, 64, 189, 255],\n [65, 63, 191, 255],\n [67, 61, 193, 255],\n [69, 59, 195, 255],\n [71, 57, 197, 255],\n [73, 55, 199, 255],\n [75, 53, 201, 255],\n [77, 51, 203, 255],\n [79, 49, 205, 255],\n [81, 47, 207, 255],\n [83, 45, 209, 255],\n [85, 43, 211, 255],\n [86, 41, 213, 255],\n [88, 39, 215, 255],\n [90, 37, 217, 255],\n [92, 35, 219, 255],\n [94, 33, 221, 255],\n [96, 31, 223, 255],\n [98, 29, 225, 255],\n [100, 27, 227, 255],\n [102, 25, 229, 255],\n [104, 23, 231, 255],\n [106, 21, 233, 255],\n [108, 19, 235, 255],\n [110, 17, 237, 255],\n [112, 15, 239, 255],\n [114, 13, 241, 255],\n [116, 11, 243, 255],\n [118, 9, 245, 255],\n [120, 7, 247, 255],\n [122, 5, 249, 255],\n [124, 3, 251, 255],\n [126, 1, 253, 255],\n [128, 0, 255, 255],\n [130, 2, 252, 255],\n [132, 4, 248, 255],\n [134, 6, 244, 255],\n [136, 8, 240, 255],\n [138, 10, 236, 255],\n [140, 12, 232, 255],\n [142, 14, 228, 255],\n [144, 16, 224, 255],\n [146, 18, 220, 255],\n [148, 20, 216, 255],\n [150, 22, 212, 255],\n [152, 24, 208, 255],\n [154, 26, 204, 255],\n [156, 28, 200, 255],\n [158, 30, 196, 255],\n [160, 32, 192, 255],\n [162, 34, 188, 255],\n [164, 36, 184, 255],\n [166, 38, 180, 255],\n [168, 40, 176, 255],\n [170, 42, 172, 255],\n [171, 44, 168, 255],\n [173, 46, 164, 255],\n [175, 48, 160, 255],\n [177, 50, 156, 255],\n [179, 52, 152, 255],\n [181, 54, 148, 255],\n [183, 56, 144, 255],\n [185, 58, 140, 255],\n [187, 60, 136, 255],\n [189, 62, 132, 255],\n [191, 64, 128, 255],\n [193, 66, 124, 255],\n [195, 68, 120, 255],\n [197, 70, 116, 255],\n [199, 72, 112, 255],\n [201, 74, 108, 255],\n [203, 76, 104, 255],\n [205, 78, 100, 255],\n [207, 80, 96, 255],\n [209, 82, 92, 255],\n [211, 84, 88, 255],\n [213, 86, 84, 255],\n [215, 88, 80, 255],\n [217, 90, 76, 255],\n [219, 92, 72, 255],\n [221, 94, 68, 255],\n [223, 96, 64, 255],\n [225, 98, 60, 255],\n [227, 100, 56, 255],\n [229, 102, 52, 255],\n [231, 104, 48, 255],\n [233, 106, 44, 255],\n [235, 108, 40, 255],\n [237, 110, 36, 255],\n [239, 112, 32, 255],\n [241, 114, 28, 255],\n [243, 116, 24, 255],\n [245, 118, 20, 255],\n [247, 120, 16, 255],\n [249, 122, 12, 255],\n [251, 124, 8, 255],\n [253, 126, 4, 255],\n [255, 128, 0, 255],\n [255, 130, 4, 255],\n [255, 132, 8, 255],\n [255, 134, 12, 255],\n [255, 136, 16, 255],\n [255, 138, 20, 255],\n [255, 140, 24, 255],\n [255, 142, 28, 255],\n [255, 144, 32, 255],\n [255, 146, 36, 255],\n [255, 148, 40, 255],\n [255, 150, 44, 255],\n [255, 152, 48, 255],\n [255, 154, 52, 255],\n [255, 156, 56, 255],\n [255, 158, 60, 255],\n [255, 160, 64, 255],\n [255, 162, 68, 255],\n [255, 164, 72, 255],\n [255, 166, 76, 255],\n [255, 168, 80, 255],\n [255, 170, 85, 255],\n [255, 172, 89, 255],\n [255, 174, 93, 255],\n [255, 176, 97, 255],\n [255, 178, 101, 255],\n [255, 180, 105, 255],\n [255, 182, 109, 255],\n [255, 184, 113, 255],\n [255, 186, 117, 255],\n [255, 188, 121, 255],\n [255, 190, 125, 255],\n [255, 192, 129, 255],\n [255, 194, 133, 255],\n [255, 196, 137, 255],\n [255, 198, 141, 255],\n [255, 200, 145, 255],\n [255, 202, 149, 255],\n [255, 204, 153, 255],\n [255, 206, 157, 255],\n [255, 208, 161, 255],\n [255, 210, 165, 255],\n [255, 212, 170, 255],\n [255, 214, 174, 255],\n [255, 216, 178, 255],\n [255, 218, 182, 255],\n [255, 220, 186, 255],\n [255, 222, 190, 255],\n [255, 224, 194, 255],\n [255, 226, 198, 255],\n [255, 228, 202, 255],\n [255, 230, 206, 255],\n [255, 232, 210, 255],\n [255, 234, 214, 255],\n [255, 236, 218, 255],\n [255, 238, 222, 255],\n [255, 240, 226, 255],\n [255, 242, 230, 255],\n [255, 244, 234, 255],\n [255, 246, 238, 255],\n [255, 248, 242, 255],\n [255, 250, 246, 255],\n [255, 252, 250, 255],\n [255, 255, 255, 255],\n ],\n },\n hotMetalBlue: {\n name: 'Hot Metal Blue',\n numColors: 256,\n colors: [\n [0, 0, 0, 255],\n [0, 0, 2, 255],\n [0, 0, 4, 255],\n [0, 0, 6, 255],\n [0, 0, 8, 255],\n [0, 0, 10, 255],\n [0, 0, 12, 255],\n [0, 0, 14, 255],\n [0, 0, 16, 255],\n [0, 0, 17, 255],\n [0, 0, 19, 255],\n [0, 0, 21, 255],\n [0, 0, 23, 255],\n [0, 0, 25, 255],\n [0, 0, 27, 255],\n [0, 0, 29, 255],\n [0, 0, 31, 255],\n [0, 0, 33, 255],\n [0, 0, 35, 255],\n [0, 0, 37, 255],\n [0, 0, 39, 255],\n [0, 0, 41, 255],\n [0, 0, 43, 255],\n [0, 0, 45, 255],\n [0, 0, 47, 255],\n [0, 0, 49, 255],\n [0, 0, 51, 255],\n [0, 0, 53, 255],\n [0, 0, 55, 255],\n [0, 0, 57, 255],\n [0, 0, 59, 255],\n [0, 0, 61, 255],\n [0, 0, 63, 255],\n [0, 0, 65, 255],\n [0, 0, 67, 255],\n [0, 0, 69, 255],\n [0, 0, 71, 255],\n [0, 0, 73, 255],\n [0, 0, 75, 255],\n [0, 0, 77, 255],\n [0, 0, 79, 255],\n [0, 0, 81, 255],\n [0, 0, 83, 255],\n [0, 0, 84, 255],\n [0, 0, 86, 255],\n [0, 0, 88, 255],\n [0, 0, 90, 255],\n [0, 0, 92, 255],\n [0, 0, 94, 255],\n [0, 0, 96, 255],\n [0, 0, 98, 255],\n [0, 0, 100, 255],\n [0, 0, 102, 255],\n [0, 0, 104, 255],\n [0, 0, 106, 255],\n [0, 0, 108, 255],\n [0, 0, 110, 255],\n [0, 0, 112, 255],\n [0, 0, 114, 255],\n [0, 0, 116, 255],\n [0, 0, 117, 255],\n [0, 0, 119, 255],\n [0, 0, 121, 255],\n [0, 0, 123, 255],\n [0, 0, 125, 255],\n [0, 0, 127, 255],\n [0, 0, 129, 255],\n [0, 0, 131, 255],\n [0, 0, 133, 255],\n [0, 0, 135, 255],\n [0, 0, 137, 255],\n [0, 0, 139, 255],\n [0, 0, 141, 255],\n [0, 0, 143, 255],\n [0, 0, 145, 255],\n [0, 0, 147, 255],\n [0, 0, 149, 255],\n [0, 0, 151, 255],\n [0, 0, 153, 255],\n [0, 0, 155, 255],\n [0, 0, 157, 255],\n [0, 0, 159, 255],\n [0, 0, 161, 255],\n [0, 0, 163, 255],\n [0, 0, 165, 255],\n [0, 0, 167, 255],\n [3, 0, 169, 255],\n [6, 0, 171, 255],\n [9, 0, 173, 255],\n [12, 0, 175, 255],\n [15, 0, 177, 255],\n [18, 0, 179, 255],\n [21, 0, 181, 255],\n [24, 0, 183, 255],\n [26, 0, 184, 255],\n [29, 0, 186, 255],\n [32, 0, 188, 255],\n [35, 0, 190, 255],\n [38, 0, 192, 255],\n [41, 0, 194, 255],\n [44, 0, 196, 255],\n [47, 0, 198, 255],\n [50, 0, 200, 255],\n [52, 0, 197, 255],\n [55, 0, 194, 255],\n [57, 0, 191, 255],\n [59, 0, 188, 255],\n [62, 0, 185, 255],\n [64, 0, 182, 255],\n [66, 0, 179, 255],\n [69, 0, 176, 255],\n [71, 0, 174, 255],\n [74, 0, 171, 255],\n [76, 0, 168, 255],\n [78, 0, 165, 255],\n [81, 0, 162, 255],\n [83, 0, 159, 255],\n [85, 0, 156, 255],\n [88, 0, 153, 255],\n [90, 0, 150, 255],\n [93, 2, 144, 255],\n [96, 4, 138, 255],\n [99, 6, 132, 255],\n [102, 8, 126, 255],\n [105, 9, 121, 255],\n [108, 11, 115, 255],\n [111, 13, 109, 255],\n [114, 15, 103, 255],\n [116, 17, 97, 255],\n [119, 19, 91, 255],\n [122, 21, 85, 255],\n [125, 23, 79, 255],\n [128, 24, 74, 255],\n [131, 26, 68, 255],\n [134, 28, 62, 255],\n [137, 30, 56, 255],\n [140, 32, 50, 255],\n [143, 34, 47, 255],\n [146, 36, 44, 255],\n [149, 38, 41, 255],\n [152, 40, 38, 255],\n [155, 41, 35, 255],\n [158, 43, 32, 255],\n [161, 45, 29, 255],\n [164, 47, 26, 255],\n [166, 49, 24, 255],\n [169, 51, 21, 255],\n [172, 53, 18, 255],\n [175, 55, 15, 255],\n [178, 56, 12, 255],\n [181, 58, 9, 255],\n [184, 60, 6, 255],\n [187, 62, 3, 255],\n [190, 64, 0, 255],\n [194, 66, 0, 255],\n [198, 68, 0, 255],\n [201, 70, 0, 255],\n [205, 72, 0, 255],\n [209, 73, 0, 255],\n [213, 75, 0, 255],\n [217, 77, 0, 255],\n [221, 79, 0, 255],\n [224, 81, 0, 255],\n [228, 83, 0, 255],\n [232, 85, 0, 255],\n [236, 87, 0, 255],\n [240, 88, 0, 255],\n [244, 90, 0, 255],\n [247, 92, 0, 255],\n [251, 94, 0, 255],\n [255, 96, 0, 255],\n [255, 98, 3, 255],\n [255, 100, 6, 255],\n [255, 102, 9, 255],\n [255, 104, 12, 255],\n [255, 105, 15, 255],\n [255, 107, 18, 255],\n [255, 109, 21, 255],\n [255, 111, 24, 255],\n [255, 113, 26, 255],\n [255, 115, 29, 255],\n [255, 117, 32, 255],\n [255, 119, 35, 255],\n [255, 120, 38, 255],\n [255, 122, 41, 255],\n [255, 124, 44, 255],\n [255, 126, 47, 255],\n [255, 128, 50, 255],\n [255, 130, 53, 255],\n [255, 132, 56, 255],\n [255, 134, 59, 255],\n [255, 136, 62, 255],\n [255, 137, 65, 255],\n [255, 139, 68, 255],\n [255, 141, 71, 255],\n [255, 143, 74, 255],\n [255, 145, 76, 255],\n [255, 147, 79, 255],\n [255, 149, 82, 255],\n [255, 151, 85, 255],\n [255, 152, 88, 255],\n [255, 154, 91, 255],\n [255, 156, 94, 255],\n [255, 158, 97, 255],\n [255, 160, 100, 255],\n [255, 162, 103, 255],\n [255, 164, 106, 255],\n [255, 166, 109, 255],\n [255, 168, 112, 255],\n [255, 169, 115, 255],\n [255, 171, 118, 255],\n [255, 173, 121, 255],\n [255, 175, 124, 255],\n [255, 177, 126, 255],\n [255, 179, 129, 255],\n [255, 181, 132, 255],\n [255, 183, 135, 255],\n [255, 184, 138, 255],\n [255, 186, 141, 255],\n [255, 188, 144, 255],\n [255, 190, 147, 255],\n [255, 192, 150, 255],\n [255, 194, 153, 255],\n [255, 196, 156, 255],\n [255, 198, 159, 255],\n [255, 200, 162, 255],\n [255, 201, 165, 255],\n [255, 203, 168, 255],\n [255, 205, 171, 255],\n [255, 207, 174, 255],\n [255, 209, 176, 255],\n [255, 211, 179, 255],\n [255, 213, 182, 255],\n [255, 215, 185, 255],\n [255, 216, 188, 255],\n [255, 218, 191, 255],\n [255, 220, 194, 255],\n [255, 222, 197, 255],\n [255, 224, 200, 255],\n [255, 226, 203, 255],\n [255, 228, 206, 255],\n [255, 229, 210, 255],\n [255, 231, 213, 255],\n [255, 233, 216, 255],\n [255, 235, 219, 255],\n [255, 237, 223, 255],\n [255, 239, 226, 255],\n [255, 240, 229, 255],\n [255, 242, 232, 255],\n [255, 244, 236, 255],\n [255, 246, 239, 255],\n [255, 248, 242, 255],\n [255, 250, 245, 255],\n [255, 251, 249, 255],\n [255, 253, 252, 255],\n [255, 255, 255, 255],\n ],\n },\n pet20Step: {\n name: 'PET 20 Step',\n numColors: 256,\n colors: [\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n ],\n },\n gray: {\n name: 'Gray',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0, 0],\n [1, 1, 1],\n ],\n green: [\n [0, 0, 0],\n [1, 1, 1],\n ],\n blue: [\n [0, 0, 0],\n [1, 1, 1],\n ],\n },\n },\n jet: {\n name: 'Jet',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0, 0],\n [0.35, 0, 0],\n [0.66, 1, 1],\n [0.89, 1, 1],\n [1, 0.5, 0.5],\n ],\n green: [\n [0, 0, 0],\n [0.125, 0, 0],\n [0.375, 1, 1],\n [0.64, 1, 1],\n [0.91, 0, 0],\n [1, 0, 0],\n ],\n blue: [\n [0, 0.5, 0.5],\n [0.11, 1, 1],\n [0.34, 1, 1],\n [0.65, 0, 0],\n [1, 0, 0],\n ],\n },\n },\n hsv: {\n name: 'HSV',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 1, 1],\n [0.15873, 1, 1],\n [0.174603, 0.96875, 0.96875],\n [0.333333, 0.03125, 0.03125],\n [0.349206, 0, 0],\n [0.666667, 0, 0],\n [0.68254, 0.03125, 0.03125],\n [0.84127, 0.96875, 0.96875],\n [0.857143, 1, 1],\n [1, 1, 1],\n ],\n green: [\n [0, 0, 0],\n [0.15873, 0.9375, 0.9375],\n [0.174603, 1, 1],\n [0.507937, 1, 1],\n [0.666667, 0.0625, 0.0625],\n [0.68254, 0, 0],\n [1, 0, 0],\n ],\n blue: [\n [0, 0, 0],\n [0.333333, 0, 0],\n [0.349206, 0.0625, 0.0625],\n [0.507937, 1, 1],\n [0.84127, 1, 1],\n [0.857143, 0.9375, 0.9375],\n [1, 0.09375, 0.09375],\n ],\n },\n },\n hot: {\n name: 'Hot',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0.0416, 0.0416],\n [0.365079, 1, 1],\n [1, 1, 1],\n ],\n green: [\n [0, 0, 0],\n [0.365079, 0, 0],\n [0.746032, 1, 1],\n [1, 1, 1],\n ],\n blue: [\n [0, 0, 0],\n [0.746032, 0, 0],\n [1, 1, 1],\n ],\n },\n },\n cool: {\n name: 'Cool',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0, 0],\n [1, 1, 1],\n ],\n green: [\n [0, 1, 1],\n [1, 0, 0],\n ],\n blue: [\n [0, 1, 1],\n [1, 1, 1],\n ],\n },\n },\n spring: {\n name: 'Spring',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 1, 1],\n [1, 1, 1],\n ],\n green: [\n [0, 0, 0],\n [1, 1, 1],\n ],\n blue: [\n [0, 1, 1],\n [1, 0, 0],\n ],\n },\n },\n summer: {\n name: 'Summer',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0, 0],\n [1, 1, 1],\n ],\n green: [\n [0, 0.5, 0.5],\n [1, 1, 1],\n ],\n blue: [\n [0, 0.4, 0.4],\n [1, 0.4, 0.4],\n ],\n },\n },\n autumn: {\n name: 'Autumn',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 1, 1],\n [1, 1, 1],\n ],\n green: [\n [0, 0, 0],\n [1, 1, 1],\n ],\n blue: [\n [0, 0, 0],\n [1, 0, 0],\n ],\n },\n },\n winter: {\n name: 'Winter',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0, 0],\n [1, 0, 0],\n ],\n green: [\n [0, 0, 0],\n [1, 1, 1],\n ],\n blue: [\n [0, 1, 1],\n [1, 0.5, 0.5],\n ],\n },\n },\n bone: {\n name: 'Bone',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0, 0],\n [0.746032, 0.652778, 0.652778],\n [1, 1, 1],\n ],\n green: [\n [0, 0, 0],\n [0.365079, 0.319444, 0.319444],\n [0.746032, 0.777778, 0.777778],\n [1, 1, 1],\n ],\n blue: [\n [0, 0, 0],\n [0.365079, 0.444444, 0.444444],\n [1, 1, 1],\n ],\n },\n },\n copper: {\n name: 'Copper',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0, 0],\n [0.809524, 1, 1],\n [1, 1, 1],\n ],\n green: [\n [0, 0, 0],\n [1, 0.7812, 0.7812],\n ],\n blue: [\n [0, 0, 0],\n [1, 0.4975, 0.4975],\n ],\n },\n },\n spectral: {\n name: 'Spectral',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0, 0],\n [0.05, 0.4667, 0.4667],\n [0.1, 0.5333, 0.5333],\n [0.15, 0, 0],\n [0.2, 0, 0],\n [0.25, 0, 0],\n [0.3, 0, 0],\n [0.35, 0, 0],\n [0.4, 0, 0],\n [0.45, 0, 0],\n [0.5, 0, 0],\n [0.55, 0, 0],\n [0.6, 0, 0],\n [0.65, 0.7333, 0.7333],\n [0.7, 0.9333, 0.9333],\n [0.75, 1, 1],\n [0.8, 1, 1],\n [0.85, 1, 1],\n [0.9, 0.8667, 0.8667],\n [0.95, 0.8, 0.8],\n [1, 0.8, 0.8],\n ],\n green: [\n [0, 0, 0],\n [0.05, 0, 0],\n [0.1, 0, 0],\n [0.15, 0, 0],\n [0.2, 0, 0],\n [0.25, 0.4667, 0.4667],\n [0.3, 0.6, 0.6],\n [0.35, 0.6667, 0.6667],\n [0.4, 0.6667, 0.6667],\n [0.45, 0.6, 0.6],\n [0.5, 0.7333, 0.7333],\n [0.55, 0.8667, 0.8667],\n [0.6, 1, 1],\n [0.65, 1, 1],\n [0.7, 0.9333, 0.9333],\n [0.75, 0.8, 0.8],\n [0.8, 0.6, 0.6],\n [0.85, 0, 0],\n [0.9, 0, 0],\n [0.95, 0, 0],\n [1, 0.8, 0.8],\n ],\n blue: [\n [0, 0, 0],\n [0.05, 0.5333, 0.5333],\n [0.1, 0.6, 0.6],\n [0.15, 0.6667, 0.6667],\n [0.2, 0.8667, 0.8667],\n [0.25, 0.8667, 0.8667],\n [0.3, 0.8667, 0.8667],\n [0.35, 0.6667, 0.6667],\n [0.4, 0.5333, 0.5333],\n [0.45, 0, 0],\n [0.5, 0, 0],\n [0.55, 0, 0],\n [0.6, 0, 0],\n [0.65, 0, 0],\n [0.7, 0, 0],\n [0.75, 0, 0],\n [0.8, 0, 0],\n [0.85, 0, 0],\n [0.9, 0, 0],\n [0.95, 0, 0],\n [1, 0.8, 0.8],\n ],\n },\n },\n coolwarm: {\n name: 'CoolWarm',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0.2298057, 0.2298057],\n [0.03125, 0.26623388, 0.26623388],\n [0.0625, 0.30386891, 0.30386891],\n [0.09375, 0.342804478, 0.342804478],\n [0.125, 0.38301334, 0.38301334],\n [0.15625, 0.424369608, 0.424369608],\n [0.1875, 0.46666708, 0.46666708],\n [0.21875, 0.509635204, 0.509635204],\n [0.25, 0.552953156, 0.552953156],\n [0.28125, 0.596262162, 0.596262162],\n [0.3125, 0.639176211, 0.639176211],\n [0.34375, 0.681291281, 0.681291281],\n [0.375, 0.722193294, 0.722193294],\n [0.40625, 0.761464949, 0.761464949],\n [0.4375, 0.798691636, 0.798691636],\n [0.46875, 0.833466556, 0.833466556],\n [0.5, 0.865395197, 0.865395197],\n [0.53125, 0.897787179, 0.897787179],\n [0.5625, 0.924127593, 0.924127593],\n [0.59375, 0.944468518, 0.944468518],\n [0.625, 0.958852946, 0.958852946],\n [0.65625, 0.96732803, 0.96732803],\n [0.6875, 0.969954137, 0.969954137],\n [0.71875, 0.966811177, 0.966811177],\n [0.75, 0.958003065, 0.958003065],\n [0.78125, 0.943660866, 0.943660866],\n [0.8125, 0.923944917, 0.923944917],\n [0.84375, 0.89904617, 0.89904617],\n [0.875, 0.869186849, 0.869186849],\n [0.90625, 0.834620542, 0.834620542],\n [0.9375, 0.795631745, 0.795631745],\n [0.96875, 0.752534934, 0.752534934],\n [1, 0.705673158, 0.705673158],\n ],\n green: [\n [0, 0.298717966, 0.298717966],\n [0.03125, 0.353094838, 0.353094838],\n [0.0625, 0.406535296, 0.406535296],\n [0.09375, 0.458757618, 0.458757618],\n [0.125, 0.50941904, 0.50941904],\n [0.15625, 0.558148092, 0.558148092],\n [0.1875, 0.604562568, 0.604562568],\n [0.21875, 0.648280772, 0.648280772],\n [0.25, 0.688929332, 0.688929332],\n [0.28125, 0.726149107, 0.726149107],\n [0.3125, 0.759599947, 0.759599947],\n [0.34375, 0.788964712, 0.788964712],\n [0.375, 0.813952739, 0.813952739],\n [0.40625, 0.834302879, 0.834302879],\n [0.4375, 0.849786142, 0.849786142],\n [0.46875, 0.860207984, 0.860207984],\n [0.5, 0.86541021, 0.86541021],\n [0.53125, 0.848937047, 0.848937047],\n [0.5625, 0.827384882, 0.827384882],\n [0.59375, 0.800927443, 0.800927443],\n [0.625, 0.769767752, 0.769767752],\n [0.65625, 0.734132809, 0.734132809],\n [0.6875, 0.694266682, 0.694266682],\n [0.71875, 0.650421156, 0.650421156],\n [0.75, 0.602842431, 0.602842431],\n [0.78125, 0.551750968, 0.551750968],\n [0.8125, 0.49730856, 0.49730856],\n [0.84375, 0.439559467, 0.439559467],\n [0.875, 0.378313092, 0.378313092],\n [0.90625, 0.312874446, 0.312874446],\n [0.9375, 0.24128379, 0.24128379],\n [0.96875, 0.157246067, 0.157246067],\n [1, 0.01555616, 0.01555616],\n ],\n blue: [\n [0, 0.753683153, 0.753683153],\n [0.03125, 0.801466763, 0.801466763],\n [0.0625, 0.84495867, 0.84495867],\n [0.09375, 0.883725899, 0.883725899],\n [0.125, 0.917387822, 0.917387822],\n [0.15625, 0.945619588, 0.945619588],\n [0.1875, 0.968154911, 0.968154911],\n [0.21875, 0.98478814, 0.98478814],\n [0.25, 0.995375608, 0.995375608],\n [0.28125, 0.999836203, 0.999836203],\n [0.3125, 0.998151185, 0.998151185],\n [0.34375, 0.990363227, 0.990363227],\n [0.375, 0.976574709, 0.976574709],\n [0.40625, 0.956945269, 0.956945269],\n [0.4375, 0.931688648, 0.931688648],\n [0.46875, 0.901068838, 0.901068838],\n [0.5, 0.865395561, 0.865395561],\n [0.53125, 0.820880546, 0.820880546],\n [0.5625, 0.774508472, 0.774508472],\n [0.59375, 0.726736146, 0.726736146],\n [0.625, 0.678007945, 0.678007945],\n [0.65625, 0.628751763, 0.628751763],\n [0.6875, 0.579375448, 0.579375448],\n [0.71875, 0.530263762, 0.530263762],\n [0.75, 0.481775914, 0.481775914],\n [0.78125, 0.434243684, 0.434243684],\n [0.8125, 0.387970225, 0.387970225],\n [0.84375, 0.343229596, 0.343229596],\n [0.875, 0.300267182, 0.300267182],\n [0.90625, 0.259301199, 0.259301199],\n [0.9375, 0.220525627, 0.220525627],\n [0.96875, 0.184115123, 0.184115123],\n [1, 0.150232812, 0.150232812],\n ],\n },\n },\n blues: {\n name: 'Blues',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0.9686274528503418, 0.9686274528503418],\n [0.125, 0.87058824300765991, 0.87058824300765991],\n [0.25, 0.7764706015586853, 0.7764706015586853],\n [0.375, 0.61960786581039429, 0.61960786581039429],\n [0.5, 0.41960784792900085, 0.41960784792900085],\n [0.625, 0.25882354378700256, 0.25882354378700256],\n [0.75, 0.12941177189350128, 0.12941177189350128],\n [0.875, 0.031372550874948502, 0.031372550874948502],\n [1, 0.031372550874948502, 0.031372550874948502],\n ],\n green: [\n [0, 0.9843137264251709, 0.9843137264251709],\n [0.125, 0.92156863212585449, 0.92156863212585449],\n [0.25, 0.85882353782653809, 0.85882353782653809],\n [0.375, 0.7921568751335144, 0.7921568751335144],\n [0.5, 0.68235296010971069, 0.68235296010971069],\n [0.625, 0.57254904508590698, 0.57254904508590698],\n [0.75, 0.44313725829124451, 0.44313725829124451],\n [0.875, 0.31764706969261169, 0.31764706969261169],\n [1, 0.18823529779911041, 0.18823529779911041],\n ],\n blue: [\n [0, 1, 1],\n [0.125, 0.9686274528503418, 0.9686274528503418],\n [0.25, 0.93725490570068359, 0.93725490570068359],\n [0.375, 0.88235294818878174, 0.88235294818878174],\n [0.5, 0.83921569585800171, 0.83921569585800171],\n [0.625, 0.7764706015586853, 0.7764706015586853],\n [0.75, 0.70980393886566162, 0.70980393886566162],\n [0.875, 0.61176472902297974, 0.61176472902297974],\n [1, 0.41960784792900085, 0.41960784792900085],\n ],\n },\n },\n};\n\nexport default colormapsData;\n","const RENDERING_DEFAULTS = {\n MINIMUM_SLAB_THICKNESS: 5e-2,\n MAXIMUM_RAY_DISTANCE: 1e6,\n};\n\nObject.freeze(RENDERING_DEFAULTS);\n\nexport default RENDERING_DEFAULTS;\n","const EPSILON = 1e-3;\n\nexport default EPSILON;\n","export default function _typeof(obj) {\n \"@babel/helpers - typeof\";\n\n return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (obj) {\n return typeof obj;\n } : function (obj) {\n return obj && \"function\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n }, _typeof(obj);\n}","// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#examples\nfunction deepFreeze(object) {\n // Retrieve the property names defined on object\n const propNames = Object.getOwnPropertyNames(object);\n\n // Freeze properties before freezing self\n\n for (const name of propNames) {\n const value = object[name];\n\n if (value && typeof value === 'object') {\n deepFreeze(value);\n }\n }\n\n return Object.freeze(object);\n}\n\nexport default deepFreeze;\n","import deepFreeze from '../utilities/deepFreeze';\n\nconst MPR_CAMERA_VALUES = {\n axial: {\n viewPlaneNormal: [0, 0, -1],\n viewUp: [0, -1, 0],\n },\n sagittal: {\n viewPlaneNormal: [1, 0, 0],\n viewUp: [0, 0, 1],\n },\n coronal: {\n viewPlaneNormal: [0, -1, 0],\n viewUp: [0, 0, 1],\n },\n};\n\n// Note: Object.freeze is only shallow, so we need to deepFreeze\nconst mprCameraValues = deepFreeze(MPR_CAMERA_VALUES);\nexport default mprCameraValues;\n","import { ViewportPreset } from '../types';\n\nconst presets: ViewportPreset[] = [\n {\n name: 'CT-AAA',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity:\n '12 -3024 0 143.556 0 166.222 0.686275 214.389 0.696078 419.736 0.833333 3071 0.803922',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer:\n '24 -3024 0 0 0 143.556 0.615686 0.356863 0.184314 166.222 0.882353 0.603922 0.290196 214.389 1 1 1 419.736 1 0.937033 0.954531 3071 0.827451 0.658824 1',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'CT-AAA2',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity:\n '16 -3024 0 129.542 0 145.244 0.166667 157.02 0.5 169.918 0.627451 395.575 0.8125 1578.73 0.8125 3071 0.8125',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer:\n '32 -3024 0 0 0 129.542 0.54902 0.25098 0.14902 145.244 0.6 0.627451 0.843137 157.02 0.890196 0.47451 0.6 169.918 0.992157 0.870588 0.392157 395.575 1 0.886275 0.658824 1578.73 1 0.829256 0.957922 3071 0.827451 0.658824 1',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'CT-Bone',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity: '8 -3024 0 -16.4458 0 641.385 0.715686 3071 0.705882',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer:\n '16 -3024 0 0 0 -16.4458 0.729412 0.254902 0.301961 641.385 0.905882 0.815686 0.552941 3071 1 1 1',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'CT-Bones',\n gradientOpacity: '4 0 1 985.12 1',\n specularPower: '1',\n scalarOpacity: '8 -1000 0 152.19 0 278.93 0.190476 952 0.2',\n specular: '0',\n shade: '1',\n ambient: '0.2',\n colorTransfer:\n '20 -1000 0.3 0.3 1 -488 0.3 1 0.3 463.28 1 0 0 659.15 1 0.912535 0.0374849 953 1 0.3 0.3',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'CT-Cardiac',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity:\n '12 -3024 0 -77.6875 0 94.9518 0.285714 179.052 0.553571 260.439 0.848214 3071 0.875',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer:\n '24 -3024 0 0 0 -77.6875 0.54902 0.25098 0.14902 94.9518 0.882353 0.603922 0.290196 179.052 1 0.937033 0.954531 260.439 0.615686 0 0 3071 0.827451 0.658824 1',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'CT-Cardiac2',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity:\n '12 -3024 0 42.8964 0 163.488 0.428571 277.642 0.776786 1587 0.754902 3071 0.754902',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer:\n '24 -3024 0 0 0 42.8964 0.54902 0.25098 0.14902 163.488 0.917647 0.639216 0.0588235 277.642 1 0.878431 0.623529 1587 1 1 1 3071 0.827451 0.658824 1',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'CT-Cardiac3',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity:\n '14 -3024 0 -86.9767 0 45.3791 0.169643 139.919 0.589286 347.907 0.607143 1224.16 0.607143 3071 0.616071',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer:\n '28 -3024 0 0 0 -86.9767 0 0.25098 1 45.3791 1 0 0 139.919 1 0.894893 0.894893 347.907 1 1 0.25098 1224.16 1 1 1 3071 0.827451 0.658824 1',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'CT-Chest-Contrast-Enhanced',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity:\n '10 -3024 0 67.0106 0 251.105 0.446429 439.291 0.625 3071 0.616071',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer:\n '20 -3024 0 0 0 67.0106 0.54902 0.25098 0.14902 251.105 0.882353 0.603922 0.290196 439.291 1 0.937033 0.954531 3071 0.827451 0.658824 1',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'CT-Chest-Vessels',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '1',\n scalarOpacity:\n '10 -3024 0 -1278.35 0 22.8277 0.428571 439.291 0.625 3071 0.616071',\n specular: '0',\n shade: '1',\n ambient: '0.2',\n colorTransfer:\n '20 -3024 0 0 0 -1278.35 0.54902 0.25098 0.14902 22.8277 0.882353 0.603922 0.290196 439.291 1 0.937033 0.954531 3071 0.827451 0.658824 1',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'CT-Coronary-Arteries',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '1',\n scalarOpacity:\n '12 -2048 0 136.47 0 159.215 0.258929 318.43 0.571429 478.693 0.776786 3661 1',\n specular: '0',\n shade: '0',\n ambient: '0.2',\n colorTransfer:\n '24 -2048 0 0 0 136.47 0 0 0 159.215 0.159804 0.159804 0.159804 318.43 0.764706 0.764706 0.764706 478.693 1 1 1 3661 1 1 1',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'CT-Coronary-Arteries-2',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '1',\n scalarOpacity:\n '14 -2048 0 142.677 0 145.016 0.116071 192.174 0.5625 217.24 0.776786 384.347 0.830357 3661 0.830357',\n specular: '0',\n shade: '1',\n ambient: '0.2',\n colorTransfer:\n '28 -2048 0 0 0 142.677 0 0 0 145.016 0.615686 0 0.0156863 192.174 0.909804 0.454902 0 217.24 0.972549 0.807843 0.611765 384.347 0.909804 0.909804 1 3661 1 1 1',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'CT-Coronary-Arteries-3',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity:\n '14 -2048 0 128.643 0 129.982 0.0982143 173.636 0.669643 255.884 0.857143 584.878 0.866071 3661 1',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer:\n '28 -2048 0 0 0 128.643 0 0 0 129.982 0.615686 0 0.0156863 173.636 0.909804 0.454902 0 255.884 0.886275 0.886275 0.886275 584.878 0.968627 0.968627 0.968627 3661 1 1 1',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'CT-Cropped-Volume-Bone',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '1',\n scalarOpacity: '10 -2048 0 -451 0 -450 1 1050 1 3661 1',\n specular: '0',\n shade: '0',\n ambient: '0.2',\n colorTransfer:\n '20 -2048 0 0 0 -451 0 0 0 -450 0.0556356 0.0556356 0.0556356 1050 1 1 1 3661 1 1 1',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'CT-Fat',\n gradientOpacity: '6 0 1 985.12 1 988 1',\n specularPower: '1',\n scalarOpacity: '14 -1000 0 -100 0 -99 0.15 -60 0.15 -59 0 101.2 0 952 0',\n specular: '0',\n shade: '0',\n ambient: '0.2',\n colorTransfer:\n '36 -1000 0.3 0.3 1 -497.5 0.3 1 0.3 -99 0 0 1 -76.946 0 1 0 -65.481 0.835431 0.888889 0.0165387 83.89 1 0 0 463.28 1 0 0 659.15 1 0.912535 0.0374849 2952 1 0.300267 0.299886',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'CT-Liver-Vasculature',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '1',\n scalarOpacity:\n '14 -2048 0 149.113 0 157.884 0.482143 339.96 0.660714 388.526 0.830357 1197.95 0.839286 3661 0.848214',\n specular: '0',\n shade: '0',\n ambient: '0.2',\n colorTransfer:\n '28 -2048 0 0 0 149.113 0 0 0 157.884 0.501961 0.25098 0 339.96 0.695386 0.59603 0.36886 388.526 0.854902 0.85098 0.827451 1197.95 1 1 1 3661 1 1 1',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'CT-Lung',\n gradientOpacity: '6 0 1 985.12 1 988 1',\n specularPower: '1',\n scalarOpacity: '12 -1000 0 -600 0 -599 0.15 -400 0.15 -399 0 2952 0',\n specular: '0',\n shade: '1',\n ambient: '0.2',\n colorTransfer:\n '24 -1000 0.3 0.3 1 -600 0 0 1 -530 0.134704 0.781726 0.0724558 -460 0.929244 1 0.109473 -400 0.888889 0.254949 0.0240258 2952 1 0.3 0.3',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'CT-MIP',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity: '8 -3024 0 -637.62 0 700 1 3071 1',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer: '16 -3024 0 0 0 -637.62 1 1 1 700 1 1 1 3071 1 1 1',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'CT-Muscle',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity:\n '10 -3024 0 -155.407 0 217.641 0.676471 419.736 0.833333 3071 0.803922',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer:\n '20 -3024 0 0 0 -155.407 0.54902 0.25098 0.14902 217.641 0.882353 0.603922 0.290196 419.736 1 0.937033 0.954531 3071 0.827451 0.658824 1',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'CT-Pulmonary-Arteries',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '1',\n scalarOpacity:\n '14 -2048 0 -568.625 0 -364.081 0.0714286 -244.813 0.401786 18.2775 0.607143 447.798 0.830357 3592.73 0.839286',\n specular: '0',\n shade: '1',\n ambient: '0.2',\n colorTransfer:\n '28 -2048 0 0 0 -568.625 0 0 0 -364.081 0.396078 0.301961 0.180392 -244.813 0.611765 0.352941 0.0705882 18.2775 0.843137 0.0156863 0.156863 447.798 0.752941 0.752941 0.752941 3592.73 1 1 1',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'CT-Soft-Tissue',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '1',\n scalarOpacity: '10 -2048 0 -167.01 0 -160 1 240 1 3661 1',\n specular: '0',\n shade: '0',\n ambient: '0.2',\n colorTransfer:\n '20 -2048 0 0 0 -167.01 0 0 0 -160 0.0556356 0.0556356 0.0556356 240 1 1 1 3661 1 1 1',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'CT-Air',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity: '8 -3024 0.705882 -900.0 0.715686 -500.0 0 3071 0',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer:\n '16 -3024 1 1 1 -900.0 0.2 1.0 1.0 -500.0 0.3 0.3 1.0 3071 0 0 0 ',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'MR-Angio',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '1',\n scalarOpacity:\n '12 -2048 0 151.354 0 158.279 0.4375 190.112 0.580357 200.873 0.732143 3661 0.741071',\n specular: '0',\n shade: '1',\n ambient: '0.2',\n colorTransfer:\n '24 -2048 0 0 0 151.354 0 0 0 158.279 0.74902 0.376471 0 190.112 1 0.866667 0.733333 200.873 0.937255 0.937255 0.937255 3661 1 1 1',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'MR-Default',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '1',\n scalarOpacity: '12 0 0 20 0 40 0.15 120 0.3 220 0.375 1024 0.5',\n specular: '0',\n shade: '1',\n ambient: '0.2',\n colorTransfer:\n '24 0 0 0 0 20 0.168627 0 0 40 0.403922 0.145098 0.0784314 120 0.780392 0.607843 0.380392 220 0.847059 0.835294 0.788235 1024 1 1 1',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'MR-MIP',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '1',\n scalarOpacity: '8 0 0 98.3725 0 416.637 1 2800 1',\n specular: '0',\n shade: '0',\n ambient: '0.2',\n colorTransfer: '16 0 1 1 1 98.3725 1 1 1 416.637 1 1 1 2800 1 1 1',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'MR-T2-Brain',\n gradientOpacity: '4 0 1 160.25 1',\n specularPower: '40',\n scalarOpacity: '10 0 0 36.05 0 218.302 0.171429 412.406 1 641 1',\n specular: '0.5',\n shade: '1',\n ambient: '0.3',\n colorTransfer:\n '16 0 0 0 0 98.7223 0.956863 0.839216 0.192157 412.406 0 0.592157 0.807843 641 1 1 1',\n diffuse: '0.6',\n interpolation: '1',\n },\n {\n name: 'DTI-FA-Brain',\n gradientOpacity: '4 0 1 0.9950 1',\n specularPower: '40',\n scalarOpacity:\n '16 0 0 0 0 0.3501 0.0158 0.49379 0.7619 0.6419 1 0.9920 1 0.9950 0 0.9950 0',\n specular: '0.5',\n shade: '1',\n ambient: '0.3',\n colorTransfer:\n '28 0 1 0 0 0 1 0 0 0.24974 0.4941 1 0 0.49949 0 0.9882 1 0.7492 0.51764 0 1 0.9950 1 0 0 0.9950 1 0 0',\n diffuse: '0.9',\n interpolation: '1',\n },\n];\n\nexport default presets;\n","function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {\n try {\n var info = gen[key](arg);\n var value = info.value;\n } catch (error) {\n reject(error);\n return;\n }\n\n if (info.done) {\n resolve(value);\n } else {\n Promise.resolve(value).then(_next, _throw);\n }\n}\n\nexport default function _asyncToGenerator(fn) {\n return function () {\n var self = this,\n args = arguments;\n return new Promise(function (resolve, reject) {\n var gen = fn.apply(self, args);\n\n function _next(value) {\n asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"next\", value);\n }\n\n function _throw(err) {\n asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"throw\", err);\n }\n\n _next(undefined);\n });\n };\n}","function _defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n}\n\nexport default function _createClass(Constructor, protoProps, staticProps) {\n if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n if (staticProps) _defineProperties(Constructor, staticProps);\n Object.defineProperty(Constructor, \"prototype\", {\n writable: false\n });\n return Constructor;\n}","export default function _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n}","export default function _defineProperty(obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n}","import macro from '@kitware/vtk.js/macros';\nimport vtkOpenGLTexture from '@kitware/vtk.js/Rendering/OpenGL/Texture';\n\n/**\n * vtkStreamingOpenGLTexture - A dervied class of the core vtkOpenGLTexture.\n * This class has methods to update the texture memory on the GPU slice by slice\n * in an efficient yet GPU-architecture friendly manner.\n *\n *\n * @param {*} publicAPI The public API to extend\n * @param {*} model The private model to extend.\n */\nfunction vtkStreamingOpenGLTexture(publicAPI, model) {\n model.classHierarchy.push('vtkStreamingOpenGLTexture');\n\n const superCreate3DFilterableFromRaw = publicAPI.create3DFilterableFromRaw;\n\n publicAPI.create3DFilterableFromRaw = (\n width,\n height,\n depth,\n numComps,\n dataType,\n data\n ) => {\n model.inputDataType = dataType;\n model.inputNumComps = numComps;\n\n superCreate3DFilterableFromRaw(\n width,\n height,\n depth,\n numComps,\n dataType,\n data\n );\n };\n\n /**\n * This function updates the GPU texture memory to match the current\n * representation of data held in RAM.\n *\n * @param {Float32Array|Uint8Array} data The data array which has been updated.\n */\n publicAPI.update3DFromRaw = (data) => {\n const { updatedFrames } = model;\n\n if (!updatedFrames.length) {\n return;\n }\n\n model._openGLRenderWindow.activateTexture(publicAPI);\n publicAPI.createTexture();\n publicAPI.bind();\n\n let bytesPerVoxel;\n let TypedArrayConstructor;\n\n if (data instanceof Uint8Array) {\n bytesPerVoxel = 1;\n TypedArrayConstructor = Uint8Array;\n } else if (data instanceof Int16Array) {\n bytesPerVoxel = 2;\n TypedArrayConstructor = Int16Array;\n } else if (data instanceof Float32Array) {\n bytesPerVoxel = 4;\n TypedArrayConstructor = Float32Array;\n } else {\n throw new Error(`No support for given TypedArray.`);\n }\n\n for (let i = 0; i < updatedFrames.length; i++) {\n if (updatedFrames[i]) {\n model.fillSubImage3D(data, i, bytesPerVoxel, TypedArrayConstructor);\n }\n }\n\n // Reset updatedFrames\n model.updatedFrames = [];\n\n if (model.generateMipmap) {\n model.context.generateMipmap(model.target);\n }\n\n publicAPI.deactivate();\n return true;\n };\n\n /**\n * This function updates the GPU texture memory to match the current\n * representation of data held in RAM.\n *\n * @param {Float32Array|Uint8Array} data The data array which has been updated.\n * @param {number} frameIndex The frame to load in.\n * @param {number} BytesPerVoxel The number of bytes per voxel in the data, so we don't have to constantly\n * check the array type.\n * @param {object} TypedArrayConstructor The constructor for the array type. Again so we don't have to constantly check.\n */\n model.fillSubImage3D = (\n data,\n frameIndex,\n bytesPerVoxel,\n TypedArrayConstructor\n ) => {\n const buffer = data.buffer;\n\n const frameLength = model.width * model.height;\n const frameLengthInBytes = frameLength * model.components * bytesPerVoxel;\n\n const zOffset = frameIndex * frameLengthInBytes;\n const rowLength = model.width * model.components;\n\n const gl = model.context;\n\n /**\n * It appears that the implementation of texSubImage3D uses 2D textures to do the texture copy if\n * MAX_TEXTURE_SIZE is greater than MAX_TEXTURE_SIZE_3D. As such if you make a single block too big\n * the transfer messes up cleanly and you render a black box or some data if you are lucky.\n *\n * This block-size based on 2D texture size seems like the safest approach that should work on most systems.\n *\n * There are certainly further optimizations that could be done here, we can do bigger chunks with other systems\n * But we need to find the _exact_ criteria. And then its not even guaranteed it'll be much faster.\n */\n const MAX_TEXTURE_SIZE = gl.getParameter(gl.MAX_TEXTURE_SIZE);\n let blockHeight = Math.floor(\n (bytesPerVoxel * MAX_TEXTURE_SIZE) / model.width\n );\n\n // Cap to actual frame height:\n blockHeight = Math.min(blockHeight, model.height);\n\n const multiRowBlockLength = rowLength * blockHeight;\n const multiRowBlockLengthInBytes = multiRowBlockLength * bytesPerVoxel;\n\n const normalBlocks = Math.floor(model.height / blockHeight);\n\n const lastBlockHeight = model.height % blockHeight;\n const multiRowLastBlockLength = rowLength * lastBlockHeight;\n\n // Perform most blocks.\n for (let block = 0; block < normalBlocks; block++) {\n const yOffset = block * blockHeight;\n\n // Dataview of block\n const dataView = new TypedArrayConstructor(\n buffer,\n zOffset + block * multiRowBlockLengthInBytes,\n multiRowBlockLength\n );\n\n gl.texSubImage3D(\n model.target, // target\n 0, // mipMap level (always zero)\n 0, // xOffset\n yOffset, // yOffset\n frameIndex,\n model.width,\n blockHeight, //model.height,\n 1, // numFramesInBlock,\n model.format,\n model.openGLDataType,\n dataView\n );\n }\n\n // perform last block if present\n\n if (lastBlockHeight !== 0) {\n const yOffset = normalBlocks * blockHeight;\n\n // Dataview of last block\n const dataView = new TypedArrayConstructor(\n buffer,\n zOffset + normalBlocks * multiRowBlockLengthInBytes,\n multiRowLastBlockLength\n );\n\n gl.texSubImage3D(\n model.target, // target\n 0, // mipMap level (always zero)\n 0, // xOffset\n yOffset, // yOffset\n frameIndex,\n model.width,\n lastBlockHeight, //model.height,\n 1, // numFramesInBlock,\n model.format,\n model.openGLDataType,\n dataView\n );\n }\n };\n\n publicAPI.getTextureParameters = () => {\n return {\n width: model.width,\n height: model.height,\n depth: model.depth,\n numComps: model.inputNumComps,\n dataType: model.inputDataType,\n };\n };\n\n /**\n * Called when a frame is loaded so that on next render we know which data to load in.\n * @param {number} frameIndex The frame to load in.\n */\n publicAPI.setUpdatedFrame = (frameIndex) => {\n model.updatedFrames[frameIndex] = true;\n };\n}\n\n// ----------------------------------------------------------------------------\n// Object factory\n// ----------------------------------------------------------------------------\n\n// ----------------------------------------------------------------------------\n\nconst DEFAULT_VALUES = {\n updatedFrames: [],\n};\n\nexport function extend(publicAPI, model, initialValues = {}) {\n Object.assign(model, DEFAULT_VALUES, initialValues);\n\n vtkOpenGLTexture.extend(publicAPI, model, initialValues);\n\n // Object methods\n vtkStreamingOpenGLTexture(publicAPI, model);\n}\n\n// ----------------------------------------------------------------------------\n\nexport const newInstance = macro.newInstance(\n extend,\n 'vtkStreamingOpenGLTexture'\n);\n\n// ----------------------------------------------------------------------------\n\nexport default { newInstance, extend };\n","import { vtkStreamingOpenGLTexture } from '../../RenderingEngine/vtkClasses';\nimport { IVolume, Metadata, Point3, IImageVolume, Mat3 } from '../../types';\n\n/** The base class for volume data. It includes the volume metadata\n * and the volume data along with the loading status.\n */\nexport class ImageVolume implements IImageVolume {\n /** Read-only unique identifier for the volume */\n readonly volumeId: string;\n /** Dimensions of the volume */\n dimensions: Point3;\n /** volume direction in world space */\n direction: Mat3;\n /** volume metadata */\n metadata: Metadata;\n /** volume origin, Note this is an opinionated origin for the volume */\n origin: Point3;\n /** volume scalar data */\n scalarData: Float32Array | Uint8Array;\n /** Whether preScaling has been performed on the volume */\n isPrescaled = false;\n /** volume scaling parameters if it contains scaled data */\n scaling?: {\n PET?: {\n // @TODO: Do these values exist?\n SUVlbmFactor?: number;\n SUVbsaFactor?: number;\n // accessed in ProbeTool\n suvbwToSuvlbm?: number;\n suvbwToSuvbsa?: number;\n };\n };\n /** volume size in bytes */\n sizeInBytes?: number; // Seems weird to pass this in? Why not grab it from scalarData.byteLength\n /** volume spacing in 3d world space */\n spacing: Point3;\n /** volume number of voxels */\n numVoxels: number;\n /** volume image data */\n imageData?: any;\n /** open gl texture for the volume */\n vtkOpenGLTexture: any; // No good way of referencing vtk classes as they aren't classes.\n /** load status object for the volume */\n loadStatus?: Record<string, any>;\n /** optional image ids for the volume if it is made of separated images */\n imageIds?: Array<string>;\n /** optional reference volume id if the volume is derived from another volume */\n referencedVolumeId?: string;\n /** whether the metadata for the pixel spacing is not undefined */\n hasPixelSpacing: boolean;\n\n constructor(props: IVolume) {\n this.volumeId = props.volumeId;\n this.metadata = props.metadata;\n this.dimensions = props.dimensions;\n this.spacing = props.spacing;\n this.origin = props.origin;\n this.direction = props.direction;\n this.imageData = props.imageData;\n this.scalarData = props.scalarData;\n this.sizeInBytes = props.sizeInBytes;\n this.vtkOpenGLTexture = vtkStreamingOpenGLTexture.newInstance();\n this.numVoxels =\n this.dimensions[0] * this.dimensions[1] * this.dimensions[2];\n\n if (props.scaling) {\n this.scaling = props.scaling;\n }\n\n if (props.referencedVolumeId) {\n this.referencedVolumeId = props.referencedVolumeId;\n }\n }\n\n cancelLoading: () => void;\n}\n\nexport default ImageVolume;\n","/**\n * EventTarget - Provides the [EventTarget](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget) interface\n */\nclass CornerstoneEventTarget implements EventTarget {\n private listeners;\n\n constructor() {\n this.listeners = {};\n }\n\n public reset() {\n this.listeners = {};\n }\n\n public addEventListener(type, callback) {\n if (!this.listeners[type]) {\n this.listeners[type] = [];\n }\n\n // prevent multiple callbacks from firing\n if (this.listeners[type].indexOf(callback) !== -1) {\n return;\n }\n\n this.listeners[type].push(callback);\n }\n\n public removeEventListener(type, callback) {\n if (!this.listeners[type]) {\n return;\n }\n\n const stack = this.listeners[type];\n const stackLength = stack.length;\n\n for (let i = 0; i < stackLength; i++) {\n if (stack[i] === callback) {\n stack.splice(i, 1);\n\n return;\n }\n }\n }\n\n dispatchEvent(event) {\n if (!this.listeners[event.type]) {\n //console.warn(`Skipping dispatch since there are no listeners for ${event.type}`);\n return;\n }\n\n const stack = this.listeners[event.type].slice();\n const stackLength = stack.length;\n\n for (let i = 0; i < stackLength; i++) {\n stack[i].call(this, event);\n }\n\n return !event.defaultPrevented;\n }\n}\n\n/**\n * EventTarget - Provides the [EventTarget](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget) interface\n */\nconst eventTarget = new CornerstoneEventTarget();\n\nexport default eventTarget;\n","import eventTarget from '../eventTarget';\n\n/**\n * Small utility to trigger a custom event for a given EventTarget.\n *\n * @example\n *\n * ```javascript\n * triggerEvent(element, Events.IMAGE_RENDERED, { element })\n * ```\n * or it can trigger event on the eventTarget itself\n *\n * ```javascript\n * triggerEvent(eventTarget, CSTOOLS_EVENTS.ANNOTATION_MODIFIED, { viewportId, annotationUID })\n * ```\n *\n * @param el - The element or EventTarget to trigger the event upon\n * @param type - The event type name\n * @param detail - The event detail to be sent\n * @returns false if event is cancelable and at least one of the event handlers\n * which received event called Event.preventDefault(). Otherwise it returns true.\n */\nexport default function triggerEvent(\n el: EventTarget = eventTarget,\n type: string,\n detail: unknown = null\n): boolean {\n if (!type) {\n throw new Error('Event type was not defined');\n }\n\n const event = new CustomEvent(type, {\n detail,\n cancelable: true,\n });\n\n return el.dispatchEvent(event);\n}\n","/**\n * Removes the data loader scheme from the imageId\n *\n * @param imageId - Image ID\n * @returns imageId without the data loader scheme\n */\nexport default function imageIdToURI(imageId: string): string {\n const colonIndex = imageId.indexOf(':');\n return imageId.substring(colonIndex + 1);\n}\n","import {\n ICache,\n IImage,\n IImageVolume,\n IImageLoadObject,\n IVolumeLoadObject,\n ICachedImage,\n ICachedVolume,\n EventTypes,\n} from '../types';\nimport { triggerEvent, imageIdToURI } from '../utilities';\nimport eventTarget from '../eventTarget';\nimport Events from '../enums/Events';\n\nconst MAX_CACHE_SIZE_1GB = 1073741824;\n\nclass Cache implements ICache {\n private readonly _imageCache: Map<string, ICachedImage>; // volatile space\n private readonly _volumeCache: Map<string, ICachedVolume>; // non-volatile space\n private _imageCacheSize: number;\n private _volumeCacheSize: number;\n private _maxCacheSize: number;\n\n constructor() {\n this._imageCache = new Map();\n this._volumeCache = new Map();\n this._imageCacheSize = 0;\n this._volumeCacheSize = 0;\n this._maxCacheSize = MAX_CACHE_SIZE_1GB; // Default 1GB\n }\n\n /**\n * Set the maximum cache Size\n *\n * Maximum cache size should be set before adding the data; otherwise, it\n * will throw an error.\n *\n * @param newMaxCacheSize - new maximum cache size\n *\n */\n public setMaxCacheSize = (newMaxCacheSize: number): void => {\n if (!newMaxCacheSize || typeof newMaxCacheSize !== 'number') {\n const errorMessage = `New max cacheSize ${this._maxCacheSize} should be defined and should be a number.`;\n throw new Error(errorMessage);\n }\n\n this._maxCacheSize = newMaxCacheSize;\n };\n\n /**\n * Checks if there is enough space in the cache for requested byte size\n *\n * It throws error, if the sum of volatile (image) cache and unallocated cache\n * is less than the requested byteLength\n *\n * @param byteLength - byte length of requested byte size\n *\n * @returns - boolean indicating if there is enough space in the cache\n */\n public isCacheable = (byteLength: number): boolean => {\n const unallocatedSpace = this.getBytesAvailable();\n const imageCacheSize = this._imageCacheSize;\n const availableSpace = unallocatedSpace + imageCacheSize;\n\n return availableSpace > byteLength;\n };\n\n /**\n * Returns maximum CacheSize allowed\n *\n * @returns maximum allowed cache size\n */\n public getMaxCacheSize = (): number => this._maxCacheSize;\n\n /**\n * Returns current size of the cache\n *\n * @returns current size of the cache\n */\n public getCacheSize = (): number =>\n this._imageCacheSize + this._volumeCacheSize;\n\n /**\n * Returns the unallocated size of the cache\n *\n */\n public getBytesAvailable(): number {\n return this.getMaxCacheSize() - this.getCacheSize();\n }\n\n /**\n * Deletes the imageId from the image cache\n *\n * @param imageId - imageId\n *\n */\n private _decacheImage = (imageId: string) => {\n const { imageLoadObject } = this._imageCache.get(imageId);\n\n // Cancel any in-progress loading\n if (imageLoadObject.cancelFn) {\n imageLoadObject.cancelFn();\n }\n\n if (imageLoadObject.decache) {\n imageLoadObject.decache();\n }\n\n this._imageCache.delete(imageId);\n };\n\n /**\n * Deletes the volumeId from the volume cache\n *\n * @param volumeId - volumeId\n *\n */\n private _decacheVolume = (volumeId: string) => {\n const cachedVolume = this._volumeCache.get(volumeId);\n const { volumeLoadObject, volume } = cachedVolume;\n\n if (volume.cancelLoading) {\n volume.cancelLoading();\n }\n\n if (volume.imageData) {\n volume.imageData = null;\n }\n\n if (volumeLoadObject.cancelFn) {\n // Cancel any in-progress loading\n volumeLoadObject.cancelFn();\n }\n\n if (volumeLoadObject.decache) {\n volumeLoadObject.decache();\n }\n\n this._volumeCache.delete(volumeId);\n };\n\n /**\n * Deletes all the images and volumes in the cache\n *\n * Relevant events are fired for each decached image (IMAGE_CACHE_IMAGE_REMOVED) and\n * the decached volume (VOLUME_CACHE_VOLUME_REMOVED).\n *\n * @fires Events.IMAGE_CACHE_IMAGE_REMOVED\n * @fires Events.VOLUME_CACHE_VOLUME_REMOVED\n *\n */\n public purgeCache = (): void => {\n const imageIterator = this._imageCache.keys();\n\n /* eslint-disable no-constant-condition */\n while (true) {\n const { value: imageId, done } = imageIterator.next();\n\n if (done) {\n break;\n }\n\n this.removeImageLoadObject(imageId);\n\n triggerEvent(eventTarget, Events.IMAGE_CACHE_IMAGE_REMOVED, { imageId });\n }\n\n this.purgeVolumeCache();\n };\n\n /**\n * Deletes all the volumes in the cache\n */\n public purgeVolumeCache = (): void => {\n const volumeIterator = this._volumeCache.keys();\n\n /* eslint-disable no-constant-condition */\n while (true) {\n const { value: volumeId, done } = volumeIterator.next();\n\n if (done) {\n break;\n }\n\n this.removeVolumeLoadObject(volumeId);\n\n triggerEvent(eventTarget, Events.VOLUME_CACHE_VOLUME_REMOVED, {\n volumeId,\n });\n }\n };\n\n /**\n * Purges the cache if necessary based on the requested number of bytes\n *\n * 1) it sorts the volatile (image) cache based on the most recent used images\n * and starts purging from the oldest ones.\n * Note: for a volume, if the volume-related image Ids is provided, it starts\n * by purging the none-related image Ids (those that are not related to the\n * current volume)\n * 2) For a volume, if we purge all images that won't be included in this volume and still\n * don't have enough unallocated space, purge images that will be included\n * in this volume until we have enough space. These will need to be\n * re-fetched, but we must do this not to straddle over the given memory\n * limit, even for a short time, as this may crash the application.\n *\n * @fires Events.IMAGE_CACHE_IMAGE_REMOVED\n *\n * @param numBytes - Number of bytes for the image/volume that is\n * going to be stored inside the cache\n * @param volumeImageIds - list of imageIds that correspond to the\n * volume whose numberOfBytes we want to store in the cache.\n * @returns bytesAvailable or undefined in purging cache\n * does not successfully make enough space for the requested number of bytes\n */\n public decacheIfNecessaryUntilBytesAvailable(\n numBytes: number,\n volumeImageIds?: Array<string>\n ): number | undefined {\n let bytesAvailable = this.getBytesAvailable();\n\n // If max cache size has not been exceeded, do nothing\n if (bytesAvailable >= numBytes) {\n return bytesAvailable;\n }\n\n let cachedImages = Array.from(this._imageCache.values());\n\n // Cache size has been exceeded, create list of images sorted by timeStamp\n // So we can purge the least recently used image\n function compare(a, b) {\n if (a.timeStamp > b.timeStamp) {\n return 1;\n }\n if (a.timeStamp < b.timeStamp) {\n return -1;\n }\n\n return 0;\n }\n\n cachedImages.sort(compare);\n let cachedImageIds = cachedImages.map((im) => im.imageId);\n\n let imageIdsToPurge = cachedImageIds;\n\n // if we are making space for a volume, we start by purging the imageIds\n // that are not related to the volume\n if (volumeImageIds) {\n imageIdsToPurge = cachedImageIds.filter(\n (id) => !volumeImageIds.includes(id)\n );\n }\n\n // Remove images (that are not related to the volume) from volatile cache\n // until the requested number of bytes become available\n for (const imageId of imageIdsToPurge) {\n this.removeImageLoadObject(imageId);\n\n triggerEvent(eventTarget, Events.IMAGE_CACHE_IMAGE_REMOVED, { imageId });\n\n bytesAvailable = this.getBytesAvailable();\n if (bytesAvailable >= numBytes) {\n return bytesAvailable;\n }\n }\n\n // Remove the imageIds (both volume related and not related)\n cachedImages = Array.from(this._imageCache.values());\n cachedImageIds = cachedImages.map((im) => im.imageId);\n\n // Remove volume-image Ids from volatile cache until the requested number of bytes\n // become available\n for (const imageId of cachedImageIds) {\n this.removeImageLoadObject(imageId);\n\n triggerEvent(eventTarget, Events.IMAGE_CACHE_IMAGE_REMOVED, { imageId });\n\n bytesAvailable = this.getBytesAvailable();\n if (bytesAvailable >= numBytes) {\n return bytesAvailable;\n }\n }\n\n // Technically we should not reach here, since isCacheable will throw an\n // error if unallocated + volatile (image) cache cannot fit the upcoming\n // number of bytes\n }\n\n /**\n * Puts a new image load object into the cache\n *\n * First, it creates a CachedImage object and put it inside the imageCache for\n * the imageId. After the imageLoadObject promise resolves to an image,\n * it: 1) adds the image into the correct CachedImage object 2) increments the\n * cache size, 3) triggers IMAGE_CACHE_IMAGE_ADDED 4) Purge the cache if\n * necessary -- if the cache size is greater than the maximum cache size, it\n * iterates over the imageCache and decache them one by one until the cache\n * size becomes less than the maximum allowed cache size\n *\n * @fires Events.IMAGE_CACHE_IMAGE_ADDED\n * @fires Events.CACHE_SIZE_EXCEEDED if the cache size exceeds the maximum\n *\n * @param imageId - ImageId for the image\n * @param imageLoadObject - The object that is loading or loaded the image\n */\n public putImageLoadObject(\n imageId: string,\n imageLoadObject: IImageLoadObject\n ): Promise<any> {\n if (imageId === undefined) {\n throw new Error('putImageLoadObject: imageId must not be undefined');\n }\n\n if (imageLoadObject.promise === undefined) {\n throw new Error(\n 'putImageLoadObject: imageLoadObject.promise must not be undefined'\n );\n }\n\n if (this._imageCache.has(imageId)) {\n throw new Error('putImageLoadObject: imageId already in cache');\n }\n\n if (\n imageLoadObject.cancelFn &&\n typeof imageLoadObject.cancelFn !== 'function'\n ) {\n throw new Error(\n 'putImageLoadObject: imageLoadObject.cancel must be a function'\n );\n }\n\n const cachedImage: ICachedImage = {\n loaded: false,\n imageId,\n sharedCacheKey: undefined, // The sharedCacheKey for this imageId. undefined by default\n imageLoadObject,\n timeStamp: Date.now(),\n sizeInBytes: 0,\n };\n\n this._imageCache.set(imageId, cachedImage);\n\n return imageLoadObject.promise\n .then((image: IImage) => {\n if (!this._imageCache.get(imageId)) {\n // If the image has been purged before being loaded, we stop here.\n console.warn(\n 'The image was purged from the cache before it completed loading.'\n );\n return;\n }\n\n if (image.sizeInBytes === undefined) {\n throw new Error(\n 'putImageLoadObject: image.sizeInBytes must not be undefined'\n );\n }\n if (image.sizeInBytes.toFixed === undefined) {\n throw new Error(\n 'putImageLoadObject: image.sizeInBytes is not a number'\n );\n }\n\n // check if there is enough space in unallocated + image Cache\n if (!this.isCacheable(image.sizeInBytes)) {\n throw new Error(Events.CACHE_SIZE_EXCEEDED);\n }\n\n // if there is, decache if necessary\n this.decacheIfNecessaryUntilBytesAvailable(image.sizeInBytes);\n\n cachedImage.loaded = true;\n cachedImage.image = image;\n cachedImage.sizeInBytes = image.sizeInBytes;\n this._incrementImageCacheSize(cachedImage.sizeInBytes);\n\n const eventDetails: EventTypes.ImageCacheImageAddedEventDetail = {\n image: cachedImage,\n };\n\n triggerEvent(eventTarget, Events.IMAGE_CACHE_IMAGE_ADDED, eventDetails);\n\n cachedImage.sharedCacheKey = image.sharedCacheKey;\n })\n .catch((error) => {\n // console.warn(error)\n this._imageCache.delete(imageId);\n throw error;\n });\n }\n\n /**\n * Returns the object that is loading a given imageId\n *\n * @param imageId - Image ID\n * @returns IImageLoadObject\n */\n public getImageLoadObject(imageId: string): IImageLoadObject {\n if (imageId === undefined) {\n throw new Error('getImageLoadObject: imageId must not be undefined');\n }\n const cachedImage = this._imageCache.get(imageId);\n\n if (cachedImage === undefined) {\n return;\n }\n\n // Bump time stamp for cached image\n cachedImage.timeStamp = Date.now();\n\n return cachedImage.imageLoadObject;\n }\n\n /**\n * It checks the imageCache for the provided imageId, and returns true\n * if the image is loaded, false otherwise. Note, this only checks the imageCache\n * and does not check the volume cache.\n * @param imageId - image Id to check\n * @returns boolean\n */\n public isImageIdCached(imageId: string): boolean {\n const cachedImage = this._imageCache.get(imageId);\n\n if (!cachedImage) {\n return false;\n }\n\n return cachedImage.loaded;\n }\n\n /**\n * Returns the volume that contains the requested imageId. It will check the\n * imageIds inside the volume to find a match.\n *\n * @param imageId - ImageId\n * @returns - Volume object\n */\n public getVolumeContainingImageId(imageId: string): {\n volume: IImageVolume;\n imageIdIndex: number;\n } {\n const volumeIds = Array.from(this._volumeCache.keys());\n const imageIdToUse = imageIdToURI(imageId);\n\n for (const volumeId of volumeIds) {\n const cachedVolume = this._volumeCache.get(volumeId);\n\n if (!cachedVolume.volume) {\n return;\n }\n\n let { imageIds } = cachedVolume.volume;\n\n if (!imageIds || imageIds.length === 0) {\n continue;\n }\n\n imageIds = imageIds.map((id) => imageIdToURI(id));\n\n const imageIdIndex = imageIds.indexOf(imageIdToUse);\n if (imageIdIndex > -1) {\n return { volume: cachedVolume.volume, imageIdIndex };\n }\n }\n }\n\n /**\n * Returns the cached image from the imageCache for the requested imageId.\n * It first strips the imageId to remove the data loading scheme.\n *\n * @param imageId - Image ID\n * @returns cached image\n */\n public getCachedImageBasedOnImageURI(\n imageId: string\n ): ICachedImage | undefined {\n const imageURIToUse = imageIdToURI(imageId);\n\n const cachedImageIds = Array.from(this._imageCache.keys());\n const foundImageId = cachedImageIds.find((imageId) => {\n return imageIdToURI(imageId) === imageURIToUse;\n });\n\n if (!foundImageId) {\n return;\n }\n\n return this._imageCache.get(foundImageId);\n }\n /**\n * Puts a new image load object into the cache\n *\n * First, it creates a CachedVolume object and put it inside the volumeCache for\n * the volumeId. After the volumeLoadObject promise resolves to a volume,\n * it: 1) adds the volume into the correct CachedVolume object inside volumeCache\n * 2) increments the cache size, 3) triggers VOLUME_CACHE_VOLUME_ADDED 4) Purge\n * the cache if necessary -- if the cache size is greater than the maximum cache size, it\n * iterates over the imageCache (not volumeCache) and decache them one by one\n * until the cache size becomes less than the maximum allowed cache size\n *\n * @fires Events.VOLUME_CACHE_VOLUME_ADDED\n *\n * @param volumeId - volumeId of the volume\n * @param volumeLoadObject - The object that is loading or loaded the volume\n */\n public putVolumeLoadObject(\n volumeId: string,\n volumeLoadObject: IVolumeLoadObject\n ): Promise<any> {\n if (volumeId === undefined) {\n throw new Error('putVolumeLoadObject: volumeId must not be undefined');\n }\n if (volumeLoadObject.promise === undefined) {\n throw new Error(\n 'putVolumeLoadObject: volumeLoadObject.promise must not be undefined'\n );\n }\n if (this._volumeCache.has(volumeId)) {\n throw new Error(\n `putVolumeLoadObject: volumeId:${volumeId} already in cache`\n );\n }\n if (\n volumeLoadObject.cancelFn &&\n typeof volumeLoadObject.cancelFn !== 'function'\n ) {\n throw new Error(\n 'putVolumeLoadObject: volumeLoadObject.cancel must be a function'\n );\n }\n\n // todo: @Erik there are two loaded flags, one inside cachedVolume and the other\n // inside the volume.loadStatus.loaded, the actual all pixelData loaded is the\n // loadStatus one. This causes confusion\n const cachedVolume: ICachedVolume = {\n loaded: false,\n volumeId,\n volumeLoadObject,\n timeStamp: Date.now(),\n sizeInBytes: 0,\n };\n\n this._volumeCache.set(volumeId, cachedVolume);\n\n return volumeLoadObject.promise\n .then((volume: IImageVolume) => {\n if (!this._volumeCache.get(volumeId)) {\n // If the image has been purged before being loaded, we stop here.\n console.warn(\n 'The image was purged from the cache before it completed loading.'\n );\n return;\n }\n\n if (volume.sizeInBytes === undefined) {\n throw new Error(\n 'putVolumeLoadObject: volume.sizeInBytes must not be undefined'\n );\n }\n if (volume.sizeInBytes.toFixed === undefined) {\n throw new Error(\n 'putVolumeLoadObject: volume.sizeInBytes is not a number'\n );\n }\n\n // this.isCacheable is called at the volume loader, before requesting\n // the images of the volume\n\n this.decacheIfNecessaryUntilBytesAvailable(\n volume.sizeInBytes,\n // @ts-ignore: // todo ImageVolume does not have imageIds\n volume.imageIds\n );\n\n // cachedVolume.loaded = true\n cachedVolume.volume = volume;\n cachedVolume.sizeInBytes = volume.sizeInBytes;\n this._incrementVolumeCacheSize(cachedVolume.sizeInBytes);\n\n const eventDetails: EventTypes.VolumeCacheVolumeAddedEventDetail = {\n volume: cachedVolume,\n };\n\n triggerEvent(\n eventTarget,\n Events.VOLUME_CACHE_VOLUME_ADDED,\n eventDetails\n );\n })\n .catch((error) => {\n this._volumeCache.delete(volumeId);\n throw error;\n });\n }\n\n /**\n * Returns the object that is loading a given volumeId\n *\n * @param volumeId - Volume ID\n * @returns IVolumeLoadObject\n */\n public getVolumeLoadObject = (volumeId: string): IVolumeLoadObject => {\n if (volumeId === undefined) {\n throw new Error('getVolumeLoadObject: volumeId must not be undefined');\n }\n const cachedVolume = this._volumeCache.get(volumeId);\n\n if (cachedVolume === undefined) {\n return;\n }\n\n // Bump time stamp for cached volume (not used for anything for now)\n cachedVolume.timeStamp = Date.now();\n\n return cachedVolume.volumeLoadObject;\n };\n\n /**\n * Returns the volume associated with the volumeId\n *\n * @param volumeId - Volume ID\n * @returns Volume\n */\n public getVolume = (volumeId: string): IImageVolume => {\n if (volumeId === undefined) {\n throw new Error('getVolume: volumeId must not be undefined');\n }\n const cachedVolume = this._volumeCache.get(volumeId);\n\n if (cachedVolume === undefined) {\n return;\n }\n\n // Bump time stamp for cached volume (not used for anything for now)\n cachedVolume.timeStamp = Date.now();\n\n return cachedVolume.volume;\n };\n\n /**\n * Removes the image loader associated with a given Id from the cache\n *\n * It increases the cache size after removing the image.\n *\n * @fires Events.IMAGE_CACHE_IMAGE_REMOVED\n *\n * @param imageId - Image ID\n */\n public removeImageLoadObject = (imageId: string): void => {\n if (imageId === undefined) {\n throw new Error('removeImageLoadObject: imageId must not be undefined');\n }\n const cachedImage = this._imageCache.get(imageId);\n\n if (cachedImage === undefined) {\n throw new Error(\n 'removeImageLoadObject: imageId was not present in imageCache'\n );\n }\n\n this._incrementImageCacheSize(-cachedImage.sizeInBytes);\n\n const eventDetails = {\n imageId,\n };\n\n triggerEvent(eventTarget, Events.IMAGE_CACHE_IMAGE_REMOVED, eventDetails);\n this._decacheImage(imageId);\n };\n\n /**\n * Removes the volume loader associated with a given Id from the cache\n *\n * It increases the cache size after removing the image.\n *\n * @fires Events.VOLUME_CACHE_VOLUME_REMOVED\n *\n * @param imageId - ImageId\n */\n public removeVolumeLoadObject = (volumeId: string): void => {\n if (volumeId === undefined) {\n throw new Error('removeVolumeLoadObject: volumeId must not be undefined');\n }\n const cachedVolume = this._volumeCache.get(volumeId);\n\n if (cachedVolume === undefined) {\n throw new Error(\n 'removeVolumeLoadObject: volumeId was not present in volumeCache'\n );\n }\n\n this._incrementVolumeCacheSize(-cachedVolume.sizeInBytes);\n\n const eventDetails = {\n volume: cachedVolume,\n volumeId,\n };\n\n triggerEvent(eventTarget, Events.VOLUME_CACHE_VOLUME_REMOVED, eventDetails);\n this._decacheVolume(volumeId);\n };\n\n /**\n * Increases the image cache size with the provided increment\n *\n * @param increment - bytes length\n */\n private _incrementImageCacheSize = (increment: number) => {\n this._imageCacheSize += increment;\n };\n\n /**\n * Increases the cache size with the provided increment\n *\n * @param increment - bytes length\n */\n private _incrementVolumeCacheSize = (increment: number) => {\n this._volumeCacheSize += increment;\n };\n}\n\n/**\n * This module deals with Caching of images and volumes\n * The cache has two main components: a volatile portion for images and a\n * non-volatile portion for volumes. Individual 2D images are volatile and\n * will be replaced by new images hitting the cache. When you allocate volumes,\n * these are non-volatile and reserve a block of memory from the cache.\n * Volumes must be released manually.\n * We will have a shared block of memory allocated for the entire cache, e.g. 1GB\n * which will be shared for images and volumes.\n *\n * **When a new image is added:**\n * We check if there is enough unallocated + volatile space for the single image\n *\n * if so\n * - We allocate the image in image cache, and if necessary oldest images\n * are decached to match the maximumCacheSize criteria\n * - If a volume contains that imageId, copy it over using TypedArray's set method.\n * If no volumes contain the imageId, the image is fetched by image loaders\n *\n * If not (cache is mostly/completely full with volumes)\n * - throw that the cache does not have enough working space to allocate the image\n *\n *\n * **When a new volume is added:**\n * Check if there is enough unallocated + volatile space to allocate the volume:\n *\n * If so:\n * - Decache oldest images which won't be included in this volume until\n * we have enough free space for the volume\n * - If not enough space from previous space, decache images that will be included\n * in the volume until we have enough free space (These will need to be re-fetched,\n * but we must do this not to straddle over the given memory limit, even for a\n * short time, as this may crash the app)\n * - At this point, if any of the frames (indexed by imageId) are present in the volatile\n * image cache, copy these over to the volume now\n *\n * If not (cache is mostly/completely full with volumes),\n * - throw that the cache does not have enough working space to allocate the volume.\n *\n */\nconst cache = new Cache();\nexport default cache;\nexport { Cache }; // for documentation\n","// prettier-ignore\n// @ts-nocheck\n/**\n * Generates a unique id that has limited chance of collision\n *\n * @see {@link https://stackoverflow.com/a/2117523/1867984|StackOverflow: Source}\n * @returns a v4 compliant GUID\n */\nexport default function uuidv4(): string {\n return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>\n (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)\n );\n}\n","import '@kitware/vtk.js/Rendering/Profiles/Volume';\n\nimport vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData';\nimport type { vtkImageData as vtkImageDataType } from '@kitware/vtk.js/Common/DataModel/ImageData';\nimport vtkDataArray from '@kitware/vtk.js/Common/Core/DataArray';\nimport cloneDeep from 'lodash.clonedeep';\n\nimport { ImageVolume } from './cache/classes/ImageVolume';\nimport type * as Types from './types';\nimport cache from './cache/cache';\nimport Events from './enums/Events';\nimport eventTarget from './eventTarget';\nimport triggerEvent from './utilities/triggerEvent';\nimport { uuidv4 } from './utilities';\nimport { Point3, Metadata, EventTypes, Mat3 } from './types';\n\ninterface VolumeLoaderOptions {\n imageIds: Array<string>;\n}\n\ninterface DerivedVolumeOptions {\n volumeId: string;\n targetBuffer?: {\n type: 'Float32Array' | 'Uint8Array';\n sharedArrayBuffer?: boolean;\n };\n}\ninterface LocalVolumeOptions {\n scalarData: Float32Array | Uint8Array;\n metadata: Metadata;\n dimensions: Point3;\n spacing: Point3;\n origin: Point3;\n direction: Mat3;\n}\n\nfunction createInternalVTKRepresentation({\n dimensions,\n metadata,\n spacing,\n direction,\n origin,\n scalarData,\n}): vtkImageDataType {\n const { PhotometricInterpretation } = metadata;\n\n let numComponents = 1;\n if (PhotometricInterpretation === 'RGB') {\n numComponents = 3;\n }\n\n const scalarArray = vtkDataArray.newInstance({\n name: 'Pixels',\n numberOfComponents: numComponents,\n values: scalarData,\n });\n\n const imageData = vtkImageData.newInstance();\n\n imageData.setDimensions(dimensions);\n imageData.setSpacing(spacing);\n imageData.setDirection(direction);\n imageData.setOrigin(origin);\n imageData.getPointData().setScalars(scalarArray);\n\n return imageData;\n}\n\n/**\n * This module deals with VolumeLoaders and loading volumes\n */\n\nconst volumeLoaders = {};\n\nlet unknownVolumeLoader;\n\n/**\n * Load a volume using a registered Cornerstone Volume Loader.\n *\n * The volume loader that is used will be\n * determined by the volume loader scheme matching against the volumeId.\n *\n * @param volumeId - A Cornerstone Volume Object's volumeId\n * @param options - Options to be passed to the Volume Loader. Options\n * contain the ImageIds that is passed to the loader\n *\n * @returns An Object which can be used to act after a volume is loaded or loading fails\n *\n */\nfunction loadVolumeFromVolumeLoader(\n volumeId: string,\n options: VolumeLoaderOptions\n): Types.IVolumeLoadObject {\n const colonIndex = volumeId.indexOf(':');\n const scheme = volumeId.substring(0, colonIndex);\n const loader = volumeLoaders[scheme];\n\n if (loader === undefined || loader === null) {\n if (unknownVolumeLoader !== undefined) {\n return unknownVolumeLoader(volumeId, options);\n }\n\n throw new Error(\n 'loadVolumeFromVolumeLoader: no volume loader for volumeId'\n );\n }\n\n const volumeLoadObject = loader(volumeId, options);\n\n // Broadcast a volume loaded event once the image is loaded\n volumeLoadObject.promise.then(\n function (volume) {\n triggerEvent(eventTarget, Events.VOLUME_LOADED, { volume });\n },\n function (error) {\n const errorObject: EventTypes.VolumeLoadedFailedEventDetail = {\n volumeId,\n error,\n };\n\n triggerEvent(eventTarget, Events.VOLUME_LOADED_FAILED, errorObject);\n }\n );\n\n return volumeLoadObject;\n}\n\n/**\n * Loads a volume given a volumeId and optional priority and returns a promise which will resolve to\n * the loaded image object or fail if an error occurred. The loaded image is not stored in the cache.\n *\n * @param volumeId - A Cornerstone Image Object's volumeId\n * @param options - Options to be passed to the Volume Loader\n *\n * @returns An Object which can be used to act after an image is loaded or loading fails\n */\nexport function loadVolume(\n volumeId: string,\n options: VolumeLoaderOptions = { imageIds: [] }\n): Promise<Types.IImageVolume> {\n if (volumeId === undefined) {\n throw new Error('loadVolume: parameter volumeId must not be undefined');\n }\n\n let volumeLoadObject = cache.getVolumeLoadObject(volumeId);\n\n if (volumeLoadObject !== undefined) {\n return volumeLoadObject.promise;\n }\n\n volumeLoadObject = loadVolumeFromVolumeLoader(volumeId, options);\n\n return volumeLoadObject.promise.then((volume: Types.IImageVolume) => {\n volume.imageData = createInternalVTKRepresentation(volume);\n return volume;\n });\n}\n\n/**\n * Loads an image given an volumeId and optional priority and returns a promise which will resolve to\n * the loaded image object or fail if an error occurred. The image is stored in the cache.\n *\n * @param volumeId - A Cornerstone Image Object's volumeId\n * @param options - Options to be passed to the Volume Loader\n *\n * @returns Volume Loader Object\n */\nexport async function createAndCacheVolume(\n volumeId: string,\n options: VolumeLoaderOptions\n): Promise<Record<string, any>> {\n if (volumeId === undefined) {\n throw new Error(\n 'createAndCacheVolume: parameter volumeId must not be undefined'\n );\n }\n\n let volumeLoadObject = cache.getVolumeLoadObject(volumeId);\n\n if (volumeLoadObject !== undefined) {\n return volumeLoadObject.promise;\n }\n\n volumeLoadObject = loadVolumeFromVolumeLoader(volumeId, options);\n\n volumeLoadObject.promise.then((volume: Types.IImageVolume) => {\n volume.imageData = createInternalVTKRepresentation(volume);\n });\n\n cache.putVolumeLoadObject(volumeId, volumeLoadObject).catch((err) => {\n throw err;\n });\n\n return volumeLoadObject.promise;\n}\n\n/**\n * Based on a referencedVolumeId, it will build and cache a new volume. If\n * no scalarData is specified in the options, an empty derived volume will be\n * created that matches the image metadata of the referenceVolume. If scalarData\n * is given, it will be used to generate the intensity values for the derivedVolume.\n * Finally, it will save the volume in the cache.\n * @param referencedVolumeId - the volumeId from which the new volume will get its metadata\n * @param options - DerivedVolumeOptions {uid: derivedVolumeUID, targetBuffer: { type: FLOAT32Array | Uint8Array}, scalarData: if provided}\n *\n * @returns ImageVolume\n */\nexport async function createAndCacheDerivedVolume(\n referencedVolumeId: string,\n options: DerivedVolumeOptions\n): Promise<ImageVolume> {\n const referencedVolume = cache.getVolume(referencedVolumeId);\n\n if (!referencedVolume) {\n throw new Error(\n `Cannot created derived volume: Referenced volume with id ${referencedVolumeId} does not exist.`\n );\n }\n\n let { volumeId } = options;\n const { targetBuffer } = options;\n\n if (volumeId === undefined) {\n volumeId = uuidv4();\n }\n\n const { metadata, dimensions, spacing, origin, direction, scalarData } =\n referencedVolume;\n const scalarLength = scalarData.length;\n\n let numBytes, TypedArray;\n\n // If target buffer is provided\n if (targetBuffer) {\n if (targetBuffer.type === 'Float32Array') {\n numBytes = scalarLength * 4;\n TypedArray = Float32Array;\n } else if (targetBuffer.type === 'Uint8Array') {\n numBytes = scalarLength;\n TypedArray = Uint8Array;\n } else {\n throw new Error('TargetBuffer should be Float32Array or Uint8Array');\n }\n } else {\n // Use float32 if no targetBuffer is provided\n numBytes = scalarLength * 4;\n TypedArray = Float32Array;\n }\n\n // check if there is enough space in unallocated + image Cache\n const isCacheable = cache.isCacheable(numBytes);\n if (!isCacheable) {\n throw new Error(Events.CACHE_SIZE_EXCEEDED);\n }\n\n let volumeScalarData;\n if (targetBuffer?.sharedArrayBuffer) {\n const buffer = new SharedArrayBuffer(numBytes);\n volumeScalarData = new TypedArray(buffer);\n } else {\n volumeScalarData = new TypedArray(scalarLength);\n }\n\n // Todo: handle more than one component for segmentation (RGB)\n const scalarArray = vtkDataArray.newInstance({\n name: 'Pixels',\n numberOfComponents: 1,\n values: volumeScalarData,\n });\n\n const derivedImageData = vtkImageData.newInstance();\n\n derivedImageData.setDimensions(dimensions);\n derivedImageData.setSpacing(spacing);\n derivedImageData.setDirection(direction);\n derivedImageData.setOrigin(origin);\n derivedImageData.getPointData().setScalars(scalarArray);\n\n const derivedVolume = new ImageVolume({\n volumeId,\n metadata: cloneDeep(metadata),\n dimensions: [dimensions[0], dimensions[1], dimensions[2]],\n spacing,\n origin,\n direction,\n imageData: derivedImageData,\n scalarData: volumeScalarData,\n sizeInBytes: numBytes,\n referencedVolumeId,\n });\n\n const volumeLoadObject = {\n promise: Promise.resolve(derivedVolume),\n };\n\n await cache.putVolumeLoadObject(volumeId, volumeLoadObject);\n\n return derivedVolume;\n}\n\n/**\n * Creates and cache a volume based on a set of provided properties including\n * dimensions, spacing, origin, direction, metadata, scalarData. It should be noted that\n * scalarData should be provided for this function to work. If a volume with the same\n * Id exists in the cache it returns it immediately.\n * @param options - { scalarData, metadata, dimensions, spacing, origin, direction }\n * @param volumeId - Id of the generated volume\n *\n * @returns ImageVolume\n */\nexport function createLocalVolume(\n options: LocalVolumeOptions,\n volumeId: string,\n preventCache = false\n): ImageVolume {\n const { scalarData, metadata, dimensions, spacing, origin, direction } =\n options;\n\n if (\n !scalarData ||\n !(scalarData instanceof Uint8Array || scalarData instanceof Float32Array)\n ) {\n throw new Error(\n 'To use createLocalVolume you should pass scalarData of type Uint8Array or Float32Array'\n );\n }\n\n // Todo: handle default values for spacing, origin, direction if not provided\n if (volumeId === undefined) {\n volumeId = uuidv4();\n }\n\n const cachedVolume = cache.getVolume(volumeId);\n\n if (cachedVolume) {\n return cachedVolume as ImageVolume;\n }\n\n const scalarLength = dimensions[0] * dimensions[1] * dimensions[2];\n\n const numBytes = scalarData ? scalarData.buffer.byteLength : scalarLength * 4;\n\n // check if there is enough space in unallocated + image Cache\n const isCacheable = cache.isCacheable(numBytes);\n if (!isCacheable) {\n throw new Error(Events.CACHE_SIZE_EXCEEDED);\n }\n\n const scalarArray = vtkDataArray.newInstance({\n name: 'Pixels',\n numberOfComponents: 1,\n values: scalarData,\n });\n\n const imageData = vtkImageData.newInstance();\n\n imageData.setDimensions(dimensions);\n imageData.setSpacing(spacing);\n imageData.setDirection(direction);\n imageData.setOrigin(origin);\n imageData.getPointData().setScalars(scalarArray);\n\n const derivedVolume = new ImageVolume({\n volumeId,\n metadata: cloneDeep(metadata),\n dimensions: [dimensions[0], dimensions[1], dimensions[2]],\n spacing,\n origin,\n direction,\n imageData: imageData,\n scalarData,\n sizeInBytes: numBytes,\n });\n\n if (preventCache) {\n return derivedVolume;\n }\n\n const volumeLoadObject = {\n promise: Promise.resolve(derivedVolume),\n };\n cache.putVolumeLoadObject(volumeId, volumeLoadObject);\n\n return derivedVolume;\n}\n\n/**\n * Registers an volumeLoader plugin with cornerstone for the specified scheme\n *\n * @param scheme - The scheme to use for this volume loader (e.g. 'dicomweb', 'wadouri', 'http')\n * @param volumeLoader - A Cornerstone Volume Loader function\n */\nexport function registerVolumeLoader(\n scheme: string,\n volumeLoader: Types.VolumeLoaderFn\n): void {\n volumeLoaders[scheme] = volumeLoader;\n}\n\n/**\n * Registers a new unknownVolumeLoader and returns the previous one\n *\n * @param volumeLoader - A Cornerstone Volume Loader\n *\n * @returns The previous Unknown Volume Loader\n */\nexport function registerUnknownVolumeLoader(\n volumeLoader: Types.VolumeLoaderFn\n): Types.VolumeLoaderFn | undefined {\n const oldVolumeLoader = unknownVolumeLoader;\n\n unknownVolumeLoader = volumeLoader;\n\n return oldVolumeLoader;\n}\n","import macro from '@kitware/vtk.js/macros';\nimport vtkVolumeMapper from '@kitware/vtk.js/Rendering/Core/VolumeMapper';\n\n/**\n * vtkSharedVolumeMapper - A derived class of the core vtkVolumeMapper class\n * the scalar texture in as an argument. This is so we can share the same texture\n * memory across different mappers/actors, so we don't duplicate memory usage.\n *\n *\n *\n * @param {*} publicAPI The public API to extend\n * @param {*} model The private model to extend.\n * @hidden\n */\nfunction vtkSharedVolumeMapper(publicAPI, model) {\n model.classHierarchy.push('vtkSharedVolumeMapper');\n\n const superDelete = publicAPI.delete;\n publicAPI.delete = () => {\n model.scalarTexture = null;\n superDelete();\n };\n}\n\n// ----------------------------------------------------------------------------\n// Object factory\n// ----------------------------------------------------------------------------\n\n// ----------------------------------------------------------------------------\n\nconst DEFAULT_VALUES = {\n scalarTexture: null,\n};\n\nexport function extend(publicAPI, model, initialValues = {}) {\n Object.assign(model, DEFAULT_VALUES, initialValues);\n\n vtkVolumeMapper.extend(publicAPI, model, initialValues);\n\n macro.setGet(publicAPI, model, ['scalarTexture']);\n\n // Object methods\n vtkSharedVolumeMapper(publicAPI, model);\n}\n\n// ----------------------------------------------------------------------------\n\nexport const newInstance = macro.newInstance(extend, 'vtkSharedVolumeMapper');\n\n// ----------------------------------------------------------------------------\n\nexport default { newInstance, extend };\n","import { vtkSharedVolumeMapper } from '../vtkClasses';\n\n/**\n * Given an imageData and a vtkOpenGLTexture, it creates a \"shared\" vtk volume mapper\n * from which various volume actors can be created.\n *\n * @param imageData - the vtkImageData object that contains the data to\n * render.\n * @param vtkOpenGLTexture - The vtkOpenGLTexture that will be used to render\n * the volume.\n * @returns The volume mapper.\n */\nexport default function createVolumeMapper(\n imageData: any,\n vtkOpenGLTexture: any\n): any {\n const volumeMapper = vtkSharedVolumeMapper.newInstance();\n\n volumeMapper.setInputData(imageData);\n\n const spacing = imageData.getSpacing();\n // Set the sample distance to half the mean length of one side. This is where the divide by 6 comes from.\n // https://github.com/Kitware/VTK/blob/6b559c65bb90614fb02eb6d1b9e3f0fca3fe4b0b/Rendering/VolumeOpenGL2/vtkSmartVolumeMapper.cxx#L344\n const sampleDistance = (spacing[0] + spacing[1] + spacing[2]) / 6;\n\n // This is to allow for good pixel level image quality.\n volumeMapper.setMaximumSamplesPerRay(4000);\n\n volumeMapper.setSampleDistance(sampleDistance);\n\n volumeMapper.setScalarTexture(vtkOpenGLTexture);\n\n return volumeMapper;\n}\n","import RequestType from '../enums/RequestType';\nimport { IImage } from '../types';\nimport { uuidv4 } from '../utilities';\n\ntype AdditionalDetails = {\n imageId?: string;\n volumeId?: string;\n};\n\ntype RequestDetailsInterface = {\n requestFn: () => Promise<IImage | void>;\n type: RequestType;\n additionalDetails: AdditionalDetails;\n};\n\ntype RequestPool = {\n [name in RequestType]: { [key: number]: RequestDetailsInterface[] };\n};\n\n/**\n * RequestPool manager class is a base class that manages the request pools.\n * It is used imageRetrievalPoolManager, and imageLoadPoolManager to retrieve and load images.\n * Previously requestPoolManager was used to manage the retrieval and loading and decoding\n * of the images in a way that new requests were sent after the image was both loaded and decoded\n * which was not performant since it was waiting for the image to be loaded and decoded before\n * sending the next request which is a network request and can be done in parallel.\n * Now, we use separate imageRetrievalPoolManager and imageLoadPoolManager\n * to improve performance and both are extending the RequestPoolManager class which\n * is a basic queueing pool.\n *\n * A new requestPool can be created by instantiating a new RequestPoolManager class.\n *\n * ```javascript\n * const requestPoolManager = new RequestPoolManager()\n * ```\n *\n * ## ImageLoadPoolManager\n *\n * You can use the imageLoadPoolManager to load images, by providing a `requestFn`\n * that returns a promise for the image. You can provide a `type` to specify the type of\n * request (interaction, thumbnail, prefetch), and you can provide additional details\n * that will be passed to the requestFn. Below is an example of a requestFn that loads\n * an image from an imageId:\n *\n * ```javascript\n *\n * const priority = -5\n * const requestType = RequestType.Interaction\n * const additionalDetails = { imageId }\n * const options = {\n * targetBuffer: {\n * type: 'Float32Array',\n * offset: null,\n * length: null,\n * },\n * preScale: {\n * enabled: true,\n * },\n * }\n *\n * imageLoadPoolManager.addRequest(\n * loadAndCacheImage(imageId, options).then(() => { // set on viewport}),\n * requestType,\n * additionalDetails,\n * priority\n * )\n * ```\n * ### ImageRetrievalPoolManager\n * You don't need to directly use the imageRetrievalPoolManager to load images\n * since the imageLoadPoolManager will automatically use it for retrieval. However,\n * maximum number of concurrent requests can be set by calling `setMaxConcurrentRequests`.\n */\nclass RequestPoolManager {\n private id: string;\n private awake: boolean;\n private requestPool: RequestPool;\n private numRequests = {\n interaction: 0,\n thumbnail: 0,\n prefetch: 0,\n };\n /* maximum number of requests of each type. */\n public maxNumRequests: {\n interaction: number;\n thumbnail: number;\n prefetch: number;\n };\n /* A public property that is used to set the delay between requests. */\n public grabDelay: number;\n private timeoutHandle: number;\n\n /**\n * By default a request pool containing three priority groups, one for each\n * of the request types, is created. Maximum number of requests of each type\n * is set to 6.\n */\n constructor(id?: string) {\n this.id = id ? id : uuidv4();\n\n this.requestPool = {\n interaction: { 0: [] },\n thumbnail: { 0: [] },\n prefetch: { 0: [] },\n };\n\n this.grabDelay = 5;\n this.awake = false;\n\n this.numRequests = {\n interaction: 0,\n thumbnail: 0,\n prefetch: 0,\n };\n\n this.maxNumRequests = {\n interaction: 6,\n thumbnail: 6,\n prefetch: 5,\n };\n }\n\n /**\n * This function sets the maximum number of requests for a given request type.\n * @param type - The type of request you want to set the max number\n * of requests for it can be either of interaction, prefetch, or thumbnail.\n * @param maxNumRequests - The maximum number of requests that can be\n * made at a time.\n */\n public setMaxSimultaneousRequests(\n type: RequestType,\n maxNumRequests: number\n ): void {\n this.maxNumRequests[type] = maxNumRequests;\n }\n\n /**\n * It returns the maximum number of requests of a given type that can be made\n * @param type - The type of request.\n * @returns The maximum number of requests of a given type.\n */\n public getMaxSimultaneousRequests(type: RequestType): number {\n return this.maxNumRequests[type];\n }\n\n /**\n * Stops further fetching of the requests, all the ongoing requests will still\n * be retrieved\n */\n public destroy(): void {\n if (this.timeoutHandle) {\n window.clearTimeout(this.timeoutHandle);\n }\n }\n\n /**\n * Adds the requests to the pool of requests.\n *\n * @param requestFn - A function that returns a promise which resolves in the image\n * @param type - Priority category, it can be either of interaction, prefetch,\n * or thumbnail.\n * @param additionalDetails - Additional details that requests can contain.\n * For instance the volumeId for the volume requests\n * @param priority - Priority number for each category of requests. Its default\n * value is priority 0. The lower the priority number, the higher the priority number\n *\n */\n public addRequest(\n requestFn: () => Promise<IImage | void>,\n type: RequestType,\n additionalDetails: Record<string, unknown>,\n priority = 0\n ): void {\n // Describe the request\n const requestDetails: RequestDetailsInterface = {\n requestFn,\n type,\n additionalDetails,\n };\n\n // Check if the priority group exists on the request type\n if (this.requestPool[type][priority] === undefined) {\n this.requestPool[type][priority] = [];\n }\n\n // Adding the request to the correct priority group of the request type\n this.requestPool[type][priority].push(requestDetails);\n\n // Wake up\n if (!this.awake) {\n this.awake = true;\n this.startGrabbing();\n } else if (type === RequestType.Interaction) {\n // Todo: this is a hack for interaction right now, we should separate\n // the grabbing from the adding requests\n this.startGrabbing();\n }\n }\n\n /**\n * Filter the requestPoolManager's pool of request based on the result of\n * provided filter function. The provided filter function needs to return false or true\n *\n * @param filterFunction - The filter function for filtering of the requests to keep\n */\n public filterRequests(\n filterFunction: (requestDetails: RequestDetailsInterface) => boolean\n ): void {\n Object.keys(this.requestPool).forEach((type: string) => {\n const requestType = this.requestPool[type];\n Object.keys(requestType).forEach((priority) => {\n requestType[priority] = requestType[priority].filter(\n (requestDetails: RequestDetailsInterface) => {\n return filterFunction(requestDetails);\n }\n );\n });\n });\n }\n\n /**\n * Clears the requests specific to the provided type. For instance, the\n * pool of requests of type 'interaction' can be cleared via this function.\n *\n *\n * @param type - category of the request (either interaction, prefetch or thumbnail)\n */\n public clearRequestStack(type: string): void {\n if (!this.requestPool[type]) {\n throw new Error(`No category for the type ${type} found`);\n }\n this.requestPool[type] = { 0: [] };\n }\n\n private sendRequests(type) {\n const requestsToSend = this.maxNumRequests[type] - this.numRequests[type];\n\n for (let i = 0; i < requestsToSend; i++) {\n const requestDetails = this.getNextRequest(type);\n if (requestDetails === null) {\n return false;\n } else if (requestDetails) {\n this.numRequests[type]++;\n this.awake = true;\n\n requestDetails.requestFn().finally(() => {\n this.numRequests[type]--;\n this.startAgain();\n });\n }\n }\n\n return true;\n }\n\n private getNextRequest(type): RequestDetailsInterface | null {\n const interactionPriorities = this.getSortedPriorityGroups(type);\n for (const priority of interactionPriorities) {\n if (this.requestPool[type][priority].length) {\n return this.requestPool[type][priority].shift();\n }\n }\n\n return null;\n }\n\n protected startGrabbing(): void {\n const hasRemainingInteractionRequests = this.sendRequests(\n RequestType.Interaction\n );\n const hasRemainingThumbnailRequests = this.sendRequests(\n RequestType.Thumbnail\n );\n const hasRemainingPrefetchRequests = this.sendRequests(\n RequestType.Prefetch\n );\n\n if (\n !hasRemainingInteractionRequests &&\n !hasRemainingThumbnailRequests &&\n !hasRemainingPrefetchRequests\n ) {\n this.awake = false;\n }\n }\n\n protected startAgain(): void {\n if (!this.awake) {\n return;\n }\n\n if (this.grabDelay !== undefined) {\n this.timeoutHandle = window.setTimeout(() => {\n this.startGrabbing();\n }, this.grabDelay);\n } else {\n this.startGrabbing();\n }\n }\n\n protected getSortedPriorityGroups(type: string): Array<number> {\n const priorities = Object.keys(this.requestPool[type])\n .map(Number)\n .filter((priority) => this.requestPool[type][priority].length)\n .sort();\n return priorities;\n }\n\n /**\n * Returns the request pool containing different categories, their priority and\n * the added request details.\n *\n * @returns the request pool which contains different categories, their priority and\n * the added request details\n */\n getRequestPool(): RequestPool {\n return this.requestPool;\n }\n}\n\nconst requestPoolManager = new RequestPoolManager();\n\nexport { RequestPoolManager };\nexport default requestPoolManager;\n","import { RequestPoolManager } from './requestPoolManager';\nimport RequestType from '../enums/RequestType';\n\n/**\n * You can use the imageLoadPoolManager to load images, by providing a `requestFn`\n * that returns a promise for the image. You can provide a `type` to specify the type of\n * request (interaction, thumbnail, prefetch), and you can provide additional details\n * that will be passed to the requestFn. Below is an example of a requestFn that loads\n * an image from an imageId:\n *\n * ```javascript\n *\n * const priority = -5\n * const requestType = RequestType.Interaction\n * const additionalDetails = { imageId }\n * const options = {\n * targetBuffer: {\n * type: 'Float32Array',\n * offset: null,\n * length: null,\n * },\n * preScale: {\n * enabled: true,\n * },\n * }\n *\n * imageLoadPoolManager.addRequest(\n * loadAndCacheImage(imageId, options).then(() => { // set on viewport}),\n * requestType,\n * additionalDetails,\n * priority\n * )\n * ```\n */\nconst imageLoadPoolManager = new RequestPoolManager('imageLoadPool');\n\nimageLoadPoolManager.grabDelay = 0;\n\nimageLoadPoolManager.setMaxSimultaneousRequests(RequestType.Interaction, 1000);\nimageLoadPoolManager.setMaxSimultaneousRequests(RequestType.Thumbnail, 1000);\nimageLoadPoolManager.setMaxSimultaneousRequests(RequestType.Prefetch, 1000);\n\nexport default imageLoadPoolManager;\n","import cache from './cache/cache';\nimport Events from './enums/Events';\nimport eventTarget from './eventTarget';\nimport { triggerEvent } from './utilities';\nimport { IImage, ImageLoaderFn, IImageLoadObject, EventTypes } from './types';\nimport imageLoadPoolManager from './requestPool/imageLoadPoolManager';\n\nexport interface ImageLoaderOptions {\n priority: number;\n requestType: string;\n additionalDetails?: Record<string, unknown>;\n}\n/**\n * This module deals with ImageLoaders, loading images and caching images\n */\nconst imageLoaders = {};\nlet unknownImageLoader;\n\n/**\n * Loads an image using a registered Cornerstone Image Loader.\n *\n * The image loader that is used will be\n * determined by the image loader scheme matching against the imageId.\n *\n * @param imageId - A Cornerstone Image Object's imageId\n * @param Options - to be passed to the Image Loader\n *\n * @returns - An Object which can be used to act after an image is loaded or loading fails\n */\nfunction loadImageFromImageLoader(\n imageId: string,\n options: ImageLoaderOptions\n): IImageLoadObject {\n // Extract the image loader scheme: wadors:https://image1 => wadors\n const colonIndex = imageId.indexOf(':');\n const scheme = imageId.substring(0, colonIndex);\n const loader = imageLoaders[scheme];\n if (loader === undefined || loader === null) {\n if (unknownImageLoader !== undefined) {\n return unknownImageLoader(imageId);\n }\n throw new Error('loadImageFromImageLoader: no image loader for imageId');\n }\n // Load using the registered loader\n const imageLoadObject = loader(imageId, options);\n // Broadcast an image loaded event once the image is loaded\n imageLoadObject.promise.then(\n function (image) {\n triggerEvent(eventTarget, Events.IMAGE_LOADED, { image });\n },\n function (error) {\n const errorObject: EventTypes.ImageLoadedFailedEventDetail = {\n imageId,\n error,\n };\n triggerEvent(eventTarget, Events.IMAGE_LOAD_FAILED, errorObject);\n }\n );\n return imageLoadObject;\n}\n\n/**\n * Gets the imageLoadObject by 1) Looking in to the cache to see if the\n * imageLoadObject has already been cached, 2) Checks inside the volume cache\n * to see if there is a volume that contains the same imageURI for the requested\n * imageID 3) Checks inside the imageCache for similar imageURI that might have\n * been stored as a result of decaching a volume 4) Finally if none were found\n * it request it from the registered imageLoaders.\n *\n * @param imageId - A Cornerstone Image Object's imageId\n * @param options - Options to be passed to the Image Loader\n *\n * @returns An Object which can be used to act after an image is loaded or loading fails\n */\nfunction loadImageFromCacheOrVolume(\n imageId: string,\n options: ImageLoaderOptions\n): IImageLoadObject {\n // 1. Check inside the image cache for imageId\n let imageLoadObject = cache.getImageLoadObject(imageId);\n if (imageLoadObject !== undefined) {\n return imageLoadObject;\n }\n // 2. Check if there exists a volume in the cache containing the imageId,\n // we copy the pixelData over.\n const cachedVolumeInfo = cache.getVolumeContainingImageId(imageId);\n if (cachedVolumeInfo && cachedVolumeInfo.volume.loadStatus.loaded) {\n // 2.1 Convert the volume at the specific slice to a cornerstoneImage object.\n // this will copy the pixel data over.\n const { volume, imageIdIndex } = cachedVolumeInfo;\n imageLoadObject = volume.convertToCornerstoneImage(imageId, imageIdIndex);\n return imageLoadObject;\n }\n // 3. If no volume found, we search inside the imageCache for the imageId\n // that has the same URI which had been cached if the volume was converted\n // to an image\n const cachedImage = cache.getCachedImageBasedOnImageURI(imageId);\n if (cachedImage) {\n imageLoadObject = cachedImage.imageLoadObject;\n return imageLoadObject;\n }\n // 4. if not in image cache nor inside the volume cache, we request the\n // image loaders to load it\n imageLoadObject = loadImageFromImageLoader(imageId, options);\n\n return imageLoadObject;\n}\n\n/**\n * Loads an image given an imageId and optional priority and returns a promise\n * which will resolve to the loaded image object or fail if an error occurred.\n * The loaded image is not stored in the cache.\n *\n *\n * @param imageId - A Cornerstone Image Object's imageId\n * @param options - Options to be passed to the Image Loader\n *\n * @returns An Object which can be used to act after an image is loaded or loading fails\n */\nexport function loadImage(\n imageId: string,\n options: ImageLoaderOptions = { priority: 0, requestType: 'prefetch' }\n): Promise<IImage> {\n if (imageId === undefined) {\n throw new Error('loadImage: parameter imageId must not be undefined');\n }\n\n return loadImageFromCacheOrVolume(imageId, options).promise;\n}\n\n/**\n * Loads an image given an imageId and optional priority and returns a promise\n * which will resolve to the loaded image object or fail if an error occurred.\n * The image is stored in the cache.\n *\n * @param imageId - A Cornerstone Image Object's imageId\n * @param options - Options to be passed to the Image Loader\n *\n * @returns Image Loader Object\n */\nexport function loadAndCacheImage(\n imageId: string,\n options: ImageLoaderOptions = { priority: 0, requestType: 'prefetch' }\n): Promise<IImage> {\n if (imageId === undefined) {\n throw new Error(\n 'loadAndCacheImage: parameter imageId must not be undefined'\n );\n }\n const imageLoadObject = loadImageFromCacheOrVolume(imageId, options);\n\n // if not inside cache, store it\n if (!cache.getImageLoadObject(imageId)) {\n cache.putImageLoadObject(imageId, imageLoadObject).catch((err) => {\n console.warn(err);\n });\n }\n\n return imageLoadObject.promise;\n}\n\n/**\n * Load and cache a list of imageIds\n *\n * @param imageIds - list of imageIds\n * @param options - options for loader\n *\n */\nexport function loadAndCacheImages(\n imageIds: Array<string>,\n options: ImageLoaderOptions = { priority: 0, requestType: 'prefetch' }\n): Promise<IImage>[] {\n if (!imageIds || imageIds.length === 0) {\n throw new Error(\n 'loadAndCacheImages: parameter imageIds must be list of image Ids'\n );\n }\n\n const allPromises = imageIds.map((imageId) => {\n return loadAndCacheImage(imageId, options);\n });\n\n return allPromises;\n}\n\n/**\n * Removes the imageId from the request pool manager and executes the `cancel`\n * function if it exists.\n *\n * @param imageId - A Cornerstone Image Object's imageId\n *\n */\nexport function cancelLoadImage(imageId: string): void {\n const filterFunction = ({ additionalDetails }) => {\n if (additionalDetails.imageId) {\n return additionalDetails.imageId !== imageId;\n }\n\n // for volumes\n return true;\n };\n\n // Instruct the request pool manager to filter queued\n // requests to ensure requests we no longer need are\n // no longer sent.\n imageLoadPoolManager.filterRequests(filterFunction);\n\n // TODO: Cancel decoding and retrieval as well (somehow?)\n\n // cancel image loading if in progress\n const imageLoadObject = cache.getImageLoadObject(imageId);\n\n if (imageLoadObject) {\n imageLoadObject.cancelFn();\n }\n}\n\n/**\n * Removes the imageIds from the request pool manager and calls the `cancel`\n * function if it exists.\n *\n * @param imageIds - Array of Cornerstone Image Object's imageIds\n *\n */\nexport function cancelLoadImages(imageIds: Array<string>): void {\n imageIds.forEach((imageId) => cancelLoadImage(imageId));\n}\n\n/**\n * Removes all the ongoing image loads by calling the `cancel` method on each\n * imageLoadObject. If no `cancel` method is available, it will be ignored.\n *\n */\nexport function cancelLoadAll(): void {\n const requestPool = imageLoadPoolManager.getRequestPool();\n\n Object.keys(requestPool).forEach((type: string) => {\n const requests = requestPool[type];\n\n Object.keys(requests).forEach((priority) => {\n const requestDetails = requests[priority].pop();\n const { imageId, volumeId } = requestDetails.additionalDetails;\n\n let loadObject;\n\n if (imageId) {\n loadObject = cache.getImageLoadObject(imageId);\n } else if (volumeId) {\n loadObject = cache.getVolumeLoadObject(volumeId);\n }\n if (loadObject) {\n loadObject.cancel();\n }\n });\n // resetting the pool types to be empty\n imageLoadPoolManager.clearRequestStack(type);\n\n // TODO: Clear retrieval and decoding queues as well\n });\n}\n\n/**\n * Registers an imageLoader plugin with cornerstone for the specified scheme\n *\n * @param scheme - The scheme to use for this image loader (e.g. 'dicomweb', 'wadouri', 'http')\n * @param imageLoader - A Cornerstone Image Loader function\n */\nexport function registerImageLoader(\n scheme: string,\n imageLoader: ImageLoaderFn\n): void {\n imageLoaders[scheme] = imageLoader;\n}\n/**\n * Registers a new unknownImageLoader and returns the previous one\n *\n * @param imageLoader - A Cornerstone Image Loader\n *\n * @returns The previous Unknown Image Loader\n */\nexport function registerUnknownImageLoader(\n imageLoader: ImageLoaderFn\n): ImageLoaderFn {\n const oldImageLoader = unknownImageLoader;\n unknownImageLoader = imageLoader;\n return oldImageLoader;\n}\n/**\n * Removes all registered and unknown image loaders. This should be called\n * when the application is unmounted to prevent memory leaks.\n *\n */\nexport function unregisterAllImageLoaders(): void {\n Object.keys(imageLoaders).forEach(\n (imageLoader) => delete imageLoaders[imageLoader]\n );\n unknownImageLoader = undefined;\n}\n","// This module defines a way to access various metadata about an imageId. This layer of abstraction exists\n// So metadata can be provided in different ways (e.g. by parsing DICOM P10 or by a WADO-RS document)\n\nconst providers = [];\n\n/**\n * Adds a metadata provider with the specified priority\n * @param provider - Metadata provider function\n * @param priority - 0 is default/normal, > 0 is high, < 0 is low\n *\n * @category MetaData\n */\nexport function addProvider(\n provider: (type: string, query: any) => any,\n priority = 0\n): void {\n let i;\n\n // Find the right spot to insert this provider based on priority\n for (i = 0; i < providers.length; i++) {\n if (providers[i].priority <= priority) {\n break;\n }\n }\n\n // Insert the decode task at position i\n providers.splice(i, 0, {\n priority,\n provider,\n });\n}\n\n/**\n * Removes the specified provider\n *\n * @param provider - Metadata provider function\n *\n * @category MetaData\n */\nexport function removeProvider(\n provider: (type: string, query: any) => { any }\n): void {\n for (let i = 0; i < providers.length; i++) {\n if (providers[i].provider === provider) {\n providers.splice(i, 1);\n\n break;\n }\n }\n}\n\n/**\n * Removes all providers\n *\n * @category MetaData\n */\nexport function removeAllProviders(): void {\n while (providers.length > 0) {\n providers.pop();\n }\n}\n\n/**\n * Gets metadata from the registered metadata providers. Will call each one from highest priority to lowest\n * until one responds\n *\n * @param type - The type of metadata requested from the metadata store\n * @param query - The query for the metadata store, often imageId\n *\n * @returns The metadata retrieved from the metadata store\n * @category MetaData\n */\nfunction getMetaData(type: string, query: string): any {\n // Invoke each provider in priority order until one returns something\n for (let i = 0; i < providers.length; i++) {\n const result = providers[i].provider(type, query);\n\n if (result !== undefined) {\n return result;\n }\n }\n}\n\nexport { getMetaData as get };\n","/**\n * Given a low and high window level, return the window width and window center\n * @param low - The low window level.\n * @param high - The high window level.\n * @returns a JavaScript object with two properties: windowWidth and windowCenter.\n */\nfunction toWindowLevel(\n low: number,\n high: number\n): {\n windowWidth: number;\n windowCenter: number;\n} {\n const windowWidth = Math.abs(low - high);\n const windowCenter = low + windowWidth / 2;\n\n return { windowWidth, windowCenter };\n}\n\n/**\n * Given a window width and center, return the lower and upper bounds of the window\n * @param windowWidth - the width of the window in HU\n * @param windowCenter - The center of the window.\n * @returns a JavaScript object with two properties: lower and upper.\n */\nfunction toLowHighRange(\n windowWidth: number,\n windowCenter: number\n): {\n lower: number;\n upper: number;\n} {\n const lower = windowCenter - windowWidth / 2.0;\n const upper = windowCenter + windowWidth / 2.0;\n\n return { lower, upper };\n}\n\nexport { toWindowLevel, toLowHighRange };\n","/**\n * Calculate the minimum and maximum values in an Array\n *\n * @param storedPixelData - The pixel data to calculate the min and max values for\n * @returns an object with two properties: min and max\n */\nexport default function getMinMax(storedPixelData: number[]): {\n min: number;\n max: number;\n} {\n // we always calculate the min max values since they are not always\n // present in DICOM and we don't want to trust them anyway as cornerstone\n // depends on us providing reliable values for these\n let min = storedPixelData[0];\n\n let max = storedPixelData[0];\n\n let storedPixel;\n const numPixels = storedPixelData.length;\n\n for (let index = 1; index < numPixels; index++) {\n storedPixel = storedPixelData[index];\n min = Math.min(min, storedPixel);\n max = Math.max(max, storedPixel);\n }\n\n return {\n min,\n max,\n };\n}\n","import {\n VolumeActor,\n IImageVolume,\n VOIRange,\n ScalingParameters,\n} from '../../types';\nimport { loadAndCacheImage } from '../../imageLoader';\nimport * as metaData from '../../metaData';\nimport { getMinMax, windowLevel } from '../../utilities';\nimport { RequestType } from '../../enums';\n\nconst PRIORITY = 0;\nconst REQUEST_TYPE = RequestType.Prefetch;\n\n/**\n * It sets the default window level of an image volume based on the VOI.\n * It first look for the VOI in the metadata and if it is not found, it\n * loads the middle slice image (middle imageId) and based on its min\n * and max pixel values, it calculates the VOI.\n * Finally it sets the VOI on the volumeActor transferFunction\n * @param volumeActor - The volume actor\n * @param imageVolume - The image volume that we want to set the VOI for.\n */\nasync function setDefaultVolumeVOI(\n volumeActor: VolumeActor,\n imageVolume: IImageVolume\n): Promise<void> {\n let voi = getVOIFromMetadata(imageVolume);\n\n if (!voi) {\n voi = await getVOIFromMinMax(imageVolume);\n }\n\n if (!voi || voi.lower === undefined || voi.upper === undefined) {\n throw new Error(\n 'Could not get VOI from metadata, nor from the min max of the image middle slice'\n );\n }\n\n voi = handlePreScaledVolume(imageVolume, voi);\n const { lower, upper } = voi;\n\n volumeActor\n .getProperty()\n .getRGBTransferFunction(0)\n .setMappingRange(lower, upper);\n}\n\nfunction handlePreScaledVolume(imageVolume: IImageVolume, voi: VOIRange) {\n const imageIds = imageVolume.imageIds;\n const imageIdIndex = Math.floor(imageIds.length / 2);\n const imageId = imageIds[imageIdIndex];\n\n const generalSeriesModule =\n metaData.get('generalSeriesModule', imageId) || {};\n\n /**\n * If the volume is prescaled and the modality is PT Sometimes you get super high\n * values at the peak and it skews the min/max so nothing useful is displayed\n * Therefore, we follow the majority of other viewers and we set the min/max\n * for the scaled PT to be 0, 5\n */\n if (generalSeriesModule.modality === 'PT' && imageVolume.isPrescaled) {\n return {\n lower: 0,\n upper: 5,\n };\n }\n\n return voi;\n}\n\n/**\n * Get the VOI from the metadata of the middle slice of the image volume. It checks\n * the metadata for the VOI and if it is not found, it returns null\n *\n * @param imageVolume - The image volume that we want to get the VOI from.\n * @returns VOIRange with lower and upper values\n */\nfunction getVOIFromMetadata(imageVolume: IImageVolume): VOIRange {\n const { imageIds } = imageVolume;\n\n const imageIdIndex = Math.floor(imageIds.length / 2);\n const imageId = imageIds[imageIdIndex];\n\n const voiLutModule = metaData.get('voiLutModule', imageId);\n\n if (voiLutModule && voiLutModule.windowWidth && voiLutModule.windowCenter) {\n const { windowWidth, windowCenter } = voiLutModule;\n\n const voi = {\n windowWidth: Array.isArray(windowWidth) ? windowWidth[0] : windowWidth,\n windowCenter: Array.isArray(windowCenter)\n ? windowCenter[0]\n : windowCenter,\n };\n\n const { lower, upper } = windowLevel.toLowHighRange(\n Number(voi.windowWidth),\n Number(voi.windowCenter)\n );\n\n return {\n lower,\n upper,\n };\n }\n}\n\n/**\n * It loads the middle slice image (middle imageId) and based on its min\n * and max pixel values, it calculates the VOI.\n *\n * @param imageVolume - The image volume that we want to get the VOI from.\n * @returns The VOIRange with lower and upper values\n */\nasync function getVOIFromMinMax(imageVolume: IImageVolume): Promise<VOIRange> {\n const { scalarData, imageIds } = imageVolume;\n\n // Get the middle image from the list of imageIds\n const imageIdIndex = Math.floor(imageIds.length / 2);\n const imageId = imageVolume.imageIds[imageIdIndex];\n const generalSeriesModule =\n metaData.get('generalSeriesModule', imageId) || {};\n const { modality } = generalSeriesModule;\n const modalityLutModule = metaData.get('modalityLutModule', imageId) || {};\n\n const numImages = imageIds.length;\n const bytesPerImage = scalarData.byteLength / numImages;\n const voxelsPerImage = scalarData.length / numImages;\n const bytePerPixel = scalarData.BYTES_PER_ELEMENT;\n\n let type;\n\n if (scalarData instanceof Uint8Array) {\n type = 'Uint8Array';\n } else if (scalarData instanceof Float32Array) {\n type = 'Float32Array';\n } else {\n throw new Error('Unsupported array type');\n }\n\n const scalingParameters: ScalingParameters = {\n rescaleSlope: modalityLutModule.rescaleSlope,\n rescaleIntercept: modalityLutModule.rescaleIntercept,\n modality,\n };\n\n let scalingParametersToUse;\n if (modality === 'PT') {\n const suvFactor = metaData.get('scalingModule', imageId);\n\n if (suvFactor) {\n scalingParametersToUse = {\n ...scalingParameters,\n suvbw: suvFactor.suvbw,\n };\n }\n }\n\n const byteOffset = imageIdIndex * bytesPerImage;\n\n const options = {\n targetBuffer: {\n arrayBuffer: scalarData.buffer,\n offset: byteOffset,\n length: voxelsPerImage,\n type,\n },\n priority: PRIORITY,\n requestType: REQUEST_TYPE,\n preScale: {\n enabled: true,\n scalingParameters: scalingParametersToUse,\n },\n };\n\n // Loading the middle slice image for a volume has two scenarios, the first one is that\n // uses the same volumeLoader which might not resolve to an image (since for performance\n // reasons volumes' pixelData is set via offset and length on the volume arrayBuffer\n // when each slice is loaded). The second scenario is that the image might not reach\n // to the volumeLoader, and an already cached image (with Image object) is used\n // instead. For the first scenario, we use the arrayBuffer of the volume to get the correct\n // slice for the imageScalarData, and for the second scenario we use the getPixelData\n // on the Cornerstone IImage object to get the pixel data.\n const image = await loadAndCacheImage(imageId, options);\n\n let imageScalarData;\n if (!image) {\n imageScalarData = _getImageScalarDataFromImageVolume(\n imageVolume,\n byteOffset,\n bytePerPixel,\n voxelsPerImage\n );\n } else {\n imageScalarData = image.getPixelData();\n }\n\n // Get the min and max pixel values of the middle slice\n const { min, max } = getMinMax(imageScalarData);\n\n return {\n lower: min,\n upper: max,\n };\n}\n\nfunction _getImageScalarDataFromImageVolume(\n imageVolume,\n byteOffset,\n bytePerPixel,\n voxelsPerImage\n) {\n const { scalarData } = imageVolume;\n const { volumeBuffer } = scalarData;\n if (scalarData.BYTES_PER_ELEMENT !== bytePerPixel) {\n byteOffset *= scalarData.BYTES_PER_ELEMENT / bytePerPixel;\n }\n\n const TypedArray = scalarData.constructor;\n const imageScalarData = new TypedArray(voxelsPerImage);\n\n const volumeBufferView = new TypedArray(\n volumeBuffer,\n byteOffset,\n voxelsPerImage\n );\n\n imageScalarData.set(volumeBufferView);\n\n return imageScalarData;\n}\n\nexport default setDefaultVolumeVOI;\n","import vtkVolume from '@kitware/vtk.js/Rendering/Core/Volume';\n\nimport { VolumeActor } from './../../types/IActor';\nimport { VoiModifiedEventDetail } from './../../types/EventTypes';\nimport { loadVolume } from '../../volumeLoader';\nimport createVolumeMapper from './createVolumeMapper';\nimport BlendModes from '../../enums/BlendModes';\nimport { triggerEvent } from '../../utilities';\nimport { Events } from '../../enums';\nimport setDefaultVolumeVOI from './setDefaultVolumeVOI';\n\ninterface createVolumeActorInterface {\n volumeId: string;\n callback?: ({\n volumeActor,\n volumeId,\n }: {\n volumeActor: VolumeActor;\n volumeId: string;\n }) => void;\n blendMode?: BlendModes;\n}\n\n/**\n * Given a volumeId, it creates a vtk volume actor and returns it. If\n * callback is provided, it will be called with the volume actor and the\n * volumeId. If blendMode is provided, it will be set on the volume actor.\n *\n * @param props - createVolumeActorInterface\n * @returns A promise that resolves to a VolumeActor.\n */\nasync function createVolumeActor(\n props: createVolumeActorInterface,\n element: HTMLDivElement,\n viewportId: string,\n suppressEvents = false\n): Promise<VolumeActor> {\n const { volumeId, callback, blendMode } = props;\n\n const imageVolume = await loadVolume(volumeId);\n\n if (!imageVolume) {\n throw new Error(\n `imageVolume with id: ${imageVolume.volumeId} does not exist`\n );\n }\n\n const { imageData, vtkOpenGLTexture } = imageVolume;\n\n const volumeMapper = createVolumeMapper(imageData, vtkOpenGLTexture);\n\n if (blendMode) {\n volumeMapper.setBlendMode(blendMode);\n }\n\n const volumeActor = vtkVolume.newInstance();\n volumeActor.setMapper(volumeMapper);\n\n // If the volume is composed of imageIds, we can apply a default VOI based\n // on either the metadata or the min/max of the middle slice. Example of other\n // types of volumes which might not be composed of imageIds would be e.g., nrrd, nifti\n // format volumes\n if (imageVolume.imageIds) {\n await setDefaultVolumeVOI(volumeActor, imageVolume);\n }\n\n if (callback) {\n callback({ volumeActor, volumeId });\n }\n\n if (!suppressEvents) {\n triggerVOIModified(element, viewportId, volumeActor, volumeId);\n }\n\n return volumeActor;\n}\n\nfunction triggerVOIModified(\n element: HTMLDivElement,\n viewportId: string,\n volumeActor: VolumeActor,\n volumeId: string\n) {\n const voiRange = volumeActor\n .getProperty()\n .getRGBTransferFunction(0)\n // @ts-ignore: vtk d ts problem\n .getRange();\n\n const voiModifiedEventDetail: VoiModifiedEventDetail = {\n viewportId,\n range: {\n lower: voiRange[0],\n upper: voiRange[1],\n },\n volumeId,\n };\n\n triggerEvent(element, Events.VOI_MODIFIED, voiModifiedEventDetail);\n}\n\nexport default createVolumeActor;\n","const VIEWPORT_ELEMENT = 'viewport-element';\nconst CANVAS_CSS_CLASS = 'cornerstone-canvas';\n\n/**\n * Create a canvas and append it to the element\n *\n * @param element - An HTML Element\n * @returns canvas - A Canvas DOM element\n */\nfunction createCanvas(element: Element | HTMLDivElement): HTMLCanvasElement {\n const canvas = document.createElement('canvas');\n\n canvas.style.position = 'absolute';\n canvas.style.width = '100%';\n canvas.style.height = '100%';\n canvas.classList.add(CANVAS_CSS_CLASS);\n element.appendChild(canvas);\n\n return canvas;\n}\n\n/**\n * Creates an internal div that will contain canvas and SVG layer as children\n * @param element - An HTML Element\n * @returns div Cornerstone internal div that will include the canvas and SVG\n * as its children\n */\nexport function createViewportElement(element: HTMLDivElement): HTMLDivElement {\n const div = document.createElement('div');\n div.style.position = 'relative';\n div.style.width = '100%';\n div.style.height = '100%';\n div.classList.add(VIEWPORT_ELEMENT);\n element.appendChild(div);\n\n return div;\n}\n\n/**\n * Create a canvas or returns the one that already exists for a given element.\n * It first checks if the element has a canvas, if not it creates one and returns it.\n *\n * @param element - An HTML Element\n * @returns canvas a Canvas DOM element\n */\nexport default function getOrCreateCanvas(\n element: HTMLDivElement\n): HTMLCanvasElement {\n const canvasSelector = `canvas.${CANVAS_CSS_CLASS}`;\n const viewportElement = `div.${VIEWPORT_ELEMENT}`;\n\n // Internal div with `relative` positioning to enable absolute positioning\n // of the canvas and svg layer.\n const internalDiv =\n element.querySelector(viewportElement) || createViewportElement(element);\n\n return internalDiv.querySelector(canvasSelector) || createCanvas(internalDiv);\n}\n","export default function _arrayLikeToArray(arr, len) {\n if (len == null || len > arr.length) len = arr.length;\n\n for (var i = 0, arr2 = new Array(len); i < len; i++) {\n arr2[i] = arr[i];\n }\n\n return arr2;\n}","import arrayLikeToArray from \"./arrayLikeToArray.js\";\nexport default function _unsupportedIterableToArray(o, minLen) {\n if (!o) return;\n if (typeof o === \"string\") return arrayLikeToArray(o, minLen);\n var n = Object.prototype.toString.call(o).slice(8, -1);\n if (n === \"Object\" && o.constructor) n = o.constructor.name;\n if (n === \"Map\" || n === \"Set\") return Array.from(o);\n if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return arrayLikeToArray(o, minLen);\n}","import arrayWithoutHoles from \"./arrayWithoutHoles.js\";\nimport iterableToArray from \"./iterableToArray.js\";\nimport unsupportedIterableToArray from \"./unsupportedIterableToArray.js\";\nimport nonIterableSpread from \"./nonIterableSpread.js\";\nexport default function _toConsumableArray(arr) {\n return arrayWithoutHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableSpread();\n}","import arrayLikeToArray from \"./arrayLikeToArray.js\";\nexport default function _arrayWithoutHoles(arr) {\n if (Array.isArray(arr)) return arrayLikeToArray(arr);\n}","export default function _iterableToArray(iter) {\n if (typeof Symbol !== \"undefined\" && iter[Symbol.iterator] != null || iter[\"@@iterator\"] != null) return Array.from(iter);\n}","export default function _nonIterableSpread() {\n throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}","import type { IRenderingEngine } from '../types';\n\nconst cache = {};\n\nconst renderingEngineCache = {\n /**\n * Returns the `RenderingEngine` instance with the given `id`.\n *\n * @param id - The `id` of the `RenderingEngine` instance to fetch.\n * @returns The `RenderingEngine` instance.\n */\n get: (id: string): IRenderingEngine => {\n return cache[id];\n },\n /**\n * Adds the `RenderingEngine` instance to the cache.\n *\n * @param re - The `RenderingEngine` to add.\n */\n set: (re: IRenderingEngine): void => {\n const renderingEngineId = re.id;\n\n cache[renderingEngineId] = re;\n },\n /**\n * Deletes the `RenderingEngine` instance from the cache.\n *\n * @param id - The `id` of the `RenderingEngine` instance to delete.\n * @returns True if the delete was successful.\n */\n delete: (id: string) => {\n return delete cache[id];\n },\n\n getAll: (): Array<IRenderingEngine> => {\n const renderingEngineIds = Object.keys(cache);\n const renderingEngines = renderingEngineIds.map((id) => cache[id]);\n\n return renderingEngines;\n },\n};\n\nexport default renderingEngineCache;\n","import { mat3, mat4, vec3 } from 'gl-matrix';\nimport macro from '@kitware/vtk.js/macros';\nimport vtkOpenGLVolumeMapper from '@kitware/vtk.js/Rendering/OpenGL/VolumeMapper';\nimport { Filter } from '@kitware/vtk.js/Rendering/OpenGL/Texture/Constants';\nimport { VtkDataTypes } from '@kitware/vtk.js/Common/Core/DataArray/Constants';\nimport vtkDataArray from '@kitware/vtk.js/Common/Core/DataArray';\nimport { Representation } from '@kitware/vtk.js/Rendering/Core/Property/Constants';\n\nconst { vtkWarningMacro } = macro;\n/**\n * vtkStreamingOpenGLVolumeMapper - A dervied class of the core vtkOpenGLVolumeMapper class.\n * This class replaces the buildBufferObjects function so that we progressively upload our textures\n * into GPU memory using the new methods on vtkStreamingOpenGLTexture.\n *\n *\n * @param {*} publicAPI The public API to extend\n * @param {*} model The private model to extend.\n */\nfunction vtkStreamingOpenGLVolumeMapper(publicAPI, model) {\n model.classHierarchy.push('vtkStreamingOpenGLVolumeMapper');\n\n /**\n * buildBufferObjects - A fork of vtkOpenGLVolumeMapper's buildBufferObjects method.\n * This fork performs most of the same actions, but builds the textures progressively using\n * vtkStreamingOpenGLTexture's methods, and also prevents recomputation of the texture for each\n * vtkStreamingOpenGLVolumeMapper using the texture.\n *\n *\n * @param {*} ren The renderer.\n * @param {*} actor The actor to build the buffer objects for.\n */\n publicAPI.buildBufferObjects = (ren, actor) => {\n const image = model.currentInput;\n if (!image) {\n return;\n }\n\n const scalars = image.getPointData() && image.getPointData().getScalars();\n if (!scalars) {\n return;\n }\n\n const vprop = actor.getProperty();\n\n if (!model.jitterTexture.getHandle()) {\n const oTable = new Uint8Array(32 * 32);\n for (let i = 0; i < 32 * 32; ++i) {\n oTable[i] = 255.0 * Math.random();\n }\n model.jitterTexture.setMinificationFilter(Filter.LINEAR);\n model.jitterTexture.setMagnificationFilter(Filter.LINEAR);\n model.jitterTexture.create2DFromRaw(\n 32,\n 32,\n 1,\n VtkDataTypes.UNSIGNED_CHAR,\n oTable\n );\n }\n\n const numComp = scalars.getNumberOfComponents();\n const iComps = vprop.getIndependentComponents();\n const numIComps = iComps ? numComp : 1;\n\n // rebuild opacity tfun?\n let toString = `${vprop.getMTime()}`;\n if (model.opacityTextureString !== toString) {\n const oWidth = 1024;\n const oSize = oWidth * 2 * numIComps;\n const ofTable = new Float32Array(oSize);\n const tmpTable = new Float32Array(oWidth);\n\n for (let c = 0; c < numIComps; ++c) {\n const ofun = vprop.getScalarOpacity(c);\n const opacityFactor =\n model.renderable.getSampleDistance() /\n vprop.getScalarOpacityUnitDistance(c);\n\n const oRange = ofun.getRange();\n ofun.getTable(oRange[0], oRange[1], oWidth, tmpTable, 1);\n // adjust for sample distance etc\n for (let i = 0; i < oWidth; ++i) {\n ofTable[c * oWidth * 2 + i] =\n 1.0 - (1.0 - tmpTable[i]) ** opacityFactor;\n ofTable[c * oWidth * 2 + i + oWidth] = ofTable[c * oWidth * 2 + i];\n }\n }\n\n model.opacityTexture.releaseGraphicsResources(model._openGLRenderWindow);\n model.opacityTexture.setMinificationFilter(Filter.LINEAR);\n model.opacityTexture.setMagnificationFilter(Filter.LINEAR);\n\n // use float texture where possible because we really need the resolution\n // for this table. Errors in low values of opacity accumulate to\n // visible artifacts. High values of opacity quickly terminate without\n // artifacts.\n if (\n model._openGLRenderWindow.getWebgl2() ||\n (model.context.getExtension('OES_texture_float') &&\n model.context.getExtension('OES_texture_float_linear'))\n ) {\n model.opacityTexture.create2DFromRaw(\n oWidth,\n 2 * numIComps,\n 1,\n VtkDataTypes.FLOAT,\n ofTable\n );\n } else {\n const oTable = new Uint8Array(oSize);\n for (let i = 0; i < oSize; ++i) {\n oTable[i] = 255.0 * ofTable[i];\n }\n model.opacityTexture.create2DFromRaw(\n oWidth,\n 2 * numIComps,\n 1,\n VtkDataTypes.UNSIGNED_CHAR,\n oTable\n );\n }\n model.opacityTextureString = toString;\n }\n\n // rebuild color tfun?\n toString = `${vprop.getMTime()}`;\n\n if (model.colorTextureString !== toString) {\n const cWidth = 1024;\n const cSize = cWidth * 2 * numIComps * 3;\n const cTable = new Uint8Array(cSize);\n const tmpTable = new Float32Array(cWidth * 3);\n\n for (let c = 0; c < numIComps; ++c) {\n const cfun = vprop.getRGBTransferFunction(c);\n const cRange = cfun.getRange();\n cfun.getTable(cRange[0], cRange[1], cWidth, tmpTable, 1);\n for (let i = 0; i < cWidth * 3; ++i) {\n cTable[c * cWidth * 6 + i] = 255.0 * tmpTable[i];\n cTable[c * cWidth * 6 + i + cWidth * 3] = 255.0 * tmpTable[i];\n }\n }\n\n model.colorTexture.releaseGraphicsResources(model._openGLRenderWindow);\n model.colorTexture.setMinificationFilter(Filter.LINEAR);\n model.colorTexture.setMagnificationFilter(Filter.LINEAR);\n\n model.colorTexture.create2DFromRaw(\n cWidth,\n 2 * numIComps,\n 3,\n VtkDataTypes.UNSIGNED_CHAR,\n cTable\n );\n model.colorTextureString = toString;\n }\n\n // rebuild the scalarTexture if the data has changed\n toString = `${image.getMTime()}`;\n\n if (model.scalarTextureString !== toString) {\n // Build the textures\n const dims = image.getDimensions();\n\n const previousTextureParameters =\n model.scalarTexture.getTextureParameters();\n\n const dataType = image.getPointData().getScalars().getDataType();\n const data = image.getPointData().getScalars().getData();\n\n let shouldReset = true;\n\n if (\n previousTextureParameters.dataType &&\n previousTextureParameters.dataType === dataType\n ) {\n const previousTextureSize =\n previousTextureParameters.width *\n previousTextureParameters.height *\n previousTextureParameters.depth *\n previousTextureParameters.numComps;\n if (data.length === previousTextureSize) {\n shouldReset = false;\n }\n }\n\n if (shouldReset) {\n model.scalarTexture.releaseGraphicsResources(model._openGLRenderWindow);\n model.scalarTexture.resetFormatAndType();\n\n model.scalarTexture.create3DFilterableFromRaw(\n dims[0],\n dims[1],\n dims[2],\n numComp,\n scalars.getDataType(),\n scalars.getData(),\n model.renderable.getPreferSizeOverAccuracy()\n );\n } else {\n model.scalarTexture.deactivate();\n model.scalarTexture.update3DFromRaw(data);\n }\n\n model.scalarTextureString = toString;\n }\n\n if (!model.tris.getCABO().getElementCount()) {\n // build the CABO\n const ptsArray = new Float32Array(12);\n for (let i = 0; i < 4; i++) {\n ptsArray[i * 3] = (i % 2) * 2 - 1.0;\n ptsArray[i * 3 + 1] = i > 1 ? 1.0 : -1.0;\n ptsArray[i * 3 + 2] = -1.0;\n }\n\n const cellArray = new Uint16Array(8);\n cellArray[0] = 3;\n cellArray[1] = 0;\n cellArray[2] = 1;\n cellArray[3] = 3;\n cellArray[4] = 3;\n cellArray[5] = 0;\n cellArray[6] = 3;\n cellArray[7] = 2;\n\n const points = vtkDataArray.newInstance({\n numberOfComponents: 3,\n values: ptsArray,\n });\n points.setName('points');\n const cells = vtkDataArray.newInstance({\n numberOfComponents: 1,\n values: cellArray,\n });\n model.tris.getCABO().createVBO(cells, 'polys', Representation.SURFACE, {\n points,\n cellOffset: 0,\n });\n }\n\n model.VBOBuildTime.modified();\n };\n\n publicAPI.setCameraShaderParameters = (cellBO, ren, actor) => {\n const program = cellBO.getProgram();\n const cam = model.openGLCamera.getRenderable();\n const crange = cam.getClippingRange();\n // NOTE: the actual slab thickness clipping is done with clipping planes,\n // but here we still need to set the cam uniform to the clipping range.\n\n program.setUniformf('camThick', crange[1] - crange[0]);\n program.setUniformf('camNear', crange[0]);\n program.setUniformf('camFar', crange[1]);\n\n // // [WMVP]C == {world, model, view, projection} coordinates\n // // E.g., WCPC == world to projection coordinate transformation\n cam.setIsPerformingCoordinateTransformation(true);\n const keyMats = model.openGLCamera.getKeyMatrices(ren);\n cam.setIsPerformingCoordinateTransformation(false);\n const actMats = model.openGLVolume.getKeyMatrices();\n mat4.multiply(model.modelToView, keyMats.wcvc, actMats.mcwc);\n\n const bounds = model.currentInput.getBounds();\n const spc = model.currentInput.getSpacing();\n const dims = model.currentInput.getDimensions();\n\n // compute the viewport bounds of the volume\n // we will only render those fragments.\n const pos = new Float64Array(3);\n const dir = new Float64Array(3);\n let dcxmin = 1.0;\n let dcxmax = -1.0;\n let dcymin = 1.0;\n let dcymax = -1.0;\n\n for (let i = 0; i < 8; ++i) {\n vec3.set(\n pos,\n bounds[i % 2],\n bounds[2 + (Math.floor(i / 2) % 2)],\n bounds[4 + Math.floor(i / 4)]\n );\n vec3.transformMat4(pos, pos, model.modelToView);\n if (!cam.getParallelProjection()) {\n vec3.normalize(dir, pos);\n\n // now find the projection of this point onto a\n // nearZ distance plane. Since the camera is at 0,0,0\n // in VC the ray is just t*pos and\n // t is -nearZ/dir.z\n // intersection becomes pos.x/pos.z\n const t = -crange[0] / pos[2];\n vec3.scale(pos, dir, t);\n }\n // now convert to DC\n vec3.transformMat4(pos, pos, keyMats.vcpc);\n\n dcxmin = Math.min(pos[0], dcxmin);\n dcxmax = Math.max(pos[0], dcxmax);\n dcymin = Math.min(pos[1], dcymin);\n dcymax = Math.max(pos[1], dcymax);\n }\n\n program.setUniformf('dcxmin', dcxmin);\n program.setUniformf('dcxmax', dcxmax);\n program.setUniformf('dcymin', dcymin);\n program.setUniformf('dcymax', dcymax);\n\n if (program.isUniformUsed('cameraParallel')) {\n program.setUniformi('cameraParallel', cam.getParallelProjection());\n }\n\n const ext = model.currentInput.getSpatialExtent();\n const vsize = new Float64Array(3);\n vec3.set(\n vsize,\n (ext[1] - ext[0]) * spc[0],\n (ext[3] - ext[2]) * spc[1],\n (ext[5] - ext[4]) * spc[2]\n );\n program.setUniform3f('vSpacing', spc[0], spc[1], spc[2]);\n\n vec3.set(pos, ext[0], ext[2], ext[4]);\n\n model.currentInput.indexToWorldVec3(pos, pos);\n\n vec3.transformMat4(pos, pos, model.modelToView);\n\n program.setUniform3f('vOriginVC', pos[0], pos[1], pos[2]);\n\n // apply the image directions\n const i2wmat4 = model.currentInput.getIndexToWorld();\n mat4.multiply(model.idxToView, model.modelToView, i2wmat4);\n\n mat3.multiply(\n model.idxNormalMatrix,\n keyMats.normalMatrix,\n actMats.normalMatrix\n );\n mat3.multiply(\n model.idxNormalMatrix,\n model.idxNormalMatrix,\n model.currentInput.getDirection()\n );\n\n const maxSamples =\n vec3.length(vsize) / model.renderable.getSampleDistance();\n if (maxSamples > model.renderable.getMaximumSamplesPerRay()) {\n vtkWarningMacro(`The number of steps required ${Math.ceil(\n maxSamples\n )} is larger than the\n specified maximum number of steps ${model.renderable.getMaximumSamplesPerRay()}.\n Please either change the\n volumeMapper sampleDistance or its maximum number of samples.`);\n }\n\n const vctoijk = new Float64Array(3);\n\n vec3.set(vctoijk, 1.0, 1.0, 1.0);\n vec3.divide(vctoijk, vctoijk, vsize);\n program.setUniform3f('vVCToIJK', vctoijk[0], vctoijk[1], vctoijk[2]);\n program.setUniform3i('volumeDimensions', dims[0], dims[1], dims[2]);\n\n if (!model._openGLRenderWindow.getWebgl2()) {\n const volInfo = model.scalarTexture.getVolumeInfo();\n program.setUniformf('texWidth', model.scalarTexture.getWidth());\n program.setUniformf('texHeight', model.scalarTexture.getHeight());\n program.setUniformi('xreps', volInfo.xreps);\n program.setUniformi('xstride', volInfo.xstride);\n program.setUniformi('ystride', volInfo.ystride);\n }\n\n // map normals through normal matrix\n // then use a point on the plane to compute the distance\n const normal = new Float64Array(3);\n const pos2 = new Float64Array(3);\n for (let i = 0; i < 6; ++i) {\n switch (i) {\n case 1:\n vec3.set(normal, -1.0, 0.0, 0.0);\n vec3.set(pos2, ext[0], ext[2], ext[4]);\n break;\n case 2:\n vec3.set(normal, 0.0, 1.0, 0.0);\n vec3.set(pos2, ext[1], ext[3], ext[5]);\n break;\n case 3:\n vec3.set(normal, 0.0, -1.0, 0.0);\n vec3.set(pos2, ext[0], ext[2], ext[4]);\n break;\n case 4:\n vec3.set(normal, 0.0, 0.0, 1.0);\n vec3.set(pos2, ext[1], ext[3], ext[5]);\n break;\n case 5:\n vec3.set(normal, 0.0, 0.0, -1.0);\n vec3.set(pos2, ext[0], ext[2], ext[4]);\n break;\n case 0:\n default:\n vec3.set(normal, 1.0, 0.0, 0.0);\n vec3.set(pos2, ext[1], ext[3], ext[5]);\n break;\n }\n vec3.transformMat3(normal, normal, model.idxNormalMatrix);\n vec3.transformMat4(pos2, pos2, model.idxToView);\n const dist = -1.0 * vec3.dot(pos2, normal);\n\n // we have the plane in view coordinates\n // specify the planes in view coordinates\n program.setUniform3f(`vPlaneNormal${i}`, normal[0], normal[1], normal[2]);\n program.setUniformf(`vPlaneDistance${i}`, dist);\n\n if (actor.getProperty().getUseLabelOutline()) {\n const image = model.currentInput;\n const worldToIndex = image.getWorldToIndex();\n\n program.setUniformMatrix('vWCtoIDX', worldToIndex);\n\n // Get the projection coordinate to world coordinate transformation matrix.\n mat4.invert(model.projectionToWorld, keyMats.wcpc);\n program.setUniformMatrix('PCWCMatrix', model.projectionToWorld);\n\n const size = publicAPI.getRenderTargetSize();\n const offset = publicAPI.getRenderTargetOffset();\n\n program.setUniformf('vpWidth', size[0]);\n program.setUniformf('vpHeight', size[1]);\n\n // TODO: You need to use the fix/labelMapOutline branch or these\n // won't be consumed by the shader\n program.setUniformf('vpOffsetX', offset[0] / size[0]);\n program.setUniformf('vpOffsetY', offset[1] / size[1]);\n }\n }\n\n mat4.invert(model.projectionToView, keyMats.vcpc);\n model.projectionToView[10] = model.projectionToView[14];\n program.setUniformMatrix('PCVCMatrix', model.projectionToView);\n\n // handle lighting values\n switch (model.lastLightComplexity) {\n default:\n case 0: // no lighting, tcolor is fine as is\n break;\n\n case 1: // headlight\n case 2: // light kit\n case 3: {\n // positional not implemented fallback to directional\n // mat3.transpose(keyMats.normalMatrix, keyMats.normalMatrix);\n let lightNum = 0;\n const lightColor = [];\n ren.getLights().forEach((light) => {\n const status = light.getSwitch();\n if (status > 0) {\n const dColor = light.getColor();\n const intensity = light.getIntensity();\n lightColor[0] = dColor[0] * intensity;\n lightColor[1] = dColor[1] * intensity;\n lightColor[2] = dColor[2] * intensity;\n program.setUniform3fArray(`lightColor${lightNum}`, lightColor);\n const ldir = light.getDirection();\n vec3.set(normal, ldir[0], ldir[1], ldir[2]);\n vec3.transformMat3(normal, normal, keyMats.normalMatrix);\n program.setUniform3f(\n `lightDirectionVC${lightNum}`,\n normal[0],\n normal[1],\n normal[2]\n );\n // camera DOP is 0,0,-1.0 in VC\n const halfAngle = [\n -0.5 * normal[0],\n -0.5 * normal[1],\n -0.5 * (normal[2] - 1.0),\n ];\n program.setUniform3fArray(`lightHalfAngleVC${lightNum}`, halfAngle);\n lightNum++;\n }\n });\n // mat3.transpose(keyMats.normalMatrix, keyMats.normalMatrix);\n }\n }\n };\n\n // publicAPI.getRenderTargetSize = () => {\n // // https://github.com/Kitware/vtk-js/blob/master/Sources/Rendering/OpenGL/VolumeMapper/index.js#L952\n // if (model.lastXYF > 1.43) {\n // const sz = model.framebuffer.getSize()\n // return [model.fvp[0] * sz[0], model.fvp[1] * sz[1]]\n // }\n\n // // This seems wrong, it assumes the renderWindow only has one renderer\n // // but I don't know if this stuff is correct...\n\n // const { usize, vsize } = model.openGLRenderer.getTiledSizeAndOrigin()\n\n // return [usize, vsize]\n // }\n\n // publicAPI.getRenderTargetSize = () => {\n // if (model._useSmallViewport) {\n // return [model._smallViewportWidth, model._smallViewportHeight]\n // }\n\n // return model._openGLRenderWindow.getFramebufferSize()\n // }\n publicAPI.getRenderTargetSize = () => {\n if (model._useSmallViewport) {\n return [model._smallViewportWidth, model._smallViewportHeight];\n }\n\n const { usize, vsize } = model.openGLRenderer.getTiledSizeAndOrigin();\n\n return [usize, vsize];\n };\n\n publicAPI.getRenderTargetOffset = () => {\n const { lowerLeftU, lowerLeftV } =\n model.openGLRenderer.getTiledSizeAndOrigin();\n\n return [lowerLeftU, lowerLeftV];\n };\n}\n\n// ----------------------------------------------------------------------------\n// Object factory\n// ----------------------------------------------------------------------------\n\n// ----------------------------------------------------------------------------\n\nconst DEFAULT_VALUES = {};\n\nexport function extend(publicAPI, model, initialValues = {}) {\n Object.assign(model, DEFAULT_VALUES, initialValues);\n\n vtkOpenGLVolumeMapper.extend(publicAPI, model, initialValues);\n\n model.scalarTexture = initialValues.scalarTexture;\n model.previousState = {};\n\n // Object methods\n vtkStreamingOpenGLVolumeMapper(publicAPI, model);\n}\n\n// ----------------------------------------------------------------------------\n\nexport const newInstance = macro.newInstance(\n extend,\n 'vtkStreamingOpenGLVolumeMapper'\n);\n\n// ----------------------------------------------------------------------------\n\nexport default { newInstance, extend };\n","import macro from '@kitware/vtk.js/macros';\n// import vtkGenericWidgetRepresentation from '@kitware/vtk.js/Rendering/SceneGraph/GenericWidgetRepresentation'\nimport vtkOpenGLActor from '@kitware/vtk.js/Rendering/OpenGL/Actor';\nimport vtkOpenGLActor2D from '@kitware/vtk.js/Rendering/OpenGL/Actor2D';\nimport vtkOpenGLCamera from '@kitware/vtk.js/Rendering/OpenGL/Camera';\nimport vtkOpenGLGlyph3DMapper from '@kitware/vtk.js/Rendering/OpenGL/Glyph3DMapper';\nimport vtkOpenGLImageMapper from '@kitware/vtk.js/Rendering/OpenGL/ImageMapper';\nimport vtkOpenGLImageSlice from '@kitware/vtk.js/Rendering/OpenGL/ImageSlice';\nimport vtkOpenGLPixelSpaceCallbackMapper from '@kitware/vtk.js/Rendering/OpenGL/PixelSpaceCallbackMapper';\nimport vtkOpenGLPolyDataMapper from '@kitware/vtk.js/Rendering/OpenGL/PolyDataMapper';\nimport vtkOpenGLRenderer from '@kitware/vtk.js/Rendering/OpenGL/Renderer';\nimport vtkOpenGLSkybox from '@kitware/vtk.js/Rendering/OpenGL/Skybox';\nimport vtkOpenGLSphereMapper from '@kitware/vtk.js/Rendering/OpenGL/SphereMapper';\nimport vtkOpenGLStickMapper from '@kitware/vtk.js/Rendering/OpenGL/StickMapper';\nimport vtkOpenGLTexture from '@kitware/vtk.js/Rendering/OpenGL/Texture';\nimport vtkOpenGLVolume from '@kitware/vtk.js/Rendering/OpenGL/Volume';\nimport vtkOpenGLVolumeMapper from '@kitware/vtk.js/Rendering/OpenGL/VolumeMapper';\nimport vtkViewNodeFactory from '@kitware/vtk.js/Rendering/SceneGraph/ViewNodeFactory';\nimport vtkStreamingOpenGLVolumeMapper from './vtkStreamingOpenGLVolumeMapper';\n\n/**\n * vtkStreamingOpenGLViewNodeFactory - A fork of the vtkOpenGLViewNodeFactory,\n * so that we can inject our custom derived \"Streaming\" classes.\n *\n * @param {*} publicAPI The public API to extend\n * @param {*} model The private model to extend.\n */\nfunction vtkStreamingOpenGLViewNodeFactory(publicAPI, model) {\n // Set our className\n model.classHierarchy.push('vtkStreamingOpenGLViewNodeFactory');\n\n /**\n * createNode - fork of createNode from vtkOpenGLViewNodeFactory.\n * This fork is required to inject the properties from model.getModelInitialValues.\n *\n * @param {object} dataObject An instance of a vtk.js class.\n */\n publicAPI.createNode = (dataObject) => {\n if (dataObject.isDeleted()) {\n return null;\n }\n\n let cpt = 0;\n let className = dataObject.getClassName(cpt++);\n let isObject = false;\n const keys = Object.keys(model.overrides);\n while (className && !isObject) {\n if (keys.indexOf(className) !== -1) {\n isObject = true;\n } else {\n className = dataObject.getClassName(cpt++);\n }\n }\n\n if (!isObject) {\n return null;\n }\n\n const initialValues = model.getModelInitialValues(dataObject);\n\n const vn = model.overrides[className](initialValues);\n vn.setMyFactory(publicAPI);\n return vn;\n };\n\n /**\n * getModelInitialValues - This function allows us to pass textures down from our\n * vtkSharedVolumeMapper to new instances of vtkStreamingOpenGLVolumeMapper.\n * The prevents us from sharing memory.\n *\n * TODO: It would be beneficial to push similar, but generalized, functionality\n * back to vtk.js in the future.\n *\n * @param {object} dataObject An instance of a vtk.js class.\n */\n model.getModelInitialValues = (dataObject) => {\n const initialValues = {};\n\n const className = dataObject.getClassName();\n\n if (className === 'vtkSharedVolumeMapper') {\n initialValues.scalarTexture = dataObject.getScalarTexture();\n }\n\n return initialValues;\n };\n}\n\n// ----------------------------------------------------------------------------\n// Object factory\n// ----------------------------------------------------------------------------\n\nconst DEFAULT_VALUES = {};\n\n// ----------------------------------------------------------------------------\n\nexport function extend(publicAPI, model, initialValues = {}) {\n Object.assign(model, DEFAULT_VALUES, initialValues);\n\n // Inheritance\n vtkViewNodeFactory.extend(publicAPI, model, initialValues);\n\n // Object methods\n vtkStreamingOpenGLViewNodeFactory(publicAPI, model);\n\n // Initialization\n publicAPI.registerOverride('vtkActor', vtkOpenGLActor.newInstance);\n publicAPI.registerOverride('vtkActor2D', vtkOpenGLActor2D.newInstance);\n publicAPI.registerOverride('vtkCamera', vtkOpenGLCamera.newInstance);\n publicAPI.registerOverride(\n 'vtkGlyph3DMapper',\n vtkOpenGLGlyph3DMapper.newInstance\n );\n publicAPI.registerOverride(\n 'vtkImageMapper',\n vtkOpenGLImageMapper.newInstance\n );\n publicAPI.registerOverride('vtkImageSlice', vtkOpenGLImageSlice.newInstance);\n publicAPI.registerOverride('vtkMapper', vtkOpenGLPolyDataMapper.newInstance);\n publicAPI.registerOverride(\n 'vtkPixelSpaceCallbackMapper',\n vtkOpenGLPixelSpaceCallbackMapper.newInstance\n );\n publicAPI.registerOverride('vtkRenderer', vtkOpenGLRenderer.newInstance);\n publicAPI.registerOverride('vtkSkybox', vtkOpenGLSkybox.newInstance);\n publicAPI.registerOverride(\n 'vtkSphereMapper',\n vtkOpenGLSphereMapper.newInstance\n );\n publicAPI.registerOverride(\n 'vtkStickMapper',\n vtkOpenGLStickMapper.newInstance\n );\n publicAPI.registerOverride('vtkTexture', vtkOpenGLTexture.newInstance);\n publicAPI.registerOverride('vtkVolume', vtkOpenGLVolume.newInstance);\n publicAPI.registerOverride(\n 'vtkVolumeMapper',\n vtkOpenGLVolumeMapper.newInstance\n );\n publicAPI.registerOverride(\n 'vtkSharedVolumeMapper',\n vtkStreamingOpenGLVolumeMapper.newInstance\n );\n // publicAPI.registerOverride(\n // 'vtkWidgetRepresentation',\n // vtkGenericWidgetRepresentation.newInstance\n // )\n}\n\n// ----------------------------------------------------------------------------\n\nexport const newInstance = macro.newInstance(\n extend,\n 'vtkStreamingOpenGLViewNodeFactory'\n);\n\n// ----------------------------------------------------------------------------\n\nexport default { newInstance, extend };\n","import macro from '@kitware/vtk.js/macros';\nimport vtkOpenGLRenderWindow from '@kitware/vtk.js/Rendering/OpenGL/RenderWindow';\nimport vtkStreamingOpenGLViewNodeFactory from './vtkStreamingOpenGLViewNodeFactory';\n\n/**\n * vtkStreamingOpenGLRenderWindow - A dervied class of the core vtkOpenGLRenderWindow class.\n * The main purpose for this class extension is to add in our own node factory, so we can use\n * our extended \"streaming\" classes for progressive texture loading.\n *\n *\n * @param {*} publicAPI The public API to extend\n * @param {*} model The private model to extend.\n */\nfunction vtkStreamingOpenGLRenderWindow(publicAPI, model) {\n model.classHierarchy.push('vtkStreamingOpenGLRenderWindow');\n}\n\n// ----------------------------------------------------------------------------\n// Object factory\n// ----------------------------------------------------------------------------\n\n// ----------------------------------------------------------------------------\n\nexport function extend(publicAPI, model, initialValues = {}) {\n Object.assign(model, initialValues);\n\n vtkOpenGLRenderWindow.extend(publicAPI, model, initialValues);\n\n model.myFactory = vtkStreamingOpenGLViewNodeFactory.newInstance();\n /* eslint-disable no-use-before-define */\n model.myFactory.registerOverride('vtkRenderWindow', newInstance);\n /* eslint-enable no-use-before-define */\n\n // Object methods\n vtkStreamingOpenGLRenderWindow(publicAPI, model);\n}\n\n// ----------------------------------------------------------------------------\n\nexport const newInstance = macro.newInstance(\n extend,\n 'vtkStreamingOpenGLRenderWindow'\n);\n\n// ----------------------------------------------------------------------------\n\nexport default { newInstance, extend };\n","import macro from '@kitware/vtk.js/macros';\nimport vtkStreamingOpenGLRenderWindow from './vtkStreamingOpenGLRenderWindow';\nimport vtkRenderer from '@kitware/vtk.js/Rendering/Core/Renderer';\nimport vtkRenderWindow from '@kitware/vtk.js/Rendering/Core/RenderWindow';\nimport vtkRenderWindowInteractor from '@kitware/vtk.js/Rendering/Core/RenderWindowInteractor';\n\n// Load basic classes for vtk() factory\nimport '@kitware/vtk.js/Common/Core/Points';\nimport '@kitware/vtk.js/Common/Core/DataArray';\nimport '@kitware/vtk.js/Common/DataModel/PolyData';\nimport '@kitware/vtk.js/Rendering/Core/Actor';\nimport '@kitware/vtk.js/Rendering/Core/Mapper';\n\n/**\n * vtkOffscreenMultiRenderWindow - A class to deal with offscreen rendering with multiple renderers.\n *\n * This class is based on the vtkGenericRenderWindow with two key differences:\n * - the vtkGenericRenderWindow had a renderer at the top level, with helpers to get it from the renderWindow.\n * although you could add more renderers, this gave special status to the first viewport. Which was confusing.\n * - When checking the size of the container element we no longer check the client size, as the canvas is offscreen.\n * - We aren't using interactor styles, so don't set one up.\n *\n * Additionally this class has some new helpers to easily add/associate renderers to different viewportIds.\n *\n *\n * @param {*} publicAPI The public API to extend\n * @param {*} model The private model to extend.\n */\nfunction vtkOffscreenMultiRenderWindow(publicAPI, model) {\n // Capture resize trigger method to remove from publicAPI\n const invokeResize = publicAPI.invokeResize;\n delete publicAPI.invokeResize;\n\n // VTK renderWindow. No renderers set by default\n model.renderWindow = vtkRenderWindow.newInstance();\n model.rendererMap = {};\n\n // OpenGLRenderWindow\n model.openGLRenderWindow = vtkStreamingOpenGLRenderWindow.newInstance();\n model.renderWindow.addView(model.openGLRenderWindow);\n\n // Interactor\n model.interactor = vtkRenderWindowInteractor.newInstance();\n model.interactor.setView(model.openGLRenderWindow);\n model.interactor.initialize();\n\n publicAPI.addRenderer = ({ viewport, id, background }) => {\n const renderer = vtkRenderer.newInstance({\n viewport,\n background: background || model.background,\n });\n\n model.renderWindow.addRenderer(renderer);\n model.rendererMap[id] = renderer;\n };\n\n publicAPI.destroy = () => {\n const rwi = model.renderWindow.getInteractor();\n rwi.delete();\n };\n\n publicAPI.removeRenderer = (id) => {\n const renderer = publicAPI.getRenderer(id);\n model.renderWindow.removeRenderer(renderer);\n renderer.delete();\n delete model.rendererMap[id];\n };\n\n publicAPI.getRenderer = (id) => {\n return model.rendererMap[id];\n };\n\n publicAPI.getRenderers = () => {\n const { rendererMap } = model;\n\n const renderers = Object.keys(rendererMap).map((id) => {\n return { id, renderer: rendererMap[id] };\n });\n\n return renderers;\n };\n\n // Handle window resize\n publicAPI.resize = () => {\n if (model.container) {\n // Don't use getBoundingClientRect() as in vtkGenericRenderWindow as is an offscreen canvas.\n const { width, height } = model.container;\n\n // Note: we do not scale by devicePixelRatio here because it has already\n // been done when adding the offscreenCanvas viewport representations\n model.openGLRenderWindow.setSize(Math.floor(width), Math.floor(height));\n invokeResize();\n model.renderWindow.render();\n }\n };\n\n // Handle DOM container relocation\n publicAPI.setContainer = (el) => {\n // Switch container\n model.container = el;\n model.openGLRenderWindow.setContainer(model.container);\n };\n\n // Properly release GL context\n publicAPI.delete = macro.chain(\n publicAPI.setContainer,\n publicAPI.destroy,\n model.openGLRenderWindow.delete,\n publicAPI.delete\n );\n\n publicAPI.resize();\n}\n\n// ----------------------------------------------------------------------------\n// Object factory\n// ----------------------------------------------------------------------------\n\nconst DEFAULT_VALUES = {\n background: [0.0, 0.0, 0.0],\n container: null,\n};\n\n// ----------------------------------------------------------------------------\n\nexport function extend(publicAPI, model, initialValues = {}) {\n Object.assign(model, DEFAULT_VALUES, initialValues);\n\n // Object methods\n macro.obj(publicAPI, model);\n macro.get(publicAPI, model, [\n 'renderWindow',\n 'openGLRenderWindow',\n 'interactor',\n 'container',\n ]);\n macro.event(publicAPI, model, 'resize');\n\n // Object specific methods\n vtkOffscreenMultiRenderWindow(publicAPI, model);\n}\n\n// ----------------------------------------------------------------------------\n\nexport const newInstance = macro.newInstance(extend);\n\n// ----------------------------------------------------------------------------\n\nexport default { newInstance, extend };\n","export default function _assertThisInitialized(self) {\n if (self === void 0) {\n throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");\n }\n\n return self;\n}","export default function _getPrototypeOf(o) {\n _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {\n return o.__proto__ || Object.getPrototypeOf(o);\n };\n return _getPrototypeOf(o);\n}","import getPrototypeOf from \"./getPrototypeOf.js\";\nexport default function _superPropBase(object, property) {\n while (!Object.prototype.hasOwnProperty.call(object, property)) {\n object = getPrototypeOf(object);\n if (object === null) break;\n }\n\n return object;\n}","import superPropBase from \"./superPropBase.js\";\nexport default function _get() {\n if (typeof Reflect !== \"undefined\" && Reflect.get) {\n _get = Reflect.get.bind();\n } else {\n _get = function _get(target, property, receiver) {\n var base = superPropBase(target, property);\n if (!base) return;\n var desc = Object.getOwnPropertyDescriptor(base, property);\n\n if (desc.get) {\n return desc.get.call(arguments.length < 3 ? target : receiver);\n }\n\n return desc.value;\n };\n }\n\n return _get.apply(this, arguments);\n}","export default function _setPrototypeOf(o, p) {\n _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {\n o.__proto__ = p;\n return o;\n };\n return _setPrototypeOf(o, p);\n}","import setPrototypeOf from \"./setPrototypeOf.js\";\nexport default function _inherits(subClass, superClass) {\n if (typeof superClass !== \"function\" && superClass !== null) {\n throw new TypeError(\"Super expression must either be null or a function\");\n }\n\n subClass.prototype = Object.create(superClass && superClass.prototype, {\n constructor: {\n value: subClass,\n writable: true,\n configurable: true\n }\n });\n Object.defineProperty(subClass, \"prototype\", {\n writable: false\n });\n if (superClass) setPrototypeOf(subClass, superClass);\n}","import _typeof from \"./typeof.js\";\nimport assertThisInitialized from \"./assertThisInitialized.js\";\nexport default function _possibleConstructorReturn(self, call) {\n if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) {\n return call;\n } else if (call !== void 0) {\n throw new TypeError(\"Derived constructors may only return object or undefined\");\n }\n\n return assertThisInitialized(self);\n}","import cache, { Cache } from './cache';\nimport ImageVolume from './classes/ImageVolume';\n\nexport { ImageVolume, Cache };\nexport default cache;\n","import type Point3 from '../types/Point3';\n\n/**\n * Given an imageData object and a point in physical space, return the index of the\n * voxel that contains the point. TODO: this should be pushed to vtk upstream.\n * @param imageData - The image data object.\n * @param physicalPoint - The point in physical space that you want to transform to\n * index space.\n * @returns An array of integers.\n */\nexport default function transformWorldToIndex(imageData, worldPos: Point3) {\n const continuousIndex = imageData.worldToIndex(worldPos);\n const index = continuousIndex.map(Math.round);\n\n return index;\n}\n","import arrayWithHoles from \"./arrayWithHoles.js\";\nimport iterableToArrayLimit from \"./iterableToArrayLimit.js\";\nimport unsupportedIterableToArray from \"./unsupportedIterableToArray.js\";\nimport nonIterableRest from \"./nonIterableRest.js\";\nexport default function _slicedToArray(arr, i) {\n return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || unsupportedIterableToArray(arr, i) || nonIterableRest();\n}","export default function _arrayWithHoles(arr) {\n if (Array.isArray(arr)) return arr;\n}","export default function _iterableToArrayLimit(arr, i) {\n var _i = arr == null ? null : typeof Symbol !== \"undefined\" && arr[Symbol.iterator] || arr[\"@@iterator\"];\n\n if (_i == null) return;\n var _arr = [];\n var _n = true;\n var _d = false;\n\n var _s, _e;\n\n try {\n for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {\n _arr.push(_s.value);\n\n if (i && _arr.length === i) break;\n }\n } catch (err) {\n _d = true;\n _e = err;\n } finally {\n try {\n if (!_n && _i[\"return\"] != null) _i[\"return\"]();\n } finally {\n if (_d) throw _e;\n }\n }\n\n return _arr;\n}","export default function _nonIterableRest() {\n throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}","import type vtkActor from '@kitware/vtk.js/Rendering/Core/Actor';\nimport type vtkImageSlice from '@kitware/vtk.js/Rendering/Core/ImageSlice';\nimport type vtkVolume from '@kitware/vtk.js/Rendering/Core/Volume';\n\n/**\n * Checks if a vtk Actor is an image actor (vtkVolume or vtkImageSlice) otherwise returns false.\n *\n * @param actor - actor\n * @returns A boolean value.\n */\nexport default function isImageActor(\n actor: vtkActor | vtkVolume | vtkImageSlice\n): boolean {\n if (actor.isA('vtkVolume')) {\n return true;\n }\n\n if (actor.isA('vtkImageSlice')) {\n return true;\n }\n\n return false;\n}\n","import { Point3, Plane } from '../types';\nimport { vec3, mat3 } from 'gl-matrix';\n\n/**\n * It calculates the intersection of a line and a plane.\n * Plane equation is Ax+By+Cz=D\n * @param p0 - [x,y,z] of the first point of the line\n * @param p1 - [x,y,z] of the second point of the line\n * @param plane - [A, B, C, D] Plane parameter: Ax+By+Cz=D\n * @returns - [X,Y,Z] coordinates of the intersection\n */\nfunction linePlaneIntersection(p0: Point3, p1: Point3, plane: Plane): Point3 {\n const [x0, y0, z0] = p0;\n const [x1, y1, z1] = p1;\n const [A, B, C, D] = plane;\n const a = x1 - x0;\n const b = y1 - y0;\n const c = z1 - z0;\n const t = (-1 * (A * x0 + B * y0 + C * z0 - D)) / (A * a + B * b + C * c);\n const X = a * t + x0;\n const Y = b * t + y0;\n const Z = c * t + z0;\n\n return [X, Y, Z];\n}\n\n/**\n * It returns the plane equation defined by a point and a normal vector.\n * @param normal - normal vector\n * @param point - a point on the plane\n * @returns - [A, B,C, D] of plane equation A*X + B*Y + C*Z = D\n */\nfunction planeEquation(normal: Point3, point: Point3 | vec3): Plane {\n const [A, B, C] = normal;\n const D = A * point[0] + B * point[1] + C * point[2];\n return [A, B, C, D];\n}\n\n/**\n * Computes the intersection of three planes in 3D space with equations:\n * A1*X + B1*Y + C1*Z = D1\n * A2*X + B2*Y + C2*Z = D2\n * A3*X + B3*Y + C3*Z = D3\n * @returns - [x, y, z] the intersection in the world coordinate\n */\nfunction threePlaneIntersection(\n firstPlane: Plane,\n secondPlane: Plane,\n thirdPlane: Plane\n): Point3 {\n const [A1, B1, C1, D1] = firstPlane;\n const [A2, B2, C2, D2] = secondPlane;\n const [A3, B3, C3, D3] = thirdPlane;\n const m0 = mat3.fromValues(A1, A2, A3, B1, B2, B3, C1, C2, C3);\n const m1 = mat3.fromValues(D1, D2, D3, B1, B2, B3, C1, C2, C3);\n const m2 = mat3.fromValues(A1, A2, A3, D1, D2, D3, C1, C2, C3);\n const m3 = mat3.fromValues(A1, A2, A3, B1, B2, B3, D1, D2, D3);\n\n // TODO: handle no intersection scenario\n const x = mat3.determinant(m1) / mat3.determinant(m0);\n const y = mat3.determinant(m2) / mat3.determinant(m0);\n const z = mat3.determinant(m3) / mat3.determinant(m0);\n return [x, y, z];\n}\n\n/**\n * Computes the distance of a point in 3D space to a plane\n * @param plane - [A, B, C, D] of plane equation A*X + B*Y + C*Z = D\n * @param point - [A, B, C] the plane in World coordinate\n * @param signed - if true, the distance is signed\n * @returns - the distance of the point to the plane\n * */\nfunction planeDistanceToPoint(\n plane: Plane,\n point: Point3,\n signed = false\n): number {\n const [A, B, C, D] = plane;\n const [x, y, z] = point;\n const numerator = A * x + B * y + C * z - D;\n const distance = Math.abs(numerator) / Math.sqrt(A * A + B * B + C * C);\n const sign = signed ? Math.sign(numerator) : 1;\n return sign * distance;\n}\n\nexport {\n linePlaneIntersection,\n planeEquation,\n threePlaneIntersection,\n planeDistanceToPoint,\n};\n","/**\n * A function that checks if there is a value in the array that is NaN.\n * or if the input is a number it just checks if it is NaN.\n * @param input - The input to check if it is NaN.\n * @returns - True if the input is NaN, false otherwise.\n */\nexport default function hasNaNValues(input: number[] | number): boolean {\n if (Array.isArray(input)) {\n return input.some((value) => Number.isNaN(value));\n }\n return Number.isNaN(input);\n}\n","import type { vtkCamera } from '@kitware/vtk.js/Rendering/Core/Camera';\nimport vtkMatrixBuilder from '@kitware/vtk.js/Common/Core/MatrixBuilder';\nimport vtkMath from '@kitware/vtk.js/Common/Core/Math';\nimport vtkPlane from '@kitware/vtk.js/Common/DataModel/Plane';\n\nimport { vec2, vec3, mat4 } from 'gl-matrix';\nimport _cloneDeep from 'lodash.clonedeep';\n\nimport Events from '../enums/Events';\nimport ViewportType from '../enums/ViewportType';\nimport renderingEngineCache from './renderingEngineCache';\nimport { triggerEvent, planar, isImageActor } from '../utilities';\nimport hasNaNValues from '../utilities/hasNaNValues';\nimport { RENDERING_DEFAULTS } from '../constants';\nimport type {\n ICamera,\n ActorEntry,\n IRenderingEngine,\n ViewportInputOptions,\n Point2,\n Point3,\n FlipDirection,\n EventTypes,\n} from '../types';\nimport type { ViewportInput, IViewport } from '../types/IViewport';\nimport type { vtkSlabCamera } from './vtkClasses/vtkSlabCamera';\n\n/**\n * An object representing a single viewport, which is a camera\n * looking into a viewport, and an associated target output `HTMLDivElement`.\n * Viewport is a base class that can be extended to create a specific\n * viewport type. Both VolumeViewport and StackViewport are subclasses\n * of Viewport. Common logic for all viewports is contained in Viewport class\n * which is camera properties/methods, vtk.js actors, and other common\n * logic.\n */\nclass Viewport implements IViewport {\n /** unique identifier for the viewport */\n readonly id: string;\n /** HTML element in DOM that is used for rendering the viewport */\n readonly element: HTMLDivElement;\n /** an internal canvas that is created on the provided HTML element */\n readonly canvas: HTMLCanvasElement;\n /** RenderingEngine id that the viewport belongs to */\n readonly renderingEngineId: string;\n /** Type of viewport */\n readonly type: ViewportType;\n protected flipHorizontal = false;\n protected flipVertical = false;\n protected rotation = 0;\n public isDisabled: boolean;\n\n /** sx of viewport on the offscreen canvas */\n sx: number;\n /** sy of viewport on the offscreen canvas */\n sy: number;\n /** sWidth of viewport on the offscreen canvas */\n sWidth: number;\n /** sHeight of viewport on the offscreen canvas */\n sHeight: number;\n /** a Map containing the actor uid and actors */\n _actors: Map<string, any>;\n /** Default options for the viewport which includes orientation, viewPlaneNormal and backgroundColor */\n readonly defaultOptions: any;\n /** options for the viewport which includes orientation axis and backgroundColor */\n options: ViewportInputOptions;\n private _suppressCameraModifiedEvents = false;\n /** A flag representing if viewport methods should fire events or not */\n readonly suppressEvents: boolean;\n protected hasPixelSpacing = true;\n /** The camera that is initially defined on the reset for\n * the relative pan/zoom\n */\n protected initialCamera: ICamera;\n\n constructor(props: ViewportInput) {\n this.id = props.id;\n this.renderingEngineId = props.renderingEngineId;\n this.type = props.type;\n this.element = props.element;\n this.canvas = props.canvas;\n this.sx = props.sx;\n this.sy = props.sy;\n this.sWidth = props.sWidth;\n this.sHeight = props.sHeight;\n this._actors = new Map();\n // Set data attributes for render events\n this.element.setAttribute('data-viewport-uid', this.id);\n this.element.setAttribute(\n 'data-rendering-engine-uid',\n this.renderingEngineId\n );\n\n this.defaultOptions = _cloneDeep(props.defaultOptions);\n this.suppressEvents = props.defaultOptions.suppressEvents\n ? props.defaultOptions.suppressEvents\n : false;\n this.options = _cloneDeep(props.defaultOptions);\n this.isDisabled = false;\n }\n\n getFrameOfReferenceUID: () => string;\n canvasToWorld: (canvasPos: Point2) => Point3;\n worldToCanvas: (worldPos: Point3) => Point2;\n customRenderViewportToCanvas: () => unknown;\n resize: () => void;\n getProperties: () => void;\n\n static get useCustomRenderingPipeline(): boolean {\n return false;\n }\n\n /**\n * Returns the rendering engine driving the `Viewport`.\n *\n * @returns The RenderingEngine instance.\n */\n public getRenderingEngine(): IRenderingEngine {\n return renderingEngineCache.get(this.renderingEngineId);\n }\n\n /**\n * Returns the `vtkRenderer` responsible for rendering the `Viewport`.\n *\n * @returns The `vtkRenderer` for the `Viewport`.\n */\n public getRenderer() {\n const renderingEngine = this.getRenderingEngine();\n\n if (!renderingEngine || renderingEngine.hasBeenDestroyed) {\n throw new Error('Rendering engine has been destroyed');\n }\n\n return renderingEngine.offscreenMultiRenderWindow.getRenderer(this.id);\n }\n\n /**\n * Renders the `Viewport` using the `RenderingEngine`.\n */\n public render(): void {\n const renderingEngine = this.getRenderingEngine();\n\n renderingEngine.renderViewport(this.id);\n }\n\n /**\n * Sets new options and (TODO) applies them.\n *\n * @param options - The viewport options to set.\n * @param immediate - If `true`, renders the viewport after the options are set.\n */\n public setOptions(options: ViewportInputOptions, immediate = false): void {\n this.options = <ViewportInputOptions>_cloneDeep(options);\n\n // TODO When this is needed we need to move the camera position.\n // We can steal some logic from the tools we build to do this.\n\n if (immediate) {\n this.render();\n }\n }\n\n /**\n * Resets the options the `Viewport`'s `defaultOptions`\n *\n * @param immediate - If `true`, renders the viewport after the options are reset.\n */\n public reset(immediate = false) {\n this.options = _cloneDeep(this.defaultOptions);\n\n // TODO When this is needed we need to move the camera position.\n // We can steal some logic from the tools we build to do this.\n\n if (immediate) {\n this.render();\n }\n }\n\n /**\n * Flip the viewport on horizontal or vertical axis, this method\n * works with vtk-js backed rendering pipeline.\n *\n * @param flipOptions - Flip options specifying the axis of flip\n * @param flipOptions.flipHorizontal - Flip the viewport on horizontal axis\n * @param flipOptions.flipVertical - Flip the viewport on vertical axis\n */\n protected flip({ flipHorizontal, flipVertical }: FlipDirection): void {\n const imageData = this.getDefaultImageData();\n\n if (!imageData) {\n return;\n }\n\n const camera = this.getCamera();\n const { viewPlaneNormal, viewUp, focalPoint, position } = camera;\n\n const viewRight = vec3.cross(vec3.create(), viewPlaneNormal, viewUp);\n let viewUpToSet = vec3.copy(vec3.create(), viewUp);\n const viewPlaneNormalToSet = vec3.negate(vec3.create(), viewPlaneNormal);\n\n // for both flip horizontal and vertical we need to move the camera to the\n // other side of the image\n const distance = vec3.distance(position, focalPoint);\n\n // If the pan has been applied, we need to be able\n // apply the pan back\n const dimensions = imageData.getDimensions();\n const middleIJK = dimensions.map((d) => Math.floor(d / 2));\n\n const idx = [middleIJK[0], middleIJK[1], middleIJK[2]];\n const centeredFocalPoint = imageData.indexToWorld(idx, vec3.create());\n\n const resetFocalPoint = this._getFocalPointForResetCamera(\n centeredFocalPoint as Point3,\n camera,\n { resetPan: true, resetToCenter: false }\n );\n\n const panDir = vec3.subtract(vec3.create(), focalPoint, resetFocalPoint);\n const panValue = vec3.length(panDir);\n\n const getPanDir = (mirrorVec) => {\n const panDirMirror = vec3.scale(\n vec3.create(),\n mirrorVec,\n 2 * vec3.dot(panDir, mirrorVec)\n );\n vec3.subtract(panDirMirror, panDirMirror, panDir);\n vec3.normalize(panDirMirror, panDirMirror);\n\n return panDirMirror;\n };\n\n // Flipping horizontal mean that the camera should move\n // to the other side of the image but looking at the\n // same direction and same focal point\n if (flipHorizontal) {\n // we need to apply the pan value to the new focal point but in the direction\n // that is mirrored on the viewUp for the flip horizontal and\n // viewRight for the flip vertical\n\n // mirror the pan direction based on the viewUp\n const panDirMirror = getPanDir(viewUpToSet);\n\n // move focal point from the resetFocalPoint to the newFocalPoint\n // based on the panDirMirror and panValue\n const newFocalPoint = vec3.scaleAndAdd(\n vec3.create(),\n resetFocalPoint,\n panDirMirror,\n panValue\n );\n\n // move the camera position also the same way as the focal point\n const newPosition = vec3.scaleAndAdd(\n vec3.create(),\n newFocalPoint,\n viewPlaneNormalToSet,\n distance\n );\n\n this.setCamera({\n viewPlaneNormal: viewPlaneNormalToSet as Point3,\n position: newPosition as Point3,\n focalPoint: newFocalPoint as Point3,\n });\n\n this.flipHorizontal = !this.flipHorizontal;\n }\n\n // Flipping vertical mean that the camera should negate the view up\n // and also move to the other side of the image but looking at the\n if (flipVertical) {\n viewUpToSet = vec3.negate(viewUpToSet, viewUp);\n\n // we need to apply the pan value to the new focal point but in the direction\n const panDirMirror = getPanDir(viewRight);\n\n const newFocalPoint = vec3.scaleAndAdd(\n vec3.create(),\n resetFocalPoint,\n panDirMirror,\n panValue\n );\n\n const newPosition = vec3.scaleAndAdd(\n vec3.create(),\n newFocalPoint,\n viewPlaneNormalToSet,\n distance\n );\n\n this.setCamera({\n focalPoint: newFocalPoint as Point3,\n viewPlaneNormal: viewPlaneNormalToSet as Point3,\n viewUp: viewUpToSet as Point3,\n position: newPosition as Point3,\n });\n\n this.flipVertical = !this.flipVertical;\n }\n\n this.render();\n }\n\n private getDefaultImageData(): any {\n const actorEntry = this.getDefaultActor();\n\n if (actorEntry && isImageActor(actorEntry.actor)) {\n return actorEntry.actor.getMapper().getInputData();\n }\n }\n\n /**\n * Get the default actor\n * @returns An actor entry.\n */\n public getDefaultActor(): ActorEntry {\n return this.getActors()[0];\n }\n\n /**\n * Get all the actors in the viewport\n * @returns An array of ActorEntry objects.\n */\n public getActors(): Array<ActorEntry> {\n return Array.from(this._actors.values());\n }\n\n /**\n * Get an actor by its UID\n * @param actorUID - The unique ID of the actor.\n * @returns An ActorEntry object.\n */\n public getActor(actorUID: string): ActorEntry {\n return this._actors.get(actorUID);\n }\n\n /**\n * Get an actor UID by its index\n * @param index - array index.\n * @returns actorUID\n */\n public getActorUIDByIndex(index: number): string {\n const actor = this.getActors()[index];\n if (actor) {\n return actor.uid;\n }\n }\n\n /**\n * Get an actor by its index\n * @param index - array index.\n * @returns actorUID\n */\n public getActorByIndex(index: number): ActorEntry {\n return this.getActors()[index];\n }\n\n /**\n * It removes all actors from the viewport and then adds the actors from the array.\n * @param actors - An array of ActorEntry objects.\n */\n public setActors(actors: Array<ActorEntry>): void {\n this.removeAllActors();\n const resetCameraPanAndZoom = true;\n // when we set the actor we need to reset the camera to initialize the\n // camera focal point with the bounds of the actors.\n this.addActors(actors, resetCameraPanAndZoom);\n }\n\n /**\n * Remove the actor from the viewport\n * @param actorUID - The unique identifier for the actor.\n */\n public removeActor(actorUID: string): void {\n const actorEntry = this.getActor(actorUID);\n if (!actorEntry) {\n console.warn(`Actor ${actorUID} does not exist for this viewport`);\n return;\n }\n const renderer = this.getRenderer();\n renderer.removeViewProp(actorEntry.actor); // removeActor not implemented in vtk?\n this._actors.delete(actorUID);\n }\n\n /**\n * Remove the actors with the given UIDs from the viewport\n * @param actorUIDs - An array of actor UIDs to remove.\n */\n public removeActors(actorUIDs: Array<string>): void {\n actorUIDs.forEach((actorUID) => {\n this.removeActor(actorUID);\n });\n }\n\n /**\n * Add a list of actors (actor entries) to the viewport\n * @param resetCameraPanAndZoom - force reset pan and zoom of the camera,\n * default value is false.\n * @param actors - An array of ActorEntry objects.\n */\n public addActors(\n actors: Array<ActorEntry>,\n resetCameraPanAndZoom = false\n ): void {\n const renderingEngine = this.getRenderingEngine();\n if (!renderingEngine || renderingEngine.hasBeenDestroyed) {\n console.warn(\n 'Viewport::addActors::Rendering engine has not been initialized or has been destroyed'\n );\n return;\n }\n\n actors.forEach((actor) => this.addActor(actor));\n\n // set the clipping planes for the actors\n this.resetCamera(resetCameraPanAndZoom, resetCameraPanAndZoom);\n }\n\n /**\n * Add an actor to the viewport including its id, its actor and slabThickness\n * if defined\n * @param actorEntry - ActorEntry\n * @param actorEntry.uid - The unique identifier for the actor.\n * @param actorEntry.actor - The volume actor.\n * @param actorEntry.slabThickness - The slab thickness.\n */\n public addActor(actorEntry: ActorEntry): void {\n const { uid: actorUID, actor } = actorEntry;\n const renderingEngine = this.getRenderingEngine();\n\n if (!renderingEngine || renderingEngine.hasBeenDestroyed) {\n console.warn(\n `Cannot add actor UID of ${actorUID} Rendering Engine has been destroyed`\n );\n return;\n }\n\n if (!actorUID || !actor) {\n throw new Error('Actors should have uid and vtk Actor properties');\n }\n\n if (this.getActor(actorUID)) {\n console.warn(`Actor ${actorUID} already exists for this viewport`);\n return;\n }\n\n const renderer = this.getRenderer();\n renderer.addActor(actor);\n this._actors.set(actorUID, Object.assign({}, actorEntry));\n }\n\n /**\n * Remove all actors from the renderer\n */\n public removeAllActors(): void {\n this.getRenderer().removeAllViewProps();\n this._actors = new Map();\n return;\n }\n\n /**\n * Reset the camera to the default viewport camera without firing events\n */\n protected resetCameraNoEvent(): void {\n this._suppressCameraModifiedEvents = true;\n this.resetCamera();\n this._suppressCameraModifiedEvents = false;\n }\n\n /**\n * Sets the camera to the default viewport camera without firing events\n * @param camera - The camera to use for the viewport.\n */\n protected setCameraNoEvent(camera: ICamera): void {\n this._suppressCameraModifiedEvents = true;\n this.setCamera(camera);\n this._suppressCameraModifiedEvents = false;\n }\n\n /**\n * Calculates the intersections between the volume's boundaries and the viewplane.\n * 1) Determine the viewplane using the camera's ViewplaneNormal and focalPoint.\n * 2) Using volumeBounds, calculate the line equation for the 3D volume's 12 edges.\n * 3) Intersect each edge to the viewPlane and see whether the intersection point is inside the volume bounds.\n * 4) Return list of intersection points\n * It should be noted that intersection points may range from 3 to 6 points.\n * Orthogonal views have four points of intersection.\n *\n * @param imageData - vtkImageData\n * @param focalPoint - camera focal point\n * @param normal - view plane normal\n * @returns intersections list\n */\n private _getViewImageDataIntersections(imageData, focalPoint, normal) {\n // Viewplane equation: Ax+By+Cz=D\n const A = normal[0];\n const B = normal[1];\n const C = normal[2];\n const D = A * focalPoint[0] + B * focalPoint[1] + C * focalPoint[2];\n\n // Computing the edges of the 3D cube\n const bounds = imageData.getBounds();\n const edges = this._getEdges(bounds);\n\n const intersections = [];\n\n for (const edge of edges) {\n // start point: [x0, y0, z0], end point: [x1, y1, z1]\n const [[x0, y0, z0], [x1, y1, z1]] = edge;\n // Check if the edge is parallel to plane\n if (A * (x1 - x0) + B * (y1 - y0) + C * (z1 - z0) === 0) {\n continue;\n }\n const intersectionPoint = planar.linePlaneIntersection(\n [x0, y0, z0],\n [x1, y1, z1],\n [A, B, C, D]\n );\n\n if (this._isInBounds(intersectionPoint, bounds)) {\n intersections.push(intersectionPoint);\n }\n }\n\n return intersections;\n }\n\n /**\n * Resets the camera based on the rendering volume(s) bounds. If\n * resetPan and resetZoom are true it places the focal point at the center of\n * the volume (or slice); otherwise, only the camera zoom and camera Pan or Zoom\n * is reset for the current view.\n * @param resetPan - If true, the camera focal point is reset to the center of the volume (slice)\n * @param resetZoom - If true, the camera zoom is reset to the default zoom\n * @param storeAsInitialCamera - If true, reset camera is stored as the initial camera (to allow differences to\n * be detected for pan/zoom values)\n * @returns boolean\n */\n protected resetCamera(\n resetPan = true,\n resetZoom = true,\n resetToCenter = true,\n storeAsInitialCamera = true\n ): boolean {\n const renderer = this.getRenderer();\n\n // fix the flip right away, since we rely on the viewPlaneNormal and\n // viewUp for later. Basically, we need to flip back if flipHorizontal\n // is true or flipVertical is true\n this.setCamera({\n flipHorizontal: false,\n flipVertical: false,\n });\n\n const previousCamera = _cloneDeep(this.getCamera());\n\n const bounds = renderer.computeVisiblePropBounds();\n const focalPoint = <Point3>[0, 0, 0];\n const imageData = this.getDefaultImageData();\n\n // Todo: remove this, this is just for tests passing\n if (imageData) {\n const spc = imageData.getSpacing();\n\n bounds[0] = bounds[0] + spc[0] / 2;\n bounds[1] = bounds[1] - spc[0] / 2;\n bounds[2] = bounds[2] + spc[1] / 2;\n bounds[3] = bounds[3] - spc[1] / 2;\n bounds[4] = bounds[4] + spc[2] / 2;\n bounds[5] = bounds[5] - spc[2] / 2;\n }\n\n const activeCamera = this.getVtkActiveCamera();\n const viewPlaneNormal = <Point3>activeCamera.getViewPlaneNormal();\n const viewUp = <Point3>activeCamera.getViewUp();\n\n // Reset the perspective zoom factors, otherwise subsequent zooms will cause\n // the view angle to become very small and cause bad depth sorting.\n // todo: parallel projection only\n\n focalPoint[0] = (bounds[0] + bounds[1]) / 2.0;\n focalPoint[1] = (bounds[2] + bounds[3]) / 2.0;\n focalPoint[2] = (bounds[4] + bounds[5]) / 2.0;\n\n if (imageData) {\n const dimensions = imageData.getDimensions();\n const middleIJK = dimensions.map((d) => Math.floor(d / 2));\n\n const idx = [middleIJK[0], middleIJK[1], middleIJK[2]];\n imageData.indexToWorld(idx, focalPoint);\n }\n\n const { widthWorld, heightWorld } =\n this._getWorldDistanceViewUpAndViewRight(bounds, viewUp, viewPlaneNormal);\n\n const canvasSize = [this.sWidth, this.sHeight];\n\n const boundsAspectRatio = widthWorld / heightWorld;\n const canvasAspectRatio = canvasSize[0] / canvasSize[1];\n\n let radius;\n\n if (boundsAspectRatio < canvasAspectRatio) {\n // can fit full height, so use it.\n radius = heightWorld / 2;\n } else {\n const scaleFactor = boundsAspectRatio / canvasAspectRatio;\n\n radius = (heightWorld * scaleFactor) / 2;\n }\n\n //const angle = vtkMath.radiansFromDegrees(activeCamera.getViewAngle())\n const parallelScale = 1.1 * radius;\n\n let w1 = bounds[1] - bounds[0];\n let w2 = bounds[3] - bounds[2];\n let w3 = bounds[5] - bounds[4];\n w1 *= w1;\n w2 *= w2;\n w3 *= w3;\n radius = w1 + w2 + w3;\n\n // If we have just a single point, pick a radius of 1.0\n radius = radius === 0 ? 1.0 : radius;\n\n // compute the radius of the enclosing sphere\n radius = Math.sqrt(radius) * 0.5;\n\n const distance = 1.1 * radius;\n\n const viewUpToSet: Point3 =\n Math.abs(vtkMath.dot(viewUp, viewPlaneNormal)) > 0.999\n ? [-viewUp[2], viewUp[0], viewUp[1]]\n : viewUp;\n\n const focalPointToSet = this._getFocalPointForResetCamera(\n focalPoint,\n previousCamera,\n { resetPan, resetToCenter }\n );\n\n const positionToSet: Point3 = [\n focalPointToSet[0] + distance * viewPlaneNormal[0],\n focalPointToSet[1] + distance * viewPlaneNormal[1],\n focalPointToSet[2] + distance * viewPlaneNormal[2],\n ];\n\n renderer.resetCameraClippingRange(bounds);\n\n const clippingRangeToUse: Point2 = [\n -RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE,\n RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE,\n ];\n\n activeCamera.setPhysicalScale(radius);\n activeCamera.setPhysicalTranslation(\n -focalPointToSet[0],\n -focalPointToSet[1],\n -focalPointToSet[2]\n );\n\n this.setCamera({\n parallelScale: resetZoom ? parallelScale : previousCamera.parallelScale,\n focalPoint: focalPointToSet,\n position: positionToSet,\n viewAngle: 90,\n viewUp: viewUpToSet,\n clippingRange: clippingRangeToUse,\n });\n\n const modifiedCamera = _cloneDeep(this.getCamera());\n\n if (storeAsInitialCamera) {\n this.setInitialCamera(modifiedCamera);\n }\n\n const RESET_CAMERA_EVENT = {\n type: 'ResetCameraEvent',\n renderer,\n };\n\n // Here to let parallel/distributed compositing intercept\n // and do the right thing.\n renderer.invokeEvent(RESET_CAMERA_EVENT);\n\n this.triggerCameraModifiedEventIfNecessary(previousCamera, modifiedCamera);\n\n return true;\n }\n\n /**\n * Sets the provided camera as the initial camera.\n * This allows computing differences applied later as compared to the initial\n * position, for things like zoom and pan.\n * @param camera - to store as the initial value.\n */\n protected setInitialCamera(camera: ICamera): void {\n this.initialCamera = camera;\n }\n\n /**\n * Helper function to return the current canvas pan value.\n *\n * @returns a Point2 containing the current pan values\n * on the canvas,\n * computed from the current camera, where the initial pan\n * value is [0,0].\n */\n public getPan(): Point2 {\n const activeCamera = this.getVtkActiveCamera();\n const focalPoint = activeCamera.getFocalPoint() as Point3;\n\n const zero3 = this.canvasToWorld([0, 0]);\n const initialCanvasFocal = this.worldToCanvas(\n <Point3>vec3.subtract(vec3.create(), this.initialCamera.focalPoint, zero3)\n );\n const currentCanvasFocal = this.worldToCanvas(\n <Point3>vec3.subtract(vec3.create(), focalPoint, zero3)\n );\n const result = <Point2>(\n vec2.subtract(vec2.create(), initialCanvasFocal, currentCanvasFocal)\n );\n return result;\n }\n\n /**\n * Sets the canvas pan value relative to the initial view position of 0,0\n * Modifies the camera to perform the pan.\n */\n public setPan(pan: Point2, storeAsInitialCamera = false): void {\n const previousCamera = this.getCamera();\n const { focalPoint, position } = previousCamera;\n const zero3 = this.canvasToWorld([0, 0]);\n const delta2 = vec2.subtract(vec2.create(), pan, this.getPan());\n if (\n Math.abs(delta2[0]) < 1 &&\n Math.abs(delta2[1]) < 1 &&\n !storeAsInitialCamera\n ) {\n return;\n }\n const delta = vec3.subtract(\n vec3.create(),\n this.canvasToWorld(<Point2>delta2),\n zero3\n );\n const newFocal = vec3.subtract(vec3.create(), focalPoint, delta);\n const newPosition = vec3.subtract(vec3.create(), position, delta);\n this.setCamera(\n {\n ...previousCamera,\n focalPoint: newFocal as Point3,\n position: newPosition as Point3,\n },\n storeAsInitialCamera\n );\n }\n\n /**\n * Returns a current zoom level relative to the initial parallel scale\n * originally applied to the image. That is, on initial display,\n * the zoom level is 1. Computed as a function of the camera.\n */\n public getZoom(): number {\n const activeCamera = this.getVtkActiveCamera();\n const { parallelScale: initialParallelScale } = this.initialCamera;\n return initialParallelScale / activeCamera.getParallelScale();\n }\n\n /** Zooms the image using parallel scale by updating the camera value.\n * @param value - The relative parallel scale to apply. It is relative\n * to the initial offsets value.\n * @param storeAsInitialCamera - can be set to true to reset the camera\n * after applying this zoom as the initial camera. A subsequent getZoom\n * call will return \"1\", but the zoom will have been applied.\n */\n public setZoom(value: number, storeAsInitialCamera = false): void {\n const camera = this.getCamera();\n const { parallelScale: initialParallelScale } = this.initialCamera;\n const parallelScale = initialParallelScale / value;\n if (camera.parallelScale === parallelScale && !storeAsInitialCamera) {\n return;\n }\n this.setCamera(\n {\n ...camera,\n parallelScale,\n },\n storeAsInitialCamera\n );\n }\n\n /**\n * Because the focalPoint is always in the centre of the viewport,\n * we must do planar computations if the frame (image \"slice\") is to be preserved.\n * 1. Calculate the intersection of the view plane with the imageData\n * which results in points of intersection (minimum of 3, maximum of 6)\n * 2. Calculate average of the intersection points to get newFocalPoint\n * 3. Set the new focalPoint\n * @param imageData - imageData\n * @returns focalPoint\n */\n private _getFocalPointForViewPlaneReset(imageData) {\n // Todo: move some where else\n const { focalPoint, viewPlaneNormal: normal } = this.getCamera();\n const intersections = this._getViewImageDataIntersections(\n imageData,\n focalPoint,\n normal\n );\n\n let x = 0;\n let y = 0;\n let z = 0;\n\n intersections.forEach(([point_x, point_y, point_z]) => {\n x += point_x;\n y += point_y;\n z += point_z;\n });\n\n const newFocalPoint = <Point3>[\n x / intersections.length,\n y / intersections.length,\n z / intersections.length,\n ];\n // Set the focal point on the average of the intersection points\n return newFocalPoint;\n }\n\n /**\n * Gets the target output canvas for the `Viewport`.\n *\n * @returns an HTMLCanvasElement.\n */\n public getCanvas(): HTMLCanvasElement {\n return <HTMLCanvasElement>this.canvas;\n }\n /**\n * Gets the active vtkCamera for the viewport.\n *\n * @returns vtk driven camera\n */\n protected getVtkActiveCamera(): vtkCamera | vtkSlabCamera {\n const renderer = this.getRenderer();\n\n return renderer.getActiveCamera();\n }\n\n /**\n * Get the camera's current state\n * @returns The camera object.\n */\n public getCamera(): ICamera {\n const vtkCamera = this.getVtkActiveCamera();\n\n return {\n viewUp: <Point3>vtkCamera.getViewUp(),\n viewPlaneNormal: <Point3>vtkCamera.getViewPlaneNormal(),\n position: <Point3>vtkCamera.getPosition(),\n focalPoint: <Point3>vtkCamera.getFocalPoint(),\n parallelProjection: vtkCamera.getParallelProjection(),\n parallelScale: vtkCamera.getParallelScale(),\n viewAngle: vtkCamera.getViewAngle(),\n flipHorizontal: this.flipHorizontal,\n flipVertical: this.flipVertical,\n };\n }\n\n /**\n * Set the camera parameters\n * @param cameraInterface - ICamera\n * @param storeAsInitialCamera - to set the provided camera as the initial one,\n * used to compute differences for things like pan and zoom.\n */\n public setCamera(\n cameraInterface: ICamera,\n storeAsInitialCamera = false\n ): void {\n const vtkCamera = this.getVtkActiveCamera();\n const previousCamera = _cloneDeep(this.getCamera());\n const updatedCamera = Object.assign({}, previousCamera, cameraInterface);\n const {\n viewUp,\n viewPlaneNormal,\n position,\n focalPoint,\n parallelScale,\n viewAngle,\n flipHorizontal,\n flipVertical,\n clippingRange,\n } = cameraInterface;\n\n // Note: Flip camera should be two separate calls since\n // for flip, we need to flip the viewportNormal, and if\n // flipHorizontal, and flipVertical are both true, that would\n // the logic would be incorrect. So instead, we handle flip Horizontal\n // and flipVertical separately.\n if (flipHorizontal !== undefined) {\n // flip if not flipped but requested to flip OR if flipped but requested to\n // not flip\n const flipH =\n (flipHorizontal && !this.flipHorizontal) ||\n (!flipHorizontal && this.flipHorizontal);\n\n if (flipH) {\n this.flip({ flipHorizontal: flipH });\n }\n }\n\n if (flipVertical !== undefined) {\n const flipV =\n (flipVertical && !this.flipVertical) ||\n (!flipVertical && this.flipVertical);\n\n if (flipV) {\n this.flip({ flipVertical: flipV });\n }\n }\n\n if (viewUp !== undefined) {\n vtkCamera.setViewUp(viewUp);\n }\n\n if (viewPlaneNormal !== undefined) {\n vtkCamera.setDirectionOfProjection(\n -viewPlaneNormal[0],\n -viewPlaneNormal[1],\n -viewPlaneNormal[2]\n );\n }\n\n if (position !== undefined) {\n vtkCamera.setPosition(...position);\n }\n\n if (focalPoint !== undefined) {\n vtkCamera.setFocalPoint(...focalPoint);\n }\n\n if (parallelScale !== undefined) {\n vtkCamera.setParallelScale(parallelScale);\n }\n\n if (viewAngle !== undefined) {\n vtkCamera.setViewAngle(viewAngle);\n }\n\n if (clippingRange !== undefined) {\n vtkCamera.setClippingRange(clippingRange);\n }\n\n // update clippingPlanes if volume viewports\n const actorEntry = this.getDefaultActor();\n if (actorEntry?.actor?.isA('vtkVolume')) {\n this.updateClippingPlanesForActors(updatedCamera);\n }\n\n if (actorEntry?.actor?.isA('vtkImageSlice')) {\n const renderer = this.getRenderer();\n renderer.resetCameraClippingRange();\n }\n\n if (storeAsInitialCamera) {\n this.setInitialCamera(updatedCamera);\n }\n\n this.triggerCameraModifiedEventIfNecessary(\n previousCamera,\n this.getCamera()\n );\n }\n\n /**\n * Trigger camera modified event\n * @param cameraInterface - ICamera\n * @param cameraInterface - ICamera\n */\n public triggerCameraModifiedEventIfNecessary(\n previousCamera: ICamera,\n updatedCamera: ICamera\n ): void {\n if (!this._suppressCameraModifiedEvents && !this.suppressEvents) {\n const eventDetail: EventTypes.CameraModifiedEventDetail = {\n previousCamera,\n camera: updatedCamera,\n element: this.element,\n viewportId: this.id,\n renderingEngineId: this.renderingEngineId,\n rotation: this.rotation,\n };\n\n triggerEvent(this.element, Events.CAMERA_MODIFIED, eventDetail);\n }\n }\n\n /**\n * Updates the actors clipping planes orientation from the camera properties\n * @param updatedCamera - ICamera\n */\n protected updateClippingPlanesForActors(updatedCamera: ICamera): void {\n const actorEntries = this.getActors();\n actorEntries.forEach((actorEntry) => {\n // we assume that the first two clipping plane of the mapper are always\n // the 'camera' clipping. Update clipping planes only if the actor is\n // a vtkVolume\n if (!actorEntry.actor || !isImageActor(actorEntry.actor)) {\n return;\n }\n\n const mapper = actorEntry.actor.getMapper();\n const vtkPlanes = mapper.getClippingPlanes();\n\n let slabThickness = RENDERING_DEFAULTS.MINIMUM_SLAB_THICKNESS;\n if (actorEntry.slabThickness) {\n slabThickness = actorEntry.slabThickness;\n }\n\n const { viewPlaneNormal, focalPoint } = updatedCamera;\n\n this.setOrientationOfClippingPlanes(\n vtkPlanes,\n slabThickness,\n viewPlaneNormal,\n focalPoint\n );\n });\n }\n\n public setOrientationOfClippingPlanes(\n vtkPlanes: Array<vtkPlane>,\n slabThickness: number,\n viewPlaneNormal: Point3,\n focalPoint: Point3\n ): void {\n if (vtkPlanes.length < 2) {\n return;\n }\n\n const scaledDistance = <Point3>[\n viewPlaneNormal[0],\n viewPlaneNormal[1],\n viewPlaneNormal[2],\n ];\n vtkMath.multiplyScalar(scaledDistance, slabThickness);\n\n vtkPlanes[0].setNormal(viewPlaneNormal);\n const newOrigin1 = <Point3>[0, 0, 0];\n vtkMath.subtract(focalPoint, scaledDistance, newOrigin1);\n vtkPlanes[0].setOrigin(newOrigin1);\n\n vtkPlanes[1].setNormal(\n -viewPlaneNormal[0],\n -viewPlaneNormal[1],\n -viewPlaneNormal[2]\n );\n const newOrigin2 = <Point3>[0, 0, 0];\n vtkMath.add(focalPoint, scaledDistance, newOrigin2);\n vtkPlanes[1].setOrigin(newOrigin2);\n }\n\n private _getWorldDistanceViewUpAndViewRight(bounds, viewUp, viewPlaneNormal) {\n const viewUpCorners = this._getCorners(bounds);\n const viewRightCorners = this._getCorners(bounds);\n\n const viewRight = vec3.cross(vec3.create(), viewUp, viewPlaneNormal);\n\n let transform = vtkMatrixBuilder\n .buildFromDegree()\n .identity()\n .rotateFromDirections(viewUp, [1, 0, 0]);\n\n viewUpCorners.forEach((pt) => transform.apply(pt));\n\n // range is now maximum X distance\n let minY = Infinity;\n let maxY = -Infinity;\n for (let i = 0; i < 8; i++) {\n const y = viewUpCorners[i][0];\n if (y > maxY) {\n maxY = y;\n }\n if (y < minY) {\n minY = y;\n }\n }\n\n transform = vtkMatrixBuilder\n .buildFromDegree()\n .identity()\n .rotateFromDirections(\n [viewRight[0], viewRight[1], viewRight[2]],\n [1, 0, 0]\n );\n\n viewRightCorners.forEach((pt) => transform.apply(pt));\n\n // range is now maximum Y distance\n let minX = Infinity;\n let maxX = -Infinity;\n for (let i = 0; i < 8; i++) {\n const x = viewRightCorners[i][0];\n if (x > maxX) {\n maxX = x;\n }\n if (x < minX) {\n minX = x;\n }\n }\n\n return { widthWorld: maxX - minX, heightWorld: maxY - minY };\n }\n\n _getCorners(bounds: Array<number>): Array<number>[] {\n return [\n [bounds[0], bounds[2], bounds[4]],\n [bounds[0], bounds[2], bounds[5]],\n [bounds[0], bounds[3], bounds[4]],\n [bounds[0], bounds[3], bounds[5]],\n [bounds[1], bounds[2], bounds[4]],\n [bounds[1], bounds[2], bounds[5]],\n [bounds[1], bounds[3], bounds[4]],\n [bounds[1], bounds[3], bounds[5]],\n ];\n }\n\n _getFocalPointForResetCamera(\n centeredFocalPoint: Point3,\n previousCamera: ICamera,\n { resetPan = true, resetToCenter = true }\n ): Point3 {\n if (resetToCenter && resetPan) {\n return centeredFocalPoint;\n }\n\n if (resetToCenter && !resetPan) {\n return hasNaNValues(previousCamera.focalPoint)\n ? centeredFocalPoint\n : previousCamera.focalPoint;\n }\n\n if (!resetToCenter && resetPan) {\n // this is an interesting case that means the reset camera should not\n // change the slice (default behavior is to go to the center of the\n // image), and rather just reset the pan on the slice that is currently\n // being viewed\n const oldCamera = previousCamera;\n const oldFocalPoint = oldCamera.focalPoint;\n const oldViewPlaneNormal = oldCamera.viewPlaneNormal;\n\n const vectorFromOldFocalPointToCenteredFocalPoint = vec3.subtract(\n vec3.create(),\n centeredFocalPoint,\n oldFocalPoint\n );\n\n const distanceFromOldFocalPointToCenteredFocalPoint = vec3.dot(\n vectorFromOldFocalPointToCenteredFocalPoint,\n oldViewPlaneNormal\n );\n\n const newFocalPoint = vec3.scaleAndAdd(\n vec3.create(),\n centeredFocalPoint,\n oldViewPlaneNormal,\n -1 * distanceFromOldFocalPointToCenteredFocalPoint\n );\n\n return [newFocalPoint[0], newFocalPoint[1], newFocalPoint[2]];\n }\n\n if (!resetPan && !resetToCenter) {\n // this means the reset camera should not change the slice and should not\n // touch the pan either.\n return hasNaNValues(previousCamera.focalPoint)\n ? centeredFocalPoint\n : previousCamera.focalPoint;\n }\n }\n\n /**\n * Determines whether or not the 3D point position is inside the boundaries of the 3D imageData.\n * @param point - 3D coordinate\n * @param bounds - Bounds of the image\n * @returns boolean\n */\n _isInBounds(point: Point3, bounds: number[]): boolean {\n const [xMin, xMax, yMin, yMax, zMin, zMax] = bounds;\n const [x, y, z] = point;\n if (x < xMin || x > xMax || y < yMin || y > yMax || z < zMin || z > zMax) {\n return false;\n }\n return true;\n }\n\n /**\n * Returns a list of edges for the imageData bounds, which are\n * the cube edges in the case of volumeViewport edges.\n * p1: front, bottom, left\n * p2: front, top, left\n * p3: back, bottom, left\n * p4: back, top, left\n * p5: front, bottom, right\n * p6: front, top, right\n * p7: back, bottom, right\n * p8: back, top, right\n * @param bounds - Bounds of the renderer\n * @returns Edges of the containing bounds\n */\n _getEdges(bounds: Array<number>): Array<[number[], number[]]> {\n const [p1, p2, p3, p4, p5, p6, p7, p8] = this._getCorners(bounds);\n return [\n [p1, p2],\n [p1, p5],\n [p1, p3],\n [p2, p4],\n [p2, p6],\n [p3, p4],\n [p3, p7],\n [p4, p8],\n [p5, p7],\n [p5, p6],\n [p6, p8],\n [p7, p8],\n ];\n }\n}\n\nexport default Viewport;\n","import { Point3 } from '../types';\n\n/**\n * Converts `vtkVolumeActor` bounds to corners in world space.\n *\n * @param volumeActor - The `vtkVolumeActor`.\n *\n * @returns An array of the corners of the `volumeActor` in world space.\n */\nexport default function getVolumeActorCorners(volumeActor): Array<Point3> {\n const imageData = volumeActor.getMapper().getInputData();\n const bounds = imageData.extentToBounds(imageData.getExtent());\n\n return [\n [bounds[0], bounds[2], bounds[4]],\n [bounds[0], bounds[2], bounds[5]],\n [bounds[0], bounds[3], bounds[4]],\n [bounds[0], bounds[3], bounds[5]],\n [bounds[1], bounds[2], bounds[4]],\n [bounds[1], bounds[2], bounds[5]],\n [bounds[1], bounds[3], bounds[4]],\n [bounds[1], bounds[3], bounds[5]],\n ];\n}\n","import vtkMatrixBuilder from '@kitware/vtk.js/Common/Core/MatrixBuilder';\nimport getVolumeActorCorners from './getVolumeActorCorners';\nimport type { VolumeActor, Point3, ActorSliceRange } from '../types';\n\n/**\n * Given a `vtkVolumeActor`, and a normal direction,\n * calculate the range of slices in the focal normal direction that encapsulate\n * the volume. Also project the `focalPoint` onto this range.\n *\n * @param volumeActor - The `vtkVolumeActor`.\n * @param viewPlaneNormal - The normal to the camera view.\n * @param focalPoint - The focal point of the camera.\n *\n * @returns an object containing the `min`, `max` and `current`\n * positions in the normal direction.\n */\nexport default function getSliceRange(\n volumeActor: VolumeActor,\n viewPlaneNormal: Point3,\n focalPoint: Point3\n): ActorSliceRange {\n const corners = getVolumeActorCorners(volumeActor);\n\n // Get rotation matrix from normal to +X (since bounds is aligned to XYZ)\n const transform = vtkMatrixBuilder\n .buildFromDegree()\n .identity()\n .rotateFromDirections(viewPlaneNormal, [1, 0, 0]);\n\n corners.forEach((pt) => transform.apply(pt));\n\n const transformedFocalPoint = [...focalPoint];\n\n transform.apply(transformedFocalPoint);\n\n const currentSlice = transformedFocalPoint[0];\n\n // range is now maximum X distance\n let minX = Infinity;\n let maxX = -Infinity;\n for (let i = 0; i < 8; i++) {\n const x = corners[i][0];\n if (x > maxX) {\n maxX = x;\n }\n if (x < minX) {\n minX = x;\n }\n }\n\n return {\n min: minX,\n max: maxX,\n current: currentSlice,\n actor: volumeActor,\n viewPlaneNormal,\n focalPoint,\n };\n}\n","import { vec3 } from 'gl-matrix';\nimport { IImageVolume, Point3 } from '../types';\n\n/**\n * Given an `imageVolume` and a normal direction (`viewPlaneNormal`), calculates\n * the spacing between voxels in the normal direction. If (`viewPlaneNormal`) is\n * parallel to one of the directions you will obtain the spacing in that direction.\n * Otherwise each of the `imageVolume`'s directions are projected onto the volume,\n * so that you obtain a spacing of the order of \"seeing a new set of voxels if the camera where to dolly\".\n *\n * @param imageVolume - The image volume to calculate the spacing in the normal direction.\n * @param viewPlaneNormal - The normal direction of the view plane.\n * @returns\n */\nexport default function getSpacingInNormalDirection(\n imageVolume: IImageVolume,\n viewPlaneNormal: Point3\n): number {\n const { direction, spacing } = imageVolume;\n\n // Calculate size of spacing vector in normal direction\n const iVector = direction.slice(0, 3) as Point3;\n const jVector = direction.slice(3, 6) as Point3;\n const kVector = direction.slice(6, 9) as Point3;\n\n const dotProducts = [\n vec3.dot(iVector, <vec3>viewPlaneNormal),\n vec3.dot(jVector, <vec3>viewPlaneNormal),\n vec3.dot(kVector, <vec3>viewPlaneNormal),\n ];\n\n const projectedSpacing = vec3.create();\n\n vec3.set(\n projectedSpacing,\n dotProducts[0] * spacing[0],\n dotProducts[1] * spacing[1],\n dotProducts[2] * spacing[2]\n );\n\n const spacingInNormalDirection = vec3.length(projectedSpacing);\n\n return spacingInNormalDirection;\n}\n","import cache from '../cache/cache';\n// import type { VolumeViewport } from '../RenderingEngine'\nimport { ICamera, IImageVolume, IVolumeViewport } from '../types';\nimport getSpacingInNormalDirection from './getSpacingInNormalDirection';\n\n/**\n * Given a volume viewport and camera, find the target volume.\n * The imageVolume is retrieved from cache for the specified targetVolumeId or\n * in case it is not provided, it chooses the volumeId on the viewport (there\n * might be more than one in case of fusion) that has the finest resolution in the\n * direction of view (normal).\n *\n * @param viewport - volume viewport\n * @param camera - current camera\n * @param targetVolumeId - If a target volumeId is given that volume\n * is forced to be used.\n *\n * @returns An object containing the imageVolume and spacingInNormalDirection.\n *\n */\nexport default function getTargetVolumeAndSpacingInNormalDir(\n viewport: IVolumeViewport,\n camera: ICamera,\n targetVolumeId?: string\n): {\n imageVolume: IImageVolume;\n spacingInNormalDirection: number;\n} {\n const { viewPlaneNormal } = camera;\n const volumeActors = viewport.getActors();\n\n if (!volumeActors || !volumeActors.length) {\n return { spacingInNormalDirection: null, imageVolume: null };\n }\n const numVolumeActors = volumeActors.length;\n\n const imageVolumes = volumeActors.map((va) => {\n // prefer the referenceUID if it is set, since it can be a derived actor\n // and the uid does not necessarily match the volumeId\n const uid = va.referenceId ?? va.uid;\n return cache.getVolume(uid);\n });\n\n // If a volumeId is defined, set that volume as the target\n if (targetVolumeId) {\n const imageVolume = imageVolumes.find(\n (iv) => iv.volumeId === targetVolumeId\n );\n\n const spacingInNormalDirection = getSpacingInNormalDirection(\n imageVolume,\n viewPlaneNormal\n );\n\n return { imageVolume, spacingInNormalDirection };\n }\n\n // Fetch volume actor with finest resolution in direction of projection.\n const smallest = {\n spacingInNormalDirection: Infinity,\n imageVolume: null,\n };\n\n for (let i = 0; i < numVolumeActors; i++) {\n const imageVolume = imageVolumes[i];\n\n const spacingInNormalDirection = getSpacingInNormalDirection(\n imageVolume,\n viewPlaneNormal\n );\n\n if (spacingInNormalDirection < smallest.spacingInNormalDirection) {\n smallest.spacingInNormalDirection = spacingInNormalDirection;\n smallest.imageVolume = imageVolume;\n }\n }\n\n return smallest;\n}\n","import { ImageSliceData, IVolumeViewport, VolumeActor } from '../types';\nimport getSliceRange from './getSliceRange';\nimport getTargetVolumeAndSpacingInNormalDir from './getTargetVolumeAndSpacingInNormalDir';\n\n/**\n * It calculates the number of slices and the current slice index for a given\n * Volume viewport\n * @param viewport - volume viewport\n * @returns An object with two properties: numberOfSlices and imageIndex.\n */\nfunction getImageSliceDataForVolumeViewport(\n viewport: IVolumeViewport\n): ImageSliceData {\n const camera = viewport.getCamera();\n\n const { spacingInNormalDirection, imageVolume } =\n getTargetVolumeAndSpacingInNormalDir(viewport, camera);\n\n if (!imageVolume) {\n return;\n }\n\n const { viewPlaneNormal, focalPoint } = camera;\n\n const actorEntry = viewport\n .getActors()\n .find(\n (a) =>\n a.referenceId === imageVolume.volumeId || a.uid === imageVolume.volumeId\n );\n\n if (!actorEntry) {\n console.warn('No actor found for with actorUID of', imageVolume.volumeId);\n }\n\n const volumeActor = actorEntry.actor as VolumeActor;\n const sliceRange = getSliceRange(volumeActor, viewPlaneNormal, focalPoint);\n\n const { min, max, current } = sliceRange;\n\n // calculate number of steps from min to max with current normal spacing in direction\n const numberOfSlices = Math.round((max - min) / spacingInNormalDirection) + 1;\n\n // calculate the imageIndex based on min, max, current\n let imageIndex = ((current - min) / (max - min)) * numberOfSlices;\n imageIndex = Math.floor(imageIndex);\n\n // Clamp imageIndex\n if (imageIndex > numberOfSlices - 1) {\n imageIndex = numberOfSlices - 1;\n } else if (imageIndex < 0) {\n imageIndex = 0;\n }\n\n return {\n numberOfSlices,\n imageIndex,\n };\n}\n\nexport default getImageSliceDataForVolumeViewport;\n","import renderingEngineCache from './renderingEngineCache';\nimport type { IRenderingEngine } from '../types';\n\n/**\n * Method to retrieve a RenderingEngine by its unique identifier.\n *\n * @example\n * How to get a RenderingEngine that was created earlier:\n * ```javascript\n * import { RenderingEngine, getRenderingEngine } from 'vtkjs-viewport';\n *\n * const renderingEngine = new RenderingEngine('my-engine');\n *\n * // getting reference to rendering engine later...\n * const renderingEngine = getRenderingEngine('my-engine');\n * ```\n *\n * @param id - The identifier that was used to create the RenderingEngine\n * @returns the matching RenderingEngine, or `undefined` if there is no match\n * @public\n */\nexport function getRenderingEngine(id: string): IRenderingEngine | undefined {\n return renderingEngineCache.get(id);\n}\n\n/**\n * Get all the rendering engines that are currently registered\n * @returns An array of rendering engines.\n */\nexport function getRenderingEngines(): IRenderingEngine[] | undefined {\n return renderingEngineCache.getAll();\n}\n\nexport default getRenderingEngine;\n","import {\n getImageSliceDataForVolumeViewport,\n triggerEvent,\n} from '../../utilities';\nimport { EventTypes } from '../../types';\nimport { Events } from '../../enums';\nimport { getRenderingEngine } from '../getRenderingEngine';\nimport BaseVolumeViewport from '../BaseVolumeViewport';\n\n// Keeping track of previous imageIndex for each viewportId\ntype VolumeImageState = Record<string, number>;\n\nconst state: VolumeImageState = {};\n\nexport function resetVolumeNewImageState(viewportId: string): void {\n if (state[viewportId] !== undefined) {\n delete state[viewportId];\n }\n}\n\n/**\n * It captures the camera modified event and with the camera focal point and viewPlaneNomad\n * it calculates the image index in the view direction. Finally it triggers\n * a VOLUME_NEW_IMAGE event with the image index.\n *\n * @internal\n *\n * @param cameraEvent - The camera modified event\n * @param viewportImageData - The image data of the viewport\n */\nfunction volumeNewImageEventDispatcher(\n cameraEvent: EventTypes.CameraModifiedEvent\n): void {\n const { renderingEngineId, viewportId } = cameraEvent.detail;\n const renderingEngine = getRenderingEngine(renderingEngineId);\n const viewport = renderingEngine.getViewport(viewportId);\n\n if (!(viewport instanceof BaseVolumeViewport)) {\n throw new Error(\n `volumeNewImageEventDispatcher: viewport is not a BaseVolumeViewport`\n );\n }\n\n if (state[viewport.id] === undefined) {\n state[viewport.id] = 0;\n }\n\n const { numberOfSlices, imageIndex } =\n getImageSliceDataForVolumeViewport(viewport);\n\n if (state[viewport.id] === imageIndex) {\n return;\n }\n\n state[viewport.id] = imageIndex;\n\n const eventDetail: EventTypes.VolumeNewImageEventDetail = {\n imageIndex,\n viewportId,\n renderingEngineId,\n numberOfSlices,\n };\n\n triggerEvent(viewport.element, Events.VOLUME_NEW_IMAGE, eventDetail);\n}\n\nexport default volumeNewImageEventDispatcher;\n","import macro from '@kitware/vtk.js/macros';\nimport vtkCamera from '@kitware/vtk.js/Rendering/Core/Camera';\nimport { vec3, mat4 } from 'gl-matrix';\nimport vtkMath from '@kitware/vtk.js/Common/Core/Math';\n\n/**\n * vtkSlabCamera - A derived class of the core vtkCamera class\n *\n * This customization is necesssary because when we do coordinate transformations\n * we need to set the cRange between [d, d + 0.1],\n * where d is distance between the camera position and the focal point.\n * While when we render we set to the clippingRange [0.01, d * 2],\n * where d is the calculated from the bounds of all the actors.\n *\n * @param {*} publicAPI The public API to extend\n * @param {*} model The private model to extend.\n */\nfunction vtkSlabCamera(publicAPI, model) {\n model.classHierarchy.push('vtkSlabCamera');\n\n // Set up private variables and methods\n const tmpMatrix = mat4.identity(new Float64Array(16));\n const tmpvec1 = new Float64Array(3);\n\n /**\n * getProjectionMatrix - A fork of vtkCamera's getProjectionMatrix method.\n * This fork performs most of the same actions, but define crange around\n * model.distance when doing coordinate transformations.\n */\n publicAPI.getProjectionMatrix = (aspect, nearz, farz) => {\n const result = mat4.create();\n\n if (model.projectionMatrix) {\n const scale = 1 / model.physicalScale;\n vec3.set(tmpvec1, scale, scale, scale);\n\n mat4.copy(result, model.projectionMatrix);\n mat4.scale(result, result, tmpvec1);\n mat4.transpose(result, result);\n return result;\n }\n\n mat4.identity(tmpMatrix);\n\n let cRange0 = model.clippingRange[0];\n let cRange1 = model.clippingRange[1];\n if (model.isPerformingCoordinateTransformation) {\n /**\n * NOTE: this is necessary because we want the coordinate transformation\n * respect to the view plane (plane orthogonal to the camera and passing to\n * the focal point).\n *\n * When vtk.js computes the coordinate transformations, it simply uses the\n * camera matrix (no ray casting).\n *\n * However for the volume viewport the clipping range is set to be\n * (-RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE, RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE).\n * The clipping range is used in the camera method getProjectionMatrix().\n * The projection matrix is used then for viewToWorld/worldToView methods of\n * the renderer. This means that vkt.js will not return the coordinates of\n * the point on the view plane (i.e. the depth coordinate will corresponded\n * to the focal point).\n *\n * Therefore the clipping range has to be set to (distance, distance + 0.01),\n * where now distance is the distance between the camera position and focal\n * point. This is done internally, in our camera customization when the flag\n * isPerformingCoordinateTransformation is set to true.\n */\n cRange0 = model.distance;\n cRange1 = model.distance + 0.1;\n }\n\n const cWidth = cRange1 - cRange0;\n const cRange = [\n cRange0 + ((nearz + 1) * cWidth) / 2.0,\n cRange0 + ((farz + 1) * cWidth) / 2.0,\n ];\n\n if (model.parallelProjection) {\n // set up a rectangular parallelipiped\n const width = model.parallelScale * aspect;\n const height = model.parallelScale;\n\n const xmin = (model.windowCenter[0] - 1.0) * width;\n const xmax = (model.windowCenter[0] + 1.0) * width;\n const ymin = (model.windowCenter[1] - 1.0) * height;\n const ymax = (model.windowCenter[1] + 1.0) * height;\n\n mat4.ortho(tmpMatrix, xmin, xmax, ymin, ymax, cRange[0], cRange[1]);\n mat4.transpose(tmpMatrix, tmpMatrix);\n } else if (model.useOffAxisProjection) {\n throw new Error('Off-Axis projection is not supported at this time');\n } else {\n const tmp = Math.tan(vtkMath.radiansFromDegrees(model.viewAngle) / 2.0);\n let width;\n let height;\n if (model.useHorizontalViewAngle === true) {\n width = cRange0 * tmp;\n height = (cRange0 * tmp) / aspect;\n } else {\n width = cRange0 * tmp * aspect;\n height = cRange0 * tmp;\n }\n\n const xmin = (model.windowCenter[0] - 1.0) * width;\n const xmax = (model.windowCenter[0] + 1.0) * width;\n const ymin = (model.windowCenter[1] - 1.0) * height;\n const ymax = (model.windowCenter[1] + 1.0) * height;\n const znear = cRange[0];\n const zfar = cRange[1];\n\n tmpMatrix[0] = (2.0 * znear) / (xmax - xmin);\n tmpMatrix[5] = (2.0 * znear) / (ymax - ymin);\n tmpMatrix[2] = (xmin + xmax) / (xmax - xmin);\n tmpMatrix[6] = (ymin + ymax) / (ymax - ymin);\n tmpMatrix[10] = -(znear + zfar) / (zfar - znear);\n tmpMatrix[14] = -1.0;\n tmpMatrix[11] = (-2.0 * znear * zfar) / (zfar - znear);\n tmpMatrix[15] = 0.0;\n }\n\n mat4.copy(result, tmpMatrix);\n\n return result;\n };\n}\n\n// ----------------------------------------------------------------------------\n// Object factory\n// ----------------------------------------------------------------------------\n\n// ----------------------------------------------------------------------------\n\nconst DEFAULT_VALUES = {\n isPerformingCoordinateTransformation: false,\n};\n\nexport function extend(publicAPI, model, initialValues = {}) {\n Object.assign(model, DEFAULT_VALUES, initialValues);\n\n vtkCamera.extend(publicAPI, model, initialValues);\n\n macro.setGet(publicAPI, model, ['isPerformingCoordinateTransformation']);\n\n // Object methods\n vtkSlabCamera(publicAPI, model);\n}\n\n// ----------------------------------------------------------------------------\n\nexport const newInstance = macro.newInstance(extend, 'vtkSlabCamera');\n\n// ----------------------------------------------------------------------------\n\nexport default { newInstance, extend };\n","function e(e,t,r,n){return new(r||(r=Promise))((function(o,a){function i(e){try{d(n.next(e))}catch(e){a(e)}}function c(e){try{d(n.throw(e))}catch(e){a(e)}}function d(e){var t;e.done?o(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(i,c)}d((n=n.apply(e,t||[])).next())}))}const t=[\"geforce 320m\",\"geforce 8600\",\"geforce 8600m gt\",\"geforce 8800 gs\",\"geforce 8800 gt\",\"geforce 9400\",\"geforce 9400m g\",\"geforce 9400m\",\"geforce 9600m gt\",\"geforce 9600m\",\"geforce fx go5200\",\"geforce gt 120\",\"geforce gt 130\",\"geforce gt 330m\",\"geforce gtx 285\",\"google swiftshader\",\"intel g41\",\"intel g45\",\"intel gma 4500mhd\",\"intel gma x3100\",\"intel hd 3000\",\"intel q45\",\"legacy\",\"mali-2\",\"mali-3\",\"mali-4\",\"quadro fx 1500\",\"quadro fx 4\",\"quadro fx 5\",\"radeon hd 2400\",\"radeon hd 2600\",\"radeon hd 4670\",\"radeon hd 4850\",\"radeon hd 4870\",\"radeon hd 5670\",\"radeon hd 5750\",\"radeon hd 6290\",\"radeon hd 6300\",\"radeon hd 6310\",\"radeon hd 6320\",\"radeon hd 6490m\",\"radeon hd 6630m\",\"radeon hd 6750m\",\"radeon hd 6770m\",\"radeon hd 6970m\",\"sgx 543\",\"sgx543\"];function r(e){return e=e.toLowerCase().replace(/^angle ?\\((.+)\\)*$/,\"$1\").replace(/\\s(\\d{1,2}gb|direct3d.+$)|\\(r\\)| \\([^)]+\\)$/g,\"\").replace(/(?:vulkan|opengl) \\d+\\.\\d+(?:\\.\\d+)?(?: \\((.*)\\))?/,\"$1\")}const n=\"undefined\"==typeof window,o=(()=>{if(n)return;const{userAgent:e,platform:t,maxTouchPoints:r}=window.navigator,o=/(iphone|ipod|ipad)/i.test(e),a=\"iPad\"===t||\"MacIntel\"===t&&r>0&&!window.MSStream;return{isIpad:a,isMobile:/android/i.test(e)||o||a,isSafari12:/Version\\/12.+Safari/.test(e)}})();function a(e,t,r){if(!r)return[t];const n=function(e){const t=\"\\n precision highp float;\\n attribute vec3 aPosition;\\n varying float vvv;\\n void main() {\\n vvv = 0.31622776601683794;\\n gl_Position = vec4(aPosition, 1.0);\\n }\\n \",r=\"\\n precision highp float;\\n varying float vvv;\\n void main() {\\n vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * vvv;\\n enc = fract(enc);\\n enc -= enc.yzww * vec4(1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0, 0.0);\\n gl_FragColor = enc;\\n }\\n \",n=e.createShader(35633),o=e.createShader(35632),a=e.createProgram();if(!(o&&n&&a))return;e.shaderSource(n,t),e.shaderSource(o,r),e.compileShader(n),e.compileShader(o),e.attachShader(a,n),e.attachShader(a,o),e.linkProgram(a),e.detachShader(a,n),e.detachShader(a,o),e.deleteShader(n),e.deleteShader(o),e.useProgram(a);const i=e.createBuffer();e.bindBuffer(34962,i),e.bufferData(34962,new Float32Array([-1,-1,0,3,-1,0,-1,3,0]),35044);const c=e.getAttribLocation(a,\"aPosition\");e.vertexAttribPointer(c,3,5126,!1,0,0),e.enableVertexAttribArray(c),e.clearColor(1,1,1,1),e.clear(16384),e.viewport(0,0,1,1),e.drawArrays(4,0,3);const d=new Uint8Array(4);return e.readPixels(0,0,1,1,6408,5121,d),e.deleteProgram(a),e.deleteBuffer(i),d.join(\"\")}(e),a=\"801621810\",i=\"8016218135\",c=\"80162181161\",d=(null==o?void 0:o.isIpad)?[[\"a7\",c,12],[\"a8\",i,15],[\"a8x\",i,15],[\"a9\",i,15],[\"a9x\",i,15],[\"a10\",i,15],[\"a10x\",i,15],[\"a12\",a,15],[\"a12x\",a,15],[\"a12z\",a,15],[\"a14\",a,15],[\"m1\",a,15]]:[[\"a7\",c,12],[\"a8\",i,12],[\"a9\",i,15],[\"a10\",i,15],[\"a11\",a,15],[\"a12\",a,15],[\"a13\",a,15],[\"a14\",a,15]];let l;\"80162181255\"===n?l=d.filter((([,,e])=>e>=14)):(l=d.filter((([,e])=>e===n)),l.length||(l=d));return l.map((([e])=>`apple ${e} gpu`))}const i=[],c=[];function d(e,t){if(e===t)return 0;const r=e;e.length>t.length&&(e=t,t=r);let n=e.length,o=t.length;for(;n>0&&e.charCodeAt(~-n)===t.charCodeAt(~-o);)n--,o--;let a,d=0;for(;d<n&&e.charCodeAt(d)===t.charCodeAt(d);)d++;if(n-=d,o-=d,0===n)return o;let l,s,f=0,u=0,h=0;for(;u<n;)c[u]=e.charCodeAt(d+u),i[u]=++u;for(;h<o;)for(a=t.charCodeAt(d+h),l=h++,f=h,u=0;u<n;u++)s=a===c[u]?l:l+1,l=i[u],f=i[u]=l>f?s>f?f+1:s:s>l?l+1:s;return f}function l(e){return null!=e}class s extends Error{constructor(e){super(e),Object.setPrototypeOf(this,new.target.prototype)}}const f=({mobileTiers:i=[0,15,30,60],desktopTiers:c=[0,15,30,60],override:f={},glContext:u,failIfMajorPerformanceCaveat:h=!1,benchmarksURL:g=\"https://unpkg.com/detect-gpu@4.0.45/dist/benchmarks\"}={})=>e(void 0,void 0,void 0,(function*(){const p={};if(n)return{tier:0,type:\"SSR\"};const{isIpad:m=!!(null==o?void 0:o.isIpad),isMobile:v=!!(null==o?void 0:o.isMobile),screenSize:w=window.screen,loadBenchmarks:x=(t=>e(void 0,void 0,void 0,(function*(){const e=yield fetch(`${g}/${t}`).then((e=>e.json()));if(parseInt(e.shift().split(\".\")[0],10)<4)throw new s(\"Detect GPU benchmark data is out of date. Please update to version 4x\");return e})))}=f;let{renderer:A}=f;const P=(e,t,r,n,o)=>({device:o,fps:n,gpu:r,isMobile:v,tier:e,type:t});let b,S=\"\";if(A)A=r(A),b=[A];else{const e=u||function(e,t=!1){const r={alpha:!1,antialias:!1,depth:!1,failIfMajorPerformanceCaveat:t,powerPreference:\"high-performance\",stencil:!1};e&&delete r.powerPreference;const n=window.document.createElement(\"canvas\"),o=n.getContext(\"webgl\",r)||n.getContext(\"experimental-webgl\",r);return null!=o?o:void 0}(null==o?void 0:o.isSafari12,h);if(!e)return P(0,\"WEBGL_UNSUPPORTED\");const t=e.getExtension(\"WEBGL_debug_renderer_info\");if(t&&(A=e.getParameter(t.UNMASKED_RENDERER_WEBGL)),!A)return P(1,\"FALLBACK\");S=A,A=r(A),b=function(e,t,r){return\"apple gpu\"===t?a(e,t,r):[t]}(e,A,v)}const y=(yield Promise.all(b.map((function(t){var r;return e(this,void 0,void 0,(function*(){const e=(e=>{const t=v?[\"adreno\",\"apple\",\"mali-t\",\"mali\",\"nvidia\",\"powervr\"]:[\"intel\",\"apple\",\"amd\",\"radeon\",\"nvidia\",\"geforce\"];for(const r of t)if(e.includes(r))return r})(t);if(!e)return;const n=`${v?\"m\":\"d\"}-${e}${m?\"-ipad\":\"\"}.json`,o=p[n]=null!==(r=p[n])&&void 0!==r?r:x(n);let a;try{a=yield o}catch(e){if(e instanceof s)throw e;return}const i=function(e){var t;const r=(e=e.replace(/\\([^)]+\\)/,\"\")).match(/\\d+/)||e.match(/(\\W|^)([A-Za-z]{1,3})(\\W|$)/g);return null!==(t=null==r?void 0:r.join(\"\").replace(/\\W|amd/g,\"\"))&&void 0!==t?t:\"\"}(t);let c=a.filter((([,e])=>e===i));c.length||(c=a.filter((([e])=>e.includes(t))));const l=c.length;if(0===l)return;let f,[u,,,h]=l>1?c.map((e=>[e,d(t,e[0])])).sort((([,e],[,t])=>e-t))[0][0]:c[0],g=Number.MAX_VALUE;const{devicePixelRatio:A}=window,P=w.width*A*w.height*A;for(const e of h){const[t,r]=e,n=t*r,o=Math.abs(P-n);o<g&&(g=o,f=e)}if(!f)return;const[,,b,S]=f;return[g,b,u,S]}))})))).filter(l).sort((([e=Number.MAX_VALUE,t],[r=Number.MAX_VALUE,n])=>e===r?t-n:e-r));if(!y.length){const e=t.find((e=>A.includes(e)));return e?P(0,\"BLOCKLISTED\",e):P(1,\"FALLBACK\",`${A} (${S})`)}const[,C,E,L]=y[0];if(-1===C)return P(0,\"BLOCKLISTED\",E,C,L);const M=v?i:c;let $=0;for(let e=0;e<M.length;e++)C>=M[e]&&($=e);return P($,\"BENCHMARK\",E,C,L)}));export{f as getGPUTier};\n//# sourceMappingURL=detect-gpu.esm.js.map\n","import { getGPUTier } from 'detect-gpu';\n\nlet csRenderInitialized = false;\nlet useCPURendering = false;\n\n// https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/By_example/Detect_WebGL\nfunction hasActiveWebGLContext() {\n // Create canvas element. The canvas is not added to the\n // document itself, so it is never displayed in the\n // browser window.\n const canvas = document.createElement('canvas');\n // Get WebGLRenderingContext from canvas element.\n const gl =\n canvas.getContext('webgl') || canvas.getContext('experimental-webgl');\n\n // Report the result.\n if (gl && gl instanceof WebGLRenderingContext) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Initialize the cornerstone-core. If the browser has a webgl context and\n * the detected gpu (by detect-gpu library) indicates the GPU is not low end we\n * will use webgl GPU rendering. Otherwise we will use cpu rendering.\n *\n * @param defaultConfiguration - A configuration object\n * @returns A promise that resolves to true cornerstone has been initialized successfully.\n * @category Initialization\n */\nasync function init(defaultConfiguration = {}): Promise<boolean> {\n if (csRenderInitialized) {\n return csRenderInitialized;\n }\n\n // detectGPU\n const hasWebGLContext = hasActiveWebGLContext();\n if (!hasWebGLContext) {\n useCPURendering = true;\n console.log('CornerstoneRender: GPU not detected, using CPU rendering');\n } else {\n const gpuTier = await getGPUTier();\n console.log(\n 'CornerstoneRender: Using detect-gpu to get the GPU benchmark:',\n gpuTier\n );\n if (gpuTier.tier < 1) {\n console.log(\n 'CornerstoneRender: GPU is not powerful enough, using CPU rendering'\n );\n useCPURendering = true;\n } else {\n console.log('CornerstoneRender: using GPU rendering');\n }\n }\n csRenderInitialized = true;\n return csRenderInitialized;\n}\n\n/**\n * It sets the useCPURenderingOnlyForDebugOrTests variable to the status value.\n * This only should be used for debugging or tests. DO NOT USE IT IF YOU ARE NOT\n * SURE WHAT YOU ARE DOING.\n * @param status - boolean\n * @category Initialization\n *\n */\nfunction setUseCPURendering(status: boolean): void {\n useCPURendering = status;\n csRenderInitialized = true;\n}\n\n/**\n * Resets the cornerstone-core init state if it has been manually\n * initialized to force use the cpu rendering (e.g., for tests)\n * @category Initialization\n *\n */\nfunction resetUseCPURendering() {\n useCPURendering = !hasActiveWebGLContext();\n}\n\n/**\n * Returns whether or not we are using CPU rendering.\n * @returns true if we are using CPU rendering.\n * @category Initialization\n *\n */\nfunction getShouldUseCPURendering(): boolean {\n return useCPURendering;\n}\n\n/**\n *\n * Returns whether or not cornerstone-core has been initialized.\n * @returns true if the cornerstone render has been initialized.\n * @category Initialization\n *\n */\nfunction isCornerstoneInitialized(): boolean {\n return csRenderInitialized;\n}\n\nexport {\n init,\n getShouldUseCPURendering,\n isCornerstoneInitialized,\n setUseCPURendering,\n resetUseCPURendering,\n};\n","import vtkVolume from '@kitware/vtk.js/Rendering/Core/Volume';\n\nimport cache from '../cache';\nimport ViewportType from '../enums/ViewportType';\nimport Viewport from './Viewport';\nimport { createVolumeActor } from './helpers';\nimport volumeNewImageEventDispatcher, {\n resetVolumeNewImageState,\n} from './helpers/volumeNewImageEventDispatcher';\nimport { loadVolume } from '../volumeLoader';\nimport vtkSlabCamera from './vtkClasses/vtkSlabCamera';\nimport { getShouldUseCPURendering } from '../init';\nimport type {\n Point2,\n Point3,\n IImageData,\n IVolumeInput,\n ActorEntry,\n FlipDirection,\n VolumeViewportProperties,\n} from '../types';\nimport type { ViewportInput } from '../types/IViewport';\nimport type IVolumeViewport from '../types/IVolumeViewport';\nimport { Events, BlendModes, OrientationAxis } from '../enums';\nimport eventTarget from '../eventTarget';\nimport { imageIdToURI, triggerEvent } from '../utilities';\nimport type { vtkSlabCamera as vtkSlabCameraType } from './vtkClasses/vtkSlabCamera';\nimport { VoiModifiedEventDetail } from '../types/EventTypes';\n\n/**\n * Abstract base class for volume viewports. VolumeViewports are used to render\n * 3D volumes from which various orientations can be viewed. Since VolumeViewports\n * use SharedVolumeMappers behind the scene, memory footprint of visualizations\n * of the same volume in different orientations is very small.\n *\n * For setting volumes on viewports you need to use {@link addVolumesToViewports}\n * which will add volumes to the specified viewports.\n */\nabstract class BaseVolumeViewport extends Viewport implements IVolumeViewport {\n useCPURendering = false;\n private _FrameOfReferenceUID: string;\n\n constructor(props: ViewportInput) {\n super(props);\n\n this.useCPURendering = getShouldUseCPURendering();\n\n if (this.useCPURendering) {\n throw new Error(\n 'VolumeViewports cannot be used whilst CPU Fallback Rendering is enabled.'\n );\n }\n\n const renderer = this.getRenderer();\n\n const camera = vtkSlabCamera.newInstance();\n renderer.setActiveCamera(camera);\n\n switch (this.type) {\n case ViewportType.ORTHOGRAPHIC:\n camera.setParallelProjection(true);\n break;\n case ViewportType.VOLUME_3D:\n camera.setParallelProjection(true);\n break;\n case ViewportType.PERSPECTIVE:\n camera.setParallelProjection(false);\n break;\n default:\n throw new Error(`Unrecognized viewport type: ${this.type}`);\n }\n\n this.initializeVolumeNewImageEventDispatcher();\n }\n\n static get useCustomRenderingPipeline(): boolean {\n return false;\n }\n\n private initializeVolumeNewImageEventDispatcher(): void {\n const volumeNewImageHandlerBound = volumeNewImageHandler.bind(this);\n const volumeNewImageCleanUpBound = volumeNewImageCleanUp.bind(this);\n\n function volumeNewImageHandler(cameraEvent) {\n const { viewportId } = cameraEvent.detail;\n\n if (viewportId !== this.id || this.isDisabled) {\n return;\n }\n\n const viewportImageData = this.getImageData();\n\n if (!viewportImageData) {\n return;\n }\n\n volumeNewImageEventDispatcher(cameraEvent);\n }\n\n function volumeNewImageCleanUp(evt) {\n const { viewportId } = evt.detail;\n\n if (viewportId !== this.id) {\n return;\n }\n\n this.element.removeEventListener(\n Events.CAMERA_MODIFIED,\n volumeNewImageHandlerBound\n );\n\n eventTarget.removeEventListener(\n Events.ELEMENT_DISABLED,\n volumeNewImageCleanUpBound\n );\n\n resetVolumeNewImageState(viewportId);\n }\n\n this.element.removeEventListener(\n Events.CAMERA_MODIFIED,\n volumeNewImageHandlerBound\n );\n this.element.addEventListener(\n Events.CAMERA_MODIFIED,\n volumeNewImageHandlerBound\n );\n\n eventTarget.addEventListener(\n Events.ELEMENT_DISABLED,\n volumeNewImageCleanUpBound\n );\n }\n\n /**\n * Sets the properties for the volume viewport on the volume\n * (if fusion, it sets it for the first volume in the fusion)\n *\n * @param voiRange - Sets the lower and upper voi\n * @param volumeId - The volume id to set the properties for (if undefined, the first volume)\n * @param suppressEvents - If true, the viewport will not emit events\n */\n public setProperties(\n { voiRange }: VolumeViewportProperties = {},\n volumeId?: string,\n suppressEvents = false\n ): void {\n if (volumeId !== undefined && !this.getActor(volumeId)) {\n return;\n }\n\n const actorEntries = this.getActors();\n\n if (!actorEntries.length) {\n return;\n }\n\n let volumeActor;\n\n if (volumeId) {\n const actorEntry = actorEntries.find((entry: ActorEntry) => {\n return entry.uid === volumeId;\n });\n\n volumeActor = actorEntry?.actor as vtkVolume;\n }\n\n // // set it for the first volume (if there are more than one - fusion)\n if (!volumeActor) {\n volumeActor = actorEntries[0].actor as vtkVolume;\n volumeId = actorEntries[0].uid;\n }\n\n if (!voiRange) {\n return;\n }\n\n // Todo: later when we have more properties, refactor the setVoiRange code below\n const { lower, upper } = voiRange;\n volumeActor.getProperty().getRGBTransferFunction(0).setRange(lower, upper);\n\n if (!suppressEvents) {\n const eventDetail: VoiModifiedEventDetail = {\n viewportId: this.id,\n range: voiRange,\n volumeId: volumeId,\n };\n\n triggerEvent(this.element, Events.VOI_MODIFIED, eventDetail);\n }\n }\n\n /**\n * Creates volume actors for all volumes defined in the `volumeInputArray`.\n * For each entry, if a `callback` is supplied, it will be called with the new volume actor as input.\n * For each entry, if a `blendMode` and/or `slabThickness` is defined, this will be set on the actor's\n * `VolumeMapper`.\n *\n * @param volumeInputArray - The array of `VolumeInput`s which define the volumes to add.\n * @param immediate - Whether the `Viewport` should be rendered as soon as volumes are added.\n */\n public async setVolumes(\n volumeInputArray: Array<IVolumeInput>,\n immediate = false,\n suppressEvents = false\n ): Promise<void> {\n const firstImageVolume = cache.getVolume(volumeInputArray[0].volumeId);\n\n if (!firstImageVolume) {\n throw new Error(\n `imageVolume with id: ${firstImageVolume.volumeId} does not exist`\n );\n }\n\n const FrameOfReferenceUID = firstImageVolume.metadata.FrameOfReferenceUID;\n\n await this._isValidVolumeInputArray(volumeInputArray, FrameOfReferenceUID);\n\n this._FrameOfReferenceUID = FrameOfReferenceUID;\n\n const volumeActors = [];\n\n // One actor per volume\n for (let i = 0; i < volumeInputArray.length; i++) {\n const { volumeId, actorUID, slabThickness } = volumeInputArray[i];\n\n const actor = await createVolumeActor(\n volumeInputArray[i],\n this.element,\n this.id,\n suppressEvents\n );\n\n // We cannot use only volumeId since then we cannot have for instance more\n // than one representation of the same volume (since actors would have the\n // same name, and we don't allow that) AND We cannot use only any uid, since\n // we rely on the volume in the cache for mapper. So we prefer actorUID if\n // it is defined, otherwise we use volumeId for the actor name.\n const uid = actorUID || volumeId;\n volumeActors.push({\n uid,\n actor,\n slabThickness,\n referenceId: volumeId,\n });\n }\n\n this._setVolumeActors(volumeActors);\n\n triggerEvent(this.element, Events.VOLUME_VIEWPORT_NEW_VOLUME, {\n viewportId: this.id,\n volumeActors,\n });\n\n if (immediate) {\n this.render();\n }\n }\n\n /**\n * Creates and adds volume actors for all volumes defined in the `volumeInputArray`.\n * For each entry, if a `callback` is supplied, it will be called with the new volume actor as input.\n *\n * @param volumeInputArray - The array of `VolumeInput`s which define the volumes to add.\n * @param immediate - Whether the `Viewport` should be rendered as soon as volumes are added.\n */\n public async addVolumes(\n volumeInputArray: Array<IVolumeInput>,\n immediate = false,\n suppressEvents = false\n ): Promise<void> {\n const firstImageVolume = cache.getVolume(volumeInputArray[0].volumeId);\n\n if (!firstImageVolume) {\n throw new Error(\n `imageVolume with id: ${firstImageVolume.volumeId} does not exist`\n );\n }\n\n const volumeActors = [];\n\n await this._isValidVolumeInputArray(\n volumeInputArray,\n this._FrameOfReferenceUID\n );\n\n // One actor per volume\n for (let i = 0; i < volumeInputArray.length; i++) {\n const { volumeId, visibility, actorUID, slabThickness } =\n volumeInputArray[i];\n\n const actor = await createVolumeActor(\n volumeInputArray[i],\n this.element,\n this.id,\n suppressEvents\n );\n\n if (visibility === false) {\n actor.setVisibility(false);\n }\n\n // We cannot use only volumeId since then we cannot have for instance more\n // than one representation of the same volume (since actors would have the\n // same name, and we don't allow that) AND We cannot use only any uid, since\n // we rely on the volume in the cache for mapper. So we prefer actorUID if\n // it is defined, otherwise we use volumeId for the actor name.\n const uid = actorUID || volumeId;\n volumeActors.push({\n uid,\n actor,\n slabThickness,\n // although the actor UID is defined, we need to use the volumeId for the\n // referenceId, since the actor UID is used to reference the actor in the\n // viewport, however, the actor is created from its volumeId\n // and if later we need to grab the referenced volume from cache,\n // we can use the referenceId to get the volume from the cache\n referenceId: volumeId,\n });\n }\n\n this.addActors(volumeActors);\n\n if (immediate) {\n // render\n this.render();\n }\n }\n\n /**\n * It removes the volume actor from the Viewport. If the volume actor is not in\n * the viewport, it does nothing.\n * @param actorUIDs - Array of actor UIDs to remove. In case of simple volume it will\n * be the volume Id, but in case of Segmentation it will be `{volumeId}-{representationType}`\n * since the same volume can be rendered in multiple representations.\n * @param immediate - If true, the Viewport will be rendered immediately\n */\n public removeVolumeActors(actorUIDs: Array<string>, immediate = false): void {\n // Todo: This is actually removeActors\n this.removeActors(actorUIDs);\n\n if (immediate) {\n this.render();\n }\n }\n\n /**\n * It sets the orientation for the camera, the orientation can be one of the\n * following: axial, sagittal, coronal, default. Use the Enums.OrientationAxis\n * to set the orientation. The \"default\" orientation is the orientation that\n * the volume was acquired in (scan axis)\n *\n * @param orientation - The orientation to set the camera to.\n * @param immediate - Whether the `Viewport` should be rendered as soon as the camera is set.\n */\n public setOrientation(orientation: OrientationAxis, immediate = true): void {\n console.warn('Method \"setOrientation\" needs implementation');\n }\n\n private async _isValidVolumeInputArray(\n volumeInputArray: Array<IVolumeInput>,\n FrameOfReferenceUID: string\n ): Promise<boolean> {\n const numVolumes = volumeInputArray.length;\n\n // Check all other volumes exist and have the same FrameOfReference\n for (let i = 1; i < numVolumes; i++) {\n const volumeInput = volumeInputArray[i];\n\n const imageVolume = await loadVolume(volumeInput.volumeId);\n\n if (!imageVolume) {\n throw new Error(\n `imageVolume with id: ${imageVolume.volumeId} does not exist`\n );\n }\n\n if (FrameOfReferenceUID !== imageVolume.metadata.FrameOfReferenceUID) {\n throw new Error(\n `Volumes being added to viewport ${this.id} do not share the same FrameOfReferenceUID. This is not yet supported`\n );\n }\n }\n\n return true;\n }\n\n /**\n * gets the visible bounds of the viewport in the world coordinate system\n */\n public getBounds(): number[] {\n const renderer = this.getRenderer();\n const bounds = renderer.computeVisiblePropBounds();\n return bounds;\n }\n\n /**\n * Flip the viewport along the desired axis\n * @param flipDirection - FlipDirection\n */\n public flip(flipDirection: FlipDirection): void {\n super.flip(flipDirection);\n }\n\n public getFrameOfReferenceUID = (): string => {\n return this._FrameOfReferenceUID;\n };\n\n /**\n * Checks if the viewport has a volume actor with the given volumeId\n * @param volumeId - the volumeId to look for\n * @returns Boolean indicating if the volume is present in the viewport\n */\n public hasVolumeId(volumeId: string): boolean {\n // Note: this assumes that the uid of the volume is the same as the volumeId\n // which is not guaranteed to be the case for SEG.\n const actorEntries = this.getActors();\n return actorEntries.some((actorEntry) => {\n return actorEntry.uid === volumeId;\n });\n }\n\n /**\n * Returns the image and its properties that is being shown inside the\n * stack viewport. It returns, the image dimensions, image direction,\n * image scalar data, vtkImageData object, metadata, and scaling (e.g., PET suvbw)\n * Note: since the volume viewport supports fusion, to get the\n * image data for a specific volume, use the optional volumeId\n * argument.\n *\n * @param volumeId - The volumeId of the volume to get the image for.\n * @returns IImageData: {dimensions, direction, scalarData, vtkImageData, metadata, scaling}\n */\n public getImageData(volumeId?: string): IImageData | undefined {\n const defaultActor = this.getDefaultActor();\n if (!defaultActor) {\n return;\n }\n\n const { uid: defaultActorUID } = defaultActor;\n volumeId = volumeId ?? defaultActorUID;\n\n const { actor } = this.getActor(volumeId);\n\n if (!actor.isA('vtkVolume')) {\n return;\n }\n\n const volume = cache.getVolume(volumeId);\n\n const vtkImageData = actor.getMapper().getInputData();\n return {\n dimensions: vtkImageData.getDimensions(),\n spacing: vtkImageData.getSpacing(),\n origin: vtkImageData.getOrigin(),\n direction: vtkImageData.getDirection(),\n scalarData: vtkImageData.getPointData().getScalars().getData(),\n imageData: actor.getMapper().getInputData(),\n metadata: {\n Modality: volume?.metadata?.Modality,\n },\n scaling: volume?.scaling,\n hasPixelSpacing: true,\n };\n }\n\n /**\n * Attaches the volume actors to the viewport.\n *\n * @param volumeActorEntries - The volume actors to add the viewport.\n *\n */\n private _setVolumeActors(volumeActorEntries: Array<ActorEntry>): void {\n this.setActors(volumeActorEntries);\n }\n\n /**\n * canvasToWorld Returns the world coordinates of the given `canvasPos`\n * projected onto the plane defined by the `Viewport`'s `vtkCamera`'s focal point\n * and the direction of projection.\n *\n * @param canvasPos - The position in canvas coordinates.\n * @returns The corresponding world coordinates.\n * @public\n */\n public canvasToWorld = (canvasPos: Point2): Point3 => {\n const vtkCamera = this.getVtkActiveCamera() as vtkSlabCameraType;\n\n /**\n * NOTE: this is necessary because we want the coordinate transformation\n * respect to the view plane (plane orthogonal to the camera and passing to\n * the focal point).\n *\n * When vtk.js computes the coordinate transformations, it simply uses the\n * camera matrix (no ray casting).\n *\n * However for the volume viewport the clipping range is set to be\n * (-RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE, RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE).\n * The clipping range is used in the camera method getProjectionMatrix().\n * The projection matrix is used then for viewToWorld/worldToView methods of\n * the renderer. This means that vkt.js will not return the coordinates of\n * the point on the view plane (i.e. the depth coordinate will correspond\n * to the focal point).\n *\n * Therefore the clipping range has to be set to (distance, distance + 0.01),\n * where now distance is the distance between the camera position and focal\n * point. This is done internally, in our camera customization when the flag\n * isPerformingCoordinateTransformation is set to true.\n */\n\n vtkCamera.setIsPerformingCoordinateTransformation(true);\n\n const renderer = this.getRenderer();\n const offscreenMultiRenderWindow =\n this.getRenderingEngine().offscreenMultiRenderWindow;\n const openGLRenderWindow =\n offscreenMultiRenderWindow.getOpenGLRenderWindow();\n const size = openGLRenderWindow.getSize();\n const devicePixelRatio = window.devicePixelRatio || 1;\n const canvasPosWithDPR = [\n canvasPos[0] * devicePixelRatio,\n canvasPos[1] * devicePixelRatio,\n ];\n const displayCoord = [\n canvasPosWithDPR[0] + this.sx,\n canvasPosWithDPR[1] + this.sy,\n ];\n\n // The y axis display coordinates are inverted with respect to canvas coords\n displayCoord[1] = size[1] - displayCoord[1];\n\n const worldCoord = openGLRenderWindow.displayToWorld(\n displayCoord[0],\n displayCoord[1],\n 0,\n renderer\n );\n\n vtkCamera.setIsPerformingCoordinateTransformation(false);\n\n return [worldCoord[0], worldCoord[1], worldCoord[2]];\n };\n\n /**\n * Returns the canvas coordinates of the given `worldPos`\n * projected onto the `Viewport`'s `canvas`.\n *\n * @param worldPos - The position in world coordinates.\n * @returns The corresponding canvas coordinates.\n * @public\n */\n public worldToCanvas = (worldPos: Point3): Point2 => {\n const vtkCamera = this.getVtkActiveCamera() as vtkSlabCameraType;\n\n /**\n * NOTE: this is necessary because we want the coordinate trasformation\n * respect to the view plane (plane orthogonal to the camera and passing to\n * the focal point).\n *\n * When vtk.js computes the coordinate transformations, it simply uses the\n * camera matrix (no ray casting).\n *\n * However for the volume viewport the clipping range is set to be\n * (-RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE, RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE).\n * The clipping range is used in the camera method getProjectionMatrix().\n * The projection matrix is used then for viewToWorld/worldToView methods of\n * the renderer. This means that vkt.js will not return the coordinates of\n * the point on the view plane (i.e. the depth coordinate will corresponded\n * to the focal point).\n *\n * Therefore the clipping range has to be set to (distance, distance + 0.01),\n * where now distance is the distance between the camera position and focal\n * point. This is done internally, in our camera customization when the flag\n * isPerformingCoordinateTransformation is set to true.\n */\n\n vtkCamera.setIsPerformingCoordinateTransformation(true);\n\n const renderer = this.getRenderer();\n const offscreenMultiRenderWindow =\n this.getRenderingEngine().offscreenMultiRenderWindow;\n const openGLRenderWindow =\n offscreenMultiRenderWindow.getOpenGLRenderWindow();\n const size = openGLRenderWindow.getSize();\n const displayCoord = openGLRenderWindow.worldToDisplay(\n ...worldPos,\n renderer\n );\n\n // The y axis display coordinates are inverted with respect to canvas coords\n displayCoord[1] = size[1] - displayCoord[1];\n\n const canvasCoord = <Point2>[\n displayCoord[0] - this.sx,\n displayCoord[1] - this.sy,\n ];\n\n const devicePixelRatio = window.devicePixelRatio || 1;\n const canvasCoordWithDPR = <Point2>[\n canvasCoord[0] / devicePixelRatio,\n canvasCoord[1] / devicePixelRatio,\n ];\n\n vtkCamera.setIsPerformingCoordinateTransformation(false);\n\n return canvasCoordWithDPR;\n };\n\n /*\n * Checking if the imageURI is in the volumes that are being\n * rendered by the viewport. imageURI is the imageId without the schema\n * for instance for the imageId of wadors:http://..., the http://... is the imageURI.\n * Why we don't check the imageId is because the same image can be shown in\n * another viewport (StackViewport) with a different schema\n *\n * @param imageURI - The imageURI to check\n * @returns True if the imageURI is in the volumes that are being rendered by the viewport\n */\n public hasImageURI = (imageURI: string): boolean => {\n const volumeActors = this.getActors().filter(({ actor }) =>\n actor.isA('vtkVolume')\n );\n\n return volumeActors.some(({ uid }) => {\n const volume = cache.getVolume(uid);\n\n if (!volume || !volume.imageIds) {\n return false;\n }\n\n const volumeImageURIs = volume.imageIds.map(imageIdToURI);\n\n return volumeImageURIs.includes(imageURI);\n });\n };\n\n /**\n * Reset the camera for the volume viewport\n */\n resetCamera(\n resetPan?: boolean,\n resetZoom?: boolean,\n resetToCenter?: boolean\n ): boolean {\n return super.resetCamera(resetPan, resetZoom, resetToCenter);\n }\n\n getCurrentImageIdIndex = (): number => {\n throw new Error('Method not implemented.');\n };\n\n getCurrentImageId = (): string => {\n throw new Error('Method not implemented.');\n };\n\n getIntensityFromWorld(point: Point3): number {\n throw new Error('Method not implemented.');\n }\n\n setBlendMode(\n blendMode: BlendModes,\n filterActorUIDs?: string[],\n immediate?: boolean\n ): void {\n throw new Error('Method not implemented.');\n }\n\n setSlabThickness(slabThickness: number, filterActorUIDs?: string[]): void {\n throw new Error('Method not implemented.');\n }\n\n getSlabThickness(): number {\n throw new Error('Method not implemented.');\n }\n}\n\nexport default BaseVolumeViewport;\n","import { vec3 } from 'gl-matrix';\nimport vtkPlane from '@kitware/vtk.js/Common/DataModel/Plane';\n\nimport cache from '../cache';\nimport transformWorldToIndex from '../utilities/transformWorldToIndex';\nimport type {\n Point3,\n IVolumeInput,\n ActorEntry,\n IImageVolume,\n OrientationVectors,\n} from '../types';\nimport type { ViewportInput } from '../types/IViewport';\nimport { RENDERING_DEFAULTS, MPR_CAMERA_VALUES, EPSILON } from '../constants';\nimport { BlendModes, OrientationAxis } from '../enums';\nimport BaseVolumeViewport from './BaseVolumeViewport';\n\n/**\n * An object representing a VolumeViewport. VolumeViewports are used to render\n * 3D volumes from which various orientations can be viewed. Since VolumeViewports\n * use SharedVolumeMappers behind the scene, memory footprint of visualizations\n * of the same volume in different orientations is very small.\n *\n * For setting volumes on viewports you need to use {@link addVolumesToViewports}\n * which will add volumes to the specified viewports.\n */\nclass VolumeViewport extends BaseVolumeViewport {\n private _useAcquisitionPlaneForViewPlane = false;\n constructor(props: ViewportInput) {\n super(props);\n\n const { orientation } = this.options;\n\n // if the camera is set to be acquisition axis then we need to skip\n // it for now until the volume is set\n if (orientation && orientation !== OrientationAxis.ACQUISITION) {\n const { viewPlaneNormal, viewUp } =\n this._getOrientationVectors(orientation);\n const camera = this.getVtkActiveCamera();\n camera.setDirectionOfProjection(\n -viewPlaneNormal[0],\n -viewPlaneNormal[1],\n -viewPlaneNormal[2]\n );\n camera.setViewUpFrom(viewUp);\n\n this.resetCamera();\n return;\n }\n\n this._useAcquisitionPlaneForViewPlane = true;\n }\n\n /**\n * Creates volume actors for all volumes defined in the `volumeInputArray`.\n * For each entry, if a `callback` is supplied, it will be called with the new volume actor as input.\n * For each entry, if a `blendMode` and/or `slabThickness` is defined, this will be set on the actor's\n * `VolumeMapper`.\n *\n * @param volumeInputArray - The array of `VolumeInput`s which define the volumes to add.\n * @param immediate - Whether the `Viewport` should be rendered as soon as volumes are added.\n */\n public async setVolumes(\n volumeInputArray: Array<IVolumeInput>,\n immediate = false,\n suppressEvents = false\n ): Promise<void> {\n const firstImageVolume = cache.getVolume(volumeInputArray[0].volumeId);\n\n if (!firstImageVolume) {\n throw new Error(\n `imageVolume with id: ${firstImageVolume.volumeId} does not exist`\n );\n }\n\n if (this._useAcquisitionPlaneForViewPlane) {\n this._setViewPlaneToAcquisitionPlane(firstImageVolume);\n this._useAcquisitionPlaneForViewPlane = false;\n }\n\n return super.setVolumes(volumeInputArray, immediate, suppressEvents);\n }\n\n /**\n * Creates and adds volume actors for all volumes defined in the `volumeInputArray`.\n * For each entry, if a `callback` is supplied, it will be called with the new volume actor as input.\n *\n * @param volumeInputArray - The array of `VolumeInput`s which define the volumes to add.\n * @param immediate - Whether the `Viewport` should be rendered as soon as volumes are added.\n */\n public async addVolumes(\n volumeInputArray: Array<IVolumeInput>,\n immediate = false,\n suppressEvents = false\n ): Promise<void> {\n const firstImageVolume = cache.getVolume(volumeInputArray[0].volumeId);\n\n if (!firstImageVolume) {\n throw new Error(\n `imageVolume with id: ${firstImageVolume.volumeId} does not exist`\n );\n }\n\n if (this._useAcquisitionPlaneForViewPlane) {\n this._setViewPlaneToAcquisitionPlane(firstImageVolume);\n this._useAcquisitionPlaneForViewPlane = false;\n }\n\n return super.addVolumes(volumeInputArray, immediate, suppressEvents);\n }\n\n /**\n * It sets the orientation for the camera, the orientation can be one of the\n * following: axial, sagittal, coronal, default. Use the Enums.OrientationAxis\n * to set the orientation. The \"default\" orientation is the orientation that\n * the volume was acquired in (scan axis)\n *\n * @param orientation - The orientation to set the camera to.\n * @param immediate - Whether the `Viewport` should be rendered as soon as the camera is set.\n */\n public setOrientation(orientation: OrientationAxis, immediate = true): void {\n let viewPlaneNormal, viewUp;\n\n if (MPR_CAMERA_VALUES[orientation]) {\n ({ viewPlaneNormal, viewUp } = MPR_CAMERA_VALUES[orientation]);\n } else if (orientation === 'acquisition') {\n ({ viewPlaneNormal, viewUp } = this._getAcquisitionPlaneOrientation());\n } else {\n throw new Error(\n `Invalid orientation: ${orientation}. Use Enums.OrientationAxis instead.`\n );\n }\n\n this.setCamera({\n viewPlaneNormal,\n viewUp,\n });\n\n this.resetCamera();\n\n if (immediate) {\n this.render();\n }\n }\n\n private _getOrientationVectors(\n orientation: OrientationAxis | OrientationVectors\n ): OrientationVectors {\n if (typeof orientation === 'object') {\n if (orientation.viewPlaneNormal && orientation.viewUp) {\n return orientation;\n } else {\n throw new Error(\n 'Invalid orientation object. It must contain viewPlaneNormal and viewUp'\n );\n }\n } else if (\n typeof orientation === 'string' &&\n MPR_CAMERA_VALUES[orientation]\n ) {\n return MPR_CAMERA_VALUES[orientation];\n } else {\n throw new Error(\n `Invalid orientation: ${orientation}. Valid orientations are: ${Object.keys(\n MPR_CAMERA_VALUES\n ).join(', ')}`\n );\n }\n }\n\n private _getAcquisitionPlaneOrientation(): OrientationVectors {\n const actorEntry = this.getDefaultActor();\n\n if (!actorEntry) {\n return;\n }\n\n // Todo: fix this after we add the volumeId reference to actorEntry later\n // in the segmentation refactor\n const volumeId = actorEntry.uid;\n\n const imageVolume = cache.getVolume(volumeId);\n\n if (!imageVolume) {\n throw new Error(\n `imageVolume with id: ${volumeId} does not exist in cache`\n );\n }\n\n const { direction } = imageVolume;\n const viewPlaneNormal = direction.slice(6, 9).map((x) => -x) as Point3;\n const viewUp = (direction.slice(3, 6) as Point3).map((x) => -x) as Point3;\n\n return {\n viewPlaneNormal,\n viewUp,\n };\n }\n\n private _setViewPlaneToAcquisitionPlane(imageVolume: IImageVolume): void {\n let viewPlaneNormal, viewUp;\n\n if (imageVolume) {\n const { direction } = imageVolume;\n viewPlaneNormal = direction.slice(6, 9).map((x) => -x) as Point3;\n viewUp = (direction.slice(3, 6) as Point3).map((x) => -x) as Point3;\n } else {\n ({ viewPlaneNormal, viewUp } = this._getAcquisitionPlaneOrientation());\n }\n\n this.setCamera({\n viewPlaneNormal,\n viewUp,\n });\n\n this.resetCamera();\n }\n\n /**\n * Given a point in world coordinates, return the intensity at that point\n * @param point - The point in world coordinates to get the intensity\n * from.\n * @returns The intensity value of the voxel at the given point.\n */\n public getIntensityFromWorld(point: Point3): number {\n const { actor, uid } = this.getDefaultActor();\n if (!actor.isA('vtkVolume')) {\n return;\n }\n\n const imageData = actor.getMapper().getInputData();\n\n const volume = cache.getVolume(uid);\n const { dimensions } = volume;\n\n const index = transformWorldToIndex(imageData, point);\n\n const voxelIndex =\n index[2] * dimensions[0] * dimensions[1] +\n index[1] * dimensions[0] +\n index[0];\n\n return volume.scalarData[voxelIndex];\n }\n\n public setBlendMode(\n blendMode: BlendModes,\n filterActorUIDs = [],\n immediate = false\n ): void {\n let actorEntries = this.getActors();\n\n if (filterActorUIDs && filterActorUIDs.length > 0) {\n actorEntries = actorEntries.filter((actorEntry: ActorEntry) => {\n return filterActorUIDs.includes(actorEntry.uid);\n });\n }\n\n actorEntries.forEach((actorEntry) => {\n const { actor } = actorEntry;\n\n const mapper = actor.getMapper();\n // @ts-ignore vtk incorrect typing\n mapper.setBlendMode(blendMode);\n });\n\n if (immediate) {\n this.render();\n }\n }\n\n /**\n * Reset the camera for the volume viewport\n */\n public resetCamera(\n resetPan = true,\n resetZoom = true,\n resetToCenter = true\n ): boolean {\n super.resetCamera(resetPan, resetZoom, resetToCenter);\n const activeCamera = this.getVtkActiveCamera();\n // Set large numbers to ensure everything is always rendered\n if (activeCamera.getParallelProjection()) {\n activeCamera.setClippingRange(\n -RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE,\n RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE\n );\n } else {\n activeCamera.setClippingRange(\n RENDERING_DEFAULTS.MINIMUM_SLAB_THICKNESS,\n RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE\n );\n }\n\n const viewPlaneNormal = <Point3>activeCamera.getViewPlaneNormal();\n const focalPoint = <Point3>activeCamera.getFocalPoint();\n\n const actorEntries = this.getActors();\n actorEntries.forEach((actorEntry) => {\n // we assume that the first two clipping plane of the mapper are always\n // the 'camera' clipping. Add clipping planes only if the actor is\n // a vtkVolume\n if (!actorEntry.actor || !actorEntry.actor.isA('vtkVolume')) {\n return;\n }\n const mapper = actorEntry.actor.getMapper();\n const vtkPlanes = mapper.getClippingPlanes();\n if (vtkPlanes.length === 0) {\n const clipPlane1 = vtkPlane.newInstance();\n const clipPlane2 = vtkPlane.newInstance();\n const newVtkPlanes = [clipPlane1, clipPlane2];\n\n let slabThickness = RENDERING_DEFAULTS.MINIMUM_SLAB_THICKNESS;\n if (actorEntry.slabThickness) {\n slabThickness = actorEntry.slabThickness;\n }\n\n this.setOrientationOfClippingPlanes(\n newVtkPlanes,\n slabThickness,\n viewPlaneNormal,\n focalPoint\n );\n\n mapper.addClippingPlane(clipPlane1);\n mapper.addClippingPlane(clipPlane2);\n }\n });\n\n return true;\n }\n\n /**\n * It sets the slabThickness of the actors of the viewport. If filterActorUIDs are\n * provided, only the actors with the given UIDs will be affected. If no\n * filterActorUIDs are provided, all actors will be affected.\n *\n * @param slabThickness - The slab thickness to set.\n * @param blendMode - The blend mode to use when rendering the actors.\n * @param filterActorUIDs - Optional argument to filter the actors to apply\n * the slab thickness to (if not provided, all actors will be affected).\n */\n public setSlabThickness(slabThickness: number, filterActorUIDs = []): void {\n let actorEntries = this.getActors();\n\n if (filterActorUIDs && filterActorUIDs.length > 0) {\n actorEntries = actorEntries.filter((actorEntry) => {\n return filterActorUIDs.includes(actorEntry.uid);\n });\n }\n\n actorEntries.forEach((actorEntry) => {\n const { actor } = actorEntry;\n\n if (actor.isA('vtkVolume')) {\n actorEntry.slabThickness = slabThickness;\n }\n });\n\n const currentCamera = this.getCamera();\n this.updateClippingPlanesForActors(currentCamera);\n this.triggerCameraModifiedEventIfNecessary(currentCamera, currentCamera);\n }\n\n /**\n * Gets the largest slab thickness from all actors in the viewport.\n *\n * @returns slabThickness - The slab thickness.\n */\n public getSlabThickness(): number {\n const actors = this.getActors();\n let slabThickness = RENDERING_DEFAULTS.MINIMUM_SLAB_THICKNESS;\n actors.forEach((actor) => {\n if (actor.slabThickness > slabThickness) {\n slabThickness = actor.slabThickness;\n }\n });\n\n return slabThickness;\n }\n\n /**\n * Uses viewport camera and volume actor to decide if the viewport\n * is looking at the volume in the direction of acquisition (imageIds).\n * If so, it uses the origin and focalPoint to calculate the slice index.\n * Todo: This only works if the imageIds are properly sorted\n *\n * @returns The slice index\n */\n public getCurrentImageIdIndex = (): number | undefined => {\n return this._getImageIdIndex();\n };\n\n /**\n * Uses viewport camera and volume actor to decide if the viewport\n * is looking at the volume in the direction of acquisition (imageIds).\n * If so, it uses the origin and focalPoint to find which imageId is\n * currently being viewed.\n *\n * @returns ImageId\n */\n public getCurrentImageId = (): string | undefined => {\n const index = this._getImageIdIndex();\n\n if (isNaN(index)) {\n return;\n }\n\n const { uid, actor } = this.getDefaultActor();\n if (!actor.isA('vtkVolume')) {\n return;\n }\n\n const volume = cache.getVolume(uid);\n\n if (!volume) {\n return;\n }\n\n const imageIds = volume.imageIds;\n\n return imageIds[index];\n };\n\n private _getImageIdIndex = () => {\n const { viewPlaneNormal, focalPoint } = this.getCamera();\n\n // Todo: handle scenario of fusion of multiple volumes\n // we cannot only check number of actors, because we might have\n // segmentations ...\n const { direction, origin, spacing } = this.getImageData();\n\n // get the last 3 components of the direction - axis normal\n const dir = direction.slice(direction.length - 3);\n\n const dot = Math.abs(\n dir[0] * viewPlaneNormal[0] +\n dir[1] * viewPlaneNormal[1] +\n dir[2] * viewPlaneNormal[2]\n );\n\n // if dot is not 1 or -1 return null since it means\n // viewport is not looking at the image acquisition plane\n if (dot - 1 > EPSILON) {\n return;\n }\n\n // how many steps are from the origin to the focal point in the\n // normal direction\n const spacingInNormal = spacing[2];\n const sub = vec3.create();\n vec3.sub(sub, focalPoint, origin);\n const distance = vec3.dot(sub, viewPlaneNormal);\n\n // divide by the spacing in the normal direction to get the\n // number of steps, and subtract 1 to get the index\n return Math.round(Math.abs(distance) / spacingInNormal);\n };\n}\n\nexport default VolumeViewport;\n","/**\n * A utility that can be used to invert (in place) an RgbTransferFunction.\n *\n * @example\n * Grabbing a reference to the RGB Transfer function from the viewport:\n * ```\n * const rgbTransferFunction = viewport\n * .getActor()\n * .getProperty()\n * .getRGBTransferFunction(0);\n *\n * rgbTransferFunction.setRange(0, 5);\n *\n * invertRgbTransferFunction(rgbTransferFunction);\n * ```\n *\n * @see {@link https://kitware.github.io/vtk-js/api/Rendering_Core_ColorTransferFunction.html|VTK.js: ColorTransferFunction}\n * @param rgbTransferFunction\n */\nexport default function invertRgbTransferFunction(\n rgbTransferFunction: any\n): void {\n const size = rgbTransferFunction.getSize();\n\n for (let index = 0; index < size; index++) {\n const nodeValue1 = [];\n\n rgbTransferFunction.getNodeValue(index, nodeValue1);\n\n nodeValue1[1] = 1 - nodeValue1[1];\n nodeValue1[2] = 1 - nodeValue1[2];\n nodeValue1[3] = 1 - nodeValue1[3];\n\n rgbTransferFunction.setNodeValue(index, nodeValue1);\n }\n}\n","/**\n * returns equal if the two arrays are identical within the\n * given tolerance.\n *\n * @param v1 - The first array of values\n * @param v2 - The second array of values.\n * @param tolerance - The acceptable tolerance, the default is 0.00001\n *\n * @returns True if the two values are within the tolerance levels.\n */\nexport default function isEqual(\n v1: number[] | Float32Array,\n v2: number[] | Float32Array,\n tolerance = 1e-5\n): boolean {\n if (v1.length !== v2.length) {\n return false;\n }\n\n for (let i = 0; i < v1.length; i++) {\n if (Math.abs(v1[i] - v2[i]) > tolerance) {\n return false;\n }\n }\n\n return true;\n}\n","/**\n * Use the performance.now() method if possible, and if not, use Date.now()\n *\n * @return {number} Time elapsed since the time origin\n * @memberof Polyfills\n */\nexport default function (): number {\n if (window.performance) {\n return performance.now();\n }\n\n return Date.now();\n}\n","/* eslint no-bitwise: 0 */\n\n/**\n * Volume of Interest Lookup Table Function\n *\n * @typedef {Function} VOILUTFunction\n *\n * @param {Number} modalityLutValue\n * @returns {Number} transformed value\n * @memberof Objects\n */\n\n/**\n * @module: VOILUT\n */\n\n/**\n *\n * @param {Number} windowWidth Window Width\n * @param {Number} windowCenter Window Center\n * @returns {VOILUTFunction} VOI LUT mapping function\n * @memberof VOILUT\n */\nfunction generateLinearVOILUT(windowWidth: number, windowCenter: number) {\n return function (modalityLutValue) {\n return ((modalityLutValue - windowCenter) / windowWidth + 0.5) * 255.0;\n };\n}\n\n/**\n * Generate a non-linear volume of interest lookup table\n *\n * @param {LUT} voiLUT Volume of Interest Lookup Table Object\n *\n * @returns {VOILUTFunction} VOI LUT mapping function\n * @memberof VOILUT\n */\nfunction generateNonLinearVOILUT(voiLUT) {\n // We don't trust the voiLUT.numBitsPerEntry, mainly thanks to Agfa!\n const bitsPerEntry = Math.max(...voiLUT.lut).toString(2).length;\n const shift = bitsPerEntry - 8;\n const minValue = voiLUT.lut[0] >> shift;\n const maxValue = voiLUT.lut[voiLUT.lut.length - 1] >> shift;\n const maxValueMapped = voiLUT.firstValueMapped + voiLUT.lut.length - 1;\n\n return function (modalityLutValue) {\n if (modalityLutValue < voiLUT.firstValueMapped) {\n return minValue;\n } else if (modalityLutValue >= maxValueMapped) {\n return maxValue;\n }\n\n return voiLUT.lut[modalityLutValue - voiLUT.firstValueMapped] >> shift;\n };\n}\n\n/**\n * Retrieve a VOI LUT mapping function given the current windowing settings\n * and the VOI LUT for the image\n *\n * @param {Number} windowWidth Window Width\n * @param {Number} windowCenter Window Center\n * @param {LUT} [voiLUT] Volume of Interest Lookup Table Object\n *\n * @return {VOILUTFunction} VOI LUT mapping function\n * @memberof VOILUT\n */\nexport default function (windowWidth: number, windowCenter: number, voiLUT) {\n if (voiLUT) {\n return generateNonLinearVOILUT(voiLUT);\n }\n\n return generateLinearVOILUT(windowWidth, windowCenter);\n}\n","import {\n CPUFallbackTransform,\n Point2,\n TransformMatrix2D,\n} from '../../../../types';\n\n// By Simon Sarris\n// Www.simonsarris.com\n// Sarris@acm.org\n//\n// Free to use and distribute at will\n// So long as you are nice to people, etc\n\n// Simple class for keeping track of the current transformation matrix\n\n// For instance:\n// Var t = new Transform();\n// T.rotate(5);\n// Var m = t.m;\n// Ctx.setTransform(m[0], m[1], m[2], m[3], m[4], m[5]);\n\n// Is equivalent to:\n// Ctx.rotate(5);\n\n// But now you can retrieve it :)\n\n// Remember that this does not account for any CSS transforms applied to the canvas\nexport class Transform implements CPUFallbackTransform {\n private m: TransformMatrix2D;\n\n constructor() {\n this.reset();\n }\n\n getMatrix(): TransformMatrix2D {\n return this.m;\n }\n\n reset(): void {\n this.m = [1, 0, 0, 1, 0, 0];\n }\n\n clone(): CPUFallbackTransform {\n const transform = new Transform();\n\n transform.m[0] = this.m[0];\n transform.m[1] = this.m[1];\n transform.m[2] = this.m[2];\n transform.m[3] = this.m[3];\n transform.m[4] = this.m[4];\n transform.m[5] = this.m[5];\n\n return transform;\n }\n\n multiply(matrix: TransformMatrix2D): void {\n const m11 = this.m[0] * matrix[0] + this.m[2] * matrix[1];\n const m12 = this.m[1] * matrix[0] + this.m[3] * matrix[1];\n\n const m21 = this.m[0] * matrix[2] + this.m[2] * matrix[3];\n const m22 = this.m[1] * matrix[2] + this.m[3] * matrix[3];\n\n const dx = this.m[0] * matrix[4] + this.m[2] * matrix[5] + this.m[4];\n const dy = this.m[1] * matrix[4] + this.m[3] * matrix[5] + this.m[5];\n\n this.m[0] = m11;\n this.m[1] = m12;\n this.m[2] = m21;\n this.m[3] = m22;\n this.m[4] = dx;\n this.m[5] = dy;\n }\n\n invert(): void {\n const d = 1 / (this.m[0] * this.m[3] - this.m[1] * this.m[2]);\n const m0 = this.m[3] * d;\n const m1 = -this.m[1] * d;\n const m2 = -this.m[2] * d;\n const m3 = this.m[0] * d;\n const m4 = d * (this.m[2] * this.m[5] - this.m[3] * this.m[4]);\n const m5 = d * (this.m[1] * this.m[4] - this.m[0] * this.m[5]);\n\n this.m[0] = m0;\n this.m[1] = m1;\n this.m[2] = m2;\n this.m[3] = m3;\n this.m[4] = m4;\n this.m[5] = m5;\n }\n\n rotate(rad: number): void {\n const c = Math.cos(rad);\n const s = Math.sin(rad);\n const m11 = this.m[0] * c + this.m[2] * s;\n const m12 = this.m[1] * c + this.m[3] * s;\n const m21 = this.m[0] * -s + this.m[2] * c;\n const m22 = this.m[1] * -s + this.m[3] * c;\n\n this.m[0] = m11;\n this.m[1] = m12;\n this.m[2] = m21;\n this.m[3] = m22;\n }\n\n translate(x: number, y: number): void {\n this.m[4] += this.m[0] * x + this.m[2] * y;\n this.m[5] += this.m[1] * x + this.m[3] * y;\n }\n\n scale(sx: number, sy: number) {\n this.m[0] *= sx;\n this.m[1] *= sx;\n this.m[2] *= sy;\n this.m[3] *= sy;\n }\n\n transformPoint(point: Point2): Point2 {\n const x = point[0];\n const y = point[1];\n\n return [\n x * this.m[0] + y * this.m[2] + this.m[4],\n x * this.m[1] + y * this.m[3] + this.m[5],\n ];\n }\n}\n","import { Transform } from './transform';\nimport {\n CPUFallbackEnabledElement,\n CPUFallbackTransform,\n} from '../../../../types';\n\n/**\n * Calculate the transform for a Cornerstone enabled element\n *\n * @param enabledElement - The Cornerstone Enabled Element\n * @param scale - The viewport scale\n * @returns The current transform\n */\nexport default function (\n enabledElement: CPUFallbackEnabledElement,\n scale?: number\n): CPUFallbackTransform {\n const transform = new Transform();\n\n if (!enabledElement.viewport.displayedArea) {\n return transform;\n }\n\n // Move to center of canvas\n transform.translate(\n enabledElement.canvas.width / 2,\n enabledElement.canvas.height / 2\n );\n\n // Apply the rotation before scaling for non square pixels\n const angle = enabledElement.viewport.rotation;\n\n if (angle !== 0) {\n transform.rotate((angle * Math.PI) / 180);\n }\n\n // Apply the scale\n let widthScale = enabledElement.viewport.scale;\n let heightScale = enabledElement.viewport.scale;\n\n const width =\n enabledElement.viewport.displayedArea.brhc.x -\n (enabledElement.viewport.displayedArea.tlhc.x - 1);\n const height =\n enabledElement.viewport.displayedArea.brhc.y -\n (enabledElement.viewport.displayedArea.tlhc.y - 1);\n\n if (enabledElement.viewport.displayedArea.presentationSizeMode === 'NONE') {\n if (\n enabledElement.image.rowPixelSpacing <\n enabledElement.image.columnPixelSpacing\n ) {\n widthScale *=\n enabledElement.image.columnPixelSpacing /\n enabledElement.image.rowPixelSpacing;\n } else if (\n enabledElement.image.columnPixelSpacing <\n enabledElement.image.rowPixelSpacing\n ) {\n heightScale *=\n enabledElement.image.rowPixelSpacing /\n enabledElement.image.columnPixelSpacing;\n }\n } else {\n // These should be good for \"TRUE SIZE\" and \"MAGNIFY\"\n widthScale = enabledElement.viewport.displayedArea.columnPixelSpacing;\n heightScale = enabledElement.viewport.displayedArea.rowPixelSpacing;\n\n if (\n enabledElement.viewport.displayedArea.presentationSizeMode ===\n 'SCALE TO FIT'\n ) {\n // Fit TRUE IMAGE image (width/height) to window\n const verticalScale =\n enabledElement.canvas.height / (height * heightScale);\n const horizontalScale =\n enabledElement.canvas.width / (width * widthScale);\n\n // Apply new scale\n widthScale = heightScale = Math.min(horizontalScale, verticalScale);\n\n if (\n enabledElement.viewport.displayedArea.rowPixelSpacing <\n enabledElement.viewport.displayedArea.columnPixelSpacing\n ) {\n widthScale *=\n enabledElement.viewport.displayedArea.columnPixelSpacing /\n enabledElement.viewport.displayedArea.rowPixelSpacing;\n } else if (\n enabledElement.viewport.displayedArea.columnPixelSpacing <\n enabledElement.viewport.displayedArea.rowPixelSpacing\n ) {\n heightScale *=\n enabledElement.viewport.displayedArea.rowPixelSpacing /\n enabledElement.viewport.displayedArea.columnPixelSpacing;\n }\n }\n }\n\n transform.scale(widthScale, heightScale);\n\n // Unrotate to so we can translate unrotated\n if (angle !== 0) {\n transform.rotate((-angle * Math.PI) / 180);\n }\n\n // Apply the pan offset\n transform.translate(\n enabledElement.viewport.translation.x,\n enabledElement.viewport.translation.y\n );\n\n // Rotate again so we can apply general scale\n if (angle !== 0) {\n transform.rotate((angle * Math.PI) / 180);\n }\n\n if (scale !== undefined) {\n // Apply the font scale\n transform.scale(scale, scale);\n }\n\n // Apply Flip if required\n if (enabledElement.viewport.hflip) {\n transform.scale(-1, 1);\n }\n\n if (enabledElement.viewport.vflip) {\n transform.scale(1, -1);\n }\n\n // Move back from center of image\n transform.translate(-width / 2, -height / 2);\n\n return transform;\n}\n","import calculateTransform from './calculateTransform';\nimport { CPUFallbackEnabledElement } from '../../../../types';\n\n/**\n * Sets the canvas context transformation matrix to the pixel coordinate system. This allows\n * geometry to be driven using the canvas context using coordinates in the pixel coordinate system\n * @param {EnabledElement} enabledElement The\n * @param {CanvasRenderingContext2D} context The CanvasRenderingContext2D for the enabledElement's Canvas\n * @param {Number} [scale] Optional scale to apply\n * @returns {void}\n */\nexport default function (\n enabledElement: CPUFallbackEnabledElement,\n context: CanvasRenderingContext2D,\n scale?: number\n): void {\n if (enabledElement === undefined) {\n throw new Error(\n 'setToPixelCoordinateSystem: parameter enabledElement must not be undefined'\n );\n }\n if (context === undefined) {\n throw new Error(\n 'setToPixelCoordinateSystem: parameter context must not be undefined'\n );\n }\n\n const transform = calculateTransform(enabledElement, scale);\n const m = transform.getMatrix();\n\n context.setTransform(m[0], m[1], m[2], m[3], m[4], m[5]);\n}\n","import { CPUFallbackEnabledElement, IImage } from '../../../../types';\n\n/**\n * Determine whether or not an Enabled Element needs to be re-rendered.\n *\n * If the imageId has changed, or if any of the last rendered viewport\n * parameters have changed, this function will return true.\n *\n * @param enabledElement - An Enabled Element\n * @param image - An Image\n * @returns Whether - or not the Enabled Element needs to re-render its image\n */\nexport default function doesImageNeedToBeRendered(\n enabledElement: CPUFallbackEnabledElement,\n image: IImage\n): boolean {\n const lastRenderedImageId = enabledElement.renderingTools.lastRenderedImageId;\n const lastRenderedViewport =\n enabledElement.renderingTools.lastRenderedViewport;\n\n return (\n image.imageId !== lastRenderedImageId ||\n !lastRenderedViewport ||\n lastRenderedViewport.windowCenter !==\n enabledElement.viewport.voi.windowCenter ||\n lastRenderedViewport.windowWidth !==\n enabledElement.viewport.voi.windowWidth ||\n lastRenderedViewport.invert !== enabledElement.viewport.invert ||\n lastRenderedViewport.rotation !== enabledElement.viewport.rotation ||\n lastRenderedViewport.hflip !== enabledElement.viewport.hflip ||\n lastRenderedViewport.vflip !== enabledElement.viewport.vflip ||\n lastRenderedViewport.modalityLUT !== enabledElement.viewport.modalityLUT ||\n lastRenderedViewport.voiLUT !== enabledElement.viewport.voiLUT ||\n lastRenderedViewport.colormap !== enabledElement.viewport.colormap\n );\n}\n","import { CPUFallbackEnabledElement, IImage } from '../../../../types';\n\n/**\n * Sets size and clears canvas\n *\n * @param {Object} enabledElement Cornerstone Enabled Element\n * @param {Object} image Image to be rendered\n * @returns {void}\n * @memberof rendering\n */\nexport default function (\n enabledElement: CPUFallbackEnabledElement,\n image: IImage\n): void {\n const renderCanvas = enabledElement.renderingTools.renderCanvas;\n\n // Resize the canvas\n renderCanvas.width = image.width;\n renderCanvas.height = image.height;\n\n const canvasContext = renderCanvas.getContext('2d');\n\n // NOTE - we need to fill the render canvas with white pixels since we\n // control the luminance using the alpha channel to improve rendering performance.\n canvasContext.fillStyle = 'white';\n canvasContext.fillRect(0, 0, renderCanvas.width, renderCanvas.height);\n\n const renderCanvasData = canvasContext.getImageData(\n 0,\n 0,\n image.width,\n image.height\n );\n\n enabledElement.renderingTools.renderCanvasContext = canvasContext;\n enabledElement.renderingTools.renderCanvasData = renderCanvasData;\n}\n","import {\n CPUFallbackEnabledElement,\n CPUFallbackRenderingTools,\n} from '../../../../types';\n\n/**\n * Saves the parameters of the last render into renderingTools, used later to decide if data can be reused.\n *\n * @param {Object} enabledElement Cornerstone EnabledElement\n * @returns {Object} enabledElement.renderingTools\n * @memberof rendering\n */\n\nexport default function (\n enabledElement: CPUFallbackEnabledElement\n): CPUFallbackRenderingTools {\n const imageId = enabledElement.image.imageId;\n const viewport = enabledElement.viewport;\n const isColor = enabledElement.image.color;\n\n enabledElement.renderingTools.lastRenderedImageId = imageId;\n enabledElement.renderingTools.lastRenderedIsColor = isColor;\n enabledElement.renderingTools.lastRenderedViewport = {\n windowCenter: viewport.voi.windowCenter,\n windowWidth: viewport.voi.windowWidth,\n invert: viewport.invert,\n rotation: viewport.rotation,\n hflip: viewport.hflip,\n vflip: viewport.vflip,\n modalityLUT: viewport.modalityLUT,\n voiLUT: viewport.voiLUT,\n colormap: viewport.colormap,\n };\n\n return enabledElement.renderingTools;\n}\n","import now from './now';\nimport generateColorLUT from './generateColorLUT';\nimport storedColorPixelDataToCanvasImageData from './storedColorPixelDataToCanvasImageData';\nimport storedRGBAPixelDataToCanvasImageData from './storedRGBAPixelDataToCanvasImageData';\nimport setToPixelCoordinateSystem from './setToPixelCoordinateSystem';\nimport doesImageNeedToBeRendered from './doesImageNeedToBeRendered';\nimport initializeRenderCanvas from './initializeRenderCanvas';\nimport saveLastRendered from './saveLastRendered';\nimport {\n IImage,\n CPUFallbackViewport,\n CPUFallbackEnabledElement,\n} from '../../../../types';\n\n/**\n * Generates an appropriate Look Up Table to render the given image with the given window width and level (specified in the viewport)\n * Uses an internal cache for performance\n *\n * @param {Object} image The image to be rendered\n * @param {Object} viewport The viewport values used for rendering\n * @returns {Uint8ClampedArray} Look Up Table array.\n * @memberof rendering\n */\nfunction getLut(image: IImage, viewport: CPUFallbackViewport) {\n // If we have a cached lut and it has the right values, return it immediately\n if (\n image.cachedLut !== undefined &&\n image.cachedLut.windowCenter === viewport.voi.windowCenter &&\n image.cachedLut.windowWidth === viewport.voi.windowWidth &&\n image.cachedLut.invert === viewport.invert\n ) {\n return image.cachedLut.lutArray;\n }\n\n // Lut is invalid or not present, regenerate it and cache it\n generateColorLUT(\n image,\n viewport.voi.windowWidth,\n viewport.voi.windowCenter,\n viewport.invert\n );\n image.cachedLut.windowWidth = viewport.voi.windowWidth;\n image.cachedLut.windowCenter = viewport.voi.windowCenter;\n image.cachedLut.invert = viewport.invert;\n\n return image.cachedLut.lutArray;\n}\n\n/**\n * Returns an appropriate canvas to render the Image. If the canvas available in the cache is appropriate\n * it is returned, otherwise adjustments are made. It also sets the color transfer functions.\n *\n * @param enabledElement - The cornerstone enabled element\n * @param image - The image to be rendered\n * @param invalidated - Is pixel data valid\n * @returns An appropriate canvas for rendering the image\n * @memberof rendering\n */\nfunction getRenderCanvas(\n enabledElement: CPUFallbackEnabledElement,\n image: IImage,\n invalidated: boolean\n): HTMLCanvasElement {\n const canvasWasColor =\n enabledElement.renderingTools.lastRenderedIsColor === true;\n\n if (!enabledElement.renderingTools.renderCanvas || !canvasWasColor) {\n enabledElement.renderingTools.renderCanvas =\n document.createElement('canvas');\n }\n\n const renderCanvas = enabledElement.renderingTools.renderCanvas;\n\n // The ww/wc is identity and not inverted - get a canvas with the image rendered into it for\n // Fast drawing\n if (\n enabledElement.viewport.voi.windowWidth === 255 &&\n enabledElement.viewport.voi.windowCenter === 128 &&\n enabledElement.viewport.invert === false &&\n image.getCanvas &&\n image.getCanvas()\n ) {\n return image.getCanvas();\n }\n\n // Apply the lut to the stored pixel data onto the render canvas\n if (\n doesImageNeedToBeRendered(enabledElement, image) === false &&\n invalidated !== true\n ) {\n return renderCanvas;\n }\n\n // If our render canvas does not match the size of this image reset it\n // NOTE: This might be inefficient if we are updating multiple images of different\n // Sizes frequently.\n if (\n renderCanvas.width !== image.width ||\n renderCanvas.height !== image.height\n ) {\n initializeRenderCanvas(enabledElement, image);\n }\n\n // Get the lut to use\n let start = now();\n const colorLUT = getLut(image, enabledElement.viewport);\n\n image.stats = image.stats || {};\n image.stats.lastLutGenerateTime = now() - start;\n\n const renderCanvasData = enabledElement.renderingTools.renderCanvasData;\n const renderCanvasContext = enabledElement.renderingTools.renderCanvasContext;\n\n // The color image voi/invert has been modified - apply the lut to the underlying\n // Pixel data and put it into the renderCanvas\n if (image.rgba) {\n storedRGBAPixelDataToCanvasImageData(\n image,\n colorLUT,\n renderCanvasData.data\n );\n } else {\n storedColorPixelDataToCanvasImageData(\n image,\n colorLUT,\n renderCanvasData.data\n );\n }\n\n start = now();\n renderCanvasContext.putImageData(renderCanvasData, 0, 0);\n image.stats.lastPutImageDataTime = now() - start;\n\n return renderCanvas;\n}\n\n/**\n * API function to render a color image to an enabled element\n *\n * @param {EnabledElement} enabledElement The Cornerstone Enabled Element to redraw\n * @param {Boolean} invalidated - true if pixel data has been invalidated and cached rendering should not be used\n * @returns {void}\n * @memberof rendering\n */\nexport function renderColorImage(\n enabledElement: CPUFallbackEnabledElement,\n invalidated: boolean\n): void {\n if (enabledElement === undefined) {\n throw new Error(\n 'renderColorImage: enabledElement parameter must not be undefined'\n );\n }\n\n const image = enabledElement.image;\n\n if (image === undefined) {\n throw new Error(\n 'renderColorImage: image must be loaded before it can be drawn'\n );\n }\n\n // Get the canvas context and reset the transform\n const context = enabledElement.canvas.getContext('2d');\n\n context.setTransform(1, 0, 0, 1, 0, 0);\n\n // Clear the canvas\n context.fillStyle = 'black';\n context.fillRect(\n 0,\n 0,\n enabledElement.canvas.width,\n enabledElement.canvas.height\n );\n\n // Turn off image smooth/interpolation if pixelReplication is set in the viewport\n context.imageSmoothingEnabled = !enabledElement.viewport.pixelReplication;\n\n // Save the canvas context state and apply the viewport properties\n setToPixelCoordinateSystem(enabledElement, context);\n\n const renderCanvas = getRenderCanvas(enabledElement, image, invalidated);\n\n const sx = enabledElement.viewport.displayedArea.tlhc.x - 1;\n const sy = enabledElement.viewport.displayedArea.tlhc.y - 1;\n const width = enabledElement.viewport.displayedArea.brhc.x - sx;\n const height = enabledElement.viewport.displayedArea.brhc.y - sy;\n\n context.drawImage(renderCanvas, sx, sy, width, height, 0, 0, width, height);\n\n enabledElement.renderingTools = saveLastRendered(enabledElement);\n}\n","import getVOILUT from './getVOILut';\nimport { IImage, CPUFallbackLUT } from '../../../../types';\n\n/**\n * Creates a LUT used while rendering to convert stored pixel values to\n * display pixels\n *\n * @param image - A Cornerstone Image Object\n * @param windowWidth - The Window Width\n * @param windowCenter - The Window Center\n * @param invert - A boolean describing whether or not the image has been inverted\n * @param voiLUT- A Volume of Interest Lookup Table\n *\n * @returns A lookup table to apply to the image\n */\nexport default function (\n image: IImage,\n windowWidth: number | number[],\n windowCenter: number | number[],\n invert: boolean,\n voiLUT?: CPUFallbackLUT\n) {\n const maxPixelValue = image.maxPixelValue;\n const minPixelValue = image.minPixelValue;\n const offset = Math.min(minPixelValue, 0);\n\n if (image.cachedLut === undefined) {\n const length = maxPixelValue - offset + 1;\n\n image.cachedLut = {};\n image.cachedLut.lutArray = new Uint8ClampedArray(length);\n }\n\n const lut = image.cachedLut.lutArray;\n const vlutfn = getVOILUT(\n Array.isArray(windowWidth) ? windowWidth[0] : windowWidth,\n Array.isArray(windowCenter) ? windowCenter[0] : windowCenter,\n voiLUT\n );\n\n if (invert === true) {\n for (\n let storedValue = minPixelValue;\n storedValue <= maxPixelValue;\n storedValue++\n ) {\n lut[storedValue + -offset] = 255 - vlutfn(storedValue);\n }\n } else {\n for (\n let storedValue = minPixelValue;\n storedValue <= maxPixelValue;\n storedValue++\n ) {\n lut[storedValue + -offset] = vlutfn(storedValue);\n }\n }\n\n return lut;\n}\n","import now from './now';\nimport { IImage } from '../../../../types';\n\n/**\n * Converts stored RGBA color pixel values to display pixel values using a LUT.\n *\n * @param {Image} image A Cornerstone Image Object\n * @param {Array} lut Lookup table array\n * @param {Uint8ClampedArray} canvasImageDataData canvasImageData.data buffer filled with white pixels\n *\n * @returns {void}\n * @memberof Internal\n */\nexport default function (\n image: IImage,\n lut: Uint8ClampedArray,\n canvasImageDataData: Uint8ClampedArray\n): void {\n let start = now();\n const pixelData = image.getPixelData();\n\n image.stats.lastGetPixelDataTime = now() - start;\n\n const minPixelValue = image.minPixelValue;\n let canvasImageDataIndex = 0;\n let storedPixelDataIndex = 0;\n const numPixels = pixelData.length;\n\n // NOTE: As of Nov 2014, most javascript engines have lower performance when indexing negative indexes.\n // We have a special code path for this case that improves performance. Thanks to @jpambrun for this enhancement\n start = now();\n if (minPixelValue < 0) {\n while (storedPixelDataIndex < numPixels) {\n canvasImageDataData[canvasImageDataIndex++] =\n lut[pixelData[storedPixelDataIndex++] + -minPixelValue]; // Red\n canvasImageDataData[canvasImageDataIndex++] =\n lut[pixelData[storedPixelDataIndex++] + -minPixelValue]; // Green\n canvasImageDataData[canvasImageDataIndex++] =\n lut[pixelData[storedPixelDataIndex++] + -minPixelValue]; // Blue\n canvasImageDataData[canvasImageDataIndex++] =\n pixelData[storedPixelDataIndex++];\n }\n } else {\n while (storedPixelDataIndex < numPixels) {\n canvasImageDataData[canvasImageDataIndex++] =\n lut[pixelData[storedPixelDataIndex++]]; // Red\n canvasImageDataData[canvasImageDataIndex++] =\n lut[pixelData[storedPixelDataIndex++]]; // Green\n canvasImageDataData[canvasImageDataIndex++] =\n lut[pixelData[storedPixelDataIndex++]]; // Blue\n canvasImageDataData[canvasImageDataIndex++] =\n pixelData[storedPixelDataIndex++];\n }\n }\n image.stats.lastStoredPixelDataToCanvasImageDataTime = now() - start;\n}\n","import now from './now';\nimport { IImage } from '../../../../types';\n\n/**\n * Converts stored color pixel values to display pixel values using a LUT.\n *\n * Note: Skips alpha value for any input image pixel data.\n *\n * @param {Image} image A Cornerstone Image Object\n * @param {Array} lut Lookup table array\n * @param {Uint8ClampedArray} canvasImageDataData canvasImageData.data buffer filled with white pixels\n *\n * @returns {void}\n * @memberof Internal\n */\nexport default function (\n image: IImage,\n lut: Uint8ClampedArray,\n canvasImageDataData: Uint8ClampedArray\n): void {\n let start = now();\n const pixelData = image.getPixelData();\n\n image.stats.lastGetPixelDataTime = now() - start;\n\n const minPixelValue = image.minPixelValue;\n let canvasImageDataIndex = 0;\n let storedPixelDataIndex = 0;\n const numPixels = pixelData.length;\n\n // NOTE: As of Nov 2014, most javascript engines have lower performance when indexing negative indexes.\n // We have a special code path for this case that improves performance. Thanks to @jpambrun for this enhancement\n start = now();\n if (minPixelValue < 0) {\n while (storedPixelDataIndex < numPixels) {\n canvasImageDataData[canvasImageDataIndex++] =\n lut[pixelData[storedPixelDataIndex++] + -minPixelValue]; // Red\n canvasImageDataData[canvasImageDataIndex++] =\n lut[pixelData[storedPixelDataIndex++] + -minPixelValue]; // Green\n canvasImageDataData[canvasImageDataIndex] =\n lut[pixelData[storedPixelDataIndex] + -minPixelValue]; // Blue\n storedPixelDataIndex += 2;\n canvasImageDataIndex += 2;\n }\n } else {\n while (storedPixelDataIndex < numPixels) {\n canvasImageDataData[canvasImageDataIndex++] =\n lut[pixelData[storedPixelDataIndex++]]; // Red\n canvasImageDataData[canvasImageDataIndex++] =\n lut[pixelData[storedPixelDataIndex++]]; // Green\n canvasImageDataData[canvasImageDataIndex] =\n lut[pixelData[storedPixelDataIndex]]; // Blue\n storedPixelDataIndex += 2;\n canvasImageDataIndex += 2;\n }\n }\n image.stats.lastStoredPixelDataToCanvasImageDataTime = now() - start;\n}\n","import now from './now';\nimport { IImage } from '../../../../types';\n\n/**\n * This function transforms stored pixel values into a canvas image data buffer\n * by using a LUT. This is the most performance sensitive code in cornerstone and\n * we use a special trick to make this go as fast as possible. Specifically we\n * use the alpha channel only to control the luminance rather than the red, green and\n * blue channels which makes it over 3x faster. The canvasImageDataData buffer needs\n * to be previously filled with white pixels.\n *\n * NOTE: Attribution would be appreciated if you use this technique!\n *\n * @param {Image} image A Cornerstone Image Object\n * @param {Array} lut Lookup table array\n * @param {Uint8ClampedArray} canvasImageDataData canvasImageData.data buffer filled with white pixels\n *\n * @returns {void}\n * @memberof Internal\n */\nexport default function (\n image: IImage,\n lut: Uint8ClampedArray,\n canvasImageDataData: Uint8ClampedArray\n): void {\n let start = now();\n const pixelData = image.getPixelData();\n\n image.stats.lastGetPixelDataTime = now() - start;\n\n const numPixels = pixelData.length;\n const minPixelValue = image.minPixelValue;\n let canvasImageDataIndex = 3;\n let storedPixelDataIndex = 0;\n\n // NOTE: As of Nov 2014, most javascript engines have lower performance when indexing negative indexes.\n // We have a special code path for this case that improves performance. Thanks to @jpambrun for this enhancement\n\n // Added two paths (Int16Array, Uint16Array) to avoid polymorphic deoptimization in chrome.\n start = now();\n if (pixelData instanceof Int16Array) {\n if (minPixelValue < 0) {\n while (storedPixelDataIndex < numPixels) {\n canvasImageDataData[canvasImageDataIndex] =\n lut[pixelData[storedPixelDataIndex++] + -minPixelValue]; // Alpha\n canvasImageDataIndex += 4;\n }\n } else {\n while (storedPixelDataIndex < numPixels) {\n canvasImageDataData[canvasImageDataIndex] =\n lut[pixelData[storedPixelDataIndex++]]; // Alpha\n canvasImageDataIndex += 4;\n }\n }\n } else if (pixelData instanceof Uint16Array) {\n while (storedPixelDataIndex < numPixels) {\n canvasImageDataData[canvasImageDataIndex] =\n lut[pixelData[storedPixelDataIndex++]]; // Alpha\n canvasImageDataIndex += 4;\n }\n } else if (minPixelValue < 0) {\n while (storedPixelDataIndex < numPixels) {\n canvasImageDataData[canvasImageDataIndex] =\n lut[pixelData[storedPixelDataIndex++] + -minPixelValue]; // Alpha\n canvasImageDataIndex += 4;\n }\n } else {\n while (storedPixelDataIndex < numPixels) {\n canvasImageDataData[canvasImageDataIndex] =\n lut[pixelData[storedPixelDataIndex++]]; // Alpha\n canvasImageDataIndex += 4;\n }\n }\n\n image.stats.lastStoredPixelDataToCanvasImageDataTime = now() - start;\n}\n","import now from './now';\nimport { IImage } from '../../../../types';\n\n/**\n * This function transforms stored pixel values into a canvas image data buffer\n * by using a LUT. This is the most performance sensitive code in cornerstone and\n * we use a special trick to make this go as fast as possible. Specifically we\n * use the alpha channel only to control the luminance rather than the red, green and\n * blue channels which makes it over 3x faster. The canvasImageDataData buffer needs\n * to be previously filled with white pixels.\n *\n * NOTE: Attribution would be appreciated if you use this technique!\n *\n * @param {Image} image A Cornerstone Image Object\n * @param {Array} lut Lookup table array\n * @param {Uint8ClampedArray} canvasImageDataData canvasImageData.data buffer filled with white pixels\n *\n * @returns {void}\n * @memberof Internal\n */\nexport default function (\n image: IImage,\n lutFunction: (value: number) => number,\n canvasImageDataData: Uint8ClampedArray\n): void {\n let start = now();\n const pixelData = image.getPixelData();\n\n image.stats.lastGetPixelDataTime = now() - start;\n\n const numPixels = pixelData.length;\n // const minPixelValue = image.minPixelValue;\n let canvasImageDataIndex = 3;\n let storedPixelDataIndex = 0;\n\n // NOTE: As of Nov 2014, most javascript engines have lower performance when indexing negative indexes.\n // We have a special code path for this case that improves performance. Thanks to @jpambrun for this enhancement\n\n // Added two paths (Int16Array, Uint16Array) to avoid polymorphic deoptimization in chrome.\n start = now();\n\n while (storedPixelDataIndex < numPixels) {\n canvasImageDataData[canvasImageDataIndex] = lutFunction(\n pixelData[storedPixelDataIndex++]\n ); // Alpha\n canvasImageDataIndex += 4;\n }\n\n image.stats.lastStoredPixelDataToCanvasImageDataTime = now() - start;\n}\n","import now from './now';\nimport { IImage } from '../../../../types';\n\n/**\n * This function transforms stored pixel values into a canvas image data buffer\n * by using a LUT.\n *\n * @param {Image} image A Cornerstone Image Object\n * @param {Array} lut Lookup table array\n * @param {Uint8ClampedArray} canvasImageDataData canvasImageData.data buffer filled with white pixels\n *\n * @returns {void}\n * @memberof Internal\n */\nexport default function (\n image: IImage,\n lut: Uint8ClampedArray,\n canvasImageDataData: Uint8ClampedArray\n): void {\n let start = now();\n const pixelData = image.getPixelData();\n\n image.stats.lastGetPixelDataTime = now() - start;\n\n const numPixels = pixelData.length;\n const minPixelValue = image.minPixelValue;\n let canvasImageDataIndex = 0;\n let storedPixelDataIndex = 0;\n let pixelValue;\n\n // NOTE: As of Nov 2014, most javascript engines have lower performance when indexing negative indexes.\n // We have a special code path for this case that improves performance. Thanks to @jpambrun for this enhancement\n\n // Added two paths (Int16Array, Uint16Array) to avoid polymorphic deoptimization in chrome.\n start = now();\n if (pixelData instanceof Int16Array) {\n if (minPixelValue < 0) {\n while (storedPixelDataIndex < numPixels) {\n pixelValue = lut[pixelData[storedPixelDataIndex++] + -minPixelValue];\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = 255; // Alpha\n }\n } else {\n while (storedPixelDataIndex < numPixels) {\n pixelValue = lut[pixelData[storedPixelDataIndex++]];\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = 255; // Alpha\n }\n }\n } else if (pixelData instanceof Uint16Array) {\n while (storedPixelDataIndex < numPixels) {\n pixelValue = lut[pixelData[storedPixelDataIndex++]];\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = 255; // Alpha\n }\n } else if (minPixelValue < 0) {\n while (storedPixelDataIndex < numPixels) {\n pixelValue = lut[pixelData[storedPixelDataIndex++] + -minPixelValue];\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = 255; // Alpha\n }\n } else {\n while (storedPixelDataIndex < numPixels) {\n pixelValue = lut[pixelData[storedPixelDataIndex++]];\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = 255; // Alpha\n }\n }\n\n image.stats.lastStoredPixelDataToCanvasImageDataTime = now() - start;\n}\n","/**\n * Check if two lookup tables match\n *\n * @param {LUT} a A lookup table function\n * @param {LUT} b Another lookup table function\n * @return {boolean} Whether or not they match\n * @memberof rendering\n */\nexport default function (a: any, b: any) {\n // If undefined, they are equal\n if (!a && !b) {\n return true;\n }\n // If one is undefined, not equal\n if (!a || !b) {\n return false;\n }\n\n // Check the unique ids\n return a.id === b.id;\n}\n","import computeAutoVoi from './computeAutoVoi';\nimport lutMatches from './lutMatches';\nimport generateLut from './generateLut';\nimport { IImage, CPUFallbackViewport } from '../../../../types';\n\n/**\n * Retrieve or generate a LUT Array for an Image and Viewport\n *\n * @param {Image} image An Image Object\n * @param {Viewport} viewport An Viewport Object\n * @param {Boolean} invalidated Whether or not the LUT data has been invalidated\n * (e.g. by a change to the windowWidth, windowCenter, or invert viewport parameters).\n * @return {Uint8ClampedArray} LUT Array\n * @memberof rendering\n */\nexport default function (\n image: IImage,\n viewport: CPUFallbackViewport,\n invalidated: boolean\n): Uint8ClampedArray {\n // If we have a cached lut and it has the right values, return it immediately\n if (\n image.cachedLut !== undefined &&\n image.cachedLut.windowCenter === viewport.voi.windowCenter &&\n image.cachedLut.windowWidth === viewport.voi.windowWidth &&\n lutMatches(image.cachedLut.modalityLUT, viewport.modalityLUT) &&\n lutMatches(image.cachedLut.voiLUT, viewport.voiLUT) &&\n image.cachedLut.invert === viewport.invert &&\n invalidated !== true\n ) {\n return image.cachedLut.lutArray;\n }\n\n computeAutoVoi(viewport, image);\n\n // Lut is invalid or not present, regenerate it and cache it\n generateLut(\n image,\n viewport.voi.windowWidth,\n viewport.voi.windowCenter,\n viewport.invert,\n viewport.modalityLUT,\n viewport.voiLUT\n );\n\n image.cachedLut.windowWidth = viewport.voi.windowWidth;\n image.cachedLut.windowCenter = viewport.voi.windowCenter;\n image.cachedLut.invert = viewport.invert;\n image.cachedLut.voiLUT = viewport.voiLUT;\n image.cachedLut.modalityLUT = viewport.modalityLUT;\n\n return image.cachedLut.lutArray;\n}\n","import type { IImage, CPUFallbackViewport } from '../../../../types';\n\n/**\n * Computes the VOI to display all the pixels if no VOI LUT data (Window Width/Window Center or voiLUT) exists on the viewport object.\n *\n * @param viewport - Object containing the viewport properties\n * @param image - An Image loaded by a Cornerstone Image Loader\n */\nexport default function computeAutoVoi(\n viewport: CPUFallbackViewport,\n image: IImage\n): void {\n if (hasVoi(viewport)) {\n return;\n }\n\n const maxVoi = image.maxPixelValue * image.slope + image.intercept;\n const minVoi = image.minPixelValue * image.slope + image.intercept;\n const ww = maxVoi - minVoi;\n const wc = (maxVoi + minVoi) / 2;\n\n if (viewport.voi === undefined) {\n viewport.voi = {\n windowWidth: ww,\n windowCenter: wc,\n };\n } else {\n viewport.voi.windowWidth = ww;\n viewport.voi.windowCenter = wc;\n }\n}\n\n/**\n * Check if viewport has voi LUT data\n * @param viewport - The viewport to check for voi LUT data\n * @returns true viewport has LUT data (Window Width/Window Center or voiLUT). Otherwise, false.\n */\nfunction hasVoi(viewport: CPUFallbackViewport): boolean {\n const hasLut =\n viewport.voiLUT && viewport.voiLUT.lut && viewport.voiLUT.lut.length > 0;\n\n return (\n hasLut ||\n (viewport.voi.windowWidth !== undefined &&\n viewport.voi.windowCenter !== undefined)\n );\n}\n","import getModalityLut from './getModalityLut';\nimport getVOILUT from './getVOILut';\nimport { IImage, CPUFallbackLUT } from '../../../../types';\n\n/**\n * Creates a LUT used while rendering to convert stored pixel values to\n * display pixels\n *\n * @param image - A Cornerstone Image Object\n * @param windowWidth - The Window Width\n * @param windowCenter - The Window Center\n * @param invert - A boolean describing whether or not the image has been inverted\n * @param modalityLUT - A modality Lookup Table\n * @param voiLUT - A Volume of Interest Lookup Table\n *\n * @returns A lookup table to apply to the image\n */\nexport default function (\n image: IImage,\n windowWidth: number,\n windowCenter: number,\n invert: boolean,\n modalityLUT: CPUFallbackLUT,\n voiLUT: CPUFallbackLUT\n): Uint8ClampedArray {\n const maxPixelValue = image.maxPixelValue;\n const minPixelValue = image.minPixelValue;\n const offset = Math.min(minPixelValue, 0);\n\n if (image.cachedLut === undefined) {\n const length = maxPixelValue - offset + 1;\n\n image.cachedLut = {};\n image.cachedLut.lutArray = new Uint8ClampedArray(length);\n }\n\n const lut = image.cachedLut.lutArray;\n\n const mlutfn = getModalityLut(image.slope, image.intercept, modalityLUT);\n const vlutfn = getVOILUT(windowWidth, windowCenter, voiLUT);\n\n if (image.isPreScaled) {\n // if the image is already preScaled, it means that the slop and the intercept\n // are applied and there is no need for a modalityLut\n if (invert === true) {\n for (\n let storedValue = minPixelValue;\n storedValue <= maxPixelValue;\n storedValue++\n ) {\n lut[storedValue + -offset] = 255 - vlutfn(storedValue);\n }\n } else {\n for (\n let storedValue = minPixelValue;\n storedValue <= maxPixelValue;\n storedValue++\n ) {\n lut[storedValue + -offset] = vlutfn(storedValue);\n }\n }\n } else {\n if (invert === true) {\n for (\n let storedValue = minPixelValue;\n storedValue <= maxPixelValue;\n storedValue++\n ) {\n lut[storedValue + -offset] = 255 - vlutfn(mlutfn(storedValue));\n }\n } else {\n for (\n let storedValue = minPixelValue;\n storedValue <= maxPixelValue;\n storedValue++\n ) {\n lut[storedValue + -offset] = vlutfn(mlutfn(storedValue));\n }\n }\n }\n\n return lut;\n}\n","/**\n * Generates a linear modality transformation function\n *\n * See DICOM PS3.3 C.11.1 Modality LUT Module\n *\n * http://dicom.nema.org/medical/Dicom/current/output/chtml/part03/sect_C.11.html\n *\n * @param {Number} slope m in the equation specified by Rescale Intercept (0028,1052).\n * @param {Number} intercept The value b in relationship between stored values (SV) and the output units specified in Rescale Type (0028,1054).\n\n Output units = m*SV + b.\n * @return {function(*): *} A linear modality LUT function. Given a stored pixel it returns the modality pixel value\n * @memberof Internal\n */\nfunction generateLinearModalityLUT(slope, intercept) {\n return (storedPixelValue) => storedPixelValue * slope + intercept;\n}\n\nfunction generateNonLinearModalityLUT(modalityLUT) {\n const minValue = modalityLUT.lut[0];\n const maxValue = modalityLUT.lut[modalityLUT.lut.length - 1];\n const maxValueMapped = modalityLUT.firstValueMapped + modalityLUT.lut.length;\n\n return (storedPixelValue) => {\n if (storedPixelValue < modalityLUT.firstValueMapped) {\n return minValue;\n } else if (storedPixelValue >= maxValueMapped) {\n return maxValue;\n }\n\n return modalityLUT.lut[storedPixelValue];\n };\n}\n\n/**\n * Get the appropriate Modality LUT for the current situation.\n *\n * @param {Number} [slope] m in the equation specified by Rescale Intercept (0028,1052).\n * @param {Number} [intercept] The value b in relationship between stored values (SV) and the output units specified in Rescale Type (0028,1054).\n * @param {Function} [modalityLUT] A modality LUT function. Given a stored pixel it returns the modality pixel value.\n *\n * @return {function(*): *} A modality LUT function. Given a stored pixel it returns the modality pixel value.\n * @memberof Internal\n */\nexport default function (\n slope: number,\n intercept: number,\n modalityLUT: unknown\n) {\n if (modalityLUT) {\n return generateNonLinearModalityLUT(modalityLUT);\n }\n\n return generateLinearModalityLUT(slope, intercept);\n}\n","import storedPixelDataToCanvasImageData from './storedPixelDataToCanvasImageData';\nimport storedPixelDataToCanvasImageDataPET from './storedPixelDataToCanvasImageDataPET';\nimport storedPixelDataToCanvasImageDataRGBA from './storedPixelDataToCanvasImageDataRGBA';\nimport setToPixelCoordinateSystem from './setToPixelCoordinateSystem';\nimport now from './now';\nimport getLut from './getLut';\nimport doesImageNeedToBeRendered from './doesImageNeedToBeRendered';\nimport initializeRenderCanvas from './initializeRenderCanvas';\nimport saveLastRendered from './saveLastRendered';\nimport { IImage, CPUFallbackEnabledElement } from '../../../../types';\n\n/**\n * Returns an appropriate canvas to render the Image. If the canvas available in the cache is appropriate\n * it is returned, otherwise adjustments are made. It also sets the color transfer functions.\n *\n * @param {Object} enabledElement The cornerstone enabled element\n * @param {Object} image The image to be rendered\n * @param {Boolean} invalidated Is pixel data valid\n * @param {Boolean} [useAlphaChannel = true] Will an alpha channel be used\n * @returns {HTMLCanvasElement} An appropriate canvas for rendering the image\n * @memberof rendering\n */\nfunction getRenderCanvas(\n enabledElement: CPUFallbackEnabledElement,\n image: IImage,\n invalidated: boolean,\n useAlphaChannel = true\n): HTMLCanvasElement {\n const canvasWasColor =\n enabledElement.renderingTools.lastRenderedIsColor === true;\n\n if (!enabledElement.renderingTools.renderCanvas || canvasWasColor) {\n enabledElement.renderingTools.renderCanvas =\n document.createElement('canvas');\n initializeRenderCanvas(enabledElement, image);\n }\n\n const renderCanvas = enabledElement.renderingTools.renderCanvas;\n\n if (\n doesImageNeedToBeRendered(enabledElement, image) === false &&\n invalidated !== true\n ) {\n return renderCanvas;\n }\n\n // If our render canvas does not match the size of this image reset it\n // NOTE: This might be inefficient if we are updating multiple images of different\n // Sizes frequently.\n if (\n renderCanvas.width !== image.width ||\n renderCanvas.height !== image.height\n ) {\n initializeRenderCanvas(enabledElement, image);\n }\n\n image.stats = image.stats || {};\n\n const renderCanvasData = enabledElement.renderingTools.renderCanvasData;\n const renderCanvasContext = enabledElement.renderingTools.renderCanvasContext;\n\n let start = now();\n image.stats.lastLutGenerateTime = now() - start;\n\n const { viewport } = enabledElement;\n\n // If modality is 'PT' and the image is scaled then the results are floating points,\n // and we cannot create a lut for it (cannot have float indices). Therefore,\n // we use a mapping function to get the voiLUT from the values by applying\n // the windowLevel and windowWidth.\n if (viewport.modality === 'PT' && image.isPreScaled) {\n const { windowWidth, windowCenter } = viewport.voi;\n const minimum = windowCenter - windowWidth / 2;\n const maximum = windowCenter + windowWidth / 2;\n const range = maximum - minimum;\n const collectedMultiplierTerms = 255.0 / range;\n\n let petVOILutFunction;\n\n if (viewport.invert) {\n petVOILutFunction = (value) =>\n 255 - (value - minimum) * collectedMultiplierTerms;\n } else {\n // Note, don't need to math.floor, that is dealt with by setting the value in the Uint8Array.\n petVOILutFunction = (value) =>\n (value - minimum) * collectedMultiplierTerms;\n }\n\n storedPixelDataToCanvasImageDataPET(\n image,\n petVOILutFunction,\n renderCanvasData.data\n );\n } else {\n // Get the lut to use\n const lut = getLut(image, viewport, invalidated);\n\n if (useAlphaChannel) {\n storedPixelDataToCanvasImageData(image, lut, renderCanvasData.data);\n } else {\n storedPixelDataToCanvasImageDataRGBA(image, lut, renderCanvasData.data);\n }\n }\n\n start = now();\n renderCanvasContext.putImageData(renderCanvasData, 0, 0);\n image.stats.lastPutImageDataTime = now() - start;\n\n return renderCanvas;\n}\n\n/**\n * API function to draw a grayscale image to a given enabledElement\n *\n * @param {EnabledElement} enabledElement The Cornerstone Enabled Element to redraw\n * @param {Boolean} invalidated - true if pixel data has been invalidated and cached rendering should not be used\n * @returns {void}\n * @memberof rendering\n */\nexport function renderGrayscaleImage(\n enabledElement: CPUFallbackEnabledElement,\n invalidated: boolean\n): void {\n if (enabledElement === undefined) {\n throw new Error(\n 'drawImage: enabledElement parameter must not be undefined'\n );\n }\n\n const image = enabledElement.image;\n\n if (image === undefined) {\n throw new Error('drawImage: image must be loaded before it can be drawn');\n }\n\n // Get the canvas context and reset the transform\n const context = enabledElement.canvas.getContext('2d');\n\n context.setTransform(1, 0, 0, 1, 0, 0);\n\n // Clear the canvas\n context.fillStyle = 'black';\n context.fillRect(\n 0,\n 0,\n enabledElement.canvas.width,\n enabledElement.canvas.height\n );\n\n // Turn off image smooth/interpolation if pixelReplication is set in the viewport\n context.imageSmoothingEnabled = !enabledElement.viewport.pixelReplication;\n\n // Save the canvas context state and apply the viewport properties\n setToPixelCoordinateSystem(enabledElement, context);\n\n const renderCanvas = getRenderCanvas(enabledElement, image, invalidated);\n\n const sx = enabledElement.viewport.displayedArea.tlhc.x - 1;\n const sy = enabledElement.viewport.displayedArea.tlhc.y - 1;\n const width = enabledElement.viewport.displayedArea.brhc.x - sx;\n const height = enabledElement.viewport.displayedArea.brhc.y - sy;\n\n context.drawImage(renderCanvas, sx, sy, width, height, 0, 0, width, height);\n\n enabledElement.renderingTools = saveLastRendered(enabledElement);\n}\n","import { Point2, Point4, CPUFallbackLookupTable } from '../../../../types';\n\n// This code was created based on vtkLookupTable\n// http://www.vtk.org/doc/release/5.0/html/a01697.html\n// https://github.com/Kitware/VTK/blob/master/Common/Core/vtkLookupTable.cxx\nconst BELOW_RANGE_COLOR_INDEX = 0;\nconst ABOVE_RANGE_COLOR_INDEX = 1;\nconst NAN_COLOR_INDEX = 2;\n\n/**\n * Converts an HSV (Hue, Saturation, Value) color to RGB (Red, Green, Blue) color value\n * @param {Number} hue A number representing the hue color value\n * @param {any} sat A number representing the saturation color value\n * @param {any} val A number representing the value color value\n * @returns {Numberp[]} An RGB color array\n */\nfunction HSVToRGB(hue, sat, val) {\n if (hue > 1) {\n throw new Error('HSVToRGB expects hue < 1');\n }\n\n const rgb = [];\n\n if (sat === 0) {\n rgb[0] = val;\n rgb[1] = val;\n rgb[2] = val;\n\n return rgb;\n }\n\n const hueCase = Math.floor(hue * 6);\n const frac = 6 * hue - hueCase;\n const lx = val * (1 - sat);\n const ly = val * (1 - sat * frac);\n const lz = val * (1 - sat * (1 - frac));\n\n switch (hueCase) {\n /* 0<hue<1/6 */\n case 0:\n case 6:\n rgb[0] = val;\n rgb[1] = lz;\n rgb[2] = lx;\n break;\n\n /* 1/6<hue<2/6 */\n case 1:\n rgb[0] = ly;\n rgb[1] = val;\n rgb[2] = lx;\n break;\n\n /* 2/6<hue<3/6 */\n case 2:\n rgb[0] = lx;\n rgb[1] = val;\n rgb[2] = lz;\n break;\n\n /* 3/6<hue/4/6 */\n case 3:\n rgb[0] = lx;\n rgb[1] = ly;\n rgb[2] = val;\n break;\n\n /* 4/6<hue<5/6 */\n case 4:\n rgb[0] = lz;\n rgb[1] = lx;\n rgb[2] = val;\n break;\n\n /* 5/6<hue<1 */\n case 5:\n rgb[0] = val;\n rgb[1] = lx;\n rgb[2] = ly;\n break;\n }\n\n return rgb;\n}\n\n/**\n * Maps a value to an index in the table\n * @param {Number} v A double value which table index will be returned.\n * @param {any} p An object that contains the Table \"Range\", the table \"MaxIndex\",\n * A \"Shift\" from first value in the table and the table \"Scale\" value\n * @returns {Number} The mapped index in the table\n * @memberof Colors\n */\nfunction linearIndexLookupMain(v, p) {\n let dIndex;\n\n // NOTE: Added Math.floor since values were not integers? Check VTK source\n if (v < p.Range[0]) {\n dIndex = p.MaxIndex + BELOW_RANGE_COLOR_INDEX + 1.5;\n } else if (v > p.Range[1]) {\n dIndex = p.MaxIndex + ABOVE_RANGE_COLOR_INDEX + 1.5;\n } else {\n dIndex = (v + p.Shift) * p.Scale;\n }\n\n return Math.floor(dIndex);\n}\n\n/**\n * Maps scalar values into colors via a lookup table\n * LookupTable is an object that is used by mapper objects to map scalar values into rgba (red-green-blue-alpha transparency) color specification,\n * or rgba into scalar values. The color table can be created by direct insertion of color values, or by specifying hue, saturation, value, and alpha range and generating a table\n */\nclass LookupTable implements CPUFallbackLookupTable {\n NumberOfColors: number;\n Ramp: string;\n TableRange: Point2;\n HueRange: Point2;\n SaturationRange: Point2;\n ValueRange: Point2;\n AlphaRange: Point2;\n NaNColor: Point4;\n BelowRangeColor: Point4;\n UseBelowRangeColor: boolean;\n AboveRangeColor: Point4;\n UseAboveRangeColor: boolean;\n InputRange: Point2;\n Table: Point4[];\n\n /**\n * Creates a default linear LookupTable object with 256 colors.\n */\n constructor() {\n this.NumberOfColors = 256;\n this.Ramp = 'linear';\n this.TableRange = [0, 255];\n this.HueRange = [0, 0.66667];\n this.SaturationRange = [1, 1];\n this.ValueRange = [1, 1];\n this.AlphaRange = [1, 1];\n this.NaNColor = [128, 0, 0, 255];\n this.BelowRangeColor = [0, 0, 0, 255];\n this.UseBelowRangeColor = true;\n this.AboveRangeColor = [255, 255, 255, 255];\n this.UseAboveRangeColor = true;\n this.InputRange = [0, 255];\n this.Table = [];\n }\n\n /**\n * Specify the number of values (i.e., colors) in the lookup table.\n * @param {Number} number The number of colors in he LookupTable\n * @returns {void}\n * @memberof Colors\n */\n public setNumberOfTableValues(number) {\n this.NumberOfColors = number;\n }\n\n /**\n * Set the shape of the table ramp to either 'linear', 'scurve' or 'sqrt'\n * @param {String} ramp A string value representing the shape of the table. Allowed values are 'linear', 'scurve' or 'sqrt'\n * @returns {void}\n * @memberof Colors\n */\n public setRamp(ramp) {\n this.Ramp = ramp;\n }\n\n /**\n * Sets the minimum/maximum scalar values for scalar mapping.\n * Scalar values less than minimum range value are clamped to minimum range value.\n * Scalar values greater than maximum range value are clamped to maximum range value.\n * @param {Number} start A double representing the minimum scaler value of the LookupTable\n * @param {any} end A double representing the maximum scaler value of the LookupTable\n * @returns {void}\n * @memberof Colors\n */\n public setTableRange(start, end) {\n this.TableRange[0] = start;\n this.TableRange[1] = end;\n }\n\n /**\n * Set the range in hue (using automatic generation). Hue ranges between [0,1].\n * @param {Number} start A double representing the minimum hue value in a range. Min. is 0\n * @param {Number} end A double representing the maximum hue value in a range. Max. is 1\n * @returns {void}\n * @memberof Colors\n */\n public setHueRange(start, end) {\n this.HueRange[0] = start;\n this.HueRange[1] = end;\n }\n\n /**\n * Set the range in saturation (using automatic generation). Saturation ranges between [0,1].\n * @param {Number} start A double representing the minimum Saturation value in a range. Min. is 0\n * @param {Number} end A double representing the maximum Saturation value in a range. Max. is 1\n * @returns {void}\n * @memberof Colors\n */\n public setSaturationRange(start, end) {\n this.SaturationRange[0] = start;\n this.SaturationRange[1] = end;\n }\n\n /**\n * Set the range in value (using automatic generation). Value ranges between [0,1].\n * @param {Numeber } start A double representing the minimum value in a range. Min. is 0\n * @param {Numeber} end A double representing the maximum value in a range. Max. is 1\n * @returns {void}\n * @memberof Colors\n */\n public setValueRange(start, end) {\n // Set the range in value (using automatic generation). Value ranges between [0,1].\n this.ValueRange[0] = start;\n this.ValueRange[1] = end;\n }\n\n /**\n * (Not Used) Sets the range of scalars which will be mapped.\n * @param {Number} start the minimum scalar value in the range\n * @param {Number} end the maximum scalar value in the range\n * @returns {void}\n * @memberof Colors\n */\n public setRange(start, end) {\n this.InputRange[0] = start;\n this.InputRange[1] = end;\n }\n\n /**\n * Set the range in alpha (using automatic generation). Alpha ranges from [0,1].\n * @param {Number} start A double representing the minimum alpha value\n * @param {Number} end A double representing the maximum alpha value\n * @returns {void}\n * @memberof Colors\n */\n public setAlphaRange(start, end) {\n // Set the range in alpha (using automatic generation). Alpha ranges from [0,1].\n this.AlphaRange[0] = start;\n this.AlphaRange[1] = end;\n }\n\n /**\n * Map one value through the lookup table and return the color as an\n * RGBA array of doubles between 0 and 1.\n * @param {Number} scalar A double scalar value which will be mapped to a color in the LookupTable\n * @returns {Number[]} An RGBA array of doubles between 0 and 1\n * @memberof Colors\n */\n public getColor(scalar) {\n return this.mapValue(scalar);\n }\n\n /**\n * Generate lookup table from hue, saturation, value, alpha min/max values. Table is built from linear ramp of each value.\n * @param {Boolean} force true to force the build of the LookupTable. Otherwie, false. This is useful if a lookup table has been defined manually\n * (using SetTableValue) and then an application decides to rebuild the lookup table using the implicit process.\n * @returns {void}\n * @memberof Colors\n */\n public build(force) {\n if (this.Table.length > 1 && !force) {\n return;\n }\n\n // Clear the table\n this.Table = [];\n\n const maxIndex = this.NumberOfColors - 1;\n\n let hinc, sinc, vinc, ainc;\n\n if (maxIndex) {\n hinc = (this.HueRange[1] - this.HueRange[0]) / maxIndex;\n sinc = (this.SaturationRange[1] - this.SaturationRange[0]) / maxIndex;\n vinc = (this.ValueRange[1] - this.ValueRange[0]) / maxIndex;\n ainc = (this.AlphaRange[1] - this.AlphaRange[0]) / maxIndex;\n } else {\n hinc = sinc = vinc = ainc = 0.0;\n }\n\n for (let i = 0; i <= maxIndex; i++) {\n const hue = this.HueRange[0] + i * hinc;\n const sat = this.SaturationRange[0] + i * sinc;\n const val = this.ValueRange[0] + i * vinc;\n const alpha = this.AlphaRange[0] + i * ainc;\n\n const rgb = HSVToRGB(hue, sat, val);\n const c_rgba: Point4 = [0, 0, 0, 0];\n\n switch (this.Ramp) {\n case 'scurve':\n c_rgba[0] = Math.floor(\n 127.5 * (1.0 + Math.cos((1.0 - rgb[0]) * Math.PI))\n );\n c_rgba[1] = Math.floor(\n 127.5 * (1.0 + Math.cos((1.0 - rgb[1]) * Math.PI))\n );\n c_rgba[2] = Math.floor(\n 127.5 * (1.0 + Math.cos((1.0 - rgb[2]) * Math.PI))\n );\n c_rgba[3] = Math.floor(alpha * 255);\n break;\n case 'linear':\n c_rgba[0] = Math.floor(rgb[0] * 255 + 0.5);\n c_rgba[1] = Math.floor(rgb[1] * 255 + 0.5);\n c_rgba[2] = Math.floor(rgb[2] * 255 + 0.5);\n c_rgba[3] = Math.floor(alpha * 255 + 0.5);\n break;\n case 'sqrt':\n c_rgba[0] = Math.floor(Math.sqrt(rgb[0]) * 255 + 0.5);\n c_rgba[1] = Math.floor(Math.sqrt(rgb[1]) * 255 + 0.5);\n c_rgba[2] = Math.floor(Math.sqrt(rgb[2]) * 255 + 0.5);\n c_rgba[3] = Math.floor(Math.sqrt(alpha) * 255 + 0.5);\n break;\n default:\n throw new Error(`Invalid Ramp value (${this.Ramp})`);\n }\n\n this.Table.push(c_rgba);\n }\n\n this.buildSpecialColors();\n }\n\n /**\n * Ensures the out-of-range colors (Below range and Above range) are set correctly.\n * @returns {void}\n * @memberof Colors\n */\n private buildSpecialColors() {\n const numberOfColors = this.NumberOfColors;\n const belowRangeColorIndex = numberOfColors + BELOW_RANGE_COLOR_INDEX;\n const aboveRangeColorIndex = numberOfColors + ABOVE_RANGE_COLOR_INDEX;\n const nanColorIndex = numberOfColors + NAN_COLOR_INDEX;\n\n // Below range color\n if (this.UseBelowRangeColor || numberOfColors === 0) {\n this.Table[belowRangeColorIndex] = this.BelowRangeColor;\n } else {\n // Duplicate the first color in the table.\n this.Table[belowRangeColorIndex] = this.Table[0];\n }\n\n // Above range color\n if (this.UseAboveRangeColor || numberOfColors === 0) {\n this.Table[aboveRangeColorIndex] = this.AboveRangeColor;\n } else {\n // Duplicate the last color in the table.\n this.Table[aboveRangeColorIndex] = this.Table[numberOfColors - 1];\n }\n\n // Always use NanColor\n this.Table[nanColorIndex] = this.NaNColor;\n }\n\n /**\n * Similar to GetColor - Map one value through the lookup table and return the color as an\n * RGBA array of doubles between 0 and 1.\n * @param {Numeber} v A double scalar value which will be mapped to a color in the LookupTable\n * @returns {Number[]} An RGBA array of doubles between 0 and 1\n * @memberof Colors\n */\n private mapValue(v) {\n const index = this.getIndex(v);\n\n if (index < 0) {\n return this.NaNColor;\n } else if (index === 0) {\n if (this.UseBelowRangeColor && v < this.TableRange[0]) {\n return this.BelowRangeColor;\n }\n } else if (index === this.NumberOfColors - 1) {\n if (this.UseAboveRangeColor && v > this.TableRange[1]) {\n return this.AboveRangeColor;\n }\n }\n\n return this.Table[index];\n }\n\n /**\n * Return the table index associated with a particular value.\n * @param {Number} v A double value which table index will be returned.\n * @returns {Number} The index in the LookupTable\n * @memberof Colors\n */\n private getIndex(v) {\n const p = {\n Range: [],\n MaxIndex: this.NumberOfColors - 1,\n Shift: -this.TableRange[0],\n Scale: 1,\n };\n\n if (this.TableRange[1] <= this.TableRange[0]) {\n p.Scale = Number.MAX_VALUE;\n } else {\n p.Scale = p.MaxIndex / (this.TableRange[1] - this.TableRange[0]);\n }\n\n p.Range[0] = this.TableRange[0];\n p.Range[1] = this.TableRange[1];\n\n // First, check whether we have a number...\n if (isNaN(v)) {\n // For backwards compatibility\n return -1;\n }\n\n // Map to an index:\n let index = linearIndexLookupMain(v, p);\n\n // For backwards compatibility, if the index indicates an\n // Out-of-range value, truncate to index range for in-range colors.\n if (index === this.NumberOfColors + BELOW_RANGE_COLOR_INDEX) {\n index = 0;\n } else if (index === this.NumberOfColors + ABOVE_RANGE_COLOR_INDEX) {\n index = this.NumberOfColors - 1;\n }\n\n return index;\n }\n\n /**\n * Directly load color into lookup table. Use [0,1] double values for color component specification.\n * Make sure that you've either used the Build() method or used SetNumberOfTableValues() prior to using this method.\n * @param {Number} index The index in the LookupTable of where to insert the color value\n * @param {Number[]} rgba An array of [0,1] double values for an RGBA color component\n * @returns {void}\n * @memberof Colors\n */\n public setTableValue(index, rgba) {\n // Check if it index, red, green, blue and alpha were passed as parameter\n if (arguments.length === 5) {\n rgba = Array.prototype.slice.call(arguments, 1);\n }\n\n // Check the index to make sure it is valid\n if (index < 0) {\n throw new Error(\n `Can't set the table value for negative index (${index})`\n );\n }\n\n if (index >= this.NumberOfColors) {\n new Error(\n `Index ${index} is greater than the number of colors ${this.NumberOfColors}`\n );\n }\n\n this.Table[index] = rgba;\n\n if (index === 0 || index === this.NumberOfColors - 1) {\n // This is needed due to the way the special colors are stored in\n // The internal table. If Above/BelowRangeColors are not used and\n // The min/max colors are changed in the table with this member\n // Function, then the colors used for values outside the range may\n // Be incorrect. Calling this here ensures the out-of-range colors\n // Are set correctly.\n this.buildSpecialColors();\n }\n }\n}\n\nexport default LookupTable;\n","import LookupTable from './lookupTable';\nimport CPU_COLORMAPS from '../../../../constants/cpuColormaps';\nimport {\n CPUFallbackColormap,\n CPUFallbackColormapData,\n Point4,\n} from '../../../../types';\n\nconst COLOR_TRANSPARENT: Point4 = [0, 0, 0, 0];\n\n/**\n * Generate linearly spaced vectors\n * http://cens.ioc.ee/local/man/matlab/techdoc/ref/linspace.html\n * @param {Number} a A number representing the first vector\n * @param {Number} b A number representing the second vector\n * @param {Number} n The number of linear spaced vectors to generate\n * @returns {Array} An array of points representing linear spaced vectors.\n * @memberof Colors\n */\nfunction linspace(a: number, b: number, n: number): number[] {\n n = n === null ? 100 : n;\n\n const increment = (b - a) / (n - 1);\n const vector = [];\n\n while (n-- > 0) {\n vector.push(a);\n a += increment;\n }\n\n // Make sure the last item will always be \"b\" because most of the\n // Time we'll get numbers like 1.0000000000000002 instead of 1.\n vector[vector.length - 1] = b;\n\n return vector;\n}\n\n/**\n * Returns the \"rank/index\" of the element in a sorted array if found or the highest index if not. Uses (binary search)\n * @param {Array} array A sorted array to search in\n * @param {any} elem the element in the array to search for\n * @returns {number} The rank/index of the element in the given array\n * @memberof Colors\n */\nfunction getRank(array, elem) {\n let left = 0;\n let right = array.length - 1;\n\n while (left <= right) {\n const mid = left + Math.floor((right - left) / 2);\n const midElem = array[mid];\n\n if (midElem === elem) {\n return mid;\n } else if (elem < midElem) {\n right = mid - 1;\n } else {\n left = mid + 1;\n }\n }\n\n return left;\n}\n\n/**\n * Find the indices into a sorted array a such that, if the corresponding elements\n * In v were inserted before the indices, the order of a would be preserved.\n * http://lagrange.univ-lyon1.fr/docs/numpy/1.11.0/reference/generated/numpy.searchsorted.html\n * @param {Array} inputArray The array where the values will be inserted\n * @param {Array} values An array of the values to be inserted into the inputArray\n * @returns {Array} The indices where elements should be inserted to maintain order.\n * @memberof Colors\n */\nfunction searchSorted(inputArray, values) {\n let i;\n const indexes = [];\n const len = values.length;\n\n inputArray.sort(function (a, b) {\n return a - b;\n });\n\n for (i = 0; i < len; i++) {\n indexes[i] = getRank(inputArray, values[i]);\n }\n\n return indexes;\n}\n\n/**\n * Creates an *N* -element 1-d lookup table\n * @param {Number} N The number of elements in the result lookup table\n * @param {Array} data represented by a list of x,y0,y1 mapping correspondences. Each element in this\n * List represents how a value between 0 and 1 (inclusive) represented by x is mapped to\n * A corresponding value between 0 and 1 (inclusive). The two values of y are to allow for\n * Discontinuous mapping functions (say as might be found in a sawtooth) where y0 represents\n * The value of y for values of x <= to that given, and y1 is the value to be used for x >\n * Than that given). The list must start with x=0, end with x=1, and all values of x must be\n * In increasing order. Values between the given mapping points are determined by simple linear\n * Interpolation.\n * @param {any} gamma value denotes a \"gamma curve\" value which adjusts the brightness\n * at the bottom and top of the map.\n * @returns {any[]} an array \"result\" where result[x*(N-1)] gives the closest value for\n * Values of x between 0 and 1.\n * @memberof Colors\n */\nfunction makeMappingArray(N, data, gamma) {\n let i;\n const x = [];\n const y0 = [];\n const y1 = [];\n const lut = [];\n\n gamma = gamma === null ? 1 : gamma;\n\n for (i = 0; i < data.length; i++) {\n const element = data[i];\n\n x.push((N - 1) * element[0]);\n y0.push(element[1]);\n y1.push(element[1]);\n }\n\n const xLinSpace = linspace(0, 1, N);\n\n for (i = 0; i < N; i++) {\n xLinSpace[i] = (N - 1) * Math.pow(xLinSpace[i], gamma);\n }\n\n const xLinSpaceIndexes = searchSorted(x, xLinSpace);\n\n for (i = 1; i < N - 1; i++) {\n const index = xLinSpaceIndexes[i];\n const colorPercent =\n (xLinSpace[i] - x[index - 1]) / (x[index] - x[index - 1]);\n const colorDelta = y0[index] - y1[index - 1];\n\n lut[i] = colorPercent * colorDelta + y1[index - 1];\n }\n\n lut[0] = y1[0];\n lut[N - 1] = y0[data.length - 1];\n\n return lut;\n}\n\n/**\n * Creates a Colormap based on lookup tables using linear segments.\n * @param {{red:Array, green:Array, blue:Array}} segmentedData An object with a red, green and blue entries.\n * Each entry should be a list of x, y0, y1 tuples, forming rows in a table.\n * @param {Number} N The number of elements in the result Colormap\n * @param {any} gamma value denotes a \"gamma curve\" value which adjusts the brightness\n * at the bottom and top of the Colormap.\n * @returns {Array} The created Colormap object\n * @description The lookup table is generated using linear interpolation for each\n * Primary color, with the 0-1 domain divided into any number of\n * Segments.\n * https://github.com/stefanv/matplotlib/blob/3f1a23755e86fef97d51e30e106195f34425c9e3/lib/matplotlib/colors.py#L663\n * @memberof Colors\n */\nfunction createLinearSegmentedColormap(segmentedData, N, gamma) {\n let i;\n const lut = [];\n\n N = N === null ? 256 : N;\n gamma = gamma === null ? 1 : gamma;\n\n const redLut = makeMappingArray(N, segmentedData.red, gamma);\n const greenLut = makeMappingArray(N, segmentedData.green, gamma);\n const blueLut = makeMappingArray(N, segmentedData.blue, gamma);\n\n for (i = 0; i < N; i++) {\n const red = Math.round(redLut[i] * 255);\n const green = Math.round(greenLut[i] * 255);\n const blue = Math.round(blueLut[i] * 255);\n const rgba = [red, green, blue, 255];\n\n lut.push(rgba);\n }\n\n return lut;\n}\n\n/**\n * Return all available colormaps (id and name)\n * @returns {Array<{id,key}>} An array of colormaps with an object containing the \"id\" and display \"name\"\n * @memberof Colors\n */\nexport function getColormapsList() {\n const colormaps = [];\n const keys = Object.keys(CPU_COLORMAPS);\n\n keys.forEach(function (key) {\n if (CPU_COLORMAPS.hasOwnProperty(key)) {\n const colormap = CPU_COLORMAPS[key];\n\n colormaps.push({\n id: key,\n name: colormap.name,\n });\n }\n });\n\n colormaps.sort(function (a, b) {\n const aName = a.name.toLowerCase();\n const bName = b.name.toLowerCase();\n\n if (aName === bName) {\n return 0;\n }\n\n return aName < bName ? -1 : 1;\n });\n\n return colormaps;\n}\n\n/**\n * Return a colorMap object with the provided id and colormapData\n * if the Id matches existent colorMap objects (check colormapsData) the colormapData is ignored.\n * if the colormapData is not empty, the colorMap will be added to the colormapsData list. Otherwise, an empty colorMap object is returned.\n * @param {string} id The ID of the colormap\n * @param {Object} colormapData - An object that can contain a name, numColors, gama, segmentedData and/or colors\n * @returns {*} The Colormap Object\n * @memberof Colors\n */\nexport function getColormap(\n id: string,\n colormapData?: CPUFallbackColormapData\n): CPUFallbackColormap {\n let colormap = CPU_COLORMAPS[id];\n\n if (!colormap) {\n colormap = CPU_COLORMAPS[id] = colormapData || {\n name: '',\n colors: [],\n };\n }\n\n if (!colormap.colors && colormap.segmentedData) {\n colormap.colors = createLinearSegmentedColormap(\n colormap.segmentedData,\n colormap.numColors,\n colormap.gamma\n );\n }\n\n const cpuFallbackColormap: CPUFallbackColormap = {\n getId() {\n return id;\n },\n\n getColorSchemeName() {\n return colormap.name;\n },\n\n setColorSchemeName(name) {\n colormap.name = name;\n },\n\n getNumberOfColors() {\n return colormap.colors.length;\n },\n\n setNumberOfColors(numColors) {\n while (colormap.colors.length < numColors) {\n colormap.colors.push(COLOR_TRANSPARENT);\n }\n\n colormap.colors.length = numColors;\n },\n\n getColor(index) {\n if (this.isValidIndex(index)) {\n return colormap.colors[index];\n }\n\n return COLOR_TRANSPARENT;\n },\n\n getColorRepeating(index) {\n const numColors = colormap.colors.length;\n\n index = numColors ? index % numColors : 0;\n\n return this.getColor(index);\n },\n\n setColor(index, rgba) {\n if (this.isValidIndex(index)) {\n colormap.colors[index] = rgba;\n }\n },\n\n addColor(rgba) {\n colormap.colors.push(rgba);\n },\n\n insertColor(index, rgba) {\n if (this.isValidIndex(index)) {\n colormap.colors.splice(index, 1, rgba);\n }\n },\n\n removeColor(index) {\n if (this.isValidIndex(index)) {\n colormap.colors.splice(index, 1);\n }\n },\n\n clearColors() {\n colormap.colors = [];\n },\n\n buildLookupTable(lut) {\n if (!lut) {\n return;\n }\n\n const numColors = colormap.colors.length;\n\n lut.setNumberOfTableValues(numColors);\n\n for (let i = 0; i < numColors; i++) {\n lut.setTableValue(i, colormap.colors[i]);\n }\n },\n\n createLookupTable() {\n const lut = new LookupTable();\n\n this.buildLookupTable(lut);\n\n return lut;\n },\n\n isValidIndex(index) {\n return index >= 0 && index < colormap.colors.length;\n },\n };\n\n return cpuFallbackColormap;\n}\n","import setToPixelCoordinateSystem from './setToPixelCoordinateSystem';\nimport now from './now';\nimport initializeRenderCanvas from './initializeRenderCanvas';\nimport getLut from './getLut';\nimport saveLastRendered from './saveLastRendered';\nimport doesImageNeedToBeRendered from './doesImageNeedToBeRendered';\nimport storedPixelDataToCanvasImageDataPseudocolorLUT from './storedPixelDataToCanvasImageDataPseudocolorLUT';\nimport storedPixelDataToCanvasImageDataPseudocolorLUTPET from './storedPixelDataToCanvasImageDataPseudocolorLUTPET';\nimport * as colors from '../colors/index';\nimport type { IImage, CPUFallbackEnabledElement } from '../../../../types';\n\nfunction clamp(value: number, min: number, max: number) {\n return Math.max(min, Math.min(max, value));\n}\n\n/**\n * Returns an appropriate canvas to render the Image. If the canvas available in the cache is appropriate\n * it is returned, otherwise adjustments are made. It also sets the color transfer functions.\n *\n * @param {Object} enabledElement The cornerstone enabled element\n * @param {Object} image The image to be rendered\n * @param {Boolean} invalidated Is pixel data valid\n * @returns {HTMLCanvasElement} An appropriate canvas for rendering the image\n * @memberof rendering\n */\nfunction getRenderCanvas(\n enabledElement: CPUFallbackEnabledElement,\n image: IImage,\n invalidated: boolean\n): HTMLCanvasElement {\n if (!enabledElement.renderingTools.renderCanvas) {\n enabledElement.renderingTools.renderCanvas =\n document.createElement('canvas');\n }\n\n const renderCanvas = enabledElement.renderingTools.renderCanvas;\n\n let colormap =\n enabledElement.viewport.colormap || enabledElement.options.colormap;\n\n if (enabledElement.options && enabledElement.options.colormap) {\n console.warn(\n 'enabledElement.options.colormap is deprecated. Use enabledElement.viewport.colormap instead'\n );\n }\n if (colormap && typeof colormap === 'string') {\n colormap = colors.getColormap(colormap);\n }\n\n if (!colormap) {\n throw new Error('renderPseudoColorImage: colormap not found.');\n }\n\n const colormapId = colormap.getId();\n\n if (\n doesImageNeedToBeRendered(enabledElement, image) === false &&\n invalidated !== true &&\n enabledElement.renderingTools.colormapId === colormapId\n ) {\n return renderCanvas;\n }\n\n // If our render canvas does not match the size of this image reset it\n // NOTE: This might be inefficient if we are updating multiple images of different\n // Sizes frequently.\n if (\n renderCanvas.width !== image.width ||\n renderCanvas.height !== image.height\n ) {\n initializeRenderCanvas(enabledElement, image);\n }\n\n // Get the lut to use\n let start = now();\n\n if (\n !enabledElement.renderingTools.colorLUT ||\n invalidated ||\n enabledElement.renderingTools.colormapId !== colormapId\n ) {\n colormap.setNumberOfColors(256);\n enabledElement.renderingTools.colorLUT = colormap.createLookupTable();\n enabledElement.renderingTools.colormapId = colormapId;\n }\n\n const renderCanvasData = enabledElement.renderingTools.renderCanvasData;\n const renderCanvasContext = enabledElement.renderingTools.renderCanvasContext;\n const { viewport } = enabledElement;\n const colorLUT = enabledElement.renderingTools.colorLUT;\n\n if (viewport.modality === 'PT') {\n const { windowWidth, windowCenter } = viewport.voi;\n const minimum = windowCenter - windowWidth / 2;\n const maximum = windowCenter + windowWidth / 2;\n const range = maximum - minimum;\n const collectedMultiplierTerms = 255.0 / range;\n\n let petVOILutFunction;\n\n if (viewport.invert) {\n petVOILutFunction = (value) => {\n return clamp(\n Math.floor(255 - (value - minimum) * collectedMultiplierTerms),\n 0,\n 255\n );\n };\n } else {\n petVOILutFunction = (value) => {\n return clamp(\n Math.floor((value - minimum) * collectedMultiplierTerms),\n 0,\n 255\n );\n };\n }\n\n storedPixelDataToCanvasImageDataPseudocolorLUTPET(\n image,\n petVOILutFunction,\n colorLUT,\n renderCanvasData.data\n );\n } else {\n const lut = getLut(image, enabledElement.viewport, invalidated);\n\n image.stats = image.stats || {};\n image.stats.lastLutGenerateTime = now() - start;\n\n storedPixelDataToCanvasImageDataPseudocolorLUT(\n image,\n lut,\n colorLUT,\n renderCanvasData.data\n );\n }\n\n start = now();\n renderCanvasContext.putImageData(renderCanvasData, 0, 0);\n image.stats.lastPutImageDataTime = now() - start;\n\n return renderCanvas;\n}\n\n/**\n * API function to draw a pseudo-color image to a given enabledElement\n *\n * @param {EnabledElement} enabledElement The Cornerstone Enabled Element to redraw\n * @param {Boolean} invalidated - true if pixel data has been invalidated and cached rendering should not be used\n * @returns {void}\n * @memberof rendering\n */\nexport function renderPseudoColorImage(\n enabledElement: CPUFallbackEnabledElement,\n invalidated: boolean\n): void {\n if (enabledElement === undefined) {\n throw new Error(\n 'drawImage: enabledElement parameter must not be undefined'\n );\n }\n\n const image = enabledElement.image;\n\n if (image === undefined) {\n throw new Error('drawImage: image must be loaded before it can be drawn');\n }\n\n // Get the canvas context and reset the transform\n const context = enabledElement.canvas.getContext('2d');\n\n context.setTransform(1, 0, 0, 1, 0, 0);\n\n // Clear the canvas\n context.fillStyle = 'black';\n context.fillRect(\n 0,\n 0,\n enabledElement.canvas.width,\n enabledElement.canvas.height\n );\n\n // Turn off image smooth/interpolation if pixelReplication is set in the viewport\n context.imageSmoothingEnabled = !enabledElement.viewport.pixelReplication;\n\n // Save the canvas context state and apply the viewport properties\n setToPixelCoordinateSystem(enabledElement, context);\n\n // If no options are set we will retrieve the renderCanvas through the\n // Normal Canvas rendering path\n // TODO: Add WebGL support for pseudocolor pipeline\n const renderCanvas = getRenderCanvas(enabledElement, image, invalidated);\n\n const sx = enabledElement.viewport.displayedArea.tlhc.x - 1;\n const sy = enabledElement.viewport.displayedArea.tlhc.y - 1;\n const width = enabledElement.viewport.displayedArea.brhc.x - sx;\n const height = enabledElement.viewport.displayedArea.brhc.y - sy;\n\n context.drawImage(renderCanvas, sx, sy, width, height, 0, 0, width, height);\n\n enabledElement.renderingTools = saveLastRendered(enabledElement);\n}\n","import * as colors from '../colors/index';\nimport now from './now';\nimport type { IImage, CPUFallbackLookupTable } from '../../../../types';\n\n/**\n *\n * @param {Image} image A Cornerstone Image Object\n * @param {Array} grayscaleLut Lookup table array\n * @param {LookupTable|Array} colorLUT Lookup table array\n * @param {Uint8ClampedArray} canvasImageDataData canvasImageData.data buffer filled with white pixels\n *\n * @returns {void}\n * @memberof Internal\n */\nfunction storedPixelDataToCanvasImageDataPseudocolorLUTPET(\n image: IImage,\n lutFunction: (value: number) => number,\n colorLUT: CPUFallbackLookupTable,\n canvasImageDataData: Uint8ClampedArray\n): void {\n let start = now();\n const pixelData = image.getPixelData();\n\n image.stats.lastGetPixelDataTime = now() - start;\n\n const numPixels = pixelData.length;\n const minPixelValue = image.minPixelValue;\n let canvasImageDataIndex = 0;\n let storedPixelDataIndex = 0;\n let grayscale;\n let rgba;\n let clut;\n\n start = now();\n\n if (colorLUT instanceof colors.LookupTable) {\n clut = colorLUT.Table;\n } else {\n clut = colorLUT;\n }\n\n if (minPixelValue < 0) {\n while (storedPixelDataIndex < numPixels) {\n grayscale = lutFunction(\n pixelData[storedPixelDataIndex++] + -minPixelValue\n );\n\n rgba = clut[grayscale];\n canvasImageDataData[canvasImageDataIndex++] = rgba[0];\n canvasImageDataData[canvasImageDataIndex++] = rgba[1];\n canvasImageDataData[canvasImageDataIndex++] = rgba[2];\n canvasImageDataData[canvasImageDataIndex++] = rgba[3];\n }\n } else {\n while (storedPixelDataIndex < numPixels) {\n grayscale = lutFunction(pixelData[storedPixelDataIndex++]);\n rgba = clut[grayscale];\n canvasImageDataData[canvasImageDataIndex++] = rgba[0];\n canvasImageDataData[canvasImageDataIndex++] = rgba[1];\n canvasImageDataData[canvasImageDataIndex++] = rgba[2];\n canvasImageDataData[canvasImageDataIndex++] = rgba[3];\n }\n }\n\n image.stats.lastStoredPixelDataToCanvasImageDataTime = now() - start;\n}\n\nexport default storedPixelDataToCanvasImageDataPseudocolorLUTPET;\n","import * as colors from '../colors/index';\nimport now from './now';\nimport type { IImage, CPUFallbackLookupTable } from '../../../../types';\n\n/**\n *\n * @param {Image} image A Cornerstone Image Object\n * @param {Array} grayscaleLut Lookup table array\n * @param {LookupTable|Array} colorLUT Lookup table array\n * @param {Uint8ClampedArray} canvasImageDataData canvasImageData.data buffer filled with white pixels\n *\n * @returns {void}\n * @memberof Internal\n */\nfunction storedPixelDataToCanvasImageDataPseudocolorLUT(\n image: IImage,\n grayscaleLut: Uint8ClampedArray,\n colorLUT: CPUFallbackLookupTable,\n canvasImageDataData: Uint8ClampedArray\n): void {\n let start = now();\n const pixelData = image.getPixelData();\n\n image.stats.lastGetPixelDataTime = now() - start;\n\n const numPixels = pixelData.length;\n const minPixelValue = image.minPixelValue;\n let canvasImageDataIndex = 0;\n let storedPixelDataIndex = 0;\n let grayscale;\n let rgba;\n let clut;\n\n start = now();\n\n if (colorLUT instanceof colors.LookupTable) {\n clut = colorLUT.Table;\n } else {\n clut = colorLUT;\n }\n\n if (minPixelValue < 0) {\n while (storedPixelDataIndex < numPixels) {\n grayscale =\n grayscaleLut[pixelData[storedPixelDataIndex++] + -minPixelValue];\n rgba = clut[grayscale];\n canvasImageDataData[canvasImageDataIndex++] = rgba[0];\n canvasImageDataData[canvasImageDataIndex++] = rgba[1];\n canvasImageDataData[canvasImageDataIndex++] = rgba[2];\n canvasImageDataData[canvasImageDataIndex++] = rgba[3];\n }\n } else {\n while (storedPixelDataIndex < numPixels) {\n grayscale = grayscaleLut[pixelData[storedPixelDataIndex++]];\n rgba = clut[grayscale];\n canvasImageDataData[canvasImageDataIndex++] = rgba[0];\n canvasImageDataData[canvasImageDataIndex++] = rgba[1];\n canvasImageDataData[canvasImageDataIndex++] = rgba[2];\n canvasImageDataData[canvasImageDataIndex++] = rgba[3];\n }\n }\n\n image.stats.lastStoredPixelDataToCanvasImageDataTime = now() - start;\n}\n\nexport default storedPixelDataToCanvasImageDataPseudocolorLUT;\n","import now from './rendering/now';\nimport { renderColorImage } from './rendering/renderColorImage';\nimport { renderGrayscaleImage } from './rendering/renderGrayscaleImage';\nimport { renderPseudoColorImage } from './rendering/renderPseudoColorImage';\nimport { CPUFallbackEnabledElement } from '../../../types';\n\n/**\n * Draw an image to a given enabled element synchronously\n *\n * @param enabledElement - An enabled element to draw into\n * @param invalidated - true if pixel data has been invalidated and cached rendering should not be used\n */\nexport default function (\n enabledElement: CPUFallbackEnabledElement,\n invalidated: boolean\n): void {\n const image = enabledElement.image;\n\n // Check if enabledElement can be redrawn\n if (!enabledElement.canvas || !enabledElement.image) {\n return;\n }\n\n // Start measuring the time needed to draw the image.\n const start = now();\n\n image.stats = {\n lastGetPixelDataTime: -1.0,\n lastStoredPixelDataToCanvasImageDataTime: -1.0,\n lastPutImageDataTime: -1.0,\n lastRenderTime: -1.0,\n lastLutGenerateTime: -1.0,\n };\n\n if (image) {\n let render = image.render;\n\n if (!render) {\n if (enabledElement.viewport.colormap) {\n render = renderPseudoColorImage;\n } else if (image.color) {\n render = renderColorImage;\n } else {\n render = renderGrayscaleImage;\n }\n }\n\n render(enabledElement, invalidated);\n }\n\n // Calculate how long it took to draw the image/layers\n const renderTimeInMs = now() - start;\n\n image.stats.lastRenderTime = renderTimeInMs;\n\n enabledElement.invalid = false;\n enabledElement.needsRedraw = false;\n}\n","import calculateTransform from './calculateTransform';\nimport {\n CPUFallbackEnabledElement,\n CPUFallbackTransform,\n} from '../../../../types';\n\nexport default function (\n enabledElement: CPUFallbackEnabledElement\n): CPUFallbackTransform {\n // Todo: for some reason using the cached transfer after the first call\n // does not give correct transform.\n // if (enabledElement.transform) {\n // return enabledElement.transform;\n // }\n\n return calculateTransform(enabledElement);\n}\n","import getTransform from './getTransform';\n\nimport { Point2, CPUFallbackEnabledElement } from '../../../../types';\n\n/**\n * Converts a point in the canvas coordinate system to the pixel coordinate system\n * system. This can be used to reset tools' image coordinates after modifications\n * have been made in canvas space (e.g. moving a tool by a few cm, independent of\n * image resolution).\n *\n * @param element - The Cornerstone element within which the input point lies\n * @param pt - The input point in the canvas coordinate system\n *\n * @returns The transformed point in the pixel coordinate system\n */\nexport default function (\n enabledElement: CPUFallbackEnabledElement,\n pt: Point2\n): Point2 {\n const transform = getTransform(enabledElement);\n\n transform.invert();\n\n return transform.transformPoint(pt);\n}\n","import getTransform from './getTransform';\nimport { CPUFallbackEnabledElement, Point2 } from '../../../../types';\n\n/**\n * Converts a point in the pixel coordinate system to the canvas coordinate system\n * system. This can be used to render using canvas context without having the weird\n * side effects that come from scaling and non square pixels\n *\n * @param {HTMLDivElement} element An HTML Element enabled for Cornerstone\n * @param {{x: Number, y: Number}} pt The transformed point in the pixel coordinate system\n *\n * @returns {{x: Number, y: Number}} The input point in the canvas coordinate system\n * @memberof PixelCoordinateSystem\n */\nexport default function (\n enabledElement: CPUFallbackEnabledElement,\n pt: Point2\n): Point2 {\n const transform = getTransform(enabledElement);\n\n return transform.transformPoint(pt);\n}\n","import { CPUFallbackViewport } from '../../../../types';\n\nconst state = {\n viewport: {},\n};\n\n/**\n * Sets new default values for `getDefaultViewport`\n *\n * @param {Object} viewport - Object that sets new default values for getDefaultViewport\n * @returns {undefined}\n */\nexport default function (viewport: CPUFallbackViewport): void {\n state.viewport = viewport || {};\n}\n\nexport { state };\n","/**\n * Check if the supplied parameter is undefined and throws and error\n * @param {any} checkParam the parameter to validate for undefined\n * @param {any} errorMsg the error message to be thrown\n * @returns {void}\n * @memberof internal\n */\nexport function validateParameterUndefined(\n checkParam: any | undefined,\n errorMsg: string\n): void {\n if (checkParam === undefined) {\n throw new Error(errorMsg);\n }\n}\n\n/**\n * Check if the supplied parameter is undefined or null and throws and error\n * @param {any} checkParam the parameter to validate for undefined\n * @param {any} errorMsg the error message to be thrown\n * @returns {void}\n * @memberof internal\n */\nexport function validateParameterUndefinedOrNull(\n checkParam: any | null | undefined,\n errorMsg: string\n): void {\n if (checkParam === undefined || checkParam === null) {\n throw new Error(errorMsg);\n }\n}\n","import { validateParameterUndefinedOrNull } from './validator';\nimport { IImage } from '../../../../types';\n\n/**\n * Check if the angle is rotated\n * @param {Number} rotation the rotation angle\n * @returns {Boolean} true if the angle is rotated; Otherwise, false.\n * @memberof Internal\n */\nfunction isRotated(rotation?: number | null): boolean {\n return !(\n rotation === null ||\n rotation === undefined ||\n rotation === 0 ||\n rotation === 180\n );\n}\n\n/**\n * Retrieves the current image dimensions given an enabled element\n *\n * @param {any} image The Cornerstone image.\n * @param {Number} rotation Optional. The rotation angle of the image.\n * @return {{width:Number, height:Number}} The Image dimensions\n * @memberof Internal\n */\nexport default function (\n image: IImage,\n rotation = null\n): { height: number; width: number } {\n validateParameterUndefinedOrNull(\n image,\n 'getImageSize: parameter image must not be undefined'\n );\n validateParameterUndefinedOrNull(\n image.width,\n 'getImageSize: parameter image must have width'\n );\n validateParameterUndefinedOrNull(\n image.height,\n 'getImageSize: parameter image must have height'\n );\n\n if (isRotated(rotation)) {\n return {\n height: image.width,\n width: image.height,\n };\n }\n\n return {\n width: image.width,\n height: image.height,\n };\n}\n","import { validateParameterUndefinedOrNull } from './validator';\nimport getImageSize from './getImageSize';\nimport { IImage } from '../../../../types';\n\n/**\n * Calculates the horizontal, vertical and minimum scale factor for an image\n @param canvas - The window size where the image is displayed. This can be any HTML element or structure with a width, height fields (e.g. canvas).\n * @param image - The cornerstone image object\n * @param rotation - The rotation angle of the image.\n * @returns The calculated horizontal, vertical and minimum scale factor\n */\nexport default function (\n canvas: HTMLCanvasElement,\n image: IImage,\n rotation: number | null = null\n): {\n verticalScale: number;\n horizontalScale: number;\n scaleFactor: number;\n} {\n validateParameterUndefinedOrNull(\n canvas,\n 'getImageScale: parameter canvas must not be undefined'\n );\n validateParameterUndefinedOrNull(\n image,\n 'getImageScale: parameter image must not be undefined'\n );\n\n const imageSize = getImageSize(image, rotation);\n const rowPixelSpacing = image.rowPixelSpacing || 1;\n const columnPixelSpacing = image.columnPixelSpacing || 1;\n let verticalRatio = 1;\n let horizontalRatio = 1;\n\n if (rowPixelSpacing < columnPixelSpacing) {\n horizontalRatio = columnPixelSpacing / rowPixelSpacing;\n } else {\n // even if they are equal we want to calculate this ratio (the ration might be 0.5)\n verticalRatio = rowPixelSpacing / columnPixelSpacing;\n }\n\n const verticalScale = canvas.height / imageSize.height / verticalRatio;\n const horizontalScale = canvas.width / imageSize.width / horizontalRatio;\n\n // Fit image to window\n return {\n verticalScale,\n horizontalScale,\n scaleFactor: Math.min(horizontalScale, verticalScale),\n };\n}\n","import createViewport from './createViewport';\nimport getImageFitScale from './getImageFitScale';\nimport {\n IImage,\n CPUFallbackColormap,\n CPUFallbackViewport,\n} from '../../../../types';\n\n/**\n * Creates a new viewport object containing default values for the image and canvas\n *\n * @param canvas - A Canvas DOM element\n * @param image - A Cornerstone Image Object\n * @returns viewport - object\n */\nexport default function (\n canvas: HTMLCanvasElement,\n image: IImage,\n modality?: string,\n colormap?: CPUFallbackColormap\n): CPUFallbackViewport {\n if (canvas === undefined) {\n throw new Error(\n 'getDefaultViewport: parameter canvas must not be undefined'\n );\n }\n\n if (image === undefined) {\n return createViewport();\n }\n\n // Fit image to window\n const scale = getImageFitScale(canvas, image, 0).scaleFactor;\n\n let voi;\n\n if (modality === 'PT' && image.isPreScaled) {\n voi = {\n windowWidth: 5,\n windowCenter: 2.5,\n };\n } else if (\n image.windowWidth !== undefined &&\n image.windowCenter !== undefined\n ) {\n voi = {\n windowWidth: Array.isArray(image.windowWidth)\n ? image.windowWidth[0]\n : image.windowWidth,\n windowCenter: Array.isArray(image.windowCenter)\n ? image.windowCenter[0]\n : image.windowCenter,\n };\n }\n\n return {\n scale,\n translation: {\n x: 0,\n y: 0,\n },\n voi,\n invert: image.invert,\n pixelReplication: false,\n rotation: 0,\n hflip: false,\n vflip: false,\n modalityLUT: image.modalityLUT,\n modality,\n voiLUT: image.voiLUT,\n colormap: colormap !== undefined ? colormap : image.colormap,\n displayedArea: {\n tlhc: {\n x: 1,\n y: 1,\n },\n brhc: {\n x: image.columns,\n y: image.rows,\n },\n rowPixelSpacing:\n image.rowPixelSpacing === undefined ? 1 : image.rowPixelSpacing,\n columnPixelSpacing:\n image.columnPixelSpacing === undefined ? 1 : image.columnPixelSpacing,\n presentationSizeMode: 'NONE',\n },\n };\n}\n","import { state } from './setDefaultViewport';\nimport {\n CPUFallbackViewportDisplayedArea,\n CPUFallbackViewport,\n} from '../../../../types';\n\n// eslint-disable-next-line valid-jsdoc\n/**\n * Creates the default displayed area.\n * C.10.4 Displayed Area Module: This Module describes Attributes required to define a Specified Displayed Area space.\n *\n * @returns {tlhc: {x,y}, brhc: {x, y},rowPixelSpacing: Number, columnPixelSpacing: Number, presentationSizeMode: Number} displayedArea object\n * @memberof Internal\n */\nfunction createDefaultDisplayedArea(): CPUFallbackViewportDisplayedArea {\n return {\n // Top Left Hand Corner\n tlhc: {\n x: 1,\n y: 1,\n },\n // Bottom Right Hand Corner\n brhc: {\n x: 1,\n y: 1,\n },\n rowPixelSpacing: 1,\n columnPixelSpacing: 1,\n presentationSizeMode: 'NONE',\n };\n}\n\n/**\n * Creates a new viewport object containing default values\n *\n * @returns {Viewport} viewport object\n * @memberof Internal\n */\nexport default function createViewport(): CPUFallbackViewport {\n const displayedArea = createDefaultDisplayedArea();\n const initialDefaultViewport = {\n scale: 1,\n translation: {\n x: 0,\n y: 0,\n },\n voi: {\n windowWidth: undefined,\n windowCenter: undefined,\n },\n invert: false,\n pixelReplication: false,\n rotation: 0,\n hflip: false,\n vflip: false,\n modalityLUT: undefined,\n voiLUT: undefined,\n colormap: undefined,\n labelmap: false,\n displayedArea,\n };\n\n return Object.assign({}, initialDefaultViewport, state.viewport);\n}\n","import getImageFitScale from './getImageFitScale';\nimport { CPUFallbackEnabledElement } from '../../../../types';\n\n/**\n * Adjusts an image's scale and translation so the image is centered and all pixels\n * in the image are viewable.\n *\n * @param element - The Cornerstone element to update\n */\nexport default function (enabledElement: CPUFallbackEnabledElement): void {\n const { image } = enabledElement;\n\n // The new scale is the minimum of the horizontal and vertical scale values\n enabledElement.viewport.scale = getImageFitScale(\n enabledElement.canvas,\n image,\n enabledElement.viewport.rotation\n ).scaleFactor;\n\n enabledElement.viewport.translation.x = 0;\n enabledElement.viewport.translation.y = 0;\n}\n","import fitToWindow from './fitToWindow';\nimport getImageSize from './getImageSize';\nimport { CPUFallbackEnabledElement } from '../../../../types';\n\n/**\n * This module is responsible for enabling an element to display images with cornerstone\n *\n * @param {HTMLDivElement} element The DOM element enabled for Cornerstone\n * @param {HTMLDivElement} canvas The Canvas DOM element within the DOM element enabled for Cornerstone\n * @returns {void}\n */\nfunction setCanvasSize(enabledElement: CPUFallbackEnabledElement) {\n const { canvas } = enabledElement;\n const { clientWidth, clientHeight } = canvas;\n\n // Set the canvas to be same resolution as the client.\n if (canvas.width !== clientWidth || canvas.height !== clientHeight) {\n canvas.width = clientWidth;\n canvas.height = clientHeight;\n }\n}\n\n/**\n * Checks if the image of a given enabled element fitted the window\n * before the resize\n *\n * @param {EnabledElement} enabledElement The Cornerstone Enabled Element\n * @param {number} oldCanvasWidth The width of the canvas before the resize\n * @param {number} oldCanvasHeight The height of the canvas before the resize\n * @return {Boolean} true if it fitted the windows, false otherwise\n */\nfunction wasFitToWindow(\n enabledElement: CPUFallbackEnabledElement,\n oldCanvasWidth: number,\n oldCanvasHeight: number\n): boolean {\n const scale = enabledElement.viewport.scale;\n const imageSize = getImageSize(\n enabledElement.image,\n enabledElement.viewport.rotation\n );\n const imageWidth = Math.round(imageSize.width * scale);\n const imageHeight = Math.round(imageSize.height * scale);\n const x = enabledElement.viewport.translation.x;\n const y = enabledElement.viewport.translation.y;\n\n return (\n (imageWidth === oldCanvasWidth && imageHeight <= oldCanvasHeight) ||\n (imageWidth <= oldCanvasWidth &&\n imageHeight === oldCanvasHeight &&\n x === 0 &&\n y === 0)\n );\n}\n\n/**\n * Rescale the image relative to the changed size of the canvas\n *\n * @param {EnabledElement} enabledElement The Cornerstone Enabled Element\n * @param {number} oldCanvasWidth The width of the canvas before the resize\n * @param {number} oldCanvasHeight The height of the canvas before the resize\n * @return {void}\n */\nfunction relativeRescale(\n enabledElement: CPUFallbackEnabledElement,\n oldCanvasWidth: number,\n oldCanvasHeight: number\n): void {\n const scale = enabledElement.viewport.scale;\n const canvasWidth = enabledElement.canvas.width;\n const canvasHeight = enabledElement.canvas.height;\n const relWidthChange = canvasWidth / oldCanvasWidth;\n const relHeightChange = canvasHeight / oldCanvasHeight;\n const relChange = Math.sqrt(relWidthChange * relHeightChange);\n\n enabledElement.viewport.scale = relChange * scale;\n}\n\n/**\n * Resizes an enabled element and optionally fits the image to window\n *\n * @param {HTMLDivElement} element The DOM element enabled for Cornerstone\n * @param {Boolean} forceFitToWindow true to to force a refit, false to rescale accordingly\n * @returns {void}\n */\nexport default function (\n enabledElement: CPUFallbackEnabledElement,\n forceFitToWindow = false\n): void {\n const oldCanvasWidth = enabledElement.canvas.width;\n const oldCanvasHeight = enabledElement.canvas.height;\n\n setCanvasSize(enabledElement);\n\n if (enabledElement.image === undefined) {\n return;\n }\n\n if (\n forceFitToWindow ||\n wasFitToWindow(enabledElement, oldCanvasWidth, oldCanvasHeight)\n ) {\n // Fit the image to the window again if it fitted before the resize\n fitToWindow(enabledElement);\n } else {\n // Adapt the scale of a zoomed or panned image relative to the size change\n relativeRescale(enabledElement, oldCanvasWidth, oldCanvasHeight);\n }\n}\n","import vtkDataArray from '@kitware/vtk.js/Common/Core/DataArray';\nimport vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData';\nimport type { vtkImageData as vtkImageDataType } from '@kitware/vtk.js/Common/DataModel/ImageData';\nimport _cloneDeep from 'lodash.clonedeep';\nimport vtkCamera from '@kitware/vtk.js/Rendering/Core/Camera';\nimport { vec2, vec3, mat4 } from 'gl-matrix';\nimport vtkImageMapper from '@kitware/vtk.js/Rendering/Core/ImageMapper';\nimport vtkImageSlice from '@kitware/vtk.js/Rendering/Core/ImageSlice';\nimport vtkColorTransferFunction from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction';\nimport * as metaData from '../metaData';\nimport Viewport from './Viewport';\nimport eventTarget from '../eventTarget';\nimport Events from '../enums/Events';\nimport {\n triggerEvent,\n isEqual,\n invertRgbTransferFunction,\n windowLevel as windowLevelUtil,\n imageIdToURI,\n isImageActor,\n} from '../utilities';\nimport {\n Point2,\n Point3,\n VOIRange,\n ICamera,\n IImage,\n IImageData,\n CPUIImageData,\n PTScaling,\n Scaling,\n StackViewportProperties,\n FlipDirection,\n ActorEntry,\n CPUFallbackEnabledElement,\n CPUFallbackColormapData,\n EventTypes,\n IStackViewport,\n VolumeActor,\n Mat3,\n} from '../types';\nimport { ViewportInput } from '../types/IViewport';\nimport drawImageSync from './helpers/cpuFallback/drawImageSync';\nimport { getColormap } from './helpers/cpuFallback/colors/index';\n\nimport { loadAndCacheImage } from '../imageLoader';\nimport imageLoadPoolManager from '../requestPool/imageLoadPoolManager';\nimport InterpolationType from '../enums/InterpolationType';\nimport canvasToPixel from './helpers/cpuFallback/rendering/canvasToPixel';\nimport pixelToCanvas from './helpers/cpuFallback/rendering/pixelToCanvas';\nimport getDefaultViewport from './helpers/cpuFallback/rendering/getDefaultViewport';\nimport calculateTransform from './helpers/cpuFallback/rendering/calculateTransform';\nimport resize from './helpers/cpuFallback/rendering/resize';\n\nimport resetCamera from './helpers/cpuFallback/rendering/resetCamera';\nimport { Transform } from './helpers/cpuFallback/rendering/transform';\nimport { getShouldUseCPURendering } from '../init';\nimport RequestType from '../enums/RequestType';\nimport {\n StackViewportNewStackEventDetail,\n StackViewportScrollEventDetail,\n VoiModifiedEventDetail,\n} from '../types/EventTypes';\nimport cache from '../cache';\nimport correctShift from './helpers/cpuFallback/rendering/correctShift';\nimport { ImageActor } from '../types/IActor';\nimport isRgbaSourceRgbDest from './helpers/isRgbaSourceRgbDest';\n\nconst EPSILON = 1; // Slice Thickness\n\ninterface ImagePixelModule {\n bitsAllocated: number;\n bitsStored: number;\n samplesPerPixel: number;\n highBit: number;\n photometricInterpretation: string;\n pixelRepresentation: string;\n windowWidth: number;\n windowCenter: number;\n modality: string;\n}\n\ninterface ImageDataMetaData {\n bitsAllocated: number;\n numComps: number;\n origin: Point3;\n direction: Mat3;\n dimensions: Point3;\n spacing: Point3;\n numVoxels: number;\n imagePlaneModule: unknown;\n imagePixelModule: ImagePixelModule;\n}\n\ninterface ImagePlaneModule {\n columnCosines?: Point3;\n columnPixelSpacing?: number;\n imageOrientationPatient?: Float32Array;\n imagePositionPatient?: Point3;\n pixelSpacing?: Point2;\n rowCosines?: Point3;\n rowPixelSpacing?: number;\n sliceLocation?: number;\n sliceThickness?: number;\n frameOfReferenceUID: string;\n columns: number;\n rows: number;\n}\n\n// TODO This needs to be exposed as its published to consumers.\ntype CalibrationEvent = {\n rowScale: number;\n columnScale: number;\n};\n\n/**\n * An object representing a single stack viewport, which is a camera\n * looking into an internal viewport, and an associated target output `canvas`.\n *\n * StackViewports can be rendered using both GPU and a fallback CPU is the GPU\n * is not available (or low performance). Read more about StackViewports in\n * the documentation section of this website.\n */\nclass StackViewport extends Viewport implements IStackViewport {\n private imageIds: Array<string>;\n // current imageIdIndex that is rendered in the viewport\n private currentImageIdIndex: number;\n // the imageIdIndex that is targeted to be loaded with scrolling but has not initiated loading yet\n private targetImageIdIndex: number;\n // setTimeout if the image is debounced to be loaded\n private debouncedTimeout: number;\n\n // Viewport Properties\n private voiRange: VOIRange;\n private initialVOIRange: VOIRange;\n private invert = false;\n private interpolationType: InterpolationType;\n\n // Helpers\n private _imageData: vtkImageDataType;\n private cameraFocalPointOnRender: Point3; // we use focalPoint since flip manipulates the position and makes it useless to track\n private stackInvalidated = false; // if true -> new actor is forced to be created for the stack\n private voiApplied = false;\n private rotationCache = 0;\n private _publishCalibratedEvent = false;\n private _calibrationEvent: CalibrationEvent;\n private _cpuFallbackEnabledElement?: CPUFallbackEnabledElement;\n // CPU fallback\n private useCPURendering: boolean;\n private cpuImagePixelData: number[];\n private cpuRenderingInvalidated: boolean;\n private csImage: IImage;\n\n // TODO: These should not be here and will be nuked\n public modality: string; // this is needed for tools\n public scaling: Scaling;\n\n /**\n * Constructor for the StackViewport class\n * @param props - ViewportInput\n */\n constructor(props: ViewportInput) {\n super(props);\n this.scaling = {};\n this.modality = null;\n this.useCPURendering = getShouldUseCPURendering();\n\n if (this.useCPURendering) {\n this._cpuFallbackEnabledElement = {\n canvas: this.canvas,\n renderingTools: {},\n transform: new Transform(),\n viewport: {},\n };\n } else {\n const renderer = this.getRenderer();\n const camera = vtkCamera.newInstance();\n renderer.setActiveCamera(camera);\n\n const viewPlaneNormal = <Point3>[0, 0, -1];\n const viewUp = <Point3>[0, -1, 0];\n\n camera.setDirectionOfProjection(\n -viewPlaneNormal[0],\n -viewPlaneNormal[1],\n -viewPlaneNormal[2]\n );\n camera.setViewUp(...viewUp);\n camera.setParallelProjection(true);\n camera.setThicknessFromFocalPoint(0.1);\n // @ts-ignore: vtkjs incorrect typing\n camera.setFreezeFocalPoint(true);\n }\n\n this.imageIds = [];\n this.currentImageIdIndex = 0;\n this.targetImageIdIndex = 0;\n this.cameraFocalPointOnRender = [0, 0, 0];\n this.resetCamera();\n\n this.initializeElementDisabledHandler();\n }\n\n static get useCustomRenderingPipeline(): boolean {\n return getShouldUseCPURendering();\n }\n\n private initializeElementDisabledHandler() {\n eventTarget.addEventListener(\n Events.ELEMENT_DISABLED,\n function elementDisabledHandler() {\n clearTimeout(this.debouncedTimeout);\n\n eventTarget.removeEventListener(\n Events.ELEMENT_DISABLED,\n elementDisabledHandler\n );\n }\n );\n }\n\n /**\n * Resizes the viewport - only used in CPU fallback for StackViewport. The\n * GPU resizing happens inside the RenderingEngine.\n */\n public resize = (): void => {\n // GPU viewport resize is handled inside the RenderingEngine\n if (this.useCPURendering) {\n this._resizeCPU();\n }\n };\n\n /**\n * Returns the image and its properties that is being shown inside the\n * stack viewport. It returns, the image dimensions, image direction,\n * image scalar data, vtkImageData object, metadata, and scaling (e.g., PET suvbw)\n *\n * @returns IImageData: dimensions, direction, scalarData, vtkImageData, metadata, scaling\n */\n public getImageData(): IImageData | CPUIImageData {\n if (this.useCPURendering) {\n return this.getImageDataCPU();\n } else {\n return this.getImageDataGPU();\n }\n }\n\n private _resizeCPU = (): void => {\n if (this._cpuFallbackEnabledElement.viewport) {\n resize(this._cpuFallbackEnabledElement);\n }\n };\n\n private getImageDataGPU(): IImageData | undefined {\n const defaultActor = this.getDefaultActor();\n\n if (!defaultActor) {\n return;\n }\n\n const { actor } = defaultActor;\n if (!isImageActor(actor)) {\n return;\n }\n\n const vtkImageData = actor.getMapper().getInputData();\n return {\n dimensions: vtkImageData.getDimensions(),\n spacing: vtkImageData.getSpacing(),\n origin: vtkImageData.getOrigin(),\n direction: vtkImageData.getDirection(),\n scalarData: vtkImageData.getPointData().getScalars().getData(),\n imageData: actor.getMapper().getInputData(),\n metadata: { Modality: this.modality },\n scaling: this.scaling,\n hasPixelSpacing: this.hasPixelSpacing,\n preScale: {\n ...this.csImage.preScale,\n },\n };\n }\n\n private getImageDataCPU(): CPUIImageData | undefined {\n const { metadata } = this._cpuFallbackEnabledElement;\n\n const spacing = metadata.spacing;\n\n return {\n dimensions: metadata.dimensions,\n spacing,\n origin: metadata.origin,\n direction: metadata.direction,\n metadata: { Modality: this.modality },\n scaling: this.scaling,\n imageData: {\n getDirection: () => metadata.direction,\n getDimensions: () => metadata.dimensions,\n getScalarData: () => this.cpuImagePixelData,\n getSpacing: () => spacing,\n worldToIndex: (point: Point3) => {\n const canvasPoint = this.worldToCanvasCPU(point);\n const pixelCoord = canvasToPixel(\n this._cpuFallbackEnabledElement,\n canvasPoint\n );\n return [pixelCoord[0], pixelCoord[1], 0];\n },\n indexToWorld: (point: Point3) => {\n const canvasPoint = pixelToCanvas(this._cpuFallbackEnabledElement, [\n point[0],\n point[1],\n ]);\n return this.canvasToWorldCPU(canvasPoint);\n },\n },\n scalarData: this.cpuImagePixelData,\n hasPixelSpacing: this.hasPixelSpacing,\n preScale: {\n ...this.csImage.preScale,\n },\n };\n }\n\n /**\n * Returns the frame of reference UID, if the image doesn't have imagePlaneModule\n * metadata, it returns undefined, otherwise, frameOfReferenceUID is returned.\n * @returns frameOfReferenceUID : string representing frame of reference id\n */\n public getFrameOfReferenceUID = (): string | undefined => {\n // Get the current image that is displayed in the viewport\n const imageId = this.getCurrentImageId();\n\n if (!imageId) {\n return;\n }\n\n // Use the metadata provider to grab its imagePlaneModule metadata\n const imagePlaneModule = metaData.get('imagePlaneModule', imageId);\n\n // If nothing exists, return undefined\n if (!imagePlaneModule) {\n return;\n }\n\n // Otherwise, provide the FrameOfReferenceUID so we can map\n // annotations made on VolumeViewports back to StackViewports\n // and vice versa\n return imagePlaneModule.frameOfReferenceUID;\n };\n\n /**\n * Creates imageMapper based on the provided vtkImageData and also creates\n * the imageSliceActor and connects it to the imageMapper.\n * For color stack images, it sets the independent components to be false which\n * is required in vtk.\n *\n * @param imageData - vtkImageData for the viewport\n * @returns actor vtkActor\n */\n\n private createActorMapper = (imageData) => {\n const mapper = vtkImageMapper.newInstance();\n mapper.setInputData(imageData);\n\n const actor = vtkImageSlice.newInstance();\n\n // @ts-ignore: vtkjs incorrect typing\n actor.setMapper(mapper);\n\n if (imageData.getPointData().getNumberOfComponents() > 1) {\n // @ts-ignore: vtkjs incorrect typing\n actor.getProperty().setIndependentComponents(false);\n }\n\n return actor;\n };\n\n /**\n * Retrieves the metadata from the metadata provider, and optionally adds the\n * scaling to the viewport if modality is PET and scaling metadata is provided.\n *\n * @param imageId - a string representing the imageId for the image\n * @returns imagePlaneModule and imagePixelModule containing the metadata for the image\n */\n private buildMetadata(imageId: string) {\n const {\n pixelRepresentation,\n bitsAllocated,\n bitsStored,\n highBit,\n photometricInterpretation,\n samplesPerPixel,\n } = metaData.get('imagePixelModule', imageId);\n\n const voiLutModule = metaData.get('voiLutModule', imageId);\n\n let windowWidth, windowCenter;\n if (voiLutModule) {\n ({ windowWidth, windowCenter } = voiLutModule);\n\n if (Array.isArray(windowWidth)) {\n windowWidth = windowWidth[0];\n }\n\n if (Array.isArray(windowCenter)) {\n windowCenter = windowCenter[0];\n }\n }\n\n const { modality } = metaData.get('generalSeriesModule', imageId);\n const imageIdScalingFactor = metaData.get('scalingModule', imageId);\n\n if (modality === 'PT' && imageIdScalingFactor) {\n this._addScalingToViewport(imageIdScalingFactor);\n }\n\n // todo: some tools rely on the modality\n this.modality = modality;\n\n let imagePlaneModule = this._getImagePlaneModule(imageId);\n\n // Todo: for now, it gives error for getImageData\n if (!this.useCPURendering) {\n imagePlaneModule = this.calibrateIfNecessary(imageId, imagePlaneModule);\n }\n\n return {\n imagePlaneModule,\n imagePixelModule: {\n bitsAllocated,\n bitsStored,\n samplesPerPixel,\n highBit,\n photometricInterpretation,\n pixelRepresentation,\n windowWidth,\n windowCenter,\n modality,\n },\n };\n }\n\n /**\n * Checks the metadataProviders to see if a calibratedPixelSpacing is\n * given. If so, checks the actor to see if it needs to be modified, and\n * set the flags for imageCalibration if a new actor needs to be created\n *\n * @param imageId - imageId\n * @param imagePlaneModule - imagePlaneModule\n * @returns modified imagePlaneModule with the calibrated spacings\n */\n private calibrateIfNecessary(imageId, imagePlaneModule) {\n const calibratedPixelSpacing = metaData.get(\n 'calibratedPixelSpacing',\n imageId\n );\n\n if (!calibratedPixelSpacing) {\n return imagePlaneModule;\n }\n\n const [calibratedRowSpacing, calibratedColumnSpacing] =\n calibratedPixelSpacing;\n\n // Todo: This is necessary in general, but breaks an edge case when an image\n // is calibrated to some other spacing, and it gets calibrated BACK to the\n // original spacing.\n if (\n imagePlaneModule.rowPixelSpacing === calibratedRowSpacing &&\n imagePlaneModule.columnPixelSpacing === calibratedColumnSpacing\n ) {\n return imagePlaneModule;\n }\n\n // Check if there is already an actor\n const imageDataMetadata = this.getImageData();\n\n // If no actor (first load) and calibration matches the dicom header\n if (\n !imageDataMetadata &&\n imagePlaneModule.rowPixelSpacing === calibratedRowSpacing &&\n imagePlaneModule.columnPixelSpacing === calibratedColumnSpacing\n ) {\n return imagePlaneModule;\n }\n\n // If no actor (first load) and calibration doesn't match headers\n // -> needs calibration\n if (\n !imageDataMetadata &&\n (imagePlaneModule.rowPixelSpacing !== calibratedRowSpacing ||\n imagePlaneModule.columnPixelSpacing !== calibratedColumnSpacing)\n ) {\n this._publishCalibratedEvent = true;\n\n this._calibrationEvent = <CalibrationEvent>{\n rowScale: calibratedRowSpacing / imagePlaneModule.rowPixelSpacing,\n columnScale:\n calibratedColumnSpacing / imagePlaneModule.columnPixelSpacing,\n };\n\n // modify imagePlaneModule for actor to use calibrated spacing\n imagePlaneModule.rowPixelSpacing = calibratedRowSpacing;\n imagePlaneModule.columnPixelSpacing = calibratedColumnSpacing;\n return imagePlaneModule;\n }\n\n // If there is already an actor, check if calibration is needed for the current actor\n const { imageData } = imageDataMetadata;\n const [columnPixelSpacing, rowPixelSpacing] = imageData.getSpacing();\n\n imagePlaneModule.rowPixelSpacing = calibratedRowSpacing;\n imagePlaneModule.columnPixelSpacing = calibratedColumnSpacing;\n\n // If current actor spacing matches the calibrated spacing\n if (\n rowPixelSpacing === calibratedRowSpacing &&\n columnPixelSpacing === calibratedPixelSpacing\n ) {\n // No calibration is required\n return imagePlaneModule;\n }\n\n // Calibration is required\n this._publishCalibratedEvent = true;\n\n this._calibrationEvent = <CalibrationEvent>{\n rowScale: calibratedRowSpacing / rowPixelSpacing,\n columnScale: calibratedColumnSpacing / columnPixelSpacing,\n };\n\n return imagePlaneModule;\n }\n\n /**\n * Sets the properties for the viewport on the default actor. Properties include\n * setting the VOI, inverting the colors and setting the interpolation type, rotation\n * @param voiRange - Sets the lower and upper voi\n * @param invert - Inverts the colors\n * @param interpolationType - Changes the interpolation type (1:linear, 0: nearest)\n * @param rotation - image rotation in degrees\n */\n public setProperties(\n {\n voiRange,\n invert,\n interpolationType,\n rotation,\n }: StackViewportProperties = {},\n suppressEvents = false\n ): void {\n // if voi is not applied for the first time, run the setVOI function\n // which will apply the default voi\n if (typeof voiRange !== 'undefined' || !this.voiApplied) {\n this.setVOI(voiRange, suppressEvents);\n }\n\n if (typeof invert !== 'undefined') {\n this.setInvertColor(invert);\n }\n\n if (typeof interpolationType !== 'undefined') {\n this.setInterpolationType(interpolationType);\n }\n\n if (typeof rotation !== 'undefined') {\n if (this.rotationCache !== rotation) {\n this.setRotation(this.rotationCache, rotation);\n }\n }\n }\n\n /**\n * Retrieve the viewport properties\n * @returns viewport properties including voi, invert, interpolation type, rotation, flip\n */\n public getProperties = (): StackViewportProperties => {\n return {\n voiRange: this.voiRange,\n rotation: this.rotationCache,\n interpolationType: this.interpolationType,\n invert: this.invert,\n };\n };\n\n /**\n * Reset the viewport properties to the default values\n */\n public resetProperties(): void {\n this.cpuRenderingInvalidated = true;\n\n this.fillWithBackgroundColor();\n\n if (this.useCPURendering) {\n this._cpuFallbackEnabledElement.renderingTools = {};\n }\n\n this._resetProperties();\n\n this.render();\n }\n\n /**\n * If the user has selected CPU rendering, return the CPU camera, otherwise\n * return the default camera\n * @returns The camera object.\n */\n public getCamera(): ICamera {\n if (this.useCPURendering) {\n return this.getCameraCPU();\n } else {\n return super.getCamera();\n }\n }\n\n /**\n * Set the camera based on the provided camera object.\n * @param cameraInterface - The camera interface that will be used to\n * render the scene.\n */\n public setCamera(\n cameraInterface: ICamera,\n storeAsInitialCamera = false\n ): void {\n if (this.useCPURendering) {\n this.setCameraCPU(cameraInterface);\n } else {\n super.setCamera(cameraInterface, storeAsInitialCamera);\n }\n }\n\n private _resetProperties() {\n // to force the default voi to be applied on the next render\n this.voiApplied = false;\n\n this.setProperties({\n voiRange: this.initialVOIRange,\n rotation: 0,\n interpolationType: InterpolationType.LINEAR,\n invert: false,\n });\n }\n\n private _setPropertiesFromCache(): void {\n const suppressEvents = true;\n this.setProperties(\n {\n voiRange: this.voiRange,\n rotation: this.rotation,\n interpolationType: this.interpolationType,\n invert: this.invert,\n },\n suppressEvents\n );\n }\n\n private getCameraCPU(): Partial<ICamera> {\n const { metadata, viewport } = this._cpuFallbackEnabledElement;\n const { direction } = metadata;\n\n // focalPoint and position of CPU camera is just a placeholder since\n // tools need focalPoint to be defined\n const viewPlaneNormal = direction.slice(6, 9).map((x) => -x) as Point3;\n let viewUp = direction.slice(3, 6).map((x) => -x) as Point3;\n\n // If camera is rotated, we need the correct rotated viewUp along the\n // viewPlaneNormal vector\n if (this.rotation) {\n const rotationMatrix = mat4.fromRotation(\n mat4.create(),\n (this.rotation * Math.PI) / 180,\n viewPlaneNormal\n );\n viewUp = vec3.transformMat4(\n vec3.create(),\n viewUp,\n rotationMatrix\n ) as Point3;\n }\n\n const canvasCenter: Point2 = [\n this.element.clientWidth / 2,\n this.element.clientHeight / 2,\n ];\n\n // Focal point is the center of the canvas in world coordinate by construction\n const canvasCenterWorld = this.canvasToWorld(canvasCenter);\n\n // parallel scale is half of the viewport height in the world units (mm)\n\n const topLeftWorld = this.canvasToWorld([0, 0]);\n const bottomLeftWorld = this.canvasToWorld([0, this.element.clientHeight]);\n\n const parallelScale = vec3.distance(topLeftWorld, bottomLeftWorld) / 2;\n\n return {\n parallelProjection: true,\n focalPoint: canvasCenterWorld,\n position: [0, 0, 0],\n parallelScale,\n scale: viewport.scale,\n viewPlaneNormal: [\n viewPlaneNormal[0],\n viewPlaneNormal[1],\n viewPlaneNormal[2],\n ],\n viewUp: [viewUp[0], viewUp[1], viewUp[2]],\n flipHorizontal: this.flipHorizontal,\n flipVertical: this.flipVertical,\n };\n }\n\n private setCameraCPU(cameraInterface: ICamera): void {\n const { viewport, image } = this._cpuFallbackEnabledElement;\n const previousCamera = this.getCameraCPU();\n\n const { focalPoint, parallelScale, scale, flipHorizontal, flipVertical } =\n cameraInterface;\n\n const { clientHeight } = this.element;\n\n if (focalPoint) {\n const focalPointCanvas = this.worldToCanvasCPU(focalPoint);\n const focalPointPixel = canvasToPixel(\n this._cpuFallbackEnabledElement,\n focalPointCanvas\n );\n\n const prevFocalPointCanvas = this.worldToCanvasCPU(\n previousCamera.focalPoint\n );\n const prevFocalPointPixel = canvasToPixel(\n this._cpuFallbackEnabledElement,\n prevFocalPointCanvas\n );\n\n const deltaPixel = vec2.create();\n vec2.subtract(\n deltaPixel,\n vec2.fromValues(focalPointPixel[0], focalPointPixel[1]),\n vec2.fromValues(prevFocalPointPixel[0], prevFocalPointPixel[1])\n );\n\n const shift = correctShift(\n { x: deltaPixel[0], y: deltaPixel[1] },\n viewport\n );\n\n viewport.translation.x -= shift.x;\n viewport.translation.y -= shift.y;\n }\n\n if (parallelScale) {\n // We need to convert he parallelScale which has a physical meaning to\n // camera scale factor (since CPU works with scale). Since parallelScale represents\n // half of the height of the viewport in the world unit (mm), we can use that\n // to compute the scale factor which is the ratio of the viewport height in pixels\n // to the current rendered image height.\n const { rowPixelSpacing } = image;\n const scale = (clientHeight * rowPixelSpacing * 0.5) / parallelScale;\n\n viewport.scale = scale;\n viewport.parallelScale = parallelScale;\n }\n\n if (scale) {\n const { rowPixelSpacing } = image;\n viewport.scale = scale;\n viewport.parallelScale = (clientHeight * rowPixelSpacing * 0.5) / scale;\n }\n\n if (flipHorizontal !== undefined || flipVertical !== undefined) {\n this.setFlipCPU({ flipHorizontal, flipVertical });\n }\n\n // re-calculate the transforms\n this._cpuFallbackEnabledElement.transform = calculateTransform(\n this._cpuFallbackEnabledElement\n );\n\n const eventDetail: EventTypes.CameraModifiedEventDetail = {\n previousCamera,\n camera: this.getCamera(),\n element: this.element,\n viewportId: this.id,\n renderingEngineId: this.renderingEngineId,\n rotation: this.rotation,\n };\n\n triggerEvent(this.element, Events.CAMERA_MODIFIED, eventDetail);\n }\n\n private setFlipCPU({ flipHorizontal, flipVertical }: FlipDirection): void {\n const { viewport } = this._cpuFallbackEnabledElement;\n\n if (flipHorizontal !== undefined) {\n viewport.hflip = flipHorizontal;\n this.flipHorizontal = viewport.hflip;\n }\n\n if (flipVertical !== undefined) {\n viewport.vflip = flipVertical;\n this.flipVertical = viewport.vflip;\n }\n }\n\n private setVOI(voiRange: VOIRange, suppressEvents?: boolean): void {\n if (this.useCPURendering) {\n this.setVOICPU(voiRange, suppressEvents);\n return;\n }\n\n this.setVOIGPU(voiRange, suppressEvents);\n }\n\n private setRotation(rotationCache: number, rotation: number): void {\n const previousCamera = this.getCamera();\n\n if (this.useCPURendering) {\n this.setRotationCPU(rotationCache, rotation);\n } else {\n this.setRotationGPU(rotationCache, rotation);\n }\n\n // New camera after rotation\n const camera = this.getCamera();\n\n const eventDetail: EventTypes.CameraModifiedEventDetail = {\n previousCamera,\n camera,\n element: this.element,\n viewportId: this.id,\n renderingEngineId: this.renderingEngineId,\n rotation: this.rotation,\n };\n\n triggerEvent(this.element, Events.CAMERA_MODIFIED, eventDetail);\n }\n\n private setInterpolationType(interpolationType: InterpolationType): void {\n if (this.useCPURendering) {\n this.setInterpolationTypeCPU(interpolationType);\n return;\n }\n\n this.setInterpolationTypeGPU(interpolationType);\n }\n\n private setInvertColor(invert: boolean): void {\n if (this.useCPURendering) {\n this.setInvertColorCPU(invert);\n return;\n }\n\n this.setInvertColorGPU(invert);\n }\n\n private setRotationCPU(rotationCache: number, rotation: number): void {\n const { viewport } = this._cpuFallbackEnabledElement;\n\n viewport.rotation = rotation;\n this.rotationCache = rotation;\n this.rotation = rotation;\n }\n\n private setRotationGPU(rotationCache: number, rotation: number): void {\n // Moving back to zero rotation, for new scrolled slice rotation is 0 after camera reset\n this.getVtkActiveCamera().roll(rotationCache);\n\n // rotating camera to the new value\n this.getVtkActiveCamera().roll(-rotation);\n this.rotationCache = rotation;\n this.rotation = rotation;\n }\n\n private setInterpolationTypeGPU(interpolationType: InterpolationType): void {\n const defaultActor = this.getDefaultActor();\n\n if (!defaultActor) {\n return;\n }\n\n const { actor } = defaultActor;\n if (!isImageActor(actor)) {\n return;\n }\n const volumeProperty = actor.getProperty();\n\n // @ts-ignore\n volumeProperty.setInterpolationType(interpolationType);\n this.interpolationType = interpolationType;\n }\n\n private setInterpolationTypeCPU(interpolationType: InterpolationType): void {\n const { viewport } = this._cpuFallbackEnabledElement;\n\n if (interpolationType === InterpolationType.LINEAR) {\n viewport.pixelReplication = false;\n } else {\n viewport.pixelReplication = true;\n }\n\n this.interpolationType = interpolationType;\n }\n\n private setInvertColorCPU(invert: boolean): void {\n const { viewport } = this._cpuFallbackEnabledElement;\n\n if (!viewport) {\n return;\n }\n\n viewport.invert = invert;\n this.invert = invert;\n }\n\n private setInvertColorGPU(invert: boolean): void {\n const defaultActor = this.getDefaultActor();\n\n if (!defaultActor) {\n return;\n }\n\n const { actor } = defaultActor;\n if (!isImageActor(actor)) {\n return;\n }\n\n // Duplicated logic to make sure typescript stops complaining\n // about vtkActor not having the correct property\n if (actor.isA('vtkVolume')) {\n const volumeActor = actor as VolumeActor;\n const tfunc = volumeActor.getProperty().getRGBTransferFunction(0);\n\n if ((!this.invert && invert) || (this.invert && !invert)) {\n invertRgbTransferFunction(tfunc);\n }\n this.invert = invert;\n } else if (actor.isA('vtkImageSlice')) {\n const imageSliceActor = actor as vtkImageSlice;\n const tfunc = imageSliceActor.getProperty().getRGBTransferFunction(0);\n\n if ((!this.invert && invert) || (this.invert && !invert)) {\n invertRgbTransferFunction(tfunc);\n }\n this.invert = invert;\n }\n }\n\n private setVOICPU(voiRange: VOIRange, suppressEvents?: boolean): void {\n const { viewport, image } = this._cpuFallbackEnabledElement;\n\n if (!viewport || !image) {\n return;\n }\n\n if (typeof voiRange === 'undefined') {\n const { windowWidth: ww, windowCenter: wc } = image;\n\n const wwToUse = Array.isArray(ww) ? ww[0] : ww;\n const wcToUse = Array.isArray(wc) ? wc[0] : wc;\n viewport.voi = {\n windowWidth: wwToUse,\n windowCenter: wcToUse,\n };\n\n const { lower, upper } = windowLevelUtil.toLowHighRange(wwToUse, wcToUse);\n voiRange = { lower, upper };\n } else {\n const { lower, upper } = voiRange;\n const { windowCenter, windowWidth } = windowLevelUtil.toWindowLevel(\n lower,\n upper\n );\n\n if (!viewport.voi) {\n viewport.voi = {\n windowWidth: 0,\n windowCenter: 0,\n };\n }\n\n viewport.voi.windowWidth = windowWidth;\n viewport.voi.windowCenter = windowCenter;\n }\n\n this.voiApplied = true;\n this.voiRange = voiRange;\n const eventDetail: VoiModifiedEventDetail = {\n viewportId: this.id,\n range: voiRange,\n };\n\n if (!suppressEvents) {\n triggerEvent(this.element, Events.VOI_MODIFIED, eventDetail);\n }\n }\n\n private setVOIGPU(voiRange: VOIRange, suppressEvents?: boolean): void {\n const defaultActor = this.getDefaultActor();\n if (!defaultActor) {\n return;\n }\n\n const { actor } = defaultActor;\n\n if (!isImageActor(actor)) {\n return;\n }\n\n const imageActor = actor as ImageActor;\n\n let voiRangeToUse = voiRange;\n if (typeof voiRangeToUse === 'undefined') {\n const imageData = imageActor.getMapper().getInputData();\n const range = imageData.getPointData().getScalars().getRange();\n voiRangeToUse = { lower: range[0], upper: range[1] };\n }\n\n const { windowWidth, windowCenter } = windowLevelUtil.toWindowLevel(\n voiRangeToUse.lower,\n voiRangeToUse.upper\n );\n\n imageActor.getProperty().setColorWindow(windowWidth);\n imageActor.getProperty().setColorLevel(windowCenter);\n\n this.voiApplied = true;\n this.voiRange = voiRangeToUse;\n\n if (!suppressEvents) {\n const eventDetail: VoiModifiedEventDetail = {\n viewportId: this.id,\n range: voiRangeToUse,\n };\n\n triggerEvent(this.element, Events.VOI_MODIFIED, eventDetail);\n }\n }\n\n /**\n * Adds scaling parameters to the viewport to be used along all slices\n *\n * @param imageIdScalingFactor - suvbw, suvlbm, suvbsa\n */\n private _addScalingToViewport(imageIdScalingFactor) {\n if (!this.scaling.PET) {\n // These ratios are constant across all frames, so only need one.\n const { suvbw, suvlbm, suvbsa } = imageIdScalingFactor;\n\n const petScaling = <PTScaling>{};\n\n if (suvlbm) {\n petScaling.suvbwToSuvlbm = suvlbm / suvbw;\n }\n\n if (suvbsa) {\n petScaling.suvbwToSuvbsa = suvbsa / suvbw;\n }\n\n this.scaling.PET = petScaling;\n }\n }\n\n /**\n * Calculates number of components based on the dicom metadata\n *\n * @param photometricInterpretation - string dicom tag\n * @returns number representing number of components\n */\n private _getNumCompsFromPhotometricInterpretation(\n photometricInterpretation: string\n ): number {\n // TODO: this function will need to have more logic later\n // see http://dicom.nema.org/medical/Dicom/current/output/chtml/part03/sect_C.7.6.3.html#sect_C.7.6.3.1.2\n let numberOfComponents = 1;\n if (\n photometricInterpretation === 'RGB' ||\n photometricInterpretation.indexOf('YBR') !== -1 ||\n photometricInterpretation === 'PALETTE COLOR'\n ) {\n numberOfComponents = 3;\n }\n\n return numberOfComponents;\n }\n\n /**\n * Calculates image metadata based on the image object. It calculates normal\n * axis for the images, and output image metadata\n *\n * @param image - stack image containing cornerstone image\n * @returns image metadata: bitsAllocated, number of components, origin,\n * direction, dimensions, spacing, number of voxels.\n */\n private _getImageDataMetadata(image: IImage): ImageDataMetaData {\n // TODO: Creating a single image should probably not require a metadata provider.\n // We should define the minimum we need to display an image and it should live on\n // the Image object itself. Additional stuff (e.g. pixel spacing, direction, origin, etc)\n // should be optional and used if provided through a metadata provider.\n\n const { imagePlaneModule, imagePixelModule } = this.buildMetadata(\n image.imageId\n );\n\n let rowCosines, columnCosines;\n\n rowCosines = <Point3>imagePlaneModule.rowCosines;\n columnCosines = <Point3>imagePlaneModule.columnCosines;\n\n // if null or undefined\n if (rowCosines == null || columnCosines == null) {\n rowCosines = <Point3>[1, 0, 0];\n columnCosines = <Point3>[0, 1, 0];\n }\n\n const rowCosineVec = vec3.fromValues(\n rowCosines[0],\n rowCosines[1],\n rowCosines[2]\n );\n const colCosineVec = vec3.fromValues(\n columnCosines[0],\n columnCosines[1],\n columnCosines[2]\n );\n const scanAxisNormal = vec3.create();\n vec3.cross(scanAxisNormal, rowCosineVec, colCosineVec);\n\n let origin = imagePlaneModule.imagePositionPatient;\n // if null or undefined\n if (origin == null) {\n origin = [0, 0, 0];\n }\n\n const xSpacing =\n imagePlaneModule.columnPixelSpacing || image.columnPixelSpacing;\n const ySpacing = imagePlaneModule.rowPixelSpacing || image.rowPixelSpacing;\n const xVoxels = image.columns;\n const yVoxels = image.rows;\n\n // Note: For rendering purposes, we use the EPSILON as the z spacing.\n // This is purely for internal implementation logic since we are still\n // technically rendering 3D objects with vtk.js, but the abstracted intention\n // of the stack viewport is to render 2D images\n const zSpacing = EPSILON;\n const zVoxels = 1;\n\n const numComps =\n image.numComps ||\n this._getNumCompsFromPhotometricInterpretation(\n imagePixelModule.photometricInterpretation\n );\n\n return {\n bitsAllocated: imagePixelModule.bitsAllocated,\n numComps,\n origin,\n direction: [...rowCosineVec, ...colCosineVec, ...scanAxisNormal] as Mat3,\n dimensions: [xVoxels, yVoxels, zVoxels],\n spacing: [xSpacing, ySpacing, zSpacing],\n numVoxels: xVoxels * yVoxels * zVoxels,\n imagePlaneModule,\n imagePixelModule,\n };\n }\n\n /**\n * Converts the image direction to camera viewUp and viewplaneNormal\n *\n * @param imageDataDirection - vtkImageData direction\n * @returns viewplane normal and viewUp of the camera\n */\n private _getCameraOrientation(imageDataDirection: Mat3): {\n viewPlaneNormal: Point3;\n viewUp: Point3;\n } {\n const viewPlaneNormal = imageDataDirection.slice(6, 9).map((x) => -x);\n\n const viewUp = imageDataDirection.slice(3, 6).map((x) => -x);\n return {\n viewPlaneNormal: [\n viewPlaneNormal[0],\n viewPlaneNormal[1],\n viewPlaneNormal[2],\n ],\n viewUp: [viewUp[0], viewUp[1], viewUp[2]],\n };\n }\n\n /**\n * Creates vtkImagedata based on the image object, it creates\n * and empty scalar data for the image based on the metadata\n * tags (e.g., bitsAllocated)\n *\n * @param image - cornerstone Image object\n */\n private _createVTKImageData({\n origin,\n direction,\n dimensions,\n spacing,\n bitsAllocated,\n numComps,\n numVoxels,\n }): void {\n let pixelArray;\n switch (bitsAllocated) {\n case 8:\n pixelArray = new Uint8Array(numVoxels * numComps);\n break;\n\n case 16:\n pixelArray = new Float32Array(numVoxels * numComps);\n\n break;\n case 24:\n pixelArray = new Uint8Array(numVoxels * 3 * numComps);\n\n break;\n default:\n console.log('bit allocation not implemented');\n }\n\n const scalarArray = vtkDataArray.newInstance({\n name: 'Pixels',\n numberOfComponents: numComps,\n values: pixelArray,\n });\n\n this._imageData = vtkImageData.newInstance();\n\n this._imageData.setDimensions(dimensions);\n this._imageData.setSpacing(spacing);\n this._imageData.setDirection(direction);\n this._imageData.setOrigin(origin);\n this._imageData.getPointData().setScalars(scalarArray);\n }\n\n /**\n * Sets the imageIds to be visualized inside the stack viewport. It accepts\n * list of imageIds, the index of the first imageId to be viewed. It is a\n * asynchronous function that returns a promise resolving to imageId being\n * displayed in the stack viewport.\n *\n *\n * @param imageIds - list of strings, that represents list of image Ids\n * @param currentImageIdIndex - number representing the index of the initial image to be displayed\n */\n public async setStack(\n imageIds: Array<string>,\n currentImageIdIndex = 0\n ): Promise<string> {\n this.imageIds = imageIds;\n this.currentImageIdIndex = currentImageIdIndex;\n this.targetImageIdIndex = currentImageIdIndex;\n this.stackInvalidated = true;\n this.rotationCache = 0;\n this.flipVertical = false;\n this.flipHorizontal = false;\n this.voiApplied = false;\n\n this._resetProperties();\n\n this.fillWithBackgroundColor();\n\n if (this.useCPURendering) {\n this._cpuFallbackEnabledElement.renderingTools = {};\n delete this._cpuFallbackEnabledElement.viewport.colormap;\n }\n\n const imageId = await this._setImageIdIndex(currentImageIdIndex);\n\n const eventDetail: StackViewportNewStackEventDetail = {\n imageIds,\n viewportId: this.id,\n element: this.element,\n currentImageIdIndex: currentImageIdIndex,\n };\n\n triggerEvent(eventTarget, Events.STACK_VIEWPORT_NEW_STACK, eventDetail);\n\n return imageId;\n }\n\n /**\n * It checks if the new image object matches the dimensions, spacing,\n * and direction of the previously displayed image in the viewport or not.\n * It returns a boolean\n *\n * @param image - Cornerstone Image object\n * @param imageData - vtkImageData\n * @returns boolean\n */\n private _checkVTKImageDataMatchesCornerstoneImage(\n image: IImage,\n imageData: vtkImageDataType\n ): boolean {\n if (!imageData) {\n return false;\n }\n\n const [xSpacing, ySpacing] = imageData.getSpacing();\n const [xVoxels, yVoxels] = imageData.getDimensions();\n const imagePlaneModule = this._getImagePlaneModule(image.imageId);\n const direction = imageData.getDirection();\n const rowCosines = direction.slice(0, 3);\n const columnCosines = direction.slice(3, 6);\n\n // using spacing, size, and direction only for now\n return (\n (xSpacing === image.rowPixelSpacing ||\n (image.rowPixelSpacing === null && xSpacing === 1.0)) &&\n (ySpacing === image.columnPixelSpacing ||\n (image.columnPixelSpacing === null && ySpacing === 1.0)) &&\n xVoxels === image.columns &&\n yVoxels === image.rows &&\n isEqual(imagePlaneModule.rowCosines, <Point3>rowCosines) &&\n isEqual(imagePlaneModule.columnCosines, <Point3>columnCosines)\n );\n }\n\n /**\n * It Updates the vtkImageData of the viewport with the new pixel data\n * from the provided image object.\n *\n * @param image - Cornerstone Image object\n */\n private _updateVTKImageDataFromCornerstoneImage(image: IImage): void {\n const imagePlaneModule = this._getImagePlaneModule(image.imageId);\n let origin = imagePlaneModule.imagePositionPatient;\n\n if (origin == null) {\n origin = [0, 0, 0];\n }\n\n this._imageData.setOrigin(origin);\n\n // 1. Update the pixel data in the vtkImageData object with the pixelData\n // from the loaded Cornerstone image\n const pixelData = image.getPixelData();\n const scalars = this._imageData.getPointData().getScalars();\n const scalarData = scalars.getData() as Uint8Array | Float32Array;\n\n if (image.rgba || isRgbaSourceRgbDest(pixelData, scalarData)) {\n if (!image.rgba) {\n console.warn('rgba not specified but data looks rgba ish', image);\n }\n // if image is already cached with rgba for any reason (cpu fallback),\n // we need to convert it to rgb for the pixel data set\n // RGB case\n const numPixels = pixelData.length / 4;\n\n let rgbIndex = 0;\n let index = 0;\n\n for (let i = 0; i < numPixels; i++) {\n scalarData[index++] = pixelData[rgbIndex++]; // red\n scalarData[index++] = pixelData[rgbIndex++]; // green\n scalarData[index++] = pixelData[rgbIndex++]; // blue\n rgbIndex++; // skip alpha\n }\n } else {\n scalarData.set(pixelData);\n }\n\n // Trigger modified on the VTK Object so the texture is updated\n // TODO: evaluate directly changing things with texSubImage3D later\n this._imageData.modified();\n }\n\n /**\n * It uses imageLoadPoolManager to add request for the imageId. It loadsAndCache\n * the image and triggers the STACK_NEW_IMAGE when the request successfully retrieves\n * the image. Next, the volume actor gets updated with the new new retrieved image.\n *\n * @param imageId - string representing the imageId\n * @param imageIdIndex - index of the imageId in the imageId list\n */\n private async _loadAndDisplayImage(\n imageId: string,\n imageIdIndex: number\n ): Promise<string> {\n if (this.useCPURendering) {\n await this._loadAndDisplayImageCPU(imageId, imageIdIndex);\n } else {\n await this._loadAndDisplayImageGPU(imageId, imageIdIndex);\n }\n\n return imageId;\n }\n\n private _loadAndDisplayImageCPU(\n imageId: string,\n imageIdIndex: number\n ): Promise<string> {\n return new Promise((resolve, reject) => {\n // 1. Load the image using the Image Loader\n function successCallback(\n image: IImage,\n imageIdIndex: number,\n imageId: string\n ) {\n // Perform this check after the image has finished loading\n // in case the user has already scrolled away to another image.\n // In that case, do not render this image.\n if (this.currentImageIdIndex !== imageIdIndex) {\n return;\n }\n\n this.csImage = image;\n\n const eventDetail: EventTypes.StackNewImageEventDetail = {\n image,\n imageId,\n imageIdIndex,\n viewportId: this.id,\n renderingEngineId: this.renderingEngineId,\n };\n\n triggerEvent(this.element, Events.STACK_NEW_IMAGE, eventDetail);\n\n const metadata = this._getImageDataMetadata(image) as ImageDataMetaData;\n\n image.isPreScaled = image.preScale?.scaled;\n\n const viewport = getDefaultViewport(\n this.canvas,\n image,\n this.modality,\n this._cpuFallbackEnabledElement.viewport.colormap\n );\n\n this._cpuFallbackEnabledElement.image = image;\n this._cpuFallbackEnabledElement.metadata = {\n ...metadata,\n };\n this.cpuImagePixelData = image.getPixelData();\n\n const viewportSettingToUse = Object.assign(\n {},\n viewport,\n this._cpuFallbackEnabledElement.viewport\n );\n\n // Important: this.stackInvalidated is different than cpuRenderingInvalidated. The\n // former is being used to maintain the previous state of the viewport\n // in the same stack, the latter is used to trigger drawImageSync\n this._cpuFallbackEnabledElement.viewport = this.stackInvalidated\n ? viewport\n : viewportSettingToUse;\n\n // used the previous state of the viewport, then stackInvalidated is set to false\n this.stackInvalidated = false;\n\n // new viewport is set to the current viewport, then cpuRenderingInvalidated is set to true\n this.cpuRenderingInvalidated = true;\n\n this._cpuFallbackEnabledElement.transform = calculateTransform(\n this._cpuFallbackEnabledElement\n );\n\n // Todo: trigger an event to allow applications to hook into END of loading state\n // Currently we use loadHandlerManagers for this\n\n // Trigger the image to be drawn on the next animation frame\n this.render();\n\n // Update the viewport's currentImageIdIndex to reflect the newly\n // rendered image\n this.currentImageIdIndex = imageIdIndex;\n resolve(imageId);\n }\n\n function errorCallback(\n error: Error,\n imageIdIndex: number,\n imageId: string\n ) {\n const eventDetail = {\n error,\n imageIdIndex,\n imageId,\n };\n\n if (!this.suppressEvents) {\n triggerEvent(eventTarget, Events.IMAGE_LOAD_ERROR, eventDetail);\n }\n\n reject(error);\n }\n\n function sendRequest(imageId, imageIdIndex, options) {\n return loadAndCacheImage(imageId, options).then(\n (image) => {\n successCallback.call(this, image, imageIdIndex, imageId);\n },\n (error) => {\n errorCallback.call(this, error, imageIdIndex, imageId);\n }\n );\n }\n\n // Todo: Note that eventually all viewport data is converted into Float32Array,\n // we use it here for the purpose of scaling for now.\n const type = 'Float32Array';\n\n const priority = -5;\n const requestType = RequestType.Interaction;\n const additionalDetails = { imageId };\n const options = {\n targetBuffer: {\n type,\n offset: null,\n length: null,\n },\n preScale: {\n enabled: true,\n },\n useRGBA: true,\n };\n\n imageLoadPoolManager.addRequest(\n sendRequest.bind(this, imageId, imageIdIndex, options),\n requestType,\n additionalDetails,\n priority\n );\n });\n }\n\n private _loadAndDisplayImageGPU(imageId: string, imageIdIndex: number) {\n return new Promise((resolve, reject) => {\n // 1. Load the image using the Image Loader\n function successCallback(image, imageIdIndex, imageId) {\n // Todo: trigger an event to allow applications to hook into END of loading state\n // Currently we use loadHandlerManagers for this\n // Perform this check after the image has finished loading\n // in case the user has already scrolled away to another image.\n // In that case, do not render this image.\n if (this.currentImageIdIndex !== imageIdIndex) {\n return;\n }\n\n // cornerstone image\n this.csImage = image;\n\n const eventDetail: EventTypes.StackNewImageEventDetail = {\n image,\n imageId,\n imageIdIndex,\n viewportId: this.id,\n renderingEngineId: this.renderingEngineId,\n };\n\n triggerEvent(this.element, Events.STACK_NEW_IMAGE, eventDetail);\n this._updateActorToDisplayImageId(image);\n\n // Trigger the image to be drawn on the next animation frame\n this.render();\n\n // Update the viewport's currentImageIdIndex to reflect the newly\n // rendered image\n this.currentImageIdIndex = imageIdIndex;\n resolve(imageId);\n }\n\n function errorCallback(error, imageIdIndex, imageId) {\n const eventDetail = {\n error,\n imageIdIndex,\n imageId,\n };\n\n triggerEvent(eventTarget, Events.IMAGE_LOAD_ERROR, eventDetail);\n reject(error);\n }\n\n function sendRequest(imageId, imageIdIndex, options) {\n return loadAndCacheImage(imageId, options).then(\n (image) => {\n successCallback.call(this, image, imageIdIndex, imageId);\n },\n (error) => {\n errorCallback.call(this, error, imageIdIndex, imageId);\n }\n );\n }\n\n // Todo: Note that eventually all viewport data is converted into Float32Array,\n // we use it here for the purpose of scaling for now.\n const type = 'Float32Array';\n\n const priority = -5;\n const requestType = RequestType.Interaction;\n const additionalDetails = { imageId };\n\n const options = {\n targetBuffer: {\n type,\n offset: null,\n length: null,\n },\n preScale: {\n enabled: true,\n },\n useRGBA: false,\n };\n\n const eventDetail: EventTypes.PreStackNewImageEventDetail = {\n imageId,\n imageIdIndex,\n viewportId: this.id,\n renderingEngineId: this.renderingEngineId,\n };\n triggerEvent(this.element, Events.PRE_STACK_NEW_IMAGE, eventDetail);\n\n imageLoadPoolManager.addRequest(\n sendRequest.bind(this, imageId, imageIdIndex, options),\n requestType,\n additionalDetails,\n priority\n );\n });\n }\n\n /**\n * It updates the volume actor with the retrieved cornerstone image.\n * It first checks if the new image has the same dimensions, spacings, and\n * dimensions of the previous one: 1) If yes, it updates the pixel data 2) if not,\n * it creates a whole new volume actor for the image.\n * Note: Camera gets reset for both situations. Therefore, each image renders at\n * its exact 3D location in the space, and both image and camera moves while scrolling.\n *\n * @param image - Cornerstone image\n * @returns\n */\n private _updateActorToDisplayImageId(image) {\n // This function should do the following:\n // - Get the existing actor's vtkImageData that is being used to render the current image and check if we can reuse the vtkImageData that is in place (i.e. do the image dimensions and data type match?)\n // - If we can reuse it, replace the scalar data under the hood\n // - If we cannot reuse it, create a new actor, remove the old one, and reset the camera\n\n // 2. Check if we can reuse the existing vtkImageData object, if one is present.\n const sameImageData = this._checkVTKImageDataMatchesCornerstoneImage(\n image,\n this._imageData\n );\n\n const activeCamera = this.getRenderer().getActiveCamera();\n\n // Cache camera props so we can trigger one camera changed event after\n // The full transition.\n const previousCameraProps = _cloneDeep(this.getCamera());\n if (sameImageData && !this.stackInvalidated) {\n // 3a. If we can reuse it, replace the scalar data under the hood\n this._updateVTKImageDataFromCornerstoneImage(image);\n\n // Since the 3D location of the imageData is changing as we scroll, we need\n // to modify the camera position to render this properly. However, resetting\n // causes problem related to zoom and pan tools: upon rendering of a new slice\n // the pan and zoom will get reset. To solve this, 1) we store the camera\n // properties related to pan and zoom 2) reset the camera to correctly place\n // it in the space 3) restore the pan, zoom props.\n const cameraProps = this.getCamera();\n\n const panCache = vec3.subtract(\n vec3.create(),\n this.cameraFocalPointOnRender,\n cameraProps.focalPoint\n );\n\n // store rotation cache since reset camera will reset it\n const rotationCache = this.rotationCache;\n\n // Reset the camera to point to the new slice location, reset camera doesn't\n // modify the direction of projection and viewUp\n this.resetCameraNoEvent();\n\n // restore the rotation cache for the new slice\n this.setRotation(rotationCache, rotationCache);\n\n // set the flip back to the previous value since the restore camera props\n // rely on the correct flip value\n this.setCameraNoEvent({\n flipHorizontal: previousCameraProps.flipHorizontal,\n flipVertical: previousCameraProps.flipVertical,\n });\n\n const { focalPoint } = this.getCamera();\n this.cameraFocalPointOnRender = focalPoint;\n\n // This is necessary to initialize the clipping range and it is not related\n // to our custom slabThickness.\n // @ts-ignore: vtkjs incorrect typing\n activeCamera.setFreezeFocalPoint(true);\n\n // We shouldn't restore the focalPoint, position and parallelScale after reset\n // if it is the first render or we have completely re-created the vtkImageData\n this._restoreCameraProps(\n cameraProps,\n previousCameraProps,\n panCache as Point3\n );\n\n // Restore rotation for the new slice of the image\n this.rotationCache = 0;\n this._setPropertiesFromCache();\n\n return;\n }\n\n const {\n origin,\n direction,\n dimensions,\n spacing,\n bitsAllocated,\n numComps,\n numVoxels,\n imagePixelModule,\n } = this._getImageDataMetadata(image);\n\n // 3b. If we cannot reuse the vtkImageData object (either the first render\n // or the size has changed), create a new one\n this._createVTKImageData({\n origin,\n direction,\n dimensions,\n spacing,\n bitsAllocated,\n numComps,\n numVoxels,\n });\n\n // Set the scalar data of the vtkImageData object from the Cornerstone\n // Image's pixel data\n this._updateVTKImageDataFromCornerstoneImage(image);\n\n // Create a VTK Image Slice actor to display the vtkImageData object\n const actor = this.createActorMapper(this._imageData);\n const actors = [];\n actors.push({ uid: this.id, actor });\n this.setActors(actors);\n // Adjusting the camera based on slice axis. this is required if stack\n // contains various image orientations (axial ct, sagittal xray)\n const { viewPlaneNormal, viewUp } = this._getCameraOrientation(direction);\n\n this.setCameraNoEvent({ viewUp, viewPlaneNormal });\n\n // Reset the camera to point to the new slice location, reset camera doesn't\n // modify the direction of projection and viewUp\n this.resetCameraNoEvent();\n\n this.triggerCameraEvent(this.getCamera(), previousCameraProps);\n\n // This is necessary to initialize the clipping range and it is not related\n // to our custom slabThickness.\n // @ts-ignore: vtkjs incorrect typing\n activeCamera.setFreezeFocalPoint(true);\n\n // set voi for the first time\n const { windowCenter, windowWidth } = imagePixelModule;\n let voiRange =\n typeof windowCenter === 'number' && typeof windowWidth === 'number'\n ? windowLevelUtil.toLowHighRange(windowWidth, windowCenter)\n : undefined;\n\n // check if the image is already prescaled\n const isPreScaled =\n this.csImage.isPreScaled || this.csImage.preScale?.scaled;\n\n if (imagePixelModule.modality === 'PT' && isPreScaled) {\n voiRange = { lower: 0, upper: 5 };\n }\n\n this.initialVOIRange = voiRange;\n\n if (this.voiApplied && typeof voiRange === 'undefined') {\n // There are some cases when different frames within the same multi-frame\n // file are not hitting the actor cache because above\n // this.__checkVTKImageDataMatchesCornerstoneImage() call results in\n // \"false\".\n // In that case we want to keep the applied VOI range.\n voiRange = this.voiRange;\n }\n this.setProperties({ voiRange });\n\n // At the moment it appears that vtkImageSlice actors do not automatically\n // have an RGB Transfer Function created, so we need to create one.\n // Note: the 1024 here is what VTK would normally do to resample a color transfer function\n // before it is put into the GPU. Setting it with a length of 1024 allows us to\n // avoid that resampling step.\n const cfun = vtkColorTransferFunction.newInstance();\n let lower = 0;\n let upper = 1024;\n if (\n voiRange &&\n voiRange.lower !== undefined &&\n voiRange.upper !== undefined\n ) {\n lower = voiRange.lower;\n upper = voiRange.upper;\n }\n cfun.addRGBPoint(lower, 0.0, 0.0, 0.0);\n cfun.addRGBPoint(upper, 1.0, 1.0, 1.0);\n actor.getProperty().setRGBTransferFunction(0, cfun);\n\n // Saving position of camera on render, to cache the panning\n const { focalPoint } = this.getCamera();\n this.cameraFocalPointOnRender = focalPoint;\n this.stackInvalidated = false;\n\n if (this._publishCalibratedEvent) {\n this.triggerCalibrationEvent();\n }\n }\n\n /**\n * Loads the image based on the provided imageIdIndex\n * @param imageIdIndex - number represents imageId index\n */\n private async _setImageIdIndex(imageIdIndex: number): Promise<string> {\n if (imageIdIndex >= this.imageIds.length) {\n throw new Error(\n `ImageIdIndex provided ${imageIdIndex} is invalid, the stack only has ${this.imageIds.length} elements`\n );\n }\n\n // Update the state of the viewport to the new imageIdIndex;\n this.currentImageIdIndex = imageIdIndex;\n this.hasPixelSpacing = true;\n\n // Todo: trigger an event to allow applications to hook into START of loading state\n // Currently we use loadHandlerManagers for this\n const imageId = await this._loadAndDisplayImage(\n this.imageIds[imageIdIndex],\n imageIdIndex\n );\n\n return imageId;\n }\n\n /**\n * Centers Pan and resets the zoom for stack viewport.\n */\n public resetCamera(resetPan = true, resetZoom = true): boolean {\n if (this.useCPURendering) {\n this.resetCameraCPU(resetPan, resetZoom);\n } else {\n this.resetCameraGPU(resetPan, resetZoom);\n }\n\n this.rotation = 0;\n this.rotationCache = 0;\n return true;\n }\n\n private resetCameraCPU(resetPan, resetZoom) {\n const { image } = this._cpuFallbackEnabledElement;\n\n if (!image) {\n return;\n }\n\n resetCamera(this._cpuFallbackEnabledElement, resetPan, resetZoom);\n\n const { scale } = this._cpuFallbackEnabledElement.viewport;\n\n // canvas center is the focal point\n const { clientWidth, clientHeight } = this.element;\n const center: Point2 = [clientWidth / 2, clientHeight / 2];\n\n const centerWorld = this.canvasToWorldCPU(center);\n\n this.setCameraCPU({\n focalPoint: centerWorld,\n scale,\n });\n }\n\n private resetCameraGPU(resetPan, resetZoom): boolean {\n // Todo: we need to make the rotation a camera properties so that\n // we can reset it there, right now it is not possible to reset the rotation\n // without this\n this.getVtkActiveCamera().roll(this.rotationCache);\n\n // For stack Viewport we since we have only one slice\n // it should be enough to reset the camera to the center of the image\n const resetToCenter = true;\n return super.resetCamera(resetPan, resetZoom, resetToCenter);\n }\n\n /**\n * It scrolls the stack of imageIds by the delta amount provided. If the debounce\n * flag is set, it will only scroll the stack if the delta is greater than the\n * debounceThreshold which is 40 milliseconds by default.\n * @param delta - number of indices to scroll, it can be positive or negative\n * @param debounce - whether to debounce the scroll event\n * @param loop - whether to loop the stack\n */\n public scroll(delta: number, debounce = true, loop = false): void {\n const imageIds = this.imageIds;\n\n const currentTargetImageIdIndex = this.targetImageIdIndex;\n const numberOfFrames = imageIds.length;\n\n let newTargetImageIdIndex = currentTargetImageIdIndex + delta;\n newTargetImageIdIndex = Math.max(0, newTargetImageIdIndex);\n\n if (loop) {\n newTargetImageIdIndex = newTargetImageIdIndex % numberOfFrames;\n } else {\n newTargetImageIdIndex = Math.min(\n numberOfFrames - 1,\n newTargetImageIdIndex\n );\n }\n\n this.targetImageIdIndex = newTargetImageIdIndex;\n\n const targetImageId = imageIds[newTargetImageIdIndex];\n\n const imageAlreadyLoaded = cache.isImageIdCached(targetImageId);\n\n // If image is already cached we want to scroll right away; however, if it is\n // not cached, we can debounce the scroll event to avoid firing multiple scroll\n // events for the images that might happen to be passing by (as a result of infinite\n // scrolling).\n if (imageAlreadyLoaded || !debounce) {\n this.setImageIdIndex(newTargetImageIdIndex);\n } else {\n clearTimeout(this.debouncedTimeout);\n this.debouncedTimeout = window.setTimeout(() => {\n this.setImageIdIndex(newTargetImageIdIndex);\n }, 40);\n }\n\n const eventData: StackViewportScrollEventDetail = {\n newImageIdIndex: newTargetImageIdIndex,\n imageId: targetImageId,\n direction: delta,\n };\n\n if (newTargetImageIdIndex !== currentTargetImageIdIndex) {\n triggerEvent(this.element, Events.STACK_VIEWPORT_SCROLL, eventData);\n }\n }\n\n /**\n * Loads the image based on the provided imageIdIndex. It is an Async function which\n * returns a promise that resolves to the imageId.\n *\n * @param imageIdIndex - number represents imageId index in the list of\n * provided imageIds in setStack\n */\n public async setImageIdIndex(imageIdIndex: number): Promise<string> {\n // If we are already on this imageId index, stop here\n if (this.currentImageIdIndex === imageIdIndex) {\n return this.getCurrentImageId();\n }\n\n // Otherwise, get the imageId and attempt to display it\n const imageId = this._setImageIdIndex(imageIdIndex);\n\n return imageId;\n }\n\n /**\n * Calibrates the image with new metadata that has been added for imageId. To calibrate\n * a viewport, you should add your calibration data manually to\n * calibratedPixelSpacingMetadataProvider and call viewport.calibrateSpacing\n * for it get applied.\n *\n * @param imageId - imageId to be calibrated\n */\n public calibrateSpacing(imageId: string): void {\n const imageIdIndex = this.getImageIds().indexOf(imageId);\n this.stackInvalidated = true;\n this._loadAndDisplayImage(imageId, imageIdIndex);\n }\n\n /**\n * Restores the camera props such zooming and panning after an image is\n * changed, if needed (after scroll)\n *\n * @param parallelScale - camera parallel scale\n */\n private _restoreCameraProps(\n { parallelScale: prevScale }: ICamera,\n previousCamera: ICamera,\n panCache: Point3\n ): void {\n const renderer = this.getRenderer();\n\n // get the focalPoint and position after the reset\n const { position, focalPoint } = this.getCamera();\n\n const newPosition = vec3.subtract(vec3.create(), position, panCache);\n const newFocal = vec3.subtract(vec3.create(), focalPoint, panCache);\n\n // Restoring previous state x,y and scale, keeping the new z\n // we need to break the flip operations since they also work on the\n // camera position and focal point\n this.setCameraNoEvent({\n parallelScale: prevScale,\n position: newPosition as Point3,\n focalPoint: newFocal as Point3,\n });\n\n const camera = this.getCamera();\n\n this.triggerCameraEvent(camera, previousCamera);\n\n // Invoking render\n const RESET_CAMERA_EVENT = {\n type: 'ResetCameraEvent',\n renderer,\n };\n\n renderer.invokeEvent(RESET_CAMERA_EVENT);\n }\n\n private triggerCameraEvent(camera: ICamera, previousCamera: ICamera) {\n // Finally emit event for the full camera change cause during load image.\n const eventDetail: EventTypes.CameraModifiedEventDetail = {\n previousCamera,\n camera,\n element: this.element,\n viewportId: this.id,\n renderingEngineId: this.renderingEngineId,\n };\n\n if (!this.suppressEvents) {\n // For crosshairs to adapt to new viewport size\n triggerEvent(this.element, Events.CAMERA_MODIFIED, eventDetail);\n }\n }\n\n private triggerCalibrationEvent() {\n // Update the indexToWorld and WorldToIndex for viewport\n const { imageData } = this.getImageData();\n // Finally emit event for the full camera change cause during load image.\n const eventDetail: EventTypes.ImageSpacingCalibratedEventDetail = {\n element: this.element,\n viewportId: this.id,\n renderingEngineId: this.renderingEngineId,\n imageId: this.getCurrentImageId(),\n // Todo: why do we need to pass imageData? isn't' indexToWorld and worldToIndex enough?\n imageData: imageData as vtkImageData,\n worldToIndex: imageData.getWorldToIndex() as mat4,\n ...this._calibrationEvent,\n };\n\n if (!this.suppressEvents) {\n // Let the tools know the image spacing has been calibrated\n triggerEvent(this.element, Events.IMAGE_SPACING_CALIBRATED, eventDetail);\n }\n\n this._publishCalibratedEvent = false;\n }\n\n /**\n * canvasToWorld Returns the world coordinates of the given `canvasPos`\n * projected onto the plane defined by the `Viewport`'s camera.\n *\n * @param canvasPos - The position in canvas coordinates.\n * @returns The corresponding world coordinates.\n * @public\n */\n public canvasToWorld = (canvasPos: Point2): Point3 => {\n if (this.useCPURendering) {\n return this.canvasToWorldCPU(canvasPos);\n }\n\n return this.canvasToWorldGPU(canvasPos);\n };\n\n /**\n * Returns the canvas coordinates of the given `worldPos`\n * projected onto the `Viewport`'s `canvas`.\n *\n * @param worldPos - The position in world coordinates.\n * @returns The corresponding canvas coordinates.\n * @public\n */\n public worldToCanvas = (worldPos: Point3): Point2 => {\n if (this.useCPURendering) {\n return this.worldToCanvasCPU(worldPos);\n }\n\n return this.worldToCanvasGPU(worldPos);\n };\n\n private canvasToWorldCPU = (canvasPos: Point2): Point3 => {\n if (!this._cpuFallbackEnabledElement.image) {\n return;\n }\n // compute the pixel coordinate in the image\n const [px, py] = canvasToPixel(this._cpuFallbackEnabledElement, canvasPos);\n\n // convert pixel coordinate to world coordinate\n const { origin, spacing, direction } = this.getImageData();\n\n const worldPos = vec3.fromValues(0, 0, 0);\n\n // Calculate size of spacing vector in normal direction\n const iVector = direction.slice(0, 3) as Point3;\n const jVector = direction.slice(3, 6) as Point3;\n\n // Calculate the world coordinate of the pixel\n vec3.scaleAndAdd(worldPos, origin, iVector, px * spacing[0]);\n vec3.scaleAndAdd(worldPos, worldPos, jVector, py * spacing[1]);\n\n return worldPos as Point3;\n };\n\n private worldToCanvasCPU = (worldPos: Point3): Point2 => {\n // world to pixel\n const { spacing, direction, origin } = this.getImageData();\n\n const iVector = direction.slice(0, 3) as Point3;\n const jVector = direction.slice(3, 6) as Point3;\n\n const diff = vec3.subtract(vec3.create(), worldPos, origin);\n\n const worldPoint: Point2 = [\n vec3.dot(diff, iVector) / spacing[0],\n vec3.dot(diff, jVector) / spacing[1],\n ];\n\n // pixel to canvas\n const canvasPoint = pixelToCanvas(\n this._cpuFallbackEnabledElement,\n worldPoint\n );\n return canvasPoint;\n };\n\n private canvasToWorldGPU = (canvasPos: Point2): Point3 => {\n const renderer = this.getRenderer();\n\n // Temporary setting the clipping range to the distance and distance + 0.1\n // in order to calculate the transformations correctly.\n // This is similar to the vtkSlabCamera isPerformingCoordinateTransformations\n // You can read more about it here there.\n const vtkCamera = this.getVtkActiveCamera();\n const crange = vtkCamera.getClippingRange();\n const distance = vtkCamera.getDistance();\n\n vtkCamera.setClippingRange(distance, distance + 0.1);\n\n const offscreenMultiRenderWindow =\n this.getRenderingEngine().offscreenMultiRenderWindow;\n const openGLRenderWindow =\n offscreenMultiRenderWindow.getOpenGLRenderWindow();\n const size = openGLRenderWindow.getSize();\n\n const devicePixelRatio = window.devicePixelRatio || 1;\n const canvasPosWithDPR = [\n canvasPos[0] * devicePixelRatio,\n canvasPos[1] * devicePixelRatio,\n ];\n const displayCoord = [\n canvasPosWithDPR[0] + this.sx,\n canvasPosWithDPR[1] + this.sy,\n ];\n\n // The y axis display coordinates are inverted with respect to canvas coords\n displayCoord[1] = size[1] - displayCoord[1];\n\n const worldCoord = openGLRenderWindow.displayToWorld(\n displayCoord[0],\n displayCoord[1],\n 0,\n renderer\n );\n\n // set clipping range back to original to be able\n vtkCamera.setClippingRange(crange[0], crange[1]);\n\n return [worldCoord[0], worldCoord[1], worldCoord[2]];\n };\n\n private worldToCanvasGPU = (worldPos: Point3) => {\n const renderer = this.getRenderer();\n\n // Temporary setting the clipping range to the distance and distance + 0.1\n // in order to calculate the transformations correctly.\n // This is similar to the vtkSlabCamera isPerformingCoordinateTransformations\n // You can read more about it here there.\n const vtkCamera = this.getVtkActiveCamera();\n const crange = vtkCamera.getClippingRange();\n const distance = vtkCamera.getDistance();\n\n vtkCamera.setClippingRange(distance, distance + 0.1);\n\n const offscreenMultiRenderWindow =\n this.getRenderingEngine().offscreenMultiRenderWindow;\n const openGLRenderWindow =\n offscreenMultiRenderWindow.getOpenGLRenderWindow();\n const size = openGLRenderWindow.getSize();\n const displayCoord = openGLRenderWindow.worldToDisplay(\n ...worldPos,\n renderer\n );\n\n // The y axis display coordinates are inverted with respect to canvas coords\n displayCoord[1] = size[1] - displayCoord[1];\n\n const canvasCoord = <Point2>[\n displayCoord[0] - this.sx,\n displayCoord[1] - this.sy,\n ];\n\n // set clipping range back to original to be able\n vtkCamera.setClippingRange(crange[0], crange[1]);\n\n const devicePixelRatio = window.devicePixelRatio || 1;\n const canvasCoordWithDPR = <Point2>[\n canvasCoord[0] / devicePixelRatio,\n canvasCoord[1] / devicePixelRatio,\n ];\n\n return canvasCoordWithDPR;\n };\n\n /**\n * Returns the index of the imageId being renderer\n *\n * @returns currently shown imageId index\n */\n public getCurrentImageIdIndex = (): number => {\n return this.currentImageIdIndex;\n };\n\n /**\n *\n * Returns the imageIdIndex that is targeted to be loaded, in case of debounced\n * loading (with scroll), the targetImageIdIndex is the latest imageId\n * index that is requested to be loaded but debounced.\n */\n public getTargetImageIdIndex = (): number => {\n return this.targetImageIdIndex;\n };\n\n /**\n * Returns the list of image Ids for the current viewport\n * @returns list of strings for image Ids\n */\n public getImageIds = (): Array<string> => {\n return this.imageIds;\n };\n\n /**\n * Returns the currently rendered imageId\n * @returns string for imageId\n */\n public getCurrentImageId = (): string => {\n return this.imageIds[this.currentImageIdIndex];\n };\n\n /**\n * Returns true if the viewport contains the given imageId\n * @param imageId - imageId\n * @returns boolean if imageId is in viewport\n */\n public hasImageId = (imageId: string): boolean => {\n return this.imageIds.includes(imageId);\n };\n\n /**\n * Returns true if the viewport contains the given imageURI (no data loader scheme)\n * @param imageURI - imageURI\n * @returns boolean if imageURI is in viewport\n */\n public hasImageURI = (imageURI: string): boolean => {\n const imageIds = this.imageIds;\n for (let i = 0; i < imageIds.length; i++) {\n if (imageIdToURI(imageIds[i]) === imageURI) return true;\n }\n\n return false;\n };\n\n /**\n * If the renderer is CPU based, throw an error. Otherwise, returns the `vtkRenderer` responsible for rendering the `Viewport`.\n *\n * @returns The `vtkRenderer` for the `Viewport`.\n */\n public getRenderer() {\n if (this.useCPURendering) {\n throw this.getCPUFallbackError('getRenderer');\n }\n\n return super.getRenderer();\n }\n\n /**\n * If the renderer is CPU based, throw an error. Otherwise, return the default\n * actor which is the first actor in the renderer.\n * @returns An actor entry.\n */\n public getDefaultActor(): ActorEntry {\n if (this.useCPURendering) {\n throw this.getCPUFallbackError('getDefaultActor');\n }\n\n return super.getDefaultActor();\n }\n\n /**\n * If the renderer is CPU based, throw an error. Otherwise, return the actors in the viewport\n * @returns An array of ActorEntry objects.\n */\n public getActors(): Array<ActorEntry> {\n if (this.useCPURendering) {\n throw this.getCPUFallbackError('getActors');\n }\n\n return super.getActors();\n }\n\n /**\n * If the renderer is CPU based, throw an error. Otherwise, it returns the actor entry for the given actor UID.\n * @param actorUID - The unique ID of the actor you want to get.\n * @returns An ActorEntry object.\n */\n public getActor(actorUID: string): ActorEntry {\n if (this.useCPURendering) {\n throw this.getCPUFallbackError('getActor');\n }\n\n return super.getActor(actorUID);\n }\n\n /**\n * If the renderer is CPU-based, throw an error; otherwise, set the\n * actors in the viewport.\n * @param actors - An array of ActorEntry objects.\n */\n public setActors(actors: Array<ActorEntry>): void {\n if (this.useCPURendering) {\n throw this.getCPUFallbackError('setActors');\n }\n\n return super.setActors(actors);\n }\n\n /**\n * If the renderer is CPU based, throw an error. Otherwise, add a list of actors to the viewport\n * @param actors - An array of ActorEntry objects.\n */\n public addActors(actors: Array<ActorEntry>): void {\n if (this.useCPURendering) {\n throw this.getCPUFallbackError('addActors');\n }\n\n return super.addActors(actors);\n }\n\n /**\n * If the renderer is CPU based, throw an error. Otherwise, add the\n * actor to the viewport\n * @param actorEntry - The ActorEntry object that was created by the\n * user.\n */\n public addActor(actorEntry: ActorEntry): void {\n if (this.useCPURendering) {\n throw this.getCPUFallbackError('addActor');\n }\n\n return super.addActor(actorEntry);\n }\n\n /**\n * It throws an error if the renderer is CPU based. Otherwise, it removes the actors from the viewport.\n */\n public removeAllActors(): void {\n if (this.useCPURendering) {\n throw this.getCPUFallbackError('removeAllActors');\n }\n\n return super.removeAllActors();\n }\n\n private getCPUFallbackError(method: string): Error {\n return new Error(\n `method ${method} cannot be used during CPU Fallback mode`\n );\n }\n\n private fillWithBackgroundColor() {\n const renderingEngine = this.getRenderingEngine();\n\n if (renderingEngine) {\n renderingEngine.fillCanvasWithBackgroundColor(\n this.canvas,\n this.options.background\n );\n }\n }\n\n public customRenderViewportToCanvas = () => {\n if (!this.useCPURendering) {\n throw new Error(\n 'Custom cpu rendering pipeline should only be hit in CPU rendering mode'\n );\n }\n\n if (this._cpuFallbackEnabledElement.image) {\n drawImageSync(\n this._cpuFallbackEnabledElement,\n this.cpuRenderingInvalidated\n );\n // reset flags\n this.cpuRenderingInvalidated = false;\n } else {\n this.fillWithBackgroundColor();\n }\n\n return {\n canvas: this.canvas,\n element: this.element,\n viewportId: this.id,\n renderingEngineId: this.renderingEngineId,\n };\n };\n\n /**\n * Sets the colormap for the current viewport.\n * @param colormap - The colormap data to use.\n */\n public setColormap(colormap: CPUFallbackColormapData): void {\n if (this.useCPURendering) {\n this.setColormapCPU(colormap);\n } else {\n this.setColormapGPU(colormap);\n }\n }\n\n /**\n * It sets the colormap to the default colormap.\n */\n public unsetColormap(): void {\n if (this.useCPURendering) {\n this.unsetColormapCPU();\n } else {\n this.unsetColormapGPU();\n }\n }\n\n private unsetColormapCPU() {\n delete this._cpuFallbackEnabledElement.viewport.colormap;\n this._cpuFallbackEnabledElement.renderingTools = {};\n\n this.cpuRenderingInvalidated = true;\n\n this.fillWithBackgroundColor();\n\n this.render();\n }\n\n private setColormapCPU(colormapData: CPUFallbackColormapData) {\n const colormap = getColormap(colormapData.name, colormapData);\n\n this._cpuFallbackEnabledElement.viewport.colormap = colormap;\n this._cpuFallbackEnabledElement.renderingTools = {};\n\n this.fillWithBackgroundColor();\n this.cpuRenderingInvalidated = true;\n\n this.render();\n }\n\n private setColormapGPU(colormap: CPUFallbackColormapData) {\n // TODO -> vtk has full colormaps which are piecewise and frankly better?\n // Do we really want a pre defined 256 color map just for the sake of harmonization?\n throw new Error('setColorMapGPU not implemented.');\n }\n\n private unsetColormapGPU() {\n // TODO -> vtk has full colormaps which are piecewise and frankly better?\n // Do we really want a pre defined 256 color map just for the sake of harmonization?\n throw new Error('unsetColormapGPU not implemented.');\n }\n\n // create default values for imagePlaneModule if values are undefined\n private _getImagePlaneModule(imageId: string): ImagePlaneModule {\n const imagePlaneModule = metaData.get('imagePlaneModule', imageId);\n\n const newImagePlaneModule: ImagePlaneModule = {\n ...imagePlaneModule,\n };\n\n if (!newImagePlaneModule.columnPixelSpacing) {\n newImagePlaneModule.columnPixelSpacing = 1;\n this.hasPixelSpacing = false;\n }\n\n if (!newImagePlaneModule.rowPixelSpacing) {\n newImagePlaneModule.rowPixelSpacing = 1;\n this.hasPixelSpacing = false;\n }\n\n if (!newImagePlaneModule.columnCosines) {\n newImagePlaneModule.columnCosines = [0, 1, 0];\n }\n\n if (!newImagePlaneModule.rowCosines) {\n newImagePlaneModule.rowCosines = [1, 0, 0];\n }\n\n if (!newImagePlaneModule.imagePositionPatient) {\n newImagePlaneModule.imagePositionPatient = [0, 0, 0];\n }\n\n if (!newImagePlaneModule.imageOrientationPatient) {\n newImagePlaneModule.imageOrientationPatient = new Float32Array([\n 1, 0, 0, 0, 1, 0,\n ]);\n }\n\n return newImagePlaneModule;\n }\n}\n\nexport default StackViewport;\n","import { CPUFallbackViewport, Point2 } from '../../../../types';\n\ntype Shift = {\n x: number;\n y: number;\n};\n/**\n * Corrects the shift by accounting for viewport rotation and flips.\n *\n * @param shift - The shift to correct.\n * @param viewportOrientation - Object containing information on the viewport orientation.\n */\nexport default function (\n shift: Shift,\n viewportOrientation: CPUFallbackViewport\n): Shift {\n const { hflip, vflip, rotation } = viewportOrientation;\n\n // Apply Flips\n shift.x *= hflip ? -1 : 1;\n shift.y *= vflip ? -1 : 1;\n\n // Apply rotations\n if (rotation !== 0) {\n const angle = (rotation * Math.PI) / 180;\n\n const cosA = Math.cos(angle);\n const sinA = Math.sin(angle);\n\n const newX = shift.x * cosA - shift.y * sinA;\n const newY = shift.x * sinA + shift.y * cosA;\n\n shift.x = newX;\n shift.y = newY;\n }\n\n return shift;\n}\n","export default (src, dest) => src.length * 3 === dest.byteLength * 4;\n","import getImageFitScale from './getImageFitScale';\nimport { CPUFallbackEnabledElement } from '../../../../types';\n\n/**\n * Resets the camera to the default position. which would be the center of the image.\n * with no translation, no flipping, no zoom and proper scale.\n */\nexport default function (\n enabledElement: CPUFallbackEnabledElement,\n resetPan = true,\n resetZoom = true\n): void {\n const { canvas, image, viewport } = enabledElement;\n const scale = getImageFitScale(canvas, image, 0).scaleFactor;\n\n viewport.vflip = false;\n viewport.hflip = false;\n\n if (resetPan) {\n viewport.translation.x = 0;\n viewport.translation.y = 0;\n }\n\n if (resetZoom) {\n viewport.displayedArea.tlhc.x = 1;\n viewport.displayedArea.tlhc.y = 1;\n viewport.displayedArea.brhc.x = image.columns;\n viewport.displayedArea.brhc.y = image.rows;\n\n viewport.scale = scale;\n }\n}\n","import BaseVolumeViewport from './BaseVolumeViewport';\nimport { RENDERING_DEFAULTS } from '../constants';\n\n/**\n * An object representing a 3-dimensional volume viewport. VolumeViewport3Ds are used to render\n * 3D volumes in their entirety, and not just load a single slice at a time.\n *\n * For setting volumes on viewports you need to use {@link addVolumesToViewports}\n * which will add volumes to the specified viewports.\n */\nclass VolumeViewport3D extends BaseVolumeViewport {\n public resetCamera(\n resetPan = true,\n resetZoom = true,\n resetToCenter = true\n ): boolean {\n super.resetCamera(resetPan, resetZoom, resetToCenter);\n const activeCamera = this.getVtkActiveCamera();\n // Set large numbers to ensure everything is always rendered\n if (activeCamera.getParallelProjection()) {\n activeCamera.setClippingRange(\n -RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE,\n RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE\n );\n } else {\n activeCamera.setClippingRange(\n RENDERING_DEFAULTS.MINIMUM_SLAB_THICKNESS,\n RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE\n );\n }\n\n return;\n }\n}\n\nexport default VolumeViewport3D;\n","// TODO -> Eventually we'll need to register to this list\nimport StackViewport from '../StackViewport';\nimport VolumeViewport from '../VolumeViewport';\nimport ViewportType from '../../enums/ViewportType';\nimport VolumeViewport3D from '../VolumeViewport3D';\n\nconst viewportTypeToViewportClass = {\n [ViewportType.ORTHOGRAPHIC]: VolumeViewport,\n [ViewportType.PERSPECTIVE]: VolumeViewport,\n [ViewportType.STACK]: StackViewport,\n [ViewportType.VOLUME_3D]: VolumeViewport3D,\n};\n\nexport default viewportTypeToViewportClass;\n","import viewportTypeToViewportClass from './viewportTypeToViewportClass';\n\nexport default function viewportTypeUsesCustomRenderingPipeline(\n viewportType: string\n) {\n return viewportTypeToViewportClass[viewportType].useCustomRenderingPipeline;\n}\n","import Events from '../enums/Events';\nimport renderingEngineCache from './renderingEngineCache';\nimport eventTarget from '../eventTarget';\nimport { triggerEvent, uuidv4 } from '../utilities';\nimport { vtkOffscreenMultiRenderWindow } from './vtkClasses';\nimport ViewportType from '../enums/ViewportType';\nimport VolumeViewport from './VolumeViewport';\nimport BaseVolumeViewport from './BaseVolumeViewport';\nimport StackViewport from './StackViewport';\nimport viewportTypeUsesCustomRenderingPipeline from './helpers/viewportTypeUsesCustomRenderingPipeline';\nimport getOrCreateCanvas from './helpers/getOrCreateCanvas';\nimport { getShouldUseCPURendering, isCornerstoneInitialized } from '../init';\nimport type IStackViewport from '../types/IStackViewport';\nimport type IRenderingEngine from '../types/IRenderingEngine';\nimport type IVolumeViewport from '../types/IVolumeViewport';\nimport type * as EventTypes from '../types/EventTypes';\nimport type {\n ViewportInput,\n PublicViewportInput,\n InternalViewportInput,\n NormalizedViewportInput,\n} from '../types/IViewport';\nimport { OrientationAxis } from '../enums';\nimport VolumeViewport3D from './VolumeViewport3D';\n\ntype ViewportDisplayCoords = {\n sxStartDisplayCoords: number;\n syStartDisplayCoords: number;\n sxEndDisplayCoords: number;\n syEndDisplayCoords: number;\n sx: number;\n sy: number;\n sWidth: number;\n sHeight: number;\n};\n\n/**\n * A RenderingEngine takes care of the full pipeline of creating viewports and rendering\n * them on a large offscreen canvas and transmitting this data back to the screen. This allows us\n * to leverage the power of vtk.js whilst only using one WebGL context for the processing, and allowing\n * us to share texture memory across on-screen viewports that show the same data.\n *\n * Instantiating a rendering engine:\n * ```js\n * const renderingEngine = new RenderingEngine('pet-ct-rendering-engine');\n * ```\n *\n * There are various ways you can trigger a render on viewports. The simplest is to call `render()`\n * on the rendering engine; however, it will trigger a render on all viewports. A more efficient\n * way to do this is to call `renderViewports([viewportId])` on the rendering engine to\n * trigger a render on a specific viewport(s). Each viewport also has a `.render` method which can be used to trigger a render on that\n * viewport.\n *\n * Rendering engine uses `detect-gpu` external library to detect if GPU is available and\n * it has minimum requirement to be able to render a volume with vtk.js. If GPU is not available\n * RenderingEngine will throw an error if you try to render a volume; however, for StackViewports\n * it is capable of falling back to CPU rendering for Stack images.\n *\n * By default RenderingEngine will use vtk.js enabled pipeline for rendering viewports,\n * however, if a custom rendering pipeline is specified by a custom viewport, it will be used instead.\n * We use this custom pipeline to render a StackViewport on CPU using Cornerstone-legacy cpu rendering pipeline.\n *\n * @public\n */\nclass RenderingEngine implements IRenderingEngine {\n /** Unique identifier for renderingEngine */\n readonly id: string;\n /** A flag which tells if the renderingEngine has been destroyed */\n public hasBeenDestroyed: boolean;\n public offscreenMultiRenderWindow: any;\n readonly offScreenCanvasContainer: any; // WebGL\n private _viewports: Map<string, IStackViewport | IVolumeViewport>;\n private _needsRender: Set<string> = new Set();\n private _animationFrameSet = false;\n private _animationFrameHandle: number | null = null;\n private useCPURendering: boolean;\n\n /**\n * @param uid - Unique identifier for RenderingEngine\n */\n constructor(id?: string) {\n this.id = id ? id : uuidv4();\n this.useCPURendering = getShouldUseCPURendering();\n\n renderingEngineCache.set(this);\n\n if (!isCornerstoneInitialized()) {\n throw new Error(\n '@cornerstonejs/core is not initialized, run init() first'\n );\n }\n\n if (!this.useCPURendering) {\n this.offscreenMultiRenderWindow =\n vtkOffscreenMultiRenderWindow.newInstance();\n this.offScreenCanvasContainer = document.createElement('div');\n this.offscreenMultiRenderWindow.setContainer(\n this.offScreenCanvasContainer\n );\n }\n\n this._viewports = new Map();\n this.hasBeenDestroyed = false;\n }\n\n /**\n * Enables the requested viewport and add it to the viewports. It will\n * properly create the Stack viewport or Volume viewport:\n *\n * 1) Checks if the viewport is defined already, if yes, remove it first\n * 2) Checks if the viewport is using a custom rendering pipeline, if no,\n * it calculates a new offscreen canvas with the new requested viewport\n * 3) Adds the viewport\n *\n *\n * ```typescript\n * renderingEngine.enableElement({\n * viewportId: viewportId,\n * type: ViewportType.ORTHOGRAPHIC,\n * element,\n * defaultOptions: {\n * orientation: Enums.OrientationAxis.AXIAL,\n * background: [1, 0, 1],\n * },\n * })\n * ```\n *\n * @fires Events.ELEMENT_ENABLED\n *\n * @param viewportInputEntry - viewport specifications\n */\n public enableElement(viewportInputEntry: PublicViewportInput): void {\n const viewportInput = this._normalizeViewportInputEntry(viewportInputEntry);\n\n this._throwIfDestroyed();\n const { element, viewportId } = viewportInput;\n\n // Throw error if no canvas\n if (!element) {\n throw new Error('No element provided');\n }\n\n // 1. Get the viewport from the list of available viewports.\n const viewport = this.getViewport(viewportId);\n\n // 1.a) If there is a found viewport, we remove the viewport and create a new viewport\n if (viewport) {\n this.disableElement(viewportId);\n // todo: if only removing the viewport, make sure resize also happens\n // this._removeViewport(viewportId)\n }\n\n // 2.a) See if viewport uses a custom rendering pipeline.\n const { type } = viewportInput;\n\n const viewportUsesCustomRenderingPipeline =\n viewportTypeUsesCustomRenderingPipeline(type);\n\n // 2.b) Retrieving the list of viewports for calculation of the new size for\n // offScreen canvas.\n\n // If the viewport being added uses a custom pipeline, or we aren't using\n // GPU rendering, we don't need to resize the offscreen canvas.\n if (!this.useCPURendering && !viewportUsesCustomRenderingPipeline) {\n this.enableVTKjsDrivenViewport(viewportInput);\n } else {\n // 3 Add the requested viewport to rendering Engine\n this.addCustomViewport(viewportInput);\n }\n\n // 5. Set the background color for the canvas\n const canvas = getOrCreateCanvas(element);\n const { background } = viewportInput.defaultOptions;\n this.fillCanvasWithBackgroundColor(canvas, background);\n }\n\n /**\n * Disables the requested viewportId from the rendering engine:\n *\n * 1) It removes the viewport from the the list of viewports\n * 2) remove the renderer from the offScreen render window if using vtk.js driven\n * rendering pipeline\n * 3) resetting the viewport to remove the canvas attributes and canvas data\n * 4) resize the offScreen appropriately (if using vtk.js driven rendering pipeline)\n *\n * @fires Events.ELEMENT_ENABLED\n *\n * @param viewportId - viewport Id\n *\n */\n public disableElement(viewportId: string): void {\n this._throwIfDestroyed();\n // 1. Getting the viewport to remove it\n const viewport = this.getViewport(viewportId);\n\n // 2 To throw if there is no viewport stored in rendering engine\n if (!viewport) {\n console.warn(`viewport ${viewportId} does not exist`);\n return;\n }\n\n // 3. Reset the viewport to remove attributes, and reset the canvas\n this._resetViewport(viewport);\n\n // 4. Remove the related renderer from the offScreenMultiRenderWindow\n if (\n !viewportTypeUsesCustomRenderingPipeline(viewport.type) &&\n !this.useCPURendering\n ) {\n this.offscreenMultiRenderWindow.removeRenderer(viewportId);\n }\n\n // 5. Remove the requested viewport from the rendering engine\n this._removeViewport(viewportId);\n viewport.isDisabled = true;\n\n // 6. Avoid rendering for the disabled viewport\n this._needsRender.delete(viewportId);\n\n // 7. Clear RAF if no viewport is left\n const viewports = this.getViewports();\n if (!viewports.length) {\n this._clearAnimationFrame();\n }\n\n // 8. Resize the offScreen canvas to accommodate for the new size (after removal)\n // Note: Resize should not reset pan and zoom when disabling an element.\n // This is because we are only resizing the offscreen canvas to deal with the element\n // which was removed, and do not wish to alter the current state of any other currently enabled element\n const immediate = true;\n const keepCamera = true;\n this.resize(immediate, keepCamera);\n }\n\n /**\n * It takes an array of viewport input objects including element, viewportId, type\n * and defaultOptions. It will add the viewport to the rendering engine and enables them.\n *\n *\n * ```typescript\n *renderingEngine.setViewports([\n * {\n * viewportId: axialViewportId,\n * type: ViewportType.ORTHOGRAPHIC,\n * element: document.getElementById('axialDiv'),\n * defaultOptions: {\n * orientation: Enums.OrientationAxis.AXIAL,\n * },\n * },\n * {\n * viewportId: sagittalViewportId,\n * type: ViewportType.ORTHOGRAPHIC,\n * element: document.getElementById('sagittalDiv'),\n * defaultOptions: {\n * orientation: Enums.OrientationAxis.SAGITTAL,\n * },\n * },\n * {\n * viewportId: customOrientationViewportId,\n * type: ViewportType.ORTHOGRAPHIC,\n * element: document.getElementById('customOrientationDiv'),\n * defaultOptions: {\n * orientation: { viewPlaneNormal: [0, 0, 1], viewUp: [0, 1, 0] },\n * },\n * },\n * ])\n * ```\n *\n * @fires Events.ELEMENT_ENABLED\n *\n * @param viewportInputEntries - Array<PublicViewportInput>\n */\n\n public setViewports(\n publicViewportInputEntries: Array<PublicViewportInput>\n ): void {\n const viewportInputEntries = this._normalizeViewportInputEntries(\n publicViewportInputEntries\n );\n this._throwIfDestroyed();\n this._reset();\n\n // 1. Split viewports based on whether they use vtk.js or a custom pipeline.\n\n const vtkDrivenViewportInputEntries: NormalizedViewportInput[] = [];\n const customRenderingViewportInputEntries: NormalizedViewportInput[] = [];\n\n viewportInputEntries.forEach((vpie) => {\n if (\n !this.useCPURendering &&\n !viewportTypeUsesCustomRenderingPipeline(vpie.type)\n ) {\n vtkDrivenViewportInputEntries.push(vpie);\n } else {\n customRenderingViewportInputEntries.push(vpie);\n }\n });\n\n this.setVtkjsDrivenViewports(vtkDrivenViewportInputEntries);\n this.setCustomViewports(customRenderingViewportInputEntries);\n }\n\n /**\n * Resizes the offscreen viewport and recalculates translations to on screen canvases.\n * It is up to the parent app to call the resize of the on-screen canvas changes.\n * This is left as an app level concern as one might want to debounce the changes, or the like.\n *\n * @param immediate - Whether all of the viewports should be rendered immediately.\n * @param keepCamera - Whether to keep the camera for other viewports while resizing the offscreen canvas\n */\n public resize(immediate = true, keepCamera = true): void {\n this._throwIfDestroyed();\n // 1. Get the viewports' canvases\n const viewports = this._getViewportsAsArray();\n\n const vtkDrivenViewports = [];\n const customRenderingViewports = [];\n\n viewports.forEach((vpie) => {\n if (!viewportTypeUsesCustomRenderingPipeline(vpie.type)) {\n vtkDrivenViewports.push(vpie);\n } else {\n customRenderingViewports.push(vpie);\n }\n });\n\n this._resizeVTKViewports(vtkDrivenViewports, keepCamera, immediate);\n\n this._resizeUsingCustomResizeHandler(\n customRenderingViewports,\n keepCamera,\n immediate\n );\n }\n\n /**\n * Returns the viewport by Id\n *\n * @returns viewport\n */\n public getViewport(viewportId: string): IStackViewport | IVolumeViewport {\n return this._viewports.get(viewportId);\n }\n\n /**\n * getViewports Returns an array of all `Viewport`s on the `RenderingEngine` instance.\n *\n * @returns Array of viewports\n */\n public getViewports(): Array<IStackViewport | IVolumeViewport> {\n this._throwIfDestroyed();\n\n return this._getViewportsAsArray();\n }\n\n /**\n * Filters all the available viewports and return the stack viewports\n * @returns stack viewports registered on the rendering Engine\n */\n public getStackViewports(): Array<IStackViewport> {\n this._throwIfDestroyed();\n\n const viewports = this.getViewports();\n\n const isStackViewport = (\n viewport: IStackViewport | IVolumeViewport\n ): viewport is StackViewport => {\n return viewport instanceof StackViewport;\n };\n\n return viewports.filter(isStackViewport);\n }\n\n /**\n * Return all the viewports that are volume viewports\n * @returns An array of VolumeViewport objects.\n */\n public getVolumeViewports(): Array<IVolumeViewport> {\n this._throwIfDestroyed();\n\n const viewports = this.getViewports();\n\n const isVolumeViewport = (\n viewport: IStackViewport | IVolumeViewport\n ): viewport is BaseVolumeViewport => {\n return viewport instanceof BaseVolumeViewport;\n };\n\n return viewports.filter(isVolumeViewport);\n }\n\n /**\n * Renders all viewports on the next animation frame.\n *\n * @fires Events.IMAGE_RENDERED\n */\n public render(): void {\n const viewports = this.getViewports();\n const viewportIds = viewports.map((vp) => vp.id);\n\n this._setViewportsToBeRenderedNextFrame(viewportIds);\n }\n\n /**\n * Renders any viewports viewing the given Frame Of Reference.\n *\n * @param FrameOfReferenceUID - The unique identifier of the\n * Frame Of Reference.\n */\n public renderFrameOfReference = (FrameOfReferenceUID: string): void => {\n const viewports = this._getViewportsAsArray();\n const viewportIdsWithSameFrameOfReferenceUID = viewports.map((vp) => {\n if (vp.getFrameOfReferenceUID() === FrameOfReferenceUID) {\n return vp.id;\n }\n });\n\n return this.renderViewports(viewportIdsWithSameFrameOfReferenceUID);\n };\n\n /**\n * Renders the provided Viewport IDs.\n *\n */\n public renderViewports(viewportIds: Array<string>): void {\n this._setViewportsToBeRenderedNextFrame(viewportIds);\n }\n\n /**\n * Renders only a specific `Viewport` on the next animation frame.\n *\n * @param viewportId - The Id of the viewport.\n */\n public renderViewport(viewportId: string): void {\n this._setViewportsToBeRenderedNextFrame([viewportId]);\n }\n\n /**\n * destroy the rendering engine. It will remove all the viewports and,\n * if the rendering engine is using the GPU, it will also destroy the GPU\n * resources.\n */\n public destroy(): void {\n if (this.hasBeenDestroyed) {\n return;\n }\n\n // remove vtk rendered first before resetting the viewport\n if (!this.useCPURendering) {\n const viewports = this._getViewportsAsArray();\n viewports.forEach((vp) => {\n this.offscreenMultiRenderWindow.removeRenderer(vp.id);\n });\n\n // Free up WebGL resources\n this.offscreenMultiRenderWindow.delete();\n\n // Make sure all references go stale and are garbage collected.\n delete this.offscreenMultiRenderWindow;\n }\n\n this._reset();\n renderingEngineCache.delete(this.id);\n\n this.hasBeenDestroyed = true;\n }\n\n /**\n * Fill the canvas with the background color\n * @param canvas - The canvas element to draw on.\n * @param backgroundColor - An array of three numbers between 0 and 1 that\n * specify the red, green, and blue values of the background color.\n */\n public fillCanvasWithBackgroundColor(\n canvas: HTMLCanvasElement,\n backgroundColor: [number, number, number]\n ): void {\n const ctx = canvas.getContext('2d');\n\n // Default to black if no background color is set\n let fillStyle;\n if (backgroundColor) {\n const rgb = backgroundColor.map((f) => Math.floor(255 * f));\n fillStyle = `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`;\n } else {\n fillStyle = 'black';\n }\n\n // We draw over the previous stack with the background color while we\n // wait for the next stack to load\n ctx.fillStyle = fillStyle;\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n }\n\n private _normalizeViewportInputEntry(\n viewportInputEntry: PublicViewportInput\n ) {\n const { type, defaultOptions } = viewportInputEntry;\n let options = defaultOptions;\n\n if (!options || Object.keys(options).length === 0) {\n options = {\n background: [0, 0, 0],\n orientation: null,\n };\n\n if (type === ViewportType.ORTHOGRAPHIC) {\n options = {\n ...options,\n orientation: OrientationAxis.AXIAL,\n };\n }\n }\n\n return {\n ...viewportInputEntry,\n defaultOptions: options,\n };\n }\n\n private _normalizeViewportInputEntries(\n viewportInputEntries: Array<PublicViewportInput>\n ): Array<NormalizedViewportInput> {\n const normalizedViewportInputs = [];\n\n viewportInputEntries.forEach((viewportInput) => {\n normalizedViewportInputs.push(\n this._normalizeViewportInputEntry(viewportInput)\n );\n });\n\n return normalizedViewportInputs;\n }\n\n private _resizeUsingCustomResizeHandler(\n customRenderingViewports: StackViewport[],\n keepCamera = true,\n immediate = true\n ) {\n // 1. If viewport has a custom resize method, call it here.\n customRenderingViewports.forEach((vp) => {\n if (typeof vp.resize === 'function') vp.resize();\n });\n\n // 3. Reset viewport cameras\n customRenderingViewports.forEach((vp) => {\n const prevCamera = vp.getCamera();\n vp.resetCamera();\n\n if (keepCamera) {\n vp.setCamera(prevCamera);\n }\n });\n\n // 2. If render is immediate: Render all\n if (immediate === true) {\n this.render();\n }\n }\n\n private _resizeVTKViewports(\n vtkDrivenViewports: Array<IStackViewport | IVolumeViewport>,\n keepCamera = true,\n immediate = true\n ) {\n const canvasesDrivenByVtkJs = vtkDrivenViewports.map((vp) => vp.canvas);\n\n if (canvasesDrivenByVtkJs.length) {\n // 1. Recalculate and resize the offscreen canvas size\n const { offScreenCanvasWidth, offScreenCanvasHeight } =\n this._resizeOffScreenCanvas(canvasesDrivenByVtkJs);\n\n // 2. Recalculate the viewports location on the off screen canvas\n this._resize(\n vtkDrivenViewports,\n offScreenCanvasWidth,\n offScreenCanvasHeight\n );\n }\n\n // 3. Reset viewport cameras\n vtkDrivenViewports.forEach((vp: IStackViewport | IVolumeViewport) => {\n const canvas = getOrCreateCanvas(vp.element);\n const rect = canvas.getBoundingClientRect();\n const devicePixelRatio = window.devicePixelRatio || 1;\n canvas.width = rect.width * devicePixelRatio;\n canvas.height = rect.height * devicePixelRatio;\n\n const prevCamera = vp.getCamera();\n vp.resetCamera();\n\n if (keepCamera) {\n vp.setCamera(prevCamera);\n }\n });\n\n // 4. If render is immediate: Render all\n if (immediate === true) {\n this.render();\n }\n }\n\n /**\n * Enables a viewport to be driven by the offscreen vtk.js rendering engine.\n *\n * @param viewportInputEntry - Information object used to\n * construct and enable the viewport.\n */\n private enableVTKjsDrivenViewport(\n viewportInputEntry: NormalizedViewportInput\n ) {\n const viewports = this._getViewportsAsArray();\n const viewportsDrivenByVtkJs = viewports.filter(\n (vp) => viewportTypeUsesCustomRenderingPipeline(vp.type) === false\n );\n\n const canvasesDrivenByVtkJs = viewportsDrivenByVtkJs.map((vp) => vp.canvas);\n\n const canvas = getOrCreateCanvas(viewportInputEntry.element);\n canvasesDrivenByVtkJs.push(canvas);\n\n const devicePixelRatio = window.devicePixelRatio || 1;\n\n const rect = canvas.getBoundingClientRect();\n canvas.width = rect.width * devicePixelRatio;\n canvas.height = rect.height * devicePixelRatio;\n\n // 2.c Calculating the new size for offScreen Canvas\n const { offScreenCanvasWidth, offScreenCanvasHeight } =\n this._resizeOffScreenCanvas(canvasesDrivenByVtkJs);\n\n // 2.d Re-position previous viewports on the offScreen Canvas based on the new\n // offScreen canvas size\n const xOffset = this._resize(\n viewportsDrivenByVtkJs,\n offScreenCanvasWidth,\n offScreenCanvasHeight\n );\n\n const internalViewportEntry = { ...viewportInputEntry, canvas };\n\n // 3 Add the requested viewport to rendering Engine\n this.addVtkjsDrivenViewport(internalViewportEntry, {\n offScreenCanvasWidth,\n offScreenCanvasHeight,\n xOffset,\n });\n }\n\n /**\n * Disables the requested viewportId from the rendering engine:\n * 1) It removes the viewport from the the list of viewports\n * 2) remove the renderer from the offScreen render window\n * 3) resetting the viewport to remove the canvas attributes and canvas data\n * 4) resize the offScreen appropriately\n *\n * @param viewportId - viewport Id\n *\n */\n private _removeViewport(viewportId: string): void {\n // 1. Get the viewport\n const viewport = this.getViewport(viewportId);\n if (!viewport) {\n console.warn(`viewport ${viewportId} does not exist`);\n return;\n }\n\n // 2. Delete the viewports from the the viewports\n this._viewports.delete(viewportId);\n }\n\n /**\n * Adds a viewport driven by vtk.js to the `RenderingEngine`.\n *\n * @param viewportInputEntry - Information object used to construct and enable the viewport.\n * @param options - Options object used to configure the viewport.\n * @param options.offScreenCanvasWidth - The width of the offscreen canvas.\n * @param options.offScreenCanvasHeight - The height of the offscreen canvas.\n * @param options.xOffset - The x offset of the viewport on the offscreen canvas.\n */\n private addVtkjsDrivenViewport(\n viewportInputEntry: InternalViewportInput,\n offscreenCanvasProperties?: {\n offScreenCanvasWidth: number;\n offScreenCanvasHeight: number;\n xOffset: number;\n }\n ): void {\n const { element, canvas, viewportId, type, defaultOptions } =\n viewportInputEntry;\n\n // Make the element not focusable, we use this for modifier keys to work\n element.tabIndex = -1;\n\n const { offScreenCanvasWidth, offScreenCanvasHeight, xOffset } =\n offscreenCanvasProperties;\n\n // 1. Calculate the size of location of the viewport on the offScreen canvas\n const {\n sxStartDisplayCoords,\n syStartDisplayCoords,\n sxEndDisplayCoords,\n syEndDisplayCoords,\n sx,\n sy,\n sWidth,\n sHeight,\n } = this._getViewportCoordsOnOffScreenCanvas(\n viewportInputEntry,\n offScreenCanvasWidth,\n offScreenCanvasHeight,\n xOffset\n );\n\n // 2. Add a renderer to the offScreenMultiRenderWindow\n this.offscreenMultiRenderWindow.addRenderer({\n viewport: [\n sxStartDisplayCoords,\n syStartDisplayCoords,\n sxEndDisplayCoords,\n syEndDisplayCoords,\n ],\n id: viewportId,\n background: defaultOptions.background\n ? defaultOptions.background\n : [0, 0, 0],\n });\n\n // 3. ViewportInput to be passed to a stack/volume viewport\n const viewportInput = <ViewportInput>{\n id: viewportId,\n element, // div\n renderingEngineId: this.id,\n type,\n canvas,\n sx,\n sy,\n sWidth,\n sHeight,\n defaultOptions: defaultOptions || {},\n };\n\n // 4. Create a proper viewport based on the type of the viewport\n let viewport;\n if (type === ViewportType.STACK) {\n // 4.a Create stack viewport\n viewport = new StackViewport(viewportInput);\n } else if (\n type === ViewportType.ORTHOGRAPHIC ||\n type === ViewportType.PERSPECTIVE\n ) {\n // 4.b Create a volume viewport\n viewport = new VolumeViewport(viewportInput);\n } else if (type === ViewportType.VOLUME_3D) {\n viewport = new VolumeViewport3D(viewportInput);\n } else {\n throw new Error(`Viewport Type ${type} is not supported`);\n }\n\n // 5. Storing the viewports\n this._viewports.set(viewportId, viewport);\n\n const eventDetail: EventTypes.ElementEnabledEventDetail = {\n element,\n viewportId,\n renderingEngineId: this.id,\n };\n\n if (!viewport.suppressEvents) {\n triggerEvent(eventTarget, Events.ELEMENT_ENABLED, eventDetail);\n }\n }\n\n /**\n * Adds a viewport using a custom rendering pipeline to the `RenderingEngine`.\n *\n * @param viewportInputEntry - Information object used to\n * construct and enable the viewport.\n */\n private addCustomViewport(viewportInputEntry: PublicViewportInput): void {\n const { element, viewportId, type, defaultOptions } = viewportInputEntry;\n\n // Make the element not focusable, we use this for modifier keys to work\n element.tabIndex = -1;\n\n const canvas = getOrCreateCanvas(element);\n\n // Add a viewport with no offset\n const { clientWidth, clientHeight } = canvas;\n\n // Set the canvas to be same resolution as the client.\n // Note: This ignores devicePixelRatio for now. We may want to change it in the\n // future but it has no benefit for the Cornerstone CPU rendering pathway at the\n // moment anyway.\n if (canvas.width !== clientWidth || canvas.height !== clientHeight) {\n canvas.width = clientWidth;\n canvas.height = clientHeight;\n }\n\n const viewportInput = <ViewportInput>{\n id: viewportId,\n renderingEngineId: this.id,\n element, // div\n type,\n canvas,\n sx: 0, // No offset, uses own renderer\n sy: 0,\n sWidth: clientWidth,\n sHeight: clientHeight,\n defaultOptions: defaultOptions || {},\n };\n\n // 4. Create a proper viewport based on the type of the viewport\n\n if (type !== ViewportType.STACK) {\n // In the future these will need to be pluggable, but we aren't there yet\n // and these are just Stacks for now.\n throw new Error('Support for fully custom viewports not yet implemented');\n }\n\n // 4.a Create stack viewport\n const viewport = new StackViewport(viewportInput);\n\n // 5. Storing the viewports\n this._viewports.set(viewportId, viewport);\n\n const eventDetail: EventTypes.ElementEnabledEventDetail = {\n element,\n viewportId,\n renderingEngineId: this.id,\n };\n\n triggerEvent(eventTarget, Events.ELEMENT_ENABLED, eventDetail);\n }\n\n /**\n * Sets multiple viewports using custom rendering\n * pipelines to the `RenderingEngine`.\n *\n * @param viewportInputEntries - An array of information\n * objects used to construct and enable the viewports.\n */\n private setCustomViewports(viewportInputEntries: PublicViewportInput[]) {\n viewportInputEntries.forEach((vpie) => this.addCustomViewport(vpie));\n }\n\n /**\n * Sets multiple vtk.js driven viewports to\n * the `RenderingEngine`.\n *\n * @param viewportInputEntries - An array of information\n * objects used to construct and enable the viewports.\n */\n private setVtkjsDrivenViewports(\n viewportInputEntries: NormalizedViewportInput[]\n ) {\n // Deal with vtkjs driven viewports\n if (viewportInputEntries.length) {\n // 1. Getting all the canvases from viewports calculation of the new offScreen size\n const vtkDrivenCanvases = viewportInputEntries.map((vp) =>\n getOrCreateCanvas(vp.element)\n );\n\n // Ensure the canvas size includes any scaling due to device pixel ratio\n vtkDrivenCanvases.forEach((canvas) => {\n const devicePixelRatio = window.devicePixelRatio || 1;\n\n const rect = canvas.getBoundingClientRect();\n canvas.width = rect.width * devicePixelRatio;\n canvas.height = rect.height * devicePixelRatio;\n });\n\n // 2. Set canvas size based on height and sum of widths\n const { offScreenCanvasWidth, offScreenCanvasHeight } =\n this._resizeOffScreenCanvas(vtkDrivenCanvases);\n\n /*\n TODO: Commenting this out until we can mock the Canvas usage in the tests (or use jsdom?)\n if (!offScreenCanvasWidth || !offScreenCanvasHeight) {\n throw new Error('Invalid offscreen canvas width or height')\n }*/\n\n // 3. Adding the viewports based on the viewportInputEntry definition to the\n // rendering engine.\n let xOffset = 0;\n for (let i = 0; i < viewportInputEntries.length; i++) {\n const vtkDrivenViewportInputEntry = viewportInputEntries[i];\n const canvas = vtkDrivenCanvases[i];\n const internalViewportEntry = {\n ...vtkDrivenViewportInputEntry,\n canvas,\n };\n\n this.addVtkjsDrivenViewport(internalViewportEntry, {\n offScreenCanvasWidth,\n offScreenCanvasHeight,\n xOffset,\n });\n\n // Incrementing the xOffset which provides the horizontal location of each\n // viewport on the offScreen canvas\n xOffset += canvas.width;\n }\n }\n }\n\n /**\n * Resizes the offscreen canvas based on the provided vtk.js driven canvases.\n *\n * @param canvases - An array of HTML Canvas\n */\n private _resizeOffScreenCanvas(\n canvasesDrivenByVtkJs: Array<HTMLCanvasElement>\n ): { offScreenCanvasWidth: number; offScreenCanvasHeight: number } {\n const { offScreenCanvasContainer, offscreenMultiRenderWindow } = this;\n\n const devicePixelRatio = window.devicePixelRatio || 1;\n\n // 1. Calculated the height of the offScreen canvas to be the maximum height\n // between canvases\n const offScreenCanvasHeight = Math.max(\n ...canvasesDrivenByVtkJs.map(\n (canvas) => canvas.clientHeight * devicePixelRatio\n )\n );\n\n // 2. Calculating the width of the offScreen canvas to be the sum of all\n let offScreenCanvasWidth = 0;\n\n canvasesDrivenByVtkJs.forEach((canvas) => {\n offScreenCanvasWidth += canvas.clientWidth * devicePixelRatio;\n });\n\n offScreenCanvasContainer.width = offScreenCanvasWidth;\n offScreenCanvasContainer.height = offScreenCanvasHeight;\n\n // 3. Resize command\n offscreenMultiRenderWindow.resize();\n\n return { offScreenCanvasWidth, offScreenCanvasHeight };\n }\n\n /**\n * Recalculates and updates the viewports location on the offScreen canvas upon its resize\n *\n * @param viewports - An array of viewports\n * @param offScreenCanvasWidth - new offScreen canvas width\n * @param offScreenCanvasHeight - new offScreen canvas height\n *\n * @returns _xOffset the final offset which will be used for the next viewport\n */\n private _resize(\n viewportsDrivenByVtkJs: Array<IStackViewport | IVolumeViewport>,\n offScreenCanvasWidth: number,\n offScreenCanvasHeight: number\n ): number {\n // Redefine viewport properties\n let _xOffset = 0;\n\n const devicePixelRatio = window.devicePixelRatio || 1;\n\n for (let i = 0; i < viewportsDrivenByVtkJs.length; i++) {\n const viewport = viewportsDrivenByVtkJs[i];\n const {\n sxStartDisplayCoords,\n syStartDisplayCoords,\n sxEndDisplayCoords,\n syEndDisplayCoords,\n sx,\n sy,\n sWidth,\n sHeight,\n } = this._getViewportCoordsOnOffScreenCanvas(\n viewport,\n offScreenCanvasWidth,\n offScreenCanvasHeight,\n _xOffset\n );\n\n _xOffset += viewport.canvas.clientWidth * devicePixelRatio;\n\n viewport.sx = sx;\n viewport.sy = sy;\n viewport.sWidth = sWidth;\n viewport.sHeight = sHeight;\n\n // Updating the renderer for the viewport\n const renderer = this.offscreenMultiRenderWindow.getRenderer(viewport.id);\n renderer.setViewport([\n sxStartDisplayCoords,\n syStartDisplayCoords,\n sxEndDisplayCoords,\n syEndDisplayCoords,\n ]);\n }\n\n // Returns the final xOffset\n return _xOffset;\n }\n\n /**\n * Calculates the location of the provided viewport on the offScreenCanvas\n *\n * @param viewports - An array of viewports\n * @param offScreenCanvasWidth - new offScreen canvas width\n * @param offScreenCanvasHeight - new offScreen canvas height\n * @param _xOffset - xOffSet to draw\n */\n private _getViewportCoordsOnOffScreenCanvas(\n viewport: InternalViewportInput | IStackViewport | IVolumeViewport,\n offScreenCanvasWidth: number,\n offScreenCanvasHeight: number,\n _xOffset: number\n ): ViewportDisplayCoords {\n const { canvas } = viewport;\n const { clientWidth, clientHeight } = canvas;\n const devicePixelRatio = window.devicePixelRatio || 1;\n const height = clientHeight * devicePixelRatio;\n const width = clientWidth * devicePixelRatio;\n\n // Update the canvas drawImage offsets.\n const sx = _xOffset;\n const sy = 0;\n const sWidth = width;\n const sHeight = height;\n\n const sxStartDisplayCoords = sx / offScreenCanvasWidth;\n\n // Need to offset y if it not max height\n const syStartDisplayCoords =\n sy + (offScreenCanvasHeight - height) / offScreenCanvasHeight;\n\n const sWidthDisplayCoords = sWidth / offScreenCanvasWidth;\n const sHeightDisplayCoords = sHeight / offScreenCanvasHeight;\n\n return {\n sxStartDisplayCoords,\n syStartDisplayCoords,\n sxEndDisplayCoords: sxStartDisplayCoords + sWidthDisplayCoords,\n syEndDisplayCoords: syStartDisplayCoords + sHeightDisplayCoords,\n sx,\n sy,\n sWidth,\n sHeight,\n };\n }\n\n /**\n * @method _getViewportsAsArray Returns an array of all viewports\n *\n * @returns {Array} Array of viewports.\n */\n private _getViewportsAsArray() {\n return Array.from(this._viewports.values());\n }\n\n private _setViewportsToBeRenderedNextFrame(viewportIds: string[]) {\n // Add the viewports to the set of flagged viewports\n viewportIds.forEach((viewportId) => {\n this._needsRender.add(viewportId);\n });\n\n // Render any flagged viewports\n this._render();\n }\n\n /**\n * Sets up animation frame if necessary\n */\n private _render() {\n // If we have viewports that need rendering and we have not already\n // set the RAF callback to run on the next frame.\n if (this._needsRender.size > 0 && this._animationFrameSet === false) {\n this._animationFrameHandle = window.requestAnimationFrame(\n this._renderFlaggedViewports\n );\n\n // Set the flag that we have already set up the next RAF call.\n this._animationFrameSet = true;\n }\n }\n\n /**\n * Renders all viewports.\n */\n private _renderFlaggedViewports = () => {\n this._throwIfDestroyed();\n\n if (!this.useCPURendering) {\n this.performVtkDrawCall();\n }\n\n const viewports = this._getViewportsAsArray();\n const eventDetailArray = [];\n\n for (let i = 0; i < viewports.length; i++) {\n const viewport = viewports[i];\n if (this._needsRender.has(viewport.id)) {\n const eventDetail =\n this.renderViewportUsingCustomOrVtkPipeline(viewport);\n eventDetailArray.push(eventDetail);\n\n // This viewport has been rendered, we can remove it from the set\n this._needsRender.delete(viewport.id);\n\n // If there is nothing left that is flagged for rendering, stop the loop\n if (this._needsRender.size === 0) {\n break;\n }\n }\n }\n\n // allow RAF to be called again\n this._animationFrameSet = false;\n this._animationFrameHandle = null;\n\n eventDetailArray.forEach((eventDetail) => {\n triggerEvent(eventDetail.element, Events.IMAGE_RENDERED, eventDetail);\n });\n };\n\n /**\n * Performs the single `vtk.js` draw call which is used to render the offscreen\n * canvas for vtk.js. This is a bulk rendering step for all Volume and Stack\n * viewports when GPU rendering is available.\n */\n private performVtkDrawCall() {\n // Render all viewports under vtk.js' control.\n const { offscreenMultiRenderWindow } = this;\n const renderWindow = offscreenMultiRenderWindow.getRenderWindow();\n\n const renderers = offscreenMultiRenderWindow.getRenderers();\n\n if (!renderers.length) {\n return;\n }\n\n for (let i = 0; i < renderers.length; i++) {\n const { renderer, id } = renderers[i];\n\n // Requesting viewports that need rendering to be rendered only\n if (this._needsRender.has(id)) {\n renderer.setDraw(true);\n } else {\n renderer.setDraw(false);\n }\n }\n\n renderWindow.render();\n\n // After redraw we set all renderers to not render until necessary\n for (let i = 0; i < renderers.length; i++) {\n renderers[i].renderer.setDraw(false);\n }\n }\n\n /**\n * Renders the given viewport\n * using its proffered method.\n *\n * @param viewport - The viewport to render\n */\n private renderViewportUsingCustomOrVtkPipeline(\n viewport: IStackViewport | IVolumeViewport\n ): EventTypes.ImageRenderedEventDetail[] {\n let eventDetail;\n\n if (viewportTypeUsesCustomRenderingPipeline(viewport.type) === true) {\n eventDetail =\n viewport.customRenderViewportToCanvas() as EventTypes.ImageRenderedEventDetail;\n } else {\n if (this.useCPURendering) {\n throw new Error(\n 'GPU not available, and using a viewport with no custom render pipeline.'\n );\n }\n\n const { offscreenMultiRenderWindow } = this;\n const openGLRenderWindow =\n offscreenMultiRenderWindow.getOpenGLRenderWindow();\n const context = openGLRenderWindow.get3DContext();\n const offScreenCanvas = context.canvas;\n\n eventDetail = this._renderViewportFromVtkCanvasToOnscreenCanvas(\n viewport,\n offScreenCanvas\n );\n }\n\n return eventDetail;\n }\n\n /**\n * Renders a particular `Viewport`'s on screen canvas.\n * @param viewport - The `Viewport` to render.\n * @param offScreenCanvas - The offscreen canvas to render from.\n */\n private _renderViewportFromVtkCanvasToOnscreenCanvas(\n viewport: IStackViewport | IVolumeViewport,\n offScreenCanvas\n ): EventTypes.ImageRenderedEventDetail {\n const {\n element,\n canvas,\n sx,\n sy,\n sWidth,\n sHeight,\n id: viewportId,\n renderingEngineId,\n suppressEvents,\n } = viewport;\n\n const { width: dWidth, height: dHeight } = canvas;\n\n const onScreenContext = canvas.getContext('2d');\n\n onScreenContext.drawImage(\n offScreenCanvas,\n sx,\n sy,\n sWidth,\n sHeight,\n 0, //dx\n 0, // dy\n dWidth,\n dHeight\n );\n\n return {\n element,\n suppressEvents,\n viewportId,\n renderingEngineId,\n };\n }\n\n /**\n * Reset the viewport by removing the data attributes\n * and clearing the context of draw. It also emits an element disabled event\n *\n * @param viewport - The `Viewport` to render.\n */\n private _resetViewport(viewport: IStackViewport | IVolumeViewport) {\n const renderingEngineId = this.id;\n\n const { element, canvas, id: viewportId } = viewport;\n\n const eventDetail: EventTypes.ElementDisabledEventDetail = {\n element,\n viewportId,\n renderingEngineId,\n };\n\n // Trigger first before removing the data attributes, as we need the enabled\n // element to remove tools associated with the viewport\n triggerEvent(eventTarget, Events.ELEMENT_DISABLED, eventDetail);\n\n element.removeAttribute('data-viewport-uid');\n element.removeAttribute('data-rendering-engine-uid');\n\n // clear drawing\n const context = canvas.getContext('2d');\n context.clearRect(0, 0, canvas.width, canvas.height);\n }\n\n private _clearAnimationFrame() {\n window.cancelAnimationFrame(this._animationFrameHandle);\n\n this._needsRender.clear();\n this._animationFrameSet = false;\n this._animationFrameHandle = null;\n }\n\n /**\n * Resets the `RenderingEngine`\n */\n private _reset() {\n const viewports = this._getViewportsAsArray();\n\n viewports.forEach((viewport) => {\n this._resetViewport(viewport);\n });\n\n this._clearAnimationFrame();\n\n this._viewports = new Map();\n }\n\n /**\n * Throws an error if trying to interact with the `RenderingEngine`\n * instance after its `destroy` method has been called.\n */\n private _throwIfDestroyed() {\n if (this.hasBeenDestroyed) {\n throw new Error(\n 'this.destroy() has been manually called to free up memory, can not longer use this instance. Instead make a new one.'\n );\n }\n }\n\n // debugging utils for offScreen canvas\n _downloadOffScreenCanvas() {\n const dataURL = this._debugRender();\n _TEMPDownloadURI(dataURL);\n }\n\n // debugging utils for offScreen canvas\n _debugRender(): void {\n const { offscreenMultiRenderWindow } = this;\n const renderWindow = offscreenMultiRenderWindow.getRenderWindow();\n\n const renderers = offscreenMultiRenderWindow.getRenderers();\n\n for (let i = 0; i < renderers.length; i++) {\n renderers[i].renderer.setDraw(true);\n }\n\n renderWindow.render();\n const openGLRenderWindow =\n offscreenMultiRenderWindow.getOpenGLRenderWindow();\n const context = openGLRenderWindow.get3DContext();\n\n const offScreenCanvas = context.canvas;\n const dataURL = offScreenCanvas.toDataURL();\n\n this._getViewportsAsArray().forEach((viewport) => {\n const { sx, sy, sWidth, sHeight } = viewport;\n\n const canvas = <HTMLCanvasElement>viewport.canvas;\n const { width: dWidth, height: dHeight } = canvas;\n\n const onScreenContext = canvas.getContext('2d');\n\n //sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight\n onScreenContext.drawImage(\n offScreenCanvas,\n sx,\n sy,\n sWidth,\n sHeight,\n 0, //dx\n 0, // dy\n dWidth,\n dHeight\n );\n });\n\n return dataURL;\n }\n}\n\nexport default RenderingEngine;\n\n// debugging utils for offScreen canvas\nfunction _TEMPDownloadURI(uri) {\n const link = document.createElement('a');\n\n link.download = 'viewport.png';\n link.href = uri;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n}\n","import RenderingEngine from './RenderingEngine';\nimport getRenderingEngine from './getRenderingEngine';\nimport VolumeViewport from './VolumeViewport';\nimport StackViewport from './StackViewport';\nimport VolumeViewport3D from './VolumeViewport3D';\nimport {\n createVolumeActor,\n createVolumeMapper,\n getOrCreateCanvas,\n} from './helpers';\n\nexport {\n getRenderingEngine,\n RenderingEngine,\n VolumeViewport,\n VolumeViewport3D,\n createVolumeActor,\n createVolumeMapper,\n getOrCreateCanvas,\n StackViewport,\n};\n\nexport default RenderingEngine;\n","import { RequestPoolManager } from './requestPoolManager';\nimport RequestType from '../enums/RequestType';\n\n/**\n * ImageRetrievalPoolManager\n * You don't need to directly use the imageRetrievalPoolManager to load images\n * since the imageLoadPoolManager will automatically use it for retrieval. However,\n * maximum number of concurrent requests can be set by calling `setMaxConcurrentRequests`.\n *\n * Retrieval (usually) === XHR requests\n */\nconst imageRetrievalPoolManager = new RequestPoolManager('imageRetrievalPool');\n\nimageRetrievalPoolManager.setMaxSimultaneousRequests(\n RequestType.Interaction,\n 200\n);\nimageRetrievalPoolManager.setMaxSimultaneousRequests(\n RequestType.Thumbnail,\n 200\n);\nimageRetrievalPoolManager.setMaxSimultaneousRequests(RequestType.Prefetch, 200);\nimageRetrievalPoolManager.grabDelay = 0;\n\nexport default imageRetrievalPoolManager;\n","import getRenderingEngine, {\n getRenderingEngines,\n} from './RenderingEngine/getRenderingEngine';\nimport { IEnabledElement } from './types';\n\n/**\n * A convenience method to find an EnabledElement given a reference to its\n * associated element. Commonly used in code that's handling a custom\n * event emitted by this library.\n *\n * @example\n * Using the renderingEngine to find the enabled element:\n * ```javascript\n * const element = getRenderingEngine(renderingEngineId)\n * .getViewport(viewportId)\n * .element\n *\n * const enabledElement = getEnabledElement(element)\n * ```\n *\n * @example\n * Using a cornerstone event's \"element\"\n * ```javascript\n * // Our \"cornerstone events\" contain the source element, which is\n * // raised on the viewport's div element\n * const { element } = evt.detail\n * const enabledElement = getEnabledElement(element)\n * ```\n *\n * @param element - a reference to an EnabledElement/Viewport's div element\n * @returns the associated EnabledElement, or undefined if no matching EnabledElement\n * can be found\n */\nexport default function getEnabledElement(\n element: HTMLDivElement | undefined\n): IEnabledElement | undefined {\n if (!element) {\n return;\n }\n\n const { viewportUid, renderingEngineUid } = element.dataset;\n\n return getEnabledElementByIds(viewportUid, renderingEngineUid);\n}\n\n/**\n * Similar to {@link getEnabledElement}, but takes the IDs of the\n * renderingEngine and viewport as parameters to return the associated\n * EnabledElement.\n *\n * @param viewportId - The Id of the viewport\n * @param renderingEngineId - The Id of the rendering engine.\n * @returns The enabled element which is an object that contains the viewport, rendering\n * engine, viewport Id, rendering engine Id, and the Frame of Reference UID.\n */\nexport function getEnabledElementByIds(\n viewportId: string,\n renderingEngineId: string\n): IEnabledElement {\n if (!renderingEngineId || !viewportId) {\n return;\n }\n\n const renderingEngine = getRenderingEngine(renderingEngineId);\n\n if (!renderingEngine || renderingEngine.hasBeenDestroyed) {\n return;\n }\n\n const viewport = renderingEngine.getViewport(viewportId);\n\n if (!viewport) {\n return;\n }\n\n const FrameOfReferenceUID = viewport.getFrameOfReferenceUID();\n\n return {\n viewport,\n renderingEngine,\n viewportId,\n renderingEngineId,\n FrameOfReferenceUID,\n };\n}\n\n/**\n * Get all the enabled elements from all the rendering engines\n * @returns An array of enabled elements.\n */\nexport function getEnabledElements(): IEnabledElement[] {\n const enabledElements = [];\n\n const renderingEngines = getRenderingEngines();\n\n renderingEngines.forEach((renderingEngine) => {\n const viewports = renderingEngine.getViewports();\n\n viewports.forEach(({ element }) => {\n enabledElements.push(getEnabledElement(element));\n });\n });\n\n return enabledElements;\n}\n","/*\n * Constants\n */\n\nconst DEFAULT_SETTINGS = Symbol('DefaultSettings');\nconst RUNTIME_SETTINGS = Symbol('RuntimeSettings');\nconst OBJECT_SETTINGS_MAP = Symbol('ObjectSettingsMap');\nconst DICTIONARY = Symbol('Dictionary');\n\n/**\n * Settings\n */\nexport default class Settings {\n constructor(base?: Settings) {\n const dictionary = Object.create(\n base instanceof Settings && DICTIONARY in base ? base[DICTIONARY] : null\n );\n Object.seal(\n Object.defineProperty(this, DICTIONARY, {\n value: dictionary,\n })\n );\n }\n\n set(key: string, value: unknown): boolean {\n return set(this[DICTIONARY], key, value, null);\n }\n\n get(key: string): unknown {\n return get(this[DICTIONARY], key);\n }\n\n /**\n * Unset a specific key or a set of keys within a namespace when the key ends with a dot (ASCII #46).\n * If the key is \".\", all keys will be removed and this command works as a reset.\n * @param key - name The key to be unset or a namespace.\n * @returns boolean\n */\n unset(key: string): boolean {\n return unset(this[DICTIONARY], key + '');\n }\n\n forEach(callback: (key: string, value: unknown) => void): void {\n iterate(this[DICTIONARY], callback);\n }\n\n extend(): Settings {\n return new Settings(this);\n }\n\n /**\n * Recursively import all properties from the given plain JavaScript object.\n * This method has the opposite effect of the `dump` method.\n * @param root - The root object whose properties will\n * be imported.\n */\n import(root: Record<string, unknown>): void {\n if (isPlainObject(root)) {\n Object.keys(root).forEach((key) => {\n set(this[DICTIONARY], key, root[key], null);\n });\n }\n }\n\n /**\n * Build a JSON representation of the current internal state of this settings\n * object. The returned object can be safely passed to `JSON.stringify`\n * function.\n * @returns The JSON representation of the current\n * state of this settings instance\n */\n dump(): Record<string, unknown> {\n const context = {};\n iterate(this[DICTIONARY], (key, value) => {\n if (typeof value !== 'undefined') {\n deepSet(context, key, value);\n }\n });\n return context;\n }\n\n static assert(subject: Settings): Settings {\n return subject instanceof Settings\n ? subject\n : Settings.getRuntimeSettings();\n }\n\n static getDefaultSettings(subfield = null): Settings | any {\n let defaultSettings = Settings[DEFAULT_SETTINGS];\n if (!(defaultSettings instanceof Settings)) {\n defaultSettings = new Settings();\n Settings[DEFAULT_SETTINGS] = defaultSettings;\n }\n\n // Given subfield of 'segmentation' it will return all settings\n // that starts with segmentation.*\n if (subfield) {\n const settingObj = {};\n defaultSettings.forEach((name: string) => {\n if (name.startsWith(subfield)) {\n const setting = name.split(`${subfield}.`)[1];\n settingObj[setting] = defaultSettings.get(name);\n }\n });\n return settingObj;\n }\n\n return defaultSettings;\n }\n\n static getRuntimeSettings(): Settings {\n let runtimeSettings = Settings[RUNTIME_SETTINGS];\n if (!(runtimeSettings instanceof Settings)) {\n runtimeSettings = new Settings(Settings.getDefaultSettings());\n Settings[RUNTIME_SETTINGS] = runtimeSettings;\n }\n return runtimeSettings;\n }\n\n static getObjectSettings(subject: unknown, from?: unknown): Settings {\n let settings = null;\n if (subject instanceof Settings) {\n settings = subject;\n } else if (typeof subject === 'object' && subject !== null) {\n let objectSettingsMap = Settings[OBJECT_SETTINGS_MAP];\n if (!(objectSettingsMap instanceof WeakMap)) {\n objectSettingsMap = new WeakMap();\n Settings[OBJECT_SETTINGS_MAP] = objectSettingsMap;\n }\n settings = objectSettingsMap.get(subject);\n if (!(settings instanceof Settings)) {\n settings = new Settings(\n Settings.assert(Settings.getObjectSettings(from))\n );\n objectSettingsMap.set(subject, settings);\n }\n }\n return settings;\n }\n\n static extendRuntimeSettings(): Settings {\n return Settings.getRuntimeSettings().extend();\n }\n}\n\n/*\n * Local Helpers\n */\n\nfunction unset(dictionary: Record<string, unknown>, name: string): boolean {\n if (name.endsWith('.')) {\n let deleteCount = 0;\n const namespace = name;\n const base = namespace.slice(0, -1);\n const deleteAll = base.length === 0;\n for (const key in dictionary) {\n if (\n Object.prototype.hasOwnProperty.call(dictionary, key) &&\n (deleteAll || key.startsWith(namespace) || key === base)\n ) {\n delete dictionary[key];\n ++deleteCount;\n }\n }\n return deleteCount > 0;\n }\n return delete dictionary[name];\n}\n\nfunction iterate(\n dictionary: Record<string, unknown>,\n callback: (key: string, value: unknown) => void\n): void {\n for (const key in dictionary) {\n callback(key, dictionary[key]);\n }\n}\n\nfunction setAll(\n dictionary: Record<string, unknown>,\n prefix: string,\n record: Record<string, unknown>,\n references: WeakSet<Record<string, unknown>>\n): boolean {\n let failCount: number;\n if (references.has(record)) {\n return set(dictionary, prefix, null, references);\n }\n references.add(record);\n failCount = 0;\n for (const field in record) {\n if (Object.prototype.hasOwnProperty.call(record, field)) {\n const key = field.length === 0 ? prefix : `${prefix}.${field}`;\n if (!set(dictionary, key, record[field], references)) {\n ++failCount;\n }\n }\n }\n references.delete(record);\n return failCount === 0;\n}\n\n/**\n * Set the key-value pair on a given dictionary. If the given value is a\n * plain javascript object, every property of that object will also be set.\n * @param dictionary {Record<string, unknown>} The target dictionary\n * @param key {string} The given key\n * @param value {unknown} The given value\n * @param references {WeakSet<Record<string, unknown>>} references is a WeakSet\n * instance used to keep track of which objects have already been iterated\n * through preventing thus possible stack overflows caused by cyclic references\n * @returns {boolean} Returns true if every given key-value pair has been\n * successfully set\n */\nfunction set(\n dictionary: Record<string, unknown>,\n key: string,\n value: unknown,\n references: WeakSet<Record<string, unknown>>\n): boolean {\n if (isValidKey(key)) {\n if (isPlainObject(value)) {\n return setAll(\n dictionary,\n key,\n value as Record<string, unknown>,\n references instanceof WeakSet ? references : new WeakSet()\n );\n }\n dictionary[key] = value;\n return true;\n }\n return false;\n}\n\nfunction get(dictionary: Record<string, unknown>, key: string): unknown {\n return dictionary[key];\n}\n\n/**\n * Make sure the -provided key correctly formatted.\n * e.g.:\n * \"my.cool.property\" (valid)\n * \"my.cool.property.\" (invalid)\n * \".my.cool.property\" (invalid)\n * \"my.cool..property\" (invalid)\n * @param key {string} The property name to be used as key within the internal\n * dictionary\n * @returns {boolean} True on success, false otherwise\n */\nfunction isValidKey(key: string): boolean {\n let last: number, current: number, previous: number;\n if (typeof key !== 'string' || (last = key.length - 1) < 0) return false;\n previous = -1;\n while ((current = key.indexOf('.', previous + 1)) >= 0) {\n if (current - previous < 2 || current === last) return false;\n previous = current;\n }\n return true;\n}\n\nfunction isPlainObject(subject: unknown) {\n if (typeof subject === 'object' && subject !== null) {\n const prototype = Object.getPrototypeOf(subject);\n if (prototype === Object.prototype || prototype === null) {\n return true;\n }\n }\n return false;\n}\n\nfunction deepSet(context, key, value) {\n const separator = key.indexOf('.');\n if (separator >= 0) {\n const subKey = key.slice(0, separator);\n let subContext = context[subKey];\n if (typeof subContext !== 'object' || subContext === null) {\n const subContextValue = subContext;\n subContext = {};\n if (typeof subContextValue !== 'undefined') {\n subContext[''] = subContextValue;\n }\n context[subKey] = subContext;\n }\n deepSet(subContext, key.slice(separator + 1, key.length), value);\n } else {\n context[key] = value;\n }\n}\n\n/**\n * Initial Settings for the repository\n */\nSettings.getDefaultSettings().set('useCursors', true);\n","/**\n * A utility that can be used to scale (in place) an RgbTransferFunction. We\n * often use this to scale the transfer function based on a PET calculation.\n *\n * @example\n * Grabbing a reference to the RGB Transfer function from the viewport:\n * ```\n * const rgbTransferFunction = viewport\n * .getActor()\n * .getProperty()\n * .getRGBTransferFunction(0);\n *\n * scaleRgbTransferFunction(rgbTransferFunction, 2);\n * ```\n *\n * @see {@link https://kitware.github.io/vtk-js/api/Rendering_Core_ColorTransferFunction.html|VTK.js: ColorTransferFunction}\n * @param rgbTransferFunction\n * @param scalingFactor\n */\nexport default function scaleRGBTransferFunction(\n rgbTransferFunction: any,\n scalingFactor: number\n): void {\n const size = rgbTransferFunction.getSize();\n\n for (let index = 0; index < size; index++) {\n const nodeValue1 = [];\n\n rgbTransferFunction.getNodeValue(index, nodeValue1);\n\n nodeValue1[1] = nodeValue1[1] * scalingFactor;\n nodeValue1[2] = nodeValue1[2] * scalingFactor;\n nodeValue1[3] = nodeValue1[3] * scalingFactor;\n\n rgbTransferFunction.setNodeValue(index, nodeValue1);\n }\n}\n","const LAST_RUNTIME_ID = Symbol('LastRuntimeId');\nconst GLOBAL_CONTEXT = {};\nconst DEFAULT_MAX = 0xffffffff; // Max 32-bit integer\nconst DEFAULT_SEPARATOR = '-';\n\n/**\n * Generate a unique numeric ID string valid during a single runtime session;\n *\n * @param context - An optional object to be used as context.\n * Defaults to a global context;\n * @param separator - The component separator. Defaults to \"-\";\n * @param max - The maximum component value. Defaults to 4294967295;\n * @returns The string representation of the the unique ID;\n */\nexport default function getRuntimeId(\n context?: unknown,\n separator?: string,\n max?: number\n): string {\n return getNextRuntimeId(\n // @ts-ignore\n context !== null && typeof context === 'object' ? context : GLOBAL_CONTEXT,\n LAST_RUNTIME_ID,\n (typeof max === 'number' && max > 0 ? max : DEFAULT_MAX) >>> 0\n ).join(typeof separator === 'string' ? separator : DEFAULT_SEPARATOR);\n}\n\n/*\n * Helpers\n */\n\nfunction getNextRuntimeId(\n context: Record<symbol, Array<number>>,\n symbol: symbol,\n max: number\n): Array<number> {\n let idComponents = context[symbol];\n if (!(idComponents instanceof Array)) {\n idComponents = [0];\n Object.defineProperty(context, symbol, { value: idComponents });\n }\n for (let carry = true, i = 0; carry && i < idComponents.length; ++i) {\n let n = idComponents[i] | 0;\n if (n < max) {\n carry = false;\n n = n + 1;\n } else {\n n = 0;\n if (i + 1 === idComponents.length) idComponents.push(0);\n }\n idComponents[i] = n;\n }\n return idComponents;\n}\n","import imageIdToURI from './imageIdToURI';\n\nconst state = {}; // Calibrated pixel spacing per imageId\n\n/**\n * Simple metadataProvider object to store metadata for calibrated spacings.\n * This can be added via cornerstone.metaData.addProvider(...) in order to store\n * and return calibrated pixel spacings when metaData type is \"calibratedPixelSpacing\".\n */\nconst metadataProvider = {\n /**\n * Adds metadata for an imageId.\n * @param imageId - the imageId for the metadata to store\n * @param payload - the payload composed of new calibrated pixel spacings\n */\n add: (imageId: string, payload: [number, number]): void => {\n const imageURI = imageIdToURI(imageId);\n if (!state[imageURI]) {\n state[imageURI] = {};\n }\n state[imageURI] = payload;\n },\n\n /**\n * Returns the metadata for an imageId if it exists.\n * @param type - the type of metadata to enquire about\n * @param imageId - the imageId to enquire about\n * @returns the calibrated pixel spacings for the imageId if it exists, otherwise undefined\n */\n get: (type: string, imageId: string): [number, number] => {\n if (type === 'calibratedPixelSpacing') {\n const imageURI = imageIdToURI(imageId);\n return state[imageURI];\n }\n },\n};\n\nexport default metadataProvider;\n","import type Point3 from '../types/Point3';\n\n/**\n * returns equal if the two vec3s are opposite within the\n * given tolerance in each dimension.\n *\n * @param v1 - The first 3 vector\n * @param v2 - The second 3 vector.\n * @param tolerance - The acceptable tolerance.\n *\n * @returns True if the two values are within the tolerance levels.\n */\nexport default function isOpposite(\n v1: Point3,\n v2: Point3,\n tolerance = 1e-5\n): boolean {\n return (\n Math.abs(v1[0] + v2[0]) < tolerance &&\n Math.abs(v1[1] + v2[1]) < tolerance &&\n Math.abs(v1[2] + v2[2]) < tolerance\n );\n}\n","import global from '../global';\n/**\n * A helper function that creates a new Float32Array that utilized a shared\n * array buffer. This allows the array to be updated simultaneously in\n * workers or the main thread. Depending on the system (the CPU, the OS, the Browser)\n * it can take a while until the change is propagated to all contexts.\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer|MDN: SharedArrayBuffer}\n * @remarks\n * We use SharedArrayBuffers in our ImageCache class. It's what allows us to\n * stream data to build a volume. It's important to note that SharedArrayBuffer\n * does not work out of the box for all web browsers. In some, it is disabled\n * behind a flag; in others, it has been removed entirely.\n *\n * @example\n * Creating an array for a Volume with known dimensions:\n * ```\n * const dimensions = [512, 512, 25];\n * const scalarData = createUint8SharedArray(dimensions[0] * dimensions[1] * dimensions[2]);\n * ```\n *\n * @param length - frame size * number of frames\n * @returns a Uint8Array with an underlying SharedArrayBuffer\n * @public\n */\nfunction createUint8SharedArray(length: number): Uint8Array {\n if (!window.crossOriginIsolated) {\n throw new Error(\n 'Your page is NOT cross-origin isolated, see https://developer.mozilla.org/en-US/docs/Web/API/crossOriginIsolated'\n );\n }\n if (window.SharedArrayBuffer === undefined) {\n throw new Error(\n 'SharedArrayBuffer is NOT supported in your browser see https://developer.chrome.com/blog/enabling-shared-array-buffer/'\n );\n }\n\n const sharedArrayBuffer = new SharedArrayBuffer(length);\n\n return new Uint8Array(sharedArrayBuffer);\n}\n\nexport default createUint8SharedArray;\n","import global from '../global';\n\n/**\n * A helper function that creates a new Float32Array that utilized a shared\n * array buffer. This allows the array to be updated simultaneously in\n * workers or the main thread. Depending on the system (the CPU, the OS, the Browser)\n * it can take a while until the change is propagated to all contexts.\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer|MDN: SharedArrayBuffer}\n * @remarks\n * We use SharedArrayBuffers in our ImageCache class. It's what allows us to\n * stream data to build a volume. It's important to note that SharedArrayBuffer\n * does not work out of the box for all web browsers. In some, it is disabled\n * behind a flag; in others, it has been removed entirely.\n *\n * @example\n * Creating an array for a Volume with known dimensions:\n * ```\n * const dimensions = [512, 512, 25];\n * const scalarData = createFloat32SharedArray(dimensions[0] * dimensions[1] * dimensions[2]);\n * ```\n *\n * @param length - frame size * number of frames\n * @returns a Float32Array with an underlying SharedArrayBuffer\n * @public\n */\nfunction createFloat32SharedArray(length: number): Float32Array {\n if (!window.crossOriginIsolated) {\n throw new Error(\n 'Your page is NOT cross-origin isolated, see https://developer.mozilla.org/en-US/docs/Web/API/crossOriginIsolated'\n );\n }\n if (window.SharedArrayBuffer === undefined) {\n throw new Error(\n 'SharedArrayBuffer is NOT supported in your browser see https://developer.chrome.com/blog/enabling-shared-array-buffer/'\n );\n }\n\n const sharedArrayBuffer = new SharedArrayBuffer(length * 4);\n\n return new Float32Array(sharedArrayBuffer);\n}\n\nexport default createFloat32SharedArray;\n","import { vec3 } from 'gl-matrix';\nimport * as metaData from '../metaData';\nimport type { IImageVolume, Point3 } from '../types';\n\nimport getSpacingInNormalDirection from './getSpacingInNormalDirection';\n\n/**\n * Given an image, a point in space and the viewPlaneNormal it returns the\n * closest imageId of the image volume that is within half voxel spacing\n * of the point in space.\n * @param imageVolume - The image volume\n * @param worldPos - The position in the world coordinate system (from mouse click)\n * @param viewPlaneNormal - The normal vector of the viewport\n * @param viewUp - The viewUp vector of the camera.\n *\n * @returns The imageId for the tool.\n */\nexport default function getClosestImageId(\n imageVolume: IImageVolume,\n worldPos: Point3,\n viewPlaneNormal: Point3,\n viewUp: Point3\n): string {\n if (!imageVolume) {\n return;\n }\n\n const { direction, imageIds } = imageVolume;\n\n if (!imageIds || !imageIds.length) {\n return;\n }\n\n // 1. Get ScanAxis vector\n const kVector = direction.slice(6, 9);\n\n // 2. Check if scanAxis is not parallel to camera viewPlaneNormal\n const dotProducts = vec3.dot(kVector as Point3, <vec3>viewPlaneNormal);\n\n // 2.a if imagePlane is not parallel to the camera: tool is not drawn on an\n // imaging plane, return\n if (Math.abs(dotProducts) < 0.99) {\n return;\n }\n\n // 3. Calculate Spacing the in the normal direction, this will get used to\n // check whether we are withing a slice\n const spacingInNormalDirection = getSpacingInNormalDirection(\n imageVolume,\n viewPlaneNormal\n );\n\n const halfSpacingInNormalDirection = spacingInNormalDirection / 2;\n\n // 4. Iterate over all imageIds and check if the tool point (worldPos) is\n // withing one of the slices defined by an imageId\n let imageIdForTool;\n for (let i = 0; i < imageIds.length; i++) {\n const imageId = imageIds[i];\n\n // 4.a Get metadata for the imageId\n const { imagePositionPatient } = metaData.get('imagePlaneModule', imageId);\n\n // 4.b Calculate the direction vector from annotation. point to the first voxel\n // of this image defined by imageId\n const dir = vec3.create();\n vec3.sub(dir, worldPos, imagePositionPatient);\n\n // 4.c Calculate the distance between the vector above and the viewplaneNormal\n // i.e., projected distance\n const dot = vec3.dot(dir, viewPlaneNormal);\n\n // 4.d If the distance is withing range, return the imageId\n if (Math.abs(dot) < halfSpacingInNormalDirection) {\n imageIdForTool = imageId;\n }\n }\n\n return imageIdForTool;\n}\n","import { Point3 } from '../types';\n\n/**\n * Returns true if the specified index is within the given dimensions.\n *\n * @param index - The index to check.\n * @param dimensions - The dimensions to check against.\n *\n * @returns True if the index is in-bounds.\n */\nexport default function indexWithinDimensions(\n index: Point3,\n dimensions: Point3\n): boolean {\n if (\n index[0] < 0 ||\n index[0] >= dimensions[0] ||\n index[1] < 0 ||\n index[1] >= dimensions[1] ||\n index[2] < 0 ||\n index[2] >= dimensions[2]\n ) {\n return false;\n }\n\n return true;\n}\n","import { IVolumeViewport } from '../types';\nimport {\n getRenderingEngines,\n getRenderingEngine,\n} from '../RenderingEngine/getRenderingEngine';\n\n/**\n * Returns the viewports containing the same volume actors (all actors) the same\n * as the target viewport. If renderingEngineId is provided, it will only return\n * viewports that are associated with the renderingEngineId; otherwise, it will\n * return search in all rendering engines.\n *\n * This method is useful for finding viewports that are associated with the same\n * volume (e.g., for tools that share state between viewports).\n *\n * @param viewport - target viewport\n * @returns array of viewports that have the same volume actor as the target viewport\n */\nfunction getVolumeViewportsContainingSameVolumes(\n targetViewport: IVolumeViewport,\n renderingEngineId?: string\n): Array<IVolumeViewport> {\n // If rendering engine is not provided, use all rendering engines\n let renderingEngines;\n if (renderingEngineId) {\n renderingEngines = [getRenderingEngine(renderingEngineId)];\n } else {\n renderingEngines = getRenderingEngines();\n }\n\n const sameVolumesViewports = [];\n\n renderingEngines.forEach((renderingEngine) => {\n const targetActors = targetViewport.getActors();\n const viewports = renderingEngine.getVolumeViewports();\n\n for (const vp of viewports) {\n const vpActors = vp.getActors();\n\n if (vpActors.length !== targetActors.length) {\n continue;\n }\n\n // every targetActors should be in the vpActors\n const sameVolumes = targetActors.every(({ uid }) =>\n vpActors.find((vpActor) => uid === vpActor.uid)\n );\n\n if (sameVolumes) {\n sameVolumesViewports.push(vp);\n }\n }\n });\n\n return sameVolumesViewports;\n}\n\nexport default getVolumeViewportsContainingSameVolumes;\n","import { IVolumeViewport } from '../types';\nimport {\n getRenderingEngines,\n getRenderingEngine,\n} from '../RenderingEngine/getRenderingEngine';\n\n/**\n * Similar to {@link getVolumeViewportsContainingSameVolumes}, but uses the volumeId\n * to filter viewports that contain the same volume.\n *\n * @returns VolumeViewport viewports array\n */\nfunction getViewportsWithVolumeId(\n volumeId: string,\n renderingEngineId?: string\n): Array<IVolumeViewport> {\n // If rendering engine is not provided, use all rendering engines\n let renderingEngines;\n if (renderingEngineId) {\n renderingEngines = [getRenderingEngine(renderingEngineId)];\n } else {\n renderingEngines = getRenderingEngines();\n }\n\n const targetViewports = [];\n\n renderingEngines.forEach((renderingEngine) => {\n const viewports = renderingEngine.getVolumeViewports();\n const filteredViewports = viewports.filter((vp) =>\n vp.hasVolumeId(volumeId)\n );\n targetViewports.push(...filteredViewports);\n });\n\n return targetViewports;\n}\n\nexport default getViewportsWithVolumeId;\n","import { IImage, CPUFallbackEnabledElement } from '../types';\n\nimport getDefaultViewport from '../RenderingEngine/helpers/cpuFallback/rendering/getDefaultViewport';\nimport calculateTransform from '../RenderingEngine/helpers/cpuFallback/rendering/calculateTransform';\nimport drawImageSync from '../RenderingEngine/helpers/cpuFallback/drawImageSync';\n\n/**\n * Renders a cornerstone image object to a canvas.\n * Note: this does not load the image but only takes care of the rendering pipeline\n *\n * @param image - Cornerstone image object\n * @param canvas - Canvas element to render to\n */\nexport default function renderToCanvas(\n canvas: HTMLCanvasElement,\n image: IImage,\n modality?: string\n): void {\n const viewport = getDefaultViewport(canvas, image, modality);\n\n const enabledElement: CPUFallbackEnabledElement = {\n canvas,\n viewport,\n image,\n renderingTools: {},\n };\n\n enabledElement.transform = calculateTransform(enabledElement);\n\n const invalidated = true;\n drawImageSync(enabledElement, invalidated);\n}\n","import { IImage } from '../types';\n\nimport { loadAndCacheImage } from '../imageLoader';\nimport * as metaData from '../metaData';\nimport { RequestType } from '../enums';\nimport imageLoadPoolManager from '../requestPool/imageLoadPoolManager';\nimport renderToCanvas from './renderToCanvas';\n\n/**\n * Loads and renders an imageId to a Canvas. It will use the CPU rendering pipeline\n * for image.\n *\n * @example\n * ```\n * const canvas = document.getElementById('myCanvas')\n * const imageId = 'myImageId'\n *\n * loadImageToCanvas(canvas, imageId)\n * ```\n * @param imageId - The imageId to render\n * @param canvas - Canvas element to render to\n * @param requestType - The type of request (default to interaction), can be 'interaction' or 'prefetch' or 'thumbnail'\n * the order of loading for the pool manager is interaction, thumbnail, prefetch\n * @param priority - The priority of the request within the request type (lower is higher priority)\n * @returns - A promise that resolves when the image has been rendered with the imageId\n */\nexport default function loadImageToCanvas(\n canvas: HTMLCanvasElement,\n imageId: string,\n requestType = RequestType.Thumbnail,\n priority = -5\n): Promise<string> {\n return new Promise((resolve, reject) => {\n function successCallback(image: IImage, imageId: string) {\n const { modality } = metaData.get('generalSeriesModule', imageId) || {};\n\n image.isPreScaled = image.isPreScaled || image.preScale?.scaled;\n renderToCanvas(canvas, image, modality);\n resolve(imageId);\n }\n\n function errorCallback(error: Error, imageId: string) {\n console.error(error, imageId);\n reject(error);\n }\n\n function sendRequest(imageId, imageIdIndex, options) {\n return loadAndCacheImage(imageId, options).then(\n (image) => {\n successCallback.call(this, image, imageId);\n },\n (error) => {\n errorCallback.call(this, error, imageId);\n }\n );\n }\n\n // IMPORTANT: Request type should be passed if not the 'interaction'\n // highest priority will be used for the request type in the imageRetrievalPool\n const options = {\n targetBuffer: {\n type: 'Float32Array',\n offset: null,\n length: null,\n },\n preScale: {\n enabled: true,\n },\n requestType,\n };\n\n imageLoadPoolManager.addRequest(\n sendRequest.bind(null, imageId, null, options),\n requestType,\n { imageId },\n priority\n );\n });\n}\n","import { vec3 } from 'gl-matrix';\nimport { metaData } from '..';\nimport { Point2, Point3 } from '../types';\n\n/**\n * Given the imageId, and 3d coordinates on the world space, it returns the continuos\n * image coordinates (IJ) on the image space. The image space is\n * defined with [0,0] being on the top left corner of the top left pixel,\n * the [1,1] being on the bottom right corner of the top left pixel.\n * @param imageId - The image id\n * @param worldCoords - The 3d coordinates on the world.\n * @returns The 2d coordinates on the image.\n *\n */\nfunction worldToImageCoords(\n imageId: string,\n worldCoords: Point3\n): Point2 | undefined {\n const imagePlaneModule = metaData.get('imagePlaneModule', imageId);\n\n if (!imagePlaneModule) {\n throw new Error(`No imagePlaneModule found for imageId: ${imageId}`);\n }\n\n // For the image coordinates we need to calculate the transformation matrix\n // from the world coordinates to the image coordinates.\n\n const {\n columnCosines,\n columnPixelSpacing,\n rowCosines,\n rowPixelSpacing,\n imagePositionPatient: origin,\n rows,\n columns,\n } = imagePlaneModule;\n\n // The origin is the image position patient, but since image coordinates start\n // from [0,0] for the top left hand of the first pixel, and the origin is at the\n // center of the first pixel, we need to account for this.\n const newOrigin = vec3.create();\n\n vec3.scaleAndAdd(newOrigin, origin, columnCosines, -columnPixelSpacing / 2);\n vec3.scaleAndAdd(newOrigin, newOrigin, rowCosines, -rowPixelSpacing / 2);\n\n // Get the subtraction vector from the origin to the world coordinates\n const sub = vec3.create();\n vec3.sub(sub, worldCoords, newOrigin);\n\n // Projected distance of the sub vector onto the rowCosines\n const rowDistance = vec3.dot(sub, rowCosines);\n\n // Projected distance of the sub vector onto the columnCosines\n const columnDistance = vec3.dot(sub, columnCosines);\n\n const imageCoords = [\n rowDistance / rowPixelSpacing,\n columnDistance / columnPixelSpacing,\n ];\n\n return imageCoords as Point2;\n}\n\nexport default worldToImageCoords;\n","import { vec3 } from 'gl-matrix';\nimport { metaData } from '..';\nimport { Point2, Point3 } from '../types';\n\n/**\n * Given the imageId and a 2d coordinates on the image space with [0,0] being the top left corner\n * of the top left pixel, and options which includes the imageId, it returns the\n * 3d coordinates on the world space.\n * @param imageId - The image id\n * @param imageCoords - The 2d coordinates on the image\n * @returns The 3d coordinates on the world.\n *\n */\nexport default function imageToWorldCoords(\n imageId: string,\n imageCoords: Point2\n): Point3 | undefined {\n const imagePlaneModule = metaData.get('imagePlaneModule', imageId);\n\n if (!imagePlaneModule) {\n throw new Error(`No imagePlaneModule found for imageId: ${imageId}`);\n }\n\n const {\n columnCosines,\n columnPixelSpacing,\n rowCosines,\n rowPixelSpacing,\n imagePositionPatient: origin,\n } = imagePlaneModule;\n\n // calculate the image coordinates in the world space\n const imageCoordsInWorld = vec3.create();\n\n // move from origin in the direction of the row cosines with the amount of\n // row pixel spacing times the first element of the image coordinates vector\n vec3.scaleAndAdd(\n imageCoordsInWorld,\n origin,\n rowCosines,\n // to accommodate the [0,0] being on the top left corner of the top left pixel\n // but the origin is at the center of the top left pixel\n rowPixelSpacing * (imageCoords[0] - 0.5)\n );\n\n vec3.scaleAndAdd(\n imageCoordsInWorld,\n imageCoordsInWorld,\n columnCosines,\n columnPixelSpacing * (imageCoords[1] - 0.5)\n );\n\n return Array.from(imageCoordsInWorld) as Point3;\n}\n","import { vec3 } from 'gl-matrix';\nimport { ActorSliceRange, Point3 } from '../types';\n\n/**\n * Given a number of frames, `deltaFrames`,\n * move the `focalPoint` and camera `position` so that it moves forward/backwards\n * `deltaFrames` in the camera's normal direction, and snaps to the nearest frame.\n *\n * @param focalPoint - The focal point to move.\n * @param position - The camera position to move.\n * @param sliceRange - The scroll range used to find the current\n * position in the stack, as well as prevent scrolling past the extent of the volume.\n * @param viewPlaneNormal - The normal direction of the camera.\n * @param spacingInNormalDirection - The spacing of frames the normal direction of the camera.\n * @param deltaFrames - The number of frames to jump.\n *\n * @returns The `newFocalPoint` and `newPosition` of the camera.\n */\nexport default function snapFocalPointToSlice(\n focalPoint: Point3,\n position: Point3,\n sliceRange: ActorSliceRange,\n viewPlaneNormal: Point3,\n spacingInNormalDirection: number,\n deltaFrames: number\n): { newFocalPoint: Point3; newPosition: Point3 } {\n const { min, max, current } = sliceRange;\n\n // Get the current offset off the camera position so we can add it on at the end.\n const posDiffFromFocalPoint = vec3.create();\n\n vec3.sub(posDiffFromFocalPoint, <vec3>position, <vec3>focalPoint);\n\n // Now we can see how many steps there are in this direction\n const steps = Math.round((max - min) / spacingInNormalDirection);\n\n // Find out current frameIndex\n const fraction = (current - min) / (max - min);\n const floatingStepNumber = fraction * steps;\n let frameIndex = Math.round(floatingStepNumber);\n\n // Dolly the focal point back to min slice focal point.\n let newFocalPoint = <Point3>[\n focalPoint[0] -\n viewPlaneNormal[0] * floatingStepNumber * spacingInNormalDirection,\n focalPoint[1] -\n viewPlaneNormal[1] * floatingStepNumber * spacingInNormalDirection,\n focalPoint[2] -\n viewPlaneNormal[2] * floatingStepNumber * spacingInNormalDirection,\n ];\n\n // Increment the slice number by deltaFrames.\n frameIndex += deltaFrames;\n\n // Clamp sliceNumber to volume.\n if (frameIndex > steps) {\n frameIndex = steps;\n } else if (frameIndex < 0) {\n frameIndex = 0;\n }\n\n // Dolly the focal towards to the correct frame focal point.\n const newSlicePosFromMin = frameIndex * spacingInNormalDirection;\n\n newFocalPoint = <Point3>[\n newFocalPoint[0] + viewPlaneNormal[0] * newSlicePosFromMin,\n newFocalPoint[1] + viewPlaneNormal[1] * newSlicePosFromMin,\n newFocalPoint[2] + viewPlaneNormal[2] * newSlicePosFromMin,\n ];\n\n const newPosition = <Point3>[\n newFocalPoint[0] + posDiffFromFocalPoint[0],\n newFocalPoint[1] + posDiffFromFocalPoint[1],\n newFocalPoint[2] + posDiffFromFocalPoint[2],\n ];\n\n return { newFocalPoint, newPosition };\n}\n","import { getRenderingEngine } from '../RenderingEngine';\nimport { getRenderingEngines } from '../RenderingEngine/getRenderingEngine';\nimport { IStackViewport, IVolumeViewport } from '../types';\n\ntype Viewport = IStackViewport | IVolumeViewport;\n\n/**\n * Get the viewport that is rendering the image with the given imageURI (imageId without\n * the loader schema), this can be a stackViewport or a volumeViewport.\n *\n * @param renderingEngine - The rendering engine that is rendering the viewports\n * @param imageURI - The imageURI of the image that is requested\n * @returns A Viewport\n */\nexport default function getViewportsWithImageURI(\n imageURI: string,\n renderingEngineId?: string\n): Array<Viewport> {\n // If rendering engine is not provided, use all rendering engines\n let renderingEngines;\n if (renderingEngineId) {\n renderingEngines = [getRenderingEngine(renderingEngineId)];\n } else {\n renderingEngines = getRenderingEngines();\n }\n\n const viewports = [];\n renderingEngines.forEach((renderingEngine) => {\n const stackViewports = renderingEngine.getStackViewports();\n\n const filteredStackViewports = stackViewports.filter((viewport) =>\n viewport.hasImageURI(imageURI)\n );\n\n // If no stack viewport found but a volumeViewport is rendering the same data\n const volumeViewports = renderingEngine.getVolumeViewports();\n\n const filteredVolumeViewports = volumeViewports.filter((viewport) =>\n viewport.hasImageURI(imageURI)\n );\n\n viewports.push(...filteredStackViewports, ...filteredVolumeViewports);\n });\n\n return viewports;\n}\n","import { vec3 } from 'gl-matrix';\nimport { planar } from '.';\nimport { metaData } from '..';\nimport { IStackViewport, Point3 } from '../types';\n\n/**\n * Given a point in 3D space and a viewport it returns the index of the closest imageId, it assumes that stack images are sorted according to their sliceLocation\n * @param point - [A, B, C] coordinates of the point in 3D space\n * @param viewport - The StackViewport to search for the closest imageId\n *\n * @returns The imageId index of the closest imageId or null if no imageId is found\n */\nexport default function getClosestStackImageIndexForPoint(\n point: Point3,\n viewport: IStackViewport\n): number | null {\n const minimalDistance = calculateMinimalDistanceForStackViewport(\n point,\n viewport\n );\n return minimalDistance ? minimalDistance.index : null;\n}\n\n//assumes that imageIds are sorted by slice location\nexport function calculateMinimalDistanceForStackViewport(\n point: Point3,\n viewport: IStackViewport\n): { distance: number; index: number } | null {\n const imageIds = viewport.getImageIds();\n const currentImageIdIndex = viewport.getCurrentImageIdIndex();\n\n if (imageIds.length === 0) return null;\n\n const getDistance = (imageId: string): null | number => {\n const planeMetadata = getPlaneMetadata(imageId);\n if (!planeMetadata) return null;\n const plane = planar.planeEquation(\n planeMetadata.planeNormal,\n planeMetadata.imagePositionPatient\n );\n const distance = planar.planeDistanceToPoint(plane, point);\n return distance;\n };\n\n const closestStack = {\n distance: getDistance(imageIds[currentImageIdIndex]) ?? Infinity,\n index: currentImageIdIndex,\n };\n\n //check higher indices\n const higherImageIds = imageIds.slice(currentImageIdIndex + 1);\n\n for (let i = 0; i < higherImageIds.length; i++) {\n const id = higherImageIds[i];\n const distance = getDistance(id);\n if (distance === null) continue;\n if (distance <= closestStack.distance) {\n closestStack.distance = distance;\n closestStack.index = i + currentImageIdIndex + 1;\n } else break;\n }\n //check lower indices\n const lowerImageIds = imageIds.slice(0, currentImageIdIndex);\n for (let i = lowerImageIds.length - 1; i >= 0; i--) {\n const id = lowerImageIds[i];\n const distance = getDistance(id);\n if (distance === null || distance === closestStack.distance) continue;\n if (distance < closestStack.distance) {\n closestStack.distance = distance;\n closestStack.index = i;\n } else break;\n }\n return closestStack.distance === Infinity ? null : closestStack;\n}\n\nfunction getPlaneMetadata(imageId: string): null | {\n rowCosines: Point3;\n columnCosines: Point3;\n imagePositionPatient: Point3;\n planeNormal: Point3;\n} {\n const targetImagePlane = metaData.get('imagePlaneModule', imageId);\n\n if (\n !targetImagePlane ||\n !(\n targetImagePlane.rowCosines instanceof Array &&\n targetImagePlane.rowCosines.length === 3\n ) ||\n !(\n targetImagePlane.columnCosines instanceof Array &&\n targetImagePlane.columnCosines.length === 3\n ) ||\n !(\n targetImagePlane.imagePositionPatient instanceof Array &&\n targetImagePlane.imagePositionPatient.length === 3\n )\n ) {\n return null;\n }\n const {\n rowCosines,\n columnCosines,\n imagePositionPatient,\n }: {\n rowCosines: Point3;\n columnCosines: Point3;\n imagePositionPatient: Point3;\n } = targetImagePlane;\n\n const rowVec = vec3.set(vec3.create(), ...rowCosines);\n const colVec = vec3.set(vec3.create(), ...columnCosines);\n const planeNormal = vec3.cross(vec3.create(), rowVec, colVec) as Point3;\n\n return { rowCosines, columnCosines, imagePositionPatient, planeNormal };\n}\n","import { mat4 } from 'gl-matrix';\nimport { addProvider } from '../metaData';\n\nconst state = {};\n\n/**\n * Simple metadataProvider object to store metadata for spatial registration module.\n */\nconst spatialRegistrationMetadataProvider = {\n /* Adding a new entry to the state object. */\n add: (query: string[], payload: mat4): void => {\n const [viewportId1, viewportId2] = query;\n const entryId = `${viewportId1}_${viewportId2}`;\n\n if (!state[entryId]) {\n state[entryId] = {};\n }\n\n state[entryId] = payload;\n },\n\n get: (type: string, query: string[]): mat4 => {\n if (type !== 'spatialRegistrationModule') {\n return;\n }\n\n const [viewportId1, viewportId2] = query;\n\n // check both ways\n const entryId = `${viewportId1}_${viewportId2}`;\n\n if (state[entryId]) {\n return state[entryId];\n }\n\n const entryIdReverse = `${viewportId2}_${viewportId1}`;\n\n if (state[entryIdReverse]) {\n return mat4.invert(mat4.create(), state[entryIdReverse]);\n }\n },\n};\n\naddProvider(\n spatialRegistrationMetadataProvider.get.bind(\n spatialRegistrationMetadataProvider\n )\n);\n\nexport default spatialRegistrationMetadataProvider;\n","import { vec3, mat4 } from 'gl-matrix';\nimport { IStackViewport } from '../types';\nimport { StackViewport } from '../RenderingEngine';\nimport spatialRegistrationMetadataProvider from './spatialRegistrationMetadataProvider';\nimport { metaData } from '..';\nimport isEqual from './isEqual';\n\n/**\n * It calculates the registration matrix between two viewports (currently only\n * translation is supported)\n * If the viewports are in the same frame of reference, it will return early,\n * but otherwise it will use the current image's metadata to calculate the\n * translation between the two viewports and adds it to the spatialRegistrationModule\n * metadata provider\n *\n *\n * @param viewport1 - The first stack viewport\n * @param viewport2 - The second stack viewport\n */\nfunction calculateViewportsSpatialRegistration(\n viewport1: IStackViewport,\n viewport2: IStackViewport\n): void {\n if (\n !(viewport1 instanceof StackViewport) ||\n !(viewport2 instanceof StackViewport)\n ) {\n throw new Error(\n 'calculateViewportsSpatialRegistration: Both viewports must be StackViewports, volume viewports are not supported yet'\n );\n }\n\n const isSameFrameOfReference =\n viewport1.getFrameOfReferenceUID() === viewport2.getFrameOfReferenceUID();\n\n if (isSameFrameOfReference) {\n return;\n }\n\n const imageId1 = viewport1.getCurrentImageId();\n const imageId2 = viewport2.getCurrentImageId();\n\n const imagePlaneModule1 = metaData.get('imagePlaneModule', imageId1);\n const imagePlaneModule2 = metaData.get('imagePlaneModule', imageId2);\n\n const isSameImagePlane =\n imagePlaneModule1 &&\n imagePlaneModule2 &&\n isEqual(\n imagePlaneModule1.imageOrientationPatient,\n imagePlaneModule2.imageOrientationPatient\n );\n\n if (!isSameImagePlane) {\n throw new Error(\n 'Viewport spatial registration only supported for same orientation (hence translation only) for now'\n );\n }\n\n const imagePositionPatient1 = imagePlaneModule1.imagePositionPatient;\n const imagePositionPatient2 = imagePlaneModule2.imagePositionPatient;\n\n const translation = vec3.subtract(\n vec3.create(),\n imagePositionPatient1,\n imagePositionPatient2\n );\n\n const mat = mat4.fromTranslation(mat4.create(), translation);\n\n spatialRegistrationMetadataProvider.add([viewport1.id, viewport2.id], mat);\n}\n\nexport default calculateViewportsSpatialRegistration;\n","import {\n IImageData,\n IStackViewport,\n IVolumeViewport,\n Point2,\n Point3,\n} from '../types';\n\n/**\n * Given a viewport, return the corners of the image in the viewport in world coordinates.\n * Note that this is different than the corners of the canvas in world coordinates since\n * an image can be zoomed out and the canvas can be larger than the image; hence, the\n * corners of the canvas in world coordinates will be outside the image.\n *\n * @param viewport - The viewport to get the corners of.\n * @returns The corners of the image in the viewport in world coordinates.\n */\nexport default function getViewportImageCornersInWorld(\n viewport: IStackViewport | IVolumeViewport\n): Point3[] {\n const { imageData, dimensions } = viewport.getImageData() as IImageData;\n const { canvas } = viewport;\n\n const topLeftCanvas: Point2 = [0, 0];\n const topRightCanvas: Point2 = [canvas.width, 0];\n const bottomRightCanvas: Point2 = [canvas.width, canvas.height];\n const bottomLeftCanvas: Point2 = [0, canvas.height];\n\n const topLeftWorld = viewport.canvasToWorld(topLeftCanvas);\n const topRightWorld = viewport.canvasToWorld(topRightCanvas);\n const bottomRightWorld = viewport.canvasToWorld(bottomRightCanvas);\n const bottomLeftWorld = viewport.canvasToWorld(bottomLeftCanvas);\n\n const topLeftImage = imageData.worldToIndex(topLeftWorld);\n const topRightImage = imageData.worldToIndex(topRightWorld);\n const bottomRightImage = imageData.worldToIndex(bottomRightWorld);\n const bottomLeftImage = imageData.worldToIndex(bottomLeftWorld);\n\n return _getStackViewportImageCorners({\n dimensions,\n imageData,\n topLeftImage,\n topRightImage,\n bottomRightImage,\n bottomLeftImage,\n topLeftWorld,\n topRightWorld,\n bottomRightWorld,\n bottomLeftWorld,\n });\n}\n\nfunction _getStackViewportImageCorners({\n dimensions,\n imageData,\n topLeftImage,\n topRightImage,\n bottomRightImage,\n bottomLeftImage,\n topLeftWorld,\n topRightWorld,\n bottomRightWorld,\n bottomLeftWorld,\n}) {\n const topLeftImageWorld = _isInBounds(topLeftImage, dimensions)\n ? topLeftWorld\n : (imageData.indexToWorld([0, 0, 0]) as Point3);\n\n const topRightImageWorld = _isInBounds(topRightImage, dimensions)\n ? topRightWorld\n : (imageData.indexToWorld([dimensions[0] - 1, 0, 0]) as Point3);\n\n const bottomRightImageWorld = _isInBounds(bottomRightImage, dimensions)\n ? bottomRightWorld\n : (imageData.indexToWorld([\n dimensions[0] - 1,\n dimensions[1] - 1,\n 0,\n ]) as Point3);\n\n const bottomLeftImageWorld = _isInBounds(bottomLeftImage, dimensions)\n ? bottomLeftWorld\n : (imageData.indexToWorld([0, dimensions[1] - 1, 0]) as Point3);\n\n return [\n topLeftImageWorld,\n topRightImageWorld,\n bottomLeftImageWorld,\n bottomRightImageWorld,\n ];\n}\n\nfunction _isInBounds(imageCoord, dimensions) {\n return (\n imageCoord[0] > 0 ||\n imageCoord[0] < dimensions[0] - 1 ||\n imageCoord[1] > 0 ||\n imageCoord[1] < dimensions[1] - 1 ||\n imageCoord[2] > 0 ||\n imageCoord[2] < dimensions[2] - 1\n );\n}\n","import vtkColorTransferFunction from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction';\nimport vtkPiecewiseFunction from '@kitware/vtk.js/Common/DataModel/PiecewiseFunction';\nimport { ViewportPreset } from '../types';\nimport { VolumeActor } from '../types/IActor';\n\n/**\n * Applies a preset to a volume actor.\n *\n * @param actor - The volume actor to apply the preset to.\n * @param preset - The preset to apply.\n */\nexport default function applyPreset(actor: VolumeActor, preset: ViewportPreset) {\n // Create color transfer function\n const colorTransferArray = preset.colorTransfer\n .split(' ')\n .splice(1)\n .map(parseFloat);\n\n const { shiftRange } = getShiftRange(colorTransferArray);\n const min = shiftRange[0];\n const width = shiftRange[1] - shiftRange[0];\n const cfun = vtkColorTransferFunction.newInstance();\n const normColorTransferValuePoints = [];\n for (let i = 0; i < colorTransferArray.length; i += 4) {\n let value = colorTransferArray[i];\n const r = colorTransferArray[i + 1];\n const g = colorTransferArray[i + 2];\n const b = colorTransferArray[i + 3];\n\n value = (value - min) / width;\n normColorTransferValuePoints.push([value, r, g, b]);\n }\n\n applyPointsToRGBFunction(normColorTransferValuePoints, shiftRange, cfun);\n\n actor.getProperty().setRGBTransferFunction(0, cfun);\n\n // Create scalar opacity function\n const scalarOpacityArray = preset.scalarOpacity\n .split(' ')\n .splice(1)\n .map(parseFloat);\n\n const ofun = vtkPiecewiseFunction.newInstance();\n const normPoints = [];\n for (let i = 0; i < scalarOpacityArray.length; i += 2) {\n let value = scalarOpacityArray[i];\n const opacity = scalarOpacityArray[i + 1];\n\n value = (value - min) / width;\n\n normPoints.push([value, opacity]);\n }\n\n applyPointsToPiecewiseFunction(normPoints, shiftRange, ofun);\n\n actor.getProperty().setScalarOpacity(0, ofun);\n\n const [\n gradientMinValue,\n gradientMinOpacity,\n gradientMaxValue,\n gradientMaxOpacity,\n ] = preset.gradientOpacity.split(' ').splice(1).map(parseFloat);\n\n actor.getProperty().setUseGradientOpacity(0, true);\n actor.getProperty().setGradientOpacityMinimumValue(0, gradientMinValue);\n actor.getProperty().setGradientOpacityMinimumOpacity(0, gradientMinOpacity);\n actor.getProperty().setGradientOpacityMaximumValue(0, gradientMaxValue);\n actor.getProperty().setGradientOpacityMaximumOpacity(0, gradientMaxOpacity);\n\n if (preset.interpolation === '1') {\n actor.getProperty().setInterpolationTypeToFastLinear();\n //actor.getProperty().setInterpolationTypeToLinear()\n }\n\n const ambient = parseFloat(preset.ambient);\n const diffuse = parseFloat(preset.diffuse);\n const specular = parseFloat(preset.specular);\n const specularPower = parseFloat(preset.specularPower);\n\n actor.getProperty().setAmbient(ambient);\n actor.getProperty().setDiffuse(diffuse);\n actor.getProperty().setSpecular(specular);\n actor.getProperty().setSpecularPower(specularPower);\n}\n\nfunction getShiftRange(colorTransferArray) {\n // Credit to paraview-glance\n // https://github.com/Kitware/paraview-glance/blob/3fec8eeff31e9c19ad5b6bff8e7159bd745e2ba9/src/components/controls/ColorBy/script.js#L133\n\n // shift range is original rgb/opacity range centered around 0\n let min = Infinity;\n let max = -Infinity;\n for (let i = 0; i < colorTransferArray.length; i += 4) {\n min = Math.min(min, colorTransferArray[i]);\n max = Math.max(max, colorTransferArray[i]);\n }\n\n const center = (max - min) / 2;\n\n return {\n shiftRange: [-center, center],\n min,\n max,\n };\n}\n\nfunction applyPointsToRGBFunction(points, range, cfun) {\n const width = range[1] - range[0];\n const rescaled = points.map(([x, r, g, b]) => [\n x * width + range[0],\n r,\n g,\n b,\n ]);\n\n cfun.removeAllPoints();\n rescaled.forEach(([x, r, g, b]) => cfun.addRGBPoint(x, r, g, b));\n\n return rescaled;\n}\n\nfunction applyPointsToPiecewiseFunction(points, range, pwf) {\n const width = range[1] - range[0];\n const rescaled = points.map(([x, y]) => [x * width + range[0], y]);\n\n pwf.removeAllPoints();\n rescaled.forEach(([x, y]) => pwf.addPoint(x, y));\n\n return rescaled;\n}\n","import BaseVolumeViewport from '../BaseVolumeViewport';\nimport type {\n IVolumeInput,\n IRenderingEngine,\n IVolumeViewport,\n} from '../../types';\n\n/**\n * Similar to {@link addVolumesToViewports} it adds volumes to viewports; however,\n * this method will Set the volumes on the viewports which means that the previous\n * volumes will be removed.\n *\n * @param renderingEngine - The rendering engine to use to get viewports from\n * @param volumeInputs - Array of volume inputs including volumeId. Other properties\n * such as visibility, callback, blendMode, slabThickness are optional\n * @param viewportIds - Array of viewport IDs to add the volume to\n * @param immediateRender - If true, the volumes will be rendered immediately\n * @returns A promise that resolves when all volumes have been added\n */\nasync function setVolumesForViewports(\n renderingEngine: IRenderingEngine,\n volumeInputs: Array<IVolumeInput>,\n viewportIds: Array<string>,\n immediateRender = false,\n suppressEvents = false\n): Promise<void> {\n // Check if all viewports are volumeViewports\n viewportIds.forEach((viewportId) => {\n const viewport = renderingEngine.getViewport(viewportId);\n\n if (!viewport) {\n throw new Error(`Viewport with Id ${viewportId} does not exist`);\n }\n\n // if not instance of BaseVolumeViewport, throw\n if (!(viewport instanceof BaseVolumeViewport)) {\n throw new Error('setVolumesForViewports only supports VolumeViewport and VolumeViewport3D');\n }\n });\n\n const setVolumePromises = viewportIds.map(async (viewportId) => {\n const viewport = renderingEngine.getViewport(viewportId) as IVolumeViewport;\n\n await viewport.setVolumes(volumeInputs, immediateRender, suppressEvents);\n });\n\n await Promise.all(setVolumePromises);\n\n return;\n}\n\nexport default setVolumesForViewports;\n","import { VolumeViewport } from '../';\nimport BaseVolumeViewport from '../BaseVolumeViewport';\nimport type { IVolumeInput, IRenderingEngine } from '../../types';\n\n/**\n * For each provided viewport it adds a volume to the viewport using the\n * provided renderingEngine\n *\n *\n * @param renderingEngine - The rendering engine to use to get viewports from\n * @param volumeInputs - Array of volume inputs including volumeId. Other properties\n * such as visibility, callback, blendMode, slabThickness are optional\n * @param viewportIds - Array of viewport IDs to add the volume to\n * @param immediateRender - If true, the volumes will be rendered immediately\n * @returns A promise that resolves when all volumes have been added\n */\nasync function addVolumesToViewports(\n renderingEngine: IRenderingEngine,\n volumeInputs: Array<IVolumeInput>,\n viewportIds: Array<string>,\n immediateRender = false,\n suppressEvents = false\n): Promise<void> {\n // Check if all viewports are volumeViewports\n for (const viewportId of viewportIds) {\n const viewport = renderingEngine.getViewport(viewportId);\n\n if (!viewport) {\n throw new Error(`Viewport with Id ${viewportId} does not exist`);\n }\n\n // if not instance of BaseVolumeViewport, throw\n if (!(viewport instanceof BaseVolumeViewport)) {\n console.warn(\n `Viewport with Id ${viewportId} is not a BaseVolumeViewport. Cannot add volume to this viewport.`\n );\n\n return;\n }\n }\n\n const addVolumePromises = viewportIds.map(async (viewportId) => {\n const viewport = renderingEngine.getViewport(viewportId) as VolumeViewport;\n\n await viewport.addVolumes(volumeInputs, immediateRender, suppressEvents);\n });\n\n await Promise.all(addVolumePromises);\n return;\n}\n\nexport default addVolumesToViewports;\n"],"names":["root","factory","exports","module","require","define","amd","self","__WEBPACK_EXTERNAL_MODULE__468__","__WEBPACK_EXTERNAL_MODULE__197__","__WEBPACK_EXTERNAL_MODULE__821__","__WEBPACK_EXTERNAL_MODULE__976__","__WEBPACK_EXTERNAL_MODULE__807__","__WEBPACK_EXTERNAL_MODULE__847__","__WEBPACK_EXTERNAL_MODULE__739__","__WEBPACK_EXTERNAL_MODULE__215__","__WEBPACK_EXTERNAL_MODULE__283__","__WEBPACK_EXTERNAL_MODULE__785__","__WEBPACK_EXTERNAL_MODULE__953__","__WEBPACK_EXTERNAL_MODULE__9__","__WEBPACK_EXTERNAL_MODULE__864__","__WEBPACK_EXTERNAL_MODULE__896__","__WEBPACK_EXTERNAL_MODULE__861__","__WEBPACK_EXTERNAL_MODULE__795__","__WEBPACK_EXTERNAL_MODULE__281__","__WEBPACK_EXTERNAL_MODULE__329__","__WEBPACK_EXTERNAL_MODULE__673__","__WEBPACK_EXTERNAL_MODULE__348__","__WEBPACK_EXTERNAL_MODULE__70__","__WEBPACK_EXTERNAL_MODULE__474__","__WEBPACK_EXTERNAL_MODULE__610__","__WEBPACK_EXTERNAL_MODULE__21__","__WEBPACK_EXTERNAL_MODULE__643__","__WEBPACK_EXTERNAL_MODULE__128__","__WEBPACK_EXTERNAL_MODULE__664__","__WEBPACK_EXTERNAL_MODULE__973__","__WEBPACK_EXTERNAL_MODULE__394__","__WEBPACK_EXTERNAL_MODULE__582__","__WEBPACK_EXTERNAL_MODULE__482__","__WEBPACK_EXTERNAL_MODULE__343__","__WEBPACK_EXTERNAL_MODULE__363__","__WEBPACK_EXTERNAL_MODULE__982__","__WEBPACK_EXTERNAL_MODULE__130__","__WEBPACK_EXTERNAL_MODULE__298__","__WEBPACK_EXTERNAL_MODULE__398__","__WEBPACK_EXTERNAL_MODULE__388__","__WEBPACK_EXTERNAL_MODULE__120__","__WEBPACK_EXTERNAL_MODULE__395__","__WEBPACK_EXTERNAL_MODULE__948__","__WEBPACK_EXTERNAL_MODULE__478__","__WEBPACK_EXTERNAL_MODULE__441__","_typeof","_regeneratorRuntime","__esModule","Op","Object","prototype","hasOwn","hasOwnProperty","$Symbol","Symbol","iteratorSymbol","iterator","asyncIteratorSymbol","asyncIterator","toStringTagSymbol","toStringTag","obj","key","value","defineProperty","enumerable","configurable","writable","err","wrap","innerFn","outerFn","tryLocsList","protoGenerator","Generator","generator","create","context","Context","_invoke","state","method","arg","Error","undefined","done","delegate","delegateResult","maybeInvokeDelegate","ContinueSentinel","sent","_sent","dispatchException","abrupt","record","tryCatch","type","fn","call","GeneratorFunction","GeneratorFunctionPrototype","IteratorPrototype","this","getProto","getPrototypeOf","NativeIteratorPrototype","values","Gp","defineIteratorMethods","forEach","AsyncIterator","PromiseImpl","invoke","resolve","reject","result","__await","then","unwrapped","error","previousPromise","callInvokeWithMethodAndArg","TypeError","info","resultName","next","nextLoc","pushTryEntry","locs","entry","tryLoc","catchLoc","finallyLoc","afterLoc","tryEntries","push","resetTryEntry","completion","reset","iterable","iteratorMethod","isNaN","length","i","doneResult","displayName","isGeneratorFunction","genFun","ctor","constructor","name","mark","setPrototypeOf","__proto__","awrap","async","Promise","iter","keys","object","reverse","pop","skipTempReset","prev","charAt","slice","stop","rootRecord","rval","exception","handle","loc","caught","hasCatch","hasFinally","finallyEntry","complete","finish","thrown","delegateYield","runtime","regeneratorRuntime","accidentalStrictMode","globalThis","Function","HASH_UNDEFINED","MAX_SAFE_INTEGER","argsTag","boolTag","dateTag","funcTag","genTag","mapTag","numberTag","objectTag","promiseTag","regexpTag","setTag","stringTag","symbolTag","weakMapTag","arrayBufferTag","dataViewTag","float32Tag","float64Tag","int8Tag","int16Tag","int32Tag","uint8Tag","uint8ClampedTag","uint16Tag","uint32Tag","reFlags","reIsHostCtor","reIsUint","cloneableTags","freeGlobal","g","freeSelf","freeExports","nodeType","freeModule","moduleExports","addMapEntry","map","pair","set","addSetEntry","add","arrayReduce","array","iteratee","accumulator","initAccum","index","isHostObject","toString","e","mapToArray","Array","size","overArg","func","transform","setToArray","uid","arrayProto","funcProto","objectProto","coreJsData","maskSrcKey","exec","IE_PROTO","funcToString","objectToString","reIsNative","RegExp","replace","Buffer","Uint8Array","getPrototype","objectCreate","propertyIsEnumerable","splice","nativeGetSymbols","getOwnPropertySymbols","nativeIsBuffer","isBuffer","nativeKeys","DataView","getNative","Map","Set","WeakMap","nativeCreate","dataViewCtorString","toSource","mapCtorString","promiseCtorString","setCtorString","weakMapCtorString","symbolProto","symbolValueOf","valueOf","Hash","entries","clear","ListCache","MapCache","Stack","__data__","assignValue","objValue","eq","assocIndexOf","baseClone","isDeep","isFull","customizer","stack","isObject","isArr","isArray","input","initCloneArray","source","copyArray","tag","getTag","isFunc","buffer","copy","cloneBuffer","isPrototype","proto","initCloneObject","copyObject","getSymbols","copySymbols","baseAssign","cloneFunc","symbol","Ctor","cloneArrayBuffer","dataView","byteOffset","byteLength","cloneDataView","typedArray","cloneTypedArray","cloneMap","regexp","lastIndex","cloneRegExp","cloneSet","initCloneByTag","stacked","get","props","keysFunc","symbolsFunc","offset","arrayPush","baseGetAllKeys","getAllKeys","arrayEach","subValue","arrayBuffer","newValue","getMapData","data","getValue","isFunction","test","baseIsNative","has","cache","pairs","LARGE_ARRAY_SIZE","isIndex","other","ArrayBuffer","ctorString","isArrayLike","isLength","inherited","isObjectLike","isArrayLikeObject","isArguments","n","baseTimes","String","skipIndexes","arrayLikeKeys","baseKeys","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","id","loaded","__webpack_modules__","getter","d","a","definition","o","window","prop","r","nmd","paths","children","Events","RequestType","ViewportType","InterpolationType","BlendModes","BlendMode","vtkConstants","COMPOSITE_BLEND","MAXIMUM_INTENSITY_BLEND","MINIMUM_INTENSITY_BLEND","AVERAGE_INTENSITY_BLEND","OrientationAxis","hotIron","numOfColors","colors","pet","numColors","hotMetalBlue","pet20Step","gray","gamma","segmentedData","red","green","blue","jet","hsv","hot","cool","spring","summer","autumn","winter","bone","copper","spectral","coolwarm","blues","RENDERING_DEFAULTS","MINIMUM_SLAB_THICKNESS","MAXIMUM_RAY_DISTANCE","freeze","deepFreeze","getOwnPropertyNames","axial","viewPlaneNormal","viewUp","sagittal","coronal","gradientOpacity","specularPower","scalarOpacity","specular","shade","ambient","colorTransfer","diffuse","interpolation","asyncGeneratorStep","gen","_next","_throw","_asyncToGenerator","args","arguments","apply","_defineProperties","target","descriptor","_createClass","Constructor","protoProps","staticProps","_classCallCheck","instance","_defineProperty","vtkStreamingOpenGLTexture","publicAPI","model","classHierarchy","superCreate3DFilterableFromRaw","create3DFilterableFromRaw","width","height","depth","numComps","dataType","inputDataType","inputNumComps","update3DFromRaw","updatedFrames","bytesPerVoxel","TypedArrayConstructor","_openGLRenderWindow","activateTexture","createTexture","bind","Int16Array","Float32Array","fillSubImage3D","generateMipmap","deactivate","frameIndex","zOffset","components","rowLength","gl","MAX_TEXTURE_SIZE","getParameter","blockHeight","Math","floor","multiRowBlockLength","min","multiRowBlockLengthInBytes","normalBlocks","lastBlockHeight","multiRowLastBlockLength","block","yOffset","texSubImage3D","format","openGLDataType","getTextureParameters","setUpdatedFrame","DEFAULT_VALUES","extend","initialValues","assign","vtkOpenGLTexture","newInstance","macro","ImageVolume","volumeId","metadata","dimensions","spacing","origin","direction","imageData","scalarData","sizeInBytes","numVoxels","scaling","referencedVolumeId","CornerstoneEventTarget","listeners","callback","indexOf","stackLength","event","defaultPrevented","triggerEvent","el","eventTarget","detail","CustomEvent","cancelable","dispatchEvent","imageIdToURI","imageId","colonIndex","substring","Cache","newMaxCacheSize","errorMessage","_maxCacheSize","getBytesAvailable","_imageCacheSize","_volumeCacheSize","imageLoadObject","_imageCache","cancelFn","decache","delete","cachedVolume","_volumeCache","volumeLoadObject","volume","cancelLoading","imageIterator","removeImageLoadObject","purgeVolumeCache","volumeIterator","removeVolumeLoadObject","timeStamp","Date","now","cachedImage","_incrementImageCacheSize","eventDetails","_decacheImage","_incrementVolumeCacheSize","_decacheVolume","increment","getMaxCacheSize","getCacheSize","numBytes","volumeImageIds","bytesAvailable","cachedImages","from","sort","b","cachedImageIds","im","imageIdsToPurge","filter","includes","promise","sharedCacheKey","image","toFixed","isCacheable","decacheIfNecessaryUntilBytesAvailable","console","warn","catch","volumeIds","imageIdToUse","imageIds","imageIdIndex","imageURIToUse","foundImageId","find","uuidv4","c","crypto","getRandomValues","createInternalVTKRepresentation","numComponents","PhotometricInterpretation","scalarArray","vtkDataArray","numberOfComponents","vtkImageData","setDimensions","setSpacing","setDirection","setOrigin","getPointData","setScalars","unknownVolumeLoader","volumeLoaders","loadVolumeFromVolumeLoader","options","scheme","loader","errorObject","loadVolume","createAndCacheVolume","createAndCacheDerivedVolume","referencedVolume","targetBuffer","scalarLength","TypedArray","sharedArrayBuffer","SharedArrayBuffer","volumeScalarData","derivedImageData","derivedVolume","cloneDeep","createLocalVolume","preventCache","registerVolumeLoader","volumeLoader","registerUnknownVolumeLoader","oldVolumeLoader","vtkSharedVolumeMapper","superDelete","scalarTexture","vtkVolumeMapper","createVolumeMapper","volumeMapper","setInputData","getSpacing","sampleDistance","setMaximumSamplesPerRay","setSampleDistance","setScalarTexture","RequestPoolManager","interaction","thumbnail","prefetch","requestPool","grabDelay","awake","numRequests","maxNumRequests","timeoutHandle","clearTimeout","requestFn","additionalDetails","priority","requestDetails","startGrabbing","filterFunction","requestType","requestsToSend","getNextRequest","finally","startAgain","getSortedPriorityGroups","shift","hasRemainingInteractionRequests","sendRequests","hasRemainingThumbnailRequests","hasRemainingPrefetchRequests","setTimeout","Number","imageLoadPoolManager","setMaxSimultaneousRequests","unknownImageLoader","imageLoaders","loadImageFromCacheOrVolume","cachedVolumeInfo","loadStatus","convertToCornerstoneImage","loadImageFromImageLoader","loadImage","loadAndCacheImage","loadAndCacheImages","allPromises","cancelLoadImage","cancelLoadImages","cancelLoadAll","requests","loadObject","cancel","registerImageLoader","imageLoader","registerUnknownImageLoader","oldImageLoader","unregisterAllImageLoaders","providers","addProvider","provider","removeProvider","removeAllProviders","getMetaData","query","toWindowLevel","low","high","windowWidth","abs","windowCenter","toLowHighRange","lower","upper","getMinMax","storedPixelData","storedPixel","max","numPixels","REQUEST_TYPE","volumeActor","imageVolume","voi","getVOIFromMetadata","getVOIFromMinMax","handlePreScaledVolume","getProperty","getRGBTransferFunction","setMappingRange","metaData","modality","isPrescaled","voiLutModule","windowLevel","generalSeriesModule","modalityLutModule","numImages","bytesPerImage","voxelsPerImage","bytePerPixel","BYTES_PER_ELEMENT","scalingParameters","rescaleSlope","rescaleIntercept","suvFactor","scalingParametersToUse","suvbw","preScale","enabled","imageScalarData","getPixelData","_getImageScalarDataFromImageVolume","volumeBuffer","volumeBufferView","setDefaultVolumeVOI","element","viewportId","suppressEvents","blendMode","setBlendMode","vtkVolume","setMapper","triggerVOIModified","voiRange","getRange","voiModifiedEventDetail","range","createVolumeActor","VIEWPORT_ELEMENT","CANVAS_CSS_CLASS","getOrCreateCanvas","canvasSelector","viewportElement","internalDiv","querySelector","div","document","createElement","style","position","classList","appendChild","createViewportElement","canvas","createCanvas","arr","len","arr2","minLen","_toConsumableArray","re","renderingEngineId","vtkWarningMacro","vtkStreamingOpenGLVolumeMapper","buildBufferObjects","ren","actor","currentInput","scalars","getScalars","vprop","jitterTexture","getHandle","oTable","random","setMinificationFilter","Filter","setMagnificationFilter","create2DFromRaw","VtkDataTypes","numComp","getNumberOfComponents","numIComps","getIndependentComponents","getMTime","opacityTextureString","oWidth","oSize","ofTable","tmpTable","ofun","getScalarOpacity","opacityFactor","renderable","getSampleDistance","getScalarOpacityUnitDistance","oRange","getTable","opacityTexture","releaseGraphicsResources","getWebgl2","getExtension","colorTextureString","cWidth","cTable","cfun","cRange","colorTexture","scalarTextureString","dims","getDimensions","previousTextureParameters","getDataType","getData","shouldReset","previousTextureSize","resetFormatAndType","getPreferSizeOverAccuracy","tris","getCABO","getElementCount","ptsArray","cellArray","Uint16Array","points","setName","cells","createVBO","Representation","cellOffset","VBOBuildTime","modified","setCameraShaderParameters","cellBO","program","getProgram","cam","openGLCamera","getRenderable","crange","getClippingRange","setUniformf","setIsPerformingCoordinateTransformation","keyMats","getKeyMatrices","actMats","openGLVolume","mat4","modelToView","wcvc","mcwc","bounds","getBounds","spc","pos","Float64Array","dir","dcxmin","dcxmax","dcymin","dcymax","vec3","getParallelProjection","t","vcpc","isUniformUsed","setUniformi","ext","getSpatialExtent","vsize","setUniform3f","indexToWorldVec3","i2wmat4","getIndexToWorld","idxToView","mat3","idxNormalMatrix","normalMatrix","getDirection","maxSamples","getMaximumSamplesPerRay","ceil","vctoijk","setUniform3i","volInfo","getVolumeInfo","getWidth","getHeight","xreps","xstride","ystride","normal","pos2","dist","getUseLabelOutline","worldToIndex","getWorldToIndex","setUniformMatrix","projectionToWorld","wcpc","getRenderTargetSize","getRenderTargetOffset","projectionToView","lastLightComplexity","lightNum","lightColor","getLights","light","getSwitch","dColor","getColor","intensity","getIntensity","setUniform3fArray","ldir","halfAngle","_useSmallViewport","_smallViewportWidth","_smallViewportHeight","openGLRenderer","getTiledSizeAndOrigin","usize","lowerLeftU","lowerLeftV","vtkOpenGLVolumeMapper","previousState","vtkStreamingOpenGLViewNodeFactory","createNode","dataObject","isDeleted","cpt","className","getClassName","overrides","getModelInitialValues","vn","setMyFactory","getScalarTexture","vtkViewNodeFactory","registerOverride","vtkOpenGLActor","vtkOpenGLActor2D","vtkOpenGLCamera","vtkOpenGLGlyph3DMapper","vtkOpenGLImageMapper","vtkOpenGLImageSlice","vtkOpenGLPolyDataMapper","vtkOpenGLPixelSpaceCallbackMapper","vtkOpenGLRenderer","vtkOpenGLSkybox","vtkOpenGLSphereMapper","vtkOpenGLStickMapper","vtkOpenGLVolume","vtkStreamingOpenGLRenderWindow","vtkOpenGLRenderWindow","myFactory","vtkOffscreenMultiRenderWindow","invokeResize","renderWindow","vtkRenderWindow","rendererMap","openGLRenderWindow","addView","interactor","vtkRenderWindowInteractor","setView","initialize","addRenderer","viewport","background","renderer","vtkRenderer","destroy","getInteractor","removeRenderer","getRenderer","getRenderers","resize","container","setSize","render","setContainer","_assertThisInitialized","ReferenceError","_getPrototypeOf","_superPropBase","property","_get","Reflect","receiver","base","desc","getOwnPropertyDescriptor","_setPrototypeOf","p","_inherits","subClass","superClass","_possibleConstructorReturn","transformWorldToIndex","worldPos","round","_slicedToArray","_i","_s","_e","_arr","_n","_d","isImageActor","isA","linePlaneIntersection","p0","p1","plane","x0","y0","z0","x1","y1","z1","A","B","C","planeEquation","point","threePlaneIntersection","firstPlane","secondPlane","thirdPlane","A1","B1","C1","D1","A2","B2","C2","D2","A3","B3","C3","D3","m0","m1","m2","m3","planeDistanceToPoint","signed","D","x","y","z","numerator","distance","sqrt","sign","hasNaNValues","some","Viewport","sx","sy","sWidth","sHeight","_actors","setAttribute","defaultOptions","_cloneDeep","isDisabled","renderingEngineCache","renderingEngine","getRenderingEngine","hasBeenDestroyed","offscreenMultiRenderWindow","renderViewport","immediate","flipHorizontal","flipVertical","getDefaultImageData","camera","getCamera","focalPoint","viewRight","viewUpToSet","viewPlaneNormalToSet","middleIJK","idx","centeredFocalPoint","indexToWorld","resetFocalPoint","_getFocalPointForResetCamera","resetPan","resetToCenter","panDir","panValue","getPanDir","mirrorVec","panDirMirror","newFocalPoint","newPosition","setCamera","actorEntry","getDefaultActor","getMapper","getInputData","getActors","actorUID","actors","removeAllActors","addActors","getActor","removeViewProp","actorUIDs","removeActor","resetCameraPanAndZoom","addActor","resetCamera","removeAllViewProps","_suppressCameraModifiedEvents","intersections","_getEdges","intersectionPoint","planar","_isInBounds","resetZoom","storeAsInitialCamera","previousCamera","computeVisiblePropBounds","activeCamera","getVtkActiveCamera","getViewPlaneNormal","getViewUp","radius","_getWorldDistanceViewUpAndViewRight","widthWorld","heightWorld","canvasSize","boundsAspectRatio","canvasAspectRatio","scaleFactor","parallelScale","w1","w2","w3","vtkMath","focalPointToSet","positionToSet","resetCameraClippingRange","clippingRangeToUse","setPhysicalScale","setPhysicalTranslation","viewAngle","clippingRange","modifiedCamera","setInitialCamera","RESET_CAMERA_EVENT","invokeEvent","triggerCameraModifiedEventIfNecessary","initialCamera","getFocalPoint","zero3","canvasToWorld","initialCanvasFocal","worldToCanvas","currentCanvasFocal","vec2","pan","delta2","getPan","delta","newFocal","getParallelScale","initialParallelScale","_getViewImageDataIntersections","point_x","point_y","point_z","getActiveCamera","vtkCamera","getPosition","parallelProjection","getViewAngle","cameraInterface","updatedCamera","flipH","flip","flipV","setViewUp","setDirectionOfProjection","setPosition","setFocalPoint","setParallelScale","setViewAngle","setClippingRange","updateClippingPlanesForActors","eventDetail","rotation","vtkPlanes","getClippingPlanes","slabThickness","setOrientationOfClippingPlanes","scaledDistance","setNormal","newOrigin1","newOrigin2","viewUpCorners","_getCorners","viewRightCorners","vtkMatrixBuilder","identity","rotateFromDirections","pt","minY","Infinity","maxY","minX","maxX","oldCamera","oldFocalPoint","oldViewPlaneNormal","vectorFromOldFocalPointToCenteredFocalPoint","distanceFromOldFocalPointToCenteredFocalPoint","xMin","xMax","yMin","yMax","zMin","zMax","p2","p3","p4","p5","p6","p7","p8","getVolumeActorCorners","extentToBounds","getExtent","getSliceRange","corners","transformedFocalPoint","currentSlice","current","getSpacingInNormalDirection","iVector","jVector","kVector","dotProducts","projectedSpacing","getTargetVolumeAndSpacingInNormalDir","targetVolumeId","volumeActors","spacingInNormalDirection","numVolumeActors","imageVolumes","va","referenceId","iv","smallest","sliceRange","numberOfSlices","imageIndex","getRenderingEngines","vtkSlabCamera","tmpMatrix","tmpvec1","getProjectionMatrix","aspect","nearz","farz","projectionMatrix","scale","physicalScale","cRange0","cRange1","isPerformingCoordinateTransformation","xmin","xmax","ymin","ymax","useOffAxisProjection","tmp","tan","useHorizontalViewAngle","znear","zfar","throw","toLowerCase","userAgent","platform","maxTouchPoints","navigator","MSStream","isIpad","isMobile","isSafari12","charCodeAt","l","s","f","u","h","super","mobileTiers","desktopTiers","override","glContext","failIfMajorPerformanceCaveat","benchmarksURL","tier","m","v","screenSize","w","screen","loadBenchmarks","fetch","json","parseInt","split","P","device","fps","gpu","S","alpha","antialias","powerPreference","stencil","getContext","UNMASKED_RENDERER_WEBGL","createShader","createProgram","shaderSource","compileShader","attachShader","linkProgram","detachShader","deleteShader","useProgram","createBuffer","bindBuffer","bufferData","getAttribLocation","vertexAttribPointer","enableVertexAttribArray","clearColor","drawArrays","readPixels","deleteProgram","deleteBuffer","join","all","match","MAX_VALUE","devicePixelRatio","E","L","M","$","csRenderInitialized","useCPURendering","hasActiveWebGLContext","WebGLRenderingContext","init","log","getGPUTier","gpuTier","setUseCPURendering","status","resetUseCPURendering","getShouldUseCPURendering","isCornerstoneInitialized","BaseVolumeViewport","_FrameOfReferenceUID","canvasPos","getOpenGLRenderWindow","getSize","canvasPosWithDPR","displayCoord","worldCoord","displayToWorld","worldToDisplay","canvasCoord","canvasCoordWithDPR","imageURI","setActiveCamera","setParallelProjection","initializeVolumeNewImageEventDispatcher","volumeNewImageHandlerBound","cameraEvent","getImageData","getViewport","getImageSliceDataForVolumeViewport","volumeNewImageEventDispatcher","volumeNewImageCleanUpBound","evt","removeEventListener","resetVolumeNewImageState","addEventListener","actorEntries","setRange","volumeInputArray","firstImageVolume","FrameOfReferenceUID","_isValidVolumeInputArray","_setVolumeActors","visibility","setVisibility","removeActors","orientation","numVolumes","volumeInput","flipDirection","defaultActor","defaultActorUID","getOrigin","Modality","hasPixelSpacing","volumeActorEntries","setActors","filterActorUIDs","VolumeViewport","_getImageIdIndex","EPSILON","spacingInNormal","sub","_getOrientationVectors","setViewUpFrom","_useAcquisitionPlaneForViewPlane","_setViewPlaneToAcquisitionPlane","MPR_CAMERA_VALUES","_getAcquisitionPlaneOrientation","voxelIndex","mapper","clipPlane1","vtkPlane","clipPlane2","newVtkPlanes","addClippingPlane","currentCamera","invertRgbTransferFunction","rgbTransferFunction","nodeValue1","getNodeValue","setNodeValue","isEqual","v1","v2","tolerance","performance","voiLUT","lut","minValue","maxValue","maxValueMapped","firstValueMapped","modalityLutValue","generateNonLinearVOILUT","generateLinearVOILUT","Transform","matrix","m11","m12","m21","m22","dx","dy","m4","m5","rad","cos","sin","enabledElement","displayedArea","translate","angle","rotate","PI","widthScale","heightScale","brhc","tlhc","presentationSizeMode","rowPixelSpacing","columnPixelSpacing","verticalScale","horizontalScale","translation","hflip","vflip","calculateTransform","getMatrix","setTransform","doesImageNeedToBeRendered","lastRenderedImageId","renderingTools","lastRenderedViewport","invert","modalityLUT","colormap","renderCanvas","canvasContext","fillStyle","fillRect","renderCanvasData","renderCanvasContext","isColor","color","lastRenderedIsColor","getRenderCanvas","invalidated","canvasWasColor","getCanvas","initializeRenderCanvas","start","colorLUT","cachedLut","maxPixelValue","minPixelValue","lutArray","Uint8ClampedArray","vlutfn","getVOILUT","generateColorLUT","storedValue","getLut","stats","lastLutGenerateTime","rgba","canvasImageDataData","pixelData","lastGetPixelDataTime","canvasImageDataIndex","storedPixelDataIndex","lastStoredPixelDataToCanvasImageDataTime","storedRGBAPixelDataToCanvasImageData","storedColorPixelDataToCanvasImageData","putImageData","lastPutImageDataTime","renderColorImage","imageSmoothingEnabled","pixelReplication","setToPixelCoordinateSystem","drawImage","saveLastRendered","lutFunction","pixelValue","lutMatches","hasVoi","maxVoi","slope","intercept","minVoi","ww","wc","computeAutoVoi","mlutfn","storedPixelValue","generateNonLinearModalityLUT","generateLinearModalityLUT","getModalityLut","isPreScaled","generateLut","renderGrayscaleImage","useAlphaChannel","minimum","collectedMultiplierTerms","storedPixelDataToCanvasImageDataPET","storedPixelDataToCanvasImageData","storedPixelDataToCanvasImageDataRGBA","HSVToRGB","hue","sat","val","rgb","hueCase","frac","lx","ly","lz","LookupTable","NumberOfColors","Ramp","TableRange","HueRange","SaturationRange","ValueRange","AlphaRange","NaNColor","BelowRangeColor","UseBelowRangeColor","AboveRangeColor","UseAboveRangeColor","InputRange","Table","number","ramp","end","scalar","mapValue","force","hinc","sinc","vinc","ainc","maxIndex","c_rgba","buildSpecialColors","numberOfColors","belowRangeColorIndex","aboveRangeColorIndex","nanColorIndex","getIndex","Range","MaxIndex","Shift","Scale","dIndex","linearIndexLookupMain","COLOR_TRANSPARENT","getRank","elem","left","right","mid","midElem","makeMappingArray","N","xLinSpace","vector","linspace","pow","xLinSpaceIndexes","inputArray","indexes","searchSorted","colorPercent","colorDelta","getColormap","colormapData","CPU_COLORMAPS","redLut","greenLut","blueLut","createLinearSegmentedColormap","cpuFallbackColormap","getId","getColorSchemeName","setColorSchemeName","getNumberOfColors","setNumberOfColors","isValidIndex","getColorRepeating","setColor","addColor","insertColor","removeColor","clearColors","buildLookupTable","setNumberOfTableValues","setTableValue","createLookupTable","clamp","renderPseudoColorImage","colormapId","clut","storedPixelDataToCanvasImageDataPseudocolorLUTPET","grayscaleLut","storedPixelDataToCanvasImageDataPseudocolorLUT","lastRenderTime","renderTimeInMs","invalid","needsRedraw","getTransform","transformPoint","validateParameterUndefinedOrNull","checkParam","errorMsg","isRotated","imageSize","getImageSize","verticalRatio","horizontalRatio","initialDefaultViewport","labelmap","getImageFitScale","columns","rows","setCanvasSize","clientWidth","clientHeight","wasFitToWindow","oldCanvasWidth","oldCanvasHeight","imageWidth","imageHeight","relativeRescale","relWidthChange","relHeightChange","relChange","StackViewport","_resizeCPU","_cpuFallbackEnabledElement","forceFitToWindow","fitToWindow","getCurrentImageId","imagePlaneModule","frameOfReferenceUID","vtkImageMapper","vtkImageSlice","setIndependentComponents","rotationCache","interpolationType","canvasToWorldCPU","canvasToWorldGPU","worldToCanvasCPU","worldToCanvasGPU","canvasToPixel","px","py","diff","worldPoint","pixelToCanvas","getDistance","currentImageIdIndex","targetImageIdIndex","drawImageSync","cpuRenderingInvalidated","fillWithBackgroundColor","setThicknessFromFocalPoint","setFreezeFocalPoint","cameraFocalPointOnRender","initializeElementDisabledHandler","elementDisabledHandler","debouncedTimeout","getImageDataCPU","getImageDataGPU","csImage","getScalarData","cpuImagePixelData","canvasPoint","pixelCoord","pixelRepresentation","bitsAllocated","bitsStored","highBit","photometricInterpretation","samplesPerPixel","imageIdScalingFactor","_addScalingToViewport","_getImagePlaneModule","calibrateIfNecessary","imagePixelModule","calibratedPixelSpacing","calibratedRowSpacing","calibratedColumnSpacing","imageDataMetadata","_publishCalibratedEvent","_calibrationEvent","rowScale","columnScale","voiApplied","setVOI","setInvertColor","setInterpolationType","setRotation","_resetProperties","getCameraCPU","setCameraCPU","setProperties","initialVOIRange","rotationMatrix","canvasCenter","canvasCenterWorld","topLeftWorld","bottomLeftWorld","focalPointCanvas","focalPointPixel","prevFocalPointCanvas","prevFocalPointPixel","deltaPixel","viewportOrientation","cosA","sinA","newX","newY","correctShift","setFlipCPU","setVOICPU","setVOIGPU","setRotationCPU","setRotationGPU","setInterpolationTypeCPU","setInterpolationTypeGPU","setInvertColorCPU","setInvertColorGPU","roll","tfunc","wwToUse","wcToUse","windowLevelUtil","imageActor","voiRangeToUse","setColorWindow","setColorLevel","PET","suvlbm","suvbsa","petScaling","suvbwToSuvlbm","suvbwToSuvbsa","rowCosines","columnCosines","buildMetadata","rowCosineVec","colCosineVec","scanAxisNormal","imagePositionPatient","xSpacing","ySpacing","xVoxels","yVoxels","_getNumCompsFromPhotometricInterpretation","imageDataDirection","pixelArray","_imageData","stackInvalidated","_setImageIdIndex","dest","rgbIndex","_loadAndDisplayImageCPU","_loadAndDisplayImageGPU","successCallback","_getImageDataMetadata","scaled","getDefaultViewport","viewportSettingToUse","errorCallback","useRGBA","_updateActorToDisplayImageId","sameImageData","_checkVTKImageDataMatchesCornerstoneImage","previousCameraProps","_updateVTKImageDataFromCornerstoneImage","cameraProps","panCache","resetCameraNoEvent","setCameraNoEvent","_restoreCameraProps","_setPropertiesFromCache","_createVTKImageData","createActorMapper","_getCameraOrientation","triggerCameraEvent","vtkColorTransferFunction","addRGBPoint","setRGBTransferFunction","triggerCalibrationEvent","_loadAndDisplayImage","resetCameraCPU","resetCameraGPU","center","centerWorld","debounce","loop","currentTargetImageIdIndex","numberOfFrames","newTargetImageIdIndex","targetImageId","imageAlreadyLoaded","setImageIdIndex","eventData","newImageIdIndex","getImageIds","prevScale","getCPUFallbackError","fillCanvasWithBackgroundColor","setColormapCPU","setColormapGPU","unsetColormapCPU","unsetColormapGPU","newImagePlaneModule","imageOrientationPatient","VolumeViewport3D","viewportTypeUsesCustomRenderingPipeline","viewportType","viewportTypeToViewportClass","useCustomRenderingPipeline","RenderingEngine","viewportIdsWithSameFrameOfReferenceUID","_getViewportsAsArray","vp","getFrameOfReferenceUID","renderViewports","_throwIfDestroyed","performVtkDrawCall","viewports","eventDetailArray","_needsRender","renderViewportUsingCustomOrVtkPipeline","_animationFrameSet","_animationFrameHandle","offScreenCanvasContainer","_viewports","viewportInputEntry","viewportInput","_normalizeViewportInputEntry","disableElement","viewportUsesCustomRenderingPipeline","addCustomViewport","enableVTKjsDrivenViewport","_resetViewport","_removeViewport","getViewports","_clearAnimationFrame","publicViewportInputEntries","viewportInputEntries","_normalizeViewportInputEntries","_reset","vtkDrivenViewportInputEntries","customRenderingViewportInputEntries","vpie","setVtkjsDrivenViewports","setCustomViewports","keepCamera","vtkDrivenViewports","customRenderingViewports","_resizeVTKViewports","_resizeUsingCustomResizeHandler","viewportIds","_setViewportsToBeRenderedNextFrame","backgroundColor","ctx","normalizedViewportInputs","prevCamera","canvasesDrivenByVtkJs","_resizeOffScreenCanvas","offScreenCanvasWidth","offScreenCanvasHeight","_resize","rect","getBoundingClientRect","viewportsDrivenByVtkJs","xOffset","internalViewportEntry","addVtkjsDrivenViewport","offscreenCanvasProperties","tabIndex","_getViewportCoordsOnOffScreenCanvas","sxStartDisplayCoords","syStartDisplayCoords","sxEndDisplayCoords","syEndDisplayCoords","vtkDrivenCanvases","vtkDrivenViewportInputEntry","_xOffset","setViewport","_render","requestAnimationFrame","_renderFlaggedViewports","getRenderWindow","renderers","setDraw","customRenderViewportToCanvas","offScreenCanvas","get3DContext","_renderViewportFromVtkCanvasToOnscreenCanvas","dWidth","dHeight","removeAttribute","clearRect","cancelAnimationFrame","uri","link","_debugRender","download","href","body","click","removeChild","dataURL","toDataURL","imageRetrievalPoolManager","getEnabledElement","dataset","getEnabledElementByIds","viewportUid","renderingEngineUid","getEnabledElements","enabledElements","DEFAULT_SETTINGS","RUNTIME_SETTINGS","OBJECT_SETTINGS_MAP","DICTIONARY","Settings","dictionary","seal","endsWith","deleteCount","namespace","deleteAll","startsWith","unset","iterate","isPlainObject","deepSet","subject","getRuntimeSettings","subfield","defaultSettings","settingObj","setting","runtimeSettings","getDefaultSettings","settings","objectSettingsMap","assert","getObjectSettings","references","last","previous","isValidKey","prefix","failCount","field","setAll","WeakSet","separator","subKey","subContext","subContextValue","scaleRGBTransferFunction","scalingFactor","LAST_RUNTIME_ID","GLOBAL_CONTEXT","getRuntimeId","idComponents","carry","getNextRuntimeId","payload","isOpposite","crossOriginIsolated","getClosestImageId","imageIdForTool","halfSpacingInNormalDirection","dot","indexWithinDimensions","targetViewport","renderingEngines","sameVolumesViewports","targetActors","getVolumeViewports","vpActors","every","vpActor","targetViewports","filteredViewports","hasVolumeId","renderToCanvas","loadImageToCanvas","worldCoords","newOrigin","imageToWorldCoords","imageCoords","imageCoordsInWorld","snapFocalPointToSlice","deltaFrames","posDiffFromFocalPoint","steps","floatingStepNumber","newSlicePosFromMin","getViewportsWithImageURI","filteredStackViewports","getStackViewports","hasImageURI","filteredVolumeViewports","getClosestStackImageIndexForPoint","minimalDistance","getCurrentImageIdIndex","planeMetadata","targetImagePlane","rowVec","colVec","planeNormal","getPlaneMetadata","closestStack","higherImageIds","lowerImageIds","calculateMinimalDistanceForStackViewport","spatialRegistrationMetadataProvider","viewportId1","viewportId2","entryId","entryIdReverse","viewport1","viewport2","imageId1","imageId2","imagePlaneModule1","imagePlaneModule2","imagePositionPatient1","imagePositionPatient2","mat","getViewportImageCornersInWorld","topRightCanvas","bottomRightCanvas","bottomLeftCanvas","topRightWorld","bottomRightWorld","topLeftImage","topRightImage","bottomRightImage","bottomLeftImage","topLeftImageWorld","topRightImageWorld","bottomRightImageWorld","_getStackViewportImageCorners","imageCoord","applyPreset","preset","colorTransferArray","parseFloat","shiftRange","getShiftRange","normColorTransferValuePoints","rescaled","removeAllPoints","applyPointsToRGBFunction","scalarOpacityArray","vtkPiecewiseFunction","normPoints","opacity","pwf","addPoint","applyPointsToPiecewiseFunction","setScalarOpacity","gradientMinValue","gradientMinOpacity","gradientMaxValue","gradientMaxOpacity","setUseGradientOpacity","setGradientOpacityMinimumValue","setGradientOpacityMinimumOpacity","setGradientOpacityMaximumValue","setGradientOpacityMaximumOpacity","setInterpolationTypeToFastLinear","setAmbient","setDiffuse","setSpecular","setSpecularPower","volumeInputs","immediateRender","setVolumePromises","setVolumes","setVolumesForViewports","addVolumePromises","addVolumes","addVolumesToViewports"],"sourceRoot":""}